国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫 - Mysql - MySQL中由load data語句引起死鎖的解決案例

MySQL中由load data語句引起死鎖的解決案例

2020-05-31 15:36CrazyJinn Mysql

這篇文章主要介紹了MySQL中由load data語句引起死鎖的解決案例,文中講到了InnoDB引擎的數(shù)據(jù)表中一些鎖的機(jī)制,需要的朋友可以參考下

一個(gè)線上項(xiàng)目報(bào)的死鎖,簡要說明一下產(chǎn)生原因、處理方案和相關(guān)的一些點(diǎn).

1、背景

這是一個(gè)類似數(shù)據(jù)分析的項(xiàng)目,數(shù)據(jù)完全通過LOAD DATA語句導(dǎo)入一個(gè)InnoDB表中。為方便描述,表結(jié)構(gòu)簡化為如下:

?
1
Create table tb(id int primary key auto_increment, c int not null) engine=innodb;

導(dǎo)入數(shù)據(jù)的語句對(duì)應(yīng)為

?
1
2
3
Load data infile ‘data1.csv' into table tb;
 
Load data infile ‘data2.csv' into table tb;
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
cat Data1.csv
 
1 100
 
2 100
 
3 100
 
 
Cat data2.csv
 
10 100
 
11 100
 
12 100

 

產(chǎn)生死鎖的證據(jù)是在show engine innodb status的LATEST DETECTED DEADLOCK段中看到死鎖信息,簡化為如下:

MySQL中由load data語句引起死鎖的解決案例

說明

從上面表格中看出,事務(wù)1在等待某一行的鎖。而事務(wù)2持有這行的鎖,但等待表的自增鎖(AUTO_INC),判斷為死鎖,事務(wù)回滾。
這里事務(wù)1沒有寫出來,但是可以推斷,事務(wù)1持有這個(gè)表的自增鎖(否則就不是死鎖了)。

2、背景知識(shí)1:AUTO_INC lock 及其選項(xiàng)

在InnoDB表中,若存在自增字段,則會(huì)維護(hù)一個(gè)表級(jí)別的鎖,這里稱為自增鎖。每次插入新數(shù)據(jù),或者update語句修改了此字段,都會(huì)需要獲取這個(gè)鎖

由于一個(gè)事務(wù)可能包含多個(gè)語句,而并非所有的語句都與自增字段有關(guān),因此InnoDB作了一個(gè)特殊的處理,自增鎖在一個(gè)語句結(jié)束后馬上被釋放。之所以說是特殊處理,是因?yàn)槠胀ǖ逆i,都是在事務(wù)結(jié)束后釋放。

若一個(gè)表有自增字段,一個(gè)insert語句不指定該字段的值,或指定為NULL時(shí),InnoDB會(huì)給它賦值為當(dāng)前的AUTO_INCREMENT的值,然后AUTO_INCREMENT加1。

與這個(gè)自增鎖相關(guān)的一個(gè)參數(shù)是innodb_autoinc_lock_mode. 默認(rèn)值為1,可選為0,1,2。

我們先來看當(dāng)這個(gè)值設(shè)置為0時(shí),一個(gè)有自增字段的表,插入一行數(shù)據(jù)時(shí)的行為:

1) 申請AUTO_INC鎖

2) 得到當(dāng)前AUTO_INCREMNT值n,給AUTO_INCREMENT 加1

3) 執(zhí)行插入操作,并將n填入新增的行對(duì)應(yīng)字段中

4) 釋放AUTO_INC鎖

我們看到這個(gè)過程中,雖然InnoDB為了減少鎖粒度,在語句執(zhí)行完成就馬上釋放,但這鎖還是太大了――它包括了插入操作的時(shí)間。這就導(dǎo)致了兩個(gè)insert語句,實(shí)際上沒辦法并行。

沒有這個(gè)參數(shù)之前,行為就是與設(shè)置為0相同,0這個(gè)選項(xiàng)就是留著兼容的。

很容易想到設(shè)置為1的時(shí)候,應(yīng)該是將3) 和 4)對(duì)調(diào)。但是本文還是要討論為0的情況,因?yàn)槲覀兊那疤崾荓OAD語句,而LOAD語句這類插入多行的語句中(包括insert …select …),即使設(shè)置為1也沒用,會(huì)退化為0的模式。

3、背景知識(shí)2:LOAD DATA語句的主從行為

為什么插入多行的語句要即使將innodb_autoinc_lock_mode設(shè)置為1,也會(huì)用0的模式呢?

主要原因還是為了主從一致性。設(shè)想binlog_format='statement',一個(gè)LOAD DATA語句在主庫的binlog直接記錄為語句本身,那從庫如何重放:

1) 將load data用到的文件發(fā)給slave,slave將文件保存在臨時(shí)目錄。

2) 在slave也執(zhí)行一次LOAD DATA語句。

其間有一個(gè)問題:slave怎么保證load data語句的自增id字段與master相同?

為了解決這個(gè)問題,主庫的binlog中還有一個(gè)set SET INSERT_ID命令,表明這個(gè)LOAD DATA語句插入的第一行的自增ID值。這樣slave在執(zhí)行l(wèi)oad data之前,先執(zhí)行了這個(gè)set SET INSERT_ID語句,用于保證執(zhí)行結(jié)果與主庫一模一樣。

上述的機(jī)制能保證主從數(shù)據(jù)一致的前提是:主從庫上LOAD DATA語句生成的自增ID值必須是連續(xù)的。

4、背景知識(shí)1+2:分析

回到前面說的模式0和1的區(qū)別,我們看到,如果AUTO_INC鎖在整個(gè)語句開始之前就獲取,在語句結(jié)束之后才釋放,這樣就能保證整個(gè)語句生成的id連續(xù)――模式0的保證。

對(duì)于1,每次拿到下一個(gè)值就釋放,插入數(shù)據(jù)后,若需要再申請,則不連續(xù)。

這就是為什么,即使設(shè)置為1,對(duì)于多行操作,會(huì)退化成0。

至此我們知道這個(gè)死鎖出現(xiàn)的原因,是這兩個(gè)LOAD DATA語句不僅會(huì)訪問相同的記錄,還會(huì)訪問同一個(gè)AUTO_INC鎖,造成互相等待。

到此沒完,因?yàn)槲覀冎离m然兩個(gè)線程訪問兩個(gè)鎖可能造成死鎖,但是死鎖還有另外一個(gè)條件,與申請順序有關(guān)。既然AUTO_INC是一個(gè)表鎖,不論誰先拿到,會(huì)阻塞其他同表的LOAD DATA的執(zhí)行,又為什么會(huì)在某個(gè)記錄上出現(xiàn)鎖等待?

5、背景知識(shí)3:AUTO_INC的加鎖時(shí)機(jī)

前面我們說到每次涉及到插入新數(shù)據(jù),就會(huì)要求對(duì)AUTO_INC加鎖,并列出了流程。但這個(gè)流程是對(duì)于需要從InnoDB中得到自增值來設(shè)置列值的情況。另一種情況是在語句中已經(jīng)指定了該列的值。

比如對(duì)于這個(gè)表,執(zhí)行 insert into tb values(9,100). 此時(shí)id的值已經(jīng)明確是9,雖然不需要取值來填,但是插入這行后有可能需要改變AUTO_INCREMENT的值(若原來是<10,則應(yīng)該改為10),所以這個(gè)鎖還是省不了。流程變成:

1) 插入數(shù)據(jù)

2) 若失敗則流程結(jié)束

3) 若成功,申請AUTO_INC鎖

4) 調(diào)用set_max….函數(shù),如有必要?jiǎng)t修改AUTO_INCREMENT

5) 語句結(jié)束時(shí)釋放AUTO_INC鎖。

6、為什么修改AUTO_INC順序

 

這么調(diào)整的好處是什么? 主要是為了減少不必要的鎖訪問。若在插入數(shù)據(jù)期間發(fā)生錯(cuò)誤,比如其他字段造成DUPLICATE KEY error,這樣就不用訪問AUTO_INC鎖。

7、死鎖過程復(fù)現(xiàn)

必須強(qiáng)調(diào)是“語句結(jié)束時(shí)”。這樣我們來看一個(gè)每行都已經(jīng)指定了自增列值的LOAD DATA語句的流程(也就是本文例子的情況):

1) 插入第一條數(shù)據(jù)

2) 申請AUTO_INC鎖

3) 插入第二條

4) 申請AUTO_INC 鎖(因?yàn)橐呀?jīng)是自己的,直接成功)

5) 。。。。。。插入剩余所有行

6) 釋放AUTO_INC鎖。

所以這個(gè)流程就簡單描述為:插入第一行,申請AUTO_INC鎖,然后插入剩下的所有行后再釋放。

我們前面提到過,插入第一條數(shù)據(jù)時(shí)可能需要訪問的記錄鎖,是要等到整個(gè)事務(wù)結(jié)束后才釋放的.

有了上面的這些背景知識(shí),我們來復(fù)現(xiàn)一下死鎖出現(xiàn)的過程

MySQL中由load data語句引起死鎖的解決案例

可以看到觸發(fā)條件還是比較苛刻的,尤其是session2要?jiǎng)偤靡玫絪ession1鎖住的那個(gè)記錄鎖。需要說明,由于InnoDB內(nèi)部對(duì)記錄的表示,同一個(gè)記錄鎖并不表示主鍵值一定相同。

8、解決方案1:去掉不必要的AUTO_INCREMENT字段

在這個(gè)業(yè)務(wù)中,由于所有的數(shù)據(jù)都是通過LOAD DATA進(jìn)去,而且都已經(jīng)指定了自增字段的值,因此這個(gè)AUTO)INCREMENT屬性是不需要的。

少了一個(gè),就死鎖不了了。

9、解決方案2:強(qiáng)制模式1

前面我們說到innodb_autoinc_lock_mode這個(gè)參數(shù)的可選值有0、1、2。當(dāng)設(shè)置為1的時(shí)候,在LOAD DATA語句會(huì)退化為模式0。但若設(shè)置為2,則無論如何都會(huì)使用模式1。

我們前面說到使用模式1會(huì)導(dǎo)致LOAD DATA生成的自增id值不連續(xù),這樣會(huì)導(dǎo)致在binlog_format是1時(shí)主從不一致,因此設(shè)置為2的前提,是binlog_format 是row.

在binlog_format='row'時(shí),設(shè)置innodb_autoinc_lock_mode為2是安全的。

若允許,方案2比方案1更輕量些,不需要修改數(shù)據(jù)和表結(jié)構(gòu)。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 黄色电影免费在线观看 | 国产精品污www一区二区三区 | 成人欧美一区二区三区在线观看 | 欧美黄色一级片免费看 | 久久亚洲视频 | av在线天堂网 | 另类视频网站 | 日韩中文字幕在线免费观看 | 日韩性精品 | 91免费观看视频 | 亚洲怡红院在线观看 | 日韩中文字幕av | 成人久久久 | 国产成人一区二区在线观看 | 久久成人精品 | 日韩精品在线视频 | 欧美一区二区三区在线观看 | 欧美日韩一区二区三区免费视频 | 91超碰在线观看 | 激情五月激情综合网 | 1000部精品久久久久久久久 | 成人爱情偷拍视频在线观看 | 国产黄色在线播放 | 澳门av | 免费激情网站 | 国产成人a亚洲精品 | 欧美一区二区三区视频 | 亚洲激情 欧美 | 久久精品 | 久久久国产精品 | 亚洲一区二区三区在线播放 | 国产精一区 | 久久机热 | 国产精品一区二区三区免费 | 精品国产一区二区三区小蝌蚪 | 在线视频亚洲 | 日韩色网 | 亚洲天堂一区在线 | 日韩精品无码一区二区三区 | 一区二区三区在线播放 | 一区二区三区在线观看视频 |