MySQL鎖表的相關知識

今天在解決數據庫同步異常的時候用到了flush tables with read lock 這個命令,於是順便就學習了下鎖表的相關知識。

 

1.FLUSH TABLES WITH READ LOCK

 

這個命令是全局讀鎖定,執行了命令之後所有庫所有表都被鎖定只讀。一般都是用在數據庫聯機備份,這個時候數據庫的寫操作將被阻塞,讀操作順利進行。

 

解鎖的語句也是unlock tables。

 

2.LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}

 

這個命令是表級別的鎖定,可以定製鎖定某一個表。例如: lock  tables test read; 不影響其他表的寫操作。

解鎖語句也是unlock tables。

等待鎖

在flush tables with read lock成功獲得鎖之前,必須等待所有語句執行完成(包括SELECT)。所以如果有個慢查詢在執行,或者一個打開的事務,或者其他進程拿着表鎖,flush tables with read lock就會被阻塞,直到所有的鎖被釋放。

刷新表

當flush tables with read lock拿到鎖後,必定flush data。對於MyISAM引擎,不光是刷新它自己的data,也刷新操作系統的data到disk上

flush tables with read lock,也就是將所有的髒頁都要刷新到磁盤,然後對所有的表加上了讀鎖,於是這時候直接拷貝數據文件也就是安全的。但是如果你發出命令flush tables with read lock時,還有其他的操作,而起是很耗時的操作呢?先說寫操作,這個FTWRL肯定是得等的,等寫操作完成才能執行FTWRL,這個很好理解。那麼對於其他的讀操作呢?比如說在FLWRL發出之前有一個query:select count(*) from tb,那麼FTWRL也得等待(show processlist可以看到 waiting for table flush)。你可能會說在mysql中讀與讀不是不會排斥的嗎,爲什麼需要等待呢?因爲FTWRL是要flush髒頁的,只有這樣才真的能保證數據一致性(比如說在xtrabackup備份myisam表的時候),而在select count(*) from tb執行的時候,因爲所有的操作都是在內存中操作,所以此時還不能完全flush,因此FTWRL就得等待。或許你還會有疑問,select的頁不是髒頁,爲什麼FTWRL還要等待呢?難道mysql不能做得更完善點嗎?我覺得mysql還不是不會做的這麼簡單吧,等待的原因是因爲這個表很大,無法一次性將所有的頁都讀到內存中來,而query具有原子性,總不可能執行一般被堵塞吧,所以說還是得乖乖的讓它執行然,所以FTWRL就得等待了。

這兩個語句在執行的時候都需要注意個特點,就是 隱式提交的語句。在退出MySQL終端的時候都會隱式的執行unlock tables。也就是如果要讓表鎖定生效就必須一直保持對話。

FLUSH TABLES WITH READ LOCK 和 LOCK TABLES比較

1、FLUSH TABLES WITH READ LOCK

這個命令是全局讀鎖定,執行了命令之後所有庫所有表都被鎖定只讀。一般都是用在數據庫聯機備份,這個時候數據庫的寫操作將被阻塞,讀操作順利進行。解鎖的語句也是unlock tables。

2、LOCK TABLES tbl_name [AS alias] {READ [LOCAL] | [LOW_PRIORITY] WRITE}

這個命令是表級別的鎖定,可以定製鎖定某一個表。例如: lock  tables test read; 不影響其他表的寫操作。解鎖語句也是unlock tables。

這兩個語句在執行的時候都需要注意個特點,就是 隱式提交的語句。在退出mysql終端的時候都會隱式的執行unlock tables。也就是如果要讓表鎖定生效就必須一直保持對話。

3、MYSQL的read lock和wirte lock

read-lock:  允許其他併發的讀請求,但阻塞寫請求,即可以同時讀,但不允許任何寫。也叫共享鎖

write-lock: 不允許其他併發的讀和寫請求,是排他的(exclusive)。也叫獨佔鎖


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章