線上IM消息的數據庫,磁盤空間使用率已到達96%html
沒申請到擴容的新機器,沒法作數據庫遷移mysql
保留的是全量聊天記錄,一條都不準刪sql
在這種場景下,爲了減小空間容量,只能對錶作碎片整理來釋放空間, optimize table數據庫
當咱們使用mysql進行delete數據,delete完之後,發現空間文件ibd並無減小,這是由於碎片空間的存在,舉個例子,一共公司有10號員工,10個座位,被開除了7個員工,但這些座位仍是保留的,碎片整理就像,讓剩下的3個員工都靠邊坐,而後把剩下的7個做爲給砸掉,這樣就能釋放出空間了bash
OPTIMIZE TABLE
reorganizes the physical storage of table data and associated index data, to reduce storage space and improve I/O efficiency when accessing the table. app
好處除了減小表數據與表索引的物理空間,還能下降訪問表時的IO,這個比較理解,整理以前,取數據須要跨越不少碎片空間,這時須要時間的,整理後,想要的數據都放在一塊兒了,直接拿就拿到了,效率提升ide
拿一張大表作碎片整理,整理以前是96Gui
[root@localhost myshard]# du -ch tbl_immsg_bigo_96.ibd |grep total 3.5G total
當執行命令時
spa
optimise table tbl_immsg_bigo_96;
整理完後,剩下2.9Gcode
myshard> optimize no_write_to_binlog table tbl_immsg_bigo_96; +---------------------------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +---------------------------+----------+----------+-------------------------------------------------------------------+ | myshard.tbl_immsg_bigo_96 | optimize | note | Table does not support optimize, doing recreate + analyze instead | | myshard.tbl_immsg_bigo_96 | optimize | status | OK | +---------------------------+----------+----------+-------------------------------------------------------------------+ 2 rows in set (3 min 21.66 sec) [root@localhost myshard]# du -ch tbl_immsg_bigo_96.ibd |grep total 2.9G total
整理期間會有不少慢查詢的告警,在告一個waiting for table metadata lock的狀態
ID: 121
USER: db_myshard_rw
HOST: 127.0.0.1:56326
DB: myshard
COMMAND: Execute
TIME: 1214
STATE: Waiting for table metadata lock
INFO: insert into myshard.tbl_immsg_bigo_0 (touid,fromuid,fromseqid,appid
這是由於optimize table的本質,是alter table
mysql 5.5 的改表過程以下
1.建立一張新的臨時表 tmp
2.把舊錶鎖住,禁止插入刪除,只容許讀寫 (這就是爲何上面的insert語句都停留在waiting for table metadata lock)
3.把數據不斷的從舊錶,拷貝到新的臨時表,(這就是上面報copy to tmp table)
4.等表拷貝完後,進行瞬間的rename操做
5.舊錶刪除掉
因此optimize最大的問題是鎖表,鎖表會致使insert,delete,update語句堵住,上面等待了1214秒,還在繼續,因此第一個結論:在使用optimize table的時候,確保不要有任何dml語句,確保業務切走,不然可能會出事故
爲何要鎖表呢?
alter過程裏,數據不停從舊錶拷貝到新表,若是這個時候舊錶被delete了數據了,那舊錶與新表的數據就不一致了,到最後rename 新表 to 舊錶表名 時候,數據量就多了
若是在拷貝數據的過程當中,對舊錶數據的delete,同時對新表也作delete,那數據就一致了,對於update和insert也同樣,這個功能能夠經過 insert觸發器,delete觸發器,update觸發器實現
pt-online-schema-change就利用3個觸發器完成在線改表,也能完成在線碎片整理,命令使用
--alter="ENGINE=InnoDB"
至關於optimize table的效果
具體命令以下,最好放在腳本里面實現,由於一次不止整理一個表,能夠把整個數據庫的表都碎片整理
pt-online-schema-change -h地址 -P端口號 -u用戶名 -p密碼 --database=數據庫 t=表名字 --charset=utf8 --max-lag=300 --check-interval=5 --alter="ENGINE=InnoDB" --max-load="Threads_running:400" --critical-load="Threads_running:400" --nocheck-replication-filters --alter-foreign-keys-method=auto --execute
使用pt-online-schema-change能夠跳過鎖表的坑
爲了保持兩張表的數據一致性,拷貝的那部分數據須要上鎖,使用共享鎖share_mode來鎖行,能夠經過show full processlist看到一次大概對10萬行,每次拷貝1秒不到
INSERT LOW_PRIORITY IGNORE INTO `myshard`.`_tbl_immsg_bigo_128_new` (`sid`, `tm_timestamp`, `tm_lasttime`, `gid`, `group_name`, `default_flag`, `group_attr`, `group_owner`, `group_extension`, `is_del`, `app_id`, `mic_seat`, `invite_perm`, `invite_media_perm`, `pub_id_search`, `apply_verify`, `public_id`, `introduc`, `family_id`, `__version`, `__deleted`) SELECT `sid`, `tm_timestamp`, `tm_lasttime`, `gid`, `group_name`, `default_flag`, `group_attr`, `group_owner`, `group_extension`, `is_del`, `app_id`, `mic_seat`, `invite_perm`, `invite_media_perm`, `pub_id_search`, `apply_verify`, `public_id`, `introduc`, `family_id`, `__version`, `__deleted` FROM `myshard`.`tbl_immsg_bigo_128` FORCE INDEX(`PRIMARY`) WHERE ((`sid` >= '2112908055')) AND ((`sid` <= '2112916949')) LOCK IN SHARE MODE /*pt-online-schema-change 119079 copy nibble*/
原本使用碎片整理是由於磁盤使用率96%,但碎片整理時發現磁盤使用率變成99%,差點就爆了
Filesystem Size Used Avail Use% Mounted on /dev/sda2 58G 2.7G 53G 5% / tmpfs 24G 0 24G 0% /dev/shm /dev/sda1 485M 32M 428M 7% /boot /dev/sda5 1.6T 452G 1.1T 31% /data /dev/sdb1 1.3T 1.2T 25G 99% /data1
這是由於在把舊錶拷貝到臨時表的時,會把表數據複製一份數據,10G的表,可能複製出來是7G,這個過程磁盤會快速消耗,不當心就會把磁盤撐滿形成數據丟失了
爲了不這個坑,應該把整個數據庫的表,按照體積從小到大排序,而且把索引文件,表結構去掉,爲了方便顯示出體積,這裏加了一個l參數,其實是不加的,只獲取表名字,而後重定向一個文件裏,碎片整理就按照這個順序
ls -lSr --ignore="*.frm" -rw-rw---- 1 mysql mysql 4096 Jul 25 12:33 tables_priv.MYI -rw-rw---- 1 mysql mysql 4096 Jul 25 12:33 procs_priv.MYI -rw-rw---- 1 mysql mysql 4096 Jul 25 12:33 columns_priv.MYI -rw-rw---- 1 mysql mysql 5120 Jul 25 12:33 proxies_priv.MYI -rw-rw---- 1 mysql mysql 5120 Jul 25 12:43 db.MYI -rw-rw---- 1 mysql mysql 8928 Jul 25 12:33 help_relation.MYD -rw-rw---- 1 mysql mysql 16384 Jul 25 12:33 help_keyword.MYI -rw-rw---- 1 mysql mysql 18432 Jul 25 12:33 help_relation.MYI -rw-rw---- 1 mysql mysql 20480 Jul 25 12:33 help_topic.MYI -rw-rw---- 1 mysql mysql 22078 Jul 25 12:33 help_category.MYD -rw-rw---- 1 mysql mysql 89241 Jul 25 12:33 help_keyword.MYD -rw-rw---- 1 mysql mysql 419392 Jul 25 12:33 help_topic.MYD
能夠寫一個腳本,統計每一個表整理的時間,整理先後的體積比較,效果以下
正在對錶tbl_immsg_bigo_128進行碎片整理...第9張,還剩93張 +----------------------------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +----------------------------+----------+----------+-------------------------------------------------------------------+ | myshard.tbl_immsg_bigo_128 | optimize | note | Table does not support optimize, doing recreate + analyze instead | | myshard.tbl_immsg_bigo_128 | optimize | status | OK | +----------------------------+----------+----------+-------------------------------------------------------------------+ 表:tbl_immsg_bigo_128, 整理前:3373M, 整理後:2729M, 節省空間:-644M,耗時:143秒 ---------------------------------------------------------------------------------------------- 正在對錶tbl_immsg_bigo_132進行碎片整理...第10張,還剩92張 +----------------------------+----------+----------+-------------------------------------------------------------------+ | Table | Op | Msg_type | Msg_text | +----------------------------+----------+----------+-------------------------------------------------------------------+ | myshard.tbl_immsg_bigo_132 | optimize | note | Table does not support optimize, doing recreate + analyze instead | | myshard.tbl_immsg_bigo_132 | optimize | status | OK | +----------------------------+----------+----------+-------------------------------------------------------------------+ 表:tbl_immsg_bigo_132, 整理前:3541M, 整理後:2889M, 節省空間:-652M,耗時:153秒
所有表整理完之後,96%的空間,碎片整理完後變成85%,騰出130G的空間