mysql 临时表增加主键_MySQL之重建表
? ? 在MySQL中,如果我們對大表頻繁進(jìn)行insert和delete操作,那么時(shí)間一長,這個(gè)表中會出現(xiàn)很多"空洞",也就是表碎片。
碎片產(chǎn)生的原因是insert隨機(jī)值作為主鍵id,會產(chǎn)生很多數(shù)據(jù)頁分裂操作;而delete掉一些排列有序的主鍵值,這些被delete的空間不會直接釋放,而是僅僅進(jìn)行delete的標(biāo)記,這些空間如果不能被利用,那就會變成"空洞"。
? ? ? 在這種情況下,往往需要對表進(jìn)行重建,從而釋放這些空余的空間,讓數(shù)據(jù)變得"緊湊些",如下:
?這個(gè)重建表的過程,在MySQL5.5之前,它的執(zhí)行邏輯是下面這樣的:
1、假設(shè)原表是A,新建一個(gè)表table B,和表A的表結(jié)構(gòu)保持一致
2、按照主鍵順序,將表A的數(shù)據(jù)一行一行的讀出來,插入到表B里面
3、交換表A和表B的名稱
當(dāng)我們執(zhí)行alter table A engine=Innodb的時(shí)候,就會執(zhí)行我們上述描述的三個(gè)動作。
在MySQL5.6及以后的版本里面,引入了Online DDL的方法,Online DDL的引入,使得上面的過程有了一點(diǎn)點(diǎn)不同,當(dāng)執(zhí)行alter table A engine=Innodb的時(shí)候,MySQL的內(nèi)部動作如下:
1、建立臨時(shí)文件file A,掃描表A主鍵的所有數(shù)據(jù)頁,注意,這里不是臨時(shí)表,而是臨時(shí)文件;
2、用數(shù)據(jù)頁中表A的記錄生成B+樹,然后存儲到臨時(shí)文件中去
3、在生成臨時(shí)文件的過程中,使用另一個(gè)log文件,將對表A的所有DML操作,記錄到log文件中,改文件大小由參數(shù)控制:
mysql>?show?variables?like?"%online%";+----------------------------------+-----------+
|?Variable_name????????????????????|?Value?????|
+----------------------------------+-----------+
|?innodb_online_alter_log_max_size?|?134217728?|
+----------------------------------+-----------+
1?row?in?set,?1?warning?(0.01?sec)
4、臨時(shí)文件file A生成之后,將log中對表A的操作應(yīng)用到臨時(shí)文件中,
5、用臨時(shí)文件替換表A的數(shù)據(jù)文件
這個(gè)重建的過程中,允許對表A做增刪改查的操作,所以稱之為Online DDL。
這里需要注意一點(diǎn),因?yàn)镺nline DDL需要在DDL的過程中支持表的增刪改查操作,所以O(shè)nline DDL一開始會獲取MDL寫鎖,但是在數(shù)據(jù)文件開始拷貝之前,就退化成MDL讀鎖了。
現(xiàn)在我們來說下第一點(diǎn)里面強(qiáng)調(diào)的臨時(shí)文件file A.
在MySQL5.5之前,我們使用臨時(shí)表作為重建的中間介質(zhì),在MySQL5.6之后,我們使用臨時(shí)文件作為重建的中間介質(zhì),這里說說這個(gè)臨時(shí)表和臨時(shí)文件的區(qū)別。
臨時(shí)表是創(chuàng)建在server層面的,臨時(shí)文件是創(chuàng)建在innodb層面的,所以O(shè)nline DDL的整個(gè)過程都是在Innodb內(nèi)部完成的,這種方法也稱之為"inplace",相對應(yīng)的,需要借助server層面臨時(shí)表的過程,稱之為"Copy"。
我們在閱讀Online DDL一節(jié)的官方文檔的時(shí)候,看到的copy和inplace也就是這個(gè)意思。詳情可參見官方文檔:
https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl.html
幾個(gè)小問題:
1、假設(shè)我們有一個(gè)1TB的表,磁盤只有1.2TB,那么還可以做inplace的DDL呢?
答案:不可以,因?yàn)閕nplace方案中的臨時(shí)文件也要占用一定的空間。
2、inplace方案進(jìn)行的表重建操作,都是Online DDL么?
答案:不是,有些操作是inplace的,也就是在innodb層面進(jìn)行的,但是卻不是online的,例如增加全文索引的操作,這個(gè)操作是inplace的,但是會阻塞增刪改查操作,因此不是Online DDL,只能說:Online DDL一定是inplace的,但是inplace方案進(jìn)行的操作,不一定是Online的。
3、加入某個(gè)表的大小是1TB,進(jìn)行alter table A engine=Innodb之后,表的空間沒有縮小,反而增大了一點(diǎn),這是為什么?
答案:可能是因?yàn)楸碇皠倓傔M(jìn)行過一次alter table的操作,而且表上面的并發(fā)增刪改比較多,在進(jìn)行alter table的過程中,這些操作都寫進(jìn)了log中,從而導(dǎo)致表的實(shí)際大小增加。
有幫助的話還希望點(diǎn)下再看哈總結(jié)
以上是生活随笔為你收集整理的mysql 临时表增加主键_MySQL之重建表的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 操作系统饥饿现象_操作系统常见面试题
- 下一篇: dncnn图像去噪_NeuNet2020