Новата функция Hot Standby в предстоящия PostgreSQL 9.0 позволява стартиране на заявки срещу възли в режим на готовност, които преди това не са правили нищо, освен да изпълняват процес на възстановяване. Две общи очаквания, които чух от потребителите, които очакват тази функция, са, че тя ще позволи или разпределяне на кратки заявки в двата възела, или ще позволи да се изпълняват дълги отчети в режим на готовност, без да се използват ресурси на главния. И двете са възможни в момента, но освен ако не разберете компромисите, свързани с това как работи Hot Standby, тук може да има някакво неочаквано поведение.
Стандартни продължителни заявки
Един от традиционните проблеми в базата данни, използваща MVCC, като PostgreSQL, е, че продължително изпълняваната заявка трябва да поддържа отворен ресурс – наричан моментна снимка в текущата реализация на Postgres – за да попречи на базата данни да премахва данни, които заявката трябва да оперират. Например, само защото друг клиент е изтрил ред и е поел ангажимент, ако вече изпълнявана заявка се нуждае от този ред, за да завърши, всъщност все още не можете да изтриете физическите дискови блокове, свързани с този ред. Трябва да изчакате, докато все още няма отворени заявки, които очакват този ред да бъде видим.
Ограничения за горещ режим на готовност
Ако имате продължителна заявка, която искате да изпълни Hot Standby, има няколко вида лоши неща, които могат да се случат, когато процесът на възстановяване прилага актуализации. Те са описани подробно в документацията за горещ режим на готовност. Някои от тези лоши неща ще доведат до анулиране на заявки, изпълнявани в режим на готовност, поради причини, които може да не са интуитивно очевидни:
- Пристига ГОРЕЩА актуализация или свързана с VACUUM актуализация, за да изтриете нещо, което заявката очаква да бъде видима
- Появява се изтриване на B-дърво
- Има проблем със заключване между заявката, която изпълнявате, и какви заключвания са необходими, за да бъде обработена актуализацията.
Ситуацията със заключване е трудна за справяне, но е малко вероятно да се случи на практика за толкова дълго, ако просто изпълнявате заявки само за четене в режим на готовност, защото те ще бъдат изолирани чрез MVCC. Другите две не са трудни за блъскане. Основното нещо, което трябва да разберете, е, че всякакво UPDATE или DELETE на главната може да доведе до прекъсване на всяка заявка в режим на готовност; няма значение дали промените дори се отнасят до това, което прави заявката.
Добре, бързо, евтино:изберете две
По същество има три неща, които хората може да искат да дадат приоритет:
- Избягвайте ограничаването на главния:Разрешете xids и свързаните моментни снимки да се придвижват неограничено върху главния, така че VACUUM и подобно почистване да не се задържат от това, което прави режимът на готовност
- Неограничени заявки:Изпълнявайте заявки в режим на готовност за произволен период от време
- Текущо възстановяване:Поддържайте процеса на възстановяване в режим на готовност актуален с това, което се случва на главния, позволявайки бързо превключване при отказ за HA
Във всяка ситуация с Hot Standby е буквално невъзможно да имате и трите наведнъж. Можете да изберете само своя компромис. Наличните параметри за настройка вече ви позволяват да оптимизирате по няколко начина:
- Деактивирането на всички тези настройки за забавяне/отлагане оптимизира за винаги текущо възстановяване, но след това ще откриете, че е по-вероятно заявките да бъдат анулирани, отколкото бихте очаквали.
- max_standby_delay оптимизира за по-дълги заявки, за сметка на поддържането на текущото възстановяване. Това забавя прилагането на актуализации в режим на готовност, след като се появи такава, която ще причини проблем (ГОРЕЩО, ВАКУУМНО, изтриване на B-дърво и т.н.).
- vacuum_defer_cleanup_age и някои хакове за моментни снимки могат да въведат някои основни ограничения за подобряване на другите два проблема, но със слаб потребителски интерфейс за това. vacuum_defer_cleanup_age е в единици идентификатори на транзакции. Трябва да имате някаква представа за средното количество xid churn във вашата система за единица време, за да превърнете начина, по който хората мислят за този проблем („отложете с поне 1 час, за да се изпълнят моите отчети“) в настройка за тази стойност. Коефициентът на потребление на xid просто не е често срещано или дори разумно нещо за измерване/предсказване. Като алтернатива можете да отворите моментна снимка на основния, преди да стартирате продължителна заявка в режим на готовност. dblink се предлага в документацията за горещ режим на готовност като начин да се постигне това. Теоретично демон в режим на готовност може да бъде написан в потребителска земя, живеещ на първичния, за да заобиколи и този проблем (Саймън има основен дизайн за такъв). По принцип стартирате серия от процеси, всеки от които придобива моментна снимка и след това заспива за определен период от време, преди да я пуснете. Като разпределите колко дълго всеки от тях е спал, можете да гарантирате, че xid моментните снимки никога не се придвижват напред твърде бързо върху главния. Вече трябва да звучи очевидно колко ужасен хак би бил това.
Потенциални подобрения
Единственото от тях, с което наистина можете да направите нещо чисто, е да затегнете и подобрите потребителския интерфейс за основното ограничение. Това превръща това в традиционния проблем, който вече присъства в базата данни:продължителна заявка държи отворена моментна снимка (или поне ограничава напредъка на свързаните с видимостта идентификатори на транзакции) на главния, като не позволява на главния да премахне неща, необходими за тази заявка, за да завършен. Алтернативно можете да мислите за това като за автоматично настройване vacuum_defer_cleanup_age.
Въпросът е как да направите основното уважавайте нуждите от продължителни заявки в готовност . Това може да е възможно, ако повече информация за изискванията за видимост на транзакциите в режим на готовност беше споделена с главния. Правенето на такъв вид обмен наистина би било нещо по-подходящо за споделяне на новата реализация на поточно репликация. Начинът, по който е осигурен обикновен сървър с горещ режим на готовност, не предоставя никаква обратна връзка към главната, подходяща за обмен на тези данни, освен подходи като вече споменатия dblink хак.
С PostgreSQL 9.0 едва достига четвърта алфа версия, може да има все още е време да видите някои подобрения в тази област още преди изданието 9.0. Би било хубаво да видим Hot Standby и Streaming Replication наистина интегрирани заедно по начин, който постига неща, които нито един от тях не е напълно способен да направи самостоятелно, преди кодирането на тази версия напълно да замръзне.