全域性鎖和表鎖 給表加個字段怎麼有這麼多阻礙?

2021-10-25 02:20:26 字數 1432 閱讀 2225

根據加鎖的範圍,mysql 裡面的鎖大致可以分成全域性鎖、表級鎖和行鎖三類。

全域性鎖

官方自帶的邏輯備份工具是 mysqldump

有乙個方法能夠拿到一致性檢視。在可重複讀隔離級別下開啟乙個事務。

當 mysqldump 使用引數–single-transaction 的時候,

導資料之前就會啟動乙個事務,來確保拿到一致性檢視。而由於 mvcc 的支援,這個過程中資料是可以正常更新的。

既然要全庫唯讀,為什麼不使用 set global readonly=true 的方式呢?

表級鎖

表鎖lock tables … read/write

如果在某個執行緒 a 中執行 lock tables t1 read, t2 write。這個語句,則其他執行緒寫 t1、讀寫 t2 的語句

都會被阻塞。同時,執行緒 a 在執行 unlock tables 之前,也只能執行讀 t1、讀寫 t2 的操作。連寫 t1 都不

允許,自然也不能訪問其他表。

另一類表級的鎖是 mdl(metadata lock)。

在 mysql 5.5 版本中引入了 mdl,當對乙個表做增刪改查操作的時候,加 mdl 讀鎖;當要對錶做結構變更操作的時候,加 mdl 寫鎖。

接下來是乙個示例環境

1、session a 先啟動,這時候會對錶 t 加乙個 mdl 讀鎖。

2、由於 session b 需要的也是 mdl 讀鎖,因此可以正常執行。

3、之後 session c 會被 blocked,是因為 session a 的 mdl 讀鎖還沒有釋放,而 session c 需要 mdl

寫鎖,因此只能被阻塞。

4、如果只有 session c 自己被阻塞還沒什麼關係,但是之後所有要在表 t 上新申請 mdl 讀鎖的請求也會被

session c 阻塞。前面我們說了,所有對錶的增刪改查操作都需要先申請 mdl 讀鎖,就都被鎖住,等於這個表現

在完全不可讀寫了。

5、如果某個表上的查詢語句頻繁,而且客戶端有重試機制,也就是說超時後會再起乙個新 session 再請求的話,

這個庫的執行緒很快就會爆滿。

如何安全地給小表加字段?

如果你要變更的表是乙個熱點表,雖然資料量不大,但是上面的請求很頻繁,而你不得不加個字段,你該怎麼做呢?

在 alter table 語句裡面設定等待時間,如果在這個指定的等待時間裡面能夠拿到 mdl 寫鎖最好,

拿不到也不要阻塞後面的業務語句,先放棄。之後開發人員或者 dba 再通過重試命令重複這個過程。

全域性鎖和表鎖 給表加個字段怎麼有這麼多阻礙?

不論是我們平時接觸到的synchronized還是reentrantlock等等鎖,都是為了解決業務中併發的問題,而資料庫中也是如此,mysql裡面的鎖大致分為三種,全域性鎖,表級鎖和行鎖三類。今天這篇文章,將會和你分享全域性鎖和表級鎖。鎖的設計是很複雜的,專欄會主要圍繞碰到鎖的現象和其背後的原理。...

表鎖和全域性鎖

目錄 鎖的作用 處理併發問題 鎖的分類 全域性鎖表級鎖 行鎖 命令 flush tables with read lock ftwrl 這個庫處理唯讀狀態 全庫邏輯備份問題 1 主庫備份,業務停擺 2 從庫備份,不能執行binlog,導致主從延遲 在不支援事物的引擎下可以使用 有事務機制的備份 my...

全域性鎖 表鎖和行鎖

全域性鎖就是對整個資料庫例項加鎖,mysql提供了乙個加全域性讀鎖的方法,命令是flush tables with read lock。讓你需要讓整個庫處於唯讀狀態的時候,可以使用這個命令,之後其他執行緒的以下語句會被阻塞 a 資料更新語句 b 資料定義語句 c 更新類事務的提交語句 mysql裡面...