web-dev-qa-db-ja.com

NDBクラスターはforeign_key_checks = OFFを無視しているようです

MySQLドキュメント によるとローカルforeign_key_checks変数

MySQL Cluster NDB 7.3.2以降、この変数を設定すると、InnoDBテーブルの場合と同じ効果がNDBテーブルに与えられます。以前は、設定は無視され、そのようなチェックはすべて適用されていました(バグ#14095855)。

外部キーを使用して、順序付けされていないInnoDBダンプファイルをインポートできるはずです。

私のNDBバージョン

# ndbd --version
MySQL distrib mysql-5.6.21 ndb-7.3.7, for Linux (x86_64)

しかし、構造体のみのダンプを追加しようとすると、

SET foreign_key_checks=OFF;

--
-- Table structure for table `aclAktion`
--

DROP TABLE IF EXISTS `aclAktion`;
CREATE TABLE `aclAktion` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '',
  `editMask` set('read','write','create','delete','super') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'read,write,create,delete',
  PRIMARY KEY (`id`),
  UNIQUE KEY `aclAktion_uIdx_name` (`name`)
) ENGINE=NDBCLUSTER ROW_FORMAT=DYNAMIC;

--
-- Table structure for table `aclGroup`
--

DROP TABLE IF EXISTS `aclGroup`;

SHOW VARIABLES LIKE 'foreign_key_checks';
CREATE TABLE `aclGroup` (  -- this is line #63 in the dumpfile
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aclRole_id` enum('gast','kunde','owner','owner_boss','red_ext','red_ext_boss','red_int','red_int_boss','verlag_boss','sysop','root') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'gast',
  `numUsers` int(11) NOT NULL DEFAULT '0',
  `name` varchar(64) NOT NULL DEFAULT '',
  `aktiv` tinyint(1) NOT NULL DEFAULT '0',
  `login` tinyint(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`),
  UNIQUE KEY `aclGroup_uIdx_name` (`name`),
  KEY `aclGroup_idx_aclRole_id` (`aclRole_id`),
  CONSTRAINT `aclGroup_fk_aclRole_id` FOREIGN KEY (`aclRole_id`) REFERENCES `aclRole` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=NDBCLUSTER ROW_FORMAT=DYNAMIC;

--
-- Table structure for table `aclRole`
--

DROP TABLE IF EXISTS `aclRole`;
CREATE TABLE `aclRole` (
  `id` enum('gast','kunde','owner','owner_boss','red_ext','red_ext_boss','red_int','red_int_boss','verlag_boss','sysop','root') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'gast',
  `numGroups` int(11) NOT NULL DEFAULT '0',
  `login` tinyint(1) NOT NULL DEFAULT '0',
  `checkNumLogins` tinyint(1) NOT NULL DEFAULT '0',
  `defaultPrivileges` set('read','write','create','delete','super') CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT 'read',
  `beschreibung` varchar(192) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) ENGINE=NDBCLUSTER ROW_FORMAT=DYNAMIC;

エラーが発生します:

ERROR 1215 (HY000) at line 63: Cannot add foreign key constraint

APIノードのエラーログは、NDBが実際に外部キーを正しく処理しようとしていることを示しています

2014-11-03 17:50:05 [NdbApi] INFO     -- Flushing incomplete GCI:s < 10865/8
2014-11-03 17:50:05 [NdbApi] INFO     -- Flushing incomplete GCI:s < 10865/8
2014-11-03 17:50:05 22485 [Note] NDB Binlog: starting log at Epoch 10865/8
2014-11-03 17:50:05 22485 [Note] NDB Binlog: ndb tables writable
2014-11-03 17:50:05 22485 [Note] NDB Binlog: Node: 2, subscribe from node 4, Subscriber bitmask 010
2014-11-03 17:50:05 22485 [Note] NDB Binlog: Node: 3, subscribe from node 4, Subscriber bitmask 010
2014-11-03 17:50:08 22485 [Note] NDB Binlog: Node: 2, unsubscribe from node 4, Subscriber bitmask 00
2014-11-03 17:50:08 22485 [Note] NDB Binlog: Node: 3, unsubscribe from node 4, Subscriber bitmask 00
2014-11-03 17:50:16 22485 [Note] NDB Binlog: Node: 2, subscribe from node 4, Subscriber bitmask 010
2014-11-03 17:50:16 22485 [Note] NDB Binlog: Node: 3, subscribe from node 4, Subscriber bitmask 010
2014-11-03 18:01:29 22485 [Note] NDB Binlog: CREATE TABLE Event: REPL$database/aclAktion
2014-11-03 18:01:29 22485 [Note] NDB Binlog: logging ./database/aclAktion (UPDATED,USE_WRITE)
2014-11-03 18:01:29 22485 [Note] NDB FK: Created mock table 'NDB$FKM_20_0_aclRole' referenced by 'aclGroup'

Ndbノードにエラーはありません

どうやら、変数foreign_key_checks = offはここでは無視されます。ヒントはありますか?

2
Michel Feldheim

モックテーブルは、ずっと前にmysqldumpが古いバージョンのMySQLにロードされた方法でした

このような問題が存在しました

その最後の行を参照してください

2014-11-03 18:01:29 22485 [Note] NDB FK: Created mock table 'NDB$FKM_20_0_aclRole' referenced by 'aclGroup'

Mysqldumpsはデフォルトでアルファベット順になっているため、外部キー関係の親テーブルが子テーブルの前ではなく後に表示される場合があります。結果として、モックテーブルは、aclGroupテーブルを採用する親を持つように作成されました。

子は同じ列の同じ親への複数の外部キー参照を持つことができないため、NDBはそれを無視し、それでもforeign_key_checks=OFFを強制しようとします。

内部的には、これはNDBストレージエンジンがafterCREATE TABLE aclGroupで実行する必要があることです。

ALTER TABLE aclGroup DROP CONSTRAINT aclGroup_fk_aclRole_id;
DROP TABLE `NDB$FKM_20_0_aclRole`;
DROP TABLE IF NOT EXISTS aclRole;
CREATE TABLE aclRole (...) ENGINE=NDBCLUSTER;
ALTER TABLE aclGroup ADD CONSTRAINT aclGroup_fk_aclRole_id
FOREIGN KEY (`aclRole_id`) REFERENCES `aclRole` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;    

mysqldumpがソートされていない外部キー制約のダンプ を見ると、これはずっと前のInnoDBの機能要求であったことがわかります。この同じ機能は、おそらくNDBでは適切に実装されていません。スクリプトでNDBCLUSTERInnoDBに変更して実行すると、問題なく動作するはずです。

したがって、はい、foreign_key_checks=OFFは無視されます。

1
RolandoMySQLDBA