
// 周日 崩溃倒计时
// 《高性能MySQL》Baron Scbwartz,
Peter Zaitsev,Vadim Tkacbenko
// 文中有错误的地方请不吝指教,不胜感激!
// 注:文中所述 " 备库 " 也即 " 从库 "
MySQL内建的复制功能
可以通过为服务器配置一个或多个备库的方式来进行数据同步。
复制功能不仅有利于构建高性能的应用,同时也是高可用性、可扩展性、灾难恢复、备份以及数据仓库等工作的基础。
一、简介
复制解决的问题是让一台服务器的数据与其他服务器保持同步。一台主库的数据可以同步到多台备库上,备库本身也可以被配置成另外一台服务器的主库。
主库和备库之间可以有多种不同的组合方式。
简单来说,就是" 你有的(数据)我也要有。"
MySQL支持两种复制方式:
基于行的复制(ROW)
基于语句的复制(STATEMENT)
相同点:
都是通过在主库上记录二进制日志、在备库上重放日志的方式来实现异步的数据复制。
不同点:
基于行的复制会比传统的基于语句的复制模式的带宽压力更大。
其他的不同点下文再做比较。
然鹅,这两种异步的复制方式也意味着,在进行数据同步时会有数据丢失的风险,在同一个时间点,备库上的数据可能与主库存在不一致,并且,无法保证主备之间的延迟。一些大的语句可能导致备库产生几秒、几分钟甚至几个小时的延迟,丢失数据造成的后果是...凉凉。
另外:
复制操作通常不会增加主库的开销(主要是开启二进制日志带来的开销)
通过复制可以将读操作指向备库来获得更好的读操作,不建议扩展写操作(即读写分离)
常见的复制架构:一主多备,可能会造成一些浪费,因为本质上,它会复制大量不必要的重复数据。
二、复制解决的问题
数据分布
负载均衡
备份
(复制是备份的技术补充,但复制既不是备份也不能取代备份)
高可用性和故障切换
(避免MySQL单点失败;缩短宕机时间)
MySQL升级测试
三、复制的工作步骤
步骤
(1). 在主库上把数据更改记录到二进制日志(Binary Log)中,这些记录被称为二进制日志事件。
(2). 备库将主库上的日志复制到自己的中继日志(Relay Log)中。
(3). 备库读取中继日志中的事件,将其重放到备库数据之上。

// MySQL复制步骤
详细说明:
第一步——记录(主库:写在小本本上)
首先在主库上记录数据发生变更的二进制日志。
在每次准备提交事务完成数据更新前,主库将数据更新
的事件记录到二进制日志中。MySQL会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。
在记录二进制日志后,主库会告诉存储引擎可以提交事务了。
第二步——复制(备库:抄主库记在小本本上的内容)
备库将主库的二进制日志复制到其本地的中继日志中。
首先,备库会启动一个I/O工作线程,I/O线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储(binlog dump)线程(此线程没有对应的SQL命令),这个二进制转储线程就会去读取主库上二进制日志中的事件。
它不会对事件进行轮询。如果此线程追赶生了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生时才会被唤醒,备库I/O线程会将接收到的事件记录到中继日志中。
第三步——重放(备库:也执行一遍刚刚抄在小本本上的作业)
备库的SQL线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。
以上,这种复制架构实现了获取事件和重放事件的解耦,允许这两个过程异步进行(即I/O线程能够独立于SQL线程之外工作)
然鹅这种架构也限制了复制的过程——
在主库上并发运行的查询在备库上只能串行化执行,因为只有一个SQL线程来重放中继日志中的事件。
四、复制的原理及方式比较
在第一部分有略提到过MySQL支持的两种复制方式,即基于行的复制和基于语句的复制。
现在来说说它俩的不同点:)
4.1 基于语句的复制(逻辑复制)
MySQL版本 <= 5.0
在此复制模式下,主库会记录那些造成数据更改的查询,当备库读取并重放这些事件时,实际上只是把主库执行过的SQL再执行一遍。
此模式不会使用太多带宽。
4.2 基于行的复制
MySQL版本 >= 5.1
这种方式会将实际数据记录在二进制日志中
最大的好处是可以正确地复制每一行,一些语句可以被更加高效地复制。
4.3 基于语句&基于行的优缺点
(理论上基于行的复制模式整体上更优)
基于语句复制模式的优缺点:
当主备的模式不同时,逻辑复制能够在多种情况下工作;
基于语句的方式执行复制的过程基本上就是执行SQL语句。这意味着所有在服务器上发生的变更都以一种容易理解的方式运行。这样出现问题时可以很好地去定位。
然鹅,很多情况下通过基于语句的模式无法正确复制。
简单地说,如果正在使用触发器或者存储过程,就不要使用基于语句的复制模式,除非能够清楚地确定不会碰到复制问题。
基于行复制模式的优缺点:
几乎没有基于行的复制模式无法处理的场景,对于所有的SQL构造、触发器、存储过程等都能正确执行。
会记录数据变更,因此在二进制日志中记录的都是实际上在主库上发生了变化的数据。你不需要查看一条语句去猜测它到底修改了哪些数据。
另外在一些情况下,基于行的二进制日志还会记录发生改变之前的数据,因此这有可能有利于某些数据恢复。
占用更少的CPU。
在某些情况下,能够帮助更快地找到并解决数据不一致的情况。
缺点是,由于语句并没有在日志里记录,因此无法判断执行了哪些SQL。
以上。
这么菜居然还不想上班?!


橘子不是唯一的水果
猫太太