前言
mysql的复制能减轻数据库的读负载压力。mysql的复制功能(异步,可能会导致同一时间点上数据不一致问题)是基于二进制日志增量进行的。同时建议在同一个IDC机房中进行复制,以减少网络问题带来的问题。
mysql的复制方式主要有两种,SBR(基于SQL语句复制)和RBR(基于行复制),实际生产中一般建议采用基于行的复制方式,该种方式能较好的解决线上主从服务器复制不一致的问题。
MySQL复制工作流程大致如下:主服务器将数据库变更写入二进制日志—>从服务器读取二进制文件并写入到relay_log中—>在从服务器上重放relay_log中的日志。
尤其要注意的是,安装mysql后务必开启mysql的二进制日志,有些mysql版本中默认是关闭二进制日志功能的,防止日后已经在运行中的mysql才开启是需要重启机器的,比较麻烦。
Mysql主从复制-基于GITD复制
一、GTID是什么
全局事务ID,其保证为每一个主服务器上提交的事务在复制集群中可以生成一个唯一 的ID(从服务器数据库将已执行的事务的GTID值发送给主服务器,主服务器将未执行事务的GTID值发送给从服务器,从而保证了同一个事务在指定的从服务器数据库中只执行一次)。
表示为 GTID=source_id:transaction_id,其中source_id为执行事务的主库server的UUID值,transaction_id是自增的事务ID。
二、GTID复制步骤
我这里以两台机器(Master:10.200.121.167 Slave:10.200.121.29,即一主一从)的复制拓扑架构,实现基于GITD的复制功能。
1、在主DB服务器上建立复制账号
CREATE USER 'user'@'ip段' IDENTIFIED by 'yourpassword';
GRANT replication SLAVE ON *.* TO 'user'@'ip段';
2、配置主数据库服务器
[mysqld]
#GTID:
server_id=135 #服务器id,一定要唯一
gtid_mode=on #开启gtid模式
enforce_gtid_consistency=on #强制gtid一致性
#binlog
log_bin=master-binlog
log-slave-updates=1
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
skip_slave_start=1
3、配置从数据库服务器
#基于gtid的复制
server_id=101
relay_log=/var/lib/mysql/relay_log
gtid_mode=on
enforce-gtid-consistency=on
log-slave-updates=on
read_only=on
master_info_repository=TABLE
relay_log_info_repository=TABLE
4、Slave从服务器初始化操作,将Master服务器上的数据初始化到从服务器上(可选)
xtrabackup --slave-info #方式一:推荐使用
mysqldump --master-data=2 --single-transaction #方式二
5、Slave机器上启动基于GTID的复制,user和passwd就是第一步中创建的
CHANGE MASTER TO MASTER_HOST = '主数据库服务器ip',
MASTER_USER = 'user',
MASTER_PASSWORD = 'yourpassword',
MASTER_AUTO_POSITION = 1;
MASTER_AUTO_POSITION是布尔类型,1表示开启状态
6、Slave从服务器上启动
#启动slave复制链路
mysql> start slave;
#查看slave状态
mysql> show slave status \G;
这时可在主数据库10.200.121.167上新建数据库、表数据,在从库10.200.121.29上均可以看到复制后的记录。
注意:
- 主从服务器上的防火墙均需关闭
- 主从上的server_id不能相同
- 基于GITD的复制只有在mysql版本大于5.6之后才推出的
三、如何提高Mysql的复制性能?
1、缩短主库写入二进制日志的时间,比如把在主库上执行的大事务SQL分解成小事务
2、减少二进制日志的传输时间,mysql二进制日志说明(https://blog.csdn.net/fanrenxiang/article/details/70193636)中说到,二进制日志格式建议设置为基于RBR的形式,即binlog_format=row或者binlog_format=mixed,同时设置 binlog_row_imgage=minimal来加快二进制日志的传输时间
3、从服务器上同步操作由单线程改为多线程的形式,例如在主上进行了大量并发修改,从上只有单线程的话就显得比较吃力(会阻塞),下面是从服务器上启动多线程复制过程(推荐mysql5.7以上)
stop slave;
set global slave_parallel_type='logical_clock'; #默认是database,即支持单个数据库事务
set global slave_parallel_workers=4; #默认是0
start;
show processlist \G; #查看从服务器中的复制线程数
引申阅读:
Mysql主从复制-基于日志点复制(https://blog.csdn.net/fanrenxiang/article/details/70194707)
Mysql二进制日志详解(https://blog.csdn.net/fanrenxiang/article/details/70193636)