Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL 异步复制

MySQL实现异步复制的示例

作者:V1ncent Chen

MySQL的复制就是将来自一个MySQL数据库服务器(主库)的数据复制到一个或多个MySQL数据库服务器(从库),本文主要介绍了MySQL实现异步复制的示例,感兴趣的可以了解一下

一、复制概述

MySQL的复制就是将来自一个MySQL数据库服务器(主库)的数据复制到一个或多个MySQL数据库服务器(从库)。其工作原理是通过binlog(二进制日志)记录事务变更然后传送到从库并重放事务,保持数据一致。

复制的主要步骤如下:

示意图:

如果binlog dump线程追赶上了主库,它将进入睡眠状态,直到主库发送信号量通知其有新的事件产生时才会被唤醒,备库I/O线程会将接收到的事件记录到中继日志中。

使用复制可以带来如下好处:

二、二进制日志格式

二进制日志在记录事务变更时有statement、row、mixed三种格式,通过binlog_format系统变量来设置:

statement

基于SQL语句的复制(Statement-Based Replication,SBR),将修改数据的SQL语句都会被记录到binlog中,优点是不需要记录每行的数据变化,这样二进制日志会比较少。缺点是在某些情况下不能很好工作,例如last_insert_id()、now()等非确定性函数,以及用户自定义函数(User-Defined Function,UDF)、存储过程、触发器时也易出问题。

基于行的复制(Row-Based Replication,RBR)。该格式不记录SQL语句,仅记录哪条数据被修改了,修改成了什么样子,能清楚地记录每一行数据的修改前后细节。优点是不会出现某些特定情况下的存储过程、函数或触发器的调用和触发无法被正确复制的问题。缺点是通常会产生大量的日志。

mixed

混合复制(Mixed-Based Replication,MBR)。它是STATEMENT和ROW这两种格式的混合体,默认使用STATEMENT格式保存二进制日志,对于STATEMENT格式无法正确复制的操作,会自动切换到基于ROW格式的复制操作,MySQL会根据执行的SQL语句选择日志保存方式。

二进制日志除了复制还会在数据库故障崩溃时进行恢复使用,因此建议将二进制日志和数据文件保存在不同的磁盘,减少I/O争用。三种日志格式中,理论上基于行的复制(row)更优,因为几乎没有基于行的复制模式无法处理的场景。对于所有的SQL构造、触发器、存储过程等都能正确执行,这也是MySQL8默认的日志格式。

三、复制的配置

MySQL最基本的复制是单路、异步、基于日志位置的复制。其架构是1台主库,1台或多台从库通过指定日志文件及位置连接到主库。

现有2台数据库环境如下,示例基本异步复制的配置步骤:

3.1 配置主库

为主库配置唯一的server_id并打开二进制日志,配置数据库配置文件(Redhat/CentOS默认是/etc/my.cnf)在[mysqld]选项下加入下列参数:

[mysqld]
server_id=71
log_bin = bin-log
sync_binlog = 1
innodb_flush_log_at_trx_commit =1

其中server_id和log_bin参数是必选,其他参数是可选项,根据自身需要选择:

3.2 配置从库

修改从库的配置参数,必要时重启服务器。在[mysqld]选项下加入下列参数:

server_id = 72
relay_log = relay-bin
log_bin = bin-log
log_slave_updates = 1
read_only = 1
skip_slave_start = 1

上面的配置只有server_id=72是必须的,其他都是可选项,自己可以根据需要选择:

3.3 创建复制专用用户

在主库上创建用户并赋予replication slave权限:

create user 'repuser'@'192.168.3.%' identified  by 'repP@ssword';
grant replication slave on *.* to 'repuser'@'192.168.3.%';

3.4 同步数据

大部分情况下主库都是都不是空的,这就需要在开启复制前获取主库的快照并还原到从库,保证复制开始时数据一致。主要方法有3种:

第一种方法由于需要关库,意味着业务要生产业务要暂停,通常不会采用。第二种采用mysqldump转储,适合数据量中等的情况。如果不能关库,采用mysqldump转储又太慢,可以试着采用第三方工具xtrabackup,由于是采用物理层面的数据文件备份,所以速度比mysqldump快很多。

下面示例采用mysqldump转储的方式,在主库开启一个会话执行下面语句:

flush tables with read lock;
show master status;

第一句会阻止所有的数据库变更,第二句显示当前的日志名称和位置,记录下来,这个就是复制的起点。

此时,另开一个会话获取数据快照,注意备份时第一个执行flush table with read lock的会话不能退出,否则可能会发生数据变更。

mysqldump --all-databases --master-data > dbdump.sql

导出之后第一个会话就可以退出了,或者执行unlock tables,让主库继续执行业务。

将上述转储文件传输到备库并导入:

scp dbdump.sql root@'192.168.3.72':/root

登录到备库上还原数据,此时主备库的数据已经相同,可以启动复制了:

mysql < dbdump.sql

3.5 将从库指向主库并启动复制:

在从库上执行change master to(8.0.23版本以上使用change replication source to),指定主库位置及我们在第三步建立的复制用户:

change master to
master_host = '192.168.3.71',
master_user='repuser',
master_password='repP@ssword',
master_log_file='mysql-bin.000009',
master_log_pos=1174;

最后两句master_log_file,master_log_pos就是上一步主库show master status显示的日志名和偏移量,由于我们在转储时加了--master-data选项,所以备份文件中自动会带上这个坐标,不加也可以。

启动复制:

start slave;
show slave status \G;

start slave 语句会启动从库上的I/O线程和SQL线程,并且连接到主库(主库上启动binlog dump线程)。

show slave status,我们可以看到备库的I/O和SQL线程都已经起来了,Slave_IO_State显示正在等待主库发送更多的事件。MySQL的基础异步复制就完成了。

到此这篇关于MySQL实现异步复制的示例的文章就介绍到这了,更多相关MySQL 异步复制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文