MySQL安全删除大表

安全地删除大表

一般有两种方法去删除大表

  • 删除表空间文件
  • delete+where条件进行分批操作
  • delete,truncate也可以实现,delete直接删除最坏情况可能是跑崩数据库。

删除表空间文件

MySQL里面直接对大表执行drop table删除有可能导致MySQL Hang住,对业务造成影响。删除超大表的前提是该表是独立表空间,然后按照如下步骤删除才能避免引起业务故障

表中数据量(假设后边还有4个0)
mysql> select count(*) from t;
+----------+
| count(*) |
+----------+
|  1100000 |
+----------+
1 row in set (0.16 sec)
创建ibd,frm硬连接
ln t.ibd t.ibd.hl
ln t.frm t.frm.hl
关闭自适应哈希索引

InnodB存储引擎会监控对表上各索引页的查询。如果观察到建立哈希索引可以带来速度提升,则建立哈希索引,称之为自适应哈希索引(Adaptive Hash Index,AHI) AHI是通过缓冲池的B+树页构造而来,因此建立的速度很快,而且不需要对整张表构建哈希索引。InnoDB存储引擎会自动根据访问的频率和模式来自动地为某些热点页建立哈希索引。
drop过程中InnoDB引擎还会删除表对应的AHI(自适应哈希索引)。而这个过程需要持有一把数据字典的互斥锁,可以在DROP TABLE的时候关闭AHI功能。

mysql> set global innodb_adaptive_hash_index=OFF;
Query OK, 0 rows affected (0.01 sec)

mysql> SHOW GLOBAL VARIABLES LIKE '%HASH%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| innodb_adaptive_hash_index       | OFF   |
| innodb_adaptive_hash_index_parts | 8     |
| metadata_locks_hash_instances    | 8     |
+----------------------------------+-------+
3 rows in set (0.00 sec)
drop 表

此时drop执行速度会非常快,会自动清理.ibd和.frm文件

mysql> drop table t;
Query OK, 0 rows affected (0.95 sec)
ionice工具删除硬连接的文件,truncate工具也可以
[root@DESKTOP-54S04AH testcompress]# ionice -c 2 -n 6 rm t.ibd.hl
[root@DESKTOP-54S04AH testcompress]# ionice -c 2 -n 6 rm t.frm.hl

delete 进行批量删除

例如

delete from table where id < 10000;
sleep 5;
delete from table where id < 20000;
.
.
.
.

pt-archiver可以归档,也可以删除

参数信息:

pt-archiver --help 
--progress 每多少行打印进度信息
--limit  限制select返回的行数
--sleep  指定select语句休眠时间
--txn-size 指定多少行提交一次事务
--bulk-delete 用单个DELETE语句批量删除每个行块。该语句删除块的第一行和最后一行之间的每一行,隐含--commit-each
--dry-run 打印查询,不做任何操作后退出

删除命令:

# 打印查询
$ pt-archiver --source h=192.168.175.230,P=3306,u=root,p='123',D=sbtest,t=t--purge --charset=utf8mb4 --where "id <= 400000" --progress=200  --limit=1000 --sleep=1 --txn-size=1000 --statistics  --dry-run
# 解释:删除sbtest库,sbtest1表数据,字符集为utf8mb4,删除条件是 id <= 1100000 ,每次取出200行进行处理,每处理200行则进行一次提交,每完成一次处理sleep 1s

SELECT /*!40001 SQL_NO_CACHE */ `id`,`k`,`c`,`pad` FROM `sbtest`.`t` FORCE INDEX(`PRIMARY`) WHERE (id <= 400000) AND (`id` < '23132073') ORDER BY `id` LIMIT 1000
SELECT /*!40001 SQL_NO_CACHE */ `id`,`k`,`c`,`pad` FROM `sbtest`.`t` FORCE INDEX(`PRIMARY`) WHERE (id <= 400000) AND (`id` < '23132073') AND ((`id` >= ?)) ORDER BY `id` LIMIT 1000
DELETE FROM `sbtest`.`sbtest1` WHERE (`id` = ?)

# 打开会话保持功能
screen -S archiver


# 执行删除
$ pt-archiver --source h=192.168.175.230,P=3306,u=root,p='123',D=sbtest,t=t--purge --charset=utf8mb4 --where "id <= 1100000 " --progress=200  --limit=1000 --sleep=1 --txn-size=1000 --statistics

小结:

delete操作之后,数据并不会马上删除,是标记为删除,相应空间也不会释放。
如果delete操作没有使用where 索引条件,还会扫描全表,加表锁。
delete过程中产生大量的日志文件。
如果表中数据需要保留一部分数据,可以使用pt-archiver工具进行归档处理,这是最安全的方法,当然要保证操作的表有主键。
如果表中所有数据都不要了,还是通过硬连接的方式,去删除.ibd文件更为高效。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shynodes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值