iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >技术分享 | Xtrabackup 备份中 Xtrabackup_binlog_info 文件记录的 GTID 信息是否准确?
  • 846
分享到

技术分享 | Xtrabackup 备份中 Xtrabackup_binlog_info 文件记录的 GTID 信息是否准确?

摘要

Xtrabackup 是由 percona 开源的免费数据库热备份软件,它能对 InnoDB 和 XtraDB 存储引擎的数据库非阻塞地备份。 为了方便建立从库,Xtrabackup 在备份完成后会将 binlog position 与

技术分享 | Xtrabackup 备份中 Xtrabackup_binlog_info 文件记录的 GTID 信息是否准确?


Xtrabackup 是由 percona 开源的免费数据库热备份软件,它能对 InnoDB 和 XtraDB 存储引擎的数据库非阻塞地备份。 为了方便建立从库,Xtrabackup 在备份完成后会将 binlog position 与 GTID 的相关信息保存于 xtrabackup_binlog_info 文件中。 但是当你使用 Xtrabackup 生成的备份建立一个从库时,会发现恢复后的实例执行 show master status,显示的 Executed_Gtid_Set 与 xtrabackup_binlog_info 文件中记录的信息并不一致,而且使用 Xtrabackup 2.4 与 8.0(对 Mysql 8.0 进行备份)生成的备份在恢复后,信息不一致的表现又不相同。本篇文章主要针对该现象进行简单的分析。

一、Xtrabackup 2.4.18 for mysql 5.7.26

现象

使用 Xtrabackup 工具备份后,xtrabackup_binlog_info 文件记录的信息如下:

# cat xtrabackup_binlog_info
mysql-bin.000003    86412752    55d3D9b9-4d49-11ea-932c-02000aba3fa6:1-595859

将该备份恢复至一个新实例并启动该实例,执行 show master status; 查看信息:

mysql> show master statusG
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 154
     Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 55d3d9b9-4d49-11ea-932c-02000aba3fa6:1-326661
1 row in set (0.00 sec)

此时会发现使用备份恢复的实例显示已执行过的 GTID 是 1-326661,而备份文件显示的是 1-595859,这是否表示两者相差的 GTID:326662-595859 代表的事务丢失了? 通过对原实例(进行备份的实例)的 binlog 进行解析,来查询 GTID:326662-595859 这部分事务所生成的数据在新实例(通过备份恢复的实例)上是否存在。可以发现 GTID:326662-595859 这部分事务的数据都存在于新实例上,也就是说数据与 xtrabackup_binlog_info 文件记录的是一致的,只不过与 show master status 命令获取的信息的不一致。

原因分析

首先我们要清楚 Xtrabackup 2.4 的备份流程,大致如下: 1.start backup 2.copy ibdata1 / copy .ibd file 3.Excuted ftwrl 4.backup non-InnoDB tables and files 5.Writing xtrabackup_binlog_info 6.Executed FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS 7.Executed UNLOCK TABLES 8.Copying ib_buffer_pool 9.completed OK! 结合备份时的 general log 可知,Xtrabackup 在执行 ftwrl 并备份完所有非 InnoDB 表格的文件后通过 show master status 获取了 binlog position 和 GTID 的信息,将其记录到 xtrabackup_binlog_info 文件中。

那么 show master status 获取的是哪些信息?

该命令提供本实例的 binlog 文件的状态信息,显示正在写入的 binlog 文件,以及当前的binlog position,并且 MySQL 5.7 在 MySQL 库下引入了 gtid_executed 表,该表会记录当前执行过的 GTID。

那么目前看来问题可能就出在 gtid_executed 表格上,通过测试和官方文档提供的信息可知,该表格虽然是 InnoDB 表,但是其中的数据并非是实时更新的,且该表格记录信息的方式存在以下两个情况: 1.如果禁用了 log_bin,实例不会在该表格记录任何信息;若从库的 log_slave_updates 为 OFF,那么从库会在应用 relay-log 中的每个事务时执行一次 insert mysql.gtid_executed 的操作。 2.如果启用了 log_bin,则该表格记录的是在 binlog 发生切换(rotate)的时候直到上一个 binlog 文件执行过的全部 GTID,而此时 show master status 获取的 Gtid 信息不再由 mysql.gtid_executed 表提供,而是由全局系统变量 gtid_exected 提供;如果服务器意外停止,则当前 binlog 文件中的 Gtid 集合不会保存在 mysql.gtid_executed 表中,在实例恢复期间,这些 Gtid 从 binlog 文件中读取并添加到表中。

小结

所以当备份恢复时,实际 show master status 可能会出现以下情况: 1.当 log_bin 禁用或者 log_slave_updates 为 OFF 时,备份恢复后的实例 show master status 显示为空。 2.当开启了 log_bin,但是该实例并未发生过 binlog 的切换时,备份恢复后的实例 show master status 显示也为空。 3.当开启了 log_bin,其该实例的 binlog 发生过切换时,备份恢复后的实例 show master status 显示的信息会比 xtrabackup_binlog_info 文件中记录的 GTID 缺失一部分,这一部分就是 mysql.gtid_executed 表格未记录的部分。

二、Xtrabackup 8.0.8 for MySQL 8.0.18

现象

使用 Xtrabackup 工具备份后,xtrabackup_binlog_info 文件记录的信息如下:

# # cat xtrabackup_binlog_info
binlog.000033    1459    70ec927f-4c6d-11ea-b88c-02000aba3fb1:1-621683

查看备份实例相对应的 binlog 解析后的内容:

# mysqlbinlog -vv binlog.000033 | less
定位至 70ec927f-4c6d-11ea-b88c-02000aba3fb1:621683

# at 508
#200213 13:46:47 server id 663728  end_log_pos 583      GTID    last_committed=0        sequence_number=2       rbr_only=yes    original_committed_timestamp=1581572807720907   immediate_commit_timestamp=15815728
07720907     transaction_length=317
;
# original_commit_timestamp=1581572807720907 (2020-02-13 13:46:47.720907 CST)
# immediate_commit_timestamp=1581572807720907 (2020-02-13 13:46:47.720907 CST)
;
;
;
SET @@SESSION.GTID_NEXT= "70ec927f-4c6d-11ea-b88c-02000aba3fb1:621683";
# at 583
#200213 13:46:47 server id 663728  end_log_pos 659      Query   thread_id=214   exec_time=0     error_code=0
SET TIMESTAMP=1581572807;
BEGIN
;
# at 659
#200213 13:46:47 server id 663728  end_log_pos 708      Rows_query
# insert into t1 values(null,2)
# at 708
#200213 13:46:47 server id 663728  end_log_pos 758      Table_map: `mysqlslap`.`t1` mapped to number 314
# at 758
#200213 13:46:47 server id 663728  end_log_pos 798      Write_rows: table id 314 flags: STMT_END_F


BINLOG "
x+JEXh2wIAoAMQAAAMQCAACAAB1pbnNlcnQgaW50byB0MSB2YWx1ZXMobnVsbCwyKQ==
x+JEXhOwIAoAMgAAAPYCAAAAADoBAAAAAAEACW15c3Fsc2xhcAACdDEAAgMDAaiBAQA=
x+JEXh6wIAoAKAAAAB4DAAAAADoBAAAAAAEAAgAC/wCKAAEAAgAAAA==
";
### INSERT INTO `mysqlslap`.`t1`
### SET
###   @1=65674 
###   @2=2 
# at 798
#200213 13:46:47 server id 663728  end_log_pos 825      Xid = 2436045
COMMIT;

可以发现该文件提供的 binlog position 与 GTID 并不对应。而 binlog.000033:1459 对应的 GTID 是 70ec927f-4c6d-11ea-b88c-02000aba3fb1:621685 提交后的下一个位置:

# at 1142
#200213 13:46:47 server id 663728  end_log_pos 1217     GTID    last_committed=2        sequence_number=4       rbr_only=yes    original_committed_timestamp=1581572807724646   immediate_commit_timestamp=15815728
07724646     transaction_length=317
;
# original_commit_timestamp=1581572807724646 (2020-02-13 13:46:47.724646 CST)
# immediate_commit_timestamp=1581572807724646 (2020-02-13 13:46:47.724646 CST)
;
;
;
SET @@SESSION.GTID_NEXT= "70ec927f-4c6d-11ea-b88c-02000aba3fb1:621685";
# at 1217
#200213 13:46:47 server id 663728  end_log_pos 1293     Query   thread_id=215   exec_time=0     error_code=0
SET TIMESTAMP=1581572807;
BEGIN
;
# at 1293
#200213 13:46:47 server id 663728  end_log_pos 1342     Rows_query
# insert into t1 values(null,2)
# at 1342
#200213 13:46:47 server id 663728  end_log_pos 1392     Table_map: `mysqlslap`.`t1` mapped to number 314
# at 1392
#200213 13:46:47 server id 663728  end_log_pos 1432     Write_rows: table id 314 flags: STMT_END_F


BINLOG "
x+JEXh2wIAoAMQAAAD4FAACAAB1pbnNlcnQgaW50byB0MSB2YWx1ZXMobnVsbCwyKQ==
x+JEXhOwIAoAMgAAAHAFAAAAADoBAAAAAAEACW15c3Fsc2xhcAACdDEAAgMDAAIBAQA=
x+JEXh6wIAoAKAAAAJgFAAAAADoBAAAAAAEAAgAC/wCMAAEAAgAAAA==
";
### INSERT INTO `mysqlslap`.`t1`
### SET
###   @1=65676 
###   @2=2 
# at 1432
#200213 13:46:47 server id 663728  end_log_pos 1459     Xid = 2436047
COMMIT;
# at 1459

再看将备份恢复到一个新实例并启动后,执行 show master status 显示的信息:

mysql> show master statusG
*************************** 1. row ***************************
             File: binlog.000034
         Position: 191
     Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 70ec927f-4c6d-11ea-b88c-02000aba3fb1:1-621685
1 row in set (0.00 sec)

可以发现与 Xtrabackup 2.4 不同的是,该备份的 xtrabackup_binlog_info 文件记录的信息并不准确,而备份恢复后显示的信息却是准确的。

原因

首先我们来看一下 Xtrabackup 8.0 针对 MySQL 8.0 备份的大致过程: 1.start backup 2.copy .ibd file 3.backup non-InnoDB tables and files 4.Executed FLUSH NO_WRITE_TO_BINLOG BINARY LOGS 5.Selecting LSN and binary log position from p_s.log_status 6.copy last binlog file 7.Writing /mysql/backup/backup/binlog.index 8.Writing xtrabackup_binlog_info 9.Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS 10.copy ib_buffer_pool 11.completed OK!

由以上步骤可知,Xtrabackup 8.0 对 MySQL 8.0 的备份与 Xtrabackup 2.4 略有不同,根据 percona 官方文档的信息,当 MySQL 8.0 中仅存在 InnoDB 引擎的表格时,不再执行ftwrl(当存在非 InnoDB 的表格或者使用 --slave-info 选项时会执行),而是根据上述步骤的第 5 步,Xtrabackup 8.0 会通过

SELECT server_uuid, local, replication, storage_engines FROM perfORMance_schema.log_status

来获取 LSN 、binlog position and Gtid。 1.performance_schema.log_status 是 MySQL 8.0 提供给在线备份工具获取复制日志文件信息的表格。查询 log_status 表时,服务器将阻止日志的记录和相关的更改来获取足够的时间以填充该表,然后释放资源。Log_status 表通知在线备份工具应记录主库的 binlog 的哪个位点和 gtid_executed 的值,还有每个复制通道的 relay log。它还为各个存储引擎提供了相关信息,例如 InnoDB 存储引擎使用的最后一个日志序列号(LSN)和最后一个检查点的 LSN。 2.经过测试发现,当无数据写入时,performance_schema.log_status 提供的 binlog position 与 GTID 是一致的,但是当有大量数据持续写入时,该表格提供的 binlog position 与 GTID 信息将不再一致,如下图: 3.既然 performance_schema.log_status 提供的信息不一致,那么为什么备份恢复后,GTID 没有缺失?这是因为 Xtrabackup 8.0 在备份过程中多了两步操作,FLUSH NO_WRITE_TO_BINLOG BINARY LOGS 和 copy binlog,Xtrabackup 8.0 在备份完非 InnoDB 表格的文件时会先切换 binlog,然后将切换后的 binlog 也进行备份,这样使用该备份恢复的新实例在启动后不仅会读取 gtid_executed 表,也会读取 binlog 文件来更新 GTID,就可以保持与备份时 xtrabackup_binlog_info 文件记录的 binlog position 保持一致(需要注意的是 MySQL 8.0 的 gtid_executed 表格不再是当 binlog 切换时更新,而是会不断的实时更新,但需要注意在有大量数据写入时也不能做到和全局变量 gtid_exeuted 保持严格一致)。 4.当 MySQL 8.0 中存在非 InnoDB 的表格,比如 MyISAM 表时,Xtrabackup 8.0 会在执行完 FLUSH NO_WRITE_TO_BINLOG BINARY LOGS 后执行 ftwrl,此时查询 performance_schema.log_status 得到的 binlog position 与 GTID 是一致的,且备份恢复后 show master status 显示的信息也与 xtrabackup_binlog_info 文件记录的信息一致。

总结

Xtrabackup 2.4 备份后生成的 xtrabackup_binlog_info 文件记录的 GTID 信息是准确的,但是备份恢复后 show master status 显示的 GTID 是不准确的。 2.Xtrabackup 8.0 在备份只有 InnoDB 表的实例时,xtrabackup_binlog_info 文件记录的 GTID 信息不一定是准确的,但是备份恢复后 show master status 显示的 GTID 是准确的。 3.Xtrabackup 8.0 在备份有非 InnoDB 表格的实例时,xtrabackup_binlog_info 文件记录的 GTID 信息是准确的,备份恢复后 show master status 显示的 GTID 也是准确的。

您可能感兴趣的文档:

--结束END--

本文标题: 技术分享 | Xtrabackup 备份中 Xtrabackup_binlog_info 文件记录的 GTID 信息是否准确?

本文链接: https://www.lsjlt.com/news/4846.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • oracle怎么查询当前用户所有的表
    要查询当前用户拥有的所有表,可以使用以下 sql 命令:select * from user_tables; 如何查询当前用户拥有的所有表 要查询当前用户拥有的所有表,可以使...
    99+
    2024-05-14
    oracle
  • oracle怎么备份表中数据
    oracle 表数据备份的方法包括:导出数据 (exp):将表数据导出到外部文件。导入数据 (imp):将导出文件中的数据导入表中。用户管理的备份 (umr):允许用户控制备份和恢复过程...
    99+
    2024-05-14
    oracle
  • oracle怎么做到数据实时备份
    oracle 实时备份通过持续保持数据库和事务日志的副本来实现数据保护,提供快速恢复。实现机制主要包括归档重做日志和 asm 卷管理系统。它最小化数据丢失、加快恢复时间、消除手动备份任务...
    99+
    2024-05-14
    oracle 数据丢失
  • oracle怎么查询所有的表空间
    要查询 oracle 中的所有表空间,可以使用 sql 语句 "select tablespace_name from dba_tablespaces",其中 dba_tabl...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限设置
    答案:要创建 oracle 新用户,请执行以下步骤:以具有 create user 权限的用户身份登录;在 sql*plus 窗口中输入 create user identified ...
    99+
    2024-05-14
    oracle
  • oracle怎么建立新用户
    在 oracle 数据库中创建用户的方法:使用 sql*plus 连接数据库;使用 create user 语法创建新用户;根据用户需要授予权限;注销并重新登录以使更改生效。 如何在 ...
    99+
    2024-05-14
    oracle
  • oracle怎么创建新用户并赋予权限密码
    本教程详细介绍了如何使用 oracle 创建一个新用户并授予其权限:创建新用户并设置密码。授予对特定表的读写权限。授予创建序列的权限。根据需要授予其他权限。 如何使用 Oracle 创...
    99+
    2024-05-14
    oracle
  • oracle怎么查询时间段内的数据记录表
    在 oracle 数据库中查询指定时间段内的数据记录表,可以使用 between 操作符,用于比较日期或时间的范围。语法:select * from table_name wh...
    99+
    2024-05-14
    oracle
  • oracle怎么查看表的分区
    问题:如何查看 oracle 表的分区?步骤:查询数据字典视图 all_tab_partitions,指定表名。结果显示分区名称、上边界值和下边界值。 如何查看 Oracle 表的分区...
    99+
    2024-05-14
    oracle
  • oracle怎么导入dump文件
    要导入 dump 文件,请先停止 oracle 服务,然后使用 impdp 命令。步骤包括:停止 oracle 数据库服务。导航到 oracle 数据泵工具目录。使用 impdp 命令导...
    99+
    2024-05-14
    oracle
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作