《深入浅出MySQL》架构篇

第31章 Mysql复制

复制就是将主数据库的DDL操作和DML操作通过二进制日志的方式传输到从库上,然后在从库上对这些日志进行重做,从而使得从库数据和主库数据保持同步的操作。

MySQL复制的优点:
(1)如果主库出现问题,可以迅速切换到从库
(2)在从库执行查询操作,减轻主库压力
(3)可以在从库上执行备份,以避免备份期间影响主库的服务

MySQL实现的是异步复制。主从库数据存在差距。

31.1 复制概述

大致原理:
(1)主库进行事物提交时会把数据变更作为事件Events记录在二进制日志文件Binlog中;主库的sync_binlog参数控制Binlog日志刷新到磁盘。
(2)主库推送Binlog中的事件到从库的中继日志Relay Log,之后,从库根据Relay Log重做变更操作。

主从复制需要三个线程:

  • Binlog Dump 线程
    运行于主库
    读取数据库事件并发送给I/O线程

  • I/O线程
    运行于从库
    获取都事件之后更新到从库的Relay Log之中

  • SQL线程
    运行于从库
    读取中继日志Relay Log中更新的数据库事件并应用。

主从复制的过程:

  • 从库启动复制(start slave)
  • 创建IO线程链接主库
  • 主库创建binlog dump线程
  • IO线程获取变更操作的事件并更新到relay log中
  • sql线程读取中继日志,进行重做

异步复制,主库和从库存在着一定的时延。

31.1.1 复制中的各类文件

二进制日志文件记录数据修改操作,例如,create,drop,insert,update,delete等。Binlog支持statement、row、mixed三种格式,对应mysql三种复制技术。

中继日志文件的格式、内容和Binglog一样,区别就是sql线程在执行完relay log中的操作之后会删除relay log。

master.info记录IO线程读取binlog的位置;
relya-log.info记录sql线程读取relaylog的位置

master.info的主要参数:

  • Master Host :主库ip
  • Master User:主库上进行复制的用户账号
  • Master Port:主库的MySQL端口号
  • Master_Log_File:从库的I/O线程当前正在读取主库的binlog文件名
  • Read_Master_Log_Pos:从库I/O线程读取到的位置

relay-log.info的主要参数:

  • Realy_Log_File:从库SQL线程正在读取和应用的中继日志Relay Log的文件名
  • Relay_Log_Pos:从库SQL线程当前正在读取和应用的中继日志Relay Log的位置
  • Relay_Master_Log_File:从库SQL线程正在读取和应用的中继日志Relay log对应于主库Binlog的文件名。
  • Exec_Master_Log_Pos:中继日志Relay Log中Relay_Log_Pos位置对应于主库Binlog的位置

31.1.2 三种复制方式

  • Statement
    SQL语句级的Binlog,每条修改数据的sql都会保存在Binlog中
  • Row
    行级别。将每一行数据的变化记录到binlog中。记录详细,并不记录sql;在复制的时候,并不会因为存储过程或者触发器造成主从库的不一致,但是记录的日志量要叫statement方式要大得多。
  • Mixed
    混合Statement和Row模式,默认采用statement模式,某些情况(例如,sql中包含时间、用户相关的函数等)下切换到Row模式。

参数binlog_format可以在全局设置也可以在当前Session中动态设置:全局设置影响所有的Session。可以通过SET 命令实时修改Binlog的格式。

例如,将statement改为row模式:

mysql> set global binlog_format = 'Row'

31.1.3 复制的三种常见架构

  1. 一主多从
    在主库读取请求压力非常大的场景下,可以通过配置一主多从复制架构实现读写分离,把大量对实时性要求不是特别高的读请求通过负载均衡分布到多个从库上,降低主库的读取压力。在主库出现异常宕机的情况下,可以把一个从库切换为主库继续工作。
  2. 多级复制
    一主多从架构能够解决大部分读请求压力特别大的场景的需求,考虑到MySQL的复制是主库“推送”Binlog日志到从库,主库的IO压力和网络压力会随着从库的增加而增长(每个从库都会在主库上有一个独立Binlog Dump线程来发送事件),而多级复制架构解决了一主多从场景下,主库额外的IO和网络压力。

与一主多从架构相比,多级复制仅仅是在主库Master1复制到从库Slave1、slave2、slave3的中间增加了一个二级主库Master2。这样,主库Master1只需要给一个从库Master2“推送”Binlog日志即可,减轻了主库Master1的推送压力。二级主库再“推送”Binlog日志给从库Slave1、Slave2和Slave3.

多级复制的缺点就是,主库的数据要经历两次复制才到达从库Slave1、Slave2和Slave3,此期间的延时要大于一主多从架构。

可以通过在二级主库Master2上选择表引擎为BLACKHOLE来降低多级复制的时延。BLACKHOLE引擎非常适合二级主库Master2的场景:Master2并不承担读写请求,仅仅负责将Binlog日志尽快传递给从库。

BlackHole引擎是“黑洞”引擎,写入blackhole表的数据并不会写到磁盘上,blackhole表永远只是一个空表,增删改查操作仅仅在Binlog中记录事件。

mysql> create table test(i int , c char(10)) engine = blackhole
Query OK, 0 rows affected
mysql> insert into test values(1,'record one'),(2,'record two')
Query OK, 2 rows affected
mysql> select * from test;
Empty Set
  1. 双主复制

双主架构特别适用于DBA做维护等需要主从切换的场景,通过双主架构避免了重复搭建从库的麻烦。

主库Master1和Master2互为主从,所有Web Client客户端的写请求都访问主库Master1,而读请求可以选择访问Master1或者Master2.

例如,DBA需要做日常维护操作,为了避免影响服务:

  • Master1上停止Slave线程。避免后续对Master2的维护操作被实时复制到Master1上对服务造成影响
  • Master2上停止Slave线程。开始日常维护操作,例如,创建索引等。
  • 在Master2库上完成维护操作之后,打开Master2上的Slave线程,让Master2库的数据和Master1库上保持同步。同步完成后,把应用的读写操作切换到Master2库上。
  • 确认Master1库上午应用访问之后,打开Master1库的Slave线程。

通过双主复制架构能够大大减轻一主多从架构下对主库进行维护带来的额外搭建从库的工作。

双主复制可以和主从复制联合起来使用:在Master2库下配置Slave1、Slave2等,这样既可以通过从库Slave1等来分担读取压力,同事在DBA做维护的同时,避免了重建从库的额外工作。

31.3 主要复制启动选项

31.3.1 log-slave-updates

log-slave-updates这个参数用来配置从库上的更新操作是否写二进制日志,默认是不打开的。但是,如果这个从库同时也要作为其他服务器的主库,搭建一个链式的复制,那么就需要打开这个选项,这样它的从库将获得它的二进制日志以进行同步操作。

31.3.2 master-connect-retry

master-connect-retry这个参数用来设置和主库的链接丢失重试的时间间隔,默认是60s,即每60秒重试一次。

31.3.3 read-only

read-only该参数用来设置从库只能接受超级用户的更新操作,从而限制应用程序错误的对从库的更新操作。

31.3.4 指定复制的数据库或者表

可以使用replicate-do-dbreplicate-do-tablereplicate-ignore-dbreplicate-ignore-tablereplicate-wild-do-table来指定从主数据库复制到从数据库的数据库或者表。

31.3.5 slave-skip-errors

在复制的过程中,由于各种原因,从库可能会遇到执行BINLOG中的SQL出错的情况(比如主键冲突),默认情况下,从库将会停止复制进程,不再进行同步,等待用户介入处理。这种问题如果不能及时发现,将会对应用或者备份产生影响。此参数的作用就是用来定义复制过程中从库可以自动跳过的错误号,当复制过程中遇到了定义中的错误号时,便可以自动跳过,直接执行后面的SQL语句,以此来最大限度地减少人工干预。

此参数可以定义多个错误号,或者通过定义成all跳过全部的错误,具体语法如下:

--slave-skip-errors = [err_code1, err_code2, ... | all]

如果从数据库主要作为主数据库的备份,那么就不应该使用这个启动参数,设置不当,很可能造成主从数据库的数据不同步。但是如果从数据库仅仅是为了分担主数据库的查询压力,且对数据的完整性要求不是很严格,那么这个选项可以减轻数据库管理员维护从数据库的工作量。

31.4 日常管理维护

31.4.1 查看从库状态

为了防止复制过程中出现故障从而导致复制进程停止,我们需要经常检查从库的复制状态。一般使用show slave status命令来检查。

主要关心两个信息:

  • Slave_IO_Running:此进程负责从库从主库上读取BINLOG日志,并写入到从库的中继日志中。
  • Slave_SQL_Running:此进程负责读取并执行中继日志中的BINLOG日志。
    只要有一个进程的状态是no,则表示复制进程停止,错误原因可以从Last_Errno字段中看到。

31.4.2 主从库同步维护

在某些繁忙的OLTP(在线事务处理)系统上,由于主库更新频繁,而从库由于各种原因(如硬件性能较差)导致更新速度较慢,从而使得主从库之间的数据差距越来越大,最终对某些应用产生影响。在这种情况下,我们要定期地进行主从库数据的同步,使得主从库的数据差距能够见到最小。常用的方法是:在负载较低时暂时阻塞主数据库的更新,强制主从数据库更新同步。

具体操作:
(1)阻塞主数据库所有更新操作

mysql> flush tables with read lock
mysql> show master status
File    Position   Binlog_DO_DB Binlog_ignore_db

记录输出的日志名和偏移量,这些是从库复制的目的坐标。
(2)从库进行复制操作

mysql> select master_pos_wait('日志名','偏移量')

函数参数就是(1)中得到的日志名和偏移量。

select语句会阻塞直到从库达到指定的日志文件的偏移量之后,返回0,表示从库与主库同步。如果返回-1,表示超时退出
(3)允许主库重新开始处理更新操作

mysql> unlock tables;

31.4.3 从库复制出错的处理

发布了280 篇原创文章 · 获赞 49 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/kaikai_sk/article/details/104842676