pt-heartbeat工具监控MySQL复制延迟
pt-heartbeat工作原理:
1,在主库上的某个数据库A中创建一张heartbeat表,按照一定的时间频率更新该表的字段(把时间更新进去)。
2,从主库连接到从上的这个数据库A中检查复制的时间记录,和从库的当前系统时间进行比较,得出时间的差异。
使用方法:
在主库上执行:
[root@:Test: ~/tidb-bench/sysbench]#pt-heartbeat --database sbtest2 --create-table --update --daemonize -uroot -p123456
这里--database表示要指定是哪个数据库。 而--create-table表示在那个数据库下创建heartbeat表来进行检测。--update表示每秒更新一次heartbeat时间记录。--daemonize表示以守护进程的方式运行此命令。-u以及-p都填写主库的用户名和密码。
接下来继续在主库上执行:
[root@:Test: ~/tidb-bench/sysbench]#pt-heartbeat -uroot -p123456 -h 172.31.26.133 -D sbtest2 --master-server-id= --monitor
这里-u和-p都是连接主库的MySQL用户和密码。但是-h后接从库的IP。-D后接数据库。--master-server-id后接主库的server-id。--monitor表示监控主从延迟值(也可以指定为--check,表示只输出一次,可用于脚本处理)。
我下面这个是下午测试的主从延迟
.00s [ .52s, .31s, .58s ]
.00s [ .78s, .54s, .01s ]
.00s [ .07s, .78s, .43s ]
其中第一列表示此时此刻的延迟,后面的三列分别表示:1分钟、5分钟、15分钟内的平均延迟时间。
在发现主从延迟的情况下,我们就要开始定位主从延迟的原因是什么。
如何定位同步延迟
MySQL 同步是通过两个线程完成的:IO_THREAD 和SQL_THREAD。IO_THREAD 与master端链接并且读取它的二进制日志事件,同时将读到的数据复制写入本地的中继日志。另一方面,SQL_THREAD从中继日志中的事件,并且在slave端尽快执行。如果发现同步延迟了,那第一步就是要确定是哪个线程引起的问题。
一般来说,I/O线程并不会造成很大的同步延迟,因为它只负责从master端读取二进制日志。然而这还是得看两个服务器之间的网络链接状况和延迟。slave端的I/O线程可能会因为带宽被占用的太多而运行缓慢。通常如果IO_THREAD可以较快地读取二进制日志并且写入中继文件,那么这表示IO_THREAD不是slave落后的罪魁祸首。
另一方面,如果是SQL_THREAD造成同步延迟的话,那很可能是因为获取的那些请求在slave端执行消耗了很长的时间。这种情况有时是因为主从两个机子的硬件性能差别导致的,也可能是由于不同的索引配置导致的,也有可能是负荷不同导致的。另外,slave的OLTP有时可能会因为加锁策略而导致同步延迟。举个例子,如果存在一个长时间运行的MyISAM读取操作,则可能会阻塞SQL线程,或者InnoDB上的数据交换会造成IX锁并锁住SQL县城的DDL。另外,如果把MySQL 5.6版本之前的单线程slave这种情况也算在里面的话,那也可能导致slave端的SQL_THREAD延迟。
让我来通过master和slave端的状态来展示一些例子,并分析是IO_THREAD还是SQL_THREAD导致的延迟。
mysql-master> SHOW MASTER STATUS;
+------------------+--------------+------------------+------------------------------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+--------------+------------------+------------------------------------------------------------------+
| mysql-bin.018196 | 15818564 | | bb11b389-d2a7-11e3-b82b-5cf3fcfc8f58:1-2331947 |
+------------------+--------------+------------------+------------------------------------------------------------------+
mysql-slave> SHOW SLAVE STATUSG
*************************** 1. row ***************************
Slave_IO_State: Queueing master event to the relay log
Master_Host: master.example.com
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.018192
Read_Master_Log_Pos: 10050480
Relay_Log_File: mysql-relay-bin.001796
Relay_Log_Pos: 157090
Relay_Master_Log_File: mysql-bin.018192
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 5395871
Relay_Log_Space: 10056139
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 230775
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2
Master_UUID: bb11b389-d2a7-11e3-b82b-5cf3fcfc8f58:2-973166
Master_Info_File: /var/lib/mysql/i1/data/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Reading event from the relay log
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: bb11b389-d2a7-11e3-b82b-5cf3fcfc8f58:2-973166
Executed_Gtid_Set: bb11b389-d2a7-11e3-b82b-5cf3fcfc8f58:2-973166,
ea75c885-c2c5-11e3-b8ee-5cf3fcfc9640:1-1370
Auto_Position: 1
我们很容易可以看出slave端的IO_THREAD已经落后,并且因此SQL_THREAD也落后了。我们可以看到master端的日志文件是mysql-bin.018196(通过master状态的文件参数可以看到),而slave的IO_THREAD正在读取的是mysql-bin.018192(slave状态中的Master_Log_File),这意味着slave的IO_THREAD正在读取的是后者而master端在写的是前者,所以slave的IO_THREAD落后了4个binlogs文件。同时,slave的SQL_THREAD正在读取文件mysql-bin.018192(slave状态的Relay_Master_Log_File)。这意味着slave的SQL_THREAD处理时间的速度足够快,但是他也有所落后了,这从slave状态的Read_Master_Log_Pos 和 Exec_Master_Log_Pos可以看出。
你可以通过 Read_Master_Log_Pos – Exec_Master_Log_Pos 得到的差值来计算SQL_THREAD的落后,但前提是Master_Log_File和Relay_Master_Log_File是相同的。这可以让你大概知道slave的 SQL_THREAD 处理事件的速度。正如我前面所说的,在这个例子中slave的IO_THREAD也处于落后状态,所以SQL_THREAD 也落后了。关于slave的状态相关参数,可以参考这篇文章。
另外Seconds_Behind_Master参数显示slave端存在巨大的延迟。然而这可能会产生一些误导,因为这个参数是通过计算最新获取的中继日志和正在执行的中继日志的时间戳差值得到的。如果还有部分master端的日志没有获取,那么这样计算出来的就不是和master端真正的时间差值。你可以通过使用 Percona Toolkit. 的pt-heartbeat 来获取更加准确的延迟时间。所以到目前为止我们已经知道了如何判别是哪一个县城导致了slave端的同步落后,接下来我将介绍一些解决方案和建议。
关于造成同步延迟的原因和一些解决方案的建议
一般如果slave的 IO_THREAD落后是因为网络速度慢导致的。大部分情况下打开 slave_compressed_protocol 可以缓解这个症状。另外,如果不需要紧急备份还原的话就关掉slave的二进制文件记录功能,以此来环节IO上的压力。
为了最小化slave的SQL_THREAD 延迟,则需要优化各个请求。我的建议是打开 log_slow_slave_statements 配置来找到slave端执行时间超过long_query_time 的请求语句。如果要获取更多关于请求的性能,可以将log_slow_verbosity 配置为“full”。
这样我们就可以观察到slave的SQL_THREAD 的那些查询请求消耗了多少时间。读者可以很据我之前的那篇文章来了解如何通过上述提到的配置选项来记录执行较慢的请求日志。log_slow_slave_statements作为提醒功能的日志第一次出现在Percona Server 5.1中,而现在已经是MySQL 5.6.11版本后的普通功能。在更早版本的MySQL Server中log_slow_slave_statements是作为命令行选项存在的。更多的细节可以参考 这篇文章 关于Percona Server特有的log_slow_verbosity功能。
另外还有一个造成slave的SQL_THREAD延迟的可能:如果你使用基于行的binlog格式,并且某些表缺少主键或者唯一键则所有的SQL_THREAD会扫描全表并造成同步延迟。所以需要确保你的表有主键或者唯一键。
此外:要多参考MySQL官方文档:https://dev.mysql.com/doc/refman/5.5/en/show-slave-status.html
在定位线程上多关注这几个:
一般上而言I/O线程不会造成过大的延迟,主要的延迟还是在SQL线程上:
Master_Log_File:表示从库I/O线程当前读取Binlog的文件名,如果比主库当前的binlog日志还小的话说明从库I/O接受主库的日志慢了。
Read_Master_Log_File:表示SQL线程正在应用的Relay Log对应的Binlog,如果这个binlog文件比较老,说明SQL线程应用日志的速度过慢,因此基本可以判断出延迟的线程是SQL线程了。
上面两个多用于进行比较。
Read_Master_Log_Pos:表示从库I/O线程读取主库Binlog的位置。
Exec_Master_Log_Pos:表示SQL线程正在应用Relay Log的位置对应于主库Binlog的位置。
你可以通过 Read_Master_Log_Pos – Exec_Master_Log_Pos 得到的差值来计算SQL_THREAD的落后,但前提是Master_Log_File和Relay_Master_Log_File是相同的
pt-heartbeat工具监控MySQL复制延迟的更多相关文章
- zabbix利用percona-toolkit工具监控Mysql主从同步状态
一.下载percona-toolkit工具包 percona-toolkit是一组高级命令行工具的集合,可以查看当前服务的摘要信息,磁盘检测,分析慢查询日志,查找重复索引,实现表同步等等. [root ...
- mysql复制延迟监控脚本
#!/bin/sh #ocpyang@126.com #repdelay.sh #查看复制延迟详细多少event #####1.juede the rep slave status export bl ...
- percona-toolkit工具检查MySQL复制一致性及修复
利用percona-toolkit工具检查MySQL数据库主从复制数据的一致性,以及修复. 一. pt-table-checksum检查主从库数据的一致性 pt-table-c ...
- mysql复制延迟排查
今天收到报警,提示从库延时,首先当然是上去查看情况,首先查看机器负载,如下: 可以看到使用cpu已经100%,io没有等待.那么查看mysql是什么情况,执行show processlist没有发现任 ...
- MySQL至TiDB复制延迟监控
因生产环境mysql中有较多复杂sql且运行效率低,因此采用tidb作为生产环境的从库进行部分慢sql及报表的读写分离.其中MySQL至TIDB采用Syncer工具同步.关于TIDB的安装及Synce ...
- LR如何利用siteScope监控MySQL性能
本次实验,是在自己的电脑上使用APMServ5.2.6部署Discuz2.X论坛下,对该论坛的数据库MySQL5.1进行性能测试的,下面讲述LoadRunner在设计场景时,如何利用siteScope ...
- Mysql 复制工具(percona-toolkit)
Mysql 复制工具 1.percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统任务,这些任务包括: 检 ...
- percona-toolkit系列之介绍和安装(mysql复制工具)
percona-toolkit使用教程(一) 一.percona-toolkit简介 percona-toolkit是一组高级命令行工具的集合,用来执行各种通过手工执行非常复杂和麻烦的mysql和系统 ...
- 监控MySQL组复制
使用 Perfomance Schema 中的表来监控组复制,假定你的MySQL编译时已经启动了 Performance Schema 表.组复制将添加如下两张 P_S 表: performance_ ...
随机推荐
- 我眼中的优秀技术leader
在这家公司工作的四年时间里,我一共接触过两个在技术团队里有很大影响力的leader.本文将基于我在工作中对他们的观察,总结一下他们身上所具有的特质,以作为自己学习的榜样.标题中的“我眼中的”,不仅表示 ...
- mongodb操作技巧
1.添加字段或更新值 db.getCollection('test').updateMany( {}, { $set:{ 'createTime':'2017-06-29 08:08', 'updat ...
- Java控制并发线程数的Semaphore
Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.以前我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是控制流量的红绿 ...
- WinForm中遇到Label要显示的内容太长,自动换行
很多朋友都会在开发WinForm中遇到Label要显示的内容太长,但却不能换行的问题.这里我总结了几种方法,供大家参考. 第一种是把Label的AutoSize属性设为False,手动修改Label的 ...
- MVC之——Razor语法
实例产品基于asp.net mvc 5.0框架,源码下载地址:http://www.jinhusns.com/Products/Download View里所有以@开头或@(/*代码*)的部分代码都会 ...
- Eclipse启动tomcat后404错误
题描述 在eclipse部署web项目后,发现tomcat可以启动,但是访问http://localhost:8080地址报404错误.而不使用eclipse启动tomcat,直接通过通过tomcat ...
- linux系统编程:进程控制(fork)
在linux中,用fork来创建一个子进程,该函数有如下特点: 1)执行一次,返回2次,它在父进程中的返回值是子进程的 PID,在子进程中的返回值是 0.子进程想要获得父进程的 PID 需要调用 ge ...
- element-ui Message组件源码分析整理笔记(八)
Message组件源码: main.js import Vue from 'vue'; import Main from './main.vue'; import { PopupManager } f ...
- 图片圆角显示与手机版文章页面CSS布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 高性能JavaScript(加载和执行)
当浏览器遇到 <script> 标签时,它是没办法知道 JavaScript 是否会向DOM中添加内容或引入其他元素,甚至关闭某一个标签.因此这个时候浏览器就会停止处理页面,先执行Java ...