【MySQL】磁盘写满之后,数据库show status受到阻塞的原因
编辑手记:前两天同事讨论到一个问题,当mysql从库磁盘满之后,show status及show slave status会被卡住,但其他select操作不受影响,但如果数据库是主库,磁盘满了之后,只有dml会被阻塞,select及show是不会受影响的。于是一群人讨论了一会,最后决定,SMC,以下就是我的结论。
1..以下所有讨论都基于mysql 5.5.37版本及官方文档,不保证适用于其他版本。
2.下文中提到的磁盘满,指的是数据文件(数据文件,日志文件,配置文件)所在磁盘分区。
3.由于篇幅问题,最后面的代码部分,只有关键的函数及逻辑判断部分。
首先查看官方文档(https://dev.mysql.com/doc/refman/5.5/en/full-disk.html),有以下观点:
1.实例每分钟检查是否有足够的空间写入。如果已经有空间了,继续执行操作。
2.每十分钟给日志文件写入一条记录,报告磁盘已经写满。
但是对不对?
下面是我对官方文档的测试结果:
1.如果主库上打开binlog,那么当磁盘满之后,每10分钟,数据库会报告一条Disk is full writing ./mysql-bin.000001 (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space),也就是说bin log写满了,等待磁盘空间,这与文档描述相同。
2,如果在主库上关闭binlog,当磁盘满了之后,任何插入行为都会失败,报错为[ERROR] ./mysqld: The table x is full,官方文档没有提到这个情况,此处的表x是innodb表。
上面是对主库所在磁盘写满之后,数据库实例的反应,下面讲讲我们遇到的情况:从库磁盘写满之后,show status及show slave status会被卡住,但其他select操作不受影响。
整个流程涉及3把锁:
1.mi- data_lock
2.LOCK_active_mi
3.LOCK_status
当一个新操作被接收到slave io线程后,如果这时候磁盘写满了,这个写入操作就会被阻塞,然后等待,直到磁盘有空间之后继续写入,这个操作中,会持有mi- data_lock锁,只有操作完成或者操作失败后,这个锁才会被释放,恰好,磁盘满不属于错误,于是操作阻塞,该线程会一直持有mi- data_lock锁。
当发起一个show slave status请求的时候,执行的时候,会首先锁住LOCK_active_mi锁,然后锁定mi- data_lock锁,当然,现在的情况下,mi- data_lock不会得到,于是LOCK_active_mi锁就会被该线程持续持有。
另外其一个会话发起show global status,执行的时候首先锁定LOCK_status锁,由于show status包括,Slave_heartbeat_period,Slave_open_temp_tables,Slave_received_heartbeats ,Slave_retried_transactions这些状态,于是还需要LOCK_active_mi锁,于是,这个会话也会被阻塞掉。
之后如果再另外发起请求,由于LOCK_status已经被锁定,于是所有涉及show status的请求,都会被阻塞到这里。
看了以上的结论,是否会想到另外一个操作顺序:磁盘写满- show status,这种操作的结果是:show status不会被阻塞的。
以下是mysql源代码(5.5.37)涉及到的具体部分:
1.io线程阻塞的相关函数及部分代码
slave.cc
slave.cc
log.cc
log.cc
mf_locache.c
my_write.c
errors.c
2.show slave status相关的函数及部分代码
sql_parse.cc
sql_parse.cc
slave.cc
3.show status相关的函数及部分代码
mysqld.cc
sql_show.cc
sql_show.cc
本文出自数据和云公众号,原文链接
MySQL 磁盘满了,怎么办?? 使用命令发现磁盘使用率为100%了,还剩几十兆。 一系列神操作: 备份数据库,删除实例、删除数据库表、重启mysql服务.结果磁盘空间均为释放 网上查了很多资源,说要进行磁盘碎片化整理。原因是datafree占据的空间太多啦。具体可以通过这个sql查看。
Mysql数据库表分区存储到指定磁盘路径 0. 前提: mysql5.6.6以上的版本以上的版本才支持单表指定目录,且目录权限是mysql:mysql。 在mysql中数据文件存放于在my.cnf中datadir指定的路径,使用的表引擎不同产生的文件格式、表文件个数也会有所差异。 mysql的表引擎有多种,表的扩展名也不一样,如innodb用“ .ibd”,archive用“.arc ”,csv用“.csv”等。
Mysql数据库表分区存储到指定磁盘路径 在mysql中数据文件存放于在my.cnf中datadir指定的路径,使用的表引擎不同产生的文件格式、表文件个数也会有所差异。
MySQL探秘(四):InnoDB的磁盘文件及落盘机制 任何一个技术都有其底层的关键基础技术,这些关键技术很有可能也是其他技术的关键技术,学习这些底层技术,就可以一通百通,让你很快的掌握其他技术。如何在磁盘上存储数据,如何使用日志文件保证数据不丢失以及如何落盘,不仅是MySQL等数据库的关键技术,也是MQ消息队列或者其他中间件的关键技术之一
[教程]在CentOS7上配置 FTP服务器 Proftpd 支持 MySQL 虚拟用户加密认证以及磁盘限额(Quota) 本文软件采用 yum 安装,不需要编译,而且随时都可以跟随 CentOS 升级 Proftpd 到最新版本,以避免可能的漏洞攻击。利用 Proftpd 现成的配置以及设置好的各种模块,可以实现 sftp 和 ssh 的结合,完美的实现虚拟用户加密密码存放于数据库。
相关文章
- django 的mysql数据配置
- PDO连接mysql和pgsql数据库
- PHP连接MySQL数据库的三种方式(mysql、mysqli、pdo)--续
- 数据库基础之Mysql(3)mysql删除历史binlog
- Mysql 如果有多个可选条件怎么加索引_MySQL|mysql-索引
- mysql数据库常用数据类型
- PHP MySQL 创建数据库
- 〖Python 数据库开发实战 - Python与MySQL交互篇⑩〗- 创建新闻管理系统的具体python文件
- MySQL数据库唯一索引
- 想提高运维效率,那就把MySQL数据库部署到Kubernetes 集群中
- 云图说:云数据库 RDS for MySQL一键开通读写分离,轻松应对业务高峰期
- 详解MySQL information_schema数据库常用的表信息以及各表对应的字段信息;以及如何登录mysql和创建视图
- MYSQL导入数据报错|MYSQL导入超大文件报错|MYSQL导入大数据库报错:2006 - MySQL server has gone away
- Xshell连接mysql数据库乱码问题解决思路总结
- 【MySQL】如何最大程度防止人为误操作MySQL数据库?这次我懂了!!
- docker中使用MySQL数据库
- 深入理解mysql之BDB系列(1)---BDB相关基础知识
- windows下如何设置mysql环境变量
- java使用Mysql批量更新(不存在就插入,存在就更新)
- MYSQL提权之反弹SHELL——数据库提权属于webshell到管理员的纵向提权,本质还是利用udf提权,无非是在mysql自定义函数中使用了反弹shell而已
- 数据库===轻量级mysql数据库管理工具
- mysql 数据库 分表后 怎么进行分页查询?Mysql分库分表方案?
- MySQL----MySQL常用的数据库数据表备份与恢复的方法
- mysql数据库安装配置
- mysql数据库之常用SQL语句及事务学习笔记(一)
- MySQL DISTINCT:去重(过滤重复数据)
- windows上同时安装多个版本的mysql数据库
- [ MySQL ] 使用 MySQL Workbentch 进行MySQL数据库备份 / 还原(Part 3:备份.sql文件方式)