Перейти к основному содержимому

Надежность

примечание

Эта страница переведена при помощи нейросети GigaChat.

Надежность является важным свойством любой серьезной системы баз данных, и PostgreSQL делает все возможное для обеспечения надежной работы. Одним из аспектов надежной работы является то, что все данные, записанные транзакцией с подтверждением, должны храниться в невосприимчивой к сбоям области, которая защищена от потери питания, сбоев операционной системы и аппаратных сбоев (за исключением отказа самой невосприимчивой к сбоям области, конечно). Успешная запись данных на постоянное хранилище компьютера (жесткий диск или эквивалент) обычно удовлетворяет этому требованию. На самом деле, даже если компьютер будет серьезно поврежден, если жесткие диски выживут, их можно перенести на другой компьютер с аналогичным оборудованием, и все подтвержденные транзакции останутся нетронутыми.

Хотя периодическая принудительная запись данных на магнитные пластины диска может показаться простой операцией, это не так. Поскольку жесткие диски значительно медленнее основной памяти и процессоров, между основной памятью компьютера и пластинами жесткого диска существует несколько уровней кеширования. Во-первых, есть буферный кеш операционной системы, который кеширует часто запрашиваемые блоки диска и объединяет записи на диск. К счастью, все операционные системы предоставляют приложениям способ принудительной записи из буферного кеша на диск, и PostgreSQL использует эти функции (см. параметр wal_sync_method).

Далее, может быть кеш в контроллере дискового накопителя. Это особенно распространено на картах контроллеров RAID. Некоторые из этих кешей являются сквозной записью, что означает, что записи отправляются на диск сразу после их получения. Другие являются записью с обратной связью, что означает, что данные отправляются на диск в какое-то более позднее время. Такие кеши могут представлять угрозу для надежности, поскольку память в кеше контроллера диска является энергозависимой и потеряет свое содержимое при сбое питания. Более качественные карты контроллеров имеют батарейные блоки питания (Battery-Backup Unit, BBU), что означает, что карта имеет батарею, которая поддерживает питание кеша в случае потери системного питания. После восстановления питания данные будут записаны на диски.

И наконец, большинство жестких дисков имеют кеши. Некоторые из них являются сквозными, а некоторые - обратимыми, и те же опасения по поводу потери данных существуют для обратимых кешей привода, что и для кешей контроллера диска. Потребительские приводы IDE и SATA особенно склонны иметь обратимые кеши, которые не переживут сбоя питания. Многие твердотельные накопители (SSD) также имеют обратимые энергозависимые кеши.

Эти кеши обычно можно отключить, однако метод для этого варьируется в зависимости от операционной системы и типа диска:

  • В Linux приводы IDE и SATA могут быть запрошены с использованием hdparm -I. Запись в кеш включена, если рядом с Write cache есть *. hdparm -W 0 можно использовать для отключения записи в кеш. Приводы SCSI могут быть запрошены с помощью sdparm. Используйте sdparm --get=WCE, чтобы проверить, включен ли кеш записи, и sdparm --clear=WCE, чтобы его отключить.
  • В FreeBSD можно запрашивать IDE-диски с помощью atacontrol и отключать кеширование записи с помощью hw.ata.wc=0 в /boot/loader.conf. SCSI-диски могут быть запрошены с использованием camcontrol identify, а кеш-запись может быть как запрошена, так и изменена с использованием sdparm при его наличии.
  • На Solaris кеш записи диска управляется с помощью format -e. Файловая система ZFS в Solaris безопасна с включенным кешем записи диска, поскольку она выдает свои собственные команды очистки кеша диска.
  • В Windows, если wal_sync_method равно open_datasync (по умолчанию), кеширование записи может быть отключено путем снятия отметки с My Computer\Open\disk drive\Properties\Hardware\Properties\Policies\Enable write caching on the disk. В качестве альтернативы, установите wal_sync_method на fsync или fsync_writethrough, что предотвратит кеширование записи.
  • На macOS предотвращение кеширования записи возможно путем установки wal_sync_method на fsync_writethrough.

Новые модели SATA-накопителей (те, которые следуют за ATAPI-6 или более поздними версиями) предлагают команду очистки кеша диска (FLUSH CACHE EXT), тогда как накопители SCSI уже давно поддерживают аналогичную команду SYNCHRONIZE CACHE. Эти команды недоступны непосредственно для PostgreSQL, но некоторые файловые системы (например, ZFS, ext4) могут использовать их для сброса данных на пластины на дисках с включенным режимом отложенной записи. К сожалению, такие файловые системы работают неоптимально при сочетании с контроллерами дисков с батарейным питанием (BBU). В таких конфигурациях команда синхронизации заставляет все данные из кеш-памяти контроллера записываться на диски, что сводит на нет многие преимущества BBU. Можно запустить программу pg_test_fsync чтобы увидеть, присутствует ли эта проблема. Если да, то преимущества производительности от использования BBU можно восстановить путем отключения барьеров записи в файловой системе или перенастройки контроллера диска, если это возможно. Если барьеры записи отключены, убедитесь, что батарея остается работоспособной, неисправная батарея потенциально может привести к потере данных. Надеюсь, разработчики файловых систем и контроллеров дисков со временем устранят такое неоптимальное поведение.

Когда операционная система отправляет запрос на запись в аппаратное обеспечение хранения, она мало что может сделать, чтобы убедиться, что данные действительно достигли области энергетически независимого хранения. Скорее, ответственность администратора заключается в том, чтобы обеспечить целостность всех компонентов хранения как для данных, так и для метаданных файловой системы. Избегайте использования контроллеров дисков, имеющих кеш-записи без поддержки батареи. На уровне привода отключите кеширование с обратной записью, если привод не гарантирует, что данные будут записаны до завершения работы. Если используется SSD, имейте в виду, что многие из них не выполняют команды сброса кеша по умолчанию. Можно проверить надежность поведения подсистемы ввода-вывода с помощью diskchecker.pl.

Еще один риск потери данных связан с самими операциями записи на пластину диска. Дисковые пластины разделены на сектора, обычно по 512 байт каждый. Каждая физическая операция чтения или записи обрабатывает целый сектор. Когда запрос на запись поступает на диск, он может быть кратен 512 байтам (PostgreSQL обычно записывает 8192 байта, или 16 секторов, за раз), а процесс записи может завершиться сбоем из-за потери питания в любой момент, что означает, что некоторые 512-байтные сектора были записаны, а другие - нет. Чтобы защитить себя от таких отказов, PostgreSQL периодически записывает полные образы страниц в постоянное хранилище WAL до изменения самой страницы на диске. Делая это, во время восстановления после сбоя PostgreSQL может восстанавливать частично записанные страницы из WAL. Если файловая система защищена от частичной записи страниц (например, ZFS), то можно отключить функцию создания изображений страниц, отключив параметр full_page_writes. Контроллеры дисков с батарейным питанием (BBU) не предотвращают частичной записи страниц, если они гарантируют, что данные записываются в BBU как полные (8-килобайтные) страницы.

PostgreSQL также защищает от некоторых видов повреждения данных на устройствах хранения, которые могут возникнуть из-за аппаратных ошибок или сбоев носителей со временем, таких как чтение/запись мусорных данных.

  • Каждая отдельная запись в файле WAL защищена с помощью контрольной суммы CRC-32 (32-разрядная), которая позволяет определить, является ли содержимое записи правильным. Значение CRC устанавливается при записи каждой записи WAL и проверяется во время восстановления после сбоя, архивного восстановления и репликации.
  • Страницы данных в настоящее время не защищены контрольными суммами по умолчанию, хотя полные образы страниц, записанные в записях WAL, будут защищены (см. initdb для получения подробной информации о включении контрольных сумм данных).
  • Внутренние структуры данных, такие как pg_xact, pg_subtrans, pg_multixact, pg_serial, pg_notify, pg_stat, pg_snapshots, напрямую не защищены контрольными суммами, равно как и страницы, защищенные полной записью страниц. Однако там, где такие структуры данных являются постоянными, записываются записи WAL, которые позволяют точно восстанавливать последние изменения при восстановлении после сбоя, и эти записи WAL защищены, как обсуждалось выше.
  • Индивидуальные файлы состояния в pg_twophase защищены с помощью CRC-32.
  • Временные файлы данных, используемые в более крупных запросах SQL для сортировки, материализации и промежуточных результатах, в настоящее время не проверяются контрольной суммой, а изменения в этих файлах не отражаются в WAL.

PostgreSQL не защищает от исправляемых ошибок памяти, и предполагается, что будет производиться работа с ОЗУ, использующим стандартные отраслевые коды коррекции ошибок (ECC) или лучшую защиту.