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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2 s锁是什么_innodb存储引擎读书笔记:锁

發布時間:2025/10/17 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2 s锁是什么_innodb存储引擎读书笔记:锁 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

myisam引擎的鎖是表鎖,在并發插入時性能較差。

innodb實現了兩種行級鎖:

  • 共享鎖(S lock)

  • 排他鎖(X lock)

  • 當一個事務獲取了行r的共享鎖是,其他的事務也可以獲取行r的共享鎖,如果其他事務想獲取行r的排他鎖,必須等待共享鎖釋放。

    innodb允許行級鎖和表級鎖同時存在。

    innodb實現了意向鎖,意向鎖是表級鎖。意向鎖有兩種:

  • 意向共享鎖(IS lock):表示事務想獲取表中某幾行的共享鎖

  • 意向排他鎖(IX lock):表示事務想獲取表中某幾行的排他鎖

  • 意向鎖不會阻塞除全表掃描之外的任何請求。

    information_schema.INNODB_TRX表的字段有:

  • trx_id:innodb引擎內部唯一的事務id

  • trx_state:事務的當前狀態

  • trx_started:事務的開始時間

  • trx_request_lock_id:如果trx_state為LOCK WAIT,則此字段的值表示事務等待的鎖的id;如果trx_state不為LOCK WAIT,則此字段為null

  • trx_wait_started:事務開始等待的時間點

  • trx_weight:事務的權重,反映了一個事務修改和鎖住的行數。當發生死鎖需要回滾的時候,innodb會選擇權重最小的事務進行回滾。

  • trx_mysql_thread_id:事務對應的線程的id

  • trx_query:事務中的sql

  • information_schema.innodb_locks表的字段有:

  • lock_id:鎖的id

  • lock_trx_id:獲取了鎖的事務的id

  • lock_mode:鎖的模式

  • lock_type:鎖的類型,表鎖還是行鎖

  • lock_table:對哪個表加了鎖

  • lock_index:對哪個索引加了鎖

  • lock_space:表空間的id

  • lock_page:被鎖住的頁的數量,lock_type為表鎖時該字段為null

  • lock_rec:被鎖住的行的數量,lock_type為表鎖時該字段為null

  • lock_data:被鎖住的行的主鍵,lock_type為表鎖時該字段為null

  • information_schema.innodb_lock_waits的字段有:

  • requesting_trx_id:申請鎖的事務的id

  • requesting_lock_id:申請的鎖的id

  • blocking_trx_id:哪個事務阻塞了requesting_trx_id

  • blocking_lock_id:哪個鎖阻塞了requesting_lock_id

  • 示例如下(為什么blocking_lock_id和requested_lock_id不是同一個鎖?導致當前事務阻塞的鎖竟然不是當前事務正在請求的鎖?確實不一樣,事務730FEE對行記錄加了X鎖,而事務7311F4要對該行記錄加S鎖。):

    一致性的非鎖定讀:innodb通過多版本控制讀取當前時刻數據庫中的行記錄。如果讀取的行記錄正在被delete、update,讀取操作不等待行上鎖的釋放,而會去讀取該行的一個快照。這個快照實際上是undo段。一致性的非鎖定讀是innodb默認的讀取方式。

    多版本并發控制MVCC:multi version concurrency controll。

    多版本指的是快照有多個版本。

    在repeatable read(innodb默認的事務隔離級別)和read committed下,innodb使用一致性非鎖定讀,但是對快照的定義不同。

    read committed下,一致性非鎖定讀總是讀取最新的快照。

    repeatable read下,一致性非鎖定讀總是讀取事務開始時的行數據版本。

    (突然想到的一個疑問:事務內的每一次對行記錄的操作,是否會操作完就釋放鎖?還是說會等到事務提交之后一起釋放?

    驗證:

    先在事務A中獲取行記錄上的S鎖:

    再在事務B中獲取該行記錄上的X鎖:

    可以看到事務B阻塞了。查看INNODB_TRX表也可以看到如下信息:

    因此說明了事務中獲取的S鎖要等到事務結束后再釋放,X鎖也是如此。這個特性與事務的隔離級別無關。

    )

    查看事務隔離級別:

    select @@tx_isolation;

    設置事務隔離級別:

    set [global | session] transaction isolation level Read uncommitted | Read committed | Repeatable Read | Serializable;

    如果選擇global,則隔離級別將應用于之后新建的session,而當前已經存在的session(包括當前session)不受影響。

    如果選擇session,則隔離級別將應用于當前session內之后的所有事務,其他已經存在的session和之后新創建的session均不受影響。

    如果事務隔離級別為repeatable read,則session A中的三次讀都會讀到id=1的記錄。如果事務隔離級別為read committed,則session A中的前兩次讀都會讀到id=1的記錄,但是第三次讀會返回空集。(已驗證)

    innodb中select操作默認使用一致性非鎖定讀。

    如果到對select操作加鎖:

    ??? select ... for update:對讀取的行記錄加X鎖,其他事務如果要在該行上加任何鎖都會被阻塞。

    ??? select ... in share mode:對讀取的行記錄加S鎖,其他事務可以對該行加S鎖,但是要加X鎖就會被阻塞。

    注意:

    1. select操作加鎖后,其他事務仍然可以執行一致性非鎖定讀select操作。

    2. 事務提交后select上的鎖才會被釋放。默認情況下,執行一條語句就是一次事務,所以select ... for update和select ... in share mode執行完后鎖就被釋放。

    AUTO-INC Locking:在執行插入操作時,自增長列(一般就是指主鍵)的值由自增長計數器確定。從自增長計數器中取值時,需要先上鎖。

    這種鎖是表級鎖,但是卻不會在事務完成之后才釋放,而是在完成插入操作后立即釋放。

    參數innodb_autoinc_lock_mode:

    取0時表示上文所提的加鎖方式;

    取1(默認值)時表示在進行simple inserts(插入前就能確定插入的行數)時采用互斥量對計數器進行累加,在進行bulk inserts(插入前不能確定插入的行數)時采用上文提到的加鎖方式。

    取2時表示對于所有的insert操作都采用互斥量。

    innodb中,如果一個表中定義了自增長列,則該列上必須建索引,如果聯合索引中包含該列,則該列必須是第一列。

    innodb中,外鍵列會自動被加上一個索引,避免表鎖。

    插入或更新外鍵列時,首先會select父表,為保證數據一致,會使用select ... lock in share mode,而不是一致性非鎖定讀。

    innodb中行鎖分類:

  • record lock:行記錄上的鎖

  • gap lock:間隙鎖,鎖定一個范圍,但不包含記錄本身

  • next-key lock:等價于record lock + gap lock。

  • innodb中,默認的事務隔離級別是repeatable read。這種隔離級別下,next-key lock是默認的行記錄鎖定算法。

    repeatable read隔離級別下,先在事務A中執行select * from t where a < 6 lock in share mode,再在事務B中執行insert into t select 5或insert into t select 6,事務B會阻塞住。如果在事務B中執行insert into t select 9,則會直接執行成功。事務A中的select會被加上next-key share lock。

    repeatable read隔離級別下,先在事務A中執行select * from t where a = 7 lock in share mode,再在事務B中執行insert into t select 5或insert into t select 6,則會直接執行成功。事務A中的select會被加上record share lock。

    lost update:

    場景(時間線順序):

  • 事務1查詢一行記錄

  • 事務2也查詢該行記錄

  • 事務1更新該行記錄

  • 事務2更新該行記錄

  • 結果是事務1的更新被覆蓋了。

    如何避免?

    事務在查詢時就加上排他鎖。

    臟數據:已被修改但還未被提交的數據。

    臟讀:一個事務讀到另一個事務中的臟數據。

    隔離級別為read uncommitted時就會出現臟讀。

    不可重復讀:同一個事務內,多次讀同一行記錄,讀到的數據不同。原因是,在該事務內的兩次select操作之間,其他事務修改了該行記錄,并提交了。

    隔離級別為read committed時會出現不可重復讀。

    事務之間可能會因鎖的問題產生阻塞。

    innodb_lock_wait_timeout:超時時間,可以在運行時修改。默認是50s。

    innodb_rollback_on_timeout:超時是是否對事務進行回滾,不可在運行時修改。默認是OFF。

    mysql中,事務中拋出異常時,mysql一般不會對事務進行回滾,而是等待用戶決定是要提交還是回滾。但是發生死鎖時,innodb會自動對其中一個事務進行回滾。

    總結

    以上是生活随笔為你收集整理的2 s锁是什么_innodb存储引擎读书笔记:锁的全部內容,希望文章能夠幫你解決所遇到的問題。

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