深入理解MySQL 5.7 GTID系列(九):实际案例一

 导 读

作者:高鹏(重庆八怪)

原文地址:

https://www.jianshu.com/p/2c25842d58d3

深入理解MySQL 5.7 GTID系列文章共十篇,本文为第四篇,点击查看:

第一篇:深入理解MySQL 5.7 GTID系列(一)

第二篇:深入理解MySQL 5.7 GTID系列(二):GTID相关内部数据结构

第三篇:深入理解MySQL 5.7 GTID系列(三):GTID的生成时机

第四篇:

深入理解MySQL 5.7 GTID系列(四):mysql.gtid_executed&PREVIOUS GTID EVENT

第五篇:深入理解MySQL 5.7 GTID系列(五)  gtid_executed&gtid_purged什么时候更新

第六篇:深入理解MySQL 5.7 GTID系列(六):MySQL启动初始化GTID模块

第七篇:深入理解MySQL 5.7 GTID系列(七)binlog_gtid_simple_recovery参数的影响总结

第八篇:深入理解MySQL 5.7 GTID系列(八):GTID带来的运维改变

该系列文章将陆续不定期更新~

本案例是一个朋友的案例,他也做过分享:

https://mp.weixin.qq.com/s/XSnFkuYzIlGWMaXIl-oPeQ

一、触发条件

  • binlog_gtid_simple_recovery=false。

  • 5.7.6以上版本。

  • GTID 关闭或者GTID中途开启有大量的未开启GTID的BINLOG。

二、本案例回顾

  • 版本:MySQL版本 5.7.19。

  • 故障为:大概每半小时发生一次故障,整个MySQL压力巨大,很多简单的操作都相应缓慢。使用iotop,top等工具都发现MySQL某个线程有大量的I/O。

  • 分析方法:使用strace发现有大量的BINLOG文件读取。

  • binlog_gtid_simple_recovery=false。

  • GTID关闭,中途开启,但是留下了很多未开启GTID的BINLOG。

  • 数据库没有重启,但是由于expire_logs_days触发了BINLOG删除。

三、故障分析

其实本案例就是前文第七部分总结中的:

Gtid关闭,simple_recovery=flase
5.7.6以上:这种方式一定得到正确的Gtid集合
重启Mysql不扫秒全部的binlog,如果是中途打开GTID重启任然需要扫描多个binlog因为需要找到Gtid event。
purge binlog或者超过参数expire_logs_days参数设置不触发全binlog扫描,如果是中途打开GTID重启
仍然需要扫描多个binlog因为需要找到Gtid event。

从案例中我们得知是中途开启的GTID,但是留下了很多未开启GTID的BINLOG,从第六部分源码bool MYSQL_BIN_LOG::init_gtid_sets()函数的分析,我们知道删除BINLOG后也会触发正向查找来获取gtid_purged(Gtid_state.lost_gtids)。当读取到第一个BINLOG的时候虽然获取到了PREVIOUS GTID EVENT但是没有GTID EVENT,而simple_recovery=flase所以需要继续查找下一个文件,直到找到同时包含PREVIOUS GTID EVENT和GTID EVENT的 那个BINLOG才会停止,那么显然这种情况下那些GTID关闭的时候生成的BINLOG将会全部扫描一遍,如果量大那么代价将是巨大的。
而案例中每半个小时会触发一次BINLOG切换,因为触发超过expire_logs_days参数设置导致BINLOG进行删除,触发了大量的BINLOG扫描。
显然有了前面的基础这个案例很容易分析。

四、案例模拟

这个案例非常好模拟。我打算直接使用strace查看。因为不是每位朋友都能方便使用GDB调试。
使用测试版本社区版本5.7.17:

+---------------+-----------+
| Log_name      | File_size |
+---------------+-----------+
| binlog.000027 |       198 |
| binlog.000028 |       198 |
| binlog.000029 |       198 |
| binlog.000030 |       198 |
| binlog.000031 |       198 |
| binlog.000032 |       198 |
| binlog.000033 |       198 |
| binlog.000034 |       198 |
| binlog.000035 |       198 |
| binlog.000036 |       198 |
| binlog.000037 |       198 |
| binlog.000038 |       198 |
| binlog.000039 |       198 |
| binlog.000040 |       198 |
| binlog.000041 |       198 |
| binlog.000042 |       198 |
| binlog.000043 |       154 |
+---------------+-----------+

mysql> show variables like '%gtid%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| binlog_gtid_simple_recovery      | OFF       |
| enforce_gtid_consistency         | ON        |
| gtid_executed_compression_period | 1000      |
| gtid_mode                        | OFF       |
| gtid_next                        | AUTOMATIC |
| gtid_owned                       |           |
| gtid_purged                      |           |
| session_track_gtids              | OFF       |
+----------------------------------+-----------+
8 rows in set (0.02 sec)
mysql> show variables like '%expir%';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| disconnect_on_expired_password | ON    |
| expire_logs_days               | 1     |
+--------------------------------+-------+
2 rows in set (0.06 sec)

然后我修改了系统时间同时MySQL开启GTID:

[root@test1 ~]# date -s '2017-12-13 10:10:10'
Wed Dec 13 10:10:10 CST 2017
mysql> set global gtid_mode=1;
Query OK, 0 rows affected (0.02 sec)

mysql> set global gtid_mode=2;
Query OK, 0 rows affected (0.01 sec)

mysql> set global gtid_mode=3;
Query OK, 0 rows affected (0.02 sec)

mysql> show variables like '%gtid_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| gtid_mode     | ON    |
+---------------+-------+
1 row in set (0.02 sec)

到一步我们已经达到了触发的标准,只要手动触发一次flush binary logs,让BINLOG刷新就会看到。当然线上是BINLOG满了做的切换。
这个时候开始做strace,并且做flush binary logs ,我们观察到:

640?wx_fmt=png

受限篇幅我这里删除了一些。我们看到很多read/lseek系统调用正是读取BINLOG的证据。
至此整个案例模拟完成。

五、总结

前文已经描述过在5.7.6以上binlog_gtid_simple_recovery应该设置为true,这样可以避免可能的大量的BINLOG的扫描。具体分析可以参考第七节和从第六部分源码bool MYSQL_BIN_LOG::init_gtid_sets()函数的分析。


对本文有任何疑问可扫码添加原文作者微信

640?wx_fmt=jpeg




640?640?640?640?

知数堂

叶金荣与吴炳锡联合打造

领跑IT精英培训

行业资深专家强强联合,倾心定制

MySQL实战/MySQL优化 /大数据实战/ Python/ SQL优化

数门精品课程

紧随技术发展趋势,定期优化培训教案

融入大量生产案例,贴合企业一线需求

社群陪伴学习,一次报名,可学1年

DBA、开发工程师必修课

上千位学员已华丽转身,薪资翻番,职位提升

改变已悄然发生,你还在等什么?

640.png?

扫码下载知数堂精品课程试听视频

(MySQL 实战/优化、大数据实战、Python开发,及SQL优化等课程)

密码:hg3h


640?wx_fmt=png

640.png? 640.png?


  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MySQL 5.7引入了GTID(Global Transaction Identifier)特性,这对于高可用性和故障恢复非常重要。GTID提供了一种跟踪跨多个数据库实例的事务的方式,使得主从复制更为可靠。下面是安装和配置MySQL 5.7 GTID主从的一般步骤: 1. **安装MySQL 5.7**: - 下载MySQL 5.7的二进制包,可以从MySQL官网下载适用于你操作系统的版本。 - 按照官方文档的指示进行安装,确保在安装过程中选择“GTID”作为复制模式。 2. **初始化主服务器**: - 配置my.cnf文件,开启GTID相关选项,例如设置`gtid_mode=ON` 和 `enforce_gtid_consistency=ON`。 - 启动MySQL服务并创建一个包含GTID的初始数据库实例。 3. **启用二进制日志**: - 在my.cnf中配置`log_bin`和`expire_logs_days`以管理二进制日志,这对主从复制至关重要。 4. **配置主从复制**: - 创建复制用户并分配合适的权限,如`REPLICATION SLAVE`。 - 在主服务器上执行`CHANGE MASTER TO`命令来指定从服务器的信息,包括GTID的位置(例如,`MASTER_GTID_FILE`和`MASTER_BINLOG_POS`)。 5. **启动从服务器**: - 使用相同的GTID配置启动从服务器。 - 运行`START SLAVE`命令,让从服务器开始同步数据。 6. **监控和调试**: - 定期检查`SHOW MASTER STATUS`和`SHOW SLAVE STATUS\G`来确保复制状态正常。 - 如果遇到问题,查看错误日志和使用`mysqlbinlog`工具分析事务历史。 **相关问题--:** 1. GTID是什么,它如何提高复制的可靠性? 2. 在配置主从复制时,如何正确设置`CHANGE MASTER TO`命令? 3. 有哪些常见的GTID复制问题及解决方法?
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值