我们可以看到底层数据在主节点和从节点中的差异,而且SQL命令似乎会把数据带入更加一致的状态。其中一个选项就是简单地启动从节点,并观察是否有一些反常的不能解释的情况导致MySQL数据复制意外地停止,你会发现它奇迹般地恢复正常了。在这种情况下,因为我们已经检查了基础表结构和表约束,所以不会产生成功的输出。
SQL_SLAVE_SKIP_COUNTER
一种常见(尽管让人感到沮丧)的方法就是简单地跳过SQL命令,然后移到数据复制流程中的下一个命令。运行下面的SQL语句能够实现该目的:
slave> SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
slave> START SLAVE SQL_THREAD;
使用数据复制状态的进阶验证功能SHOW SLAVE STATUS可以确保错误已经被跳过,如下所示:
slave> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Last_Errno: 0
Last_Error:
...
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
警告
在执行SQL_SLAVE_SKIP_COUNTER命令之前,了解SQL语句为什么失败是非常重要的。因为目前虽然只忽略了一个错误,但是后面的SQL语句很可能再次导致MySQL数据复制停止运行。你认为在跳过多少条SQL语句后才应该引起我们的注意呢?
如你所见,这个错误已经消失。MySQL数据复制正在运行中,而我们也可以回去睡觉了。但这并不是合适的解决方案。而刚刚发生的是,我们引发了主数据库和从数据库中的数据不一致。例如:
master> SELECT COUNT(*) FROM product_comment WHERE user_id=42;
+----------+
| COUNT(*) |
+----------+
| 2 |
+----------+
slave> SELECT COUNT(*) FROM product_comment WHERE user_id=42;
+----------+
| COUNT(*) |
+----------+
| 1 |
+----------+
MySQL数据复制是个非同步过程,并且不会执行表中基础数据的一致性校验和。只要SQL语句是在没有错误的情况下执行完毕,数据复制就会报告成功,而不管有多少行数据受到了影响。在第2章中我们将讨论这些设计特性并将更详细地讨论相关问题。
当在大型拓扑中同时处理多个MySQL实例时,我们可以根据之前的示例改变默认的MySQL提示符。这是通过mysql命令行客户端的如下语句实现的:
mysql> PROMPT slave>
提示
对于更复杂的拓扑,我们建议在MySQL命令行客户端的提示符中使用额外的属性,包括主机(host)、模式和用户等。