日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

lock mysql unlock_MySQL中的lock tables和unlock tables

發布時間:2023/12/2 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 lock mysql unlock_MySQL中的lock tables和unlock tables 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

MySQL允許客戶端會話顯式地獲取表鎖,以便與其他會話協作訪問表,或者防止其他會話在其需要獨占表時使用表。這個能力就是通過LOCK TABLES和UNLOCK TABLES實現的。

LOCK TABLES用于顯示的獲取表鎖,UNLOCK TABLES顯式釋放當前會話持有的任何表鎖。

MySQL 5.7版本中它們的完整語法是:

LOCK TABLES

tbl_name [[AS] alias] lock_type

[, tbl_name [[AS] alias] lock_type] …

lock_type: {

READ [LOCAL]

| [LOW_PRIORITY] WRITE

}

UNLOCK TABLES

LOCK TABLES可以為基表或視圖獲取表鎖。必須具有要鎖定的每個對象的“LOCK TABLES”權限和“SELECT”權限。

不同的鎖類型有不同的效果。

READ [LOCAL]鎖:

持有鎖的會話可以讀取表(但不能寫入表)。

多個會話可以同時獲取表的read鎖。

其它會話可以在不顯式獲取讀鎖的情況下讀取表。

加上LOCAL關鍵字,表示在持有鎖的同時允許其它會話執行非沖突插入語句(并發插入)。但是,如果要在持有鎖的同時使用外部進程操作數據庫,則不能使用READ LOCAL。對于InnoDB表,READ LOCAL與READ相同。

會話1登入,并修改提示符包含session1字樣,然后對emp表讀取,可以進行,然后用lock tables給emp表加read鎖定。

root@database-one 13:57: [(none)]> prompt \u@database-one \R:\m:\s [\d] session1>

PROMPT set to '\u@database-one \R:\m:\s [\d] session1>'

root@database-one 13:57:55 [(none)] session1>use gftest;

Database changed

root@database-one 13:58:31 [gftest] session1>select * from emp;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

+--------+------+---------+------------+--------+

5 rows in set (0.00 sec)

root@database-one 14:03:18 [gftest] session1>lock tables emp read;

Query OK, 0 rows affected (0.00 sec)

root@database-one 14:03:20 [gftest] session1>insert into emp values('陳實',31,9000,'2019-07-01',10);

ERROR 1099 (HY000): Table 'emp' was locked with a READ lock and can't be updated

可以看到,read鎖定時只能讀取,無法修改數據。

會話2登入,并修改提示符包含session2字樣,然后對emp表讀取。

root@database-one 14:04: [(none)]> prompt \u@database-one \R:\m:\s [\d] session2>

PROMPT set to '\u@database-one \R:\m:\s [\d] session2>'

root@database-one 14:05:04 [(none)] session2>use gftest;

Database changed

root@database-one 14:05:10 [gftest] session2>select * from emp;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

+--------+------+---------+------------+--------+

5 rows in set (0.00 sec)

root@database-one 14:05:20 [gftest] session2>lock tables emp read;

Query OK, 0 rows affected (0.00 sec)

可以看到,繼續能夠讀取,同時也能加read鎖。

[LOW_PRIORITY] WRITE鎖:

持有鎖的會話可以讀寫表。

只有持有鎖的會話才能訪問表。在釋放鎖之前,其他會話無法訪問它。

當保持WRITE鎖時,其他會話對表的鎖請求被阻塞。

LOW_PRIORITY關鍵字已經作廢。在以前的MySQL版本中,它影響鎖定行為,但現在已經不是這樣了?,F在不推薦使用它,它的使用會產生一個警告。

會話1登入,并修改提示符包含session1字樣,然后對emp表寫入,可以進行,然后用lock tables給emp表加write鎖定。

root@database-one 21:32: [(none)]> prompt \u@database-one \R:\m:\s [\d] session1>

PROMPT set to '\u@database-one \R:\m:\s [\d] session1>'

root@database-one 21:32:57 [(none)] session1>use gftest;

Database changed

root@database-one 21:33:07 [gftest] session1>select * from emp;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

+--------+------+---------+------------+--------+

5 rows in set (0.00 sec)

root@database-one 21:33:20 [gftest] session1>insert into emp values('陳實',31,9000,'2019-07-01',10);

Query OK, 1 row affected (0.01 sec)

root@database-one 21:34:50 [gftest] session1>lock tables emp write;

Query OK, 0 rows affected (0.00 sec)

會話2登入,并修改提示符包含session2字樣,然后對emp表進行查詢。

root@database-one 21:38: [(none)]> prompt \u@database-one \R:\m:\s [\d] session2>

PROMPT set to '\u@database-one \R:\m:\s [\d] session2>'

root@database-one 21:38:13 [(none)] session2>use gftest;

Database changed

root@database-one 21:38:21 [gftest] session2>select * from emp;

可以看到,表被以write方式鎖定后,其它會話讀取都無法進行,更不用提寫入了。

UNLOCK TABLES顯式釋放當前會話持有的任何表鎖。我們去session1中釋放鎖。

root@database-one 21:36:20 [gftest] session1>

root@database-one 21:45:29 [gftest] session1>unlock tables;

Query OK, 0 rows affected (0.00 sec)

root@database-one 21:45:43 [gftest] session1>

root@database-one 21:38:21 [gftest] session2>select * from emp;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

| 陳實 | 31 | 9000.00 | 2019-07-01 | 10 |

+--------+------+---------+------------+--------+

6 rows in set (7 min 11.08 sec)

root@database-one 21:45:43 [gftest] session2>

可以看到,session1在21:45:29后釋放了鎖,session2在21:45:43前就立即讀取出了emp表的數據,整整排隊等待了7分多鐘,這些時間都被計入了這個SELECT的執行時間。

如果語句通過表名鎖定,則不能使用別名。

root@database-one 21:57:54 [gftest] session1>lock table emp read;

Query OK, 0 rows affected (0.01 sec)

root@database-one 21:58:02 [gftest] session1>select * from emp as e;

ERROR 1100 (HY000): Table 'e' was not locked with LOCK TABLES

root@database-one 21:58:06 [gftest] session1>select * from emp;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

| 陳實 | 31 | 9000.00 | 2019-07-01 | 10 |

+--------+------+---------+------------+--------+

6 rows in set (0.00 sec)

如果使用別名鎖定,則必須在語句中使用別名引用該表:

root@database-one 22:00:54 [gftest] session1>unlock tables;

Query OK, 0 rows affected (0.00 sec)

root@database-one 22:01:23 [gftest] session1>

root@database-one 22:01:25 [gftest] session1>lock table emp as e read;

Query OK, 0 rows affected (0.00 sec)

root@database-one 22:01:30 [gftest] session1>select * from emp;

ERROR 1100 (HY000): Table 'emp' was not locked with LOCK TABLES

root@database-one 22:01:34 [gftest] session1>select * from emp as e;

+--------+------+---------+------------+--------+

| ename | age | sal | hiredate | deptno |

+--------+------+---------+------------+--------+

| 郭軍 | 27 | 8400.00 | 2019-12-08 | 10 |

| 劉杰 | 30 | 9100.00 | 2018-04-09 | 10 |

| 王艷 | 24 | 6000.00 | 2020-01-05 | 20 |

| 馬麗 | 26 | 7200.00 | 2018-07-06 | 30 |

| 肖偉 | 29 | 8700.00 | 2017-05-28 | 30 |

| 陳實 | 31 | 9000.00 | 2019-07-01 | 10 |

+--------+------+---------+------------+--------+

6 rows in set (0.00 sec)

會話可以顯式釋放其鎖,或者在某些條件下隱式釋放鎖。

會話可以使用UNLOCK TABLES顯式釋放其鎖。

如果會話已經持有鎖,還發出LOCK TABLES語句來獲取新鎖,那么在授予新鎖之前,現有鎖將被隱式釋放。

如果會話開始事務(例如,使用START transaction),則隱式執行UNLOCK TABLES,從而釋放現有鎖。

無論客戶端會話的連接正常結束或異常終止,服務器均隱式釋放該會話持有的所有表鎖(事務性和非事務性)。

LOCK TABLES和UNLOCK TABLES與事務的交互如下:

LOCK TABLES不是事務安全的,在嘗試鎖定表之前隱式提交任何活動事務。

UNLOCK TABLES隱式提交任何活動事務,前提是LOCK TABLES已用于獲取表鎖。例如,在以下語句集中,UNLOCK TABLES釋放全局讀取鎖,但不提交事務,因為沒有有效的表鎖:

FLUSH TABLES WITH READ LOCK;

START TRANSACTION;

SELECT ... ;

UNLOCK TABLES;

開始事務(例如,使用START transaction)隱式提交任何當前事務并釋放現有表鎖。

對事務表(如InnoDB TABLES)使用LOCK TABLES和UNLOCK TABLES的正確方法是,以SET autocommit=0(不是START transaction)后跟LOCK TABLES開始事務,并且在顯式提交事務之前不調用UNLOCK TABLES。例如,如果需要寫入表t1并讀取表t2,可以執行以下操作:

SET autocommit=0;

LOCK TABLES t1 WRITE, t2 READ, ...;

... do something with tables t1 and t2 here ...

COMMIT;

UNLOCK TABLES;

ROLLBACK不會釋放表鎖。

綜上所述,當我們需要獨占式的對表做一些運維操作時,使用LOCK TABLES和UNLOCK TABLES是個很不錯的選擇。

總結

以上是生活随笔為你收集整理的lock mysql unlock_MySQL中的lock tables和unlock tables的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。