前言
最近發(fā)現(xiàn)有一個780w左右的表的某個字段長度設(shè)置不合理,導(dǎo)致數(shù)據(jù)無法插入 , 于是計劃修改長度。 擔(dān)心會鎖表阻塞業(yè)務(wù)所以選擇晚上執(zhí)行修改,結(jié)果在晚上發(fā)現(xiàn)這個修改是秒生效mysql修改表數(shù)據(jù)類型, 并沒有阻塞數(shù)據(jù)庫,于是分析下原因。
字段修改前類型是(255) 字符編碼是。 修改成(2048)
MySQL的行存儲格式
mysql的每行數(shù)據(jù)的默認存儲格式是, 但是格式和格式差異不大, 本文以 的行格式說明問題, 的行格式如下:
頭部有一個變長字段列表, 其中存儲的是這一行中變長字段的長度。
比如我字段之前是(255). 而每個漢字4個字節(jié)表示, 存滿后的長度是1020字節(jié), 在頭部就需要存儲一個數(shù)字1020, 所以頭部中有兩個字節(jié)是用來表示的長度的。
現(xiàn)在我把長度改成了(2048), 修改后存滿需要8192字節(jié),還是只需要兩個字節(jié)來表示這個長度mysql修改表數(shù)據(jù)類型, 因此每一行記錄的變長字段部分不需要修改。
總結(jié) mysql的的行格式中每行頭部會開辟對應(yīng)的空間來存儲變長字段長度值。如果修改變長字段的長度 導(dǎo)致行頭部已有的空間不夠表達字段長度了, 就會修改每一行的頭部在修改每一行的頭部的時候就會鎖住全表。如果修改的字段的長度, 頭部現(xiàn)有的空間依舊可以滿足變長字段長度的表示需要, 則不會修改每一行數(shù)據(jù), 就不會鎖表了。