您好,登錄后才能下訂單哦!
本篇文章為大家展示了mysql load 相關實驗過程是怎樣的,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
一:load 的過程相當于是:先start transaction,然后再insert數據,最后commit
我猜測mysql 區別于oracle sqlldr,沒有后者的rows的參數來控制每次提交的數據行
但是我感覺 mysql 是自己通過估算出一個值,來批量讀取 ,我覺得他不是 一條一條的 insert的
二:load 如果數據存在(主鍵或者唯一鍵),默認是跳過的,可以選擇replace存在就替換!
三:load 沒有類似于oracle的 sqlldr的rows參數來控制每次提交的行數,只能先通過linux命令來
切分(split)成小文件來實現并行;
實驗一:load會不會鎖表
session1
[root@beijing-fuli-hadoop-04 ~]# cat /data/t.txt
100, liu ,18
102, liu ,18
101, liu, 18
root@localhost : (none) 11:50:05>start transaction;
Query OK, 0 rows affected (0.00 sec)
root@localhost : (none) 11:51:08>LOAD DATA LOCAL INFILE '/data/t.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
Query OK, 3 rows affected (0.03 sec)
Records: 3 Deleted: 0 Skipped: 0 Warnings: 0
然后不commit!
session2
如下全部等待
root@localhost : liuwenhe 11:52:36>delete from t where id=101;
root@localhost : liuwenhe 11:52:36>delete from t where id=102;
root@localhost : liuwenhe 11:52:36>delete from t where id=103;
如下 不等待
delete from t where id=104
delete from t where id=100
結論:
load 在提交之前,會鎖定所有剛load的數據!!!也間接的說明這是一個事務把三個數據
都load進去了,會不會是 mysql 默認把N行數據作為一個事務呢?采用大數據量來做驗證
實驗二:load是不是一個事務
1.文件/data/12.txt是26135101行數據的文件
2.然后開始load
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/12.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
3.另開一個會話,查詢數據,發現再load完成之前一直是空,
root@localhost : liuwenhe 13:55:15>select count(*) from t;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.66 sec)
這就進一步說明 load操作是一個事務的!!!
實驗三:是否允許在同一個表上同時進行load? 只要沒有沖突是可以并行的!
這里所說的沖突是指: 已經load 處理了的數據中和另一個會話要處理的數據有沖突,具體實驗如下:
假如1.txt 文件 是id從1到2147483647這個范圍的數據,而2.txt是id=2147483647的
一條數據,而3.txt是id從1到3的范圍并且還有id=2147483646這條數據
具體如下:
[root@beijing-fuli-hadoop-04 liuwenhe]# cat 2.txt
26293013,liu ,18
[root@beijing-fuli-hadoop-04 liuwenhe]# cat 3.txt
1, liu ,18
26293013,liu ,18
具體實驗過程:
實驗1)
會話1:
執行這個,因為數據量比較大,所以會執行一會
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
會話2:
[root@beijing-fuli-hadoop-04 liuwenhe]# cat 2.txt
26293013,liu ,18
然后會話1還沒有結束呢,執行如下操作,發現沒有等待!確實進去了,
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/2.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
root@localhost : liuwenhe 17:33:18>select * from t where id =26293013;
+----------+-------+------+
| id | name | num |
+----------+-------+------+
| 26293013 | liu | 18 |
+----------+-------+------+
1 row in set (0.12 sec)
說明:load順序執行,當執行到的id=1的數據到達innodb層,mysql就會把id=1的數據上鎖gap鎖,
這時候你再load=1的數據就會有鎖等待,但是你沒有執行到id=26293013的數據,也就沒有給這條數據上鎖,所以你并行執行另一個load (id=26293013)的數據就不會等待。
實驗2)
會話1:
執行這個,因為數據量比較大,所以會執行一會
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
會話2:
在會話1還沒有結束的時候,執行如下發現等待,因為id=1的數據被會話1鎖定,所以下面的操作是需要等待的,因為load 3.txt是先處理id=1的數據,但是它已經被鎖定了,
[root@beijing-fuli-hadoop-04 liuwenhe]# cat 3.txt
1, liu ,18
26293013,liu ,18
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/3.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
實驗3)load 產生死鎖:
會話1:
執行這個,因為數據量比較大,所以會執行一會;
root@localhost : liuwenhe 13:54:50>LOAD DATA LOCAL INFILE '/data/liuwenhe/1.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
會話2:
在會話1還沒有結束的時候,執行如下發現等待,因為id=1的數據被會話1鎖定,但是id=26293013的數據沒有被鎖定呢,所以說load 4.txt的時候,能把第一條數據(id=26293013)load進innodb引擎層并且鎖定,但是1這條數據卻被鎖定,進而會話1和會話2產生鎖等待!
[root@beijing-fuli-hadoop-04 liuwenhe]# cat 4.txt
26293013,liu ,18
1, liu ,18
root@localhost : (none) 18:13:10>LOAD DATA LOCAL INFILE '/data/liuwenhe/4.txt' INTO TABLE liuwenhe.t fields terminated by ',' LINES TERMINATED BY '\n' ;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
注釋:為什么會選擇回滾會話2的事務?因為我開啟了死鎖檢測,然后數據庫選擇插入更新或者刪除的行數最少的事務回滾
MySQL 如何處理死鎖?
MySQL有兩種死鎖處理方式:
等待,直到超時(innodb_lock_wait_timeout=50s)。
發起死鎖檢測,主動回滾一條事務,讓其他事務繼續執行(innodb_deadlock_detect=on)。
由于性能原因,一般都是使用死鎖檢測來進行處理死鎖。
死鎖檢測
死鎖檢測的原理是構建一個以事務為頂點、鎖為邊的有向圖,判斷有向圖是否存在環,存在即有死鎖。
回滾
檢測到死鎖之后,選擇插入更新或者刪除的行數最少的事務回滾,基于 INFORMATION_SCHEMA.INNODB_TRX 表中的 trx_weight 字段來判斷。
上述內容就是mysql load 相關實驗過程是怎樣的,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。