Postgres идва с функции за физическа и логическа репликация. Прочетете, за да научите повече за различни аспекти на физическата репликация.
Физическа репликация
Методите за физическа репликация се използват за поддържане на пълно копие на всички данни от един клъстер (в Postgres, клъстер е набор от бази данни, управлявани от един главен процес на Postgres сървър, наречен postmaster ), обикновено на друга машина. Изходната машина се нарича основна на жаргон на Postgres, а дестинацията се нарича готовност .
Горещ, топъл и „студен“ режим на готовност
Резервен сървър, който се поддържа възможно най-актуален с основния в реално време и позволява на клиентите да изпълняват транзакции само за четене, се наричагорещ режим на готовност или по-популярно реплика за четене . Горещи режими на готовност бяха добавени към Postgres във версия 9, преди която имаше само топли готовност. Топъл режим на готовност е подобен на горещ режим на готовност, с изключение на това, че не позволява на клиентите да се свързват с него.
(Отстрани:Hot standbys не могат да изпълняват заявки, които създават временни таблици. Това е ограничение на Postgres.)
„Студен” режим на готовност (не е официален термин) обикновено е сървър в режим на готовност, който не стартира до преминаване на отказ. Тъй като студеният режим на готовност не работи и не работи, възможно е при стартиране първо да се наложи да приложи изчакващи промени, преди да започне да приема клиентски връзки.
WAL файлове
При нормалния ход на операциите, PostgreSQL сървър генерира подредена серия от WAL (записване напред дневник) записи. Това са основно дневник на промените, подобно на AOF на Redis или binlog на MySQL. В основата си физическата репликация е транспортирането на тези записи към друга машина и привличането на другия пощенски администратор, който работи там, да приеме и приложи тези записи в своята локална база данни.
WAL записите се разделят на файлове с еднакъв размер (обикновено 16MB), наречениWAL сегменти или просто WAL файлове . Тези файлове се създават в директория, наречена pg_wal
под директорията с данни на клъстера (pg_wal
беше наречен pg_xlog
във версии на Postgres преди 10). Старите WAL файлове се изхвърлят, когато вече не са необходими (и също въз основа на няколко конфигурационни параметъра).
Режим на възстановяване
Postmaster може да се стартира в режим, наречен режим на възстановяване , като поставите валиден конфигурационен файл, наречен recovery.conf в директорията с данни на клъстера. В режим на възстановяване, Postgres ще импортира и прилага само WAL файлове, генерирани от първичния сървър, и сам по себе си няма да генерира никакви WAL файлове. Сървърите за топъл и горещ режим на готовност работят в режим на възстановяване.
Когато се стартира в режим на възстановяване, Postgres първо ще се опита да импортира всички WAL файлове, налични в архив (повече за това по-долу). Когато архивът няма повече WAL файлове за предлагане, той се опитва да импортира всички файлове, разположени около pg_wal
на init директория. Когато и те са готови, ако основната връзка е конфигурирана и standby_modeset на on
в recovery.conf, Postgres ще се свърже с основния и ще изтегли и приложи нови WAL записи, когато бъдат създадени в основния.
Изпращане на дневници
Представете си, че имате тригер, който ще се извиква на основния сървър всеки път, когато се създаде нов WAL файл. След това този тригер може да копира новия WAL файл на друга машина, като се каже rsync
и го поставете в pg_wal
директория на постмайстор, работещ в режим на възстановяване. Можете ли да направите такъв режим на готовност?
Отговорът е да и наистина това беше стандартната практика преди стрийминг репликацията да бъде добавена в Postgres v9. Тази практика се нарича доставка на дневници .
Тригерът е шел скрипт, който може да се конфигурира с помощта на archive_command. Името и пътят на WAL файла могат да бъдат предадени на скрипта.
Архивиране на WAL
Вместо rsync-ing върху WAL файла, да кажем, че го копираме в S3 bucketor, NFS-монтирана директория, която е достъпна и от машината в режим на готовност. Това споделено местоположение вече ще съдържа всички WAL файлове, генерирани от основния. Това сега става архив , а процесът на съхраняване на WAL файлове в архива се нарича непрекъснато архивиране или просто WAL архивиране .
Обратната на тази операция – извличане на WAL файлове от архива в Postgres в режим на възстановяване – може да се конфигурира с помощта на restore_command. Подобно на archive_command
, това също е пътят към шел скрипт. Пощенският администратор, работещ в режим на възстановяване, знае кой WAL файл иска. Името на файла може да бъде предадено на скрипта.
Като пример, ето командите за архивиране и възстановяване за съхранение и извличане на WAL файлове към и от кофа S3:
archive_command = 's3cmd put %p s3://BUCKET/path/%f' # in postgresql.conf
restore_command = 's3cmd get s3://BUCKET/path/%f %p' # in recovery.conf
При стартиране в режим на възстановяване, ако restore_command
е конфигуриран, Postgres първо ще опита да извлече WAL файлове от архива.
pg_standby
В режим на възстановяване Postgres не знае и не може да знае предварително колко WAL файла са генерирани досега. Ако командата restore_command е конфигурирана, Postgreswill многократно ще я извиква с прогресивни имена на WAL файлове (имената са в предвидима последователност), докато командата върне грешка.
Например, командата за възстановяване успя да удовлетвори заявките за WAL файлове000000010000000000000001
чрез 00000001000000000000001A
но не успява за00000001000000000000001B
тъй като не е намерен в местоположението на архива. При липса на WAL файлове от други източници, Postgres ще приеме, че WALfile 00000001000000000000001B
тепърва ще се генерира от основния и ще завърши възстановяването след прилагане на 00000001000000000000001A
.
Помислете какво се случва, ако командата за възстановяване изчака файла00000001000000000000001B
да бъде наличен, вместо да излезете с грешка, тъй като не е намерен. Postgres ще продължи да чака команда за възстановяване и следователно ще продължи да бъде в режим на възстановяване.
Това е валидна конфигурация и валиден начин за настройка на топъл режим на готовност.
Postgres се доставя с команда, наречена pg_standby, която може да се използва за настройка на топъл режим на готовност по този начин, стига архивът да е директория.pg_standby
ще изчака файлът да стане достъпен, ако не може да бъде намерен.
Командите за архивиране и възстановяване с помощта на pg_standby ще изглеждат така:
archive_command = 'cp %p /some/path/%f' # in postgresql.conf
restore_command = 'pg_standby /some/path %f %p' # in recovery.conf
Поточно репликация
След обработка на архивирани WAL файлове, както и файлове в pg_wal
директория, Postgres може да се свърже с основен сървър през мрежата и многократно да извлича и прилага нови WAL файлове, когато са създадени. Тази функция, добавена в Postgres 9, се нарича поточно репликация .
Основният сървър за свързване може да бъде посочен във файла recovery.conf:
# recovery.conf
standby_mode = on
primary_conninfo = 'host=10.0.1.10 user=repl password=p@ssw0rd'
Горещ режим на готовност
По подразбиране, когато е в режим на възстановяване, Postgres няма да приема клиентски връзки, като ги отхвърля със съобщения за грешка „системата на базата данни е в режим на възстановяване“. Като добавите реда hot_standby = on
в recovery.conf, можете да направите Postgresaccept клиентски връзки и да им позволите да изпълняват транзакции само за четене:
# recovery.conf
hot_standby = on
Обикновено няма причина да изключвате hot_standby.
Документът PostgreSQL съдържа повече информация за настройката и стартирането на режим на готовност в режим „горещ режим на готовност“.
Слотове за репликация
Слотовете за репликация бяха въведени в Postgres 9.4. Те са механизъм, който точно и трайно следи колко далеч изостава режимът на готовност от основния. Това позволява на основния да гарантира, че WAL файловете, които все още са необходими за наваксване на режима на готовност, няма да бъдат изтрити.
Преди слотове за репликация, не беше възможно първичният да определи това и ще се окажете в ситуации, в които режимът на готовност е оставен в затруднено положение, защото WAL файлът, от който се нуждае, е бил изтрит от основния. Разбира се, WAL архивите могат да решат този проблем. Без WAL архив обаче единствената възможност беше да възстановите режима на готовност от нов архив.
Можете да прочетете повече за слотовете за репликация тук.
Стъпки за настройка на горещ режим на готовност
Нека да разгледаме стъпките, необходими за настройка на горещ режим на готовност за съществуващ първичен.
1. Създаване на потребител за репликация
Първо, имаме нужда от потребител, за да се свърже в режим на готовност като:
$ psql -p 6000
psql (11.2 (Debian 11.2-1.pgdg90+1))
Type "help" for help.
postgres=# CREATE USER repluser REPLICATION PASSWORD 'p@ssw0rd';
CREATE USER
И съответните промени в pg_hba.conf
:
# TYPE DATABASE USER ADDRESS METHOD
host replication repluser standby-ip/32 md5
# (replace standby-ip)
Разбира се, можете да използвате всеки стандартен механизъм за удостоверяване на PostgreSQL. Потребителят трябва да има привилегии за репликация и влизане и не изисква достъп до конкретна база данни.
Не забравяйте да презаредите основния сървър, за да влязат в сила промените в pg_hba.conf.
2. Направете резервно копие
Режимът на готовност трябва да започне от резервно копие на основния. Можете и трябва да направите това с помощта на pg_basebackup
с нов слот за репликация:
pg_basebackup -h primary-ip -p 6000 -U repluser -C -S slot_standby1 -R -D standby
Това се свързва с основния на primary-ip:6000
с потребителя, който току-що създадохме, и прави негово резервно копие в директорията standby
. Нов слот за репликацияslot_standby1
е създаден.
3. Добавете recovery.conf в режим на готовност
Ще използваме този слот като наш слот за репликация в режим на готовност, така че да има приемственост от резервното копие.
Попитахме pg_basebackup
за да създадете recovery.conf
за нас по-горе (опция „-R“). Нека да разгледаме това:
$ cat standby/recovery.conf
standby_mode = 'on'
primary_conninfo = 'user=repluser password=''p@ssw0rd'' host=primary-ip port=6000 sslmode=prefer sslcompression=0 krbsrvname=postgres target_session_attrs=any'
primary_slot_name = 'slot_standby1'
Това всъщност е доста добре и не е нужно да го променяме допълнително. Нека просто изведем режима на готовност сега:
o$ pg_ctl -D standby -l log_standby -o --port=6001 start
waiting for server to start.... done
server started
postgres@stg1:/tmp/demo$ cat log_standby
2019-06-19 09:17:50.032 UTC [21733] LOG: listening on IPv4 address "127.0.0.1", port 6001
2019-06-19 09:17:50.034 UTC [21733] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.6001"
2019-06-19 09:17:50.067 UTC [21734] LOG: database system was interrupted; last known up at 2019-06-19 09:12:05 UTC
2019-06-19 09:17:50.111 UTC [21734] LOG: entering standby mode
2019-06-19 09:17:50.119 UTC [21734] LOG: redo starts at 0/2000028
2019-06-19 09:17:50.120 UTC [21734] LOG: consistent recovery state reached at 0/20000F8
2019-06-19 09:17:50.120 UTC [21733] LOG: database system is ready to accept read only connections
2019-06-19 09:17:50.138 UTC [21739] LOG: started streaming WAL from primary at 0/3000000 on timeline 1
И това е! Регистрационният файл показва, че стрийминг репликацията се изпълнява и работи. Вече трябва да можете да се свързвате към режим на готовност на порт 6001, да изпълнявате заявки само за четене и да виждате как промените се репликират от основния повече или по-малко в реално време.
Следващи стъпки
PostgreSQLdocs са чудесно място да започнете да ровите по-нататък във всички свързани с репликацията функции на Postgres. Ще искате да разгледате теми като отложена репликация, каскадна репликация, синхронен режим на готовност и други.
Въпреки че Postgres идва с впечатляващ набор от функции, все още има случаи на употреба, които не се поддържат. Тази уикистраница на Postgres има списък с инструменти на трети страни, които предоставят допълнителна функционалност, свързана с репликацията.