Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhancement:does it support aliyun rds? #470

Closed
dikang123 opened this issue Aug 15, 2017 · 49 comments
Closed

enhancement:does it support aliyun rds? #470

dikang123 opened this issue Aug 15, 2017 · 49 comments
Assignees

Comments

@dikang123
Copy link

dikang123 commented Aug 15, 2017

aliyun rds is a version of amazon rds in China:aliyun rds.

I have a test,but return some sort of error:
2017-08-15 16:40:38 FATAL sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax

@shlomi-noach
Copy link
Contributor

@dikang123 any more input is appreciated. What is the table you're trying to convert? Which mysql version? Which gh-ost version? What's the alter statement?

@dikang123
Copy link
Author

dikang123 commented Aug 15, 2017

original table structure:

CREATE TABLE `vote_record` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键id',
  `user_id` varchar(22) DEFAULT NULL,
  `vote_num` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '投票数',
  `group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '用户组id 0-未激活用户 1-普通用户 2-vip用户 3-管理员用户',
  `status` tinyint(2) unsigned NOT NULL DEFAULT '1' COMMENT '状态 1-正常 2-已删除',
  `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
  `modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `col2` bigint(20) DEFAULT NULL COMMENT 'test',
  PRIMARY KEY (`id`),
  UNIQUE KEY `udx_user_id` (`user_id`),
  KEY `idx_usr_id` (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=200000 DEFAULT CHARSET=utf8 COMMENT='投票记录表';

mysql version:5.6.16-log
gh-ost:1.0.40

alter statement:

./gh-ost --host=xxx --user=xxx --password=xxx --database=appversionsdb --table=vote_record --alter="add column tag int not null default 0" --chunk-size=2000 --max-load=Threads_running=20 --allow-on-master --execute

@shlomi-noach
Copy link
Contributor

@dikang123 can I get the log preceeding that fatal message please?

@siddontang do you have any insight into aliyun rds?

@dikang123
Copy link
Author

dikang123 commented Aug 16, 2017

@shlomi-noach the only thing I got after typing the command was the error:

FATAL sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax

is there some sort of debug mode?

@shlomi-noach
Copy link
Contributor

@dikang123 please run with --debug --stack

@siddontang
Copy link

siddontang commented Aug 16, 2017

Hi @shlomi-noach

I have not used Aliyun RDS before. We should know the executing query which causes the panic.

@dikang123
Copy link
Author

dikang123 commented Aug 18, 2017

@shlomi-noach
the output:

2017-08-18 11:37:28 INFO starting gh-ost 1.0.40
2017-08-18 11:37:28 INFO Migrating `appversionsdb`.`vote_record`
2017-08-18 11:37:28 FATAL sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax
goroutine 1 [running]:
runtime/debug.Stack(0x82, 0x68, 0x0)
	/usr/local/Cellar/go/1.8.3/libexec/src/runtime/debug/stack.go:24 +0x79
runtime/debug.PrintStack()
	/usr/local/Cellar/go/1.8.3/libexec/src/runtime/debug/stack.go:16 +0x22
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.logErrorEntry(0x0, 0x8f8a80, 0xc42016a160, 0x0, 0x0)
	/Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:178 +0xfd
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.Fatale(0x8f8a80, 0xc42016a160, 0x0, 0x0)
	/Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:255 +0x3e
main.main()
	/Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/cmd/gh-ost/main.go:247 +0x1d3b

image

@shlomi-noach
Copy link
Contributor

pro tip: use three backticks for multi line code formatting. See how I've edited your comment.

@shlomi-noach
Copy link
Contributor

@siddontang not even you code -- thank you!

@shlomi-noach
Copy link
Contributor

@dikang123 the error is with reading nil (or a database NULL value) into a variable via go-mysql-driver.

The error message unfortunately doesn't make it clear where this happened exactly, but by elimination I suspect this is the result of executing select @@global.port, @@global.version. Can you verify that the gh-ost user you're using can run this query? What's the output for the query?

@dikang123
Copy link
Author

dikang123 commented Aug 20, 2017

@shlomi-noach
[root@proxy ~]# mysql -uxxx -pxxx -hxxx -e "select @@global.port"
+---------------+
| @@global.port |
+---------------+
| NULL |
+---------------+

seems like the port is NULL !

[root@proxy ~]# mysql -uxxx -pxxx-hxxx-e "select @@global.version"
+------------------+
| @@global.version |
+------------------+
| 5.6.16-log |
+------------------+

@shlomi-noach
Copy link
Contributor

@dikang123 thank you. Your task is to find out why select @@global.port is NULL. This shouldn't happen, and I've never seen this happen before, never even considered this to be a possibility, and I assume this must be introduced behavior by aliyun. Can you look into it?

@dikang123
Copy link
Author

@shlomi-noach yeah, I agree about that. There exists some limitations to make the global variable 'port' a null value! Is there some method to ignore or bypass this issue?

@shlomi-noach
Copy link
Contributor

shlomi-noach commented Aug 20, 2017

@dikang123, heh, you tell me 😄

If you can please run a quick investigation and let me know what aliyun does allow. Perhaps it allows select @@port? Perhaps another way to detect the port?

BTW, what is the output of show global variables like 'version%';?

@dikang123
Copy link
Author

dikang123 commented Aug 21, 2017

@shlomi-noach

mysql>show global variables like 'version%';
+-------------------------+---------------------+
| Variable_name           | Value               |
+-------------------------+---------------------+
| version                 | 5.6.16-log          |
| version_comment         | Source distribution |
| version_compile_machine | x86_64              |
| version_compile_os      | Linux               |
+-------------------------+---------------------+

@shlomi-noach
Copy link
Contributor

shlomi-noach commented Aug 21, 2017

doesn't even mention aliyun 😮

@exherb
Copy link

exherb commented Aug 29, 2017

aliyun RDS got lots of limits:

  • can't get any global variables
  • no replicate?
  • ...

should I submit a PR to solve this issue? any suggestions?

@shlomi-noach
Copy link
Contributor

@exherb how do you mean "no replicate"?

  • does it support select @@port? (session variable)

I'm unsure how far I will pursue this, this really depends on what aliyun does or doesn't support.

@exherb
Copy link

exherb commented Aug 29, 2017

aliyun RDS replicate is readonly, so it's impossible to migrate on replicate or test on repliacate (migrate on master is possible).

mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| NULL       |
+------------+
1 row in set (0.00 sec)

Is there anyway to skip hostname and port validating? So I could dig more informations.

@shlomi-noach
Copy link
Contributor

Is there anyway to skip hostname and port validating? So I could dig more informations.

partially.

You may use -assume-master-host=myhost:3306 to make gh-ost no search for the master via replication chain, but the select @@global.hostname, @@global.port is currently non-optional, and serves as a sanity check for gh-ost.

@dikang123
Copy link
Author

@exherb I ran the test on the master.

@exherb
Copy link

exherb commented Oct 17, 2017

@dikang123 have you found a solution to this?

@zhangxiaojian
Copy link
Contributor

@dikang123 @exherb This problem is caused by @@global.port = NULL and gh-ost read from Aliyun RDS and try to covert a NULL to int... We will fix it or provide some interface to fix that. Thanks for @shlomi-noach 's analysis

@dikang123
Copy link
Author

@zhangxiaojian any progress?

@zhangxiaojian
Copy link
Contributor

@dikang123 Considering rds's security, we can't expose the port and hostname for now. so We fixed the problem by changing gh-ost's source code, please contact me if you need it . email : zj118228@alibaba-inc.com

@exherb
Copy link

exherb commented Jan 18, 2018

@zhangxiaojian why not submit a PR?

@dikang123
Copy link
Author

@zhangxiaojian thank you, I send you an email by my Work E-mail : zhukang@dianwoba.com

@shlomi-noach
Copy link
Contributor

so We fixed the problem by changing gh-ost's source code, please contact me if you need it

I'll be grateful if you can share the code in public.

@zhangxiaojian
Copy link
Contributor

@shlomi-noach @exherb @dikang123 That's really not a hard work to fix it. The problem is Aliyun RDS return ''NULL" for the variables @@global.port and @@global.hostname , the port is for check and the hostname is for log output. I try to avoid getting them and gh-ost still works.

After an internal discussion, we still can't expose the port and hostname because rds's whole architecture and security, so if gh-ost can week the check some way ?

I'm looking forward to make gh-ost work for Aliyun rds, and that's my diff code, and works with --assume-master-host --assume-rbr --allow-on-master

diff --git a/go/base/utils.go b/go/base/utils.go
index 727bc57..f391a5a 100644
--- a/go/base/utils.go
+++ b/go/base/utils.go
@@ -65,12 +65,14 @@ func StringContainsAll(s string, substrings ...string) bool {
 }

 func ValidateConnection(db *gosql.DB, connectionConfig *mysql.ConnectionConfig) (string, error) {
-	query := `select @@global.port, @@global.version`
+	//query := `select @@global.port, @@global.version`
+	query := `select @@global.version`
 	var port, extraPort int
 	var version string
-	if err := db.QueryRow(query).Scan(&port, &version); err != nil {
+	if err := db.QueryRow(query).Scan(&version); err != nil {
 		return "", err
 	}
+	port = connectionConfig.Key.Port
 	extraPortQuery := `select @@global.extra_port`
 	if err := db.QueryRow(extraPortQuery).Scan(&extraPort); err != nil {
 		// swallow this error. not all servers support extra_port
diff --git a/go/mysql/utils.go b/go/mysql/utils.go
index b670921..c8ce521 100644
--- a/go/mysql/utils.go
+++ b/go/mysql/utils.go
@@ -148,7 +148,7 @@ func GetSelfBinlogCoordinates(db *gosql.DB) (selfBinlogCoordinates *BinlogCoordi
 // GetInstanceKey reads hostname and port on given DB
 func GetInstanceKey(db *gosql.DB) (instanceKey *InstanceKey, err error) {
 	instanceKey = &InstanceKey{}
-	err = db.QueryRow(`select @@global.hostname, @@global.port`).Scan(&instanceKey.Hostname, &instanceKey.Port)
+	//err = db.QueryRow(`select @@global.hostname, @@global.port`).Scan(&instanceKey.Hostname, &instanceKey.Port)
 	return instanceKey, err
 }

@shlomi-noach
Copy link
Contributor

@zhangxiaojian first, thank you!
Second, I see the approach is to ignore port altogether. We can do that conditionally if some, say, --aliyun flag is provided.
Last, just as a side note, I encourage you to use Pull Requests: https://help.github.com/articles/about-pull-requests/, https://help.github.com/articles/creating-a-pull-request/

@zhangxiaojian
Copy link
Contributor

@shlomi-noach That's very nice , Let's fix it !

@shlomi-noach shlomi-noach self-assigned this Jan 18, 2018
@zhangxiaojian zhangxiaojian mentioned this issue Jan 30, 2018
2 tasks
@shlomi-noach
Copy link
Contributor

Given that #541 is merged, can we close this issue?

@xpol
Copy link

xpol commented May 21, 2018

Still got FATAL sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax when using gh-ost 1.0.45 which have included #541.

@shlomi-noach
Copy link
Contributor

@xpol please run with --aliyun-rds

@xpol
Copy link

xpol commented May 21, 2018

I have used all flags suggested in #541:

--allow-on-master
--assume-rbr
--assume-master-host
--aliyun-rds

@shlomi-noach
Copy link
Contributor

@xpol can you please paste output with --debug --stack?

@xpol
Copy link

xpol commented May 24, 2018

@shlomi-noach

gh-ost \
--max-load=Threads_running=25 \
--critical-load=Threads_running=1000 \
--chunk-size=1000 \
--max-lag-millis=1500 \
--user="..." \
--password="..." \
--host=....mysql.rds.aliyuncs.com \
--allow-on-master \
--database="..." \
--table="..." \
--verbose \
--alter="ADD COLUMN user_id int AFTER id" \
--allow-on-master \
--assume-rbr \
--assume-master-host \
--aliyun-rds \
--debug \
--stack
2018-05-24 14:13:53 INFO starting gh-ost 1.0.45
2018-05-24 14:13:53 INFO Migrating `...`.`.....`
2018-05-24 14:13:53 INFO Tearing down inspector
2018-05-24 14:13:53 FATAL sql: Scan error on column index 0: converting driver.Value type <nil> ("<nil>") to a int: invalid syntax
goroutine 1 [running]:
runtime/debug.Stack(0x82, 0x80, 0xc4201f2070)
        /usr/local/go/src/runtime/debug/stack.go:24 +0xa7
runtime/debug.PrintStack()
        /usr/local/go/src/runtime/debug/stack.go:16 +0x22
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.logErrorEntry(0x0, 0x938aa0, 0xc42004e060, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:178 +0xfd
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.Fatale(0x938aa0, 0xc42004e060, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:255 +0x3e
main.main()
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/cmd/gh-ost/main.go:254 +0x1e06

@shlomi-noach
Copy link
Contributor

Wow this error is lost in the logs. It is generated somewhere that is not listed.

Are you sure there's --debug in this invocation? I'm hoping for more debug messages.

@shlomi-noach
Copy link
Contributor

(yes there is --debug, I can see it... Forget me asking)

@shlomi-noach
Copy link
Contributor

Unrelated: no need to define --assume-master-host if you're not providing a value.

@xpol
Copy link

xpol commented May 24, 2018

Removed --assume-master-host:

gh-ost \
--max-load=Threads_running=25 \
--critical-load=Threads_running=1000 \
--chunk-size=1000 \
--max-lag-millis=1500 \
--user="..." \
--password="..." \
--host=....mysql.rds.aliyuncs.com \
--allow-on-master \
--database="pap" \
--table="mytable" \
--verbose \
--alter="ADD COLUMN user_id int AFTER id" \
--allow-on-master \
--assume-rbr \
--aliyun-rds \
--debug \
--stack
2018-05-24 14:35:34 INFO starting gh-ost 1.0.45
2018-05-24 14:35:34 INFO Migrating `...`.`...`
2018-05-24 14:35:34 INFO connection validated on xxx.mysql.rds.aliyuncs.com:3306
2018-05-24 14:35:34 INFO User has REPLICATION CLIENT, REPLICATION SLAVE privileges, and has ALL privileges on `mydb`.*
2018-05-24 14:35:34 INFO binary logs validated on xxx.mysql.rds.aliyuncs.com:3306
2018-05-24 14:35:34 INFO Inspector initiated on xxx.mysql.rds.aliyuncs.com:3306, version 5.6.16-log
2018-05-24 14:35:34 INFO Table found. Engine=InnoDB
2018-05-24 14:35:34 DEBUG Estimated number of rows via STATUS: 31885496
2018-05-24 14:35:34 DEBUG Validated no foreign keys exist on table
2018-05-24 14:35:34 DEBUG Validated no triggers exist on table
2018-05-24 14:35:34 INFO Estimated number of rows via EXPLAIN: 31885496
2018-05-24 14:35:34 DEBUG Potential unique keys in mytable: [PRIMARY (auto_increment): [id]; has nullable: false idx_aid_and_bid: [aid bid]; has nullable: false]
2018-05-24 14:35:34 INFO Recursively searching for replication master
2018-05-24 14:35:34 DEBUG Looking for master on xxx.mysql.rds.aliyuncs.com:3306
2018-05-24 14:35:34 DEBUG Master of xxx.mysql.rds.aliyuncs.com:3306 is 10.x.x.x:3010
2018-05-24 14:35:34 DEBUG Looking for master on 10.x.x.x:3010
2018-05-24 14:36:37 ERROR dial tcp 10.x.x.x:3010: getsockopt: connection timed out
goroutine 1 [running]:
runtime/debug.Stack(0x56, 0xc0, 0xc42001e1c0)
        /usr/local/go/src/runtime/debug/stack.go:24 +0xa7
runtime/debug.PrintStack()
        /usr/local/go/src/runtime/debug/stack.go:16 +0x22
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.logErrorEntry(0x2, 0x938e20, 0xc420082b40, 0xc420045758, 0xc420082b40)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:178 +0xfd
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.Errore(0x938e20, 0xc420082b40, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:224 +0x3e
github.com/github/gh-ost/vendor/github.com/outbrain/golib/sqlutils.QueryRowsMap(0xc420190140, 0x7930f6, 0x11, 0xc420045810, 0x0, 0x0, 0x0, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/sqlutils/sqlutils.go:209 +0x132
github.com/github/gh-ost/go/mysql.GetMasterKeyFromSlaveStatus(0xc420178280, 0x0, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/mysql/utils.go:89 +0x17b
github.com/github/gh-ost/go/mysql.GetMasterConnectionConfigSafe(0xc420178280, 0xc420045a40, 0xc420045900, 0xc42025c0c8, 0x0, 0xc4201be230)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/mysql/utils.go:123 +0xc0
github.com/github/gh-ost/go/mysql.GetMasterConnectionConfigSafe(0xc420058500, 0xc420045a40, 0xc4201e8300, 0x0, 0xc4201e8390, 0xc4201f60f0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/mysql/utils.go:144 +0x48e
github.com/github/gh-ost/go/logic.(*Inspector).getMasterConnectionConfig(0xc42010a5e0, 0x0, 0x0, 0xc420045b30)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/logic/inspect.go:756 +0xba
github.com/github/gh-ost/go/logic.(*Migrator).initiateInspector(0xc420128090, 0x7b9720, 0xc420128090)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/logic/migrator.go:732 +0x144
github.com/github/gh-ost/go/logic.(*Migrator).Migrate(0xc420128090, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/logic/migrator.go:338 +0x375
main.main()
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/cmd/gh-ost/main.go:251 +0x1d5c
2018-05-24 14:36:37 INFO Tearing down inspector
2018-05-24 14:36:37 FATAL dial tcp 10.x.x.x:3010: getsockopt: connection timed out
goroutine 1 [running]:
runtime/debug.Stack(0x56, 0xc0, 0xc42001e2c0)
        /usr/local/go/src/runtime/debug/stack.go:24 +0xa7
runtime/debug.PrintStack()
        /usr/local/go/src/runtime/debug/stack.go:16 +0x22
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.logErrorEntry(0x0, 0x938e20, 0xc420082b40, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:178 +0xfd
github.com/github/gh-ost/vendor/github.com/outbrain/golib/log.Fatale(0x938e20, 0xc420082b40, 0x0, 0x0)
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/vendor/github.com/outbrain/golib/log/log.go:255 +0x3e
main.main()
        /Users/shlomi-noach/dev/go/src/github.com/github/gh-ost/go/cmd/gh-ost/main.go:254 +0x1e06

@xpol
Copy link

xpol commented May 24, 2018

I guess i should add --assume-master-host=xxx.mysql.rds.aliyuncs.com, and seems works (not add --execute yet):

@zhangxiaojian
Copy link
Contributor

@xpol what's your rds instance version ? 5.6 or 5.7 ?

@zhangxiaojian
Copy link
Contributor

Yes, need --assume-master-host following the instance name.

@zhangxiaojian
Copy link
Contributor

By the way, @shlomi-noach I have written an article about gh-ost in our teem blog, http://mysql.taobao.org/monthly/2018/05/ , sorry in chinese.. I think we can update the gh-ost's doc to show how it works now. What's your opinion ?

@shlomi-noach
Copy link
Contributor

I think we can update the gh-ost's doc to show how it works now. What's your opinion ?

Yes please!

@xpol
Copy link

xpol commented May 24, 2018

@zhangxiaojian MySQL: 5.6

@dikang123
Copy link
Author

should I close this issue? @shlomi-noach @xpol @zhangxiaojian

@shlomi-noach
Copy link
Contributor

Thank you all! Issue is closed and aliyun RDS is supported.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants