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

PostgreSQL 13:Не позволявайте на слотове да убият основното ви

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

Производство на WAL

Както знаете, WAL се произвежда за промени в базата данни в основен сървър:вмъквания, актуализации и т.н. . По-активната база данни ще произведе повече WAL — в много активен сървър може да има много гигабайти WAL, произвеждани всяка минута. WAL се записва във файлове с имена в нарастваща числова последователност и файловете винаги са с еднакъв размер (16 MB е по подразбиране и е типично). След като данните във файл вече не са необходими, този файл може да бъде рециклиран , което означава да го преименувате на позиция с по-висок номер в последователността, за да може да бъде попълнена с нови данни по-късно.

(Има специални ситуации, като например нарастване на активността, което води до създаване на допълнителни файлове; когато по-късно нарастването отшуми, тези допълнителни файлове се премахват, вместо да се рециклират.)

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

Слотове за репликация

Репликацията в PostgreSQL работи чрез обработка на WAL файлове. За да работи това, всички WAL файлове трябва да са временно достъпни, докато не бъдат обработени. Следователно е необходим механизъм, който да каже на основното управление на WAL да не рециклира или премахва файлове.

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

Слотове за репликация сами по себе си заемат много малко дисково пространство. Те просто съхраняват малка част от метаданни, включително указател към позиция в WAL. Но WAL данните, които защитава, са друг въпрос:при силно активен сървър те могат да бъдат измерени в гигабайти или по-лошо.

Разход на WAL

Подаването на данни към физическа реплика означава копиране на WAL данните от основния сървър. По същия начин логическата реплика трябва да прочете WAL данни (и да предаде интерпретирана версия към репликата). Прочетената WAL позиция е това, което прорезът следи. След като репликата е осигурила WAL данните по някакъв начин, слотът може да бъде разширен; това казва на управлението на WAL в основния, че след това WAL файлът е достъпен за премахване. Това се случва непрекъснато, когато репликата е активна, така че WAL в основния сървър ще използва същото количество дисково пространство или може би само малко повече. Дори два пъти повече или десет пъти повече може да е приемливо, в зависимост от условията.

Проблемът е, че ако реплика умре напълно и не се възстанови за дълъг период от време; или репликата е унищожена и DBA забравя да премахне слота за репликация; или слотът е забравен остатък от някакъв експеримент; или дори репликата се подава през бавна мрежова връзка, тогава запазеният WAL ще расте без граници. И това се превръща в тиктакаща бомба.

Ограничаване на размера на слота

За да се бори с този проблем, Киотаро Хоригучи работеше от февруари 2017 г. в пач на PostgreSQL, за да ограничи размера на WAL, запазен от слот. След  много дълъг процес на преглед и преработка го интегрирах за PostgreSQL 13, като подобрих управлението на фермите на PostgreSQL с висока достъпност.

Основният принцип е, че е по-добре да убиете реплика (като по някакъв начин направите слота й невалиден; повече за това по-долу), отколкото да убиете основния сървър, който захранва тази реплика, и да премахнете цялата продукция с нея.

Начинът, по който работи е доста ясен:задайте max_slot_wal_keep_size (документация) в postgresql.conf до максималното количество дисково пространство на WAL, което слотовете за репликация могат да резервират. Ако слот достигне тази точка и възникне контролна точка, този слот ще бъде маркиран като невалиден и някои WAL файлове може да бъдат изтрити. Ако слотът е бил активно използван от walsender процес, този процес ще бъде сигнализиран, така че да приключи. Ако walsender стартира отново, той ще установи, че необходимите WAL файлове вече няма да са там. Репликата, използваща този слот, ще трябва да бъде повторно клонирана.

Ако max_slot_wal_keep_size е нула, което е стойността по подразбиране, тогава няма ограничение. Не препоръчвам това, защото води до неуспехи, когато слотове запълнят диска.

Наблюдение на здравето на слота

Включени са и някои функции за наблюдение. Две колони в pg_replication_slots са подходящи. Най-критичният е wal_status . Ако тази колона е reserved , тогава слотът сочи към данни в рамките на max_wal_size; ако е extended след това надхвърли max_wal_size , но все още е защитен от wal_keep_size или max_slot_wal_keep_size (включително когато max_slot_wal_keep_size е нула). И едното и другото състояние е добро и нормално. Въпреки това, когато слот надхвърли лимита, той първо става unreserved , което означава, че е в непосредствена опасност, но все пак може да се възстанови, ако е достатъчно бързо. Накрая състоянието става lost когато WAL файловете са премахнати и не е възможно възстановяване.

Другата колона е safe_wal_size :показва броя на байтовете на WAL, които могат да бъдат записани, преди този слот да изпадне в опасност от премахване на WAL файлове. Предлагаме да следите отблизо тази колона във вашата система за наблюдение и да предупреждавате, когато тя стане ниска. Нула или отрицателно означава, че репликата ви ще бъде мъртва веднага щом се появи контролна точка:

SELECT slot_name, active, wal_status, safe_wal_size
  FROM pg_catalog.pg_replication_slots;

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

(Забележка:safe_wal_size беше въведен в 13beta3, така че не забравяйте да прегледате актуалната документация или ще видите min_safe_lsn вместо. Игнорирайте това.)

Благодаря

Специални благодарности на Киотаро Хоригучи за работата по решаването на този проблем. Няколко рецензенти се задълбочиха в това, сред които бих искал да благодаря особено на Масахико Савада, Фуджи Масао, Жехан-Гийом де Рортаис и Амит Капила (без определен ред).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Postgres не използва индекс, когато сканирането на индекса е много по-добър вариант

  2. Как мога да генерирам уникален низ за запис в таблица в Postgres?

  3. Как да пишем с главни букви първата буква на всяка дума в PostgreSQL

  4. Подобрения в разделянето в PostgreSQL 11

  5. PostgreSQL - Писане на динамичен sql в съхранена процедура, която връща набор от резултати