暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql主从复制架构实战(三)之GTID篇

踱岚视角 2024-09-21
2

一、导读

1.1、认识GTID

1.1.1、什么是GTID

全局事务ID,保证为每一个在主数据库上提交的事务在复制集群中可以生成一个唯一的ID,GTID包括两个值,一个是server uuid代表每个库的id值,并且唯一性,另外一个是transaction_id事务id,代表已执行事务的id,且主库与从库1:1相等。

1.2、GTID与基于二进制日志复制的区别?

两者都是基于bin_log日志复制的,二进制复制是从服务器告诉主服务器从哪个二进制日志偏移量进行增量同步,如果指定错误就会遗漏或者重复,GTID是从库把已执行事务的GTID值发送给主库,主库对比日志之后把未执行的GTID值传给从库,从而更新从库,同一个事务只在指定的从库执行一次,不会发生重复执行。

1.3、GTID模式复制使用限制

1)不能使用create table table_name select * from table_name模式的语句;

2)在一个事务中既包含事务表的操作又包含非事务表;

3)不支持CREATE TEMPORARY TABLE or DROP TEMPORARY TABLE语句操作;

4)使用GTID复制从库跳过错误时,不支持sql_slave_skip_counter参数的语法。

二、环境规划

2 

2.1、操作系统

Linux ubuntu2204 5.15.0-119-generic #129-Ubuntu SMP  Fri Aug 2 19:25:20 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

注:主从库尽量保持一致。

2.2、数据库版本

mysql  Ver  8.0.39-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))

注:主从库尽量保持一致。

2.3、存储规划

项目

项目值

备注

数据库配置文件目录

/etc/mysql

按实际调整

数据库数据存储目录

/var/lib/mysql

按实际调整

数据库日志文件目录

/var/log/mysql

按实际调整

数据库启动脚本目录

/etc/systemd/system

/etc/init.d

注:主从库尽量保持一致。

2.4、IP地址

服务器

主机名

IP地址

端口号

备注

主库

Master

192.168.56.18

3306

按实际调整

从库

Slave

192.168.56.19

3306

按实际调整

2.5、主从复制数据库初始化方式

本次采用xtraBackup对主库进行物理备份,然后在从库上进行还原的方式进行主从复制初始化工作。

当然也可以通过mysqldump进行主库逻辑导出,然后在从库上进行还原的方式进行主从复制初始化工作。

也可以通过clone技术在线搭建主从复制环境。

在后续的文章中会逐一介绍。

2.6、主从复制机制

本次采用基于row的模式对主库进行同步复制到备库。

当然也可以通过statementmixed等复制方式进行主从同步,在后续的文章中会逐一介绍。

2.7、主从复制实现方式

本文采用基于GTID方式,当然也可以基于binlogposition的方式来实现,前面的文章中已经介绍。

2.8、主从复制模式

本次采用默认的复制模式,异步复制,主服务器提交事务后立即返回,而不等待从服务器确认。

当然也可以设置为半同步复制,完全同步复制模式,在后续的文章中会逐一介绍。

2.9、主从库侧部署xtrabackup软件

2.9.1、下载

链接地址:https://www.percona.com/downloads/XtraBackup/

本次下载percona-xtrabackup-8.0.35-31版本。

2.9.2、安装

dpkg -i  percona-xtrabackup-80_8.0.35-31-1.jammy_amd64.deb

本次使用封装好的deb包(不同平台不一样)安装,当然也可以使用二进制代码编译安装。

注:主从库服务器都需要提前安装好。

2.10、数据库参数

参数名

主库

从库

备注

basedir




datadir




character-set-server

utf8mb4

utf8mb4


lower-case-table-names

1

1


default_authentication_plugin

mysql_native_password

mysql_native_password


server-id

1

2


log-bin

mysql-bin

mysql-bin


binlog-ignore

sys,mysql,

information_schema,performance_schema

sys,mysql,

information_schema,performance_schema

可逗号分隔,也可写多条

binlog-do-db

mydb

mydb

多数据库写多条

replication-do-table




replication-ignore-table

格式:库名.表名

格式:库名.表名

多表写多条

binlog_format

row

row


relay-log

mysql-relay

mysql-relay


log-error

/var/log/mysql/error.log

/var/log/mysql/error.log


port

3306

3306


expire_logs_days

14

14


slow_query_log

1

1


slow_query_log_file

/var/log/mysql/mysql-slow.log

/var/log/mysql/mysql-slow.log


long_query_time

2

2


max_binlog_size

100M

100M


read-only

0

1


gtid-mode

on

on


enforce-gtid-consistency

true

true


注:上表红色标识参数为必填。

三、新主从详细操作步骤

3 

3.1、主库侧数据库参数设置

3.1.1、非在线模式

按照上表设置数据库参数:

重启数据库服务生效:systemctl restart mysql

3.1.2、在线模式配置

配置之前,GTID相关参数如上图所示。

3.1.2.1、检查主库是否有不支持GTID的操作

set global enforce_gtid_consistency=warn;

 

让服务器在正常工作负载下运行一段时间并监控错误日志,最好包含一天负载最高的时间段,有条件建议观察2-3天。如果此步骤导致错误日志中出现任何警告,需要调整应用程序,使其仅使用与GTID兼容的功能,并且不能生成与GTID相关的任何警告。这是一个重要步骤,在进行下一步之前,必须确保错误日志中未出现警告。

3.1.2.2、设置GTID相关参数

set global enforce_gtid_consistency=true;

set global gtid_mode=off_permissive;

set global gtid_mode=on_permissive;

set global gtid_mode=on;

 

enforce-gtid-consistency启用后,MySQL服务器通过仅允许执行使GTID安全的语句来强制GTID一致性。在启用基于GTID的复制之前,必须将此选项设置为trueenforce_gtid_consistency的可配置值为:

  • false:允许事务违反GTID一致性。

  • true:不允许事务违反GTID一致性。

  • warn:允许事务违反GTID一致性,但在这种情况下会生成警告。

enforce_gtid_consistency仅在语句进行二进制日志记录时生效。如果在服务器上禁用了二进制日志记录,或者由于过滤器删除了语句而未将语句写入二进制日志,则不会对未记录的语句检查或强制执行GTID一致性。

联机设置gtid_mode时,只能基于OFFOFF_PERMISSIVEON_PERMISSIVEON顺序一次改变一步。例如,如果gtid_mode当前设置为OFF_PERMISSIVE,则可以更改为OFFON_PERMISSIVE,但不能直接更改为ON,否则会报以下错误:

完成配置之后,GTID相关数据配置如下:

3.1.2.3、GTID相关参数写入配置文件

enforce_gtid_consistency=true;

gtid_mode=on;

 

3.2、从库侧数据库参数设置

3.2.1、非在线模式

3.2.2、在线模式配置

操作步骤同3.1.2章节。

3.3、从库清空数据目录

3.3.1、停止数据库

systemctl stop  mysql

3.3.2、清空数据和日志目录

cd var/lib/mysql

rm  -rf  *

 

cd /var/log/mysql

rm  -rf  *

 

3.4、主库侧创建同步专属账号并授权

CREATE USER 'slave'@'%' IDENTIFIED WITH  mysql_native_password BY 'mysql123456';

GRANT REPLICATION SLAVE,replication  client  ON *.* TO 'slave'@'%';

flush privileges;

注:以上账户如果已经存在,则本步骤直接跳过,复用复制用户。

3.5、对主库进行备份

xtrabackup --backup --compress --compress-threads=8  --target-dir=/home/duolan/test/ --user=root --password='123456'  --host=192.168.56.18 --port=3306

 

--compress 表示采用压缩方式

--target-dir 表示备份文件存放目录,注意操作系统用户要有读写权限

 

3.6、将备份文件打包并拷贝至从库

3.6.1、备份文件打包

tar cvzfp test.tar.gz test

 

3.6.2、将打包文件拷贝至从库服务器

scp test.tar.gz root@192.168.56.19:/root/test

 

3.7、在从库上进行备份文件解压缩

tar xvzp test.tar.gz

 

以上步骤3.5——>3.7是常见的操作步骤,需要占用主库服务器本地磁盘空间,可以在主库服务器上使用以下命令行一次性完成上述任务,且不占用主库服务器本地空间:

xtrabackup --user=root --password=123456  --stream=xbstream --backup --parallel=10 |lz4|ssh root@192.168.56.19 'cat  |lz4 -d|xbstream --parallel=10 -x -C /root/test'

 

通过流式备份,结合管道,直接将备份文件流传输到从库主机,真正做到边备份、边传输、解压,一次性完成上述操作,非常高效。

 

注:需要配置主库到从库的ssh免密登录。

执行完毕之后,可以直接在从库主机/root/test目录下看到以下文件:

3.8、从库侧执行备份文件prepare预处理

xtrabackup --prepare --target-dir=/root/test

 

在进行数据库备份后,备份文件可能处于不一致的状态,因为备份过程中数据库可能正在进行写操作。--prepare命令的作用是将备份文件恢复到一个一致的状态,以便可以用于数据库的恢复。

 

具体来说,它会执行以下操作:

应用事务日志:将备份过程中未完成的事务进行回滚或提交,以确保数据库的一致性。

恢复数据文件:修复可能在备份过程中损坏的数据文件,使其可以被数据库服务器正确读取。

在使用增量备份时,需要将多个增量备份与一个基础备份进行合并。首先,对基础备份进行--prepare操作,然后依次对每个增量备份进行--prepare操作,并将它们合并到基础备份中,最终得到一个完整的、一致的备份集,可以用于数据库的恢复。

 

--target-dir 就是从库存放备份文件目录

3.9、从库侧执行恢复操作

3.9.1、文件copy-back

xtrabackup  --defaults-file=/etc/mysql/my.cnf --copy-back --parallel=10 --target-dir=/root/test

 

 

如果这里的target-dir直接是从库数据库文件目录,则无需执行本步骤

数据文件目录:

日志文件目录:

3.9.2、文件权限配置

chown -R  mysql:mysql /var/lib/mysql

 

chown -R  mysql:mysql /var/log/mysql

 

如果前面执行文件传输、解压都是用mysql用户的话,则无需执行本步骤。

3.10、从库启动数据库实例

3.10.1、创建/var/run/mysqld目录

mkdir -p  /var/run/mysqld

 

chown -R  mysql:mysql /var/run/mysqld

 

如果已经存在,可以忽略本步骤。

3.10.2、启动从库实例

mysqld_safe  --defaults-file=/etc/mysql/my.cnf &

 

注:很多人有个误区,认为搭建从库,需要提前创建个空白实例。对于逻辑备份确实如此,但对于物理备份,则无此必要,直接使用 mysqld_safe 启动还原后的备份文件即可。

3.11、从库执行同步配置

change master to  master_host='192.168.56.18',master_user='slave',master_password='mysql123456',  master_auto_position = 1;

 

master_host为主服务器的ip

master_user为连接主服务器的用户名;

master_password为连接主服务器的密码;

master_auto_position表示使用gtid模式进行复制。

 

3.12、从库侧开启同步slave进程

start slave;

3.13、从库侧查看slave状态

show slave status\G;

 

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

都为Yes则代表配置成功。

四、已有主从切换到GTID模式操作步骤

4 

如果已经在未开启GITD的情况下配置了主从复制,可以联机将复制模式修改为GTID以及自动定位。由于整个过程不需要停止MySQL实例,这种方式适合在生产环境中使用。开始前确保MySQL服务器满足以下前提条件:

  • 复制拓扑中的所有服务器都必须使用MySQL 5.7.6或更高版本。除非拓扑中的所有服务器都使用此版本,否则无法在任何单个服务器上联机启用GTID事务。

  • 所有服务器的gtid_mode默认设置为OFF

以下过程可以随时暂停,之后再恢复,这使得该过程具有容错能力。如果过程中出现任何不相关的错误,可以先暂停过程解决问题,然后再从停止的地方继续。但至关重要的一点是,在继续下一步之前必须完成之前的步骤。联机改为GTID复制的步骤如下。

4.1、在线配置GTID参数

在主从架构所涉及的数据库上分别执行:

 

1、 set global enforce_gtid_consistency=warn;

保证所有操作都与GTID兼容,并且确保错误日志中没有GTID的相关警告。如果出现警告,操作先暂停,故障排出后再继续后续步骤;

2、 set global enforce_gtid_consistency=true;   --同上

3、 set global gtid_mode=off_permissive;   --同上

4、 set global gtid_mode=on_permissive;   --同上

5、 确认主从所涉及数据库状态变量ongoing_anonymous_transaction_count0,使用以下语句查看:show status like  'ongoing_anonymous_transaction_count';

6、 如果二进制日志还用于复制以外的其它目的(如基于时间点的恢复等),需要在执行flush  logs后备份二进制日志文件。包含GTID事务的二进制日志在下一步执行之后无法使用。完成此步后,确保拓扑中的任何位置都不存在GTID事务。

7、 set global gtid_mode=on;

4.2、从库上配置同步复制

在主从架构所有从库上分别执行:

 

1、 stop slave;

2、 change master to master_auto_position = 1;

3、 start slave;

4.3、GTID参数持久化配置

在主从架构所有数据库库上分别执行:

 

在每台服务器上,将gtid-mode = onenforce_gtid_consistency=true添加到my.cnf

五、数据同步测试

5 

5.1、在主库侧mydb创建一个test

use mydb;

create table test(id int);

5.2、在从库侧查看同步情况

use mydb;

show tables;

5.3、在主库侧给表mydb.test插入记录

use mydb;

insert into test(id) values(1);

insert into test(id) values(2);

insert into test(id) values(3);

insert into test(id) values(4);

select count(1) from test;

commit;

5.4、在从库侧确认mydb.test记录同步情况

use mydb;

select count(1) from test;

5.5、再次查看主从库同步情况

5.5.1、主库侧

show master status\G;

5.5.2、从库侧

show slave status\G;


文章转载自踱岚视角,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论