1、复制的概述
1.1、概念
将主数据库的DDL和DML操作通过二进制日志传到复制服务器(也叫从库)上,然后在从库上对这些日志重新执行(也叫重做),从而使得从库和主库的数据保持同步。
主要优点:
- 主库有问题,可以快速切换到从库;
- 从库执行查询操作,降低主库的访问压力;
由于是异步复制
,所以主从之间数据存在一定的差异,只有更新不频繁或者对实时性要求不高的数据才从从库查询,实时性要求高的数据仍然从主库查询
- 从库执行备份,以避免备份期间影响主库的服务。
1.2、原理
主库在事务提交时,作为Events记录在Binlog中,主库推送Binlog中的时间到从库的Relay Log
步骤:
- 从库启动复制(
start slave
)时,首先创建I/O
线程连接主库;- 主库创建
Binlog Dump
线程读取数据库事件并发送给I/O
线程;I/O
线程获取到数据后更新到从库的Relay Log
中去;- 从库的
SQL
线程读取日志中更新的数据库时间并应用。
查看主库的Binlog Dump
线程以及从库的I/O
线程和SQL
线程
SHOW PROCESSLIST
1.3、复制的文件
主要包含两类文件:主库的二进制文件(Binlog)
、从库的中继文件(Relay Log)
。
查看Binlog的格式
show variables like '%binlog_ format';
三种文件复制的方式:
Statement
:基于SQL语句级别的Binlog,每条修改数据的SQL都会保存到Binlog里。基于SQL语句的复制Statement-Based Replication(SBR)
Row
:基于行级别,记录每一行数据的变化,也就是将每行数据的变化都记录到Binlog里面,记录得非常详细,但是并不记录原始SQL。基于行的复制Row-Based Replication(RBR)
Mixed
:混合Statement和Row模式,混合模式复制。
修改文件复制方式
set <global> binlog_format = 'row'
中继日志文件RelayLog的文件格式、内容和二进制日志文件Binlog一样,
唯一的区别在于从库上的SQL线程在执行完当前中继日志文件RelayLog中的事件之后,SQL线程会自动删除当前中继日志文件RelayLog
,避免从库上的中继日志文件RelayLog占用过多的磁盘空间。
从库上默认还会创建两个日志文件master.info
和relay-log.info
用来保存复制的进度
。这两个文件在磁盘上以文件形式分别记录了从库的I/O线程当前读取主库二进制日志Binlog的进度和SQL线程应用中继日志RelayLog的进度。
查看从库的复制状态
SHOW SLAVE STATUS
master.info
的内容:
MasterHost
:主库的IP。
MasterUser
:主库上,主从复制使用的用户账号。
MasterPort
:主库MySQL的端口号。
Master_Log_File
:从库的I/O线程当前正在读取的主库Binlog的文件名。
Read_Master_Log_Pos
:从库I/O线程当前读取到的位置。
relay-log.info
的内容:
Relay_Log_File
:从库SQL线程正在读取和应用的中继日志RelayLog的文件名。
Relay_Log_Pos
:从库SQL线程当前读取并应用的中继日志RelayLog的位置。
Relay_Master_Log_File
:从库SQL线程正在读取和应用的RelayLog对应于主库Binlog的文件名。
Exec_Master_Log_Pos
:中继日志RelayLog中Relay_Log_Pos位置对应于主库Binlog的位置。
2、复制的常见架构
2.1、一主多从复制架构
主库读取请求压力非常大的场景下可以采用此架构。
2.2、多级复制架构
考虑到MySQL的复制是主库“推送”Binlog日志到从库,主库的I/O压力和网络压力会随着从库的增加而增长(每个从库都会在主库上有一个独立的BinlogDump线程
来发送事件)
优点:减轻主库的推送压力,只需要将日志推送给
master2
,由它向Slave
推送日志。
缺点:经历两次异步复制,延时更大。
二级主库Master2上选择表引擎为
BLACKHOLE来降低多级复制的延时
。顾名思义,BLACKHOLE引擎是一个“黑洞”引擎,写入BLACKHOLE表的数据并不会写回到磁盘上
,BLACKHOLE表永远都是一个空表,INSERT/UPDATE/DELETE操作仅仅在Binlog中记录事件
。
2.3、双主复制/Dual Master架构
特别适用于DBA做维护等需要主从切换的场景,避免重复搭建的麻烦。
2.4、双主级联复制
3、复制方式
3.1、异步复制
隐患:从库尚未得到主库的推送日志,主库宕机了,主库可能因为磁盘损坏、内存故障造成主库Binlog丢失,从库可能损失这个事务。
3.2、半同步复制
等待其中任一从库接收到了Binlog事务并成功写入中级日志后才返回。如果推送日志过程中宕机了,此时主库上的事务会等待一段时间(rpl_semi_sync_master_timeout
参数设置,单位ms),如果这段时间内仍然无法成功推送到从库,则会自动切换为异步复制
,事务正常返回给客户端。
当检测到从库回复正常之后,主库到从库的复制方式会自动切换为半同步复制模式。
往返时延RTT(Round-TripTime)
在计算机网络中是一个重要的性能指标,它表示从发送端发送数据开始到发送端接收到接收端的确认,总共经历的时长。
查看半同步复制的状态:
show status like '%semi_ sync%';
Rpl_semi_sync_master_status
:值为ON,表示半同步复制目前处于打开状态
Rpl_semi_sync_master_yes_tx
:值为0,表示主库当前尚未有任何一个事务是通过半同步复制到从库。
Rpl_semi_sync_master_no_tx
:值为3,表示当前有3个事务不是半同步模式下从库及时响应的(记住这个值,后面会有对比)。
从半同步复制的流程会发现,半同步复制的“半”就体现在:虽然主库和从库的Binlog日志是同步的,但是主库并不等待从库应用这部分日志就返回提交结果,这部分操作是异步的,从库的数据并不是和主库实时同步的,所以只能称为半同步,而不是完全的实时同步。
3.3、主要复制启动选项
log-slave-updates
:从库上的更新操作是否需要写二进制文件,默认不打开
。如果该从库还作为其他从库的主库,那么该选项需要打开。
master-connect-retry
:与主库失联时,重试的时间间隔,默认时间60s
。
read-only
:用来设置从库只能接受超级用户的更新操作,从而限制应用程序错误的对从库的更新操作。
replicate-do-db
、replicate-do-table
、replicate-ignore-db
、replicate-ignore-table
或replicate-wild-do-table
来指定从主数据库复制到从数据库的数据库或者表。有时用户只需要将关键表备份到从库上,或者只需要将提供查询操作的表复制到从库上,这样就可以通过配置这几个参数来筛选进行同步的数据库和表。
slave-skip-errors
:用来定义复制过程中从库可以自动跳过的错误号,这样当复制过程中遇到定义中的错误号时,便可以自动跳过,直接执行后面的SQL语句,以此来最大限度地减少人工干预。作为备份数据的从库,设置不当可能造成主从数据不一致,不建议启动该参数
。
4、主从切换
- 确保所有的从库都已经执行了
Relay log
,执行stop slave io_thread
;- 选择其中的一个从库执行
stop slave
停止服务,重置成主数据库reset master
;- 在其余的从库上执行
stop slave
停止服务,,执行change master to mas ter_host = <重置为主库的从库服务器名称>
重新设置主数据库,执行start slave
;- 通知所有的客户端将应用指向新的master;
- 删除新master上的
master,info
和relay-log,info
文件,如果不删除,下次启动时还会按照从库启动;- 如果原master恢复,则可以配置成新master的从库。