2014年1月22日水曜日

Percona XtraDB Cluster設定中に気付いたwsrep_certify_nonPK

Primary Keyが無いテーブル + Galera Clusterで悲惨な目に なんていうことが昔ありました。

PXC(wsrepの要求なので、Gelara Cluster for MySQL, MariaDB Galera Cluster も同じ)はbinlog_format= ROW が必須パラメーターになっているのでPrimary Keyが無いと悲惨な目に遭うんですが、これを強制的に禁止するオプション(wsrep_certify_nonPK)を発見。

mysql> SELECT @@wsrep_certify_nonPK;
+-----------------------+
| @@wsrep_certify_nonPK |
+-----------------------+
|                     1 |
+-----------------------+
1 row in set (0.00 sec)

デフォルトはON。

mysql> CREATE TABLE d1.t1 ( num INT, val varchar(32) ) Engine= InnoDB;
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO d1.t1 VALUES (1, 'one');
Query OK, 1 row affected (0.00 sec)

mysql> UPDATE d1.t1 SET val= 'eins' WHERE num= 1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM d1.t1;
+------+------+
| num  | val  |
+------+------+
|    1 | eins |
+------+------+
1 row in set (0.00 sec)

mysql> DELETE FROM d1.t1 WHERE num= 1;
Query OK, 1 row affected (0.00 sec)

Primary Keyが無くてもINSERTもUPDATEもDELETEもできる。フツーの動作。

mysql> SET GLOBAL wsrep_certify_nonPK= OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT @@wsrep_certify_nonPK;
+-----------------------+
| @@wsrep_certify_nonPK |
+-----------------------+
|                     0 |
+-----------------------+
1 row in set (0.00 sec)

これをOFFる。と、想像通り、

mysql> INSERT INTO d1.t1 VALUES (1, 'one');
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

容赦なく蹴られるように。
Error 1213のDeadlock found.. が表示されるのは、全ノード間でデータの同期を保証する為の2相コミットっぽい仕組み(実際には2相コミットじゃない)で失敗したから(これをwsrepではCertificationと呼んでいる)で、Local Certification Failure(XA Prepare的なのに失敗)はError 1213 Deadlock found..で返される仕様になっているから。

なお飽くまで"Local" Certification Failureなので、他の(wsrep_certify_nonPK= ONな)ノードでINSERTするとINSERTできる。よって、設定する時は全てに設定しておくこと。


ところでこの動作、MariaDBには標準で無かったっけ? とか思ったけど違った。RBRの時にPkeyが無いテーブルへの更新は拒否する、じゃなくて、RBRの時でPkeyが無いテーブルへの更新でも最適化してスレーブに適用してくれる、という風情らしい。

Row-based replication with no primary key

Perconaがオリジナルだっていうのも知らなかった。

0 件のコメント :

コメントを投稿