记一次因磁盘块默认保留策略导致的数据库导入失败问题

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

近日开发人员要新测试一个功能,需要用到生产环境中的数据库(生产库版本:mysql-5.5.38-linux2.6-x86_64),因此需要我协调将生产库同步到测试库(测试库版本:mysql-5.5.38-linux2.6-x86_64)中。由于测试库中有很多从生产库同步过来的库,但这些库大都已经dirty了,所以不如重新同步一份。

由于这些数据库在我接手以前就已经存在了,但直到在我使用的过程中发现,此数据库存在问题,原来它并没有启用innodb_file_per_table选项(这个选项在MySQL 5.6.6以及更高版本中是默认启用的),如果此选项没有被启用,那么使用Innodb数据库类型的数据库的表中的数据和索引都是存放在系统表空间(the system tablespace)的,而系统表空间存放在ibdata_file文件(这个文件默认就是ibdata1)里。如果此选项没有启用就会导致文件系统的性能对数据库的性能产生巨大的影响,特别是当执行一些如DROP TABLE 和 TRUNCATE TABLE操作时。同时因为MySQL的系统表空间永远不会缩小,而且数据库中所有的数据库实例都会共享系统表空间,会导致这个文件会越来越大,以致于耗尽磁盘空间。

例如举个实际的例子:

image

image

上图就是生产库和测试库的例子,生产库的ibdata1文件已经达到了90GB,测试库的ibdata1文件也不甘示弱,达到了71GB。

以下详细说说此事情的经过。

生产库的磁盘为SSD磁盘,性能还是不错的,每日早上4点都有数据库备份脚本对生产库备份(mysqldump出sql并压缩成zip文件)。因此要将生产库的库同步到测试库的话只需要将备份文件用scp命令通过内网地址传输到测试库,将zip文件解压出来,通过nohup命令后台导入即可。

2015-10-23_091300

但随即发现问题不妙。原先监控系统早就报警说磁盘空间不足20%,一直没在意,后来发现磁盘空间直接利用率100%了。

2015-10-23_091046 

但是发现明明总空间有99GB而使用94GB,而使用率却是100%,那5GB“不翼而飞”了?经排查,先排除磁盘损坏原因,后来确定为原来是一个默认的系统保护策略。

此策略的英文描述如下:

Reserving some number of filesystem blocks for use by  privileged  processes  is done to avoid filesystem fragmentation, and to allow system daemons, such as syslogd(8), to continue to function correctly after non-privileged processes are prevented from writing to the filesystem.  Normally, the default percentage of reserved blocks is 5%.

翻译成中文大体如下:

此策略用于为一些特权进程(这个进程与root用户发起的进程不同,注意区分)正确执行完来避免造成文件系统碎片和为了允许系统后台程序如syslogd在非特权进程被阻止写入文件系统后能继续正常的工作,而采取的保留一些文件系统块用于专用的策略。默认保留的块数量是总数量的5%。

这个策略可用于ext2/ext3/ext4等系统。

2015-10-23_090920

dumpe2fs /dev/xvdb1 |grep -i "block coun"     
awk 'BEGIN{print 1310694 / 26213888}' ,bc工具做浮点数除法时有问题,建议使用awk。      
#0.05 --> 5% Reserved block count --> refer to 'man 8 tune2fs' and option '-m'

经图上计算恰好是5%!既然这是默认策略,不管是默认还是不默认的,都可以调整,然后用tune2fs调整一下,如下图所示:

2015-10-23_090434

这样那5GB空间就可以使用了,然后清除一些应用日志继续执行程序后发现还是有问题。

2015-10-23_091020

重新执行mysql导入命令后发现磁盘空间很快又被用尽了,赶紧取消导入命令。

2015-10-23_092045

2015-10-23_092011

此时才开始关注MySQL的ibdata问题,也就是文章刚开始提到的问题了。因此日后配置数据库时如果要使用Innodb一定要记得开启innodb_file_per_table选项。同时5%的磁盘保留策略最好不要随意更改,免得文件系统真的遭到破坏,比如碎片的产生。

再提醒一句:MySQL的系统表空间永远不会缩小,因此ibdata1这个文件会越来越大,要想降低ibdata文件的大小,决不能采用直接删除的办法,如果直接删除了,那就比较悲催了,因为Innodb引擎的原理会轻则导致数据库无法启动(意思是可以恢复),重则导致数据库数据丢失(也能找回来,但未必能100%找回来),唯一降低ibdata文件的办法就是重新安装数据库,没错,是重新安装数据库,将原先的数据库通过mysqldump导出(不要用percona-xtrabackup备份,这个工具并不是导出sql文件),数据库重新安装后,启用innodb_file_per_table选项,再用备份的SQL文件导入。上述操作显而易见还是非常麻烦的。

再额外说一些后续。

如果只有有限的机器做数据库使用,最好不同业务运行在不同的数据库服务器上。即一台机器上运行多个数据库服务器,每一个数据库服务器只运行一个数据库实例,这样做虽然繁琐,但它的好处也是显而易见的。例如一个数据库服务器损坏不会影响一批业务系统。每一个数据库实例可以很容易的对应一个从库,更好的实现HA。如果一个数据库服务器运行多个数据库实例,那么配置主从复制时会非常麻烦,因为有多个实例需要配置主从时,它的二进制文件和pos值在利用mysqldump命令逐个备份数据库时是很难确定的,除非借助percona-xtrabackup或者一些手动的办法,获取唯一的二进制文件和pos值。这种策略的设定正好在mysql的multiserver上很好的得到了体现。

tag:mysql ibdata文件,mysql innodb_file_per_table,tune2fs,磁盘保护策略,系统保留块计数

--end--




本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1705606,如需转载请自行联系原作者


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
30天前
|
XML 关系型数据库 MySQL
python将word(doc或docx)的内容导入mysql数据库
用python先把doc文件转换成docx文件(这一步也可以不要后续会说明),然后读取docx的文件并另存为htm格式的文件(上一步可以直接把doc文件另存为htm),python根据bs4获取p标签里的内容,如果段落中有图片则保存图片。(图片在word文档中的位置可以很好的还原到生成的数据库内容) 我见网上有把docx压缩后解压获取图片的,然后根据在根据xml来读取图片的位置,我觉得比较繁琐。用docx模块读取段落的时候还需要是不是判断段落中有分页等,然而转成htm之后就不用判断那么多直接判断段落里的样式或者图片等就可以了。
21 1
|
1月前
|
存储 搜索推荐 关系型数据库
深度探讨数据库索引的数据结构及优化策略
深度探讨数据库索引的数据结构及优化策略
|
3月前
|
数据库 数据安全/隐私保护 Python
写一个定时备份数据库的脚本,且只保留最近3天
写一个定时备份数据库的脚本,且只保留最近3天
67 3
|
3月前
|
JSON NoSQL 小程序
Mongodb数据库的导出和导入总结
Mongodb数据库的导出和导入总结
189 0
|
4月前
|
SQL 数据库 Python
记Flask-Migrate迁移数据库失败的两个Bug——详解循环导入问题
Flask-Migrate迁移数据库失败的两个Bug 1、找不到数据库:Unknown database ‘***’ 若还没有创建数据库,该迁移工具不会自动创建。你可以使用SQL命令手动创建一个数据库:
37 0
|
30天前
|
SQL 关系型数据库 MySQL
|
3月前
|
缓存 数据库 索引
高效后端开发:数据库优化策略详解
数据库优化是后端开发中不可或缺的一部分。本文将从多个方面详细阐述数据库优化策略,包括数据表设计、索引优化、查询性能优化等。通过本文的学习,读者可以了解如何优化数据库,提升后端应用性能和稳定性。
69 1
|
15天前
|
存储 关系型数据库 MySQL
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
MySQL数据库性能大揭秘:表设计优化的高效策略(优化数据类型、增加冗余字段、拆分表以及使用非空约束)
|
28天前
|
监控 Shell Linux
【Shell 命令集合 磁盘管理 】Linux 检查和创建磁盘配额数据库 quotacheck命令使用教程
【Shell 命令集合 磁盘管理 】Linux 检查和创建磁盘配额数据库 quotacheck命令使用教程
29 0
|
1月前
|
存储 关系型数据库 MySQL
Python导入Excel数据到MySQL数据库
Python导入Excel数据到MySQL数据库
73 0