MySQL/MariaDB數據庫的併發控制mysql
做者:尹正傑 sql
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。數據庫
一.併發控制概述緩存
1>.什麼是併發控制安全
MySQL是一個服務器級別的數據庫,它一般放在網絡上有不少用戶併發訪問的,所以併發控制很關鍵。
2>.鎖粒度服務器
表級鎖(MyISAM和Innodb都支持)
行級鎖(僅Innodb支持,MyISAM不支持)
3>.鎖網絡
讀鎖:
共享鎖,只讀不可寫(包括當前事務) ,多個讀互不阻塞
寫鎖:
獨佔鎖,排它鎖,寫鎖會阻塞其它事務(不包括當前事務)的讀和它鎖
4>.實現session
存儲引擎:
自行實現其鎖策略和鎖粒度
服務器級:實現了鎖,表級鎖,用戶可顯式請求
5>.分類併發
隱式鎖:
由存儲引擎自動施加鎖
顯式鎖:
用戶手動請求
6>.鎖策略ide
在鎖粒度及數據安全性尋求的平衡機制
7>.死鎖
兩個或多個事務在同一資源相互佔用,並請求鎖定對方佔用的資源的狀態
二.針對表級別顯式使用鎖實戰案例
1>.查看鎖幫助信息
MariaDB [yinzhengjie]> HELP LOCK Name: 'LOCK' Description: Syntax: LOCK TABLES tbl_name [[AS] alias] lock_type [, tbl_name [[AS] alias] lock_type] ... lock_type: READ [LOCAL] | [LOW_PRIORITY] WRITE UNLOCK TABLES MySQL enables client sessions to acquire table locks explicitly for the purpose of cooperating with other sessions for access to tables, or to prevent other sessions from modifying tables during periods when a session requires exclusive access to them. A session can acquire or release locks only for itself. One session cannot acquire locks for another session or release locks held by another session. Locks may be used to emulate transactions or to get more speed when updating tables. This is explained in more detail later in this section. LOCK TABLES explicitly acquires table locks for the current client session. Table locks can be acquired for base tables or views. You must have the LOCK TABLES privilege, and the SELECT privilege for each object to be locked. For view locking, LOCK TABLES adds all base tables used in the view to the set of tables to be locked and locks them automatically. If you lock a table explicitly with LOCK TABLES, any tables used in triggers are also locked implicitly, as described in https://mariadb.com/kb/en/triggers-and-implicit-locks/. UNLOCK TABLES explicitly releases any table locks held by the current session. LOCK TABLES implicitly releases any table locks held by the current session before acquiring new locks. Another use for UNLOCK TABLES is to release the global read lock acquired with the FLUSH TABLES WITH READ LOCK statement, which enables you to lock all tables in all databases. See [HELP FLUSH]. (This is a very convenient way to get backups if you have a file system such as Veritas that can take snapshots in time.) URL: https://mariadb.com/kb/en/transactions-lock/ MariaDB [yinzhengjie]>
2>.添加讀鎖
MariaDB [yinzhengjie]> LOCK TABLES students READ; #添加讀鎖後,可讀不可寫 Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 100 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UPDATE students SET Age = 120 WHERE Name = '齊天大聖孫悟空'; ERROR 1099 (HY000): Table 'students' was locked with a READ lock and can't be updated MariaDB [yinzhengjie]> MariaDB [yinzhengjie]>
3>.解鎖
MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 100 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UPDATE students SET Age = 120 WHERE Name = '齊天大聖孫悟空'; ERROR 1099 (HY000): Table 'students' was locked with a READ lock and can't be updated MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UNLOCK TABLES; #對錶進行解鎖 Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UPDATE students SET Age = 120 WHERE Name = '齊天大聖孫悟空'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 120 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) MariaDB [yinzhengjie]>
4>.添加寫鎖
MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 120 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> LOCK TABLES students WRITE; #添加寫鎖後,當前終端可讀可寫,其它終端既不可讀也不可寫 Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UPDATE students SET Age = 125 WHERE Name = '齊天大聖孫悟空'; Query OK, 1 row affected (0.00 sec) Rows matched: 1 Changed: 1 Warnings: 0 MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 125 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ 25 rows in set (0.00 sec) MariaDB [yinzhengjie]>
三.針對數據庫級別顯式使用鎖實戰案例
1>.添加讀鎖(注意:對數據庫級別並無寫鎖)
MariaDB [yinzhengjie]> FLUSH TABLES WITH READ LOCK; #爲數據庫實例添加讀鎖,能夠對數據庫進行讀取操做,沒法對全部數據庫進行寫入操做,通常用做數據庫溫備,並不適合數據庫冷備和熱備。 Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> CREATE TABLE students_backup SELECT * FROM students; #不可對當前數據庫進行寫入操做 ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> GRANT ALL ON yinzhengjie.* to jason@'172.30.1.%' IDENTIFIED BY 'yinzhengjie'; #很顯然其它數據庫也不能寫入數據了,包括mysql系統數據庫 ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> SELECT * FROM students; +-------+-----------------------+-----+--------+---------+-----------+ | StuID | Name | Age | Gender | ClassID | TeacherID | +-------+-----------------------+-----+--------+---------+-----------+ | 1 | Shi Zhongyu | 22 | M | 2 | 3 | | 2 | Shi Potian | 22 | M | 1 | 7 | | 3 | Xie Yanke | 53 | M | 2 | 16 | | 4 | Ding Dian | 32 | M | 4 | 4 | | 5 | Yu Yutong | 26 | M | 3 | 1 | | 6 | Shi Qing | 46 | M | 5 | NULL | | 7 | Xi Ren | 19 | F | 3 | NULL | | 8 | Lin Daiyu | 17 | F | 7 | NULL | | 9 | Ren Yingying | 20 | F | 6 | NULL | | 10 | Yue Lingshan | 19 | F | 3 | NULL | | 11 | Yuan Chengzhi | 23 | M | 6 | NULL | | 12 | Wen Qingqing | 19 | F | 1 | NULL | | 13 | Tian Boguang | 33 | M | 2 | NULL | | 14 | Lu Wushuang | 17 | F | 3 | NULL | | 15 | Duan Yu | 19 | M | 4 | NULL | | 16 | Xu Zhu | 21 | M | 1 | NULL | | 17 | Lin Chong | 25 | M | 4 | NULL | | 18 | Hua Rong | 23 | M | 7 | NULL | | 19 | Xue Baochai | 18 | F | 6 | NULL | | 20 | Diao Chan | 19 | F | 7 | NULL | | 21 | Huang Yueying | 22 | F | 6 | NULL | | 22 | Xiao Qiao | 20 | F | 1 | NULL | | 23 | Ma Chao | 23 | M | 4 | NULL | | 24 | Xu Xian | 27 | M | NULL | NULL | | 25 | 齊天大聖孫悟空 | 120 | M | NULL | NULL | +-------+-----------------------+-----+--------+---------+-----------+ rows in set (0.00 sec) MariaDB [yinzhengjie]>
2>.解鎖
MariaDB [yinzhengjie]> FLUSH TABLES WITH READ LOCK; Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> CREATE TABLE students_backup SELECT * FROM students; ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> UNLOCK TABLES; Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]> MariaDB [yinzhengjie]> CREATE TABLE students_backup SELECT * FROM students; Query OK, 25 rows affected (0.01 sec) Records: 25 Duplicates: 0 Warnings: 0 MariaDB [yinzhengjie]>
3>.關閉正在打開的表(清除查詢緩存)
MariaDB [yinzhengjie]> FLUSH TABLES ; Query OK, 0 rows affected (0.00 sec) MariaDB [yinzhengjie]>
四.查詢時加寫或讀鎖
SELECT clause [FOR UPDATE | LOCK IN SHARE MODE] #這種方式使用相對較少,感興趣的小夥伴可自行查閱資料