今天一位同學問到線上曾經碰到過連續建表,導致阻塞普通的
insert
、update
等。不過也沒有保留現場。因此有疑問為什麼建表會影響
dml?
分析
首先這個現象不是在所有場景都會碰到(否則
mysql
的使用者們早就跳起來了)。
一來建表這個操作本身很快,只涉及到寫表定義檔案和初始化表空間。中間涉及到
redo
和undo
的操作也很少(這裡只討論
innodb
表)。因此除非碰到磁碟
io響應不了,否則多數情況下建表操作很快結束,不會「穩定復現」
二來即使由於
io原因,建表過程執行時間較長,建表操作也不會阻塞一些
dml操作。
因此只能從**出發看衝突的
case。
假設session 1
正在執行乙個
create table
操作,且由於
io原因阻塞在寫表空間檔案這個步驟上。討論
session2
作如下操作的場景。
無主鍵表
insert
此時
insert
操作由於需要申請系統自增主鍵,需要對
dict_sys->mutex
加鎖。而這個鎖需要等
session1
建表操作完成後才釋放,因此出現等待。
有外來鍵表的操作
此時
session2
需要判斷外來鍵一致性,需要對
dict_sys->mutex
加鎖。
這裡包含幾個方面:外來鍵約束的
child
表插入資料時和
parent
表刪除資料時,已經這兩個表的關聯外來鍵字段被修改時,均會觸發等待。
有同學會說我們線上這兩種情況都禁止了,是不是就不會因為這個鎖的原因導致阻塞
dml?
新開啟表時
若這個
insert
操作需要新開啟乙個表時,需要根據表名從字典中取出資訊,也會觸發等待。
即使原來已經開啟過的表,也會因為執行了
flush table
或者表空間淘汰而要求下次訪問需要重新開啟。
影響的其他操作
順著
dict_sys->mutex
我們還可以發現有以下幾個操作,若發生在
session2
,都會被阻塞
1) 1) flush tables
2)select * from information_schema.tables;
2)以上兩個因為都要訪問到表物件列表,還比較好理解
3)select * from information_schema.innodb_sys_tables;
3)實際上可以用另外乙個鎖來單獨處理
sys_tables
4)show create table another_table
這個是因為必須判斷是否有外來鍵關聯
簡單留個問題:為什麼
show tables
並不會被阻塞?
關於MySQL建表對DML的影響
今天一位同學問到線上曾經碰到過連續建表,導致阻塞普通的insert update等。不過也沒有保留現場。因此有疑問為什麼建表會影響dml?分析 首先這個現象不是在所有場景都會碰到 否則mysql的使用者們早就跳起來了 一來建表這個操作本身很快,只涉及到寫表定義檔案和初始化表空間。中間涉及到redo和...
建表mysql語句嗎 關於MySQL語句建表的總結
在寫 之前,需要注意的乙個問題是,使用命令列模式寫 mysql 語句,如果涉及到中文,最好利用 mysql charset gbk 命令將客戶端字符集設定為 gbk,這樣能保證正確插入和讀 取中文資料庫端字符集可以是 gb2312,gbk,utf8 等支援中文的字符集 如果是利用 mysql 提供的...
mysql 建表原則 MySql基本的建表原則
1.定長和變長的分離 如int,char,time所佔位元組是固定的字段放在一張表 如varchar,text所佔位元組不確定的字段放在一張表中 2.常用字段和不常用字段進行分離,根據查詢頻率來設計 3.一對多的關聯表可以新增冗餘字段,如商品分類表 和商品表 在首頁中需要顯示每個分類商品總數.解決方...