关于删除MySQL Logs的一点记录
五一前,一个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的一点记录的更多相关文章
- 删除mysql数据库表里的记录
如果记录不再需要,可以用delete 命令进行删除,语法如下: DELETE FROM tablename [WHERE CONDITION] 例如,在emp 中将ename 为‘dony’的记录全部 ...
- 京东联盟开发(12)——删除MySQL表中重复记录并且只保留一条
本文介绍如何删除商品表中的一些重复记录. 有时,一条商品由于有多个skuid,比如某种手机有不同颜色,但价格.优惠等信息却是一致,导致其被多次收录.由于其各种条件基本类似,这样它在商品中多个sku都排 ...
- 删除Mysql数据表中多余的重复记录的sql语句
数据表 sniper_tb 中存在主键 id,字段url,现需要在url字段上添加 unique,但由于url存在重复记录,导致添加失败. 如何删除表中多余的url重复记录,仅保持一条? 思路一 将 ...
- 彻底删除MySQL
安装mysql数据库.最后一步APPLY SECURITY SETTINGS总是失败.感觉很郁闷.上网找了教程,有前四步,一一做了,发现还是不对.最近突然发现在环境变量那边的路径还没有卸载干净.可能我 ...
- mysql防止重复插入记录方法总结
mysql防止重复插入记录方法总结 防止mysql重复插入记录的方法有很多种,常用的是ignore,Replace,ON DUPLICATE KEY UPDATE,当然我们也可以在php中加以判断了. ...
- 删除MySQL重复数据
删除MySQL重复数据 项目背景 在最近做的一个linux性能采集项目中,发现线程的程序入库很慢,再仔细定位,发现数据库里面很多冗余数据.因为在采集中,对于同一台设备,同一个时间点应该只有一个数据,然 ...
- lnmp vps服务器删除mysql日志文件三种方法
我在上一篇文章介绍了著名的LNMP主机一键安装工具,对比了军哥lnmp和AMH主机的差别,由于AMH拥有用户后台界面,易于新手操作,值得推荐. 但是,上周末我网站宕机,收到DNSPOD发来了宕机提醒, ...
- 删除MySQL二进制日志
服务器上的120G SSD硬盘空间用了92%,检查后发现,原来是 MySQL的二进制日志没有及时清除,占用了大量的空间, 于是直接用命令:reset master 一把删干净了. 1 reset ma ...
- centos下彻底删除mysql的方法
本文记录了CentOS下MySQL的彻底卸载,供大家参考,具体内容如下: 1.查看MySQL是否安装 方式1: [root@localhost usr]# yum list installed mys ...
随机推荐
- Documentation/filesystems/sysfs.txt 文档翻译--sysfs
sysfs - 用于导出内核对象的文件系统. 1.sysfs是一个基于ram的文件系统,最初基于ramfs. 它提供了一种方法,可以将内核数据结构,它们的属性以及它们之间的链接导出到用户空间.sysf ...
- Oracle Database express 11g 第 2 版安装和配置
官方Oracle Database 快捷版 11g 第 2 版的下载地址: http://www.oracle.com/technetwork/cn/products/express-edition/ ...
- 项目管理软件选择:redmine or JIRA
个人理解,这两款软件从本质上说是issue tracking,而不是项目管理. 先说些个人的想法 1)从现阶段情况看,都是够用的,毕竟本来就是小团队 2)从扩展而言,根据现在团队的实际情况(基本都是搞 ...
- FastAdmin 环境变量 env 配置
FastAdmin 环境变量 env 配置 目前 FastAdmin 支持环境变量 env 配置. 目前支持以下环境变量 app.debug app.trace database.type datab ...
- 关于Eclipse
Navigator窗口 之前看到同事使用Eclipse的Navigator窗口,十分不解这个窗口有啥用:今天通过了解才知道Package Explorer是从工程的角度来显示文件,比如settings ...
- C#使用OpcNetApi.dll和OpcNetApi.Com.dll操作OPC
本人学习了一下.Net,恰好,51自学网,又要用这个.而网上很多VC6,VB6,VB .Net的但,很少C#的.现在研究一下,给出例子: 测试平台,是VS2008,KEPServer,OpcNetAp ...
- ROS创建Web代理(Web proxy)给QQ使用HTTP代理
使用Web代理可以提高网页的访问速度,因为访问的数据会存储在内存或是硬盘中,就会直接从代理服务器中读取.同时,为了提高网络访问的安全性,可以给Web代理服务器设置相应的权限,使它的安全性得到提高. 下 ...
- JavaScript常见集合操作
JavaScript常见集合操作 集合的遍历 FOR循环(效率最高) 优点:JavaScript最普遍的for循环,执行效率最高 缺点:无法遍历对象 for(let i=0;i<array.le ...
- pythonNetday06
进程 Process(target,name,args,kwargs) p.pid : 创建的新的进程的PID号 p.is_alive() 判断进程是否处于alive状态 p.daemon = Tru ...
- linux-ububtu64位安装docker,及基本命令
安装:貌似只支持64位 sudo apt-get install docker sudo apt-get install docker.io sudo apt-get install docker-r ...