“postgres阻塞超过120秒” – 是我的数据库还是一致?

我在Open-E存储系统上为在XenServer主机上运行的多个虚拟机使用了一个iscsi卷。 有时候,当虚拟机(因此也是在存储系统上)有非常高的磁盘I / O负载时,我在vm控制台上得到这个错误信息:

[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秒,很可能是因为磁盘对存储系统的访问还没有被处理。

但对stream程有什么影响? 例如,postgres进程在数分钟后再次将存储系统闲置时会写入数据,以便所有数据都保持一致? 或者它会中止写入,使一些表格处于不一致的状态?

我当然期望前者应该是这样 – 如果磁盘访问速度慢,postgres(或任何其他受影响的进程)应该等待,只要它需要。 我可以用悬挂几分钟的应用程序来生活。 但是,如果有数据损坏的机会,那么这些错误中的任何一个都是坏消息。

请告知在这里做什么。

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

我遇到了SATA磁盘故障之前的情况,往往等待I / O操作完成并导致此内核错误。 在这种情况发生的时候,您可能无法相信该磁盘上的数据 – 120秒的挂起仅仅是一个副作用,而不是损坏的根本原因。

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

如果您担心一致性问题,请考虑使用像diskchecker.pl这样的工具来确保您的磁盘正在进行刷新。 您也可以使用pg_test_fsync ,看看您是否得到可疑的高fsync()速率,这可能表明不安全的写caching,除非您知道您拥有超快速的电源和崩溃安全写回caching。

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

您的存储必须具有可靠的属性:

  • 一旦使用fsync()刷新写入,写入屏障, O_SYNC或类似操作,它必须位于持久性存储上,在断电,操作系统崩溃,访客虚拟机或主机崩溃等情况下不会被清除或损坏。

  • 必须遵守fsync()请求的顺序,以便如果提交ABC按写入顺序发生,则必须按顺序将其数据刷新为持久存储。 系统不允许通过将用于CB的写入混合到用于A的写入来优化事物,以获得更好的性能,因为如果它在半途中崩溃/失去电源,那么将会有数据乱序写入并且WAL重放将不可靠。

  • 一旦一个块被fsync()刷新,它必须可以从存储中获取。 只写存储或存储返回一个不同于你给它的值是不太好的。

如果您的存储具有这两个属性,则无论它是否停止,重新写入命令(只要不跨越障碍/同步执行操作),caching写入(只要它支持caching刷新)都无关紧要,等等

很难打败插拔testing。 这正是它所说的。 在批准/部署前testing期间,在整个系统处于负载状态时,将电源从整个系统中拔出,重新启动,并确保数据库重新logging日志并清理恢复。 重复。