MySQL InnoDB和MySQL复制

InnoDB和MySQL复制
MySQL复制适用于InnoDB表和MyISAM表。当从节点上的存储引擎与主节点上的原始存储引擎不同时,也可以使用复制。例如,用户可以将对主节点上的InnoDB表的修改复制到从节点上的MyISAM表。

在主服务器上失败的事务完全不会影响复制。MySQL复制基于二进制日志,MySQL在其中写入修改数据的SQL语句。一个失败的事务(例如,因为违反了外键,或者因为回滚)不会被写入二进制日志,因此它不会被发送到从服务器。

复制和级联
只有当共享外键关系的表同时在主从上使用InnoDB时,主上InnoDB表的级联操作才会在从上复制。无论使用基于语句的复制还是基于行的复制,都是如此。假设已经启动了复制,然后使用下面的create TABLE语句在master上创建了两个表:

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存储引擎,并且外键选项会被忽略。现在我们向master上的表中插入一些行:

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存储引擎在内部处理的,这意味着没有任何更改被记录下来。

发表评论

电子邮件地址不会被公开。