Я использую том iscsi в системе хранения Open-E для нескольких виртуальных машин, работающих на хосте XenServer. Иногда, когда на виртуальных машинах (и, следовательно, также и в системе хранения) наблюдается очень высокая нагрузка на дисковый ввод-вывод, я получал это сообщение об ошибке на консолях 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 секунд, скорее всего, из-за того, что доступ к диску в системе хранения еще не обработан.
Но как это влияет на процессы. Например, будет ли процесс postgres в конечном итоге записывать свои данные, когда система хранения снова простаивает через несколько минут, так что все данные по-прежнему согласованы? Или он прервет запись, оставив некоторые таблицы в несогласованном состоянии?
Я определенно ожидаю, что первое должно быть так - если доступ к диску медленный, postgres (или любой другой затронутый процесс) должен просто ждать столько, сколько потребуется. Я могу прожить с зависанием приложения несколько минут. Но если есть вероятность повреждения данных, то любая из этих ошибок действительно плохая новость.
Посоветуйте, пожалуйста, что здесь делать.
Ваша интуиция, что БД останется последовательной должен быть правильным, если только причиной 120-секундных зависаний не является сам диск. Если основная причина действительно просто в большом количестве операций ввода-вывода, PostgreSQL гарантирует, что порядок, в котором он фиксирует данные на диске, не повредит.
Раньше у меня были ситуации, когда диски SATA зависали в ожидании завершения операций ввода-вывода и приводили к этой ошибке ядра. К тому времени, когда это произойдет, вы, вероятно, уже не сможете в полной мере доверять данным на этом диске - 120-секундное зависание - это просто побочный эффект, а не основная причина повреждения.
Если вы используете транзакции, то вы в безопасности, потому что можете быть уверены, что данные сохранятся после завершения транзакции (транзакция - это операция «все или ничего»). Если вы не используете транзакции, некоторые данные могут быть потеряны или частично обновлены и т. Д. Подробнее о транзакциях
Если вас беспокоит последовательность, рассмотрите возможность использования такого инструмента, как diskchecker.pl
чтобы убедиться, что ваш диск поддерживает сбросы. Вы также можете использовать pg_test_fsync
и посмотрите, нет ли у вас подозрительно высоких частот fsync (), которые могут указывать на небезопасное кэширование записи, если вы не знаете, что у вас есть сверхбыстрый кэш обратной записи с защитой от питания и сбоев.
См. Документацию PostgreSQL о надежности записи для получения информации об этих инструментах и других параметрах.
Чтобы ваше хранилище было надежным, оно должно иметь следующие свойства:
Как только запись сбрасывается fsync()
, напишите барьеры, O_SYNC
или подобное, он должен находиться в надежном хранилище, которое не очищается или не повреждается при отключении питания, сбое ОС, сбое гостевой виртуальной машины или хоста и т. д.
Порядок fsync()
запросы должны быть выполнены, так что если совершает A
, B
и C
происходят в порядке записи, их данные также должны быть сброшены в долговременное хранилище в этом порядке. Системе не разрешено оптимизировать вещи, смешивая записи для C
и B
в записи для A
для лучшей производительности, так как если он выйдет из строя / потеряет питание на полпути, данные будут записаны в неправильном порядке, и воспроизведение WAL будет ненадежным.
Как только блок будет сброшен fsync()
он должен быть извлечен из хранилища. Хранилище только для записи или хранилище, которое возвращает значение, отличное от того, что вы ему дали, не очень хорошо.
Если ваше хранилище имеет эти два свойства, то не имеет значения, останавливается ли оно, переупорядочивает записи (пока это не выполняется через барьеры / синхронизируются), кеширует записи (пока поддерживает сброс кеша), и т.п.
Трудно превзойти тестирование plug-pull. Это именно то, что написано. Во время утверждения / тестирования перед развертыванием отключите питание всей системы, пока она находится под нагрузкой, загрузите ее резервную копию и убедитесь, что БД воспроизводит свои журналы и восстанавливается без ошибок. Повторение.