最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL表數(shù)據(jù)刪除與清理的最佳實踐

 更新時間:2025年12月25日 08:30:57   作者:·云揚·  
在MySQL運維中,刪除操作看似簡單,卻隱藏著諸多風險,誤刪表導致數(shù)據(jù)永久丟失、delete全表引發(fā)主從延遲、刪數(shù)據(jù)后磁盤空間不釋放等等,本文基于實際運維場景,詳細講解刪除表、清空表、部分數(shù)據(jù)刪除、分區(qū)表清理四大核心場景的最佳操作方案,需要的朋友可以參考下

在MySQL運維中,“刪除”操作看似簡單,卻隱藏著諸多風險——誤刪表導致數(shù)據(jù)永久丟失、delete全表引發(fā)主從延遲、刪數(shù)據(jù)后磁盤空間不釋放……這些問題往往會造成業(yè)務中斷或資源浪費。本文基于實際運維場景,詳細講解刪除表、清空表、部分數(shù)據(jù)刪除(歸檔/不歸檔)、分區(qū)表清理四大核心場景的最佳操作方案,結合實驗驗證和原理分析,幫你在“安全”與“效率”之間找到平衡。

一、刪除表:先“隔離”再“刪除”,避免誤刪風險

直接執(zhí)行DROP TABLE是高危操作——若存在未發(fā)現(xiàn)的業(yè)務依賴(如定時任務、應用SQL),會瞬間導致服務報錯;且誤刪后恢復成本極高(需從備份恢復,耗時久)。最佳實踐是先重命名表“隔離”,觀察無依賴后再刪除

1.1 操作步驟(以表t1為例)

步驟1:創(chuàng)建測試表(模擬業(yè)務表)

-- 先刪除舊表(若存在),避免沖突
drop table if exists t1;

-- 創(chuàng)建業(yè)務表t1(InnoDB引擎,含自增主鍵和時間字段)
CREATE TABLE `t1` (
  `id` int NOT NULL AUTO_INCREMENT,
  `a` varchar(20) DEFAULT NULL,  -- 業(yè)務字段1
  `b` int DEFAULT NULL,          -- 業(yè)務字段2
  `c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,  -- 自動時間戳
  PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8mb4 ;

步驟2:重命名表,實現(xiàn)“隔離”

將目標表重命名為“備份+日期”格式(如t1_bak_20231114),切斷業(yè)務直接訪問:

alter table t1 rename t1_bak_20231114;

步驟3:觀察依賴,確認安全

重命名后,觀察1-2周(根據(jù)業(yè)務周期調(diào)整),重點監(jiān)控:

  • 應用日志:是否出現(xiàn)“Table ‘martin.t1’ doesn’t exist”錯誤(排查隱藏依賴);
  • 數(shù)據(jù)庫進程:是否有定時任務或存儲過程調(diào)用原表名。

若觀察期內(nèi)無異常,說明表無依賴,可執(zhí)行刪除。

步驟4:最終刪除備份表

drop table t1_bak_20231114;

1.2 核心原理與注意事項

  • 為什么不直接drop?
    重命名本質(zhì)是“邏輯隔離”,若發(fā)現(xiàn)誤操作,可快速改回原表名(alter table t1_bak_20231114 rename t1;),恢復成本幾乎為0;而drop會直接刪除表結構和數(shù)據(jù)文件,無法快速恢復。
  • 適用場景:非緊急刪除的冗余表、歷史表(如舊業(yè)務下線后的廢棄表)。

二、清空表:選對工具(truncate),避免空間浪費與主從延遲

清空表(刪除全表數(shù)據(jù))時,很多人習慣用DELETE FROM 表名,但該操作存在兩大問題:不釋放磁盤空間、行模式binlog下產(chǎn)生大量日志導致主從延遲。正確選擇是TRUNCATE TABLE。

2.1 實驗對比:delete vs truncate

步驟1:準備測試數(shù)據(jù)(10萬行)

use martin;

-- 重建表t1
drop table if exists t1;
CREATE TABLE `t1` (
  `id` int NOT NULL AUTO_INCREMENT,
  `a` varchar(20) DEFAULT NULL,
  `b` int DEFAULT NULL,
  `c` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB CHARSET=utf8mb4 ;

-- 創(chuàng)建存儲過程,插入10萬行數(shù)據(jù)
drop procedure if exists insert_t1;
delimiter ;;  -- 臨時修改語句結束符,避免與存儲過程內(nèi);沖突
create procedure insert_t1()
begin
  declare i int;
  set i=1;
  while(i<=100000)do  -- 循環(huán)插入10萬行
    insert into t1(a,b) values(i,i);
    set i=i+1;
  end while;
end;;
delimiter ;

-- 執(zhí)行存儲過程,初始化數(shù)據(jù)
call insert_t1();

步驟2:查看數(shù)據(jù)文件大?。↖nnoDB表的.ibd文件)

InnoDB表的數(shù)據(jù)存儲在ibd文件中,先查看初始大?。?/p>

# 進入MySQL數(shù)據(jù)目錄(需根據(jù)實際路徑調(diào)整,此處為/data/mysql/data/martin)
cd /data/mysql/data/martin
# 查看t1.ibd大?。?h表示人性化顯示,如KB/MB)
ll -h t1.ibd

實驗結果t1.ibd約12MB(10萬行數(shù)據(jù))。

步驟3:用delete清空表,觀察空間變化

-- delete全表數(shù)據(jù)
delete from t1;

再執(zhí)行ll -h t1.ibd,結果:文件大小仍為12MB,無變化。

步驟4:用truncate清空表,觀察空間變化

-- 先重建表并插入數(shù)據(jù)(恢復到步驟2狀態(tài))
call insert_t1();
-- truncate清空表
truncate table t1;

再執(zhí)行ll -h t1.ibd,結果:文件大小驟減至112KB(僅保留表結構,釋放所有數(shù)據(jù)空間)。

2.2 關鍵差異:delete vs truncate

對比維度DELETETRUNCATE
操作類型DML(數(shù)據(jù)操縱語言)DDL(數(shù)據(jù)定義語言)
空間釋放不釋放(僅標記刪除)釋放(重建表結構)
binlog記錄行模式下逐行記錄(日志量大)僅記錄“ truncate操作”(日志量?。?/td>
事務支持可回滾(未提交前可撤銷)不可回滾(執(zhí)行即生效)
自增主鍵重置不重置(下次插入從上次ID繼續(xù))重置(下次插入從1開始)

2.3 注意事項

  • 必須先備份:無論用哪種方式,清空表前需用mysqldump備份數(shù)據(jù)(mysqldump -uroot -p martin t1 > t1_bak.sql),避免誤清。
  • truncate的限制:若表被外鍵引用(FOREIGN KEY),無法直接truncate(需先刪除外鍵或清空關聯(lián)表);而delete可正常執(zhí)行。

三、不歸檔刪除部分數(shù)據(jù):避免大事務,用批量刪除或工具

當需刪除表中部分數(shù)據(jù)(如刪除b<50000的歷史數(shù)據(jù))且無需歸檔時,直接執(zhí)行DELETE FROM t2 WHERE b<50000會引發(fā)大事務——鎖表時間長、占用大量undo日志、主從延遲。最佳方案是批量刪除(加limit) 或用專業(yè)工具pt-archiver。

3.1 方案1:循環(huán)批量刪除(適合中小數(shù)據(jù)量)

核心邏輯:

每次刪除1000-10000行(根據(jù)服務器性能調(diào)整),循環(huán)執(zhí)行直到滿足條件的數(shù)據(jù)刪完,避免單次刪除行數(shù)過多。

操作步驟:

步驟1:準備測試表與數(shù)據(jù)(10萬行)

use martin;

drop table if exists t2;
CREATE TABLE `t2` (        
  `id` int NOT NULL AUTO_INCREMENT,
  `a` int DEFAULT NULL,
  `b` int DEFAULT NULL,
  PRIMARY KEY (id),  -- 主鍵索引
  key idx_b(b)       -- 為查詢條件b創(chuàng)建索引,加速刪除
) ENGINE=InnoDB CHARSET=utf8mb4 ;

-- 存儲過程插入10萬行數(shù)據(jù)
drop procedure if exists insert_t2;
delimiter ;;
create procedure insert_t2()       
begin
  declare i int;                 
  set i=1;                     
  while(i<=100000)do                 
    insert into t2(a,b) values(i,i); 
    set i=i+1;                     
  end while;
end;;
delimiter ;
call insert_t2();

步驟2:備份數(shù)據(jù)(安全前提)

# 用mysqldump備份t2表
cd /data/backup
mysqldump -uroot -p martin t2 > t2_bak.sql

# 或創(chuàng)建備份表,復制數(shù)據(jù)(更快速)
create table t2_bak_1114 like t2;  -- 復制表結構
insert into t2_bak_1114 select * from t2;  -- 復制數(shù)據(jù)

步驟3:循環(huán)批量刪除

DELIMITER //

CREATE PROCEDURE delete_t2()
BEGIN
    REPEAT
        DELETE FROM t2 WHERE b < 50000 LIMIT 1000;
    UNTIL ROW_COUNT() = 0 END REPEAT;
    
    SELECT '刪除完成' AS result;
END //

DELIMITER ;

驗證結果:

-- 確認刪除效果(應返回0)
select count(*) from t2 where b < 50000;
-- 剩余數(shù)據(jù)量(應返回50000)
select count(*) from t2 where b >= 50000;

3.2 方案2:用pt-archiver工具(適合大數(shù)據(jù)量)

pt-archiver是Percona Toolkit中的工具,專為批量歸檔/刪除MySQL數(shù)據(jù)設計,支持按條件批量處理、統(tǒng)計進度,且能避免大事務。

步驟1:安裝Percona Toolkit(以CentOS為例)

# 安裝依賴
yum install -y perl-DBI perl-DBD-MySQL perl-Time-HiRes perl-IO-Socket-SSL

# 下載并安裝Percona Toolkit
wget https://downloads.percona.com/downloads/percona-toolkit/3.5.1/binary/redhat/8/x86_64/percona-toolkit-3.5.1-1.el8.x86_64.rpm
rpm -ivh percona-toolkit-3.5.1-1.el8.x86_64.rpm

# 驗證安裝(查看版本)
pt-archiver --version

步驟2:創(chuàng)建工具專用用戶(授予權限)

-- 創(chuàng)建dba用戶,允許192.168網(wǎng)段訪問
CREATE USER 'dba'@'192.168.%' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'Id81Gdac_a';
-- 授予全庫權限(生產(chǎn)環(huán)境可縮小權限范圍,僅授予martin庫權限)
GRANT all ON *.* TO 'dba'@'192.168.%';

步驟3:執(zhí)行刪除(不歸檔,僅刪除)

pt-archiver \
--source h=192.168.184.151,u=dba,p='Id81Gdac_a',D=martin,t=t2 \  # 源表信息
--where "b<50000" \  # 刪除條件
--progress 10000 \   # 每處理10000行顯示進度
--limit=1000 \       # 每次處理1000行
--txn-size 10000 \   # 每10000行提交一次事務
--no-safe-auto-increment \  # 不修改自增主鍵(避免影響后續(xù)插入)
--statistics \       # 輸出統(tǒng)計信息(如處理時間、行數(shù))
--purge              # 僅刪除,不歸檔(核心參數(shù))

統(tǒng)計結果示例:

四、歸檔刪除部分數(shù)據(jù):先遷移再刪除,兼顧數(shù)據(jù)保留與空間回收

若需刪除的部分數(shù)據(jù)需長期保留(如歸檔歷史日志),需先將數(shù)據(jù)遷移到“歸檔庫”,再刪除源表數(shù)據(jù)。同時,需注意:delete刪除后表會產(chǎn)生“空洞”(未釋放的空間),需重建表回收空間。

4.1 操作步驟(用pt-archiver實現(xiàn)歸檔+刪除)

步驟1:準備歸檔環(huán)境

  • 源庫:192.168.184.151(martin庫,t2表,需刪除b<50000的數(shù)據(jù));
  • 歸檔庫:192.168.184.152(新建archiver_db庫,t2_archiver表,用于存儲歸檔數(shù)據(jù))。

步驟2:在歸檔庫創(chuàng)建表結構

-- 登錄歸檔庫(192.168.184.152)
mysql -uroot -p

-- 創(chuàng)建歸檔數(shù)據(jù)庫
create database archiver_db;
use archiver_db;

-- 創(chuàng)建與源表結構一致的歸檔表
CREATE TABLE `t2_archiver` (        
  `id` int NOT NULL AUTO_INCREMENT,
  `a` int DEFAULT NULL,
  `b` int DEFAULT NULL,
  PRIMARY KEY (id),
  key idx_b(b)
) ENGINE=InnoDB CHARSET=utf8mb4 ;

-- 授予dba用戶歸檔庫權限
CREATE USER 'dba'@'192.168.%' IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'Id81Gdac_a';
GRANT all ON *.* TO 'dba'@'192.168.%';

步驟3:歸檔+刪除(pt-archiver)

# 關閉歸檔庫的防火墻(避免連接失敗)
iptables -F  # 僅測試環(huán)境,生產(chǎn)環(huán)境需配置白名單

# 執(zhí)行歸檔+刪除
pt-archiver \
--source h=192.168.184.151,u=dba,p='Id81Gdac_a',D=martin,t=t2 \  # 源表
--dest h=192.168.184.152,u=dba,p='Id81Gdac_a',D=archiver_db,t=t2_archiver \  # 歸檔表
--where "b<50000" \  # 歸檔條件
--progress 10000 \   # 進度顯示
--limit=1000 \       # 每次處理1000行
--txn-size 10000 \   # 事務大小
--no-safe-auto-increment \
--statistics \
--purge              # 歸檔后刪除源表數(shù)據(jù)

步驟4:驗證歸檔與刪除結果

源庫驗證

select count(*) from martin.t2 where b<50000;  -- 應返回0
select count(*) from martin.t2;  -- 應返回50001

歸檔庫驗證

select count(*) from archiver_db.t2_archiver;  -- 應返回49999
select min(b),max(b) from archiver_db.t2_archiver;  -- 應返回1和49999

4.2 回收delete產(chǎn)生的“空洞”空間

delete刪除數(shù)據(jù)后,InnoDB會將數(shù)據(jù)標記為“刪除”,但磁盤空間不釋放(形成“空洞”),需通過重建表回收空間:

-- 方法1:alter table重建表(推薦,InnoDB會整理空間)
alter table martin.t2 engine=InnoDB;

-- 方法2:optimize table(效果同上,僅支持InnoDB和MyISAM)
optimize table martin.t2;

-- 驗證空間變化
ll -h /data/mysql/data/martin/t2.ibd  # 空間應明顯減少

五、分區(qū)表刪除:按分區(qū)清理,效率翻倍

對于按時間/范圍分區(qū)的表(如日志表、訂單歷史表),刪除某一時間段的數(shù)據(jù)時,直接刪除分區(qū)比delete更高效——drop分區(qū)是DDL操作,直接刪除分區(qū)對應的物理文件,無需逐行處理,速度極快。

5.1 操作步驟(以按年份分區(qū)的日志表為例)

步驟1:創(chuàng)建RANGE分區(qū)表

use martin;

drop table if exists t3_log ;

-- 創(chuàng)建按年份分區(qū)的日志表(2016、2017、2018三個分區(qū))
CREATE TABLE t3_log (
    id INT,
    log_info VARCHAR (100),  -- 日志內(nèi)容
    date datetime            -- 分區(qū)鍵(按年份分區(qū))
) ENGINE = INNODB 
PARTITION BY RANGE (YEAR(date))(  -- RANGE分區(qū),按YEAR(date)的值分區(qū)
    PARTITION p2016 VALUES less THAN (2017),  -- 2016年數(shù)據(jù)(<2017)
    PARTITION p2017 VALUES less THAN (2018),  -- 2017年數(shù)據(jù)(<2018)
    PARTITION p2018 VALUES less THAN (2019)   -- 2018年數(shù)據(jù)(<2019)
);

步驟2:插入測試數(shù)據(jù)

insert into t3_log values 
(1,'aaa','2016-01-01'),  -- 進入p2016分區(qū)
(2,'bbb','2016-06-01'),  -- 進入p2016分區(qū)
(3,'ccc','2017-01-01'),  -- 進入p2017分區(qū)
(4,'ddd','2018-01-01');  -- 進入p2018分區(qū)

步驟3:查看分區(qū)數(shù)據(jù)分布

select 
  TABLE_SCHEMA,  -- 數(shù)據(jù)庫名
  TABLE_NAME,    -- 表名
  PARTITION_NAME,-- 分區(qū)名
  TABLE_ROWS     -- 分區(qū)行數(shù)
from information_schema.partitions 
where table_schema='martin' and table_name='t3_log';

結果:p2016(2行)、p2017(1行)、p2018(1行)。

步驟4:刪除2016年數(shù)據(jù)(直接drop分區(qū))

-- 刪除p2016分區(qū)(即刪除2016年所有數(shù)據(jù))
alter table t3_log drop partition p2016;

步驟5:驗證刪除結果

-- 查看分區(qū)列表(p2016已消失)
select PARTITION_NAME from information_schema.partitions where table_schema='martin' and table_name='t3_log';

-- 查詢?nèi)頂?shù)據(jù)(2016年數(shù)據(jù)已刪除)
select * from t3_log;  -- 僅返回2017、2018年數(shù)據(jù)

5.2 核心優(yōu)勢與適用場景

  • 效率高:drop分區(qū)耗時毫秒級,適合TB級大表;
  • 無空洞:刪除分區(qū)直接釋放文件,無需后續(xù)空間回收;
  • 適用場景:按時間/范圍分區(qū)的表(如日志表、賬單表、訂單歷史表)。

六、總結:MySQL刪除操作的核心原則與場景選型

操作場景推薦方案核心注意事項
刪除冗余表重命名→觀察→drop觀察期1-2周,排查隱藏依賴
清空全表數(shù)據(jù)truncate table先備份,外鍵表需先處理關聯(lián)關系
不歸檔刪除部分數(shù)據(jù)(?。?/td>循環(huán)delete + limit每次刪1000-10000行,加索引加速條件查詢
不歸檔刪除部分數(shù)據(jù)(大)pt-archiver --purge低峰期執(zhí)行,避免影響業(yè)務
歸檔刪除部分數(shù)據(jù)pt-archiver --dest + 重建表歸檔庫與源庫結構一致,刪除后回收空洞空間
分區(qū)表刪除歷史數(shù)據(jù)alter table drop partition分區(qū)鍵選擇合理(如時間),避免跨分區(qū)刪除

核心原則

  1. 安全優(yōu)先:任何刪除操作前必須備份,高危操作(如drop表)需先隔離觀察;
  2. 效率第二:根據(jù)數(shù)據(jù)量和場景選對工具,避免大事務和主從延遲;
  3. 空間回收:delete后需通過重建表回收空洞,truncate/drop分區(qū)無需額外操作。

掌握這些方法,可有效避免MySQL刪除操作中的常見風險,同時兼顧效率與資源合理利用,讓運維工作更穩(wěn)定、高效。

以上就是MySQL表數(shù)據(jù)刪除與清理的最佳實踐的詳細內(nèi)容,更多關于MySQL表數(shù)據(jù)刪除與清理的資料請關注腳本之家其它相關文章!

相關文章

  • MySQL導入csv、excel或者sql文件的小技巧

    MySQL導入csv、excel或者sql文件的小技巧

    這篇文章主要介紹了MySQL導入csv、excel或者sql文件的小技巧,具有很好的參考價值,希望對大家有所幫助,一起跟隨小編過來看看吧
    2018-05-05
  • MySQL索引失效的幾種情況詳析

    MySQL索引失效的幾種情況詳析

    這篇文章主要給大家介紹了關于MySQL索引失效的幾種情況,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Mysql數(shù)據(jù)庫中把varchar類型轉化為int類型的方法

    Mysql數(shù)據(jù)庫中把varchar類型轉化為int類型的方法

    這篇文章主要介紹了Mysql數(shù)據(jù)庫中把varchar類型轉化為int類型的方法的相關資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • mysql字符串拼接的幾種實用方式小結

    mysql字符串拼接的幾種實用方式小結

    在SQL語句中經(jīng)常需要進行字符串拼接,下面這篇文章主要給大家介紹了關于mysql字符串拼接的幾種實用方式,文中通過圖文以及代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • 如何利用insert?into?values插入多條數(shù)據(jù)

    如何利用insert?into?values插入多條數(shù)據(jù)

    這篇文章主要介紹了如何利用insert?into?values插入多條數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • MySQL?臨時表創(chuàng)建與使用詳細說明

    MySQL?臨時表創(chuàng)建與使用詳細說明

    MySQL臨時表是存儲在內(nèi)存或磁盤的臨時數(shù)據(jù)表,會話結束時自動銷毀,適合存儲中間計算結果或臨時數(shù)據(jù)集,其名稱以#開頭(如#TempTable),本文給大家介紹MySQL臨時表創(chuàng)建與使用詳細說明,感興趣的朋友跟隨小編一起看看吧
    2025-08-08
  • 使用Dify訪問mysql數(shù)據(jù)庫詳細代碼示例

    使用Dify訪問mysql數(shù)據(jù)庫詳細代碼示例

    這篇文章主要介紹了使用Dify訪問mysql數(shù)據(jù)庫的相關資料,并詳細講解了如何在本地搭建數(shù)據(jù)庫訪問服務,使用ngrok暴露到公網(wǎng),并創(chuàng)建知識庫、數(shù)據(jù)庫訪問工作流和智能體,需要的朋友可以參考下
    2025-03-03
  • MySQL8.0.11版本的新增特性介紹

    MySQL8.0.11版本的新增特性介紹

    這篇文章主要介紹了MySQL8.0.11版本的新增特性介紹,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2018-05-05
  • MySQL常見的腳本語句格式參考指南

    MySQL常見的腳本語句格式參考指南

    無論是運維、開發(fā)、測試,還是架構師,數(shù)據(jù)庫技術是一個必備加薪神器,下面這篇文章主要給大家介紹了關于MySQL常見的腳本語句格式參考指南的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • CentOS7環(huán)境下MySQL8常用命令小結

    CentOS7環(huán)境下MySQL8常用命令小結

    在進行MySQL的優(yōu)化之前必須要了解的就是MySQL的查詢過程,下面這篇文章主要給大家介紹了關于CentOS7環(huán)境下MySQL8常用命令的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06

最新評論

沙湾县| 台山市| 青田县| 古丈县| 瑞安市| 右玉县| 河北区| 玉树县| 景泰县| 鄂托克旗| 于都县| 县级市| 南召县| 西乌珠穆沁旗| 福泉市| 华容县| 海阳市| 乐清市| 大姚县| 南雄市| 乌鲁木齐县| 离岛区| 舒城县| 安图县| 云安县| 应用必备| 黔西县| 黄石市| 通渭县| 全南县| 阜康市| 沁阳市| 玛沁县| 东乌珠穆沁旗| 揭西县| 新闻| 扎赉特旗| 开封县| 疏勒县| 顺昌县| 无为县|