“postgres 阻塞超过 120 秒” - 我的数据库仍然一致吗?

“postgres 阻塞超过 120 秒” - 我的数据库仍然一致吗?

我正在 Open-E 存储系统上使用 iscsi 卷来为 XenServer 主机上运行的多个虚拟机提供服务。有时,当虚拟机(因此存储系统)上的磁盘 I/O 负载非常高时,我会在虚拟机控制台上收到此错误消息:

[2594520.161701] INFO: task kjournald:117 blocked for more than 120 seconds.
[2594520.161787] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[2594520.162194] INFO: task flush-202:0:229 blocked for more than 120 seconds.
[2594520.162274] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[2594520.162801] INFO: task postgres:1567 blocked for more than 120 seconds.
[2594520.162882] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.

我理解这个错误信息是由内核导致的,告知这些进程已经 120 秒没有运行了,很可能是因为对存储系统的磁盘访问尚未处理。

但对进程有什么影响呢?例如,当存储系统几分钟后再次空闲时,postgres 进程最终会写入其数据,以便所有数据仍然一致吗?或者它会中止写入,导致某些表处于不一致状态?

我当然希望是前者 - 如果磁盘访问速度很慢,postgres(或任何其他受影响的进程)应该等待,直到它需要。我可以忍受应用程序挂起几分钟。但如果有数据损坏的可能性,那么任何这些错误都是坏消息。

请指教这里该怎么做。

答案1

你的直觉是数据库会保持一致应该是正确的,除非 120 秒挂起的原因恰好是磁盘本身出现故障。如果根本原因确实只是高 I/O,PostgreSQL 将确保将数据提交到磁盘的顺序不会损坏。

我以前遇到过这样的情况:SATA 磁盘发生故障时往往会挂起,等待 I/O 操作完成,并导致此内核错误。到那时,您可能无法再信任该磁盘上的数据 - 120 秒的挂起只是一个副作用,而不是损坏的根本原因。

答案2

如果您使用事务,那么您是安全的,因为您可以确保事务完成后数据会被持久保存(事务是全有或全无的操作)。如果您不使用事务,那么某些数据可能会丢失或部分更新,等等。 有关交易的更多信息

答案3

如果您担心一致性,请考虑使用类似 的工具diskchecker.pl来确保您的磁盘能够执行刷新。您还可以使用pg_test_fsync并查看是否获得了可疑的高 fsync() 速率,这可能表明写入缓存不安全,除非您知道您拥有超快的电源和崩溃安全写回缓存。

请参阅有关写入可靠性的 PostgreSQL 文档了解有关这些工具和其他选项的信息。

您的存储必须具备以下可靠属性:

  • fsync()一旦使用、写入屏障或类似方式刷新写入O_SYNC,它必须位于持久存储中,并且不会因断电、操作系统崩溃、客户虚拟机或主机崩溃等情况而被清除或损坏。

  • 必须遵守请求的顺序fsync(),这样如果提交ABC按照写入顺序发生,则它们的数据也必须按照该顺序刷新到持久存储中。系统不允许通过将 和 的写入混合CB的写入中来优化事物以A获得更好的性能,因为如果它中途崩溃/断电,您将无序写入数据,并且 WAL 重放将不可靠。

  • 一旦块被刷新,fsync()它必须可以从存储中检索。只写存储或返回值与您给出的值不同的存储并不是很好。

如果您的存储具有这两个属性,那么它是否停滞、重新排序写入(只要它不跨越障碍/同步)、缓存写入(只要它遵守缓存刷新)等都无关紧要。

很难打败插拔测试。这就是它所说的。在批准/部署前测试期间,在系统处于负载状态时切断整个系统的电源,重新启动,并确保数据库重放其日志并干净地恢复。重复。

相关内容