在主库上,可以使用SHOW MASTER STATUS命令来查看当前主库的二进制日志位置和配置。还可以查看主库当前有哪些二进制日志是在磁盘上的:
该命令用于给PURGE MASTER LOGS命令决定使用哪个参数。另外还可以通过SHOW BINLOG EVENTS 来查看复制事件。例如,在运行前一个命令后,我们在另一个不曾使用 过的服务器.上创建一个表,因为知道这是唯一改变数据的语句,而且也知道语句在二进制日志中的偏移量是13634,所以我们可以看到如下内容:
一个比较普遍的问题是如何监控备库落后主库的延迟有多大。虽然SHOW SLAVE STATUS 输出的Seconds_ behind_ master列理论上显示了备库的延时,但由于各种各样的原因, 并不总是准确的:
解决这些问题的办法是忽略Seconds_behind_master 的值,并使用-些可以直接观察和 衡量的方式来监控备库延迟。最好的解决办法是使用heartbeat record,这是-一个在主库上会每秒更新一次的时间戳。为了计算延时,可以直接用备库当前的时间戳减去心跳记录的值。这个方法能够解决刚刚我们提到的所有问题,另外一个额外的好处是我们还可以通过时间戳知道备库当前的复制状况。包含在PerconaToolkit里的pt-heartbeat脚本是“复制心跳”最流行的一种实现。
心跳还有其他好处,记录在二进制日志中的心跳记录拥有许多用途,例如在一些很难解决的场景下可以用于灾难恢复。
刚刚所描述的几种延迟指标都不能表明备库需要多长时间才能赶上主库。这依赖于许多因素,例如备库的写入能力以及主库持续写入的次数。
在理想情况下,备库和主库的数据应该是完全一样的。但事实上备库可能发生错误并导致数据不一致。即使没有明显的错误,备库同样可能因为MySQL自身的特性导致数据不一致,例如MySQL的Bug网络中断、服务器崩溃,非正常关闭或者其他一些错误。
按照经验来看,主备一致应该是一种规范,而不是例外,也就是说,检查你的主备一致性应该是一个日常工作,特别是当使用备库来做备份时尤为重要,因为你肯定不希望从一个已经损坏的备库里获得备份数据。
MySQL并没有内建的方法来比较一台服务器与别的服务器的数据是否相同。它提供了一些组件来为表和数据生成校验值,例如CHECKSUM TABLE。 但当复制正在进行时,这种方法是不可行的。
Percona Toolkit 里的pt-table-checksum能够解决上述几个问题。其主要特性是用于确认 备库与主库的数据是否一致。工作方式是通过在主库上执行INSERT.. .SELECT查询。
这些查询对数据进行校验并将结果插人到一个表中。这些语句通过复制传递到备库,并在备库执行一遍,然后可以比较主备上的结果是否一样。由于该方法是通过复制工作的, 它能够给出一致的结果而无须同时把主备上的表都锁上。
通常情况下可以在主库上运行该工具,参数如下:
该命令将检查所有的表,并将结果插入到test. checksum表中。当查询在备库执行完后,就可以简单地比较主备之间的不同了。pt-table-checksum能够发现服务器所有的备库,在每台备库上运行查询,并自动地输出结果。
在你的职业生涯中,也许会不止一次需要去处理未被同步的备库。可能是使用校验工具发现了数据不一致,或是因为已经知道是备库忽略了某条查询或者有人在备库上修改了数据。
传统的修复不一致的办法是关闭备库,然后重新从主库复制一份数据。当备库数据不一致的问题可能导致严重后果时,一旦发现就应该将备库停止并从生产环境移除,然后再从一个备份中克隆或恢复备库。
这种方法的缺点是不太方便,特别是数据量很大时。如果能够找出并修复不一致的数据, 要比从其他服务器上重新克隆数据要有效得多。如果发现的不一致并不严重,就可以保持备库在线,并重新同步受影响的数据。
最简单的办法是使用mysqldump转储受影响的数据并重新导入。在整个过程中,如果数据没有发生变化,这种方法会很好。你可以在主库上简单地锁住表然后进行转储,再等待备库赶上主库,然后将数据导人到备库中。(需要等待备库赶上主库,这样就不至于为其他表引人新的不一致,例如那些可能通过和失去同步的表做join后进行数据更新的表)。
虽然这种方法在许多场景下是可行的,但在一个繁忙的服务器上有可能行不通。另外一个缺点是在备库上通过非复制的方式改变数据。通过复制改变备库数据(通过在主库上执行更新)通常是一种安全的技术,因为它避免了竞争条件和其他意料外的事情。如果表很大或者网络带宽受限,转储和重载数据的代价依然很高。当在一个有一百万行的表上只有一千行不同的数据呢?转储和重载表的数据是非常浪费资源的。
pt-table-sync是Percona Toolkit中的另外一个工具,可以解决该问题。该工具能够高效地查找并解决表之间的不同。它同样通过复制工作,在主库上执行查询,在备库上重新同步,这样就没有竞争条件。它是结合pt-table-checksum生成的checksum表来工作的, 所以只能 *** 作那些已知不同步的表的数据块。但该工具不是在所有场景下都有效。为了正确地同步主库和备库,该工具要求复制是正常的,否则就无法工作。pt-table-sync设计得很高效,但当数据量非常大时效率还是会很低。比较主库和备库上1TB的数据不可避免地会带来额外的工作。尽管如此,在那些合适的场景中,该工具依然能节约大量的时间和工作。
如果有备库和新主库的位置不相同,则需要找到该备库最后--条执行的事件在新主库的 二进制日志中相应的位置,然后再执行CHANGE MASTER T0。 可以通过mysqlbinlog工具 来找到备库执行的最后一条查询,然后在主库上找到同样的查询,进行简单的计算即可得到。
为了便于描述,假设每个日志事件有一个自增的数字ID,最新的备库,也就是新主库,在旧主库崩溃时获得了编号为100的事件,假设有另外两台备库: replica2和 replica3。replica2已经获取了99号事件,replica3 获取了98号事件。如果把两台备库都指向新主库的同一个二进制日志位置,它们将从101号事件开始复制,从而导致数据不同步。但只要新主库的进制日志已经通过log_slave_updates 打开,就可以在新主库的二进制日志中找到99号和100号日志,从而将备库恢复到一致的状态。
由于服务器重启,不同的配置,日志轮转或者FLUSH LOGS 命令,同一个事件在不同的服务器上可能有不同的偏移量。找到这些事件可能会耗时很长并且枯燥,但是通常没有难度。通过mysqlbinlog从二进制日志或中继日志中解析出每台备库上执行的最后一个事件, 并同样使用该命令解析新主库上的二进制日志,找到相同的查询,mysqlbinlog会打印出该事件的偏移量,在CHANGE MASTER T0命令中使用这个值。
更快的方法是把新主库和停止的备库上的字节偏移量相减,它显示了字节位置的差异。 然后把这个值和新主库当前二进制日志的位置相减,就可以得到期望的查询的位置。只需要验证一下就可以据此启动备库。
让我们看看一个相关的例子,假设server1是server2和server3的主库,其中服务器 server1已经崩溃。根据SHOW SLAVE STATUS 获得Master_Log_File/Read Master_Log_Pos的值,server2 已经执行完了server1 上所有的二进制日志,但server3还不是最新数据。下图显示了这个场景(日志事件和偏移量仅仅是为了举例)。
正如上图所示,我们可以肯定server2已经执行完了主库上的所有二进制日志,因 为Master_Log_File和Read_Master_Log_Pos值和server1上最后的日志位置是相吻合的,因此我们可以将server2提升为新主库,并将server3设置为server2的备库。
应该在server3上为需要执行的CHANGE MASTER TO语句赋予什么样的参数呢?这里需要 做一点点计算和调查。server3 在偏移量1493停止,比server2执行的最后一条语句的偏移量1582要小89字节。server2 正在向偏移量为8167的二进制日志写入,8167-89=8078,因此理论上我们应该将server3指向server2的日志的偏移量为8078的位置。最好去确认下这个位置附近的日志事件,以确定在该位置上是否是正确的日志事件,因为可能有别的例外,例如有些更新可能只发生在server2上。
假设我们观察到的事件是--样的,下面这条命令会将server3切换为server2的备库。
如果服务器在它崩溃时已经执行完成并记录了超过一个事件,会怎么样呢?因为 server2仅仅读取并执行到了偏移位置1582,你可能永远地失去了一个事件。但是如果老主库的磁盘没有损坏,仍然可以通过mysqlbinlog或者从日志服务器的二进制日志中找到丢失的事件。
如果需要从老主库上恢复丢失的事件,建议在提升新主库之后且在允许客户端连接之前做这件事情。这样就无须在每台备库上都执行丢失的事件,只需使用复制来完成。但如果崩溃的老主库完全不可用,就不得不等待,稍后再做这项工作。
首先,com.mysql.jdbc.driver应改为com.mysql.jdbc.Driver;jdbc:mysql://localhost/school应改为jdbc:mysql://localhost:3306/school。其次,如果修改完仍然报错,那就要看看你的驱动包是否加进项目。若没有,可以在lib下选中驱动包,点击右键->Build Path->Add to Build Path,即可。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)