“  复制解决的基本问题是让一台服务器的数据与其他服务器保持同步。 一台主库的数据可以同步到多台备库上,备库本身也可以被配置成另外一台服务器的主库。 主库和备库之间可以有多种不同的组合方式。 《高性能MySQL》10.1复制概述

MySQL中的两种复制

MySQL支持两种复制方式:基于行的复制基于语句的复制,两者都是通过在主库(master)记录二进制文件(binlog),然后在备库(replica)重放来实现数据的异步复制。所以同一时间,主备库的内容可能不一致,并且无法保证主备之间的延迟,一些大的语句可能导致备库产生几秒、几分钟甚至几小时的延迟。

不同版本的MySQL之间可以相互复制吗?

MySQL的复制大部分是向后兼容的,即新版本的MySQL服务器可以作为老版本MySQL服务器的备库,但反过来通常是不可行的(主要指大版本:如4.1升级到5,但无论如何,最好先对复制的设置进行测试)。

复制会对性能产生影响吗?

复制通常不会增加主库的开销,主要是启用二进制日志带来的开销,但出于备份或及时从崩溃中恢复的目的,这点开销也是必要的。除此之外,每个备库也会对主库增加一些负载(例如网络I/O开销),尤其当备库请求从主库读取旧的二进制日志文件时,可能会造成更高的I/O开销。另外锁竞争也可能阻碍事务的提交。最后,如果是从一个高吞吐量(例如5 000或更高的TPS)的主库上复制到多个备库,唤醒多个复制线程发送事件的开销将会累加。

究竟是如何复制的?

  1. 首先在主库上记录二进制日志文件,在每次准备提交事务更新数据之前,主库会将本次更新的数据记录到二进制日志中,MySQL会按照事务的提交顺序来记录二进制日志而非语句的执行顺序,在记录二进制日志后,主库会告诉存储引擎进行事务的提交。
  2. 备库会启动一个I/O线程连接到主库上,然后启动一个特殊的二进制转储线程(binlog dump),用来读取二进制日志中的事件,如果该线程(binlogdump)追上了主库,则该线程会进入休眠状态,直到主库再次通知该线程有新的事件产生,备库的I/O线程会将接收到的事件记录到中继日志中(Relaylog)。
  3. 备库的SQL线程执行最后一步,从中继日志中读取事件并在备库上执行,从而实现备库数据的更新,通常SQL线程追上I/O线程时,中继日志已经在系统缓存中,所以中继日志的开销很低。

 

mysql主从复制影响主表性能 mysql主从复制问题_mysql主从复制影响主表性能

主从复制

这种复制模式架构的优缺点

实现了获取事件和重放事件的解耦,允许两个过程异步执行,也就是说I/O线程可以独立于SQL线程之外工作,但主库上并发运行的查询在备库上只能串行(单线程)执行,因为只有一个SQL线程来重放中继日志中的文件。

复制具体实现步骤

1.在服务器上创建复制账号2.配置主库和备库3.通知备库连接到主库并从主库复制数据

1.创建复制账号

mysql > GRANT REPLICATION SLAVE,REPLICATIONCLIENT ON *.* TO repl@'192.168.0.%' IDENTIFIED BY 'p4ssword';

2.配置主库和备库

在主库的my.cnf文件中增加或修改如下内容

log_bin   = mysql-binserver_id = 10

必须明确的指定一个唯一的服务器ID,默认服务器ID通常为1,使用默认值可能会导致和其他服务器的ID冲突,这里选择10来作为服务器ID(最好选择一些有意义的约定并遵循)。

如果之前没有在MySQL的配置文件中指定log-bin选项,就需要重新启动MySQL。使用SHOW MASTER STATUS命令来检查二进制文件是否已经在主库上创建,正确结果如下图

mysql主从复制影响主表性能 mysql主从复制问题_mysql主从复制影响主表性能_02

备库上也需要在my.cnf中增加类似配置,并且同样需要重启服务器

log_bin            = mysql-binserver_id          = 2# relay_log 指定中继日志的位置和命名relay_log          = /var/lib/mysql/mysql-relay-bin# log_slave_updates 允许备库将其重放的事件也记录到自身的二进制日志中log_slave_updates  = 1# read_only 会阻止任何没有特权权限的线程修改数据read_only          = 1

事实上只有server_id是必须的。这里同样使用了log_bin,并赋予了一个明确的名字。默认情况下它是根据机器名来命名的,但如果机器名变化了可能会导致问题,为了简便起见,我们将主库和备库上的log-bin设置为相同的值。当然如果你愿意的话,也可以设置成别的值。

log_slave_updates选项会给备库增加额外的工作,但有时候只开启了二进制日志却没有设置该选项可能会碰到一些奇怪的现象。

3.启动复制

这一步是告诉备库如何连接到主库并重放其二进制日志。

mysql> CHANGE MASTER TO MASTER_HOST='server1',    -> MSTER_USER='repl',    -> MSTER_PASSWORD='p4ssword',    -> MSTER_LOG_FILE='mysql-bin.000001',    -> MSTER_LOG_POS=0;

MASTER_LOG_POS(master日志读取位置、偏移量)设置为0,因为要从日志的开头读起。当执行完这条语句后,可通过SHOW MASTER STATUS语句来检查复制是否正确执行。

之后运行下面的命令开始复制

mysql> START SLAVE;

执行后再使用SHOW MASTER STATUS检查就会发现I/O线程和SQL线程都已经开始运行。

此时如果在主库做一些数据更新,备库中的数据同样会进行更新。

内容选自书籍《高性能MySQL》第10章-复制,仅作为个人备忘使用,若需了解详细细节,还请查看原书或查看官方文档。


最后,感谢那些在背后一直支持我的人