MySQL · 快速删除大表

背景

生产环境有一张日志表 schedule_task_error_log ,数据量超过 5000w,想通过 drop 删除但是速度很慢。

1
2
-rw-rw----. 1 mysql mysql 5.1K Jan  8  2018 schedule_task_error_log.frm
-rw-rw----. 1 mysql mysql 36G May 16 18:14 schedule_task_error_log.ibd

原理

前提MySQL 开启了独立表空间MySQL 5.6.7 之后默认开启。

1
2
3
4
5
6
MariaDB> show variables like 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | ON |
+-----------------------+-------+

MySQL 在删除大表的时候为什么慢?

  • Buffer Pool 页面清除过程(拥有 InnoDB 全局锁)
  • 删除 ibd 磁盘文件过程

方案:利用了 Linux硬链接 减少 DDL 时间,加快锁释放,来进行快速删除。

实践

1. 建立硬连接

1
2
3
4
5
6
$ ln schedule_task_error_log.ibd schedule_task_error_log.ibd.hdlk
-rw-rw----. 1 mysql mysql 5.1K Jan 8 2018 schedule_task_error_log.frm
-rw-rw----. 2 mysql mysql 36G May 16 18:14 schedule_task_error_log.ibd
-rw-rw----. 2 mysql mysql 36G May 16 18:14 schedule_task_error_log.ibd.hdlk
-rw-rw----. 1 mysql mysql 5.8K Mar 14 2018 user_operation_syslog.frm
-rw-rw----. 1 mysql mysql 272K Feb 13 2019 user_operation_syslog.ibd

2. drop table

再看物理文件的引用数变为 1,然后我们可以另外找时间手动删除物理文件。

1
2
3
4
5
6
MariaDB> drop table schedule_task_error_log;
Query OK, 0 rows affected (0.78 sec)

-rw-rw----. 1 mysql mysql 36G May 16 18:14 schedule_task_error_log.ibd.hdlk
-rw-rw----. 1 mysql mysql 5.8K Mar 14 2018 user_operation_syslog.frm
-rw-rw----. 1 mysql mysql 272K Feb 13 2019 user_operation_syslog.ibd

3. 删除物理文件

1
$ rm -rf schedule_task_error_log.ibd.hdlk