目录
一.复制的概念
二.复制的方式
三.复制的兼容
四.复制的开销
五.复制解决的问题
六.复制的工作原理
七.配置复制
一.复制的概念
MySQL复制有利于构建高性能的应用,同时也是高可用性,可扩展性,灾难恢复,备份以及数据仓库等工作的基础。
复制就是让一台服务器的数据与其他服务器保持同步。一台主库的数据可以同步到多台备库上。备库本身也可以被配置成另外一台服务器的主库。
二.复制的方式
MySQL支持两种复制方式:基于行的复制,基于语句的复制(逻辑复制,在3.23版本就有)。基于行的复制在5.1版本才加进来的。两种方式都是通过在主库上记录二进制日志,在备库重放日志的方式来实现异步的数据复制。意味着同一时间点备库数据可能与主库存在不一致。一些大的语句可能导致几秒,几分钟甚至几小时的延迟。
三.复制的兼容
MySQL复制大部分是向后兼容的,新版本的服务器可以作为老版本服务器的备库,反之则不行,因为它可能无法解析新版本的新的特性或语法,使用的二进制文件的格式也可能不同。
四.复制的开销
1.启用二进制日志带来的开销
2.备库请求主库读取旧的二进制日志文件带来的网络IO开销
3.一个高吞吐量的主库复制到多个备库,唤醒多个复制线程发送事件的开销
五.复制解决的问题
1.数据分布(通过远程复制,在不同的地理位置来分布数据备份)
2.负载均衡(通过复制可以将读操作分布到多个服务器上,实现对读密集型应用的优化)
3.备份
4.高可用性和故障切换
5.MySQL升级测试(为保证升级不出错,可以先在备库上执行所有的查询测试)
六.复制的工作原理
复制的三个步骤:
先上图
1.在主库上把数据更改记录到二进制日志(Binary Log)中(这些记录被称为二进制日志事件)
在每次准备提交事务完成数据更新前,主库将数据更新的事件记录到二进制日志中。MySQL会按事务提交的顺序而非每条语句的执行顺序来记录二进制日志。在记录二进制日志后,主库会告诉存储引擎可以提交事务了。
2.备库将主库上的日志复制到自己的中继日志(Relay Log)中
备库将主库的二进制日志复制到其本地的中继日志中。首先,备库会启动一个工作线程,称为IO线程,IO线程跟主库建立一个普通的客户端连接,然后在主库上启动一个特殊的二进制转储(binlog dump)线程(该线程没有对应的SQL命令),这个二进制转储线程会读取主库上的二进制日志中的事件。它不会对事件进行轮询。如果该线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生时才会被唤醒,备库IO线程会将接收到的事件记录到中继日志中去。
3.备库读取中继日志中的事件,将其重放到备库数据之上
备库的SQL线程执行最后一步,该线程从中继日志中读取事件并在备库执行,从而实现备库数据的更新。当SQL线程追赶上IO线程时,中继日志通常已经在系统缓存中,所以中继日志开销很低。SQL线程执行的事件也可以通过配置选项来决定是否写入其自己的二进制日志中。
总结:这种复制架构实现了获取事件和重放事件的解耦,允许这两个过程异步进行。也就是IO线程能独立于SQL线程之外工作。但也限制了复制的过程,例如主库上并发运行的查询在备库只能串行化执行,因为只有一个SQL线程来重放中继日志中的事件。
七.配置复制
假设主库ip是192.168.0.1,备库是192.168.0.2
配置的步骤:
1.在每台服务器上创建复制账号
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO repl@'192.168.0.%' IDENTIFIED BY 'password'; 如果是主备库永远不更换角色,那么只需要在主库上建立一个从库可以连接的账号例如:GRANT REPLICATION SLAVE ON *.* TO repl@'192.168.0.2' IDENTIFIED BY 'password';
2.配置主库和备库
主库需要开启一些设置,打开二进制日志并指定一个独自无二的服务器ID(server ID),在主库的my.cnf(配置文件)中修改增加 log_bin = mysql-bin 和 server_id = 10(使用默认值可能会导致与其他服务器冲突,一般使用服务器IP地址的末8位,但要保证是唯一的),然后重启MySQL,使用show master status 命令来确认二进制日志文件是否已经在主库上创建,如下
备库也需要在my.cnf中增加类似的配置,并且重启服务器,增加如下配置
log_bin = mysql-bin
server_id = 2
relay_log = /var/lib/mysql/mysql-relay-bin
log_slave_updates = 1
read_only = 1
这里server_id是必须配置,relay_log指定了中继日志的位置和命名,log_slave_updates(允许备库将其重放的事件也记录到自身的二进制日志中)
有时候只开启了二进制日志,却没开启log_slave_updates,可能会碰到一些奇怪的问题,例如,配置错误时可能会导致备库的数据被修改。如果可能的话,最好使用read_only配置选项,该选项会阻止任何没有特权权限的线程修改数据。但read_only选项常常不实用,特别是对于那些需要在备库建表的应用。
3.通知备库连接到主库并从主库复制数据
这一步是告诉备库如何连接到主库并重放其二进制日志(告知二进制日志位置)。使用CHANGE MASTER TO语句,并且允许以后指向别的从库时无须重启备库。
备库中执行命令:
mysql>CHANGE MASTER TO
>MASTER_HOST=’192.168.0.2’,
>MASTER_USER=’repl’,
>MASTER_PASSWORD=’password’,
>MASTER_LOG_FILE=’mysql-bin.000048’,
>MASTER_LOG_POS=0;
这里MASTER_LOG_POS参数设置为0,因为要从日志的开头读起。执行完这条语句后,可以通过show slave status语句来检查复制是否正确执行。
Read_Master_Log_Pos是4是因为日志文件的开头是4,0只是代表着开头。Slave_IO_State,Slave_IO_Runing和Slave_SQL_Runing这三列显示未运行,这里需要执行START SLAVE命令来启动。
再次通过show slave status语句来检查,发现IO线程和SQL线程都已经开始运行(yes),Seconds_Behind_Master的值也不再是NULL。IO线程正在等待从主库传递过来的事件,这意味着IO线程已经读取了主库所有的事件。日志位置发生了变化,如果主库上做了数据更新,就会看到备库的文件和日志位置都可能会增加。
我们还可以从线程列表中看到复制线程。在主库上可以看到由备库IO线程向主库发起的连接,使用show processlist命令查看
在备库上也可以看到两个线程,一个是IO线程,一个是SQL线程,同样使用show processlist命令查看
SQL线程的Time值代表已经空闲的时间,当SQL线程重放事件时,Info列可能显示正在执行的查询。
还没有配置过主从复制,读写分离的小伙伴们,可以按照上述的方法一步步配置。有问题的地方可以私信。
这种复制的配置,只是两台刚安装好的数据库,没有数据,但实际场景都是有一台已经运行了一段时间的主库,然后用一台新的机器与之同步。这时候就需要初始化备库或从其他服务器克隆数据到备库。有兴趣的可以去查阅资料,或者等我更新下一篇文章,哈哈。