Mysql主从复制

前言
有个业务是需要做多源复制, 于是学习了一下, 资料挺多的. 也解决了问题. 但是最详细的资料肯定是官方手册, 可以了解始末. 复制详见第16章的 Replication. 还有就是内部手册讲协议的,算是更加深入了解吧。

环境

Linux 平台
​MySQL 5.7.24 及以上, 存储引擎使用 InnoDB(默认),主从版本一致

原理

Mysql主从复制_第1张图片
​ MySQL 自带主从复制
​ 支持一主一从, 一主多从, MySQL 5.7以后支持多主一从

​ 工作原理
​ 从上层来看, 复制分成三步:

  • master 将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件, binary log events, 可以通过show binlog events 进行查看);

  • slave 将 master 的 binary log events 拷贝到它的中继日志(relay log);

  • slave 重做中继日志中的事件, 将改变反映它自己的数据。

一说原理,肯定很好理解,那么 MySQL 又如何实现呢?

首先要将每次数据变动记为一条 event 保存到 binlog 日志, 那么应该知道 binlog 存储在哪里? log-bin 来指定, 但是还有个附加条件, 如果开启log-bin , 那么必须指定 service_id, 且唯一 (1 到 2的32 − 1) 随便取, 否则你连MySQL服务都启动不了

单独配置账号权限来同步,没问题! grant 分分钟添加新账户

从服务器要同步哪台主服务器呢? CHANGE MASTER TO 外加一堆参数确定到唯一

怎么来同步已有数据呢? 这个确实有点繁琐, 还需锁表, 还得 dump 数据.

增量数据怎么办? binlog 上记录了position , 从指定位置开始同步 binlog

主服务器: 我就想只同步这个库给从服务器! – 安排! binlog-do-db =db_name

主服务器: 这个库是我的, 我不同步给从服务器? – OK! binlog-ignore-db=db_name

再有就是 … 详见官网文档吧!

MySQL 主从复制方案
  1. 基于 Binary Log File + Position, 这种方式要求主从之间同步 二进制文件名称及其当前事件位置

    在 bin log 中, 每次的增删改都算作一次事件(event) 记录到 binlog 中,主服务器每次的数据变动都会使得 binlog 中 position 增加, 那么开启从服务器之后,因为从服务器同步了该位置,一旦有变化则会将 binlog 中的 event 复制过来,所以也只会从记录位置开始同步主服务器的数据

  2. 基于 GTID (global transaction identifiers) , 不需要使用日志文件或这些文件中的位置

    使用 GTID 进行复制可确保主服务器和从服务器之间的一致性,只有在主服务器上提交的所有事务才同步到从服务器上

这次讨论 Binary Log File Position。

MySQL 复制同步方式
  1. 异步复制(默认): 其中一台服务器充当主服务器, 而一台或多台其他服务器充当从服务器。

  2. 半同步复制: 在返回到执行事务的会话之前, 在主块上执行提交, 直到至少一个从属确认它已接收并记录了该事务的事件为止。

  3. 延迟复制: 使从属服务器故意延迟主服务器指定时间复制

  4. 同步复制: 使用 NDB 集群

这次也就使用默认复制同步方式

MySQL 主从复制的复制方式
  1. 基于SQL语句的复制(statement-based replication,SBR)
  2. 基于行的复制(row-based replication,RBR)
  3. 混合模式复制(mixed-based replication,MBR)

主从配置

  1. 修改 M服务器
#vi /etc/my.cnf
[MySQLd]
log-bin=MySQL-bin   //[必须]启用二进制日志
server_id=222       //[必须]服务器唯一ID, 默认是0
  1. 重启M 服务器

  2. 在 M服务器 上建立帐户并授权 slave

#/usr/local/MySQL/bin/MySQL -uroot -pmttang  
MySQL> CREATE USER 'mysync'@'192.168.6.88' IDENTIFIED BY 'q123456';
MySQL> GRANT REPLICATION SLAVE ON *.* TO 'mysync'@'192.168.6.88';
  1. 获取主服务器 binlog 文件名及 position

    首先需要进行锁表,一则防止主服务器 position 变动,二是如果需要同步主服务器现有的数据,则可以使用 mysqldump 生成快照 .dump 文件

MySQL> flush tables with read lock;  # 需要保持该客户端运行状态,如果退出,则读锁将被释放
MySQL> show master status;
+------------------+----------+--------------+------------------+
| File 			   | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 	73    | 	test 	 | 	manual,mysql 	|
+------------------+----------+--------------+------------------+
  1. 修改 S服务器
#vi /etc/my.cnf
[MySQLd]
log-bin=MySQL-bin   # [可选]启用二进制日志, 开启之后从属服务器可用于数据备份和崩溃恢复, 也可以用作更复杂的复制拓扑的一部分
server_id=226       # [必须]服务器唯一ID, 默认是0
  1. 重启服务

    添加 --skip-slave-start 配置,则不会启动复制功能

  2. 导入 dump 文件

    同步主服务器已有数据,并且主服务器执行了 mysqldump 指令,生成了 .dump 文件

  3. 在 slave 中设置主配置, 使用 CHANGE MASTER TO 语句

MySQL> CHANGE MASTER TO
->     MASTER_HOST='master_host_name', 			# 主库IP
->     MASTER_PORT=master_port,					# 主库端口
->     MASTER_USER='replication_user_name',		# 访问主库且有同步复制权限的用户
->     MASTER_PASSWORD='replication_password',	# 登录密码
->     MASTER_LOG_FILE='recorded_log_file_name',# 【关键处】从主库的该 log_bin 文件开始读取同步信息, 主库 show master status 返回结果
->     MASTER_LOG_POS=recorded_log_position;	# 【关键处】从文件中指定位置开始读取, 主库 show master status 返回结果
# 也支持 SSL 设置安全复制
# -------------------------------------------------------------------
MySQL> start slave;    							# 启动从服务器复制功能
  1. 检查从服务器复制功能状态
MySQL> show slave status\G
*************************** 1. row ***************************

    Slave_IO_State: Waiting for master to send event
    Master_Host: 192.168.6.86  	# 主服务器地址
    Master_User: mysync   		# 授权帐户名
    Master_Port: 3301    		# 数据库端口
    Connect_Retry: 60
    Master_Log_File: MySQL-bin.000004
    Read_Master_Log_Pos: 600    # 同步读取二进制日志的位置
    Relay_Log_File: ddte-relay-bin.000003
    Relay_Log_Pos: 251
    Relay_Master_Log_File: MySQL-bin.000004
    Slave_IO_Running: Yes    	# 此状态必须YES
    Slave_SQL_Running: Yes      # 此状态必须YES
    Channel_Name: master_3301
    ......

# 注:Slave_IO 及 Slave_SQL 进程必须正常运行, 即 YES 状态, 否则都是错误的状态(如:其中一个 NO 均属错误)。

最后在 master 执行命令 unlock tables; 解除锁表。

那么在M 服务器上执行增改删,那么S 服务器也会同步执行。

上面只是介绍的一主多从的配置方案, 理解之后,多源复制就很简单了。

多源复制

​ 至少需要两个 M 服务器和一个 S 服务器(本文也称“合并从服务器”), M服务器还是参照之前的主配置即可。

​ 多源复制中的从服务器需要 TABLE 主信息日志和中继日志信息日志的存储库(由master_info_repositoryrelay_log_info_repository系统变量指定) 。多源复制与FILE存储库不兼容 。

合并从服务器配置也遵循从服务器,只不过还需要添加以下配置

master_info_repository=TABLE	# 用于保存的 change master to 中设定信息, 存储在 mysql.slave_master_info 中, 内容和 show slave status\G 看到的信息一样
relay_log_info_repository=TABLE # 记录的中继日志存储路径以及对应的 master binlog 文件名及 position 如下图所示

Mysql主从复制_第2张图片
多源复制中有 channel 的概念,从属服务器上的每个通道必须从不同的主服务器复制

每个主服务器都需要单独在 从服务器上 配置 change master to 并设定不同的 channel name, 以下直接复制的官网手册指令, 按需修改即可。

mysql> CHANGE MASTER TO MASTER_HOST="master1", MASTER_USER="ted", MASTER_PASSWORD="password", \
MASTER_LOG_FILE='master1-bin.000006', MASTER_LOG_POS=628 FOR CHANNEL "master_1";
mysql> CHANGE MASTER TO MASTER_HOST="master2", MASTER_USER="ted", MASTER_PASSWORD="password", \
MASTER_LOG_FILE='master2-bin.000018', MASTER_LOG_POS=104 FOR CHANNEL "master_2";

而从服务器启动复制功能,也可以按 channel 来分别启动

# 启动
mysql> START SLAVE FOR CHANNEL "master_1";
mysql> START SLAVE FOR CHANNEL "master_2";
# 停止
STOP SLAVE;  # 停止所有
STOP SLAVE FOR CHANNEL "master_1"; # 按channel 分别停止

查看状态

mysql> SHOW SLAVE STATUS FOR CHANNEL "master_1"\G
mysql> SHOW SLAVE STATUS FOR CHANNEL "master_2"\G

以上操作过程, 主从服务器配置完成。

参考资料

  1. 复制介绍

  2. MySQL 客户端/服务端协议

  3. https://www.cnblogs.com/zzpblogs/p/12881264.html

你可能感兴趣的:(MySQL,mysql)