91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Innodb中mysql如何快速刪除2T的大表

發布時間:2020-08-11 10:26:03 來源:ITPUB博客 閱讀:208 作者:haoge0205 欄目:MySQL數據庫

假設,你有一個表 erp,如果你直接進行下面的命令

drop table erp

這個時候所有的mysql的相關進程都會停止,直到 drop結束,mysql才會恢復執行。出現這個情況的原因就是因為,在 drop table的時候, innodb維護了一個全局鎖, drop完畢鎖就釋放了。
這意味著,如果在白天,訪問量非常大的時候,如果你在不做任何處理措施的情況下,執行了刪大表的命令,整個 mysql就掛在那了,在刪表期間, QPS會嚴重下滑,然后產品經理就來找你喝茶了。所以才有了漫畫中的一幕, 你可以在晚上十二點,夜深人靜的時候再刪
當然,有的人不服,可能會說:" 你可以寫一個刪除表的存儲過程,在晚上沒啥訪問量的時候運行一次就行。"
我內心一驚,細想一下,只能說:"大家還是別抬杠了,還是聽我說一下業內通用做法。"

一個假設

先說明一下,在這里有一個前提,mysql開啟了 獨立表空間,MySQL5.6.7之后默認開啟。
也就是在 my.cnf中,有這么一條配置(這些是屬于mysql優化的知識,后期給大家介紹)

innodb_file_per_table = 1

查看表空間狀態,用下面的命令

mysql> show variables like '%per_table';  
+-----------------------+-------+  | Variable_name         | Value |  
+-----------------------+-------+  | innodb_file_per_table | OFF   |  
+-----------------------+-------+

如果 innodb_file_per_tablevalue值為 OFF,代表采用的是 共享表空間
如果 innodb_file_per_tablevalue值為 ON ,代表采用的是 獨立表空間
于是,大家要問我, 獨立表空間共享表空間的區別?
共享表空間:某一個數據庫的所有的表數據,索引文件全部放在一個文件中,默認這個共享表空間的文件路徑在data目錄下。 默認的文件名為:ibdata1(此文件,可以擴展成多個)。 注意,在這種方式下,運維超級不方便。你看,所有數據都在一個文件里,要對單表維護,十分不方便。另外,你在做 delete操作的時候,文件內會留下很多間隙,ibdata1文件不會自動收縮。換句話說,使用 共享表空間來存儲數據,會遭遇 drop table之后,空間無法釋放的問題。

獨立表空間:每一個表都以獨立方式來部署,每個表都有一個.frm表描述文件,還有一個.ibd文件。
.frm文件:保存了每個表的元數據,包括表結構的定義等,該文件與數據庫引擎無關。
.ibd文件:保存了每個表的數據和索引的文件。
注意,在這種方式下,每個表都有自已獨立的表空間,這樣運維起來方便,可以實現單表在不同數據庫之間的移動。另外,在執行 drop table操作的時候,是可以自動回收表空間。在執行 delete操作后,可以通過 alter table TableName engine=innodb可以整理碎片,回收部分表空間。

ps: my.cnf中的 datadir就是用來設置數據存儲目錄

好了,上面巴拉巴拉了一大堆,我只想說一個 事情:

在絕大部分情況下,運維一定會為mysql選擇獨立表空間的存儲方式,因為采用獨立表空間的方式,從性能優化和運維難易角度來說,實在強太多。

所以,我在一開始所提到的前提,mysql需要開啟 獨立表空間。這個假設,百分九十的情況下是成立的。如果真的遇到了,你們公司的mysql采用的是 共享表空間的情況,請你和你們家的運維談談心,問問為啥用 共享表空間

正確姿勢

假設,我們有 datadir = /data/mysql/,另外,我們有有一個 database,名為 mytest。在數據庫 mytest中,有一個表,名為 erp,執行下列命令

mysql> system ls -l /data/mysql/mytest/

得到下面的輸出(我過濾了一下)

-rw-r----- 1 mysql mysql          9023  8 18 05:21 erp.frm-rw-r----- 1 mysql mysql 2356792000512  8 18 05:21 erp.ibd

frmibd的作用,上面介紹過了。現在就是 erp.ibd文件太大,所以刪除卡住了。
如何解決這個問題呢?
這里需要利用了linux中 硬鏈接的知識,來進行快速刪除。下面容我上《鳥哥的私房菜》中的一些內容,
軟鏈接其實大家可以類比理解為windows中的快捷方式,就不多介紹了,主要介紹一下硬鏈接。
至于這個 硬鏈接,我簡單說一下,不想貼一大堆話過來,看起來太累。
就是對于真正存儲的文件來說,有一個
Innodb中mysql如何快速刪除2T的大表
然后呢有一個 文件名指向上面的 node Index
Innodb中mysql如何快速刪除2T的大表
那么,所謂的 硬鏈接,就是不止一個 文件名指向 node Index,有好幾個 文件名指向 node Index
假設,這會又有一個 文件名指向上面的 node Index,即
Innodb中mysql如何快速刪除2T的大表
這個時候,你做了刪除 文件名(1)的操作,linux系統檢測到,還有一個 文件名(2)指向 node Index,因此并不會真正的把文件刪了,而是把 步驟(2)的引用給刪了,這步操作非常快,畢竟只是刪除引用。于是圖就變成了這樣
Innodb中mysql如何快速刪除2T的大表
接下來,你再做刪除 文件名(2)的操作,linux系統檢測到,沒有其他 文件名指向該 node Index,就會刪除真正的存儲文件,這步操作,是刪真正的文件,所以比較慢。

OK,我們用的就是上面的原理。
先給 erp.ibd建立一個硬鏈接,利用 ln命令

mysql> system ln /data/mysql/mytest/erp.ibd /data/mysql/mytest/erp.ibd.hdlk

此時,文件目錄如下所示

-rw-r----- 1 mysql mysql          9023  8 18 05:21 erp.frm-rw-r----- 2 mysql mysql 2356792000512  8 18 05:21 erp.ibd-rw-r----- 2 mysql mysql 2356792000512  8 18 05:21 erp.ibd.hdlk

你會發現,多了一個 erp.ibd.hdlk文件,且 erp.ibderp.ibd.hdlk的inode均為2。
此時,你執行 drop table操作

mysql> drop table erp;Query OK, 0 rows affected (0.99 sec)

你會發現,不到1秒就刪除了。因為,此時有兩個文件名稱( erp.ibderp.ibd.hdlk),同時指向一個inode.這個時候,執行刪除操作,只是把引用給刪了,所以非常快。
那么,這時的刪除,已經把table從mysql中刪除。但是磁盤空間,還沒釋放,因為還剩一個文件 erp.ibd.hdlk

如何正確的刪除 erp.ibd.hdlk呢?
如果你沒啥經驗,一定會回答我,用 rm命令來刪。這里需要說明的是,在生產環境,直接用 rm命令來刪大文件,會造成磁盤IO開銷飆升,CPU負載過高,是會影響其他程序運行的。
那么,這種時候,就是應該用 truncate命令來刪, truncate命令在 coreutils工具集中。
詳情,大家可以去百度一下,有人對 rmtruncate命令,專程測試過, truncate命令對磁盤 IO,CPU負載幾乎無影響。
刪除腳本如下

TRUNCATE=/usr/local/bin/truncatefor i in `seq 2194 -10 10 `; 
do 
  sleep 2
  $TRUNCATE -s ${i}G /data/mysql/mytest/erp.ibd.hdlk 
done
rm -rf /data/mysql/mytest/erp.ibd.hdlk ;

從2194G開始,每次縮減10G,停2秒,繼續,直到文件只剩10G,最后使用 rm命令刪除剩余的部分。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

杨浦区| 台山市| 陆河县| 麻栗坡县| 兰考县| 崇州市| 六盘水市| 弥勒县| 高要市| 苍溪县| 墨脱县| 郴州市| 常山县| 乌鲁木齐县| 黔江区| 辽阳县| 屏东县| 綦江县| 北京市| 宁国市| 康定县| 房产| 大丰市| 高雄县| 北票市| 宁都县| 乐山市| 威信县| 喀什市| 辽源市| 平度市| 连州市| 开封市| 宿松县| 缙云县| 齐齐哈尔市| 陆丰市| 兴城市| 安康市| 江安县| 莱芜市|