載入數據卡在空狀態 MySQL
由於列現在不再對其列標題具有正確的引用/含義,我一直試圖將一個表移動到另一個表。為此,我創建了一個新表,其列數與原始表相同,只是更改了列名以更好地反映傳入的數據。
我的問題是,數據超過 5000 萬行,所以我無法簡單地更改現有的列,所以我創建了一個新表,無論如何我都希望使用它。我已經進行了必要的列更改,但是現在當我嘗試載入數據時,看起來這個過程很簡單。
+—–+——+———–+——+———+——+——-+———————————-
--------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+------+-----------+------+---------+------+-------+------------------------------------------------------------------------------------------------------+ | 481 | root | localhost | database | Query | 8617 | NULL | LOAD DATA LOCAL INFILE '/home/SQLBackUps/file.csv' INTO TABLE `tablename` FIELDS | | 483 | root | localhost | database | Sleep | 7174 | | NULL | | 485 | root | localhost | database | Query | 0 | NULL | show processlist | +-----+------+-----------+------+---------+------+-------+------------------------------------------------------------------------------------------------------+
我使用帶有必要標誌的 mysqlimport 進行了演講,因此理論上它至少應該正在執行,但是由於狀態顯示為 null,我不確定它的真正含義為 NULL,根據文件,僅出現在 show processlist . 該文件的權限如下:
-rw-rw-rw- 1 mysql mysql 14141022004 May 15 16:42 file.csv
該文件是使用 SELECT INTO OUTFILE … 創建的
我能做些什麼來加快這個過程嗎?現在它在一個非常有限的開發機器上,有 2GB 的 RAM 和一個好的處理器,所以我知道這需要一些時間,但考慮到它已經超過 2 小時而且它仍然處於空狀態,我想知道是否出了點問題,或者我可以做些什麼來加快這個過程。
還有其他方法可以快速導入數據嗎?我可以使用任何標誌來加快此過程嗎?任何和所有的幫助表示讚賞。
更新:
一大早我又啟動了這個流程,到現在已經執行了大約7個半小時,流程列表如下:
mysql> show processlist; +----+------+-----------+------+---------+-------+-------+------------------------------------------------------------------------------------------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+------+-----------+------+---------+-------+-------+------------------------------------------------------------------------------------------------------+ | 9 | root | localhost | db | Query | 22978 | NULL | LOAD DATA INFILE '/home/SQLBackUps/file.csv' INTO TABLE table FIELDS TERMINATED | | 15 | root | localhost | db | Query | 0 | NULL | show processlist | +----+------+-----------+------+---------+-------+-------+------------------------------------------------------------------------------------------------------+
當您回复我的評論時,有一件事情引起了我的注意:目標表是 InnoDB,而您正在使用 LOAD DATA INFILE。我看到兩個問題
問題 #1:載入數據文件
雖然LOAD DATA INFILE可以載入 InnoDB 表,但可以調整該命令以載入 MyYSAM 表。只有一個選項可以做到這一點:bulk_insert_buffer_size。設置為非常大或將其設置為零以禁用它。
InnoDB 沒有同義詞。
問題 #2:InnoDB 儲存引擎
讓我們看一下 InnoDB 架構
現在,想像一下您將 5000 萬行作為單個事務推送到一個 InnoDB 表中,從而提供了這個精心插圖中描述的所有管道。
為了確保發生崩潰時的數據一致性,您的數據必須寫入三個位置:
- 系統表空間(物理文件 ibdata1)中有128 個回滾段。您***傳入的表格數據必須堆積在一個回滾段上,***就像四分衛的防守鏟球一樣。
- 您在系統表空間中有一個活動的雙寫緩衝區。顧名思義,數據被寫入兩次。InnoDB 將在寫回
.ibd
文件之前先寫入雙寫緩衝區。這些數據用作崩潰恢復的源數據。- 數據也通過日誌緩衝區寫入事務日誌(右下角的重做日誌)。物理文件是 ib_logfile0 和 ib_logfile1。
我的觀點
InnoDB 可以處理 1024 個目前事務,但只有 128 個回滾段。如果還有其他交易正在進行,您就會遇到紐約市的交通擁堵。通過批量插入管理所有 InnoDB 內部,在 processlist 中看到 NULL 應該不足為奇。您應該查看四 (4) 項以確保它們是最新的:
- ibdata1 的文件大小
- ibdata1 上的時間戳
- ib_logfile0 上的時間戳
- ib_logfile1 上的時間戳
建議
您可以設置以下一項或多項
- 禁用雙寫緩衝區(將innodb_doublewrite設置為 0)。請稍後將其設置回1。
- 增加 InnoDB 緩衝池(增加innodb_buffer_pool_size)
- 增加 InnoDB 日誌文件大小(將inndo_log_file_size設置為 2G)
- 增加 InnoDB 日誌緩衝區大小(將inndo_log_buffer_size設置為 512M)
- 更改事務刷新行為(將innodb_flush_log_at_trx_commit設置為 0)。這將禁用 ACID 合規性(崩潰時可能會失去 1 秒的事務),但會提高 InnoDB 寫入性能。
- 增加Write IO Thread(設置innodb_write_io_threads為64,你也可以設置innodb_write_io_threads為64)
試一試 !!!