1. 程式人生 > >Mysql中load data infile主從複製注意點

Mysql中load data infile主從複製注意點

在mysql官方文件的描述裡,load data infile載入資料要比普通的insert快20倍,可以說是插入資料最快的方式了,所以在很多場合都會用它來提升入庫速度。

那它在主從架構中的從庫上會怎麼執行呢?(主從複製官網)剛開始我假定是在master上load成功後會以batch insert方式dump進binlog,從庫IO執行緒請求binlog,最後SQL執行緒以batch insert執行一遍,同樣能做到主從同步。但即使是batch insert方式,按照官方文件的解釋,也是會比load data infile慢的。在master端load壓力足夠大的情況下,主從延遲可能會無法忍受。帶著這樣的疑問,我準備做個測試

準備一個數據的檔案(2M)為了防止load過快而無法在從庫上觀察到,設定迴圈load 30次,然後在從庫端show processlist觀察執行情況,結果如下截圖:

通過測試可以發現

 load data infile在master端執行成功後會把資料檔案寫入到binlog裡(可用mysqlbinlog分析),在從庫IO執行緒獲取binlog寫到本地relay-log,SQL執行緒會將資料檔案extract到臨時目錄(預設/tmp,見tmp.io.dir變數值),再執行load命令將資料檔案載入進從庫(在從庫show processlist可以觀察到此現象),最終把資料臨時目錄的檔案刪除掉。

這樣保證slave與master執行相同,同時也保證了入庫速度,主從延遲不會那麼明顯(但也不一定,見後文)

上文已經提到master執行load成功後會將資料檔案寫入binlog,那問題又來了,如果這個檔案足夠大(比如 :50G 囧),主從同步效率會如何呢,我們可以想象,至少會有兩個問題:
1,主從延遲
我們將這個階段劃分成以下幾個步驟便於理解:
master端: load 50G into table ,dump into binlog
slave端: get binlog & write into relay log; extract relay log and write data into tmpdir; load into table&delete file
假定在master端執行要2小時,那麼從庫至少要延遲2小時(why? 除了主從都執行load外,計算一下資料檔案被寫入傳輸了多少次)

2,主從資料不一致
由於同步耗時長,發生異常的可能性也跟著變大,最大而且最有可能發生的問題 臨時目錄空間不足,導致資料寫入臨時目錄失敗而無法load,主從一致性就被打破了。

以上兩個問題對於主從複製來說是非常要命的,但是有問題總會有解決辦法的
solution A: 當然要避免以上的問題可以將大檔案 split成小檔案load入庫(如果不要求在一個事務裡的話)。
solution B: 如果要求在一個事務裡,那就主從都手動的執行load,顯示的指定master不寫binlog,取消check外來鍵。個人覺得這是最可取也最高效的方式(即使不要求在一個事務也可用這個方法),因為可以並行load,解決了延遲大的問題,另外減少了資料寫入次數,可以手動指定資料儲存目錄,也就降低了執行時發生異常的機率,從而保證主從資料一致性。

Java
1 2 3 至於如何操作可用這條命令: time mysql-e"set foreign_key_checks=0; set sql_log_bin=0; set unique_checks=0; load data local infile 'infile.txt' into table load_test fields terminated by '\t' lines terminated by '\n' (col1, col2);" 注意:time命令是用於統計執行時間的

對於普通檔案load到一半發生異常(雖然在 Mysql Load Data容錯性測試 能智慧的相容各種異常資料,但不能排除有其他異常),導致後半資料不能成功寫入,在這種情況下,主庫是不會將載入成功的資料檔案dump到binlog的,這樣主從資料的一致性又被打破了,所以考慮用load的時候需要注意這一點。

參考: