Настройка репликации postgresql windows
Эти параметры управляют поведением встроенного механизма потоковой репликации (см. Подраздел 26.2.5). Когда он применяется, один сервер является ведущим, а другие — ведомыми. Ведущий сервер всегда передаёт, а ведомые всегда принимают данные репликации, но когда настроена каскадная репликация (см. Подраздел 26.2.7), ведомые серверы могут быть и передающими. Следующие параметры в основном относятся к передающим и ведомым серверам, хотя некоторые параметры имеют смысл только для ведущего. Все эти параметры могут быть разными в рамках одного кластера, если это требуется.
19.6.1. Передающие серверы
Эти параметры можно задать на любом сервере, который передаёт данные репликации одному или нескольким ведомым. Ведущий сервер всегда является передающим, так что на нём они должны задаваться всегда. Роль и значение этих параметров не меняются после того, как ведомый сервер становится ведущим.
Задаёт максимально допустимое число одновременных подключений ведомых серверов или клиентов потокового копирования (т. е. максимальное количество одновременно работающих процессов передачи WAL). Значение по умолчанию — 10 . При значении 0 репликация отключается. В случае неожиданного отключения клиента потоковой передачи слот подключения может оставаться занятым до достижения тайм-аута, так что этот параметр должен быть немного больше максимально допустимого числа клиентов, чтобы отключившиеся клиенты могли переподключиться немедленно. Задать этот параметр можно только при запуске сервера. Чтобы к данному серверу могли подключаться ведомые, уровень wal_level должен быть replica или выше.
Для ведомого сервера значение этого параметра должно быть больше или равно значению на ведущем. В противном случае на ведомом сервере не будут разрешены запросы. max_replication_slots ( integer )
Задаёт максимальное число слотов репликации (см. Подраздел 26.2.6), которое сможет поддерживать сервер. Значение по умолчанию — 10. Этот параметр можно задать только при запуске сервера. Если заданное значение данного параметра будет меньше, чем число уже существующих слотов репликации, сервер не запустится. Чтобы слоты репликации можно было использовать, нужно также установить в wal_level уровень replica или выше.
На стороне подписчика указывает, сколько источников репликации (см. Главу 49) можно отслеживать одновременно, по сути ограничивая количество подписок на логическую репликацию, которые могут быть созданы на сервере. Если установленное значение будет меньше, чем текущее количество отслеживаемых источников репликации (показываемое в pg_replication_origin_status, а не в pg_replication_origin), сервер не запустится. wal_keep_segments ( integer )
Задаёт минимальное число файлов прошлых сегментов журнала, которые будут сохраняться в каталоге pg_wal , чтобы ведомый сервер мог выбрать их при потоковой репликации. Обычно сегмент имеет размер 16 мегабайт. Если ведомый сервер, подключённый к передающему, отстаёт больше чем на wal_keep_segments сегментов, передающий удаляет сегменты WAL, всё ещё необходимые ведомому, и в этом случае соединение репликации прерывается. В результате этого затем также будут прерваны зависимые соединения. (Однако ведомый сервер сможет восстановиться, выбрав этот сегмент из архива, если осуществляется архивация WAL.)
Этот параметр задаёт только минимальное число сегментов, сохраняемое в каталоге pg_wal ; система может сохранить больше сегментов для архивации WAL или для восстановления с момента контрольной точки. Если wal_keep_segments равен нулю (это значение по умолчанию), система не сохраняет никакие дополнительные сегменты для ведомых серверов, поэтому число старых сегментов WAL, доступных для ведомых, зависит от положения предыдущей контрольной точки и состояния архивации WAL. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. wal_sender_timeout ( integer )
Задаёт период времени, по истечении которого прерываются неактивные соединения репликации. Это помогает передающему серверу обнаружить сбой ведомого или разрывы сети. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию — 60 секунд. При значении, равном нулю, тайм-аут отключается.
Если узлы кластера распределены географически, его можно гибко настроить, используя разные значения в разных расположениях. Маленькие значения полезны для более быстрого обнаружения потери ведомого, подключённого по скоростному каналу, а большие — для более надёжного определения состояния ведомого, расположенного в удалённой сети, соединение с которой характеризуется большими задержками. track_commit_timestamp ( boolean )
Включает запись времени фиксации транзакций. Этот параметр можно задать только в postgresql.conf или в командной строке при запуске сервера. По умолчанию этот параметр имеет значение off .
19.6.2. Главный сервер
Эти параметры можно задать на главном/ведущем сервере, который должен передавать данные репликации одному или нескольким ведомым. Заметьте, что помимо этих параметров на ведущем сервере должен быть правильно установлен wal_level, а также может быть включена архивация WAL (см. Подраздел 19.5.3). Значения этих параметров на ведомых серверах не важны, хотя их можно подготовить заранее, на случай, если ведомый сервер придётся сделать ведущим.
Определяет список ведомых серверов, которые могут поддерживать синхронную репликацию, как описано в Подразделе 26.2.8. Активных синхронных ведомых серверов может быть один или несколько; транзакции, ожидающие фиксации, будут завершаться только после того, как эти ведомые подтвердят получение их данных. Синхронными ведомыми будут те, имена которых указаны в этом списке и которые подключены к ведущему и принимают поток данных в реальном времени (что показывает признак streaming в представлении pg_stat_replication ). Указание нескольких имён ведомых серверов позволяет обеспечить очень высокую степень доступности и защиту от потери данных.
Именем ведомого сервера в этом контексте считается значение application_name ведомого сервера, задаваемое в свойствах подключения. При организации физической репликации оно должно задаваться в строке primary_conninfo ; по умолчанию это значение параметра cluster_name, если он задан, или walreceiver в противном случае. Для логической репликации его можно задать в строке подключения для подписки (по умолчанию это имя подписки). Как задать его для других потребителей потоков репликации, вы можете узнать в их документации.
Этот параметр принимает список ведомых серверов в одной из следующих форм:
Ключевое слово FIRST , в сочетании с числом_синхронных , выбирает синхронную репликацию на основе приоритетов, когда транзакции фиксируются только после того, как их записи в WAL реплицируются на число_синхронных ведомых серверов, выбираемых согласно приоритетам. Например, со значением FIRST 3 (s1, s2, s3, s4) для фиксации транзакции необходимо дождаться ответа от трёх наиболее приоритетных из серверов s1 , s2 , s3 и s4 . Ведомые серверы, имена которых идут в этом списке первыми, будут иметь больший приоритет и будут считаться синхронными. Серверы, следующие в списке за ними, будут считаться потенциальными синхронными. Если один из текущих синхронных серверов по какой-то причине отключается, он немедленно будет заменён следующим сервером с наибольшим приоритетом. Ключевое слово FIRST может быть опущено.
Ключевое слово ANY , в сочетании с числом_синхронных , выбирает синхронную репликацию на основе кворума, когда транзакции фиксируются только после того, как их записи в WAL реплицируются на как минимум число_синхронных перечисленных серверов. Например, со значением ANY 3 (s1, s2, s3, s4) для фиксации транзакции необходимо дождаться ответа от как минимум трёх из серверов s1 , s2 , s3 и s4 .
Ключевые слова FIRST и ANY воспринимаются без учёта регистра. Если такое же имя оказывается у одного из ведомых серверов, его имя_ведомого нужно заключить в двойные кавычки.
Третья форма использовалась в PostgreSQL до версии 9.6 и по-прежнему поддерживается. По сути она равнозначна первой с FIRST и числом_синхронным , равным 1. Например, FIRST 1 (s1, s2) и s1, s2 действуют одинаково: в качестве синхронного ведомого выбирается либо s1 , либо s2 .
Специальному элементу * соответствует имя любого ведомого.
Уникальность имён ведомых серверов не контролируется. В случае дублирования имён более приоритетным будет один из серверов с подходящим именем, хотя какой именно, не определено.
Примечание
Каждое имя_ведомого должно задаваться в виде допустимого идентификатора SQL, кроме * . При необходимости его можно заключать в кавычки. Но заметьте, что идентификаторы имя_ведомого сравниваются с именами приложений без учёта регистра, независимо от того, заключены ли они в кавычки или нет.
Если имена синхронных ведомых серверов не определены, синхронная репликация не включается и фиксируемые транзакции не будут ждать репликации. Это поведение по умолчанию. Даже когда синхронная репликация включена, для отдельных транзакций можно отключить ожидание репликации, задав для параметра synchronous_commit значение local или off .
Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. vacuum_defer_cleanup_age ( integer )
Задаёт число транзакций, на которое будет отложена очистка старых версий строк при VACUUM и изменениях HOT . По умолчанию это число равно нулю, то есть старые версии строк могут удаляться сразу, как только перестанут быть видимыми в открытых транзакциях. Это значение можно сделать ненулевым на ведущем сервере, работающим с серверами горячего резерва, как описано в Разделе 26.5. В результате увеличится время, в течение которого будут успешно выполняться запросы на ведомом сервере без конфликтов из-за ранней очистки строк. Однако ввиду того, что эта отсрочка определяется числом записывающих транзакций, выполняющихся на ведущем сервере, сложно предсказать, каким будет дополнительное время отсрочки на ведомом сервере. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера.
В качестве альтернативы этому параметру можно также рассмотреть hot_standby_feedback на ведомом сервере.
Этот параметр не предотвращает очистку старых строк, которые достигли возраста, заданного параметром old_snapshot_threshold .
19.6.3. Ведомые серверы
Эти параметры управляют поведением ведомого сервера, который будет получать данные репликации. На ведущем сервере они не играют никакой роли.
Указывает строку подключения резервного сервера к передающему. Формат строки описан в Подразделе 33.1.1. Вместо опущенных параметров подключения используются соответствующие переменные окружения (см. Раздел 33.14). Если же и переменные не установлены, используются значения по умолчанию.
В строке подключения должно задаваться имя (или адрес) передающего сервера, а также номер порта, если он отличается от подразумеваемого по умолчанию ведущим. Также в ней указывается имя пользователя, соответствующее роли с необходимыми правами на передающем сервере (см. Подраздел 26.2.5.1). Если сервер осуществляет аутентификацию по паролю, дополнительно потребуется задать пароль. Его можно указать как в строке primary_conninfo , так и отдельно, в файле
/.pgpass на резервном сервере (для базы данных replication ). В строке primary_conninfo имя базы данных задавать не нужно.
Этот параметр можно задать только при запуске сервера и действует он только во время работы сервера в резервном режиме. primary_slot_name ( string )
Дополнительно задаёт заранее созданный слот, который будет использоваться при подключении к передающему серверу по протоколу потоковой репликации для управления освобождением ресурсов вышестоящего узла (см. Подраздел 26.2.6). Задать этот параметр можно только при запуске сервера. Этот параметр не действует, если не указана строка подключения primary_conninfo . promote_trigger_file ( string )
Указывает триггерный файл, при появлении которого завершается работа в режиме ведомого. Даже если это значение не установлено, существует возможность назначить ведомый сервер ведущим с помощью команды pg_ctl promote или функции pg_promote . Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. hot_standby ( boolean )
Определяет, можно ли будет подключаться к серверу и выполнять запросы в процессе восстановления, как описано в Разделе 26.5. Значение по умолчанию — on (подключения разрешаются). Задать этот параметр можно только при запуске сервера. Данный параметр играет роль только в режиме ведомого сервера или при восстановлении архива. max_standby_archive_delay ( integer )
В режиме горячего резерва этот параметр определяет, как долго должен ждать ведомый сервер, прежде чем отменять запросы, конфликтующие с очередными изменениями в WAL, как описано в Подразделе 26.5.2. Задержка max_standby_archive_delay применяется при обработке данных WAL, считываемых из архива (не текущих данных). Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию равно 30 секундам. При значении, равном -1, ведомый может ждать завершения конфликтующих запросов неограниченное время. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера.
Заметьте, что параметр max_standby_archive_delay определяет не максимальное время, которое отводится для выполнения каждого запроса, а максимальное общее время, за которое должны быть применены изменения из одного сегмента WAL. Таким образом, если один запрос привёл к значительной задержке при обработке сегмента WAL, остальным конфликтующим запросам будет отведено гораздо меньше времени. max_standby_streaming_delay ( integer )
В режиме горячего резерва этот параметр определяет, как долго должен ждать ведомый сервер, прежде чем отменять запросы, конфликтующие с очередными изменениями в WAL, как описано в Подразделе 26.5.2. Задержка max_standby_streaming_delay применяется при обработке данных WAL, поступающих при потоковой репликации. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию равно 30 секундам. При значении, равном -1, ведомый может ждать завершения конфликтующих запросов неограниченное время. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера.
Заметьте, что параметр max_standby_streaming_delay определяет не максимальное время, которое отводится для выполнения каждого запроса, а максимальное общее время, за которое должны быть применены изменения из WAL после получения от главного сервера. Таким образом, если один запрос привёл к значительной задержке, остальным конфликтующим запросам будет отводиться гораздо меньше времени, пока резервный сервер не догонит главный. wal_receiver_status_interval ( integer )
Этот параметр не переопределяет поведение old_snapshot_threshold , установленное на ведущем сервере; снимок на ведомом сервере, имеющий возраст больше заданного указанным параметром на ведущем, может стать недействительным, что приведёт к отмене транзакций на ведомом. Это объясняется тем, что предназначение old_snapshot_threshold заключается в указании абсолютного ограничения времени, в течение которого могут накапливаться мёртвые строки, которое иначе могло бы нарушаться из-за конфигурации ведомого. wal_receiver_timeout ( integer )
Задаёт период времени, по истечении которого прерываются неактивные соединения репликации. Это помогает принимающему ведомому серверу обнаружить сбой ведущего или разрыв сети. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию — 60 секунд. При значении, равном нулю, тайм-аут отключается. Задать этот параметр можно только в postgresql.conf или в командной строке при запуске сервера. wal_retrieve_retry_interval ( integer )
Определяет, сколько ведомый сервер должен ждать поступления данных WAL из любых источников (потоковая репликация, локальный pg_wal или архив WAL), прежде чем повторять попытку получения WAL. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию — 5 секунд. Задать этот параметр можно только в postgresql.conf или в командной строке сервера.
Этот параметр полезен в конфигурациях, когда для узла в схеме восстановления нужно регулировать время ожидания новых данных WAL. Например, при восстановлении архива можно ускорить реакцию на появление нового файла WAL, уменьшив значение этого параметра. В системе с низкой активностью WAL увеличение этого параметра приведёт к сокращению числа запросов, необходимых для отслеживания архивов WAL, что может быть полезно в облачных окружениях, где учитывается число обращений к инфраструктуре. recovery_min_apply_delay ( integer )
По умолчанию ведомый сервер восстанавливает записи WAL передающего настолько быстро, насколько это возможно. Иногда полезно иметь возможность задать задержку при копировании данных, например, для устранения ошибок, связанных с потерей данных. Этот параметр позволяет отложить восстановление на заданное время. Например, если установить значение 5min , ведомый сервер будет воспроизводить фиксацию транзакции не раньше, чем через 5 минут (судя по его системным часам) после времени фиксации, сообщённого ведущим. Если это значение задаётся без единиц измерения, оно считается заданным в миллисекундах. Значение по умолчанию равно нулю, то есть задержка не добавляется.
Возможна ситуация, когда задержка репликации между серверами превышает значение этого параметра. В этом случае дополнительная задержка не добавляется. Заметьте, что задержка вычисляется как разница между меткой времени, записанной в WAL на ведущем сервере, и текущим временем на ведомом. Запаздывание передачи, связанное с задержками в сети или каскадной репликацией, может существенно сократить реальное время ожидания. Если время на главном и ведомом сервере не синхронизировано, это может приводить к применению записей ранее ожидаемого, однако это не очень важно, потому что полезные значения этого параметра намного больше, чем обычно бывает разница во времени между двумя серверами.
Задержка применяется лишь для записей WAL, представляющих фиксацию транзакций. Остальные записи проигрываются незамедлительно, так как их эффект не будет заметен до применения соответствующей записи о фиксации транзакции, благодаря правилам видимости MVCC.
Задержка добавляется, как только восстанавливаемая база данных достигает согласованного состояния, и исключается, когда ведущий сервер переключается в режим основного. После переключения ведущий сервер завершает восстановление незамедлительно.
Данный параметр предназначен для применения в конфигурациях с потоковой репликацией; однако если он задан, он будет учитываться во всех случаях, кроме восстановления после сбоя. Задержка, устанавливаемая этим параметром, влияет и на работу механизма hot_standby_feedback , что может привести к раздуванию базы на главном сервере; использовать данный параметр при включении этого механизма следует с осторожностью.
Предупреждение
Этот параметр влияет на синхронную репликацию, когда synchronous_commit имеет значение remote_apply ; каждый COMMIT будет ждать подтверждения применения.
Репликация PostgreSQL представляет из себя способ реализации отказоустойчивого кластера. Инструкция написана на примере PostgreSQL 9.6 и 10, также она будет работать для PostgreSQL 9.2 (все нюансы будут отмечены отдельными комментариями).
В данном примере мы настроим потоковую (streaming) репликацию. Другой тип репликации (логическая) добавлена в PostgreSQL 10. Она позволяет реплицировать разные базы данных и таблицы на разные реплики.
Также, мы будем применять асинхронную репликацию — это вид репликации, при котором запросы выполняются сначала на мастере, затем попадают в журнал операций (WAL) и только после этого — на slave. При синхронной репликации запросы сначала попадают в WAL — после в мастер и слейв.
Используемые в данном руководстве команды, применимы для операционных систем Linux. Если Postgre работает под Windows, данную инструкцию можно использовать как шпаргалку для настройки конфигурационных файлов СУБД.
1. Подготовка серверов
Для начала, готовим наши серверы к настройке кластера.
PostgreSQL
На всех серверах баз данных должна быть установлена одна и та же версия PostgreSQL. Также, все серверы должны иметь одну и ту же архитектуру процессора.
Вот пример установки сервера PostgreSQL на CentOS 7.
Брандмауэр
При использовании брандмауэра, необходимо открыть TCP-порт 5432 — он используется сервером postgre.
а) Если управление выполняется с помощью Firewalld:
firewall-cmd --permanent --add-port=5432/tcp
б) Если используем Iptables:
iptables -A INPUT -p tcp --dport 5432 -j ACCEPT
в) Если используем UFW:
ufw allow 5432/tcp
SELinux
Если активирована система безопасности SELinux (по умолчанию в системах Red Hat / CentOS / Fedora), отключаем ее:
Если необходимо, чтобы SELinux работал, настраиваем его.
2. Настройки на Master
В данной статье мы будем настраивать серверы с IP-адресами 192.168.1.10 (первичный или master) и 192.168.1.11 (вторичный или slave).
Переходим на сервер, с которого будем реплицировать данные (мастер) и выполняем следующие действия.
Создаем пользователя в PostgreSQL
Создаем нового пользователя для репликации:
createuser --replication -P repluser
* система запросит пароль — его нужно придумать и ввести дважды. В данном примере мы создаем пользователя repluser.
Выходим из оболочки пользователя postgres:
Настраиваем postgresql
Смотрим расположение конфигурационного файла postgresql.conf командой:
В моем случае система вернула строку:
* конфигурационный файл находится по пути /etc/postgresql/9.6/main/postgresql.conf.
Открываем конфигурационный файл postgresql.conf.
* мы открываем файл, который получили sql-командой SHOW config_file;.
Редактируем следующие параметры:
- 192.168.1.10 — IP-адрес сервера, на котором он будем слушать запросы Postgre;
- wal_level указывает, сколько информации записывается в WAL (журнал операций, который используется для репликации);
- max_wal_senders — количество планируемых слейвов;
- max_replication_slots — максимальное число слотов репликации (данный параметр не нужен для postgresql 9.2 — с ним сервер не запустится);
- hot_standby — определяет, можно или нет подключаться к postgresql для выполнения запросов в процессе восстановления;
- hot_standby_feedback — определяет, будет или нет сервер slave сообщать мастеру о запросах, которые он выполняет.
Открываем конфигурационный файл pg_hba.conf — он находитсяч в том же каталоге, что и файл postgresql.conf:
Добавляем следующие строки:
host replication repluser 127.0.0.1/32 md5
host replication repluser 192.168.1.10/32 md5
host replication repluser 192.168.1.11/32 md5
* данной настройкой мы разрешаем подключение к базе данных replication пользователю repluser с локального сервера (localhost и 192.168.1.10) и сервера 192.168.1.11.
Перезапускаем службу postgresql:
systemctl restart postgresql
* обратите внимание, что название для сервиса в системах Linux может различаться.
3. Настройки на Slave
Смотрим путь до конфигурационного файла postgresql:
В моем случае путь был:
Также смотрим путь до конфигурационного файла postgresql.conf (нам это понадобиться ниже):
Останавливаем сервис postgresql:
systemctl stop postgresql
На всякий случай, создаем архив базы:
tar -czvf /tmp/data_pgsql.tar.gz /var/lib/pgsql/9.6/data
* в данном примере мы сохраним все содержимое каталога /var/lib/pgsql/9.6/data в виде архива /tmp/data_pgsql.tar.gz.
Удаляем содержимое каталога с данными:
rm -rf /var/lib/pgsql/9.6/data/*
И реплицируем данные с master сервера.
а) Если у нас postgresql 9:
su -u postgres -с "pg_basebackup -h 192.168.1.10 -U repluser -D /var/lib/pgsql/9.6/data --xlog-method=stream --write-recovery-conf"
* где 192.168.1.10 — IP-адрес мастера; /var/lib/pgsql/9.6/data — путь до каталога с данными.
б) Если у нас postgresql 10:
su - postgres -c "pg_basebackup --host=192.168.1.10 --username=repluser --pgdata=/var/lib/pgsql/10/data --wal-method=stream --write-recovery-conf"
* где 192.168.1.10 — IP-адрес мастера; /var/lib/pgsql/10/data — путь до каталога с данными.
После ввода команды система запросит пароль для созданной ранее учетной записи repluser — вводим его. Начнется процесс клонирования данных.
Открываем конфигурационный файл postgresql.conf на слейве:
И редактируем следующие параметры:
* где 192.168.1.11 — IP-адрес нашего вторичного сервера.
Репликация PostgreSQL решает две задачи:
Репликация на серверах PostgreSQL бывает двух видов:
Физическая репликация PostgreSQL
Алгоритм создания такой репликации следующий:
- Делаем резервную копию с помощью pg_basebackup. С помощью отдельных опций указываем что копию нужно подготовить к дальнейшей репликации.
- Разворачиваем полученную резервную копию на сервере репликации.
- Там же, создаем специальный файл с настройками репликации (если были указаны нужные опции для команды pg_basebackup, то все необходимые файлы, нужные для репликации, создадутся автоматом):
- в 10 версии PostgreSQL создаём файл recovery.conf, прописываем там standby_mode = on;
- начиная с 12 версии создаём пустой файл standby.signal;
Сервер репликации может принимать запросы, но только на чтение. Этот сервер не генерирует wal записи, а продолжает их получать из потока по протоколу репликации с основного сервера.
Журнальные записи можно передавать по протоколу репликации или можно использовать архив WAL. Но обычно применяют первое.
На главном сервере появляется процесс wal sender, который передаёт wal записи. На сервере репликации появляется wal receiver, который принимает эти записи.
Репликация может быть синхронной и асинхронной. При синхронной репликации основной сервер не только отправляет запись на реплику, но и дожидается подтверждения что запись туда дошла и была там применена. Но синхронная реплика сильно тормозит производительность кластера.
Переключение на реплику
Переключение на реплику осуществляется либо планово, либо аварийно. Но в любом случае оно происходит в ручном режиме. Хотя процесс можно автоматизировать, например с помощью скриптов.
Для восстановления основного сервера его обычно превращают в реплику и синхронизируют с бывшей репликой. После синхронизации сервера опять меняют местами.
Восстановление основного сервера проделывают следующими способами:
- Если основной сервер был остановлен корректно и все журнальные записи успели перейти на реплику, то можно просто поменять сервера местами:
- останавливаем основной сервер;
- реплику превращаем в основной сервер;
- основной сервер превращаем в реплику.
- реплику превращаем в основной сервер (пусть клиенты пока поработают на этом сервере);
- на основном сервере (который был выключен некорректно) очищаем каталог PGDATA;
- затем основной сервер превращаем в реплику.
Сценарии использования физической репликации
Логическая репликация PostgreSQL
При репликации передаются wal записи, но для работы логической репликации нужно изменить формат этих записей. Для этого нужно поменять параметр кластера wal_level = logical.
При такой репликации всегда используется слот логической репликации. Благодаря которому понятно, какие записи уже были переданы, а какие нет.
Подписчик и поставщик это равноценные сервера, они оба доступны на чтение и запись для клиентов. Поэтому могут возникать конфликты. Например на поставщике выполняется INSERT, а на подписчике уже такая строка есть. Подобные конфликты решаются пока только в ручном режиме.
На поставщике работает уже знакомый процесс wal sender, а на подписчике logical replication worker который получает логические wal записи и применяет их от имени суперпользователя.
Сценарии использования логической репликации
Практика
Физическая репликация
После предыдущего урока у нас два каталога PGDATA. При этом второй кластер выключен.
Очистим каталог /usr/local/pgsql/data2/ и заново сделаем туда резервную копию с помощью pg_basebackup. Ключ -R подготовит архивную копию к дальнейшей репликации (создаст файл standby.signal):
Помимо standby.signal в postgresql.auto.conf были внесены параметры для последующей репликации:
Был добавлен параметр primary_conninfo, в котором указаны опции подключения к основному серверу:
- port=5432
- sslmode=disable
- и другие.
Вот ещё пример, который не нужно выполнять!
Задаются параметры подключения к основному серверу с помощью опций pg_basebackup. Например мы подключались бы к другому серверу, а для репликации был бы отдельный пользователь, тогда команда выглядела бы так:
В команде выше мы используем следующие опции:
После такой команды, конфигурационный файл postgresql.auto.conf будет содержать такой параметр подключения к основному серверу:
Поменяем порт второго кластера, чтобы он мог работать одновременно с первым:
Файл standby.signal который появился во втором кластере означает настройку standby_mode=on в recovery.conf до PostgreSQL 12. То есть ничего делать не нужно для того чтобы перевести сервер в режим работы реплики.
Можем запустить второй кластер:
Посмотрим на процессы реплики. Процесс walreceiver streaming принимает поток wal записей, а процесс startup recovering применяет изменения:
В основном кластере появился процесс walsender postgres, который передаёт wal записи:
Проверить состояние репликации можно в представлении pg_stat_replication на главном сервере:
Внесём некоторые изменения на мастере:
Проверим, создались ли эти объекты на сервере репликации:
Сама реплика ничего менять не может:
Переведём реплику в обычный режим, то есть отключим репликацию. Это делается с помощью команды promote. При этом у нас пропадет файлик standby.signal.
После этого второй кластер может писать данные:
Логическая репликация
Поменяем параметр wal_level = logical для первого кластера и перезапустим этот его:
В первом кластере создадим публикацию (CREATE PUBLICATION) и посмотрим на неё с помощью команды \dRp+:
Во втором кластере подписываемся на эту публикацию (CREATE SUBSCRIPTION) и отключаем первоначальное копирование данных (copy_data = false):
Теперь посмотрим на подписку с помощью команды \dRs:
Проверим настроенную логическую репликацию. Для этого в первом кластере, вставим новую строчку в опубликованной табличке:
Во втором кластере увидим эту строку:
Состояние подписки можно посмотреть в представлении pg_stat_subscription:
К процессам сервера подписчика добавился logical replication worker:
Если репликация больше не нужна, надо удалить подписку, иначе на публикующем сервере останется открытым слот репликации:
На этом этот курс подошёл к концу! За основу взяты видео с этого плейлиста на YouTube. Я просто проделал все на PostgreSQL 13 и лишь некоторые моменты связанные с репликацией отличаются от PostgreSQL 10. В дальнейшем, если вернусь к теме PostgreSQL постараюсь усовершенствовать этот курс, спасибо за внимание!
В статье мы расскажем, что такое репликация и где она применяется. Также на примере двух виртуальных серверов настроим репликацию данных в PostgreSQL и проверим, что она работает.
Что такое репликация
Репликация — это дублирование данных, когда данные с одного сервера полностью повторяются на других. Приложения пишут данные в одну базу данных PostgreSQL, а изменения автоматически синхронизируются на другие базы.
Репликация используется для достижения двух целей:- Повышение отказоустойчивости. Если один из серверов выйдет из строя, то остальные продолжат работу.
- Повышение производительности. Распределение данных по серверам в разных частях страны или мира повышает скорость доступа к данным для местных пользователей.
Виды репликации в PostgreSQL
Существует несколько видов репликаций, у каждого из них свои особенности. Но прежде чем рассказывать о видах, нужно хотя бы поверхностно познакомиться с WAL — журналом предзаписи транзакций.
Когда PostgreSQL получает команду на изменение данных, она не сразу изменяет их на диске. Сначала она записывает изменения в WAL. Этот журнал нужен для того, чтобы в случае сбоя сервера можно было восстановить незафиксированные данные. Также WAL используется и для репликации данных.
Итак, в PostgreSQL есть несколько видов репликации:
Потоковая репликация (Streaming Replication). Это репликация, при которой от основного сервера PostgreSQL на реплики передается WAL. И каждая реплика затем по этому журналу изменяет свои данные. Для настройки такой репликации все серверы должны быть одной версии, работать на одной ОС и архитектуре. Потоковая репликация в Postgres бывает двух видов — асинхронная и синхронная.
- Асинхронная репликация. В этом случае PostgreSQL сначала применит изменения на основном узле и только потом отправит записи из WAL на реплики. Преимущество такого способа — быстрое подтверждение транзакции, т.к. не нужно ждать пока все реплики применят изменения. Недостаток в том, что при падении основного сервера часть данных на репликах может потеряться, так как изменения не успели продублироваться.
- Синхронная репликация. В этом случае изменения сначала записываются в WAL хотя бы одной реплики и только после этого фиксируются на основном сервере. Преимущество — более надежный способ, при котором сложнее потерять данные. Недостаток — операции выполняются медленнее, потому что прежде чем подтвердить транзакцию, нужно сначала продублировать ее на реплике.
Логическая репликация (Logical Replication). Логическая репликация оперирует записями в таблицах PostgreSQL. Этим она отличается от потоковой репликации, которая оперирует физическим уровнем данных: биты, байты, и адреса блоков на диске. Возможность настройки логической репликации появилась в PostgreSQL 10.
Этот вид репликации построен на механизме публикации/подписки: один сервер публикует изменения, другой подписывается на них. При этом подписываться можно не на все изменения, а выборочно. Например, на основном сервере 50 таблиц: 25 из них могут копироваться на одну реплику, а 25 — на другую.
Также есть несколько ограничений, главное из которых — нельзя реплицировать изменения структуры БД. То есть если на основном сервере добавится новая таблица или столбец — эти изменения не попадут в реплики автоматически, их нужно применять отдельно.
В отличие от потоковой репликации, логическая может работать между разными версиями PostgreSQL, ОС и архитектурами.Облачные базы данных
Готовые к работе управляемые базы данных MySQL с встроенной репликацией.Установить PostgreSQL
Перейдем к практике: настроим потоковую асинхронную репликацию в режиме Master-Replica: один сервер — основной, в него можно писать данные, другой — реплика, из него можно только читать.
На примере платформы Selectel создадим два отдельных сервера PostgreSQL, один из которых будет основным (Master), а второй — репликой (Replica).
В панели управления платформой заходим в раздел «Облачная платформа» — «Серверы», нажимаем кнопку «Создать сервер».
Укажем имя сервера — Master. Так нам будет проще ориентироваться в серверах. Выберем ОС — Ubuntu 20.04, конфигурацию — 2 vCPU, 8 ГБ оперативной памяти и 10 ГБ диска.
В разделе «Сеть» нужно выбрать подсеть с публичным адресом, чтобы к виртуальной машине можно было подключаться из интернета. В разделе «Доступ» нужно проверить, что вы либо записали пароль root-пользователя, либо указали правильный SSH-ключ для подключения к машине.
По такому же принципу создаем второй сервер, только укажем другое имя — Replica. Остальные параметры оставим такими же.
В итоге у нас получилось два сервера. Обратите внимание, что у них есть публичные и приватные IP-адреса.Публичные адреса мы будем использовать для подключения к машинам, а приватные — для настройки репликации.
Теперь нужно подключиться к каждому серверу по SSH. Рекомендуем открыть 2 окна терминала и держать их открытыми, потому что мы будем часто переключаться между серверами.
Итак, подключаемся к серверам и устанавливаем PostgreSQL на каждом из них:
Все, сервера готовы к настройке репликации. Сейчас они ничем не отличаются друг от друга, кроме названия. Перейдем к настройке каждого из них.
Настроить Master-сервер
Репликацию будем выполнять под пользователем postgres, который автоматически создается после установки PostgreSQL. Установим ему пароль, он нам понадобится позже:
Далее нужно разрешить этому пользователю подключаться из Replica-сервера в Master. Для этого мы отредактируем файл /etc/postgresql/12/main/pg_hba.conf.
Обратите внимание, что мы показываем настройку репликации на примере PostgreSQL 12, поэтому в пути к файлу есть номер — 12. Если у вас другая версия PostgreSQL, то вам нужно поменять путь к файлу.Итак, откроем файл:
Найдем в нем строчку «If you want to allow non-local connections, you need to add more» и впишем после нее такую строчку:
Так мы разрешаем пользователю postgres подключаться к этому серверу из Replica.
Обратите внимание, что мы используем приватные адреса, потому что виртуальные машины находятся в одной сети. При этом нам не нужно открывать порты, настраивать Firewall и так далее. Если ваши машины будут находиться в разных сетях или вы хотите, чтобы они общались друг с другом по публичным адресам — скорее всего вам придется настроить Firewall.
Далее нужно указать настройки репликации. Открываем конфигурационный файл PostgreSQL:Находим в нем эти параметры, раскомментируем их и подставляем указанные значения.
Все, Master настроен. Чтобы применить настройки, перезапускаем сервер:
Настроить Replica-сервер
Переключаемся в окно терминала Replica-сервера. Перед началом настройки нужно остановить PostgreSQL-сервер:
Аналогично Master-серверу отредактируем файл pg_hba.conf. В то же самое место вставим ту же самую строчку, но только теперь укажем IP-адрес мастера.
Добавляем в него строчку:
Затем правим файл postgresql.conf. Настройки те же самые, как и у Master, только нужно поменять IP-адрес. Открываем файл на редактирование:
Находим в нем эти параметры, раскомментируем их и подставляем указанные значения:
Сейчас настройки обоих серверов одинаковые, отличаются только IP-адреса. Это потому, что при необходимости реплики могут становиться мастером, а вся разница будет в наличии одного лишь файла. О нем расскажем далее.
Прежде чем Replica-сервер сможет начать реплицировать данные, нужно создать новую БД, идентичную Master-серверу. Для этого воспользуемся утилитой pg_basebackup. Она создаст бэкап с Master-сервера и скачает его на Replica-сервер. Эту операцию нужно выполнять от имени пользователя postgres, поэтому логинимся от него:Далее переходим в каталог с базой данных:
Удалим каталог с дефолтной БД и снова его создадим, но уже пустой:
Теперь выгрузим БД с мастера. Для выполнения этой команды нужно будет ввести пароль от пользователя postgres, который мы задавали в самом начале настройки Master-сервера.
В этой команде есть важный параметр -R. Он означает, что PostgreSQL-сервер также создаст пустой файл standby.signal. Несмотря на то, что файл пустой, само наличие этого файла означает, что этот сервер — реплика.
Файл standby.signal появился только в PostgreSQL версии 12. Раньше вместо него создавался файл recovery.conf, в котором хранились настройки для подключения к Master-серверу. Имейте это ввиду, если вы используете более ранние версии PostgreSQL.
Возвращаемся в root-пользователя и запускаем PostgreSQL-сервер:
Проверить репликацию
Теперь нужно протестировать репликацию и убедиться, что мы все правильно настроили. На Master-сервере создадим таблицу и вставим в нее одну строчку:
Переключимся в терминал Replica-сервера и проверим, что таблица с данными появилась:
Еще одна проверка — попробуем создать новую таблицу на сервере Replica. Если мы все сделали правильно, то сервер не должен позволить нам этого сделать, потому что он настроен только на репликацию с основной БД.
На Replica-сервере выполняем команду:Значит репликация настроена правильно.
Теперь покажем, как можно из Replica-сервера сделать Master. Сымитируем ситуацию, что основной сервер вышел из строя. Для этого в консоли управления платформой Selectel просто выключим сервер Master.Чтобы перевести Replica-сервер в режим записи, выполните команду:
Проверяем, снова пробуем создать новую таблицу:
На этот раз таблица создастся. Значит, мы перевели сервер из режима чтения в режим записи.
Но нужно понимать, что запросы от приложений не начнут автоматически направляться на этот сервер. Если сервисы и приложения подключались к «старому» Master-серверу напрямую, они так и будут пытаться подключаться к нему.Обычно в такой ситуации используется балансировщик нагрузки. Он сам следит за состоянием серверов и распределяет нагрузку между всеми рабочими инстансами. При этом приложения отправляют запросы не напрямую в СУБД, а в балансировщик нагрузки.
Заключение
Читайте также: