MySQL
レプリケーションは、MyISAM
に対して機能するのと同じように
InnoDB
テーブルに機能します。スレーブ上のストレージエンジンがマスタ上の元のストレージエンジンと同じではない場合での方法でレプリケーションを利用することも可能です。たとえば、スレーブ上の
MyISAM
テーブルに、マスタ上の
InnoDB
テーブルへの修正を複製することができます。
マスタに新しいスレーブを設定するには、InnoDB
テーブルの .frm
ファイルと同様に、InnoDB
テーブル領域のコピーとログファイルのコピーを作成し、そのコピーをスレーブに移動させなければいけません。もし
innodb_file_per_table
変数が有効であれば、.ibd
ファイルもコピーする必要があります。これを行うための正しい手順については
項9.6. 「InnoDB
データベースのバックアップと復旧」 を参照してください。
もしマスタか既存スレーブを閉じることができるのであれば、InnoDB
テーブル領域とログファイルの完全なバックアップを取り、それをスレーブの設定のために利用することができます。サーバーを停止させずに新しいスレーブを作成するには、商用の
InnoDB
Hot Backup
ツールを利用することもできます。
MyISAM
テーブルに対してだけ機能する
LOAD TABLE FROM MASTER
ステートメントを利用して
InnoDB
にレプリケーションを設定することはできません。2
つ可能な回避方法があります:
マスタ上のテーブルをダンプし、ダンプファイルをスレーブ内にインポートしてください。
LOAD TABLE
を利用してレプリケーションを設定する前に、tbl_name
FROM MASTERALTER
TABLE
をマスタ上で利用し、そしてあとでマスタテーブルを
tbl_name
ENGINE=MyISAMInnoDB
に変換するために ALTER
TABLE
を利用してください。しかし、定義が損失するのでこれは外部キー制約があるテーブルには利用しないで下さい。
マスタ上で失敗するトランザクションはレプリケーションにまったく影響を与えません。MySQL
レプリケーションは、MySQL がデータを変更する
SQL
ステートメントを書き込むバイナリログに基づいています。失敗するトランザクション
(たとえば、外部キー違反のため、またはロールバックされるため)
はバイナリログに書き込まないので、スレーブに送られません。項8.4.1. 「START
TRANSACTION
、COMMIT
、そして
ROLLBACK
構文」
を参照してください。
レプリケーションと CASCADE
.
マスター上の InnoDB
テーブルのカスケードアクションがスレーブ上で複製されるのは、外部キー関係を共有しているテーブルがマスターとスレーブの両方で
InnoDB
を使用している場合だけです。このことは、ステートメントベース、行ベースのどちらのレプリケーションを使用していても言えることです。たとえば、レプリケーションを開始したあと、マスター上で次の
CREATE TABLE
ステートメントを使って 2
つのテーブルを作成するとします。
CREATE TABLE fc1 ( i INT PRIMARY KEY, j INT ) ENGINE = InnoDB; CREATE TABLE fc2 ( m INT PRIMARY KEY, n INT, FOREIGN KEY ni (n) REFERENCES fc1 (i) ON DELETE CASCADE ) ENGINE = InnoDB;
スレーブでは InnoDB
のサポートが有効になっていないものとします。この場合、スレーブ上でテーブルが作成されますが、その際に
MyISAM
ストレージエンジンが使用され、FOREIGN
KEY
オプションは無視されます。ここで、マスター上でテーブルに何行か挿入します。
master>INSERT INTO fc1 VALUES (1, 1), (2, 2);
Query OK, 2 rows affected (0.09 sec) Records: 2 Duplicates: 0 Warnings: 0 master>INSERT INTO fc2 VALUES (1, 1), (2, 2), (3, 1);
Query OK, 3 rows affected (0.19 sec) Records: 3 Duplicates: 0 Warnings: 0
この時点で次に示すように、マスターとスレーブの両方でテーブル
fc1
に 2
行が格納され、テーブル
fc2
に 3
行が格納されています。
master>SELECT * FROM fc1;
+---+------+ | i | j | +---+------+ | 1 | 1 | | 2 | 2 | +---+------+ 2 rows in set (0.00 sec) master>SELECT * FROM fc2;
+---+------+ | m | n | +---+------+ | 1 | 1 | | 2 | 2 | | 3 | 1 | +---+------+ 3 rows in set (0.00 sec) slave>SELECT * FROM fc1;
+---+------+ | i | j | +---+------+ | 1 | 1 | | 2 | 2 | +---+------+ 2 rows in set (0.00 sec) slave>SELECT * FROM fc2;
+---+------+ | m | n | +---+------+ | 1 | 1 | | 2 | 2 | | 3 | 1 | +---+------+ 3 rows in set (0.00 sec)
次に、マスター上で次の
DELETE
ステートメントを実行するとします。
master> DELETE FROM fc1 WHERE i=1;
Query OK, 1 row affected (0.09 sec)
カスケードにより、マスター上のテーブル
fc2
に格納されている行が 1
件だけになりました。
master> SELECT * FROM fc2;
+---+---+
| m | n |
+---+---+
| 2 | 2 |
+---+---+
1 row in set (0.00 sec)
ところがスレーブ上では、fc1
に対する
DELETE
が実行されても fc2
からは行が削除されないため、このカスケードはスレーブには伝わりません。スレーブの
fc2
のコピーにはまだ、最初に挿入されたすべての行が格納されています。
slave> SELECT * FROM fc2;
+---+---+
| m | n |
+---+---+
| 1 | 1 |
| 3 | 1 |
| 2 | 2 |
+---+---+
3 rows in set (0.00 sec)
こうした違いが生じるのは、カスケード削除が実は
InnoDB
ストレージエンジンによって内部的に処理されているからです。したがって、この変更のロギングは一切行われません。