导致MySQL数据复制因错误而停止的原因有很多。在第2章我们会探讨更多导致数据复制停止的原因及解决方法。在这种情况下,我们发现表的模式在两台服务器上都不一样。为什么会这样呢?
我们可以确定的是表在主节点上被改动,而不是在从节点上。这里没有足够的审计历史记录来决定为什么执行了这样的操作。这个问题的发生是因为在所有MySQL数据库的应用程序模式中,某个软件的升级并没有正确地完成。下面这条语句是在检查位于主数据库的升级程序时发现的:
master> SET SQL_LOG_BIN=0;
master> ALTER TABLE product_comment
-> DROP INDEX user_id,
-> ADD INDEX (user_id, comment_dt);
master> SET SQL_LOG_BIN=1;
分析和判定这个问题的成因比检查MySQL模式和数据要求做更多的工作,因为我们不可能从任何MySQL日志中判定这种精确的语法。我们需要检查辅助系统日志中的业务流程。这样就可以确定最近运行过修改数据库模式的应用升级程序。
在这段SQL语句中,product_comment表的基本结构被修改了。在这个表中,索引user_id和comment_dt的唯一约束被移除了。因为受SET SQL_LOG_BIN=0这条语句的限制,所以这次修改并没有在从数据库的表中生效。这条语句禁用了MySQL二进制日志中的ALTER命令。说明一下,二进制日志是一个把数据复制事件传送到从节点的沟通渠道。
在大型的数据复制环境下执行ALTER TABLE语句时,有十分充足的理由使用这段语法。在每一台服务器上手动执行一条能绕过MySQL数据复制单线程限制的ALTER TABLE命令,不仅可以尽量保证MySQL服务器的正常运行时间,而且可以避免把只有单线程的MySQL的从节点服务器屏蔽。
如何处理软件升级过程中管理程序已经失效的情况呢?首先,不是所有的服务器都有这个修订程序。其次,从服务器一般应该首先被升级。更重要的是,作为一名时刻待命的DBA,我们很可能没有接到某软件将要升级的通知。还有可能当更新发生时收到了通知,但过了一段时间才发现错误,因此很难把错误和之前发生的更新联系起来。
准确地修正问题
找出为什么表结构存在差异是针对这个问题的有效解决方案。在这种情况下,应该把软件升级应用到从服务器,然后再重启MySQL数据复制。我们还可以选择修改这个表的结构,使其与主节点保持一致。然而,知道某个变化的发生并不能让我们预知另一个可能已经同时发生的变化。找出另外的变化可能会涉及大量工作和停机时间,具体取决于执行模式改变的耗时。
这个问题的结果强调了额外地检查模式对象的一致性是必要的。MySQL的表、列、触发器和存储过程都可以对数据复制产生影响。根据《Effective MySQL之备份与恢复》中的描述,对象中的常规备份策略能够在对象上收集元数据,并检查之前的版本是否有可检测的差异,这些都是很重要的。在第5章我们会讨论一些有助于判定和修正问题的工具。
提示
一直以来,为我们的数据库对象保留一份副本以用来备份是很重要的。这个过程也可以对数据复制拓扑中服务器之间的非一致性执行额外的有效性检查。