Postgresql

看不到程序進度,機器在嘗試導入 5 億條記錄時變慢

  • October 17, 2019

工作環境:PostgreSQL 12.0,Ubuntu 18.10,4GB記憶體,i5-3230M CPU@2.60GHz×4,Os 64位

我正在嘗試使用我的 PC 將包含超過 5 億條記錄的 .csv 文件導入 PostgreSQL 數據庫表。(我們正在我的 PC 上進行測試,直到它可以工作,之後我們將在伺服器上進行)

我的公司正在從 Firebird 遷移到 Postgres,所以這應該是一次性的任務。之後,我們預計每天插入約 20 萬條記錄。

使用(從原始 firebird 數據庫生成的 SQL)創建表

    CREATE TABLE REGDATA
    (
       CODIGO integer NOT NULL,
       DTAREG timestamp NOT NULL,
       PERIOD integer NOT NULL,
       FLDCODIGO integer,
       REGVALUE double precision,
       CLICODIGO integer,
       SITCODIGO integer,
       CONSTRAINT PK_REGDATA PRIMARY KEY (CODIGO)
    );

.csv 是使用FBExport 1.9生成的

./fbexport -Sc -D /opt/firebird/bin/measures.fdb -H localhost -U user -P password -F /home/dani/Documents/raw_regdata.out -Q "SELECT * FROM REGDATA"

我將 raw_regdata.out 轉換為 utf8 以使用 postgres 編碼。去掉一些字元(ã、º等)

iconv -c -t utf8 /home/dani/Documents/raw_regdata.out > /home/dani/Documents/utf8_regdata.out

我已遵循Postgres關於如何導入大數據的指南,例如:

  • 刪除所有索引;
  • 增加maintenance_work_mem (maintenance_work_mem = 512MB)
  • 增加 max_wal_size (max_wal_size = 4GB)
  • 設置 wal_level = 最小
  • 設置 max_wal_senders = 0

連接到 Postgres 集群後,我使用 COPY 導入數據

COPY REGDATA(CODIGO,DTAREG,PERIOD,FLDCODIGO,REGVALUE,CLICODIGO,SITCODIGO) from '/home/dani/Documents/utf8_regdata.out' DELIMITER ',' CSV HEADER;

問題來了,我看不到命令​​是否正在執行,一段時間後我的電腦變得非常慢,它只是****凍結了。

第一次嘗試:讓它執行 2-3 小時,然後終止程序(終端上的 Ctrl+c),從日誌中我看到它正在進行(第 131158327 行):

2019-10-16 10:28:05.657 -03 [9258] postgres@measures ERROR:  canceling statement due to user request
2019-10-16 10:28:05.657 -03 [9258] postgres@measures CONTEXT:  COPY regdata, line 131158327: ""178865944","13.03.2015 12:10:00","600","22439","358.60000000000002","9","37""
2019-10-16 10:28:05.657 -03 [9258] postgres@measures STATEMENT:  COPY REGDATA(CODIGO,DTAREG,PERIOD,FLDCODIGO,REGVALUE,CLICODIGO,SITCODIGO) from '/home/dani/Documents/utf8_regdata.out' DELIMITER ',' CSV HEADER;

但是我嘗試選擇一些東西卻什麼也得不到,我認為由於 Copy 僅在整個過程完成後送出,它只是撤消所有內容,我最終得到一個空表

第二次嘗試:讓它執行 24 小時(即使我的 PC 完全鎖定),然後再次終止該程序,希望在日誌上看到更多進展,但令我驚訝的是,我沒有看到任何類似的日誌,只有相同的 3 個警告結束和再次:

2019-10-16 17:42:31.061 -03 [5646] LOG:  using stale statistics instead of current ones because stats collector is not responding
.
.
.
2019-10-17 06:10:31.423 -03 [2734] WARNING:  worker took too long to start; canceled
2019-10-17 06:57:19.150 -03 [5964] WARNING:  autovacuum worker started without a worker entry
2019-10-17 08:04:47.445 -03 [2327] LOG:  starting PostgreSQL 12.0 (Ubuntu 12.0-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0, 64-bit
2019-10-17 08:04:47.622 -03 [2327] LOG:  listening on IPv4 address "127.0.0.1", port 5412
2019-10-17 08:04:48.048 -03 [2327] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5412"
2019-10-17 08:04:53.879 -03 [2546] LOG:  database system was interrupted; last known up at 2019-10-16 15:47:25 -03
2019-10-17 08:05:10.887 -03 [2546] LOG:  database system was not properly shut down; automatic recovery in progress
2019-10-17 08:05:11.534 -03 [2546] LOG:  redo starts at 14/B8254908
2019-10-17 08:05:11.847 -03 [2546] LOG:  invalid record length at 14/B8260848: wanted 24, got 0
2019-10-17 08:05:11.847 -03 [2546] LOG:  redo done at 14/B82607D0
2019-10-17 08:05:16.417 -03 [2327] LOG:  database system is ready to accept connections

有一種方法可以監控進度(它目前正在處理哪條線),並且在程序處於活動狀態時出現當機是正常的嗎?


編輯:查看原始火鳥數據庫,我可以看到主鍵未排序: 在此處輸入圖像描述

沒有內置的方法來監控進度。v12 為某些操作添加了進度監控,但不針對 COPY。

我在這種情況下所做的就是用來strace -s 1024 -y -p <backend pid>跟踪載入過程。這將顯示它從“/home/dani/Documents/utf8_regdata.out”文件中讀取的數據(以及一堆其他內容)。然後,您可以從該流中獲取最近的主鍵,然後fgrep -n ,<primarykey> /home/dani/Documents/utf8_regdata.out查看它所在的行號。這不是最優雅的過程,但比完全在黑暗中要好。

如果你沒有刪除主鍵,並且載入時數據沒有按主鍵順序排序,那麼一旦主鍵索引的大小超過某個門檻值,就會出現嚴重的 IO 擁塞。這可以解釋“陳舊的統計數據”和“工人啟動時間太長”,並且系統也可能變得如此緩慢以至於它似乎已經死了(特別是如果您使用的是 GUI)。

索引大小的性能崩潰門檻值通常介於shared_buffer和之間greatest(shared_buffers,RAM - shared_buffers),但具體位置取決於核心版本和設置。

引用自:https://dba.stackexchange.com/questions/251375