mysql - 如何在不挂起 MySQL 进程的情况下使用 innodb_file_per_table=1 删除 1000 多个数据库?
问题描述
我们有一个重复的过程,我们想要并且需要清理我们的数据库。每个客户或潜在客户都有自己的数据库(有 300 个表,并且每个月都在增加),该数据库在几秒钟内启动,并包含一些基本数据。
几个月后,需要清理数据库。我们简单地调用DROP DATABASE customer_1
每个数据库(让 MySQL 服务器在每个语句之间有 10 秒的时间来“休息”),然后DROP USER 'customer_1'@'127.0.0.1')
.
每隔一段时间,整个数据库就会挂起。SHOW PROCESSLIST
给
Id User Command Time State Info
[pid] adm-user Query 300 System lock DROP DATABASE `customer_1`
不会完成任何新查询。杀死相关的查询 pid 将导致 Command=Killing,仅此而已。什么都没发生。MySQL 守护进程也无法停止,因为它仍在等待完成查询。
我们已经关闭了整个服务器的电源,重新启动它,并让 MySQL 进行自动崩溃恢复,这工作正常。之后,我们可以再删除 10-30 个数据库,然后这个事件会重复。
我们已经阅读了大量有关该主题的内容,包括但不限于:
- https://www.percona.com/blog/2011/02/03/performance-problem-with-innodb-and-drop-table/
- https://www.percona.com/blog/2009/06/16/slow-drop-table/
- https://dba.stackexchange.com/questions/41995/drop-database-locked-the-server
似乎共识是,是的,它是 MySQL 在表(空间)上使用全局互斥锁,并结合大缓冲池大小。
我们的 my.cnf:
innodb_file_per_table = 1
innodb_buffer_pool_size = 9G
innodb_log_file_size = 256M
innodb_flush_method = O_DIRECT
table_open_cache = 200000
table_definition_cache = 110000
innodb_flush_log_at_trx_commit = 2
有什么方法可以让我们负责任地删除数据库——即,不让服务器因其他潜在客户而停机?
我读过简单地删除所有表文件可以工作,然后删除数据库,其中 MySQL应该简单地删除对数据库的引用。
解决方案
您应该做的一件重要的事情是为您的 MySQL 数据目录使用 XFS 文件系统。
在 ext3 文件系统上删除大文件需要太多时间,正如您无疑在您链接到的 Percona 博客中所读到的那样。使用 XFS 可以更快地删除大文件,因此全局互斥锁的保留时间更短。
我还会一次删除一张表,以进一步减少互斥锁的持有时间。然后在删除所有表之后,删除数据库。
MySQL 中的数据库根本不是物理对象。它是 MySQL 数据目录的子目录,以及一个名为的小文件db.opt
,用于存储数据库的一些属性,例如其默认字符集(在 MySQL 8.0 中,这甚至不再是一个单独的文件)。在删除所有表之后,删除数据库本身是微不足道的。
另一个建议是先删除客户的 MySQL 用户,然后让 MySQL 运行几个小时,直到该客户表中的数据不再缓存在缓冲池中。当你删除一个大表时,MySQL 必须扫描缓冲池以释放属于该表的页面。缓冲池越大,所需的时间就越长。因此,如果您让该客户表的页面过期并离开缓冲池,您可以最大限度地减少这种影响。这可能需要一些时间,因为它更多是由对其他表的需求驱动的。除了删除表之外,没有什么好的方法可以强制表的页面离开缓冲池。
我已经在某些环境中做到了。将“DROP TABLE”请求放入 RENAME TABLE 以将表移动到另一个用户无权访问的模式中。然后定期运行脚本以真正删除已在该笔中超过 7 天的表格。当来自其他表的数据取代它们时,这为页面逐渐从缓冲池中逐出提供了时间。此外,它还为用户提供了一个宽限期,让他们在决定最终删除他们需要的表时改变主意。
推荐阅读
- raspberry-pi3 - Netdata监控树莓派3A+状态如何添加“每核电压波动”图表
- node.js - Visual Studio 2019 node.js docker 远程调试:已设置断点但尚未绑定
- java - JSON中的改造列表字段不起作用
- html - Html 电子邮件签名与 Outlook 不一致
- javascript - textarea 的可访问自动完成功能
- flutter - 当您只选择其中一个复选框时,每个复选框都会被选中
- javascript - 追加查询字符串参数
- python - PyQt5:添加lineEdit的子类QSlider(用于在QtDesigner中提升)?
- javascript - 从网站获取字体颜色的正确方法是什么?
- c# - 是否可以使用 LockBits 隐藏位图中的数据?