PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Еволюция на отказоустойчивостта в PostgreSQL:Синхронно записване

PostgreSQL е страхотен проект и се развива с невероятна скорост. Ще се съсредоточим върху развитието на възможностите за отказоустойчивост в PostgreSQL във всичките му версии с поредица от публикации в блога. Това е четвъртата публикация от поредицата и ще говорим за синхронния комит и неговото въздействие върху отказоустойчивостта и надеждността на PostgreSQL.

Ако искате да наблюдавате напредъка на еволюцията от самото начало, моля, проверете първите три публикации в блога от поредицата по-долу. Всяка публикация е независима, така че всъщност не е нужно да четете една, за да разберете друга.

  1. Еволюция на отказоустойчивостта в PostgreSQL 
  2. Еволюция на отказоустойчивостта в PostgreSQL:Фаза на репликация 
  3. Еволюция на отказоустойчивостта в PostgreSQL:Пътуване във времето

Синхронно записване

По подразбиране PostgreSQL прилага асинхронна репликация, при която данните се предават поточно, когато е удобно за сървъра. Това може да означава загуба на данни в случай на отказ. Възможно е да поискате от Postgres да изисква един (или повече) режим на готовност, за да потвърди репликацията на данните преди извършване, това се нарича синхронна репликация (синхронно записване ) .

При синхронна репликация забавянето на репликацията директно влияе върху изминалото време на транзакциите на главния. При асинхронна репликация главният може да продължи с пълна скорост.

Синхронната репликация гарантира, че данните се записват в поне два възела преди потребителят или приложението да бъде казано, че транзакцията е извършена.

Потребителят може да избере режима на извършване на всяка транзакция , така че е възможно едновременно да се изпълняват както синхронни, така и асинхронни транзакции за извършване.

Това позволява гъвкави компромиси между производителност и сигурност в трайността на транзакциите.

Конфигуриране на синхронно записване

За да настроим синхронна репликация в Postgres, трябва да конфигурираме synchronous_commit параметър в postgresql.conf.

Параметърът указва дали транзакция commit ще изчака WAL записите да бъдат записани на диска, преди командата да върне успешно индикация към клиента. Валидни стойности са включениremote_applyотдалечено_запис , локален и изключено . Ще обсъдим как работят нещата по отношение на синхронната репликация, когато настроим synchronous_commit параметър с всяка от дефинираните стойности.

Нека започнем с документацията на Postgres (9.6):

Тук разбираме концепцията за синхронен комит, както описахме в уводната част на публикацията, вие сте свободни да настроите синхронна репликация, но ако не го направите, винаги има риск от загуба на данни. Но без риск от създаване на несъответствие в базата данни, за разлика от изключването на fsync off – обаче това е тема за друг пост. И накрая, стигаме до заключението, че ако трябва да не губим никакви данни между закъсненията на репликацията и искаме да сме сигурни, че данните са записани в поне два възела, преди потребителят/приложението да бъде информирано, че транзакцията е извършила , трябва да приемем загубата на някаква производителност.

Нека видим как работят различните настройки за различно ниво на синхронизация. Преди да започнем, нека поговорим как се обработва комитът от PostgreSQL репликация. Клиентът изпълнява заявки на главния възел, промените се записват в регистър на транзакциите (WAL) и се копират по мрежата в WAL на възела в режим на готовност. След това процесът на възстановяване на възела в режим на готовност чете промените от WAL и ги прилага към файловете с данни точно както по време на възстановяване при срив. Ако режимът на готовност е вгорещ режим в режим, клиентите могат да издават заявки само за четене на възела, докато това се случва. За повече подробности относно това как работи репликацията, можете да разгледате публикацията в блога за репликация в тази серия.

Фиг.1 Как работи репликацията

synchronous_commit =изключено

Когато зададем sychronous_commit = off, COMMIT не чака записът на транзакцията да бъде изхвърлен на диска. Това е подчертано на Фиг.2 по-долу.

Фиг.2 synchronous_commit =off

synchronous_commit =local

Когато зададем synchronous_commit = local, COMMIT изчаква, докато записът на транзакцията се изчисти на локалния диск. Това е подчертано на Фиг.3 по-долу.

Фиг.3 synchronous_commit =local

synchronous_commit =включено (по подразбиране)

Когато зададем synchronous_commit = on, COMMIT ще изчака, докато сървърът(ите), посочени от synchronous_standby_names потвърдете, че записът на транзакцията е безопасно записан на диска. Това е подчертано на Фиг.4 по-долу.

Забележка: Когато synchronous_standby_names е празен, тази настройка се държи по същия начин като synchronous_commit = local .

Фиг.4 synchronous_commit =on

synchronous_commit =remote_write

Когато зададем synchronous_commit = remote_write, COMMIT ще изчака, докато сървърът(ите), посочени от synchronous_standby_names потвърдете записа на записа на транзакцията в операционната система, но не е непременно достигнал до диска. Това е подчертано на фиг.5 по-долу.

Фиг.5 synchronous_commit =remote_write

synchronous_commit =remote_apply

Когато зададем synchronous_commit = remote_apply, COMMIT ще изчака, докато сървърът(ите), посочени от synchronous_standby_names потвърдете, че записът на транзакцията е приложен към базата данни. Това е подчертано на Фиг.6 по-долу.

Фиг.6 synchronous_commit =remote_apply

Сега нека разгледаме sychronous_standby_names параметър в подробности, който е посочен по-горе при настройка на synchronous_commit като onremote_apply или remote_write .

synchronous_standby_names =‘име на готовност [, …]’

Синхронният комит ще изчака отговор от един от режимите на готовност, изброени в реда на приоритета. Това означава, че ако първият режим на готовност е свързан и стрийминг, синхронният комит винаги ще чака отговор от него, дори ако вторият режим на готовност вече е отговорил. Специалната стойност на  * може да се използва като stanby_name което ще съответства на всеки свързан режим на готовност.

synchronous_standby_names =‘брой (име на готовност [, …])’

Синхронният комит ще изчака отговор от поне num брой режими на готовност, изброени по приоритет. Прилагат се същите правила като по-горе. Така че, например настройка на synchronous_standby_names = '2 (*)' ще накара синхронния комит да изчака отговор от всеки 2 резервни сървъра.

synchronous_standby_names е празен

Ако този параметър е празен, както е показано, той променя поведението на настройката synchronous_commit до on , remote_write или remote_apply да се държи същото като local (т.е. COMMIT ще изчака само прочистване на локален диск).

Заключение

В тази публикация в блога обсъдихме синхронната репликация и описахме различни нива на защита, които са налични в Postgres. Ще продължим с логическата репликация в следващата публикация в блога.

Препратки

Специални благодарности на моя колега Petr Jelinek, че ми даде идеята за илюстрации.

Документация на PostgreSQL
Готварска книга за администриране на PostgreSQL 9 – второ издание


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Има ли някакъв начин да се изпълни заявка вътре в стойността на низа (като eval) в PostgreSQL?

  2. Първи стъпки с PostgreSQL поточно репликация

  3. PSQLException:ResultSet не е позициониран правилно, може би трябва да се обадите следващия

  4. Преглед на инструментите за диаграма на базата данни, налични за PostgreSQL

  5. Индексиране на база данни в PostgreSQL