使用穷人版profiler定位调试MySQL
此文已由作者温正湖授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
周末闲得蛋疼,来英飞特做人工空气净化器。开了电脑后,习惯性得点击xshell按钮,进入InnoSQL稳定性测试机。show processlist几次,发现不对劲啊。我跑的是oltp加oltp_simple(select)测试,怎么好像没有update/delete/insert了,似乎只有select了。因为改了InnoDB层持锁相关的代码,莫非死锁(非事务死锁,而是latch死锁)了,但死锁怎么还能select呢。进一步打开oltp和oltp_simple两个screen的输出report,果然是oltp_simple正常,oltp的tps为0。为了调试方便,把oltp_simple停了。在此show processlist,发现10个线程齐刷刷地处于commit阶段。至此,通过mysql客户端似乎看不出什么了。
按照正常的定位思路,这个时候应该先看下mysqld进程输出的error log,但阴差阳错,我并没有这么做。直接想到了上gdb,但多线程情况下gdb其实挺烦,你懂点。之前在看MongoDB存储引擎WiredTiger WAL日志性能优化文章(1,2 写到不错,推荐看看)的时候提到了一个工具,叫做穷人版profiler,打算试用下。简单过滤后,摘取的10个线程信息如下:
8pthread_cond_wait@@GLIBC_2.3.2,native_cond_wait,cond=<optimized,mutex=<optimized,stage=<optimized,MYSQL_BIN_LOG::change_stage,MYSQL_BIN_LOG::ordered_commit,MYSQL_BIN_LOG::commit,ha_commit_trans,trans_commit,mysql_execute_command,mysql_parse,dispatch_command,do_command,threadpool_process_request,handle_event,at,pfs_spawn_thread,start_thread,clone,??
1__lll_lock_wait,_L_lock_926,pthread_mutex_lock,native_mutex_lock,at,src_line=src_line@entry=8845,,change_stage,thd=<optimized,MYSQL_BIN_LOG::ordered_commit,MYSQL_BIN_LOG::commit,ha_commit_trans,trans_commit,mysql_execute_command,mysql_parse,dispatch_command,do_command,threadpool_process_request,handle_event,at,pfs_spawn_thread,start_thread,clone,??
1nanosleep,sleep,wait_for_free_space,my_write,inline_mysql_file_write,need_append_buffer_lock=<optimized,MYSQL_BIN_LOG::flush_cache_to_file,MYSQL_BIN_LOG::ordered_commit,MYSQL_BIN_LOG::commit,ha_commit_trans,trans_commit,mysql_execute_command,mysql_parse,dispatch_command,do_command,threadpool_process_request,handle_event,at,pfs_spawn_thread,start_thread,clone,??
每行的第一列是拥有同样内容的线程个数。可以看到有8个线程在提交阶段等mutex latch,有一个线程在等rwlock latch,还有一个,他竟然在commit阶段sleep,在往后看,竟然是wait_for_free_space。理一理,在commit阶段flush_cache_to_file函数中在wait_for_free_space进行sleep,那么很显然,磁盘满了呗。直接用df -h看了下,数据盘果然满了。盘有100G,数据量才10G左右,咋会满。看了下数据目录,全是binlog文件。好吧,那应该是binlog过期没删。在MySQL客户端使用show variables like "%expire%"看下,发现该值为空啊,那就很显然了。这次问题是由于在MySQL主从复制环境下跑稳定性测试,没有设置binlog过期时间导致binlog堆积占满了数据盘,引起读写事务无法正常提交。 最后查看了而error log确认了下:
2017-11-12T03:35:39.653002Z 105 [ERROR] Disk is full writing './innosql-dev-bin.000099' (Errcode: 16685152 - No space left on device). Waiting for someone to free space...
2017-11-12T03:35:39.653034Z 105 [ERROR] Retry in 60 secs. Message reprinted in 600 secs
果然如此啊。那么执行set global expire_logs_days = 1设置binlog过期时间为一天,然后flush logs。迅速把磁盘空间降下来,再次show processlist,ok了!
这是一个很简单的MySQL使用问题。作为一个有经验的MySQL研发或运维人员都能够快速定位。在此只是作为一个例子来说明穷人版profiler的使用方式。我觉得他使用gdb attach到进程后快速获取各个线程的调用栈信息后后迅速detach,并将调用栈信息按照层级快速合并汇总并统计处于同样调用栈的线程个数。这样有如下优点:
1、attach后获取信息就快速detach,对MySQL进程影响较少,甚至在线上环境也能够使用。比靠人工操作高效很多;
2、自动统计和整理调用栈信息,提供直观的信息和每个线程的函数调用关系,便以形成对问题的初步了解;对于简单的问题,直接可以通过函数调用关系来知道问题所在。
3、当然,其还可以通过周期性多次采样,这样能够直观反映进程一段时间内的运行情况。
其实类似的工具不止一个。比如pstack等也有类似功能。但不管如何,这是一个不错的工具。对于c/c++多线程开发的同学,一定还是有些用处的。最后,贴上该工具的脚本,非常简单易懂:
#!/bin/bashnsamples=1sleeptime=0pid=$(pidof mysqld)for x in $(seq 1 $nsamples) do
// 获取调用栈信息
gdb -ex "set pagination 0" -ex "thread apply all bt" -batch -p $pid
sleep $sleeptime
done | \
//处理脚本
awk ' BEGIN { s = ""; }
/^Thread/ { print s; s = ""; }
/^\#/ { if (s != "" ) { s = s "," $4} else { s = $4 } }
END { print s }' | \
sort | uniq -c | sort -r -n -k 1,1
网易云免费体验馆,0成本体验20+款云产品!
更多网易技术、产品、运营经验分享请点击。
相关文章:
【推荐】 限时购校验小工具&dubbo异步调用实现限
使用穷人版profiler定位调试MySQL的更多相关文章
- 在windows下使用vs2013编译和调试mysql源代码
1. 准备工作 1)OS:win10 + VS2013 2)mysql 源码(windows版):mysql-5.6.25.zip 3)perl tool:ActivePerl-5.16.3.1604 ...
- Paip.断点调试MYSQL存储过程跟函数的解决方案大法
Paip.断点调试MYSQL存储过程跟函数的解决方案大法 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn ...
- MySQL高级学习笔记(一):mysql简介、mysq linux版的安装(mysql 5.5)
文章目录 MySQL简介 概述 mysql高手是怎样炼成的 mysq linux版的安装(mysql 5.5) 下载地址 拷贝&解压缩 检查工作 检查当前系统是否安装过mysql 检查/tmp ...
- 获取发布版SHA1和调试版SHA1
总结 调试版: 常见问题 | 高德地图API (amap.com) 发布版: 首先需要生成签名 Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值_donkor_的博客-C ...
- mysql 源码编绎修改 FLAGS,调试MYSQL
http://dev.mysql.com/doc/refman/5.7/en/source-configuration-options.html#option_cmake_cmake_c_flags ...
- 64位win7旗舰版搭建apache+php+mysql开发环境[转]
我建议把apache.php.mysql都安装在一个文件夹中,比如:web/apache.web/php.web/mysql 1.安装apache2.2.25,请查看win7下安装VC9版本的ap ...
- 安卓版php服务器的mysql数据库增删改查简单案例
界面: index.php文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...
- 通用mapper版+SpringBoot+MyBatis框架+mysql数据库的整合
转:https://blog.csdn.net/qq_35153200/article/details/79538440 开发环境: 开发工具:Intellij IDEA 2017.2.3 JDK : ...
- 解压版中文乱码问题MYSQL中文乱码
安装的是解压版的MYSQL,具体配置参考:https://jingyan.baidu.com/article/9c69d48f85032f13c9024e15.html . 1:解压之后copy 一个 ...
随机推荐
- [转]深入详解javascript之delete操作符
最近重新温习JS,对delete操作符一直处于一知半解的状态,偶然发现一篇文章,对此作了非常细致深入的解释,看完有茅塞顿开的感觉,不敢独享,大致翻译如下. 原文地址:http://perfection ...
- linux 将大文件分解为多个小文件
使用的命令为: split --bytes 500M --numeric-suffixes --suffix-length=3 foo foo_ 其中 --bytes 为小文件的大小, --suffi ...
- 机器学习:模型泛化(L1、L2 和弹性网络)
一.岭回归和 LASSO 回归的推导过程 1)岭回归和LASSO回归都是解决模型训练过程中的过拟合问题 具体操作:在原始的损失函数后添加正则项,来尽量的减小模型学习到的 θ 的大小,使得模型的泛化能力 ...
- Make 命令
Linux 下 make 命令是系统管理员和程序员用的最频繁的命令之一.管理员用它通过命令行来编译和安装很多开源的工具,程序员用它来管理他们大型复杂的项目编译问题.本文我们将用一些实例来讨论 make ...
- mongoTemplate操作内嵌文档
关系型数据库中,表与表的关联关系有1:1,也有1:n的.在java的面向对象的世界里就是主对象嵌子对象,与主对象嵌集合<子对象>的两种形式. 主对象嵌子对象操作: 新增.修改都直接用如下方 ...
- Oracle RMAN 学习:演练进阶篇
Oracle RMAN 学习:演练进阶篇 5 Rman备份演练进阶篇 5.1 是否选择增量备份 Backup命令生成的备份集中只备份了那些使用了的数据块,备份集实际大小已经较目标数据库的数据文件小了很 ...
- PowerDesigner中批量替换name和code的脚本
无论是cdm还是pdm都可以批量替换.处理.可在Tool-Execute commands-Edit/Run script中编辑运行脚本: 下面的脚本是批量将CDM中实体的用Code替换掉Name O ...
- SqlServer——用户自定义函数
在SQL Server中,用户不仅可以使用标准的内置函数,也可以使用自己定义的函数来实现一些特殊的功能.可以使用CREATE FUNCTION 语句创建.在创建时需要注意:函数名在数据库中必须唯一, ...
- 10-17C#第四部分--类型(1)
C#类型--String类 一.String类型 () 注:string与String的不同:string属于String的数据类型,小写string是大写String类型的实例化:string属于S ...
- C语言学习笔记--指针阅读技巧
1. 指针阅读技巧:右左法则 (1)从最里层的圆括号中未定义的标示符看起 (2)首先往右看,再往左看 (3)遇到圆括号或方括号时可以确定部分类型,并调转方向 (4)重复 2.3 步骤,直到阅读结束 注 ...