【问题标题】:Ingestion of Large Amount of Data in Postgres Slow and Eventually Crashes在 Postgres 中摄取大量数据缓慢并最终崩溃
【发布时间】:2017-01-14 00:20:42
【问题描述】:

我尝试使用Luigi 框架使用Python 脚本摄取大量数据(大约 100 个 csv 文件,每个文件有 1500 万行),并且摄取一直正常,直到我遇到以下错误 (来自 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",,,, ""

由于预写日志 (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",,,,,,,,,""

谢谢

【问题讨论】:

    标签: python postgresql


    【解决方案1】:

    这些 .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.html, https://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,对数据文件的更改 (表和索引所在的位置)仅在这些更改完成后写入 已记录(作为描述更改的元指令序列)并已 冲洗到永久存储。因此,在发生崩溃时,我们将能够 使用日志恢复数据库:尚未应用到数据库的任何更改 可以从日志记录中重做数据页(这是“前滚恢复”, 也称为重做)。

    您可以使用“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”命令,该命令将执行 “复制。 $ cat 巨大文件.csv |头-n 800000 | psql ... -c "\copy MyTargetTmpTable from pstdin with (format csv)"
    4. 将所有行从“MyTargetTmpTable”移到最终表格。
    5. 对剩余的 CSV 行批次重复上述所有过程。

    【讨论】:

    • @roger-dieirton 感谢您提供所有有价值的信息。它阐明了很多关于大型 csv 摄取到 postgres 数据库的要点。正如您所指出的,摄取的主要问题是设备空间不足。我有一个带有两个分区的 Linux 操作系统:一个用于用户空间,另一个用于数据。我试图将数据库保存在用户空间中,但我确实没有意识到空间不足。将其移至数据分区后,摄取就没有问题了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多