GreatSQL社区

搜索

GreatSQL社区

GreatSQL 异步复制及搭建

GreatSQL社区 已有 145 次阅读2024-9-11 10:00 |系统分类:运维实战

GreatSQL 异步复制及搭建

一、简介

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

二、复制过程

1-1 复制过程图

2.1 binlog日志

GreatSQL 复制是基于 binlog 日志来实现复制的

2.1.1 二进制日志输出格式比较

二进制日志格式记录内容主从同步使用场景大小性能
statement基于SQL如果使用了一些不确定性的函数和自定义函数,函数返回的数据在主从库上不一致。 比如 now(),last_insert_id()等。较小最好
row基于数据行默认使用基于row较大最差
mixed混合格式默认使用statement。 当statement无法正确复制时,采用rows居中

2.2 复制过程

  1. 主库把数据更新事件写入二进制日志。
  2. 从库的IO线程向主库请求二进制日志事件。
  3. 主库的binlog dump线程向从库IO线程发送二进制日志事件。
  4. 从库的IO线程将二进制日志事件写入中继日志。
  5. 从库的SQL线程应用中继日志中的事件。

2.3 二阶段提交

GreatSQL 包含两种记录数据变更的日志,redolog、binlog为了保证两个日志的对数据变更事件达到一致性,GreatSQL 内部使用XA来实现,其核心是两阶段提交。

2.3.1 事务提交流程

主从复制中,从库是通过binlog日志重放来实现复制。如何保证主从的数据一致性,就需要考虑如下两方面

  1. binlog记录的事务一定不比redolog少。
  2. binlog与redolog记录的事务的顺序性是一致的。

在两阶段协议中一般分为事务管理器(协调者)和若干事务执行器(参与者)两种角色。GreatSQL 内部实现的两阶段提交中,二进制日志充当了协调组角色,由它来通知InnoDB执行准备、提交和回滚。从实现角度分析,事务提交有准备阶段和提交阶段组成。两阶段提交流程如下图:

1-2事务提交流程

1、事务发起commit请求。

2、调用binlog-hton和innobase-hton的prepare方法完成第一阶段。binlog-hton的方法什么也没有做,innodb的prepare持有prepare_commit_mutex锁,将重做日志刷盘,并将事务状态设置为prepared。

3、如果事务涉及的所有存储引擎的prepare都执行成功,则调用TC_LOG_BIN:log_xid将事务写入到二进制日志。

4、最后,调用存储引擎的commit完成事务的提交,向重做日志写入commit标记,释放prepare_commit_mutex,并将事务设置为trx_not_started状态。

2.3.2 InnoDB恢复

数据库在奔溃恢复时,不同状态的事务,会进行不同的处理。

  • trx_commit_in_memory的事务,清除回滚段后,将事务设置为trx_commit_not_started。
  • trx_commit_active的事务,直接回滚。
  • trx_not_started的事务,表示事务已提交过,跳过。
  • trx_commit_prepared的事务,要根据二进制日志来决定事务是否提交,暂时跳过。

在数据库发生奔溃时,数据库根据重做日志进行数据恢复,逐个检查重做日志的每个事务状态。根据1-2的流程,如果已经进行到trx_not_started阶段,也就是存储引擎commit阶段,那么说明重做日志和二进制日志是一致的,正常根据重做日志的内容进行恢复即可。如果事务状态为trx_active,没有写入到二进制日志,就直接回滚。如果事务状态为trx_commit_prepared,要分两种情况:先检查二进制日志是否写入成功,如果没有写入成功,直接回滚,如果写入成功了,那就进行最后一步,调用存储引擎commit,更改事务状态为trx_not_started,也就是真正提交的状态,可以用作数据恢复。

由此可以,GreatSQL是以二进制日志的写入与否作为事务提交成功与否的标志。通过这种方式让InnoDB重做日志和GreatSQL服务器的二进制日志中的事务状态保持一致。两阶段提交很好的保持了数据的一致性和顺序性。

GreatSQL通过innodb_support_xa系统变量来控制innodb是否支持XA事务的两阶段提交,默认是支持。在GreatSQL8中已移除该变量,表示数据库内部一直启用innodb对XA事务两阶段提交的支持。

2.3.3 日志刷盘频率

两阶段提交只是从流程上保证了日志的一致性,如果日志在写盘期间,数据库发生了崩溃或者服务器宕机,存在日志数据丢失的风险。为了规避此类风险,我们需要配置正确的日志刷盘频率。

重做日志的刷盘频率由innodb_flush_log_at_commit_trx参数控制。二进制日志的刷盘频率由sync_binlog参数控制。

  • 重做日志刷盘方式 innodb_flush_log_at_trx_commit参数为1时,表示只要事务提交,立即将重做日志刷盘。 innodb_flush_log_at_trx_commit参数为2时,表示每秒将重做日志缓冲区的内容写入到操作系统页面缓冲,至于什么时候刷盘,由操作系统控制。 innodb_flush_log_at_trx_commit参数为0时,表示每秒将重做日志刷盘。
  • 二进制日志刷盘方式 sync_binlog参数为1时,表示只要事务提交,立即将二进制日志刷盘。 sync_binlog参数为N(N>1)时,表示N个二进制日志组提交后,将二进制日志刷盘。 sync_binlog参数为0时,表示二进制日志的刷盘由操作系统控制。

三、异步复制参数

3.1 源库和复制库常用参数说明

参数名参数值参数级别作用
binlog_do_dbschema配置文件修改二进制日志只记录该参数指定的库名产生的更新事件
binlog_ignore_dbschema配置文件修改二进制日志不记录该参数指定的库名产出的更新事件。
log_slave_updateON/OFF系统级别复制库应用中继日志中的事件是否写入二进制日志。用于复制级联,建议主库和从库都开启该参数。
replicate_do_dbschema配置文件修改只重放中继日志中该参数指定的库名的事件。
replicate_ignore_dbschema配置文件修改不重放中继日志中该参数指定的库名的事件。
replicate_wild_do_tableschema.%配置文件修改只重放中继日志中该参数指定的库名的事件。 建议使用这种方式进行复制过滤。
replicate_wild_ignore_tableschema.%配置文件修改不重放中继日志中该参数指定的库名的事件。 建议使用这种方式进行复制过滤。
skip_slave_startON/OFF只读参数复制库启动时,是否启动复制线程。 建议不开启该参数。
sql_log_binON/OFF会话级别会话端执行的更新事件是否写入二进制日志。
slave_parallel_workers0-N全局级别是否开启多线程复制, 并指定对少个线程并发应用复制事务。 参数值为0时,表示不开启。
slave_parallel_typelogical_lock database全局级别在源库二进制日志事件是以组的方式进行提交。 为了保证在从库并发的执行事务,有两种方式进行控制。 基于logical_lock的方式: 通过跟踪某一个时间点内的事务与事务之间的关系, 来决定尽可能的并发执行事务。 基于database的方式: 在不同数据库之间值的事务可以并发执行。
slave_preserve_commit_orderON/OFF全局级别在多线程复制库上, 事务的执行和提交顺序与中继日志中记录的顺序一致。
slave_pending_job_size_maxinteger全局级别在多线程复制库上, 应用队列用于保留暂未应用的事务的最大可用内存。 该参数的值不能小于源库上max_allowed_packet参数指定的值, 不然在执行大事务事会报错。
slave_max_allowed_packetinteger全局级别指定复制库上的sql线程和io线程能够处理的最大数据包, 该参数不能小于源库上max_allowed_packet指定的参数值。

四、异步复制部署

4.1 环境准备

使用两台服务器来部署一主一从的异步复制。

Master:192.168.135.183

Slave:192.168.135.142

4.2 部署数据库

安装GreatSQL数据库,见GreatSQL官方文档 https://greatsql.cn/docs/8.0.32-25/4-install-guide/3-install-with-tarball.html

4.3 配置复制

4.3.1 空库

初始安装的数据库没有任何应用数据。可以直接配置就能使用。

  • Master上的操作: greatsql> reset master;
  • Slave上的操作: greatsql> reset master; greatsql> reset slave all; greatsql> change master to master_host="192.168.135.183",master_port=3305,master_user='repl',ma ster_password='!QAZ2wsx',master_auto_position=1; greatsql> start slave; greatsql> show slave status\G

4.3.2 脱机

如果源数据库上存在应用数据,允许在一个接收的脱机时间窗口进行复制,那么我们可以直接把源库的数据文件复制到从库,再启动从库进行主从配置。

  • Master上的操作 创建用于复制的账户,并授予相应的权限。 停止源数据库服务。 复制源数据库上的数据文件到从库。 启动源数据库服务。
  • Slave上的操作 删除从库数据目录中的auto.cnf,从库在启动时会自动生成唯一的server_uuid。检查数据库配置文件确保server_id是唯一的。 启动从数据库服务。 配置主从同步关系,并启动主从同步线程。

4.3.3 联机

大多数情况下,复制被要求在不影响线上业务的情况下联机创建,而且还要求对线上源库影响越小越好。在联机情况下,我们通常采用mysqldump和xtrabackup工具复制源库到从库,配置主从同步。

mysqldump联机复制过程

  • Master上的操作 1.创建用于复制的账户
greatsql> create user repl@'%' identified with mysql_native_password by '!QAZ2wsx';
greatsql> grant replication client,replication slave on *.* to repl@'%';
greatsql> flush privileges;
  • Slave上的操作
  1. 创建源库信息
greatsql> change master to master_host='192.168.135.183',master_port=3305,master_user='repl',master_password='!QAZ2wsx';
  1. 使用mysqldump导入数据到从库,建立复制
greatsql> mysqldump --single-transaction --all-databases --master-data=1 --host=192.168.135.183 --port=3306 --user=root --password=!QAZ2wsx --default-character-set=utf8mb4 --apply-slave-statements|mysql -uroot -p!QAZ2wsx -h192.168.135.142 -P3305

重要参数说明:

  • --single-transaction参数对innodb表执行非锁定导出。此选项将事务隔离模式设置为repeatable read,并在转储数据之前向服务器发送start transaction sql语句。它仅适用于innodb等事务表,因为它会在发出start transaction时转储数据库一致状态,而不会阻塞任何应用程序。
  • --master-data参数为1时会导致转储输出包含类型change master to master_log_file='binlog.000004',master_log_pos=1230;的sql语句,该语句指示主库的二进制日志坐标(文件和偏移量)。如果选项值为2,则chang master to语句将被注释,仅提供信息,不会执行。如果未指定选项值,则默认值为1。
  • --apply-slave-statements参数会在change master to之前添加stop slave语句,被宰输出的结尾处添加start slave语句,用于开启复制。
  • --deafult-character-set参数指定默认字符集,GreatSQL的默认字符集为utf8mb4。

xtrabackup联机复制过程

  • Master上的操作 在源库上创建全量备份 $ xtrabackup --defaults-file=/mysql/conf/node13306.cnf --host='192.168.135.183' --port=3306 --user='root' --password='!QAZ2wsx' --backup --target-dir=/mysql/backup 2>backup.log 准备数据信息备份 $ xtrabackup --prepare --target-dir=/mysql/backup 2>restore.log

--prepare参数准备备份数据进行恢复。数据文件在准备之前是不一致的,因为它们是在备份程序运行的不同时间复制的,并且在这个时间段,有些数据已经发生变更。其原理是使用redolog进行后滚,使用undolog进行前滚。

  • Slave上的操作 关闭从库,在从库上删除数据库初始化生成的数据库文件。 $ rm -rf /mysql/dbdata/data/*;rm -rf /mysql/dbdata/log/* 从源库上拉取备份恢复后的数据文件。 $ scp -r [root@192.168.135.183:/mysql/backup/*](mailto:root@192.168.1.111:/mysql/backup/*) /mysql/dbdata/data $ mv binlog.* ib_logfile* undo_00* ../log/ $ chown -R mysql:mysql /mysql/dbdata 启动从数据库服务,并配置主从同步。 greatsql> service mysql start greatsql> change master to master_host="192.168.135.183",master_port=3305,master_user='repl',ma ster_password='!QAZ2wsx',master_auto_position=1;

五、异步复制常见问题说明

5.1 show slave 重点指标说明

我们在从库执行show slave status来观察主从同步的状态。

  • master_log_file:I/O线程正在读取的master binlog。
  • read_master_log_pos:I/O线程已经读取到master binlog的位置。
  • relay_log_file:SQL线程正在读取和执行的relay log。
  • relay_log_pos:SQL线程已经读取和执行relay log的位置。
  • relay_master_log_file:SQL线程最近执行的操作对应的是哪个master binlog。
  • relay_master_log_pos:SQL线程最新执行的操作对应的是master binlog的位置。
  • retrieved_gtid_set:接收到的gtid集合。
  • executed_gtid_set:已执行的gtid集合。
  • seconds_behind_master:SQL线程比IO线程慢多少。在网络正常的情况下,可以表示从库比源库慢多少。

5.2 常见错误

主从异步复制中,存在数据库丢失的可能性,导致主从数据不一致。如果数据量比较少的情况下,我们在从库执行相关的操作补齐数据后,对改事务进行跳过。

  • 源库删除一行记录,而slave上找不到改行数据进行删除操作。错误代码为1032。
  • 源库插入一行数据,而slave上表示改行数据早已存在,导致重复冲突。错误代码为1062。
  • 源库上更新一行数据,而slave上表示找不到改行数据执行更新操作,错误代码为1032。

5.3 主从数据校验

可以使用GreatSQL社区的gt-checksum工具对主从数据进行一致性校验,或者使用官方工具checksum进行数据校验。checksum工具对数据库校验时,会给表上读锁,这一点在使用时需要注意。

gt-checksum工具详见:https://gitee.com/GreatSQL/gt-checksum



评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

合作电话:010-64087828

社区邮箱:greatsql@greatdb.com

社区公众号
社区小助手
QQ群
GMT+8, 2024-10-7 06:24 , Processed in 0.015574 second(s), 9 queries , Redis On.
返回顶部