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

Използване на слотове за репликация на PostgreSQL

Какво представляват слотове за репликация?

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

LOG:  started streaming WAL from primary at 0/73000000 on timeline 1

FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment 000000010000000000000073 has already been removed

Типичният подход е да посочите във вашия postgresql.conf WAL архивен скрипт, който ще копира WAL файлове в едно или повече места за дългосрочни архиви. Ако нямате резерви или други клиенти за стрийминг репликация, тогава по принцип сървърът може да изхвърли WAL файла, след като архивният скрипт приключи или отговори ОК. Но все пак ще ви трябват някои скорошни WAL файлове за възстановяване при срив (данните от последните WAL файлове се възпроизвеждат по време на възстановяване при срив. В нашия пример за резервен възел, който е поставен за дълъг период на поддръжка, възникват проблеми, когато се върне онлайн и пита основният за WAL файл, който основният вече няма, тогава репликацията е неуспешна.

Този проблем беше адресиран в PostgreSQL 9.4 чрез "Репликационни слотове".

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

Алтернативните подходи за неизползване на слотове за репликация е да конфигурирате PostgreSQL с непрекъснато архивиране и да предоставите restore_command, за да предоставите на репликата достъп до архива. За да избегнете натрупване на WAL на основния, можете да използвате отделен том или устройство за съхранение за WAL файловете, например SAN или NFS. Друго нещо е със синхронната репликация, тъй като тя изисква първичният трябва да изчака резервните възли да завършат транзакцията. Това означава, че гарантира, че WAL файловете са били приложени към възлите в режим на готовност. Но все пак е най-добре да предоставите команди за архивиране от основния, така че след като WAL са рециклирани в основния, бъдете сигурни, че имате резервни копия на WAL в случай на възстановяване. Въпреки че в някои ситуации синхронната репликация не е идеално решение, тъй като идва с някои допълнителни разходи в сравнение с асинхронната репликация.

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

Има два типа слотове за репликация. Това са:

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

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

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

Логическата репликация прави същото като слотовете за физическа репликация и се използват за логическа репликация. Те обаче се използват за логическо декодиране. Идеята зад логическото декодиране е да се даде възможност на потребителите да се прикачат към регистъра на транзакциите и да го декодират с плъгин. Позволява извличане на промени, направени в базата данни и следователно в регистъра на транзакциите във всякакъв формат и за всякакви цели.

В този блог ще използваме слотове за физическа репликация и как да постигнем това с помощта на ClusterControl.

Предимства и недостатъци на използването на слотове за репликация

Слотовете за репликации определено са полезни, след като са активирани. По подразбиране „слотовете за репликация“ не са активирани и трябва да бъдат зададени  ръчно. Сред предимствата на използването на слотове за репликация са

  • Гарантира, че главният запазва достатъчно WAL сегменти, за да могат всички реплики да ги получат
  • Предотвратява главната програма да премахва редове, които биха могли да причинят конфликт при възстановяване на репликите
  • Главният може да рециклира регистрационния файл на транзакциите само след като бъде използван от всички реплики. Предимството тук е, че робът никога не може да изостане толкова много, че да е необходимо повторно синхронизиране.

Слотове за репликация също идват с някои предупреждения.

  • Осиротяла репликация слот може да причини неограничен растеж на диска поради натрупани WAL файлове от главния
  • Подчинените възли, поставени на продължителна поддръжка (като дни или седмици) и които са свързани със слот за репликация, ще имат неограничен растеж на диска поради натрупаните WAL файлове от главния

Можете да наблюдавате това, като потърсите pg_replication_slots, за да определите слотове, които не се използват. Ще проверим отново това малко по-късно.

Използване на слотове за репликация 

Както беше посочено по-рано, има два типа слотове за репликация. За този блог ще използваме физически слотове за репликация за поточно репликация.

Създаване на слот за репликация

Създаването на репликация е лесно. Трябва да извикате съществуващата функция pg_create_physical_replication_slot, за да направите това и трябва да бъде стартирана и създадена в главния възел. Функцията е проста,

maximus_db=# \df pg_create_physical_replication_slot

Schema              | pg_catalog

Name                | pg_create_physical_replication_slot

Result data type    | record

Argument data types | slot_name name, immediately_reserve boolean DEFAULT false, OUT slot_name name, OUT xlog_position pg_lsn

Type                | normal

напр. Създаване на слот за репликация с име slot1,

postgres=# SELECT pg_create_physical_replication_slot('slot1');

-[ RECORD 1 ]-----------------------+---------

pg_create_physical_replication_slot | (slot1,)

Имената на слотовете за репликация и тяхната основна конфигурация са само за цялата система, а не за целия клъстер. Например, ако имате nodeA (текущ главен) и възли в готовност nodeB и nodeC, създавайки слота на главен възел A, а именно "slot1", тогава данните няма да бъдат достъпни за nodeB и nodeC. Следователно, когато предстои преминаване/превключване при отказ, трябва да създадете отново слотовете, които сте създали.

Изпускане на слот за репликация

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

maximus_db=# \df pg_drop_replication_slot

Schema              | pg_catalog

Name                | pg_drop_replication_slot

Result data type    | void

Argument data types | name

Type                | normal

Изтриването е лесно:

maximus_db=# select pg_drop_replication_slot('slot2');

-[ RECORD 1 ]------------+-

pg_drop_replication_slot |

Наблюдение на вашите слотове за репликация на PostgreSQL

Наблюдението на вашите слотове за репликация е нещо, което не искате да пропуснете. Просто съберете информацията от view pg_replication_slots в основния/главния възел точно както по-долу:

postgres=# select * from pg_replication_slots;

-[ RECORD 1 ]-------+-----------

slot_name           | main_slot

plugin              |

slot_type           | physical

datoid              |

database            |

active              | t

active_pid          | 16297

xmin                |

catalog_xmin        |

restart_lsn         | 2/F4000108

confirmed_flush_lsn |

-[ RECORD 2 ]-------+-----------

slot_name           | main_slot2

plugin              |

slot_type           | physical

datoid              |

database            |

active              | f

active_pid          |

xmin                |

catalog_xmin        |

restart_lsn         |

confirmed_flush_lsn |

Горният резултат показва, че main_slot е зает, но не и main_slot2.

Друго нещо, което можете да направите, е да следите колко изостават от слотовете, които имате. За да постигнете това, можете просто да използвате заявката въз основа на примерния резултат по-долу:

postgres=# SELECT redo_lsn, slot_name,restart_lsn, 

round((redo_lsn-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

redo_lsn    | slot_name | restart_lsn | gb_behind 

------------+-----------+-------------+-----------

 1/8D400238 |     slot1 | 0/9A000000 | 3.80

Но redo_lsn не присъства в 9.6, ще използва redo_location, така че в 9.6,

imbd=# SELECT redo_location, slot_name,restart_lsn, 

round((redo_location-restart_lsn) / 1024 / 1024 / 1024, 2) AS GB_behind 

FROM pg_control_checkpoint(), pg_replication_slots;

-[ RECORD 1 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

-[ RECORD 2 ]-+-----------

redo_location | 2/F6008BE0

slot_name     | main_slot2

restart_lsn   | 2/F6008CC0

gb_behind     | 0.00

Изисквания за системни променливи

Внедряването на слотове за репликация изисква ръчна настройка. Има променливи, които трябва да имате предвид, които изискват промени и да бъдат посочени във вашия postgresql.conf. Вижте по-долу:

  • max_replication_slots – Ако е зададено на 0, това означава, че слотове за репликация са напълно забранени. Ако използвате PostgreSQL <10 версии, този слот трябва да бъде посочен различен от 0 (по подразбиране). От PostgreSQL 10, по подразбиране е 10. Тази променлива определя максималния брой слотове за репликация. Задаването му на по-ниска стойност от броя на съществуващите в момента слотове за репликация ще попречи на сървъра да стартира.
  • wal_level – трябва да бъде поне реплика или по-висока (репликата е по подразбиране). Настройката на hot_standby или архив ще се преобразува в реплика. За слот за физическа репликация, репликата е достатъчна. За логически слотове за репликация се предпочита логическият.
  • max_wal_senders – зададено на 10 по подразбиране, 0 във версия 9.6, което означава, че репликацията е деактивирана. Предлагаме ви да зададете това поне на 16, особено когато работите с ClusterControl.
  • hot_standby – във версии <10, трябва да зададете това на включено, което е изключено по подразбиране. Това е важно за възли в режим на готовност, което означава, че когато е включено, можете да се свързвате и да изпълнявате заявки по време на възстановяване или в режим на готовност.
  • primary_slot_name –  тази променлива се задава чрез recovery.conf на възела в режим на готовност. Това е слотът, който трябва да се използва от получателя или възела в режим на готовност, когато се свързва с подателя (или основния/главния).

Трябва да вземете под внимание, че тези променливи най-вече изискват рестартиране на услугата за база данни, за да се презаредят нови стойности.

Използване на слотове за репликация в ClusterControl PostgreSQL среда

Сега нека да видим как можем да използваме слотове за физическа репликация и да ги внедрим в настройка на Postgres, управлявана от ClusterControl.

Разгръщане на възли на базата данни PostgreSQL

Нека започнем да внедряваме PostgreSQL клъстер с 3 възела, като използваме ClusterControl, използвайки версия на PostgreSQL 9.6 този път.

ClusterControl ще разгърне възли със следните системни променливи, дефинирани съответно въз основа на техните настройки по подразбиране или настроени стойности. В:

postgres=# select name, setting from pg_settings where name in ('max_replication_slots', 'wal_level', 'max_wal_senders', 'hot_standby');

         name          | setting 

-----------------------+---------

 hot_standby           | on

 max_replication_slots | 0

 max_wal_senders       | 16

 wal_level             | replica

(4 rows)

Във версии на PostgreSQL> 9.6 стойността по подразбиране на max_replication_slots е 10, която е активирана по подразбиране, но не и в 9.6 или по-ниски версии, която е деактивирана по подразбиране. Трябва да зададете max_replication_slots по-високо от 0. В този пример зададох max_replication_slots на 5.

[email protected]:~# grep 'max_replication_slots' /etc/postgresql/9.6/main/postgresql.conf 

# max_replication_slots = 0                     # max number of replication slots

max_replication_slots = 5

и рестартира услугата,

[email protected]:~# pg_lsclusters 

Ver Cluster Port Status Owner    Data directory Log file

9.6 main    5432 online postgres /var/lib/postgresql/9.6/main pg_log/postgresql-%Y-%m-%d_%H%M%S.log



[email protected]:~# pg_ctlcluster 9.6 main restart

Задаване на слотове за репликация за първични и резервни възли

В ClusterControl няма опция за това, така че трябва да създадете своите слотове ръчно. В този пример създадох слотове в първичния хост 192.168.30.100:

192.168.10.100:5432 [email protected]_db=# SELECT pg_create_physical_replication_slot('slot1'), pg_create_physical_replication_slot('slot2');

 pg_create_physical_replication_slot | pg_create_physical_replication_slot 

-------------------------------------+-------------------------------------

 (slot1,)                            | (slot2,)

(1 row)

Проверка на това, което току-що създадохме показва,

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | f      | | |       | | 

 slot2     | | physical  | | | f      | | |       | | 

(2 rows)

Сега в възлите в режим на готовност трябва да актуализираме recovery.conf и да добавим променливата primary_slot_name и да променим името на приложението, така че да е по-лесно да идентифицираме възела. Ето как изглежда в хост 192.168.30.110 recovery.conf: 

[email protected]:/var/lib/postgresql/9.6/main/pg_log# cat ../recovery.conf 

standby_mode = 'on'

primary_conninfo = 'application_name=node11 host=192.168.30.100 port=5432 user=cmon_replication password=m8rLmZxyn23Lc2Rk'

recovery_target_timeline = 'latest'

primary_slot_name = 'slot1'

trigger_file = '/tmp/failover_5432.trigger'

Прави същото нещо и в хост 192.168.30.120, но промени името_на_приложение и зададе основното_име_слота ='slot2'.

Проверка на здравето на слота за репликация:

192.168.10.100:5432 [email protected]_db=# select * from pg_replication_slots;

 slot_name | plugin | slot_type | datoid | database | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn 

-----------+--------+-----------+--------+----------+--------+------------+------+--------------+-------------+---------------------

 slot1     | | physical  | | | t      | 24252 | |       | 0/CF0A4218 | 

 slot2     | | physical  | | | t      | 11635 | |       | 0/CF0A4218 | 

(2 rows)

Какво друго ви трябва?

Тъй като ClusterControl не поддържа репликационни слотове от този момент, има неща, които трябва да вземете предвид. Какви са тези? Да отидем в подробности.

Процес на отказ/превключване

Когато е направен опит за автоматично превключване или превключване чрез ClusterControl, слотове няма да бъдат задържани от първичните и от резервните възли. Трябва да създадете отново това ръчно, да проверите променливите дали са зададени правилно и съответно да промените recovery.conf.

Възстановяване на подчинен от главен

При повторно изграждане на подчинен файл recovery.conf няма да бъде запазен. Това означава, че вашите настройки за recovery.conf, които имат основното_слот_име, ще бъдат изтрити. Трябва да зададете това ръчно отново и да проверите изгледа pg_replication_slots, за да определите дали слотове се използват правилно или са оставени сираци.

Ако искате да изградите отново подчинения/готовия възел от главен, може да се наложи да обмислите да посочите променливата PGAPPNAME env точно като командата по-долу:

$ export PGAPPNAME="app_repl_testnode15"; /usr/pgsql-9.6/bin/pg_basebackup -h 192.168.10.190 -U cmon_replication -D /var/lib/pgsql/9.6/data -p5434 -W -S main_slot -X s -R -P

Уточняването на параметъра -R е много важно, така че ще създаде повторно recovery.conf, докато -S ще укаже името на слота да се използва при възстановяване на възела в режим на готовност.

Заключение

Внедряването на слотове за репликация в PostgreSQL е лесно, но има някои предупреждения, които трябва да запомните. Когато внедрявате с ClusterControl, ще трябва да актуализирате някои настройки по време на преодоляване на отказ или повторно изграждане на подчинен.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Escape функция за регулярен израз или модели LIKE

  2. Стимулиране на производителността за PostgreSQL с HAProxy

  3. Защо функциите PL/pgSQL могат да имат страничен ефект, докато SQL функциите не могат?

  4. SQLAlchemy - SQLite за тестване и Postgresql за разработка - Как да пренасям?

  5. Как да изброя индекси, създадени за таблица в postgres