mysql数据库的主从复制
数据库的主从复制
-
MySQL中的复制功能用于将数据变更从一个服务器(Master)复制到一个或多个从属服务器(Slave)
-
主服务器将更改写入二进制日志(binlog),从服务器请求主服务器的binlog并应用其内容日志文件的格式影响从属服务器应用更改的方式
-
MySQL支持基于语句的(statment)、基于行的(row)以及混合格式的(mixed)日志格式
-
在复制过程中主服务器使用基于行(row)的日志格式可以大幅降低主服务器和从属服务器数据不一致的情况发生
-
从属服务器数量
- 一个主服务器可以具有的从属服务器数量理论上没有限制
- 每个额外的从库都会占用主库较少资源,所以在生产环境配置从库时应该仔细斟酌每个从库的必要性
- 最佳从属服务器数量取决于许多因素:模式大小、写入次数、主服务器和从属服务器的相对性能以及 CPU 和内存可用性等因素
-
网络故障对主从复制的影响
- MySQL中的复制功能在网络故障时暂停工作,在网络故障恢复后复制工作将继续进行
- 每个从属服务器跟踪其已经处理了多少日志并在网络连接恢复时自动继续处理,此行为是自动的,不需要特殊配置
-
主库和从库的关系
- Master和Slave是一对多的关系(MySQL5.5,5.6版本)
-
一个Master主服务器可以对应多个Slave从属服务器,一个Slave从属服务器只能有一个Master主服务器
- 一个Master主服务器可以将日志传送给多个Slave从属服务器
-
一个Slave从属服务器可以作为另一个Slave从属服务器的Master主服务器,因而可以根据业务需要搭建出较复杂的复制拓扑结构
- 从MySQL5.7开始,MySQL支持多源复制(multi-source),一个slave从属服务器可以有多个master主服务器
-
主要用途
- 读写分离
- 主服务器主要用来DML操作,尽量减少SELECT查询操作
- 消耗资源的查询任务在从服务器上执行
- 服务器冗余,故障切换(fail over)
- 数据备份
- 软硬件升级
- 读写分离
实现主从复制
-
注意事项
- 所有mysql服务器应有唯一的server-id(可用范围0~4294967295,共时32位)
- 主服务器开启binlog,启用tcp/ip网络(不支持unix套接字)
- 主从复制时所使用的用户需要有REPLICATION SLAVE权限
-
实验环境
mysql-master centos7 192.168.20.30
mysql-slave centos7 192.168.20.31
-
环境配置
-
关闭防火墙
-
关闭selinux
-
配置固定ip
-
-
安装为主从mysql服务器安装mysql服务
-
为主数据库开启binlog
-
创建存放binlog日志的目录并赋予相应的权限
-
修改mysql配置文件my.cnf
-
重启数据库并查看binlog是否生成日志文件
-
-
创建主从复制时使用的用户并赋予REPLICATION SLAVE权限
-
查看主数据库的binlog信息
-
备份主数据库所有数据
mysqldump -uroot -p --all-databases --triggers --routines --events --master-data=2 --flush-logs > /root/all-master-dbs.sql #--master-data=2 记录主数据库binlog日志文件位置
-
将主数据库备份文件还原到从数据库
-
为从数据库设置server-id
-
为从数据库指定主数据库(此时数据库用户和密码为主数据库用户及密码)
change master to master_host='192.168.20.30',master_user='repl',master_password='L1g2asd.',master_port=3306,master_log_file='mysql-bin.000001',master_log_pos=617; #change master to 设置连接主数据库信息 #master_host='192.168.20.30' 指定主数据库的地址 #master_user='repl' 连接所使用的用户 #master_password='L1g2asd.' 用户密码 #master_port=3306连接端口 #master_log_file='mysql-bin.000001' 指定开始复制的binlog起始文件 #master_log_pos=617; 指定开始复制的binlog起始文件头注释号 #若主数据库服务器连接信息出现变化需要重新设置
-
启动从数据库的复制并查看状态
若出现Slave_SQL_Running为No,解决方法如下
start slave; #开启主从复制 stop slave #停止主从复制 SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; #跳过指定数量的错误事务,这里为1 #Slave_IO_Running 负责与主机的io通信 #Slave_SQL_Running 负责自己的slave mysql进程 #其他相关命令 #reset slave 直接删除master.info和relay-log.info文件,并删除所有的relay log,然后重新生成一个新的relay log,但不删除内存中保存的信息 #reset slave all 和reset slave相比会删除内存中的连接信息,使用reset slave all之前先使用stop slave命令 #reset master 删除所有index file中记录的所有binlog文件,将日志索引文件清空,创建一个新的日志文件
-
查看中继日志
-
查看连接主数据库配置信息
-
查看主从同步信息日志
-
修改配置文件,将master.info与relay-log.info保存到表中便于查看
relay_log_info_repository=table master_info_repository=table systemctl restart mysqld ---------------------------------------- mysql -uroot -p use mysql select * from slave_master_info\G select * from slave_relay_log_info\G
-
测试
-
主数据库上创建测试库和表并插入数据
-
查看从库是否同步
-
-
全局事务标识符
- 全局事务标识符 (Global Transaction Identifier, GTID) 可以唯一地标识数据库复制过程中主库binlog文件中的每个事务
- 使用GTOID时从数据库获取事务时会保留主数据库的UUID,这样每个从数据库可以确定第一个执行事务的主数据库服务器
- 从数据库不需要知道master主库具体的binlog文件和变更事件的位置坐标,因而简化了复制工作相关的配置信息
- 如果启用GTID模式,之前没有包含GTID的数据库备份不能使用,需要重新备份数据库
-
启用全局事务标识符
-
修改主从数据库配置
gtid-mode=ON #启用GTID,binlog中每个事务一起记录唯一的 GTID enforce-gtid-consistency #禁止无法以事务安全方式记录的事件
-
从库关闭数据库复制并清空连接参数
-
重新设置连接参数
change master to master_host='192.168.20.30',master_user='repl',master_password='L1g2asd.',master_port=3306,master_auto_position=1;
-
重新启动主从复制并查看状态
-
-
测试
-
主库创建新的数据库和表
-
查看从库是否同步
-
配置多主循环复制A-->B-->C-->A
-
实验环境
- mysql-masterA centos7 192.168.20.30
- mysql-masterB centos7 192.168.20.31
- mysql-masterC centos7 192.168.20.32
-
数据库的安装参考Mysql之数据库的安装与基本操作
-
修改masterA的mysql主配置文件如下
-
停止之前设置的主从复制并清空日志
-
修改masterC mysql服务配置如下
user=mysql character-set-server=utf8 explicit_defaults_for_timestamp server-id=32 log-bin=/binlogs/mysql-bin gtid-mode=ON enforce-gtid-consistency log-slave-updates
-
将masterA主库的备份还原至masterC 服务器上
-
修改masterB mysql配置
-
将masterA的主库设置为masterC
change master to master_host='192.168.20.32',master_user='repl',master_password='L1g2asd.',master_port=3306,master_auto_position=1;
-
将masterB的主库设置为masterA
change master to master_host='192.168.20.30',master_user='repl',master_password='L1g2asd.',master_port=3306,master_auto_position=1;
-
将masterC的主库设置为masterB
change master to master_host='192.168.20.31',master_user='repl',master_password='L1g2asd.',master_port=3306,master_auto_position=1;
-
启动A、B、C数据库的主从复制
-
测试
- masterA主机上创建测试数据库和表
- 查看masterB和masterC是否自动进行同步
- masterA主机上创建测试数据库和表
-
GTID跳过事务冲突:
-
用于代替原来的set global sql_slave_skip_counter = 1
-
由于在这个GTID必须是连续的,正常情况同一个服务器产生的GTID是不会存在空缺的。所以不能简单的skip掉一个事务,只能通过注入空事物的方法替换掉一个实际操作事务
-
注入空事物的方法:
stop slave; set gtid_next='xxxxxxx:N'; #'xxxxxxx:N'为原先要跳过的事务的日志文件和起始头注释号 begin;commit; #使用空事务替代要跳过的事务 set gtid_next=automatic; start slave;
-