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

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

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

Ако искате да наблюдавате напредъка на еволюцията от самото начало, моля, проверете първите две публикации в блога от поредицата:

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

Хронология

Възможността за възстановяване на базата данни до предишен момент от време създава някои сложности, които ще покрием някои от случаите, като обясним failover (фиг. 1),превключване (фиг. 2) и pg_rewind (фиг. 3) случаи по-долу в тази тема.

Например, в оригиналната история на базата данни, да предположим, че сте изпуснали критична таблица в 17:15 ч. във вторник вечерта, но не сте осъзнали грешката си до сряда на обяд. Непритеснен, изваждате резервното си копие, възстановявате до момента 17:14 във вторник вечерта и работите. В тази история на вселената на базата данни никога не сте изпускали таблицата. Но да предположим, че по-късно осъзнаете, че това не е толкова страхотна идея и бихте искали да се върнете към сряда сутринта в оригиналната история. Няма да можете, ако докато вашата база данни е била в действие, тя е презаписала някои от файловете на сегментите на WAL, които са довели до момента, към който сега искате да можете да се върнете.

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

За да се справи с този проблем, PostgreSQL има понятие за времеви линии. Всеки път, когато възстановяването на архив завърши, се създава нова времева линия, за да се идентифицира поредицата от WAL записи, генерирани след това възстановяване. Идентификационният номер на времевата линия е част от имената на файловете на сегмента на WAL, така че нова времева линия не презаписва данните на WAL, генерирани от предишни времеви линии. Всъщност е възможно да се архивират много различни времеви линии.

Помислете за ситуацията, в която не сте съвсем сигурни в кой момент да се възстановите и затова трябва да направите няколко възстановявания в момента чрез опити и грешки, докато намерите най-доброто място за разклонение от старата история. Без срокове този процес скоро би генерирал неуправляема бъркотия. С времевите линии можете да се възстановите до всяко предишно състояние, включително състояния в клонове на времевата линия, които сте изоставили по-рано.

Всеки път, когато се създаде нова времева линия, PostgreSQL създава файл „хронология на времевата линия“, който показва от коя времева линия се е разклонил и кога. Тези хронологични файлове са необходими, за да позволят на системата да избере правилните файлове на сегмента на WAL при възстановяване от архив, който съдържа множество времеви линии. Следователно те се архивират в зоната на архива на WAL точно както файловете с сегменти на WAL. Файловете с история са просто малки текстови файлове, така че е евтино и подходящо да ги съхранявате за неопределено време (за разлика от сегментните файлове, които са големи). Можете, ако желаете, да добавите коментари към файл с история, за да запишете свои собствени бележки за това как и защо е създадена тази конкретна времева линия. Такива коментари ще бъдат особено ценни, когато имате гъсталака от различни времеви линии в резултат на експериментиране.

Поведението по подразбиране на възстановяването е да се възстанови по същата времева линия, която е била текуща, когато е направено основното архивиране. Ако искате да се възстановите в някаква дъщерна времева линия (т.е. искате да се върнете към някакво състояние, което е генерирано само след опит за възстановяване), трябва да посочите идентификатора на целевата времева линия в recovery.conf. Не можете да се възстановите във времеви линии, които са се разклонили по-рано от базовото архивиране.

За опростяване на концепцията за времевите линии в PostgreSQL, проблеми, свързани с времевата линия в случай на отказ ,превключване и pg_rewind са обобщени и обяснени с фиг.1, фиг.2 и фиг.3.

Сценарий на отказ:

 Фиг.1 Преминаване при отказ 

  • Има неуспешни промени в стария главен файл (TL1)
  • Увеличаването на времевата линия представлява нова история на промените (TL2)
  • Промените от старата времева линия не могат да се възпроизвеждат отново на сървърите, които са преминали към нова времева линия
  • Старият господар не може да следва новия господар

Сценарий за превключване:

 Фиг.2 Превключване

  • Няма неуспешни промени в стария главен код (TL1)
  • Увеличаването на времевата линия представлява нова история на промените (TL2)
  • Старият главен файл може да стане в готовност за новия главен файл

pg_rewind сценарий:

Фиг.3 pg_rewind

  • Неизпълнените промени се премахват с помощта на данни от новия главен файл (TL1)
  • Старият главен код може да следва новия главен код (TL2)

pg_rewind

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

Резултатът е еквивалентен на замяна на целевата директория с данни с изходната. Всички файлове се копират, включително конфигурационните файлове. Предимството на pg_rewind пред вземането на ново базово архивиране или инструменти като rsync е, че pg_rewind не изисква четене на всички непроменени файлове в клъстера. Това го прави много по-бърз, когато базата данни е голяма и само малка част от нея се различава между клъстерите.

Как работи?

Основната идея е да копираме всичко от новия клъстер в стария, с изключение на блоковете, за които знаем, че са еднакви.

  1. Сканирайте дневника на WAL на стария клъстер, като се започне от последната контролна точка преди точката, в която историята на времевата линия на новия клъстер се отдели от стария клъстер. За всеки WAL запис направете бележка за докоснатите блокове от данни. Това дава списък с всички блокове данни, които са били променени в стария клъстер, след като новият клъстер се разклони.
  2. Копирайте всички тези променени блокове от новия клъстер в стария.
  3. Копирайте всички други файлове, като запушване и конфигурационни файлове от новия клъстер в стария клъстер, всичко с изключение на релационните файлове.
  4. Приложете WAL от новия клъстер, като се започне от контролната точка, създадена при отказ. (Строго погледнато, pg_rewind не прилага WAL, той просто създава резервен файл с етикет, който показва, че когато PostgreSQL бъде стартиран, той ще започне повторното възпроизвеждане от тази контролна точка и ще приложи целия изискван WAL.)

Забележка: wal_log_hints трябва да бъде зададен в postgresql.conf, за да може pg_rewind да работи. Този параметър може да бъде зададен само при стартиране на сървъра. Стойността по подразбиране е изключено .

Заключение

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

Препратки

Документация за PostgreSQL
Готварска книга за администриране на PostgreSQL 9 – второ издание
pg_rewind Скандинавска презентация за PGDay от Heikki Linnakangas


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Вземете броя на дните в месеца в PostgreSQL

  2. Какъв е еквивалентът на LISTAGG (база данни Oracle) в PostgreSQL?

  3. 2 начина за изброяване на всички тригери в PostgreSQL база данни

  4. PostgreSQL unnest() с номер на елемент

  5. Как да получите текущата дата в PostgreSQL