Postgres中大量数据的摄取缓慢且最终崩溃

时间:2016-08-18 15:03:57

标签: python postgresql

我尝试使用Python框架使用Luigi脚本摄取大量数据(每个包含1500万行的100个csv文件)并且摄取正常,直到我达到以下错误(来自Postgres日志),其中最重要的部分是:

2016-08-18 13:14:31.714 UTC,,,8508,,57b5b2ec.213c,1,,2016-08-18 13:06:52 UTC,13/109,0,PANIC,53100,"could not write to file ""pg_xlog/xlogtemp.8508"": No space left on device",,,,,"writing block 49526 of relation base/16384/22811",,,, ""

由于Write Ahead Logging(WAL)机制,POSTGRES似乎阻止了摄取。在摄取了10天的文件并重置数据库之后,我试图摄取更多天。第二次尝试导致数据被摄取仅增加1天。第三次尝试完全失败了。

pg_xlog是否未被清除?我不知道它们是如何被管理的以及它们的确切目的是什么,我的直觉说WAL是一种机制,POSTGRES通过该机制写入要插入数据库的行。

是否有任何我错过的数据库配置?我的桌子上的索引有问题吗?还有什么?

日志中可能相关的其他部分:

2016-08-18 12:57:45.255 UTC,,,8342,,57b5a460.2096,96,,2016-08-18 12:04:48 UTC,,0,LOG,00000,"checkpoints are occurring too frequently (25 seconds apart)",,"Consider increasing the configuration parameter ""max_wal_size"".",,,,,,,"" 2016-08-18 12:57:45.255 UTC,,,8342,,57b5a460.2096,97,,2016-08-18 12:04:48 UTC,,0,LOG,00000,"checkpoint starting: xlog",,,,,,,,,"" 2016-08-18 12:58:13.609 UTC,,,8342,,57b5a460.2096,98,,2016-08-18 12:04:48 UTC,,0,LOG,00000,"checkpoint complete: wrote 349100 buffers (16.6%); 0 transaction log file(s) added, 143 removed, 0 recycled; write=15.550 s, sync=12.677 s, t otal=28.354 s; sync files=51, longest=2.304 s, average=0.248 s; distance=2641771 kB, estimate=2641771 kB",,,,,,,,,"" 1038 2016-08-18 12:58:13.610 UTC,,,8342,,57b5a460.2096,99,,2016-08-18 12:04:48 UTC,,0,LOG,00000,"checkpoints are occurring too frequently (28 seconds apart)",,"Consider increasing the configuration parameter ""max_wal_size"".",,,,,,,"" 1039 2016-08-18 12:58:13.610 UTC,,,8342,,57b5a460.2096,100,,2016-08-18 12:04:48 UTC,,0,LOG,00000,"checkpoint starting: xlog",,,,,,,,,""

由于

1 个答案:

答案 0 :(得分:2)

.csv文件的整体大小(以GB为单位)是多少? .csv文件的最大大小是多少? 这对我来说是一个有价值的信息。

此外,了解您的执行环境非常重要:

  • 操作系统:Linux,...
  • 存储:NAS,SAN,HDD,SSD,可用存储空间......
  • 内存量
  • 处理器:速度,......
  • PG版本:9.5,......

我看到https://github.com/spotify/luigi是什么,但我认为是无关紧要的 你的问题。 我必须假设您正在将.csv文件应用到PG表中 “复制”(https://www.postgresql.org/docs/9.5/static/sql-copy.htmlhttps://www.postgresql.org/docs/9.5/static/app-psql.html)命令?

问题的原因很明显:无法写入文件 因为设备上没有剩余空间,因为磁盘已满 到意图存储的数据量。

有关WAL的深入解释,请参阅此PG文档章节: https://www.postgresql.org/docs/9.5/static/wal-intro.html 简而言之: WAL是一种确保数据完整性的方法。使用WAL,可以更改数据文件     (表和索引所在的位置)仅在这些更改之后写入     记录(作为描述变化的元指令序列)并且已经记录     冲到永久存储。因此,如果发生崩溃,我们将能够     使用日志恢复数据库:尚未应用于的任何更改     数据页可以从日志记录中重做(这是“前滚恢复”,     也被称为REDO)。

您可以使用“pg_resetxlog”程序重置WAL。这在这里解释: http://www.hivelogik.com/blog/?p=513     Postgresql:如何清理pg_xlog http://blog.endpoint.com/2014/09/pgxlog-disk-space-problem-on-postgres.html     在Postgres上解决pg_xlog磁盘空间问题 https://www.postgresql.org/docs/9.5/static/app-pgresetxlog.html     pg_resetxlog - 重置PostgreSQL数据库集群的预写日志和其他控制信息

再次,在日志跟踪中     “检查站发生得太频繁(相隔25秒)”,     “考虑增加配置参数”“max_wal_size”“。” 指出了解决方案:     增加配置参数“max_wal_size” 在以下链接中     https://dba.stackexchange.com/questions/117479/checkpoints-are-occurring-too-frequently-during-pg-restore 有关同一问题的更多信息。 在该链接中,它表示“......将大量数据加载到PostgreSQL中会导致 检查点的发生频率高于正常的检查点频率“。

最后,我有一些摄取数据文件(CSV和纯文本文件)的经验 进入PG,我建议您使用以下管道:

  1. 创建一个临时表“MyTargetTmpTable”,作为UNLOGGED,因为数据写入未记录的表 未写入预写日志。
  2. 截断表格“MyTargetTmpTable”。
  3. 将输入数据划分为有限最大大小的批次(使用Linux命令 “cat”,“head”等“tail”)并将其输入“psql”命令,该命令将执行a “复制。 $ cat hugefile.csv |头-n 800000 | psql ... -c“\从pstdin复制MyTargetTmpTable with(format csv)”
  4. 将所有行从“MyTargetTmpTable”移至最终表。
  5. 使用剩余的CSV行批次重复上述所有步骤。