【MySQL】使用硬链接的方式删除大表

Intro

MySQL中删除比较大的表时,如果直接用drop table的方式进行删除,有可能会对整个实例产生影响甚至使得实例夯住。因此可以通过硬链接的方式对表进行删除,使得对生产环境的影响降到最低。

drop table 的过程

  1. 持有 buffer pool mutex;
  2. 持有 buffer pool 中的 flush list mutex;
  3. 开始扫描 LRU list:
    1. 如果 dirty page 属于 drop table,那么就直接从 LRU list 中移除;
    2. 如果删除的 page 个数超过了define buf_lru_drop_search_size 1024的话,则释放 buffer pool mutex 和 flush list mutex ,强制通过 pthread_yield 进行一次 os context switch ,释放 cpu 时间片;
    3. 重新持有 buffer pool mutex 和 flush list mutex,继续遍历 LRU list,直到 LRU 的表头。
  4. 释放 flush list mutex;
  5. 释放 buffer pool mutex。
  6. 再次重复上述的 1-5 步骤,只不过 1-5 是删除 dirty page,这次的重复执行,删除的是 buffer pool 中的 clean page。

简单来看,整个过程可以简化为:

  1. 获取 buffer pool mutex 和 flush list mutex;
  2. 从尾部开始遍历 LRU 链表;
  3. 如果是 dirty page,那么将 dirty page 置为 clean page,并从 flush list 中删除;
  4. 然后进行第二次遍历 LRU,将 page 从 LRU 中移动到 free list 中;
  5. 释放 buffer pool mutex 和 flush list mutex。

在整个删除表的过程中,持有了 buffer pool mutex 和 flush list mutex ,如果整个 buffer pool 比较大,或者表有较多的脏页,那么持有锁的时间会比较长,导致其他事务在用到这个 buffer pool 的时候被阻塞,现象上来看就是这个实例被夯住。

硬链接删除表

?1. 主库和从库上对表建立硬链接

ln table_1.ibd table_1.ibd.hdlk
ln table_1.frm table_1.frm.hdlk

?2. 在主库进行 drop table

drop table table_1;

?3. 在 os 层删除物理文件

rm table_1.ibd.hdlk
rm table_1.frm.hdlk

?4. 如果表达到 500G 或者上 TB,则可以用 truncate 命令进行截断删除

truncate -s 2G table_1.ibd.hdlk

原文地址:https://www.cnblogs.com/haohaozhang/p/12236174.html

时间: 2024-12-13 15:46:55

【MySQL】使用硬链接的方式删除大表的相关文章

MySQL 存储过程删除大表

1.权限问题 alter routine 编辑或删除存储过程 create routine 建立存储过程 execute 创建存储过程 2.存储过程相关的一些命令 show procedure status\G 查看数据库中有哪些存储过程 show procedure status where db = 'db_name'\G 查看指定数据库(db_name)中有哪些存储过程 select name from mysql.proc where db = 'db_name'; 查看指定数据库(db

删除大表的数据:普通删除语句和游标处理的比较

一.前言 WHERE条件用不到索引的情况下如何删除大表记录?文章中只是列举出其中一种方式而已,但仍然存在很多不严谨的地方.只是 轻描淡写随着数据表越来越大,历史数据的处理将越来越困难.且过滤字段没有索引(如时间)字段,而创建索引是需要临时表空间排序的.有越来越大,创建的维护工作也随之越来越难. 除了本文介绍的方法以外,还可以通过以下几种方法来维护历史数据: 1. 创建历史表,将历史数据定期移至历史表,让源表保持"瘦小身材"(源表会有碎片,需要定期对表和索引进行重建) 2. ORACLE

WHERE条件用不到索引的情况下如何删除大表记录?

如果开发人员在做表设计阶段没有考虑到大表历史数据的维护性,随着数据量越来越大,表就越来越难管理和维护.连创建索引的失败都可能会失败(因为创建索引要利用临时表空间的的排序,当临时表空间不够大创建索引的动作就会报错).如果过滤条件用不到索引,每成功完成一次delete操作就需要全表扫描一次...那么几十GB的大表,情何以堪...? 那么有什么方法可以解决这种问题吗?当然改造生产表是可以的(利用DBMS_REDEFINITION在线重定义的方法可以很好的控制阻塞时间)再者可以利用游标获取结果集每行的R

Oracle 删除大表中部分数据

需求: 项目中有一张表大概有7000多万条数据,造成表空间已满,需要清理部分数据,打算清理3000万. 2B 做法: delete from table_name where ID > '40000000'; 备注:select count(1) from table_name where ID > 'his_batch_4000000';  的结果大概有3000万条数据. 影响: 删了N个小时也没执行完,最终强制停止,造成表被锁.(没有管理员权限,需要联系DBA 才能解锁) 改进: decl

删除大表数据

declare cursor mycursor is SELECT ROWID FROM tpr_zjjx1 WHERE jxrq=to_date('2013-06-30','yyyy-mm-dd') order by rowid; type rowid_table_type is table of rowid index by pls_integer; v_rowid rowid_table_type; BEGIN open mycursor; loop fetch mycursor bulk

MYSQL百G大表正确清空方式

当我们遇到大表清空时,会有几种相应的操作方法(表player): 1. truncate table player; 2. 创建新表.rename表.然后直接drop老表 3. 创建新表.rename表.创建老表硬链接.slowrm进行大文件删除. 注:创建新表时,需要提前和开发沟通用来确认新表自增ID起始位置 下面将是几种方案的操作步骤以及优劣势 1.操作步骤: * truncate table player; 优势:操作简单 劣势:表产生元数据锁,机器资源占用过高. 结论:强烈不推荐使用 2

MySQL DROP TABLE操作以及 DROP 大表时的注意事项

语法: 删表 DROP TABLE Syntax DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ... [RESTRICT | CASCADE] 可一次删除一张或多张表.需具有所删除表上的DROP权限. 表定义文件和数据文件均被移除.表被删除后表上的用户权限不会被自己主动删除. 參数里表中指定的表名不存在则报错,但对于存在的表仍会删除.可通过指定IF EXISTS阻止表不存在时引发的错误(此时对于不存在的表仅产生一个NOTE).

Linux文件系统 软链接 硬链接

要理解软硬链接,就先要从ext文件系统的存储原理说起 硬盘上最小的存储单位是sector, 大小为512bytes. 因为数据往往都大于512bytes所以我们把多个sector连起来存储数据, 这样做的目的是减少磁盘I/O的负担 这个多个连起来的sector叫做block.Block的大小是2的n次方倍512bytes 存储空间分为:数据区和元数据区 数据区:block存储真实数据,一般大小为1kb 2kb, 4kb 元数据区: inode存储元数据,包括inode索引,名称,大小,修改时间等

大表DROP删除小技巧

在日常工作中,经常会遇到历史大表从主库上迁移到备份机,以便腾出主库空间,那么如果你直接drop table 后,可能会引起数据库抖动,连接数升高等问题,从而影响业务. 那么用一个小技巧,即可轻松平滑的从主库上删除历史大表. 1.创建一个硬链接,在drop table 表时,"欺骗"MySQL已经删除完毕. ln test.ibd test.ibd.hdlk 2.这个时候不要直接rm test.ibd.hdlk,这样会引起磁盘IO转速上升,MySQL会发生性能抖动. 我们这里写一个脚本,