GA

2020/02/18

InnoDB ClusterはPKがないテーブルに対する更新を "ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin." のエラーにする

TL;DR

  • InnoDB Cluster(というかGroup Replication)環境で ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin. と言われたら、テーブルにPRIMARY KEYがあるかどうかを疑ってみても良いかも
  • InnoDB Cluster環境に mysqlslap --auto-generate-sql を叩き込もうとしたら気が付いた
  • このエラーメッセージを使っているのはMySQL 8.0.19現在ではGroup Replicationくらいだけれど、このエラーを返すインターフェイス自体は汎用的に作られているので将来は変わる鴨

InnoDB Clusterで遊ぼうと テキトーにMySQL ShellでInnoDB Clusterを作って mysqlslap を叩いたらこれ。
$ mysqlslap80 -P3306 -h127.0.0.1 -uroot --auto-generate-sql --auto-generate-sql-execute-number=10000 --auto-generate-sql-load-type=l
/usr/mysql/8.0.19/bin/mysqlslap: Cannot run query INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL') ERROR : The table does not comply with the requirements by an external plugin.
前にも同じエラーに当たったことがあるような気がしつつ、取り敢えず手で叩いても同じエラーになるかどうかをかくにn
$ mysql80 -P3306 -h127.0.0.1 -uroot

mysql80 52> use mysqlslap
Database changed

mysql80 52> show tables;
+---------------------+
| Tables_in_mysqlslap |
+---------------------+
| t1                  |
+---------------------+
1 row in set (0.03 sec)

mysql80 52> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `intcol1` int DEFAULT NULL,
  `charcol1` varchar(128) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
この時点でオチに気が付いてしまった。PRIMARY KEYがない。
mysql80 52> INSERT INTO t1 VALUES (1804289383,'mxvtvmC9127qJNm06sGB8R92q2j7vTiiITRDGXM9ZLzkdekbWtmXKwZ2qG1llkRw5m9DHOFilEREk3q7oce8O3BEJC0woJsm6uzFAEynLH2xCsw1KQ1lT4zg9rdxBL');
ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.

$ perror 3098
MySQL error code MY-003098 (ER_BEFORE_DML_VALIDATION_ERROR): The table does not comply with the requirements by an external plugin.
エラーコード的には Before DML Vlidation Error らしいので、Group Replicationに限らず返す ここのフック を通れば同じエラーが返る可能性はある。
というか、テストスイートの中に replication_observers_example_before_dml とかいうのがあってその中でこのエラーを期待しているらしいので、レプリケーションプラグイン全般で使うことを想定しているのであろう、たぶん。
$ grep -r ER_BEFORE_DML_VALIDATION_ERROR
sql/sql_base.cc:  ER_BEFORE_DML_VALIDATION_ERROR
sql/sql_base.cc:  if (out_value) my_error(ER_BEFORE_DML_VALIDATION_ERROR, MYF(0));
Binary file GRTAGS matches
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
mysql-test/suite/rpl/t/rpl_replication_observers_example_before_dml.test:--error ER_BEFORE_DML_VALIDATION_ERROR
^C
sql_require_primary_key と違って分かりやすいエラーが返るわけではないことにだけ注意。
mysql80 20> SELECT @@session.sql_require_primary_key;
+-----------------------------------+
| @@session.sql_require_primary_key |
+-----------------------------------+
|                                 1 |
+-----------------------------------+
1 row in set (0.00 sec)

mysql80 20> CREATE TABLE t3 (num int);
ERROR 3750 (HY000): Unable to create or change a table without a primary key, when the system variable 'sql_require_primary_key' is set. Add a primary key to the table or unset this variable to avoid this message. Note that tables without a primary key can cause performance problems in row-based replication, so please consult your DBA before changing this setting.
いないとは思うけれど、InnoDB Clusterに mysqlslap --auto-generate-sql を叩き込みたい人は --auto-generate-sql-guid-primary オプションを足せばPRIMARY KEY用のカラムを作るのでちゃんと通るようになるますよ。
$ mysqlslap80 -P3306 -h127.0.0.1 -uroot --auto-generate-sql --auto-generate-sql-execute-number=10000 --auto-generate-sql-load-type=l --auto-generate-sql-guid-primary
Benchmark
        Average number of seconds to run all queries: 19.517 seconds
        Minimum number of seconds to run all queries: 19.517 seconds
        Maximum number of seconds to run all queries: 19.517 seconds
        Number of clients running queries: 1
        Average number of queries per client: 10000

0 件のコメント :

コメントを投稿