国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

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

2024-07-24 12:45:11
字體:
來源:轉載
供稿:網友

一個線上項目報的死鎖,簡要說明一下產生原因、處理方案和相關的一些點.

1、背景

這是一個類似數據分析的項目,數據完全通過LOAD DATA語句導入一個InnoDB表中。為方便描述,表結構簡化為如下:

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

導入數據的語句對應為

Load data infile ‘data1.csv' into table tb;Load data infile ‘data2.csv' into table tb;
cat Data1.csv1 1002 1003 100Cat data2.csv10 10011 10012 100


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

2016122171536039.png (578×246)

說明

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

2、背景知識1:AUTO_INC lock 及其選項

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

由于一個事務可能包含多個語句,而并非所有的語句都與自增字段有關,因此InnoDB作了一個特殊的處理,自增鎖在一個語句結束后馬上被釋放。之所以說是特殊處理,是因為普通的鎖,都是在事務結束后釋放。

若一個表有自增字段,一個insert語句不指定該字段的值,或指定為NULL時,InnoDB會給它賦值為當前的AUTO_INCREMENT的值,然后AUTO_INCREMENT加1。

與這個自增鎖相關的一個參數是innodb_autoinc_lock_mode. 默認值為1,可選為0,1,2。

我們先來看當這個值設置為0時,一個有自增字段的表,插入一行數據時的行為:

1) 申請AUTO_INC鎖

2) 得到當前AUTO_INCREMNT值n,給AUTO_INCREMENT 加1

3) 執行插入操作,并將n填入新增的行對應字段中

4) 釋放AUTO_INC鎖

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

沒有這個參數之前,行為就是與設置為0相同,0這個選項就是留著兼容的。

很容易想到設置為1的時候,應該是將3) 和 4)對調。但是本文還是要討論為0的情況,因為我們的前提是LOAD語句,而LOAD語句這類插入多行的語句中(包括insert …select …),即使設置為1也沒用,會退化為0的模式。

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 界首市| 海丰县| 营口市| 安庆市| 杭锦后旗| 诏安县| 虞城县| 富民县| 元氏县| 都兰县| 钦州市| 富裕县| 大名县| 衡阳县| 清徐县| 阿图什市| 郁南县| 平江县| 鲁甸县| 车险| 宝兴县| 吉安市| 闸北区| 榆树市| 巴彦县| 山阴县| 邻水| 桐城市| 米脂县| 兰溪市| 略阳县| 新巴尔虎左旗| 泌阳县| 托里县| 郓城县| 保靖县| 昌邑市| 武城县| 和龙市| 温州市| 若羌县|