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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock

發布時間:2024/9/27 数据库 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Mysql 插入意向鎖與自增鎖備份鎖日志鎖

插入意向鎖Insert Intention Lock

插入意向鎖Insert intention locks是記錄級別的,它通過“INSERT”關鍵詞來向其它的事務傳達插入的意向。插入意向鎖針對的是將要插入的記錄而不是已經存在的記錄。下面我們通過例子來重現這個插入意向鎖。

示意案例

--Step1 在會話1里對city表ID大于4079的記錄進行更新操作。

USE world;

START TRANSACTION;

SELECT * FROM city WHERE ID > 4079 FOR UPDATE;

--Step2 在會話2里 新起個事務并插入一條記錄。

SELECT PS_CURRENT_THREAD_ID();

/*

PS_CURRENT_THREAD_ID()

50

*/

START TRANSACTION;

INSERT INTO world.city VALUES (4080, 'Darwin', 'AUS','Northern Territory', 146000);

?--Step3 在會話3里查看插入意向鎖的信息。這里的THREAD_ID來自Step2。

mysql> SELECT * FROM performance_schema.data_locks WHERE THREAD_ID = 50 \G

*************************** 1. row ***************************

?????????????? ENGINE: INNODB

?????? ENGINE_LOCK_ID: 140113210997976:1067:140113107561216

ENGINE_TRANSACTION_ID: 38669

??????????? THREAD_ID: 50

???????????? EVENT_ID: 75

??????? OBJECT_SCHEMA: world

????????? OBJECT_NAME: city

?????? PARTITION_NAME: NULL

??? SUBPARTITION_NAME: NULL

?????????? INDEX_NAME: NULL

OBJECT_INSTANCE_BEGIN: 140113107561216

??????????? LOCK_TYPE: TABLE

??????????? LOCK_MODE: IX

????????? LOCK_STATUS: GRANTED

??????????? LOCK_DATA: NULL

*************************** 2. row ***************************

?????????????? ENGINE: INNODB

?????? ENGINE_LOCK_ID: 140113210997976:6:35:1:140113107558304

ENGINE_TRANSACTION_ID: 38669

??????????? THREAD_ID: 50

???????????? EVENT_ID: 75

??????? OBJECT_SCHEMA: world

????????? OBJECT_NAME: city

?????? PARTITION_NAME: NULL

??? SUBPARTITION_NAME: NULL

?????????? INDEX_NAME: PRIMARY

OBJECT_INSTANCE_BEGIN: 140113107558304

??????????? LOCK_TYPE: RECORD

??????????? LOCK_MODE: X,INSERT_INTENTION

????????? LOCK_STATUS: WAITING

??????????? LOCK_DATA: supremum pseudo-record

2 rows in set (0.00 sec)

這時不難發現回話2即THREAD_ID為50的事務當前的鎖模式為X,INSERT_INTENTION即排他的插入意向鎖,這里看到鎖定的數據是“supremum pseudo-record”即該表的上界偽記錄。這里“X”對應next key鎖,但這里比較特殊,因為鎖的是上界偽記錄,很顯然是鎖定不了的(上界無法定義),這里其實是個gap lock即鎖定當前表的最后記錄和上界偽記錄之間的記錄。

?

自增鎖Auto-increment Lock

自增鎖Auto-increment Locks主要應用在一個表有自增列時,確保兩個事務對表操作時有不重復的唯一的值是很有必要的。如果使用基于語句的日志記錄到二進制日志時,還有進一步的限制,因為在重放語句時,除了第一行以外的所有行都將重新創建自動遞增值。Innodb通過參數innodb_autoinc_lock_mode設置自增鎖。

0:traditonal (每次都會產生表鎖,該自增鎖是表鎖級別,且必須等待當前SQL執行完成后或者回滾掉才會釋放。)
1:consecutive (會產生一個輕量鎖,無論是單一或者批量的insert SQL,可以立即獲得該鎖,并立即釋放,能保證復制,但自增值不一定嚴格連續。)
2:interleaved (不會鎖表,來一個處理一個,并發最高,所有insert種類的SQL都可以立馬獲得鎖并釋放,無法保證復制。)

備份鎖Backup Lock

備份鎖Backup Locks是mysql8.0里新引進的實例級別的鎖,它主要是保證備份時數據庫是一致的,它在備份時主要鎖定以下語句:

CREATE TABLE、CREATE TABLESPACE、RENAME TABLE、DROP TABLE、 CREATE USER、 ALTER USER、DROP USER、GRANT等。

備份鎖可以通過如下語句產生和收回,前提是用戶擁有BACKUP_ADMIN權限:

LOCK INSTANCE FOR BACKUP

UNLOCK INSTANCE

示意案例

-- Step1 會話1里鎖定數據庫實例

LOCK INSTANCE FOR BACKUP;

-- Step2 會話2里優化world數據庫里的city表

use world

OPTIMIZE TABLE city;

-- Step3 會話3里查看鎖的相關信息(以mysql命令行方式執行)

SELECT * FROM performance_schema.metadata_locks

WHERE OBJECT_TYPE = 'BACKUP LOCK'\G

*************************** 1. row ***************************

OBJECT_TYPE: BACKUP LOCK

OBJECT_SCHEMA: NULL

OBJECT_NAME: NULL

COLUMN_NAME: NULL

OBJECT_INSTANCE_BEGIN: 4022252031312

LOCK_TYPE: SHARED

LOCK_DURATION: EXPLICIT

LOCK_STATUS: GRANTED

SOURCE: sql_backup_lock.cc:101

OWNER_THREAD_ID: 29

OWNER_EVENT_ID: 8

*************************** 2. row ***************************

OBJECT_TYPE: BACKUP LOCK

OBJECT_SCHEMA: NULL

OBJECT_NAME: NULL

COLUMN_NAME: NULL

OBJECT_INSTANCE_BEGIN: 2520403183328

LOCK_TYPE: INTENTION_EXCLUSIVE

LOCK_DURATION: TRANSACTION

LOCK_STATUS: PENDING

SOURCE: sql_base.cc:5400

OWNER_THREAD_ID: 30

OWNER_EVENT_ID: 19

2 rows in set (0.0007 sec)

-- Step4 解鎖數據庫實例

UNLOCK INSTANCE;

在如上的例子里,會話1里進程id 29擁有一個備份鎖(back lock),而會話2里有個進程是30的在等待備份鎖釋放。這里LOCK INSTANCE FOR BACKUP是個共享鎖,而DDL語句是排他的意向鎖。

日志鎖Log Lock

在創建備份時,通常需要包含與備份一致的日志位置信息,在Mysql 5.7時需要加一個全局讀鎖才能獲取到這個信息,而在Mysql 8.0里InnoDB可以通過日志鎖來讀執行的全局事務標識(global transaction identifiers)又簡稱為GTIDs,二進制日志的位置、日志序列號(log sequence number 又簡稱為LSN)),而不再是讀全局讀鎖。

日志鎖Log Lock,可以阻止修改日志相關信息的操作。

示意案例

-- 查看日志狀態。

SELECT *

FROM performance_schema.log_status\G

*************************** 1. row ***************************

SERVER_UUID: 59e3f95b-e0d6-11e8-94e8-ace2d35785be

LOCAL: {"gtid_executed": "59e3f95b-e0d6-11e8-94e8-

ace2d35785be:1-5343", "binary_log_file": "mysqlbin.

000033", "binary_log_position": 3874615}

REPLICATION: {"channels": []}

STORAGE_ENGINES: {"InnoDB": {"LSN": 7888992157, "LSN_checkpoint":

7888992157}}

總結

以上是生活随笔為你收集整理的Mysql 死锁过程及案例详解之插入意向锁与自增锁备份锁日志锁Insert Intention Lock Auto-increment Lock Backup Lock Log Lock的全部內容,希望文章能夠幫你解決所遇到的問題。

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