MySQL中slaave_exec_modeパラメータ詳細


今日はなんとなくパラメータslaaveを見ました。exec_modeはマニュアルの説明から、このパラメータはMySQLコピーと関連しており、動的に修正できる変数であり、デフォルトはSTRICTモード(厳密モード)であり、オプション値はIDEMPOTENTモード(べき乗などのモード)があります。IDEMPOTENTモードに設定すると、ライブラリから1032(ライブラリから存在しないキー)と1062(重複キーは、メインキーまたは固有キーが必要)のエラーを回避でき、このモードはROW EVENTのbinlogsモードでのみ有効となり、STATENT EVENTのbinlogsモードでは無効となる。IDEM POTENTモードは主にマルチマスターコピーとNDB CLUSTERの場合に使用されますが、他の場合は使用を推奨しません。上記の説明から、このパラメータのライブラリに指定されたエラーをスキップさせるという問題が来ました。
1:和 sqlslaave.スカイプカウンセラーのメリットは何ですか?
2:slaave-skyp-errors=N比と、何かメリットがありますか?
この2つの問題を持って、関連するテストと説明を行います。 
環境:
MySQLバージョン:Percenna MySQL 5.7
コピーモード:ROW、GTIDがオープンしていません。
テスト:
①1062エラー:Could not execute…event on table db.x;Duplicate entry'xx'for key'PRIMARY'Error_code:1062;
主従上のテストテーブル構造:

CREATE TABLE `x` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
主従上の表の記録:
M:

select * from x;
+----+
| id |
+----+
| 2 |
| 3 |
+----+
2 rows in set (0.01 sec)
S:

select * from x;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)
主従上の表の記録はもともと違っています。主にid=1の記録が足りません。
この時上からのslaave_exec_modeはデフォルトのSTRICTモードです。

show variables like 'slave_exec_mode';
+-----------------+--------+
| Variable_name  | Value |
+-----------------+--------+
| slave_exec_mode | STRICT |
+-----------------+--------+
1 row in set (0.00 sec) 
Mにおけるbinlogsパターンは、

show variables like 'binlog_format';                                                      +---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW  |
+---------------+-------+
1 row in set (0.00 sec)
Mで実行:

insert into x values(1),(4),(5);
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
上からすでにID=1の記録が存在しているので、このときコピーから1062のエラーが報告されました。

Last_SQL_Errno: 1062
Last_SQL_Error: Could not execute Write_rows event on table dba_test.x; Duplicate entry '1' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin-3306.000006, end_log_pos 7124
このエラーが発生した時、みんなの一致したやり方は実行です。slaave.スカイプカウンタ=N。

1、set global sql_slave_skip_counter=N  N    N event
2、     N    1 ,         。
3、   N event ,             ,         
4、  insert/update/delete        event,          
sqlslaave.スカイプcounterの単位は「event」であり、多くの人がこのパラメータの単位は「トランザクション」であると考えていますが、実は間違っています。一つの事務に複数のイベントが含まれていますので、N個をスキップするのも同じ事務の中です。上に1062のエラーが発生した場合、Nを1~4に設定するのは同じです。一つのイベントをスキップします。実行されるSQLのために4つのイベントが生成される:

show binlog events in 'mysql-bin-3306.000006' from 6950;
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| Log_name       | Pos | Event_type | Server_id | End_log_pos | Info              |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| mysql-bin-3306.000006 | 6950 | Query   |    169 |    7026 | BEGIN              |
| mysql-bin-3306.000006 | 7026 | Table_map |    169 |    7074 | table_id: 707 (dba_test.x)   |
| mysql-bin-3306.000006 | 7074 | Write_rows |    169 |    7124 | table_id: 707 flags: STMT_END_F |
| mysql-bin-3306.000006 | 7124 | Xid    |    169 |    7155 | COMMIT /* xid=74803 */     |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
4 rows in set (0.00 sec)
このエラーを処理する方法は以下の通りです。
1:skyp_slaavesql.slaave.スカイプカウンタ

stop slave;                                                                   Query OK, 0 rows affected (0.00 sec)
set global sql_slave_skip_counter=[1-4];
Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)
2:設定ファイルでslaave-skyp-errors=1062を指定します。(再起動が必要です。)
この2つの方法は複製を正常にすることができますが、主従データが一致しないように(慎重に使う)、ライブラリからid=4と5の記録を失わせます。そして、第2の方法はデータベースを再起動する必要があります。ここで紹介したslaave_。exec_モデルパラメータが役に立ちます。ライブラリからこのパラメータを設定します。

set global slave_exec_mode='IDEMPOTENT';
Query OK, 0 rows affected (0.00 sec)
stop slave;                                                                   Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)
同様に主上で実行します。

insert into x values(1),(4),(5);
驚きの発見ができます。マスタデータは同期しています。コピー異常はありません。

M:
select * from x;                                                                +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.00 sec)

S:
select * from x;                                                                +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 rows in set (0.01 sec)
上のテストが見られます。パラメータはslaave_に設定されています。exec_mode='IDEM POTENT'はエラーのイベントをスキップすることができます。
②1032エラー:Could not execute…event on table db.x;Can't find record in'x'Err_code:1032;
このエラーの発生はROWモードでのコピーによって、データの整合性に厳しい要求があります。
主従上のテストテーブル構造:

CREATE TABLE `x` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
主従上の表の記録:
M:

select * from x;                                                                +----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+
3 rows in set (0.00 sec)
S:

select * from x;
+----+
| id |
+----+
| 1 |
| 3 |
+----+
2 rows in set (0.00 sec)
主従上の表の記録はもともと一致していません。上からid=2の記録が欠けています。この時上からのslaave_exec_modeはデフォルトのSTRICTモードです。

show variables like 'slave_exec_mode';
+-----------------+--------+
| Variable_name  | Value |
+-----------------+--------+
| slave_exec_mode | STRICT |
+-----------------+--------+
1 row in set (0.00 sec) 
Mにおけるbinlogsパターンは、

show variables like 'binlog_format';                                                      +---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW  |
+---------------+-------+
1 row in set (0.00 sec)
Mで実行:

BEGIN;
INSERT INTO x SELECT 4;
DELETE FROM x WHERE id = 2;
INSERT INTO x SELECT 5;
COMMIT;
上からID=2の記録がないので、このときコピーから1032のエラーが報告されました。

Last_SQL_Errno: 1032
Last_SQL_Error: Could not execute Delete_rows event on table dba_test.x; Can't find record in 'x', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin-3306.000006, end_log_pos 12102
同様に、上のテストで説明した2つの方法はコピーを正常にすることができますが、データも同じです。id=4と5の記録をなくしました。ライブラリからこのパラメータを設定し続けます。

set global slave_exec_mode='IDEMPOTENT';
Query OK, 0 rows affected (0.00 sec)
stop slave;                                                                   Query OK, 0 rows affected (0.00 sec)
start slave;
Query OK, 0 rows affected (0.00 sec)
Mで同じ動作を実行します。

BEGIN;
INSERT INTO x SELECT 4;
DELETE FROM x WHERE id = 2;
INSERT INTO x SELECT 5;
COMMIT;
主従データは同期しています。コピー異常はありません。
注意:slaave_exec_mode='IDEM POTENT'はDDLの動作にべき乗することができず、フィールドの長さが異なることによるエラーをべき乗することもできないなど、例の中のライブラリテーブルのidフィールドタイプintをビギナートに変更します。そして、binlog_だけになります。formatはROWのモードで使用され、1032および1062はべき乗などのモードでのみ使用される。
まとめ:
上記のテストのまとめについて、slaave_に対してexec_modeパラメータは、1062および1032のエラーをスキップし、同じトランザクションにおいて正常なデータ実行に影響を与えない。複数のSQLからなるトランザクションであれば、問題のあるイベントをスキップすることができる。
このパラメータを見てもいいですが、マニュアルでは普通のコピー環境で開くことを勧めないと説明しています。NDB以外の記憶エンジンについては、重複キーエラーとキーなしエラーを安全に無視できると判断した場合のみ、IDEMPOTENTモードを使用するべきである。このパラメータはNBI Custerに対して専門的に設計されており、NBI CusterモードではIDEMPOTENTモードにしか設定できない。自分の応用シーンによって決めます。通常は主従が一致しています。何かのエラーが発生したらエラーを報告しますが、特殊な処理をする時は臨時的に開けてもいいです。
またGTIDモードでのコピーは、sql_slaave.スカイプカウンタはサポートされていません。このモードのコピーは自分でテストできます。