我在 Open-E 存储系统上为在 XenServer 主机上运行的多个虚拟机使用 iscsi 卷。有时,当虚拟机(因此存储系统)上的磁盘 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(或任何其他受影响的进程)应该等待它需要的时间。我可以忍受应用程序挂起几分钟。但是,如果有可能发生数据损坏,那么这些错误中的任何一个都是坏消息。
请建议在这里做什么。
您认为数据库将保持一致的直觉应该是正确的,除非 120 秒挂起的原因恰好是磁盘本身出现故障。如果根本原因真的只是高 I/O,PostgreSQL 将确保它向磁盘提交数据的顺序将确保它没有损坏。
我以前遇到过 SATA 磁盘故障往往会挂起等待 I/O 操作完成并导致此内核错误的情况。到那时,您可能不太信任该磁盘上的数据 - 120 秒的挂起只是一个副作用,而不是损坏的根本原因。
如果您使用的是事务,那么您是安全的,因为您可以确保在事务完成时保留数据(事务是一个全有或全无的操作)。如果您不使用事务,那么一些数据可能会丢失或部分更新等。 有关事务的更多信息
如果您担心一致性,请考虑使用类似工具
diskchecker.pl
来确保您的磁盘支持刷新。您还可以使用pg_test_fsync
并查看您是否获得了可疑的高 fsync() 速率,这可能表示不安全的写缓存,除非您知道您拥有超快的电源和崩溃安全回写缓存。有关这些工具和其他选项的信息,请参阅有关写入可靠性的 PostgreSQL 文档。
您的存储必须具有可靠的属性是:
一旦写入被
fsync()
、写屏障O_SYNC
或类似的刷新,它必须位于持久存储上,该存储不会因断电、操作系统崩溃、来宾 VM 或主机崩溃等而被清除或损坏。fsync()
必须遵守请求的顺序,以便如果提交A
,B
并且C
按照写入的顺序发生,则它们的数据也必须按照该顺序刷新到持久存储。系统不允许通过混合写入C
和B
写入来优化事物以A
获得更好的性能,因为如果它崩溃/中途断电,您将无序写入数据并且 WAL 重放不会可靠。一旦一个块被刷新,
fsync()
它就必须可以从存储中检索出来。只写存储或返回与您提供的值不同的值的存储不太好。如果您的存储具有这两个属性,那么它是否停止、重新排序写入(只要它不跨障碍/同步这样做)、缓存写入(只要它支持缓存刷新)都没有关系,等等
很难击败即插即用测试。这正是它所说的。在批准/部署前测试期间,在整个系统处于负载状态时将其断电,将其重新启动,并确保数据库重放其日志并干净地恢复。重复。