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

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

周末闲得蛋疼,来英飞特做人工空气净化器。开了电脑后,习惯性得点击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. Python collections系列之计数器

    计数器(counter) Counter是对字典(无序)类型的补充,用于追踪值的出现次数. 使用counter需要导入 collections 类 ps:具备字典的所有功能 + 自己的功能 1.创建一 ...

  2. 服务监控Zabbix和Nagios的继任者

    本文转载自:https://blog.csdn.net/moonpure/article/details/78633668 为了调研市场,从而做出更好的监控工具,David Gildeh 曾采访了超过 ...

  3. nginx与二级域名的绑定 nginx安装

    nginx中文文档 http://www.nginx.cn/doc/ nginx 查看配置文件地址 http://blog.csdn.net/ljfrocky/article/details/5052 ...

  4. C# 保护进程不被结束(源代码)防任务管理器结束进程

    C# 保护进程不被结束(源代码)防任务管理器结束进程 Posted on 2013-03-25 16:03 快乐家++ 阅读(3173) 评论(3) 编辑 收藏 闲来无事,英语又学的太痛苦.看到我妈妈 ...

  5. HBase之八--(1):HBase二级索引的设计(案例讲解)

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  6. C++面试考点

    1.下面程序在x64下结果 struct st { int a; long long b; double c; }; int main() { st s; cout << &s.a ...

  7. Ubuntu16.04+TensorFlow r1.12环境搭建指南

    一.操作系统安装 OS版本:Ubuntu 16.04 (ubuntu-16.04.5-server-amd64.iso) CPU:4Core以上 内存:4GB以上 磁盘空间:80G以上 二.基础环境准 ...

  8. S2-045漏洞利用工具&解决方案

    简单的重复造一个轮子,漏洞危害蛮大的 影响版本:Struts 2.3.5 - Struts 2.3.31,Struts 2.5 - Struts 2.5.10 仅供学习测试使用,严禁非法操作! 下载链 ...

  9. DVWA平台v1.9-Command Injection

    命令拼接: &:简单的拼接,第一条命令和第二条命令间没有什么制约关系 &&:第一条命令执行成功了,才会执行第二条命令 |:第一条命令的输出作为第二条命令的输入 ||:第一条命令 ...

  10. java线程面试题及答案

    1)2017Java面试题及答案:什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务 ...