成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MySQL鎖機制 你所不了解的一些事兒

數據庫 MySQL
本教程將為大家介紹的MySQL鎖方面的問題,包括并發和隔離控制機制,表的生命周期,元數據鎖等問題。

1.MySQL中并發和隔離控制機制

Meta-data元數據鎖:在table cache緩存里實現的,為DDL(Data Definition Language)提供隔離操作。一種特別的meta-data元數據類型,叫Name Lock。(SQL層)

表級table-level數據鎖(SQL層)

存儲引擎特有機制 -- row locks行鎖,page locks頁鎖,table locks表級,versioning版本(在引擎中實現)

全局讀鎖 -- FLUSH TABLES WITH READ LOCK(SQL層)

2.在語句執行中表的生命周期

 DML(Data Manipulation Language)例子:

計算語句使用到的所有表

在每個表:打開open表 -- 從table cache緩存里得到TABLE對象,并在此表加上meta-data元數據鎖

等待全局讀鎖后改變數據

在每個表:鎖lock表 -- 在表加上table-level數據鎖

執行語句:調用:handler::write_row()/read_rnd()/read_index(),等;隱式地調用引擎級engine-level鎖機制

在每個表:釋放表的數據鎖

在每個表:釋放表的DDL鎖并把表放回table cache緩存里

 DDL語句也是一樣,沒有典型的執行計劃。

 3.獲取meta-data元數據鎖

meta-data元數據鎖的實現作為TABLE對象的一個屬性,TABLE對象代表了table cache緩存。

meta-data元數據鎖為如下任何一種:shared共享鎖 -- 隱式地加鎖,只通過標記TABLE對象“被使用”;semi-exclusive半獨享鎖,也叫Name Lock,RENAME操作會在源表和目標加上此鎖;exclusive獨享,也叫exclusive name lock,CREATE TABLE ... SELECT操作會在目標表上加上此鎖,如果沒有的話。

 4.表高速緩存(table cache)

是一個HASH變量,叫open_cache

TABLE對象是HASH元素

以HASH的操作被LOCK_open mutex互斥量保護

內部結構(The table cache: internal structure)

在緩存里,每個物理表可能被多個TABLE實例表示

相同表的所有TABLE實例,通過相連的列(a linked list)連接著

每個TABLE實例有一個table cache緩存版本的復制 -- TABLE實例保存的版本不會和當前table cache緩存版本一致,而是保存舊的和從緩存刪除的

被某些語句使用的TABLE實例被會標記為對其它的語句來說是無效的 -- 這就是meta-data元數據鎖的本質

在緩存中的TABLE實例通常地有一個有效的句柄實例連接著它

內部運算(The table cache: operations)

主要的代碼在:sql/sql_base.cc,sql/lock.cc,sql/table.h,sql/sql_table.cc

主要的方法:open_table(),close_thread_tables(),close_cached_table(),lock_table_names()

事實上,一個概念/對象組合不僅用于緩存或鎖定:LOCK_open mutex互斥量也用到其它的操作,如:使磁盤上和處理中的表創建的原子性

典型的操作,來自隔離等級Pov的重要(注:isolation PoV沒研究出是什么意思):語句查詢時,打開和關閉表 -- shared共享鎖;強制和等待直到表的所有實例被關閉 --  exclusive獨享(但不完全);Name Lock -- 特殊地情況,當手上沒有TABLE實例,只能使用一個特殊的占位符(甚至表可能不存在)。

鎖多表(The table cache: locking multiple tables)

使用一種嘗試和回退(try and back-off)的技術來避免死鎖(樂觀鎖)

為了DDL操作的一套訣竅,如使鎖升級或者防止DDL失效

 LOCK_open問題

 Lock_open互斥量:

保護table cache緩存內的結構

分組存儲引擎內的表和對象的.frm文件的創建,也為RENAME操作提供原子性操作

在每個語句訪問表時會使用它兩次:在open_tables()和close_thread_tables()

在使用DDL操作時,磁盤讀寫和甚至同步(sync)都會使用它

5.ALTER TABLE例子

ALTER TABLE執行的簡化計劃:

以TL_WRITE_ALLOW_READ的打開和加鎖表

創建一個以臨時名字的被ALTER的復制表

強制并等待直到表的所有實例都關閉(鎖升級)

交換新和舊的版本

刪除舊的版本

 這是一個常規的情況,還有一些被優化的情況。

 ALTER TABLE執行的調試:

  1. T@8: | query: alter table t1 add column k int  
  2. T@8: | >mysql_parse  
  3. T@8: | | >mysql_execute_command  
  4. T@8: | | | >mysql_alter_table  
  5. T@8: | | | | >open_ltable  
  6. T@8: | | | | | >open_table  
  7. T@8: | | | | | <open_table 
  8. T@8: | | | | | >mysql_lock_tables  
  9. T@8: | | | | | | >get_lock_data  
  10. T@8: | | | | | | | >ha_innobase::store_lock  
  11. T@8: | | | | | | | <ha_innobase::store_lock 
  12. T@8: | | | | | | <get_lock_data 
  13. T@8: | | | | | | >lock_external  
  14. T@8: | | | | | | | >ha_innobase::external_lock  
  15. T@8: | | | | | | | | enter: lock_type: 1  
  16. T@8: | | | | | | | | >trans_register_ha  
  17. T@8: | | | | | | | | | enter: stmt  
  18. T@8: | | | | | | | | <trans_register_ha 
  19. T@8: | | | | | | | <ha_innobase::external_lock 
  20. T@8: | | | | | | <lock_external 
  21. T@8: | | | | | | >thr_multi_lock  
  22. T@8: | | | | | | | >thr_lock  
  23. T@8: | | | | | | | <thr_lock 
  24. T@8: | | | | | | <thr_multi_lock 
  25. T@8: | | | | | <mysql_lock_tables 
  26. T@8: | | | | <open_ltable 
  27. T@8: | | | | >mysql_create_table  
  28. T@8: | | | | <mysql_create_table 
  29. T@8: | | | | >open_temporary_table  
  30. T@8: | | | | | >openfrm  
  31. T@8: | | | | | | >handler::ha_open  
  32. T@8: | | | | | | | enter: name: ./test/#sql-3081_1 db_type: 12 db_stat: 7 mode: 2 lock_test: 2  
  33. T@8: | | | | | | | >ha_innobase::open  
  34. T@8: | | | | | | | <ha_innobase::open 
  35. T@8: | | | | | | <handler::ha_open 
  36. T@8: | | | | | <openfrm 
  37. T@8: | | | | <open_temporary_table 
  38. T@8: | | | | >copy_data_between_tables  
  39. T@8: | | | | <copy_data_between_tables 
  40. T@8: | | | | >closefrm  
  41. T@8: | | | | <closefrm 
  42. T@8: | | | | >close_cached_table  
  43. T@8: | | | | | enter: table: t1  
  44. T@8: | | | | | >wait_while_table_is_used  
  45. T@8: | | | | | | >get_lock_data  
  46. T@8: | | | | | | <get_lock_data 
  47. T@8: | | | | | | >thr_abort_locks  
  48. T@8: | | | | | | <thr_abort_locks 
  49. T@8: | | | | | | >remove_table_from_cache  
  50. T@8: | | | | | | | enter: Table: 'test.t1' flags: 2  
  51. T@8: | | | | | | <remove_table_from_cache 
  52. T@8: | | | | | <wait_while_table_is_used 
  53. T@8: | | | | | >mysql_unlock_tables  
  54. T@8: | | | | | | >thr_multi_unlock  
  55. T@8: | | | | | | | lock: data: 0x8b7f9b0 count: 1  
  56. T@8: | | | | | | | >thr_unlock  
  57. T@8: | | | | | | | <thr_unlock 
  58. T@8: | | | | | | <thr_multi_unlock 
  59. T@8: | | | | | | >unlock_external  
  60. T@8: | | | | | | | >ha_innobase::external_lock  
  61. T@8: | | | | | | | <ha_innobase::external_lock 
  62. T@8: | | | | | | <unlock_external 
  63. T@8: | | | | | <mysql_unlock_tables 
  64. T@8: | | | | | >unlink_open_table  
  65. T@8: | | | | | | >hash_delete  
  66. T@8: | | | | | | | >free_cache_entry  
  67. T@8: | | | | | | | | >closefrm  
  68. T@8: | | | | | | | | | >ha_innobase::close  
  69. T@8: | | | | | | | | | <ha_innobase::close 
  70. T@8: | | | | | | | | <closefrm 
  71. T@8: | | | | | | | <free_cache_entry 
  72. T@8: | | | | | | <hash_delete 
  73. T@8: | | | | | <unlink_open_table 
  74. T@8: | | | | <close_cached_table 
  75. T@8: | | | | >mysql_rename_table  
  76. T@8: | | | | | >ha_innobase::rename_table  
  77. T@8: | | | | | <ha_innobase::rename_table 
  78. T@8: | | | | <mysql_rename_table 
  79. T@8: | | | | >mysql_rename_table  
  80. T@8: | | | | | >ha_innobase::rename_table  
  81. T@8: | | | | | <ha_innobase::rename_table 
  82. T@8: | | | | <mysql_rename_table 
  83. T@8: | | | | >my_delete  
  84. T@8: | | | | | my: name ./test/#sql2-3081-1.frm MyFlags 0  
  85. T@8: | | | | <my_delete 
  86. T@8: | | | | >ha_delete_table  
  87. T@8: | | | | | >ha_innobase::delete_table  
  88. T@8: | | | | | <ha_innobase::delete_table 
  89. T@8: | | | | <ha_delete_table 
  90. T@8: | | | | >ha_commit_trans 
  91. T@8: | | | | <ha_commit_trans 
  92. T@8: | | | | >ha_commit_trans 
  93. T@8: | | | | <ha_commit_trans 
  94. T@8: | | | <mysql_alter_table 
  95. T@8: | | <mysql_execute_command 
  96. T@8: | <mysql_parse 
  97. T@8: <dispatch_command 

 6.RENAME TABLE例子

得到源表和目的表的name-lock鎖:在table cache緩存內插入特殊的TABLE實例的占位符并等待直到這些表的所有實例都關閉

重命名這些表的.frm文件和調用handler::rename_table()方法

刪除name-lock鎖

 在整個解析過程中,都使用LOCK_open

  1. T@10: | query: rename table t1 to t2  
  2. T@10: | >mysql_parse  
  3. T@10: | | >mysql_execute_command  
  4. T@10: | | | >mysql_rename_tables  
  5. T@10: | | | | >lock_table_names  
  6. T@10: | | | | | >lock_table_name  
  7. T@10: | | | | | | enter: db: test name: t1  
  8. T@10: | | | | | <lock_table_name 
  9. T@10: | | | | | >remove_table_from_cache  
  10. T@10: | | | | | | enter: Table: 'test.t1' flags: 0  
  11. T@10: | | | | | | >hash_delete  
  12. T@10: | | | | | | | >free_cache_entry  
  13. T@10: | | | | | | | | >closefrm  
  14. T@10: | | | | | | | | | >ha_innobase::close  
  15. T@10: | | | | | | | | | <ha_innobase::close 
  16. T@10: | | | | | | | | <closefrm 
  17. T@10: | | | | | | | <free_cache_entry 
  18. T@10: | | | | | | <hash_delete 
  19. T@10: | | | | | <remove_table_from_cache 
  20. T@10: | | | | | >lock_table_name  
  21. T@10: | | | | | | enter: db: test name: t2  
  22. T@10: | | | | | <lock_table_name 
  23. T@10: | | | | | >remove_table_from_cache  
  24. T@10: | | | | | | enter: Table: 'test.t2' flags: 0  
  25. T@10: | | | | | <remove_table_from_cache 
  26. T@10: | | | | <lock_table_names 
  27. T@10: | | | | >rename_tables  
  28. T@10: | | | | | >do_rename  
  29. T@10: | | | | | | >mysql_rename_table  
  30. T@10: | | | | | | | >ha_innobase::rename_table  
  31. T@10: | | | | | | | <ha_innobase::rename_table 
  32. T@10: | | | | | | | >my_rename  
  33. T@10: | | | | | | | | my: from ./test/t1.frm to ./test/t2.frm MyFlags 16  
  34. T@10: | | | | | | | <my_rename 
  35. T@10: | | | | | | <mysql_rename_table 
  36. T@10: | | | | | <do_rename 
  37. T@10: | | | | <rename_tables 
  38. T@10: | | | | >unlock_table_names  
  39. T@10: | | | | | >unlock_table_name  
  40. T@10: | | | | | | >hash_delete  
  41. T@10: | | | | | | | >free_cache_entry  
  42. T@10: | | | | | | | <free_cache_entry 
  43. T@10: | | | | | | <hash_delete 
  44. T@10: | | | | | <unlock_table_name 
  45. T@10: | | | | | >unlock_table_name  
  46. T@10: | | | | | | >hash_delete  
  47. T@10: | | | | | | | >free_cache_entry  
  48. T@10: | | | | | | | <free_cache_entry 
  49. T@10: | | | | | | <hash_delete 
  50. T@10: | | | | | <unlock_table_name 
  51. T@10: | | | | <unlock_table_names 
  52. T@10: | | | <mysql_rename_tables 
  53. T@10: | | <mysql_execute_command 
  54. T@10: | <mysql_parse 

7.表級table-level鎖

主要源代碼見:sql/lock.cc,mysys/thr_lock.cc。mysql_lock/unlock_tables()(SQL層操作)和thr_multi_lock()/thr_lock()(鎖兼容邏輯lock-compatibility logic)

表是以打開著被加鎖的。被加鎖的對象被句柄關聯著;存儲引擎會調整鎖的類型。如innodb/bdb,事實上大量的對象被加鎖的,如merge/partition,見handler::store_lock()方法。

使用鎖等級避免死鎖。所有表一次性加鎖;如果存儲引擎調整鎖造成死鎖,由存儲引擎負責

在一些情況下,表會更早地被解鎖

8 .預加鎖(pre-locking)

歷史上避免死鎖方案用于表級table-level數據鎖,是要求一次性加鎖一個語句內的所有表

因此,對語句使用的函數/觸發,我們不得不打開所有直接地或間接地用到的表,且對它們加鎖。為這個,我們建立一個被使用表的可傳送閉包

為了有效實現,我們混合層次和訪問(layers and access)成某些解析/語句上下文(parser/statement context),這些上下文來自主要處理表的模板

9.全局讀鎖(global read lock)

實現為FLUSH TABLES WITH READ LOCK,用來備份

從執行上防止DDL和DML

勸告:每個DDL/DML語句檢查是否有一個正掛著的全局讀鎖和停止是否有任何一個。通過直接調用wait_if_global_read_lock()(在這個情況我們會設置來自全局讀鎖的保護,且只有調用start_waiting_global_read_lock()來消除這個保護,通常在這情況下沒有打開的表);或者通過mysql_lock_tables()(在后一種情況下,我們還重新打開表)

線程操作FLUSH TABLES WITH READ LOCK來設置一個全局讀鎖的標識,初始一個FLUSH TABLES語句。然后等待直到所有的表都清空(flush)

原文標題:MySQL 鎖機制概述

鏈接:http://www.cnblogs.com/popgo/archive/2010/07/26/1778803.html

【編輯推薦】

  1. MySQL數據庫鎖機制的原理淺析
  2. MySQL鎖定機制的原理
  3. 使用調度和鎖定進行MySQL查詢優化
  4. MySQL數據庫表里如何進行鎖定?
  5. MySQL表級鎖,行級鎖,頁級鎖各顯神通
責任編輯:彭凡 來源: 博客園
相關推薦

2019-11-21 15:08:13

DevOps云計算管理

2017-04-11 09:29:45

WOT

2013-11-11 10:07:43

靜態路由配置

2018-07-16 09:00:32

LinuxBash數組

2017-03-13 17:25:00

移動支付技術支撐易寶

2012-03-13 09:32:15

C#協變

2011-03-29 15:44:41

對日軟件外包

2021-07-12 07:01:39

AST前端abstract sy

2019-04-03 09:10:35

Rediskey-value數據庫

2010-08-19 10:12:34

路由器標準

2015-06-05 09:52:41

公有云風險成本

2014-07-29 16:21:57

Git

2017-12-26 11:37:32

云原生CNCF容器

2021-01-14 08:31:54

Web開發應用程序

2012-02-21 09:20:50

Hadoop大數據

2020-12-10 08:13:15

ARM架構 嵌入式

2021-03-09 10:05:06

5G運營商技術

2015-10-23 15:22:16

AsyncTask基礎Android

2014-05-06 10:31:21

KillallLinux命令行

2019-05-14 14:51:40

Java語法糖用法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品一区av | 国产精品久久久亚洲 | 一区二区三区亚洲视频 | 精品国产一区二区三区久久久蜜月 | 精品九九久久 | 男人天堂免费在线 | 国产一级免费在线观看 | 岛国毛片在线观看 | 久久精品国产一区老色匹 | 日韩欧美国产精品综合嫩v 一区中文字幕 | 国产一区二区在线播放 | 超碰97免费在线 | 在线欧美 | 国产日韩欧美电影 | 九九综合| 欧美精品一区在线发布 | 欧美视频二区 | 黄色大片在线播放 | 成人在线视频网 | 在线国产99 | 9久9久| 中文久久 | 成人久久久 | 日p视频免费看 | 精品亚洲一区二区三区 | 精品视频一区二区三区 | 狠狠爱网址 | 亚洲欧美日韩系列 | 亚洲国产成人精品女人久久久 | 国产精品一区二区三区在线 | 欧美一级欧美三级在线观看 | 免费的黄色片子 | 成人av观看| 日韩精品一二三 | 欧美不卡视频一区发布 | 国产精品视频一区二区三区 | 国产精品欧美一区二区三区不卡 | 日韩有码一区 | 日本精品在线播放 | 久久久青草婷婷精品综合日韩 | 欧美精品99 |