MySQL主从复制分析

  1. 复制概述
    在面对大规模数据时,MySQL复制可以将读操作分布到多个服务器上,实现对密集型应用的优化,通过简单的代码修改就能实现负载均衡;当某个站点的数据库发生了崩坏,利用MySQL复制可以显著的缩短宕机时间;为了解决等等的一系列问题,出现了MySQL复制技术。
    复制解决的基本问题是:让一台服务器的数据与其他服务器保持同步。一台主库的数据可以同步到多台备库上,备库本身也可以被配置成另外一台服务器的主库。主库和备库之间有多种组合方式。
    复制方式:基于行的复制和基于语句的复制。
    复制的工作方式为:通过在主库commit数据之间,将数据更改操作记录到二进制文件(binary log)中, 然后再主库上启动一个二进制转储线程将二进制文件转储到中继日志文件中, 然后备库从终极日志中读取事件并放在备哭执行,从而实现数据的更新;
    复制存在的问题:同一时间点卑库上的数据可能与主库存在不一致,并且无法保证主备之间的延迟。
    复制的用途:数据分布,可以在不同的地理位置来分布数据备份;上述所提及的负载均衡;实现数据备份;上述提及的缩短宕机时间;
    配置复制
    在每台服务器上创建复制账号(在备库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味着必须在主库创建一个用户,并赋予合适的权限);
    配置主库和备库(在主库打开二进制日志,并制定一个独一无二的服务器ID);
    通知备库连接到主库并从主库复制数据(告诉备库连接到主库并重放二进制日志);
    从一个全新的服务器开始复制:这中情况是有一个已经运行了一段时间的主库,然后用一台新安装的备库与之同步,此时这台备库还没有数据,采用的方式是:
    在某个时间点的主库的数据快照;
    主库当前的二进制日志文件,和获得数据快照时在该二进制日志文件中的偏移量,我们把这两个值称为日志文件坐标。
    从快照时间到现在的二进制日志;
  2. 复制的原理
    2.1 基于语句的复制
    主库会记录那些造成数据更改的查询,当备库读取并重放这些事件时,实际上只是把主库执行过的SQL语句再执行一遍
    优点:简单;二进制日志里的事件更加紧凑,不会使用太多带宽;在主备库的模式不同时,基于语句的复制还是可以支持正确的执行;
    缺点:同一条SQL在主备库上的执行时间可能不同,因此当设计时间戳的内容时不适合;还存在着无法复制的SQL;不是所有的存储引擎都支持这中复制模式正在使用触发器、存储过程不要使用基于语句的复制模式
    2.2 基于行的复制
    会将实际数据记录在二进制日志中。
    优点:可以正确的复制每一行;能够更加高效的复制数据;几乎没有基于行的复制模式无法处理的场景;
    缺点:可能是二进制日志事件非常强大。给主库上记录日志和复制增加额外的负载;执行过程像黑盒子,出现问题时无法定位出错的位置;
    2.3 两种复制方式动态切换
    默认使用基于语句的复制,当发现语句无法正确复制时,就切换到基于行的复制;
  3. 复制拓扑
    可以在任意个主库和备库之间建立复制,只有一个限制:每一个备库只能有一个主库。基本准则:
    一个MySQL备库只能有一个主库;每个备库必须有一个唯一的服务器ID;一个主库可以有多个备库;如果打开了long_slave_updates选项,一个备库可以把其他主库上的数据变换传播到其他备库;
    3.1 一个主库多个备库(适用于少量写、大量读的)
    为不同角色使用不同的备库
    把一台备库当作待用的主库,除了复制没有其他数据传输
    把一台备份库放到远程数据中心,用作才难恢复
    延迟一个或者多个备份库,用于灾难恢复
    使用其中一个备份库,作为备份、培训或者开发使用服务器
    3.2 主动-主动模式下的主-主复制(例如:多人在线文档编辑)
    包含两台服务器,每一个都被配置成对方的主库和备库。
    3.3 主动-被动模式下的主-主复制
    包含两台服务器,每一个都被配置成对方的主库和备库,区别在于一台服务器是只读的被动服务器;
    3.4 拥有备库的主-主结构
    包含两台服务器,每一个都被配置成对方的主库和备库,为每一个主库增加一个备份库;
    3.5 环形复制
    拥有三个或者更多的主库。每个服务器都是在她之前的服务器的备份库,是在他之后的服务器的主库。
    3.6 主库、分发主库以及备份库
    会使得主库负载大量产生的原因:当有多个备库时,会对主库造成很大的负载。每个备库会在主库上创建一个线程,执行binlog dump命令。该命令会读取二进制日志文件中的数据并将其发送到备份库中。每个备库都会重复这样的工作,它们不会共享binlog dump的资源。比如:在A房间(主库)里面放了一个物品,现在有N个人(复制线程),需要来参观这个物品,然后各自回到自己的房间(备哭)进行绘制。那么每个人参观所得心得大家都是不共享的,都是各自回房间进行绘制。当来的人的容量大大超出了A房间可以容纳的人数时,A房间的负载就会显著上升。
    为了解决上述问题,提出了从主库移除负载并使用分发主库的方法。分发主库实际上也是一个备库,他的唯一目的就是提取和提供主库的二进制文件。多个备份库链接到分发主库,这使得原来的主库拜托了负担。在分发主库上支持blackhole表可以支持更多的备份库。比如:我们在引入一个B房间该房间有一层透明的玻璃可以完全看到A房间内的内容,再有人来参观时,让人都在B房间中参观然后回去临摹,不在进入A房间内。
    3.7 定制的复制方案
    选择性复制:复制少量数据到备库中,主库中保存完整信息。如果每个备库只拥有主库的一部分数据,并且将读分配给备库,就可以更好的利用备库的内存。并且每个备库也至于主库一部分的写入负载,这样主库的能力更强并能保证备库的延迟。比如:A房间中有桌子,椅子,凳子,在A的备份房间BCD中,B只存放与A相同的桌子,C只存放与A相同的椅子,D只存放与A相同的凳子。到时候有人来参观凳子时,可以直接到D中去参观。
    数据归档:在备份库上保留主库的删除过程
    将备库作为全文索引:配置一台备库,将某些表设置为MyISAM存储引擎,然后创建全文索引并执行全文索引查询。
    创建日志服务器:创建没有数据的日志服务器。
  4. 复制和容量规划
    写操作是复制的瓶颈,并且很难使用复制来扩展写操作。
    备库什么时候开始延迟:观察复制延迟可视化图的尖刺部分,这一部分往往是负载加大,使得备库短时间内无法跟上主库;
    规划冗余容量:在构建大型应用的时候,有意让服务器不被充分利用
    复制管理和维护:
    1)监控复制:show master status可以查看当前主库的二进制日志位置和配置。
    2)测量备库延迟:heartbeat record是一个在主库上会每秒更新的时间戳。当计算延迟时,可利用备库当前的时间戳减去该值。
    3)确定主备库一致:Percona Toolkit中的pt-table-checksum用于确定主备库一致。
    4)从主库重新同步备库:Percona Toolkit中的pt-table-sync能够高效的查找并解决表之间的不同。
    5)改变主库:即把一个备库转换成主库。分为计划内的转换和计划外的转换。
    计划内的转换:停止向老的主库的写入;让备份库追赶上主库;将一台备份库设置为新的主库;将备份库和写操作指向新的主库,然后开启主库的写入。
    计划外的转换:。。。(待补充)
    6)确定期望的日志位置:通过mysqlbinlog工具来找到备份库执行的最后一条查询,然后再主库上找到同样的查询,进行简单的计算即可得到。
  5. 复制的问题和解决方案
    1) 数据损坏或者丢失的错误
    意外关闭可能会碰到的情况:
    主库意外关闭:利用pt-table-checksum工具检查主备库一致性,用户恢复主库的内容;指定备库从下一个二进制日志的开头读取日志;通过在主库开启sync_binlog来将二进制日志文件刷新到磁盘中,从而避免事件丢失
    备库意外关闭:利用pt-slave-restart忽略一些错误,然后去读master.info文件找到上次停止复制的位置。
    主库上的二进制日志文件损坏:只有忽略损坏的位置
    备库上的中继日志损坏:如果主库上的二进制日志是完好的,可以通过change master to 命令丢弃并重新获取损坏的事件。
    二进制日志和InnoDB事务日志不同步:通过设置sync_binlog来进行预防
    2)使用非事务型表
    非事务型表的更新发生错误时,导致主备库的数据不一致。推荐使用事务型表
    3)混合事务型和非事务型表
    避免使用
    4)不确定语句
    针对基于语句的复制模式,如果通过不确定的方式更改数据会导致主备库不一致。
    5)主备库使用不同的存储引擎
    6)备库发生数据变换
    数据不一致会在表之间传播。解决方案:重新从主库同步数据
    7)不唯一的服务器ID
    8)未定义的服务器ID
    确保服务器ID是唯一且具有标志性的
    9)对未复制的数据的依赖性
    避免在备份库上创建主库上没有的表
    10)丢失的临时表
    11)不复制所有的更新
    12)InnoDB加锁引起的锁争用
    避免让事务开启太久以减少阻塞。在主库上尽快的提交事务以释放锁。
    13)在主-主复制结构中写入两台主库
    通过设置auto_increment_increment和auto_increment_offset来错开主库和备份库生成的数字,避免自增列的冲突。
    14)过大的复制延迟
    复制一般有两种产生延迟的方式:突然产生延迟然后跟上(由于执行一条很长时间的查询导致的);稳定的延迟增大(在没有长时间运行的查询时会出现)。
    15)来自主库的过大的包
    16)受限制的复制带宽
    17)磁盘空间不足
    18)复制的局限性
  6. 复制有多快
    它与MySQL从主库复制事件并在备份库重放的速度一样快。

你可能感兴趣的:(笔记)