此文已由作者温正湖授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验。

周末闲得蛋疼,来英飞特做人工空气净化器。开了电脑后,习惯性得点击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的更多相关文章

  1. 在windows下使用vs2013编译和调试mysql源代码

    1. 准备工作 1)OS:win10 + VS2013 2)mysql 源码(windows版):mysql-5.6.25.zip 3)perl tool:ActivePerl-5.16.3.1604 ...

  2. Paip.断点调试MYSQL存储过程跟函数的解决方案大法

    Paip.断点调试MYSQL存储过程跟函数的解决方案大法 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn ...

  3. MySQL高级学习笔记(一):mysql简介、mysq linux版的安装(mysql 5.5)

    文章目录 MySQL简介 概述 mysql高手是怎样炼成的 mysq linux版的安装(mysql 5.5) 下载地址 拷贝&解压缩 检查工作 检查当前系统是否安装过mysql 检查/tmp ...

  4. 获取发布版SHA1和调试版SHA1

    总结 调试版: 常见问题 | 高德地图API (amap.com) 发布版: 首先需要生成签名 Android Studio生成签名文件,自动签名,以及获取SHA1和MD5值_donkor_的博客-C ...

  5. mysql 源码编绎修改 FLAGS,调试MYSQL

    http://dev.mysql.com/doc/refman/5.7/en/source-configuration-options.html#option_cmake_cmake_c_flags ...

  6. 64位win7旗舰版搭建apache+php+mysql开发环境[转]

      我建议把apache.php.mysql都安装在一个文件夹中,比如:web/apache.web/php.web/mysql 1.安装apache2.2.25,请查看win7下安装VC9版本的ap ...

  7. 安卓版php服务器的mysql数据库增删改查简单案例

    界面: index.php文件: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "h ...

  8. 通用mapper版+SpringBoot+MyBatis框架+mysql数据库的整合

    转:https://blog.csdn.net/qq_35153200/article/details/79538440 开发环境: 开发工具:Intellij IDEA 2017.2.3 JDK : ...

  9. 解压版中文乱码问题MYSQL中文乱码

    安装的是解压版的MYSQL,具体配置参考:https://jingyan.baidu.com/article/9c69d48f85032f13c9024e15.html . 1:解压之后copy 一个 ...

随机推荐

  1. BZOJ1116:[POI2008]CLO

    浅谈并查集:https://www.cnblogs.com/AKMer/p/10360090.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php? ...

  2. 我的ubuntu新系统自动装软件脚本

    装一些常用软件 配一下环境变量 #!/bin/bash #download g++sudo apt-get install g++ -y#download codeblockssudo apt-get ...

  3. java代码----方法类练习中~~~未领会

    总结:今天我很失败,问了老师继承的问题还是没弄懂.因为,技术宅的能力,我好怕啊.太强了. package com.da.ima2; public class yut {// 使用substring方法 ...

  4. mysql函数之二:left,right,substring,substring_index MySQL截取字符串函数方法

    函数: 1.从左开始截取字符串 left(str, length) 说明:left(被截取字段,截取长度) 例:select left(content,200) as abstract from my ...

  5. MySQL mysqldump 备份脚本(按照db.sql)

    mysqldump逻辑备份,按照db.sql文件区分,并压缩 #! /bin/bash #35 02 * * * mysql /data/mysqldata/scripts/mysqldump_per ...

  6. [phonegap]安装升级

    安装 npm install -g phonegapnpm install -g phonegap@版本号    比如 npm install -g phonegap@3.3.0-0.19.6 升级 ...

  7. spring 框架整合

    struts hibernate spring 先贴出框架整合需要的maven <project xmlns="http://maven.apache.org/POM/4.0.0&qu ...

  8. Android 4学习(3):概述 - Resources

    在应用程序中,处理与代码逻辑无关资源的最佳实践是将其放到程序的外部,典型的资源包括字符串,图片等.Android中的资源文件都在res文件夹中,这些资源包括字符串,颜色,主题,样式,图画,布局,动画, ...

  9. JVM中存储类信息的三个表格

    摘自:<Java Performance>第三章 Internal Class Loading Data The HotSpot VM maintains three hash table ...

  10. C#数据导出到Excel源代码

    最近工作中需要做一个把用户信息作为excel导出的功能,就顺便整理搜集了一些常用的导出文件的源代码,以供以后不时之需,也希望能给大家带来一些方便 一.DataSet数据集内数据转化为Excel // ...