MySQL のステートメントベースレプリケーション(SBR)で、エラーの起きているステートメントの実行を飛ばすには、スレーブで以下の作業を行う
PROMPT>STOP SLAVE PROMPT>SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; # 1 はスキップするステートメントの数 PROMPT>START SLAVE
AWS RDS ではストアドプロシージャ rds_skip_repl_error を呼ぶ
PROMPT> CALL mysql.rds_skip_repl_error;
実行例
MASTER 側で実行すべき CREATE TABLE 文を SLAVE 側で実行し、そのあと MASTER でも実行してしまい、レプリケート時にエラーが発生したケースを考える。
(このようなケースは IF NOT EXISTS で CREATE TABLE するとか SLAVE は READ-ONLY にするとかで回避できるけど)
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.1.2.3
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000440
Read_Master_Log_Pos: 2457546
Relay_Log_File: mysqld-relay-bin.002701
Relay_Log_Pos: 2448325
Relay_Master_Log_File: mysql-bin.000440
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1050
Last_Error: Error 'Table 'table_name' already exists' on query. Default database: 'database_name'. Query: 'CREATE TABLE `table_name` (
`id` int(11) NOT NULL,
...[snip]
)'
Skip_Counter: 0
Exec_Master_Log_Pos: 2448180
Relay_Log_Space: 2457890
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1050
Last_SQL_Error: Error 'Table 'table_name' already exists' on query. Default database: 'database_name'. Query: 'CREATE TABLE `table_name` (
`id` int(11) NOT NULL,
...[snip]
)'
1 row in set (0.00 sec)
CREATE TABLE の実行に失敗し、SLAVE_SQL_Running, Last_Error, Last_SQL_Error あたりからエラーが起きていることがわかる
SQL_SLAVE_SKIP_COUNTER で問題のステートメントを 1 文だけスキップする。
mysql> STOP SLAVE; Query OK, 0 rows affected (0.00 sec) mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; Query OK, 0 rows affected (0.00 sec) mysql> START SLAVE; Query OK, 0 rows affected (0.00 sec)
レプリケーションエラーが起きていないことを確認
mysql> SHOW SLAVE STATUS \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.1.2.3
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000440
Read_Master_Log_Pos: 2459563
Relay_Log_File: mysqld-relay-bin.002702
Relay_Log_Pos: 251
Relay_Master_Log_File: mysql-bin.000440
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 2459563
Relay_Log_Space: 2460009
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
1 row in set (0.00 sec)
References
- High Performance MySQL, 3rd Edition, Replication Problems and Solutions(pp.495)
- http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Appendix.MySQL.CommonDBATasks.html#Appendix.MySQL.CommonDBATasks.SkipError