深入浅出mysql gtid_Mysql 5.7 Gtid内部学习(九) 实际案例(一)
一、触发条件
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 tables,我们观察到
mysql> flush binary logs;
Query OK, 0 rows affected (0.30 sec)
strace:
[pid 6551] 10:17:15.936738 read(62, "/mysql/mysql5.7.17/binlog.000027"..., 528) = 528 <0.000039>
[pid 6551] 10:17:15.936834 stat("/mysql/mysql5.7.17/binlog.000027", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000025>
[pid 6551] 10:17:15.936925 lseek(3, 0, SEEK_SET) = 0 <0.000017>
[pid 6551] 10:17:15.936983 read(3, "/mysql/mysql5.7.17/binlog.000043"..., 165) = 165 <0.000018>
[pid 6551] 10:17:15.937076 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000020>
[pid 6551] 10:17:15.937144 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000586>
[pid 6551] 10:17:15.937819 unlink("/mysql/mysql5.7.17/binlog.000027") = 0 <0.000109>
[pid 6551] 10:17:15.938009 stat("/mysql/mysql5.7.17/binlog.000028", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000021>
[pid 6551] 10:17:15.938119 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000020>
[pid 6551] 10:17:15.938228 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000021>
[pid 6551] 10:17:15.938314 unlink("/mysql/mysql5.7.17/binlog.000028") = 0 <0.000073>
.....
[pid 6551] 10:17:15.954677 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000019>
[pid 6551] 10:17:15.954756 unlink("/mysql/mysql5.7.17/binlog.000041") = 0 <0.000099>
[pid 6551] 10:17:15.954920 stat("/mysql/mysql5.7.17/binlog.000042", {st_mode=S_IFREG|0640, st_size=198, ...}) = 0 <0.000021>
[pid 6551] 10:17:15.955022 lstat("/mysql", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000018>
[pid 6551] 10:17:15.955087 lstat("/mysql/mysql5.7.17", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000018>
[pid 6551] 10:17:15.955159 unlink("/mysql/mysql5.7.17/binlog.000042") = 0 <0.000130>
受限篇幅我这里删除了一些。我们看到很多read/lseek系统调用正是读取binlog的证据。
至此整个案例模拟完成。
五、总结
前文已经描述过在5.7.6以上binlog_gtid_simple_recovery应该设置为true,这样可以避免可能的大量的binlog的扫描。具体分析可以参考第七节和从第六部分源码bool MYSQL_BIN_LOG::init_gtid_sets()函数的分析。
深入浅出mysql gtid_Mysql 5.7 Gtid内部学习(九) 实际案例(一)相关推荐
- Mysql 5.7 Gtid内部学习(十) 实际案例(二)
本案例是我真实遇到过的一个坑,也在前文中不止一次的提到,当时也是非常纳闷,其实知道原因后只能说为什么会这么坑. 一.触发条件 本案列我测试过4个版本 percona Mysql 5.7.14 官方社区 ...
- mysql gtidpurged_Mysql 5.7 Gtid内部学习(五) mysql.gtid_executed表/gtid_executed变量/gtid_purged变量的更改时机...
本节将集中讨论下面三种Gtid更新的时机,这部分相当重要,后面的故障案列会和这节有关.下面先来看一下他们的定义 mysql.gtid_executed表:Gtid持久化的介质,Mysql启动阶段会读取 ...
- mysql 5.6 开启gtid_MySQL 5.6 GTID 原理以及使用
简介 GTID是MySQL 5.6的新特性,其全称是Global Transaction Identifier,可简化MySQL的主从切换以及Failover.GTID用于在binlog中唯一标识一个 ...
- Mysql一些重要配置参数的学习与整理(二)
2019独角兽企业重金招聘Python工程师标准>>> 原文地址:Mysql一些重要配置参数的学习与整理(二) 上一篇,Mysql一些重要配置参数的学习与整理(一)中,我们了解和学习 ...
- mysql入门很简单系列视频-学习笔记
mysql入门很简单系列视频-学习笔记 视频链接:mysql入门很简单系列视频 https://www.bilibili.com/video/av14920200/ 以前主要就了解DDL.DML.DC ...
- MySQL 5.7 基于 GTID 的主从复制实践
MySQL 5.7 基于 GTID 的主从复制实践 Posted by Mike on 2017-07-03 运维之美 Home About Archives Tags 在 「MySQL 5.7多源复 ...
- 深入浅出Mysql - 优化篇(锁)
深入浅出Mysql - 优化篇(锁) 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供许多用户共享的资源.如何保 ...
- 深入浅出Mysql - 基础篇(列类型/运算符/函数)
深入浅出Mysql - 基础篇(列类型/运算符/函数) 每一个常量.变量和参数都有数据类型,它用来指定一定的存储格式.约束和有效范围.MySQL提供了多种数据类型,主要包括数值型.字符串类型.日期和时 ...
- Mysql一些重要配置参数的学习与整理(一)
2019独角兽企业重金招聘Python工程师标准>>> 原文地址:Mysql一些重要配置参数的学习与整理(一) 最近一直在进行mysql的学习,主要是学习mysql的一些配置参数,了 ...
最新文章
- compass安装使用960 Grid System
- 今天什么日子啊,这么倒霉。。。
- 网站站内优化新方案,SEO运营人员值得一看
- 小甲鱼python课件源代码_[Python基础] 小甲鱼零基础入门Python学习视频+全套源码课件 Python视频教程 96讲...
- C#中的cookie编程
- pcb过孔漏铜_【企业资讯】大正瑞地:专注PCB药水二十年,品质、性能可靠
- 爬虫案列:京东商城长裤信息获取
- 2020年中国基层医疗研究报告
- React基础----ReactJS的使用(一)
- php 去除空格和换行
- 要实现动态加载JS脚本有4种方法:
- 如何将照片中的文字转变成可编辑的文章(如何将书上的文字转变为可编辑的文字)
- Hi3559a移植Opencv3.0
- html rtf转换,如何使用JavaScript将HTML转换为RTF
- Re27:读论文 LADAN Distinguish Confusing Law Articles for Legal Judgment Prediction
- Python GUI教程:信号、槽、事件
- 多系统折腾记录(老电脑MBR分区)
- 数字时代:DevOps工程师的必备技能清单
- HTML没有随手机静音,华为手机静音找不到?这个功能设置好,喊一声就可以找到!...
- iOS系统字体如何使用
热门文章
- (转)C#中的委托(Delegate)和事件(Event)
- Latex的空格 转载
- spring集成compass中出现的问题和总结
- STL不是线程安全的啊
- python制作软件excel_利用Python制作一个 截图+Excel操作浏览器小工具
- Java面向对象之抽象方法抽象类、接口的使用
- bug 执行nrm 报错internal/validators.js:121 throw new ERR_INVALID_ARG_TYPE(name, ‘string‘, value);
- python2.7安装报错_python2.7源码安装方式
- python爬虫--自学笔记
- java安装选择哪个可选功能_java章节习题及期末考试题答案.doc