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

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

原文地址:

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带来的运维改变

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

一、触发条件

d47e62d2b349aca45e42305ed6714efbe5ed61d9 binlog_gtid_simple_recovery=false。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 5.7.6以上版本。

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

二、本案例回顾

d47e62d2b349aca45e42305ed6714efbe5ed61d9 版本:MySQL版本 5.7.19。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 故障为:大概每半小时发生一次故障,整个MySQL压力巨大,很多简单的操作都相应缓慢。使用iotop,top等工具都发现MySQL某个线程有大量的I/O。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 分析方法:使用strace发现有大量的BINLOG文件读取。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 binlog_gtid_simple_recovery=false。
d47e62d2b349aca45e42305ed6714efbe5ed61d9 GTID关闭,中途开启,但是留下了很多未开启GTID的BINLOG。

d47e62d2b349aca45e42305ed6714efbe5ed61d9数据库没有重启,但是由于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 ,我们观察到:

0e52545ab1b769996cc0ddc1b4a10cbe6e699a11

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

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


原文发布时间为:2018-04-13
本文作者:高鹏(重庆八怪)
本文来自云栖社区合作伙伴“ 老叶茶馆”,了解相关信息可以关注“ 老叶茶馆”。
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
4月前
|
SQL 关系型数据库 MySQL
Mysql数据恢复—Mysql数据库delete删除后数据恢复案例
本地服务器,操作系统为windows server。服务器上部署mysql单实例,innodb引擎,独立表空间。未进行数据库备份,未开启binlog。 人为误操作使用Delete命令删除数据时未添加where子句,导致全表数据被删除。删除后未对该表进行任何操作。需要恢复误删除的数据。 在本案例中的mysql数据库未进行备份,也未开启binlog日志,无法直接还原数据库。
|
分布式计算 关系型数据库 MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
大数据-88 Spark 集群 案例学习 Spark Scala 案例 SuperWordCount 计算结果数据写入MySQL
167 3
|
SQL 关系型数据库 MySQL
案例剖析:MySQL唯一索引并发插入导致死锁!
案例剖析:MySQL唯一索引并发插入导致死锁!
971 0
案例剖析:MySQL唯一索引并发插入导致死锁!
|
9月前
|
关系型数据库 MySQL 大数据
大数据新视界--大数据大厂之MySQL 数据库课程设计:MySQL 数据库 SQL 语句调优的进阶策略与实际案例(2-2)
本文延续前篇,深入探讨 MySQL 数据库 SQL 语句调优进阶策略。包括优化索引使用,介绍多种索引类型及避免索引失效等;调整数据库参数,如缓冲池、连接数和日志参数;还有分区表、垂直拆分等其他优化方法。通过实际案例分析展示调优效果。回顾与数据库课程设计相关文章,强调全面认识 MySQL 数据库重要性。为读者提供综合调优指导,确保数据库高效运行。
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
1553 2
|
SQL 关系型数据库 MySQL
案例剖析,MySQL共享锁引发的死锁问题!
案例剖析,MySQL共享锁引发的死锁问题!
185 0
|
消息中间件 关系型数据库 MySQL
大数据-117 - Flink DataStream Sink 案例:写出到MySQL、写出到Kafka
大数据-117 - Flink DataStream Sink 案例:写出到MySQL、写出到Kafka
824 0
|
11月前
|
存储 SQL 关系型数据库
服务器数据恢复—云服务器上mysql数据库数据恢复案例
某ECS网站服务器,linux操作系统+mysql数据库。mysql数据库采用innodb作为默认存储引擎。 在执行数据库版本更新测试时,操作人员误误将在本来应该在测试库执行的sql脚本在生产库上执行,导致生产库上部分表被truncate,还有部分表中少量数据被delete。
293 25
|
11月前
|
SQL 关系型数据库 MySQL
数据库数据恢复——MySQL简介和数据恢复案例
MySQL数据库数据恢复环境&故障: 本地服务器,安装的windows server操作系统。 操作系统上部署MySQL单实例,引擎类型为innodb,表空间类型为独立表空间。该MySQL数据库没有备份,未开启binlog。 人为误操作,在用Delete命令删除数据时未添加where子句进行筛选导致全表数据被删除,删除后未对该表进行任何操作。
|
存储 关系型数据库 MySQL
10个案例告诉你mysql不使用子查询的原因
大家好,我是V哥。上周与朋友讨论数据库子查询问题,深受启发。为此,我整理了10个案例,详细说明如何通过优化子查询提升MySQL性能。主要问题包括性能瓶颈、索引失效、查询优化器复杂度及数据传输开销等。解决方案涵盖使用EXISTS、JOIN、IN操作符、窗口函数、临时表及索引优化等。希望通过这些案例,帮助大家在实际开发中选择更高效的查询方式,提升系统性能。关注V哥,一起探讨技术,欢迎点赞支持!
579 5

推荐镜像

更多