В предишната част се осмелих да играя с нереализирана функция, фантазирайки как ще работи. Ами HA на първо място е въпрос на дизайн и едва след това изпълнение. Това не извинява лошото изпълнение, нито прави наивното проектиране да изглежда умно. И все пак, след като покриете всички възможни сценарии и намерите подходящо най-добро правило за повечето случаи, понякога много примитивна малка промяна може да разруши крепостта. По-долу искам пясъчна среда.
Какво се случва, когато pgpool трябва да премине при отказ, но не може?
Когато проверката на здравето е неуспешна за главния, командата failover_command се задейства, за да дегенерира всички или да повиши следващия подчинен в първичен. Звучи солидно. Какво ще стане, ако той се провали, например ssh връзката се провали (например защото други - лош администратор премахва ключа от ~/.ssh/authorized_keys). Какво имаме?
Веднага след като health_check_timeout (по подразбиране 20) изтече (също повлияно от забавяне на повторния опит, максимум се оттегля и т.н.), възелът става мъртъв, така че:
t=# select nid,port,st from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
nid | port | st
-----+------+------
0 | 5400 | down
1 | 5401 | up
2 | 5402 | up
(3 rows)
Така че не са останали повторни опити и преодоляването на отказ е неуспешно. Първата опция очевидно е извършване на отказ ръчно. Но ако преодоляването на срив се провали поради някаква глупава грешка, master отново е на релси и единственият проблем, който имате, е pgpool да мисли, че главният е офлайн - вероятно бихте искали да оставите нещата така, както са били преди инцидента - нали? Разбира се, само преместването на господаря обратно онлайн не е достатъчно. Pgpool вече „дегенерира“ първичния. Просто добавянето му като нов възел също няма да помогне. Най-лошото е, че след събитието pgpool няма да се опита да провери дали старият хозяин е pg_is_in_recovery() или не, така че никога няма да го приеме като първичен. Според проследяването на грешки трябва да „Изхвърлете файла pgpool_status и да не възстановявате предишното състояние“ с командата pgpool -D.
След като изхвърлим състоянието, ние се свързваме отново, за да избегнем да видим сървъра да затвори връзката неочаквано и да стартираме:
t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
nid | port | st | role
-----+------+----+---------
0 | 5400 | up | primary
1 | 5401 | up | standby
2 | 5402 | up | standby
(3 rows)
Всички възли са архивирани и работят, pgpool разпознава главния.
Накрая искам да покрия някои съвети и наблюдения относно използването на pgpool:
-
Промяната на настройките на бекенда е малко трудна:име на хост, порт и директория изискват презареждане за добавяне на нови възли, но изискват рестартиране за редактиране на съществуващи. Докато теглото и флагът могат да се променят само с презареждане.
-
Не бъркайте стойностите на колоната load_balance_node с конфигурацията. Ако видите само един възел с истина, това не е просто ОК - така е предвидено. Това не означава, че имате само един възел в балансиращ пул - той просто показва кой възел е избран за тази конкретна сесия. По-долу е резултатът от заявката с всичките три възела, участващи в балансиране на оператори SELECT, с избран идентификатор на възел 2:
t=# show pool_nodes; node_id | hostname | port | status | lb_weight | role | select_cnt | load_balance_node | replication_delay ---------+-----------+------+--------+-----------+---------+------------+-------------------+------------------- 0 | localhost | 5400 | up | 0.125000 | primary | 61 | false | 0 1 | localhost | 5401 | up | 0.312500 | standby | 8 | false | 0 2 | localhost | 5402 | up | 0.562500 | standby | 11 | true | 0 (3 rows)
-
Можете да проверите кой възел е избран за балансиране на натоварването с show pool_nodes, но ви е грижа да го знаете за вашата заявка, а не за "покажи", така че такава проверка не винаги е достатъчно информативна. Е, можете да наблюдавате кой възел използвате за текущата заявка, с нещо като:
t=# select *,current_setting('port') from now(); now | current_setting -------------------------------+----------------- 2018-04-09 13:56:17.501779+01 | 5401 (1 row)
Важно! Но не:
t=# select now, setting from now() join pg_settings on name='port';
now | setting
-----------------------------+---------
2018-04-09 13:57:17.5229+01 | 5400
(1 row)
Тъй като ВИНАГИ ще връща главния порт. Същото важи за всеки pg_catalog SELECT.
-
Както забелязахте в предишните части, използвам по-сложен начин, отколкото просто да покажа pool_nodes за изброяване на възли със състояние. Правя го умишлено, за да демонстрирам как можете да направите резултата управляем. Използването на where прави заявката по-дълга, но резултатът е ясен, пропускайки всичко, което отвлича вниманието за нашата конкретна задача. Сравнете:
t=# select nid,port,st,role from dblink('host=localhost port=5433','show pool_nodes') as t (nid int,hostname text,port int,st text,lb_weight float,role text,cnt int,cur_node text,del int);
nid | port | st | role
-----+------+----+---------
0 | 5400 | up | primary
1 | 5401 | up | standby
2 | 5402 | up | standby
С изхода на първоначалното шоу pool_nodes...
-
Не можете да сравнявате pgbouncer и pgpool. Но ако го направите, най-важното е да знаете, че синтактичният анализ на заявките в pgpool зависи от версията на pg. Така че, когато надграждате postgreSQL, трябва да надстроите и pgpool, докато един екземпляр на pgbouncer може да има конфигурация за 8,9,10 различни клъстера в един и същ ini файл.
-
Защо не мога да използвам само скрипт за преодоляване на срив вместо pgpool? Можеш. Но pgpool го предлага ЗАЕДНО с memcached и обединяване на връзки, балансиране и разделен мозъчен контрол и се проверява от десетилетия на употреба.
-
Системата за проследяване на грешки е на мястото си - струва си да я посетите, ако работите с pgpool:https://www.pgpool.net/mantisbt/my_view_page.php
-
Множество печатни грешки в документацията, като bakance (backend + баланс?..), statemnet, разрешено или несъответствие между версията (pool_nodes преди беше int, а сега са enum, но връзката към старите стойности в pcp_node-info все още е там) развалят впечатлението на този прекрасен продукт. Формуляр за изпращане на доклада за открит „бъг“ в документацията (точно като „изпращане на корекция“ в postgres документи) обаче би го подобрил значително.
-
Важен съвет: преди да разчитате на която и да е стъпка - проверете я. напр. след популяризиране на възел не можете да го популяризирате повторно (тук популяризирането не е операция postgres, а по-скоро регистрация на възела като главен за pgpool):
[email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1 pcp_promote_node -- Command Successful [email protected]:~# sudo -u postgres pcp_promote_node -w -h 127.0.0.1 -U vao -n 1 FATAL: invalid pgpool mode for process recovery request DETAIL: specified node is already primary node, can't promote node id 1
Звучи логично и изглежда страхотно. И все пак, ако стартирате това срещу грешен възел (напр. възел 0 е ! pg_is_in_recovery):
[email protected]:~# for i in $(seq 1 3); do pcp_promote_node -w -h 127.0.0.1 -U vao -n 0; echo $?; done
pcp_promote_node -- Command Successful
0
pcp_promote_node -- Command Successful
0
pcp_promote_node -- Command Successful
0
Което е лошо, защото не можете да популяризирате възел отново и да очаквате грешка, но получавате състояние на изход 0...
Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книгаВажен съвет:Не играйте твърде много. Никога не играйте на prod!
Играейки с recovery_1st_stage_command, използвайки pg_rewind, реших да опитам от любопитство друг хак на маймуна - запитване на pgpool_recovery() без аргументи (тъй като така или иначе ги игнорирам в моята настройка) и след това просто се опитвам да прикача възела към pgpool:
[email protected]:~# psql -p 5433 -h localhost template1 -c "SELECT pgpool_recovery('or_1st.sh', '', '', '')"
pgpool_recovery
-----------------
t
(1 row)
[email protected]:~# pcp_attach_node -h 127.0.0.1 -U vao -w -n 1
pcp_attach_node -- Command Successful
Тази глупава идея ме доведе до:
[email protected]:~# ps -aef | grep pgpool
postgres 15227 1 0 11:22 ? 00:00:00 pgpool -D
postgres 15240 15227 0 11:22 ? 00:00:00 pgpool: health check process(0)
postgres 15241 15227 0 11:22 ? 00:00:00 pgpool: health check process(1)
postgres 15242 15227 0 11:22 ? 00:00:00 pgpool: health check process(2)
postgres 15648 15227 0 11:24 ? 00:00:00 [pgpool] <defunct>
postgres 16264 15227 0 11:26 ? 00:00:00 pgpool: PCP: wait for connection request
postgres 16266 15227 0 11:26 ? 00:00:00 [pgpool] <defunct>
postgres 16506 16264 0 11:26 ? 00:00:00 pgpool: PCP: processing recovery request
postgres 16560 15227 0 11:26 ? 00:00:00 [pgpool] <defunct>
postgres 16835 15227 0 11:26 ? 00:00:00 [pgpool] <defunct>
postgres 16836 15227 0 11:26 ? 00:00:00 [pgpool] <defunct>
Нямам бягство, трябва да:
[email protected]:~# kill -9
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.5433
[email protected]:~# rm /var/run/pgpoolql/.s.PGSQL.9898
Над 5433 е pgpool порт, а 9898 е pcp порт. Очевидно след срива файловете не се почистват, така че трябва да го направите ръчно.
- Прочетете внимателно и играйте много, преди да пуснете pgpool в производство. Много по-трудно е да се намери помощ с pgpool, отколкото самия postgres. Някои въпроси никога не получават отговор. Особено когато ме попитаха на грешно място (отговорих на правилното място, за да получа отговора)...
- Не забравяйте най-новата времева линия за каскадна репликация (не всъщност подсказката за pgpool, но често хората не разбират, че за да вземете нов главен файл, не е достатъчно да посочите правилната крайна точка за приемника).
- Архитектура с диаграма може да бъде намерена тук.
Заключение
След 10 години се появиха нови обещаващи функции (watchdog и виртуален ip) и важни поправки (напр. serialize_accept), но като цяло оставя подценено впечатление. Документите имат правописни грешки, които живеят там от 10 години. Не вярвам, че никой не чете документите. Не вярвам никой да не е забелязал. Просто не можете да ги докладвате по никакъв лесен начин. Има много заредени и подготвени оръжия, които лежат на сайта за документация, за да може начинаещият потребител да вземе, да насочи към крака и да дръпне спусъка. Нямам разумна идея как да го подобря - просто предупреждавам стрелците. Погрешното тълкуване на един параметър може да ви постави в отчаяна позиция на обратното инженерство, за да откриете грешката си. През всичките тези години pgpool беше и си остава вид продукт за напреднали потребители. Четейки документация, не можах да се сдържа да не си спомня стария руски виц за Шерлок Холмс:Шерлок и Уотсън летят на балона. Изведнъж силният вятър ги отвява на хиляди мили. Когато могат да кацнат, виждат момичето да пасе овце. Холмс пита момичето:"Скъпа, къде сме ние?" и момичето отговаря „Вие сте на балона!“. Шерлок благодари и докато излитат казва „Вятърът ни отведе много далеч – ние сме в Русия“. — Но откъде знаеш? — пита Уотсън. „Очевидно е – само в Русия кодери пасат овце“, отговаря Шерлок. — Но откъде знаеш, че момичето е кодер? - „Очевидно е – тя ни даде абсолютно точен и напълно безполезен отговор.“