MySQL的复制
一、概述
1.复制解决的问题是让一台服务器的数据与其他服务器保持同步,即主库的数据可以同步到多台备库上,备库也可以配置成另外一台服务器的主库。这种操作一般不会增加主库的开销,主要是启用二进制日志带来的开销。
2.两种复制方式:
基于行的复制和基于语句的复制,这两种方式主要都是通过主库上记录二进制日志、在备库重放日志的方式来实现异步的数据复制(即同一个时间点上,主库和主库的数据存在不一致)。另,其复制为向后兼容即新版本的服务器可以作为旧版本服务器的备库,反之不行。
这两种复制方式的区别在于,基于行的复制在5.1版本后才被加进去。
3.复制常见的用途:
数据分布:随意停止或开始复制并在不同的地理位置分布数据备份
负载均衡:将读操作分不到多个服务器上
备份:复制不是备份也不可取代备份
高可用和故障切换:帮助应用程序避免mysql单点失败,一个包含复制的设计良好的故障切换系统能够显著的缩短宕机时间
mysql升级测试:使用高版本的mysql作为备库保证升级全部的示例前查询可以在备库按照预期执行
二、复制的工作过程
1.在主库上把数据更改记录到二进制日志中
2.备库将主库的日志复制到自己的中继日志中
3.备库读取中继日志的事件并将其放到备库数据之上
大概过程如下图:
备库将主库的二进制日志复制到本地的中继日志中备库会启动一个工作线程(I/O线程),该线程会和主库建立普通的客户端连接,主库上启动特殊的二进制转储线程来读取二进制日志中的事件。
注:主库上的二进制转储线程不会对二进制日志中事件进行轮询并且如果其转储进度追赶上主库会进入睡眠状态,直到主库发送信号量通知有新的事件产生才会被唤醒继续接收事件记录到中继日志中。
三、配置复制
1.步骤:
在每台服务器上创建复制账号
配置主库和备库
通知备库连接到主库并从主库复制数据
2.环境:服务器server1(IP地址 192.168.0.1) 和服务器server2(IP地址 192.168.0.2)
3.创建复制账号
mysql会赋予一些特殊的权限给复制进程,在备库运行的I/O线程会建立一个到主库的TCP/IP连接,这意味需要在主库创建一个用户并赋予其合适的权限,备库I/O线程以该用户名连接到主库并读取其二进制日志。
grant replication slave ,replication client on *.* to repl@'192.168.0.%' identified by 'testxiao';
在主库和备库都创建该账号
4.配置主库和备库
假设主库是服务器server1,需要打开二进制日志并指定独一无二的服务器id,在主库的my.cnf文件中修改内容
log_bin = mysql-bin
server_id = 10
一般使用服务器的末尾两位作为唯一id
可以通过 show master status
备库上的my.cnf也要增加同样的配置
log_bin = mysql-bin
server_id = 11
relay_log = /var/lib/mysql/mysql-relay-bin
log_slave_updates = 1 表示允许备库将重放的事件记录到自身的二进制文件
read_only = 1
5.启动复制
告诉备库如何连接到主库并重放其二进制日志
change master to master_host='server1',
master_user='repl1',
master_password='testxiao',
master_log_file='mysql-bin.000001',
master_log_pos=0;
master_log_pos=0 表示从日志开头读起,可以通过show slave status检查复制是否正确执行
其中slave_io_state slave_io_running和save_sql_running这三列表示当前备库复制尚未运行,日志的开始是4不是0是因为0不是日志真正开始的位置,仅仅是日志文件头,mysql从直到第一个事件从文件的第4位开始读
start slave 该命令开始复制
再次使用show slave status
通过上图的信息可以看出来I/O线程和SQL线程已经开始运行
可以通过上述命令查看由I/O线程向主库发起的连接
6.从另一个服务器开始复制
大多数情况下一般是有一个已经运行一段时间的主库并需要三个条件让主库和备库保持同步:
在某个时间点主库的快照
主库当前的二进制日志文件和获得数据快照时在该二进制日志文件中的偏移量,这两个值被称为日志文件坐标,通过这两个值可以确定二进制日志的位置,可以通过show master status来获取这些值
从快照时间到现在的二进制日志
从别的服务器克隆备库的方法
冷备份:
关闭主库,把数据复制到备库,重启主库后会使用一个新的二进制文件,在备库通过执行change master to 指向这个文件的起始处,缺点是在复制数据时需要关闭主库
热备份:
使用mysqldump
使用快照或备份
只要找到对应的二进制日志坐标就可以使用主库的快照或者备份来初始化备库
7.推荐的复制配置
sync_binlog=1
如果开启该选项,mysql每次在提交事务前会将二进制日志同步到磁盘上保证在服务崩溃时不会丢失事件,只适用于二进制日志非中继日志
relay_log=/path/to/logs/relay-bin
skip_slave_start
read_only
以上三个配置中,第一个配置可以避免中继日志文件基于机器名来命名,第二个配置选项能够避免备库在崩溃后自动启动复制,第三个配置选项可以组织大部分用户更改非临时表。
四、复制的原理
1.基于语句的复制
主库会记录造成数据更改的查询,当备库读取并重放这些事件时实际上是把主库上执行过的sql再执行一遍,好处是:能够保证主备保持同步且无需太多的带宽,缺点是会有一些元数据(时间戳)无法保持同步并且更新必须是串行的。
2.基于行的复制
可以正确的复制每一行但是没有向后兼容性,无需重放更新主库数据的查询
mysql可以基于上述两种复制模式进行动态的切换,默认是使用基于行的复制语句的复制模式,如果发现语句无法被正确的复制就切换到基于行的复制模式。
五、复制文件
1.mysql-bin.index 该文件用来记录磁盘上的二进制日志文件,包括二进制文件的文件名
该文件并不多余,mysql需要依赖这个文件,如果这个文件中没有记录,mysql将无法是被二进制文件
2.mysql-relay-bin-index 中继日志的索引文件和上述文件作用类似
3.master.info 保存备库连接到主库所需要的信息,该文件不可被删除,否则备库再重启后将无法连接到主库上,这个文件以文本的方式记录了复制用户的密码
4.relay-log.info 包含备库复制二进制日志和中继日志坐标,删除此库备库重启后将无法知道从哪个位置开始复制
六、发送复制事件到其他备库
1.log_slave_updates选项可以让备库变成其他服务器的主库,该选项将其执行过的事件记录到它自己的二进制日志中可以使得它的备库可以从其日志中检索并执行事件
2.mysql指定服务器id的原因是:mysql在复制过程中为了防止无限循环会丢弃事件中记录的服务器id和该服务器本身ID事件相同的事件。
七、复制过滤器
1.复制过滤器是允许仅复制服务器上一部分的数据,两种复制过滤的方法:
在主库上过滤记录到二进制日志中的事件
在备库上过滤记录到中继日志的事件
可能会发生问题,一般不用
八、复制拓扑
1.可以在任意个主库和备库之间建立复制,限制条件是每一个备库只能有一个主库,条件是:
一个mysql备库只能有一个主库
每个备库必须有一个唯一的服务器id
一个主库可以有多个备库
打开log_slave_updates选项,表示一个备库可以将主库上的数据变化传播到其他的备库
2.模式:一主多备结构
主动-主动模式下的主-主复制(双向复制/双主复制),每一个都被配置成对方的主库和备库
主动-被动模式下的主-主复制