五一前,一个DBA同事反馈,在日常环境中删除一个大的slow log文件(假设文件大小10G以上吧),然后在MySQL中执行flush slow logs,会发现mysqld hang住。

今天尝试着重现了此问题,这里简要分析下原因。

重现步骤:

1. 构造slow log (将long_query_time设成了0);

2. 观察删rm slow log瞬间,tps/qps变化;

3. 观察执行flush slow logs瞬间,tps/qps变化;

4. 记录flush slow logs执行时, pstack打出的调用栈情况;

第一步,没啥好说的。

第二步,tps/qps没啥变化。

第三步,会发现tps/qps瞬间跌0,如下所示:

[ 639s] threads: , tps: 1121.00, reads/s: 15843.98, writes/s: 4490.99
[ 640s] threads: , tps: 792.99, reads/s: 10803.89, writes/s: 3150.97
[ 641s] threads: , tps: 0.00, reads/s: 0.00, writes/s: 0.00
[ 642s] threads: , tps: 0.00, reads/s: 0.00, writes/s: 0.00
[ 643s] threads: , tps: 471.01, reads/s: 6860.08, writes/s: 1908.02

mysql命令行会发现,flush slow logs执行时间刚好为3s左右。

第四步,我们看下pstack的输出结果,只记录相关的:

 Thread  (Thread 0x2afdc4101700 (LWP )):
# 0x0000003c6e40a7d6 in pthread_rwlock_rdlock () from /lib64/libpthread.so.
# 0x0000000000825135 in inline_mysql_rwlock_rdlock ()
# 0x0000000000838004 in LOGGER::lock_shared() ()
# 0x00000000008283bf in LOGGER::slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000832b30 in slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000609f23 in log_slow_statement(THD*) ()
# 0x00000000006099d1 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
# 0x0000000000606e02 in do_command(THD*) ()
# 0x00000000006f070f in do_handle_one_connection(THD*) ()
# 0x00000000006f020d in handle_one_connection ()
# 0x0000003c6e4077f1 in start_thread () from /lib64/libpthread.so.
# 0x0000003c6e0e570d in clone () from /lib64/libc.so. Thread (Thread 0x2afdd0080700 (LWP )):
# 0x0000003c6e40a7d6 in pthread_rwlock_rdlock () from /lib64/libpthread.so.
# 0x0000000000825135 in inline_mysql_rwlock_rdlock ()
# 0x0000000000838004 in LOGGER::lock_shared() ()
# 0x00000000008283bf in LOGGER::slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000832b30 in slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000609f23 in log_slow_statement(THD*) ()
# 0x00000000006099d1 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
# 0x0000000000606e02 in do_command(THD*) ()
# 0x00000000006f070f in do_handle_one_connection(THD*) ()
# 0x00000000006f020d in handle_one_connection ()
# 0x0000003c6e4077f1 in start_thread () from /lib64/libpthread.so.
# 0x0000003c6e0e570d in clone () from /lib64/libc.so. Thread (Thread 0x2afdd0101700 (LWP )):
# 0x0000003c6e40a7d6 in pthread_rwlock_rdlock () from /lib64/libpthread.so.
# 0x0000000000825135 in inline_mysql_rwlock_rdlock ()
# 0x0000000000838004 in LOGGER::lock_shared() ()
# 0x00000000008283bf in LOGGER::slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000832b30 in slow_log_print(THD*, char const*, unsigned int, unsigned long long) ()
# 0x0000000000609f23 in log_slow_statement(THD*) ()
# 0x00000000006099d1 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
# 0x0000000000606e02 in do_command(THD*) ()
# 0x00000000006f070f in do_handle_one_connection(THD*) ()
# 0x00000000006f020d in handle_one_connection ()
# 0x0000003c6e4077f1 in start_thread () from /lib64/libpthread.so.
# 0x0000003c6e0e570d in clone () from /lib64/libc.so. Thread (Thread 0x2afe18080700 (LWP )):
# 0x0000003c6e40e54d in close () from /lib64/libpthread.so.
# 0x00000000008f56ed in my_close ()
# 0x0000000000825c16 in inline_mysql_file_close ()
# 0x000000000082b305 in MYSQL_LOG::close(unsigned int) ()
# 0x000000000082b634 in MYSQL_QUERY_LOG::reopen_file() ()
# 0x0000000000828283 in LOGGER::flush_slow_log() ()
# 0x000000000071d8fc in reload_acl_and_cache(THD*, unsigned long, TABLE_LIST*, int*) ()
# 0x0000000000610200 in mysql_execute_command(THD*) ()
# 0x000000000061534d in mysql_parse(THD*, char*, unsigned int, Parser_state*) ()
# 0x00000000006086a0 in dispatch_command(enum_server_command, THD*, char*, unsigned int) ()
# 0x0000000000606e02 in do_command(THD*) ()
# 0x00000000006f070f in do_handle_one_connection(THD*) ()
# 0x00000000006f020d in handle_one_connection ()
# 0x0000003c6e4077f1 in start_thread () from /lib64/libpthread.so.
# 0x0000003c6e0e570d in clone () from /lib64/libc.so.

会发现Thread 2在执行flush slow logs操作,其他的线程都在等待锁LOCK_log上边。

背后的原因其实很简单,在shell中执行rm slow log操作时,由于mysqld仍有文件句柄打开此文件,所以实际上此时文件并未删除。执行flush logs操作,其实际执行的是1)close;2)open 操作(logger.flush_slow_log -> mysql_slow_log.reopen_file),在close操作执行时,文件系统真正删除文件,此时该线程占用着LOCK_log锁。

删除时会执行刷脏(当然我构造这个场景很极端,基本所有slow log文件的内容都在文件系统缓存中),这个会很耗时间,比如我执行这个语句耗了3s。此时间段内,如果连接发来的语句需要记log(server层的log:slow log/binlog/general log共有LOCK_log这把锁)就会处于等待状态,那么系统对外的反应就是hang住了。

flush slow logs中调用执行的close所需时间和文件大小、以及文件系统缓存中该文件脏页比例都有关系,比如我在执行flush slow logs前使用sysctl vm.drop_caches=3清空

了文件系统缓存的话,同样大小的flush slow logs操作执行时间是0.42s,相应的阻塞时间也会减少不少。

可以考虑在slow logs的文件句柄上执行posix_fadvise调用,促使不会缓存很大的log文件内容(slow log也没啥需要缓存的),这有篇霸爷的文章,可以参考下posix_fadvise清除缓存的误解和改进措施 。

另外,peter在07年就讨论过这个问题, Be careful rotating MySQL logs 其给出的建议是先mv file,然后flush logs,再执行删除文件的操作,让真正的删除行为由自己而不是mysqld完成。比较遗憾的是,七年过去了,LOCK_log这把锁的问题还没有完整的解决掉。

PS:

文章结尾记一点备忘,通过close/rm操作删除一个10G大小的文件,在执行sysctl vm.drop_caches=3清空缓存后,此操作的耗时仍在百毫秒量级(我的机器上是200ms+),其背后做了什么事情还需要找内核组的同事了解下。

bug report:  http://bugs.mysql.com/bug.php?id=72529

关于删除MySQL Logs的一点记录的更多相关文章

  1. 删除mysql数据库表里的记录

    如果记录不再需要,可以用delete 命令进行删除,语法如下: DELETE FROM tablename [WHERE CONDITION] 例如,在emp 中将ename 为‘dony’的记录全部 ...

  2. 京东联盟开发(12)——删除MySQL表中重复记录并且只保留一条

    本文介绍如何删除商品表中的一些重复记录. 有时,一条商品由于有多个skuid,比如某种手机有不同颜色,但价格.优惠等信息却是一致,导致其被多次收录.由于其各种条件基本类似,这样它在商品中多个sku都排 ...

  3. 删除Mysql数据表中多余的重复记录的sql语句

    数据表 sniper_tb 中存在主键 id,字段url,现需要在url字段上添加 unique,但由于url存在重复记录,导致添加失败. 如何删除表中多余的url重复记录,仅保持一条? 思路一 将 ...

  4. 彻底删除MySQL

    安装mysql数据库.最后一步APPLY SECURITY SETTINGS总是失败.感觉很郁闷.上网找了教程,有前四步,一一做了,发现还是不对.最近突然发现在环境变量那边的路径还没有卸载干净.可能我 ...

  5. mysql防止重复插入记录方法总结

    mysql防止重复插入记录方法总结 防止mysql重复插入记录的方法有很多种,常用的是ignore,Replace,ON DUPLICATE KEY UPDATE,当然我们也可以在php中加以判断了. ...

  6. 删除MySQL重复数据

    删除MySQL重复数据 项目背景 在最近做的一个linux性能采集项目中,发现线程的程序入库很慢,再仔细定位,发现数据库里面很多冗余数据.因为在采集中,对于同一台设备,同一个时间点应该只有一个数据,然 ...

  7. lnmp vps服务器删除mysql日志文件三种方法

    我在上一篇文章介绍了著名的LNMP主机一键安装工具,对比了军哥lnmp和AMH主机的差别,由于AMH拥有用户后台界面,易于新手操作,值得推荐. 但是,上周末我网站宕机,收到DNSPOD发来了宕机提醒, ...

  8. 删除MySQL二进制日志

    服务器上的120G SSD硬盘空间用了92%,检查后发现,原来是 MySQL的二进制日志没有及时清除,占用了大量的空间, 于是直接用命令:reset master 一把删干净了. 1 reset ma ...

  9. centos下彻底删除mysql的方法

    本文记录了CentOS下MySQL的彻底卸载,供大家参考,具体内容如下: 1.查看MySQL是否安装 方式1: [root@localhost usr]# yum list installed mys ...

随机推荐

  1. Documentation/filesystems/sysfs.txt 文档翻译--sysfs

    sysfs - 用于导出内核对象的文件系统. 1.sysfs是一个基于ram的文件系统,最初基于ramfs. 它提供了一种方法,可以将内核数据结构,它们的属性以及它们之间的链接导出到用户空间.sysf ...

  2. O​r​a​c​l​e​ ​D​a​t​a​b​a​s​e​ ​e​x​p​r​e​s​s​ ​1​1​g​ ​第​ ​2​ ​版​安​装和配置

    官方Oracle Database 快捷版 11g 第 2 版的下载地址: http://www.oracle.com/technetwork/cn/products/express-edition/ ...

  3. 项目管理软件选择:redmine or JIRA

    个人理解,这两款软件从本质上说是issue tracking,而不是项目管理. 先说些个人的想法 1)从现阶段情况看,都是够用的,毕竟本来就是小团队 2)从扩展而言,根据现在团队的实际情况(基本都是搞 ...

  4. FastAdmin 环境变量 env 配置

    FastAdmin 环境变量 env 配置 目前 FastAdmin 支持环境变量 env 配置. 目前支持以下环境变量 app.debug app.trace database.type datab ...

  5. 关于Eclipse

    Navigator窗口 之前看到同事使用Eclipse的Navigator窗口,十分不解这个窗口有啥用:今天通过了解才知道Package Explorer是从工程的角度来显示文件,比如settings ...

  6. C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC

    本人学习了一下.Net,恰好,51自学网,又要用这个.而网上很多VC6,VB6,VB .Net的但,很少C#的.现在研究一下,给出例子: 测试平台,是VS2008,KEPServer,OpcNetAp ...

  7. ROS创建Web代理(Web proxy)给QQ使用HTTP代理

    使用Web代理可以提高网页的访问速度,因为访问的数据会存储在内存或是硬盘中,就会直接从代理服务器中读取.同时,为了提高网络访问的安全性,可以给Web代理服务器设置相应的权限,使它的安全性得到提高. 下 ...

  8. JavaScript常见集合操作

    JavaScript常见集合操作 集合的遍历 FOR循环(效率最高) 优点:JavaScript最普遍的for循环,执行效率最高 缺点:无法遍历对象 for(let i=0;i<array.le ...

  9. pythonNetday06

    进程 Process(target,name,args,kwargs) p.pid : 创建的新的进程的PID号 p.is_alive() 判断进程是否处于alive状态 p.daemon = Tru ...

  10. linux-ububtu64位安装docker,及基本命令

    安装:貌似只支持64位 sudo apt-get install docker sudo apt-get install docker.io sudo apt-get install docker-r ...