MySQL5.6で増えたexplicit_defaults_for_timestamp
あまりぐぐっても出てこなかったので簡単に書いてみる。
MySQL5.5のmy.cnfをそのまま流用してMySQL5.6を起動すると以下のようなメッセージがエラーログファイルに出力される。長いので改行していますが実際は一行。
121104 22:29:57 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
こちらはMySQL 5.6.6から追加されたexplicit_defaults_for_timestampによるもの。
booleanでデフォルトはFALSE(0)。動的変更は不可となります。公式Doc
とりあえずFALSEの状態でtimestamp型のカラムを含むテーブルを作成してみます。
mysql> show global variables like 'explicit_defaults_for_timestamp'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | explicit_defaults_for_timestamp | OFF | +---------------------------------+-------+ 1 row in set (0.00 sec) mysql> use test Database changed mysql> create table test ( update_time timestamp ) ENGINE=InnoDB; Query OK, 0 rows affected (0.09 sec) mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql>
明示的に属性は指定しませんでしたが以下属性が付与されています。これは以前のバージョンと同じ挙動。
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ではmy.cnfを変更し、TRUEとして再起動後、再度作成してみます。
mysql> show global variables like 'explicit_defaults_for_timestamp'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | explicit_defaults_for_timestamp | ON | +---------------------------------+-------+ 1 row in set (0.00 sec) mysql> use test Database changed mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql> drop table test; Query OK, 0 rows affected (0.03 sec) mysql> create table test ( update_time timestamp ) ENGINE=InnoDB; Query OK, 0 rows affected (0.04 sec) mysql> show create table test\G *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `update_time` timestamp NULL DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec) mysql>
今度は属性が付与されません。
エラーログの出力にあるよう、timestamp型の暗黙的なデフォルト値(属性)はそのうち廃止されるようなので今のうちから必要な属性は自分で付与するように気をつけた方が良さそうです。
細々と解説が書いてあるので5.6へバージョンアップする際は念のため挙動が同じか確認した方が良いでしょう。エラーログにWarningが出ても気にしないのであれば当面はFALSEで運用するのもありかと。たぶん以前のバージョンと同じ挙動っぽいですし。
とはいえ早めに廃止されても問題無いようにしておくことが無難かと。
ただ周りに聞くと、なんで今更挙動変えるのー、といった声が聞こえて来たり。長い事使っている人だとデフォルトで付与されるのを前提に考えてたりするのでそうなるんだと思いますが、知らないでいると廃止されたタイミングでちょっと焦るかもしれない…
続・MySQL5.6-rcでmysqlfailoverを試してみた
前回は1台構成で動作を確認したため今回は全て別なサーバで構築したと想定し、動作するか確認しました。
検証環境
- 全てKVMのゲスト環境。CentOS6.3 64bit
- MySQL5.6はRC版を使用(全サーバで3306ポートで起動)
- MySQL Workbenchは5.2.44を使用
- MasterのIPアドレスを192.168.1.237
- Slave1のIPアドレスを192.168.1.238(read_onlyをON)
- Slave2のIPアドレスを192.168.1.240(read_onlyをON)
- mysqlfailoverを実行するのが192.168.1.239
- mysqlfailover用のアカウントとしてfailover@192.168.1.%をALL権限で作成(パスワードもfailoverにしています)
- GRANT ALL PRIVILEGES ON *.* TO 'failover'@'192.168.1.%' IDENTIFIED BY PASSWORD '*略'
レプリケーションユーザについて
何度か検証しましたが、おそらく現状のmysqlfailoverコマンドではレプリケーション用ユーザとしてrepl@192.168.1.%のように%を使うとmysqlfailoverのレプリケーションユーザの存在確認処理でマッチしないため、個別にアカウントを作成する必要があるようです。
そのため、レプリケーションユーザとして以下のように3ユーザ作成しています。
- repl@192.168.1.237
- repl@192.168.1.238
- repl@192.168.1.240
%を使うと必ず動作不可なのかはなんとも言えませんが、今の所%を使って正常動作する方法が分かっていません。
replication.pyの修正
前回replication.pyを修正していましたが、今回も修正しています。ただし修正する箇所を変更して以下のようにしています。
# diff -urN mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py{.20121101,} --- mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py.20121101 2012-09-27 05:50:38.000000000 +0900 +++ mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py 2012-11-01 02:54:42.991980521 +0900 @@ -1077,7 +1077,7 @@ # Build dictionary for the information with column information rows = [] for i in range(0, len(res[0][2:])): - rows.append(res[0][i+2]) + rows.append(res[0][i+1]) self._build_dictionary(rows) return True #
SELECT * FROM mysql.slave_master_infoを行い、値を取る処理でズレが発生しているため、取得段階で適切な位置となるよう修正する方が妥当と考えたためです。
なお、今回はserver.pyは変更していません。
mysqlfailoverの実行
準備が出来た所で動作確認を行います。
今回はfailover用ユーザを作成したため以下のように実行した後、MasterのMySQLを停止します。
# /usr/local/mysql-wb/bin/mysqlfailover \ --master=failover:failover@192.168.1.237 \ --slaves=failover:failover@192.168.1.238,failover:failover@192.168.1.240 \ --candidates=failover:failover@192.168.1.238 \ --log=/tmp/failover.log
MasterのMySQL停止後のコンソール出力とかは以下のように。一部欠けたので後日補完します。
Failover starting in 'auto' mode... # Candidate slave 192.168.1.238:3306 will become the new master. # Preparing candidate for failover. # Creating replication user if it does not exist. # Stopping slaves. # Performing STOP on all slaves. # Switching slaves to new master. # Starting slaves. # Performing START on all slaves. /tmp/failover.logへの出力 2012-11-01 03:12:53 AM INFO Master may be down. Waiting for 3 seconds. 2012-11-01 03:12:56 AM INFO Cannot reconnect to master. 2012-11-01 03:12:59 AM CRITICAL Master is confirmed to be down or unreachable. 2012-11-01 03:12:59 AM INFO Failover starting in 'auto' mode... 2012-11-01 03:12:59 AM INFO Candidate slave 192.168.1.238:3306 will become the new master. 2012-11-01 03:12:59 AM INFO Preparing candidate for failover. 2012-11-01 03:13:50 AM INFO Creating replication user if it does not exist. 2012-11-01 03:13:50 AM INFO Stopping slaves. 2012-11-01 03:13:50 AM INFO Performing STOP on all slaves. 2012-11-01 03:13:50 AM INFO Switching slaves to new master. 2012-11-01 03:13:50 AM INFO Starting slaves. 2012-11-01 03:13:50 AM INFO Performing START on all slaves. 2012-11-01 03:14:41 AM INFO Checking slaves for errors. 2012-11-01 03:14:41 AM INFO Failover complete.
切り替え後のmysqlfailoverを実行していたコンソールは以下のように。
MySQL Replication Failover Utility Failover Mode = auto Next Interval = Thu Nov 1 03:16:49 2012 Master Information ------------------ Binary Log File Position Binlog_Do_DB Binlog_Ignore_DB mysql-bin.000002 1396 Replication Health Status +----------------+-------+---------+--------+------------+-----------------------------+ | host | port | role | state | gtid_mode | health | +----------------+-------+---------+--------+------------+-----------------------------+ | 192.168.1.238 | 3306 | MASTER | UP | ON | OK | | 192.168.1.240 | 3306 | SLAVE | UP | ON | SQL thread is not running. | +----------------+-------+---------+--------+------------+-----------------------------+ Q-quit R-refresh H-health G-GTID Lists U-UUIDs L-log entries
Masterへ昇格したMySQLのread_onlyがOFFになることを期待したのですがONのままでした…
failoverユーザはALLなので変更可能だし、まだどこか設定に不備があるのかもしれません。
server.py, topology.pyを見る限りはOFFにしてくれそうな処理があったのでちゃんと動いた場合はOFFにしてくれるのでは無いかと。read_onlyについても上手く修正されるようになったら再度書きたいと思います。
MySQL5.6-rcでmysqlfailoverを試してみた
先日MySQL5.6のRC版がリリースされてMySQL WorkbenchにMHAみたいな事が出来るmysqlfailoverコマンドが追加されたので試してみました。
先に書いてしまうとそのままだとエラーとなり、正常に動作しないため、replication.pyとか変更することで動作しました。
最初の方には過程をダラダラと書いているため、要点だけ見たい方は最後の方まですっ飛ばして下さい。
検証した環境
- KVM上のCentOS6.3 64bit
- MySQL5.6はRC版を使用
- MySQL Workbenchは5.2.44を使用
- MySQL5.6は5670,5671,5672ポートで起動
- Masterは5670、Slaveは5671,5672ポートを使用
ダウンロードとインストール
# wget http://dev.mysql.com/get/Downloads/MySQLGUITools/mysql-workbench-gpl-5.2.44-src.tar.gz/from/http://cdn.mysql.com/ # tar zxf mysql-workbench-gpl-5.2.44-src.tar.gz # cd mysql-workbench-gpl-5.2.44-src/ext/mysql-utilities # python setup.py install --prefix=/usr/local/mysql-wb
全部入れようとするとXとか必要なのでコマンドだけインストール。
prefix指定するとmysqlfailover実行時にライブラリ見つからないよと怒られるので適宜exportする。
# export PYTHONPATH=/usr/local/mysql-wb/lib/python2.6/site-packages
mysqlfailoverを使う場合は5.6から追加されたGlobal Transaction IDを使用する、またmaster.infoとかをテーブルに保存する必要があるのでmy.cnfに以下内容を設定する。
log-bin=mysql-bin log-slave-updates gtid-mode=ON disable-gtid-unsafe-statements master_info_repository=TABLE relay_log_info_repository=TABLE report_host=mysql-5.6-5670 report_port=5670
report_host, report_portはMaster, Slaveでそれぞれ別な物を設定する。
disable-gtid-unsafe-statementsを設定するとトランザクションが使えないテーブル(MyISAMとか)への更新が以下のようにエラーになるためInnoDBのみで使用する事になりそうです。
ERROR 1785 (HY000): Updates to non-transactional tables are forbidden when DISABLE_GTID_UNSAFE_STATEMENTS = 1.
ただ、GRANT文なんかは使えるのでInnoDBしか使わない前提であればそんなに気にならなそうです。
レプリケーション用アカウント(show grants forの結果)
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'127.0.0.1' IDENTIFIED BY PASSWORD '*省略'
なんでこんなの書いたかというと、127.0.0.1のせいではまったから…
ということで実際に動かしてみる。オプションについては--help等でご確認下さい。
# /usr/local/mysql-wb/bin/mysqlfailover \ --master=root@127.0.0.1:5670 \ --slaves=root@127.0.0.1:5671,root@127.0.0.1:5672 \ --candidates=root@127.0.0.1:5671 \ --log=/tmp/failover.log
実行すると以下のような表示になります。感覚的にはtopコマンド近いかと。
MySQL Replication Failover Utility Failover Mode = auto Next Interval = Tue Oct 30 01:05:03 2012 Master Information ------------------ Binary Log File Position Binlog_Do_DB Binlog_Ignore_DB mysql-bin.000005 455 Replication Health Status +------------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +------------+-------+---------+--------+------------+---------+ | 127.0.0.1 | 5670 | MASTER | UP | ON | OK | | 127.0.0.1 | 5671 | SLAVE | UP | ON | OK | | 127.0.0.1 | 5672 | SLAVE | UP | ON | OK | +------------+-------+---------+--------+------------+---------+ Q-quit R-refresh H-health G-GTID Lists U-UUIDs L-log entries
この状態でMasterを停止します。するとmysqlfailoverを実行していたコンソールが以下のように止まってしまい、フェールオーバーしません。
Failover starting in 'auto' mode... # Candidate 127.0.0.1:5671 does not meet the requirements. WARNING: None of the candidates was the best slave. No candidate found for failover. ERROR: No candidate found for failover. 以下は/tmp/failover.logへの出力 2012-10-30 01:20:28 AM INFO Master may be down. Waiting for 3 seconds. 2012-10-30 01:20:31 AM INFO Cannot reconnect to master. 2012-10-30 01:20:34 AM CRITICAL Master is confirmed to be down or unreachable. 2012-10-30 01:20:34 AM INFO Failover starting in 'auto' mode... 2012-10-30 01:20:34 AM WARNING Candidate 127.0.0.1:5671 does not meet the requirements. 2012-10-30 01:20:34 AM WARNING WARNING: None of the candidates was the best slave. 2012-10-30 01:20:34 AM CRITICAL No candidate found for failover. 2012-10-30 01:20:34 AM INFO Unregistering instance on master. 2012-10-30 01:20:34 AM CRITICAL No candidate found for failover.
この状態でMasterのMySQLを起動して再度実行すると以下のようなメッセージが表示されます。
Multiple instances of failover console found for master 127.0.0.1:5670. If this is an error, restart the console with --force. Failover mode changed to 'FAIL' for this instance.
そのため、気になる人は事前にmysql.failover_consoleテーブルをdeleteして空にしましょう。
mysql> use mysql Database changed mysql> select * from failover_console; +-----------+------+ | host | port | +-----------+------+ | 127.0.0.1 | 5670 | +-----------+------+ 1 row in set (0.00 sec) mysql> delete from failover_console; Query OK, 1 row affected (0.01 sec) mysql> select * from failover_console; Empty set (0.00 sec) mysql>
もう少し詳細な情報が欲しいので-vオプションを追加します。
# /usr/local/mysql-wb/bin/mysqlfailover \ --master=root@127.0.0.1:5670 \ --slaves=root@127.0.0.1:5671,root@127.0.0.1:5672 \ --candidates=root@127.0.0.1:5671 \ --log=/tmp/failover.log \ -v
先ほどの画面にも情報が増えますが省略します。再度Masterを停止する。以下その際の出力内容。
Failover starting in 'auto' mode... # Checking eligibility of slave 127.0.0.1:5671 for candidate. # GTID_MODE=ON ... Ok # Replication user exists ... FAIL # Candidate 127.0.0.1:5671 does not meet the requirements. WARNING: None of the candidates was the best slave. # Checking eligibility of slave 127.0.0.1:5671 for candidate. # GTID_MODE=ON ... Ok # Replication user exists ... FAIL # Checking eligibility of slave 127.0.0.1:5672 for candidate. # GTID_MODE=ON ... Ok # Replication user exists ... FAIL No candidate found for failover. ERROR: No candidate found for failover. 以下同様にfailover.logへの出力。 2012-10-30 01:27:17 AM INFO Master may be down. Waiting for 3 seconds. 2012-10-30 01:27:20 AM INFO Cannot reconnect to master. 2012-10-30 01:27:23 AM CRITICAL Master is confirmed to be down or unreachable. 2012-10-30 01:27:23 AM INFO Failover starting in 'auto' mode... 2012-10-30 01:27:23 AM INFO Checking eligibility of slave 127.0.0.1:5671 for candidate. 2012-10-30 01:27:23 AM INFO GTID_MODE=ON ... Ok 2012-10-30 01:27:23 AM WARNING Replication user exists ... FAIL 2012-10-30 01:27:23 AM WARNING Candidate 127.0.0.1:5671 does not meet the requirements. 2012-10-30 01:27:23 AM WARNING WARNING: None of the candidates was the best slave. 2012-10-30 01:27:23 AM INFO Checking eligibility of slave 127.0.0.1:5671 for candidate. 2012-10-30 01:27:23 AM INFO GTID_MODE=ON ... Ok 2012-10-30 01:27:23 AM WARNING Replication user exists ... FAIL 2012-10-30 01:27:23 AM INFO Checking eligibility of slave 127.0.0.1:5672 for candidate. 2012-10-30 01:27:23 AM INFO GTID_MODE=ON ... Ok 2012-10-30 01:27:23 AM WARNING Replication user exists ... FAIL 2012-10-30 01:27:23 AM CRITICAL No candidate found for failover. 2012-10-30 01:27:23 AM INFO Unregistering instance on master. 2012-10-30 01:27:23 AM CRITICAL No candidate found for failover.
"Replication user exists ... FAIL"あたりから絞っていく。該当のソースはtopology.pyのこの辺り。
660 # Check replication user - must exist with correct privileges 661 user, passwd = slave.get_rpl_user() 662 msg = "# Replication user exists ... %s" 663 if user is None or slave.check_rpl_user(user, slave.host) != []: 664 if not self.force: 665 if self.verbose and not quiet: 666 self._report(msg % "FAIL", logging.WARN) 667 return (False, "RPL_USER", 668 "Candidate slave is missing replication user.") 669 else: 670 self._report("Replication user not found but --force used.", 671 logging.WARN) 672 elif self.verbose and not quiet: 673 self._report(msg % "Ok")
パラメータ確認用のコードを追加しながら確認したところ、user, passwdに適切な値が入って来ていない。replication.pyの以下処理が悪そうなことが判明。
1011 def _build_dictionary(self, rows): 1012 """Build the internal dictionary of values. 1013 1014 rows[in] Rows as read from the file or table 1015 """ 1016 for i in range(0, len(rows)): 1017 self.values[_MASTER_INFO_COL[i]] = rows[i]
_MASTER_INFO_COLはソースコードの頭の方で以下のように定義されている。
30 _MASTER_INFO_COL = [ 31 'Master_Log_File', 'Read_Master_Log_Pos', 'Master_Host', 'Master_User', 32 'Master_Password', 'Master_Port', 'Connect_Retry', 'Master_SSL_Allowed', 33 'Master_SSL_CA_File', 'Master_SSL_CA_Path', 'Master_SSL_Cert', 34 'Master_SSL_Cipher', 'Master_SSL_Key', 'Master_SSL_Verify_Server_Cert', 35 'Heartbeat', 'Bind', 'Ignored_server_ids', 'Uuid', 'Retry_count', 36 'SSL_CRL', 'SSL_CRL_Path', 'Enabled_auto_position', 37 ]
若干説明をはぶき気味ですが、iが0からスタートしてしまうとキーと値が1つずれてしまい、
- Master_Userにパスワード
- Master_PasswordにMasterのポート番号
が入ってしまいます。
ということで以下のように修正します。[2011/11/01 追記: 次の日記で修正箇所を変更しています]
# diff -urN mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py{.20121030,} --- mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py.20121030 2012-09-27 05:50:38.000000000 +0900 +++ mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/replication.py 2012-10-30 01:44:07.680981924 +0900 @@ -1014,7 +1014,7 @@ rows[in] Rows as read from the file or table """ for i in range(0, len(rows)): - self.values[_MASTER_INFO_COL[i]] = rows[i] + self.values[_MASTER_INFO_COL[i+1]] = rows[i] def _read_master_info_file(self): #
修正したら再度mysqlfailoverを実行する。ところがまたエラー… ぶっちゃけエラー内容も変化が無い。再び"WARNING Replication user exists ... FAIL"周辺を確認する。
どうやらslave.check_rpl_user(user, slave.host)の戻りがおかしい。ということでこれが定義されているserver.pyの処理を追いかける。537行目のuser_host_existsで失敗してるっぽい。以下該当箇所の抜粋。
537 def user_host_exists(self, user, host_or_ip): (略) 550 res = self.exec_query("SELECT host FROM mysql.user WHERE user = '%s' AND '%s' LIKE host " % (user, host_or_ip))
ここで値を取った所、hostが127.0.0.1であって欲しいのにlocalhostになっていた。正直なんでやねん、とか思いながらも引き続きソースおっかける。すると805行目のcheck_rpl_userで置き換えられてた…
805 def check_rpl_user(self, user, host): (略) 813 814 from mysql.utilities.common.user import User 815 816 errors = [] 817 if host == '127.0.0.1': 818 host = 'localhost'
先に書いた通りレプリケーションユーザはrepl@127.0.0.1で作成しているのでrepl@localhostな感じで存在確認されても存在しないことになる。ということで正しいかは分からないけどとりあえずこの処理をコメントアウト。
# diff -urN mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/server.py{.20121030,} --- mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/server.py.20121030 2012-09-27 05:50:47.000000000 +0900 +++ mysql-wb/lib/python2.6/site-packages/mysql/utilities/common/server.py 2012-10-30 02:05:54.921983906 +0900 @@ -814,8 +814,8 @@ from mysql.utilities.common.user import User errors = [] - if host == '127.0.0.1': - host = 'localhost' + #if host == '127.0.0.1': + # host = 'localhost' result = self.user_host_exists(user, host) if result is None or result == []: errors.append("The replication user %s@%s was not found " #
ということで今度こそとmysqlfailoverを再実行すると、ようやく上手く動作しました。コンソールの出力とログの出力。
Failover starting in 'auto' mode... # Checking eligibility of slave 127.0.0.1:5671 for candidate. # GTID_MODE=ON ... Ok # Replication user exists ... Ok # Candidate slave 127.0.0.1:5671 will become the new master. # Preparing candidate for failover. # LOCK STRING: FLUSH TABLES WITH READ LOCK # Connecting candidate to 127.0.0.1:5672 as a master to retrieve unprocessed GTIDs. # Change master command for 127.0.0.1:5671 # CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_USER = 'repl', MASTER_PASSWORD = 'パスワード, MASTER_PORT = 5672, MASTER_AUTO_POSITION=1 # UNLOCK STRING: UNLOCK TABLES # Waiting for candidate to catch up to slave 127.0.0.1:5672. # Slave 127.0.0.1:5671: # QUERY = SELECT SQL_THREAD_WAIT_AFTER_GTIDS('D7C09068-1DC7-11E2-BFB8-00163E6535F2:1-36', 3) # Return Code = 0 # Creating replication user if it does not exist. # Stopping slaves. # Performing STOP on all slaves. # Executing stop on slave 127.0.0.1:5671 Ok # Executing stop on slave 127.0.0.1:5672 Ok # Switching slaves to new master. # Change master command for 127.0.0.1:5671 # CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_USER = 'repl', MASTER_PASSWORD = 'パスワード', MASTER_PORT = 5671, MASTER_AUTO_POSITION=1 # Change master command for 127.0.0.1:5672 # CHANGE MASTER TO MASTER_HOST = '127.0.0.1', MASTER_USER = 'repl', MASTER_PASSWORD = 'パスワード', MASTER_PORT = 5671, MASTER_AUTO_POSITION=1 # Starting slaves. # Performing START on all slaves. # Executing start on slave 127.0.0.1:5672 Ok # Checking slaves for errors. # 127.0.0.1:5672 status: Ok # Failover complete. Failover console will restart in 5 seconds. 以下/tmp/failover.log 2012-10-30 02:12:34 AM INFO Master may be down. Waiting for 3 seconds. 2012-10-30 02:12:37 AM INFO Cannot reconnect to master. 2012-10-30 02:12:40 AM CRITICAL Master is confirmed to be down or unreachable. 2012-10-30 02:12:40 AM INFO Failover starting in 'auto' mode... 2012-10-30 02:12:40 AM INFO Checking eligibility of slave 127.0.0.1:5671 for candidate. 2012-10-30 02:12:40 AM INFO GTID_MODE=ON ... Ok 2012-10-30 02:12:40 AM INFO Replication user exists ... Ok 2012-10-30 02:12:40 AM INFO Candidate slave 127.0.0.1:5671 will become the new master. 2012-10-30 02:12:40 AM INFO Preparing candidate for failover. 2012-10-30 02:12:40 AM INFO Connecting candidate to 127.0.0.1:5672 as a master to retrieve unprocessed GTIDs. 2012-10-30 02:13:31 AM INFO Waiting for candidate to catch up to slave 127.0.0.1:5672. 2012-10-30 02:13:31 AM INFO Creating replication user if it does not exist. 2012-10-30 02:13:31 AM INFO Stopping slaves. 2012-10-30 02:13:31 AM INFO Performing STOP on all slaves. 2012-10-30 02:13:31 AM INFO Executing stop on slave 127.0.0.1:5671 Ok 2012-10-30 02:13:31 AM INFO Executing stop on slave 127.0.0.1:5672 Ok 2012-10-30 02:13:31 AM INFO Switching slaves to new master. 2012-10-30 02:13:31 AM INFO Starting slaves. 2012-10-30 02:13:31 AM INFO Performing START on all slaves. 2012-10-30 02:14:22 AM INFO Executing start on slave 127.0.0.1:5672 Ok 2012-10-30 02:14:22 AM INFO Checking slaves for errors. 2012-10-30 02:14:22 AM INFO 127.0.0.1:5672 status: Ok 2012-10-30 02:14:22 AM INFO Failover complete.
5秒待つとまたtopのような画面になりますが、Master, Slaveが変わっている事がわかります。なお参照するMasterが変更となったSlaveのSQL_THREADは停止した状態となるようです。[2011/11/05追記]START SLAVEしてるのにエラーとなるようなのでどこかおかしいっぽいです。
| host | port | role | state | gtid_mode | health | version | master_log_file | master_log_pos | IO_Thread | SQL_Thread | Secs_Behind | Remaining_Delay | IO_Error_Num | IO_Error | SQL_Error_Num | SQL_Error | Trans_Behind | +------------+-------+---------+--------+------------+-----------------------------+---------------+-------------------+-----------------+------------+-------------+--------------+------------------+---------------+-----------+----------------+---------------------------------------------+---------------+ | 127.0.0.1 | 5671 | MASTER | UP | ON | OK | 5.6.7-rc-log | mysql-bin.000003 | 7319 | | | | | | | | | | | 127.0.0.1 | 5672 | SLAVE | UP | ON | SQL thread is not running. | 5.6.7-rc-log | mysql-bin.000003 | 191 | Yes | No | 0 | No | 0 | | 1593 | Failed during slave workers initialization | 0 | +------------+-------+---------+--------+------------+-----------------------------+---------------+-------------------+-----------------+------------+-------------+--------------+------------------+---------------+-----------+----------------+---------------------------------------------+---------------+
ということで想定通り動作するようになりました。今回は同一のサーバ上で3つのMySQLを起動している環境のため、実運用に近い環境(全部別な物理サーバでMySQLが稼働)ではreplication.pyを修正するだけで動作するのではないかと。後日全部別環境にして動作するか試してみたいと思います。
※初めて書いた日記なので色々適当になっているのでそのうち修正するかもしれません…