Как стать автором
Обновить

Миграция Postgrespro с Centos7 на AlmaLinux8. Как бонус — пара седых волос

Время на прочтение5 мин
Количество просмотров4.4K

В статье описывается один из способов обновления дистибутива операционной системы с работающим кластером баз данных Postgres Pro Standard версии 11. В дальнейшем, для краткости, кластер баз данных Postgres Pro Standard 11 будем называть Postgrespro, Centos7 - Centos, а AlmaLinux8 - Almalinux. Способ заключается в том, чтобы настроить физическую репликацию Postgrespro между разными дистрибутивами операционной системы с последующим переводом слейва в режим мастера. При чтении множества статей о настройке физической репликации я нигде не встречал упоминание о том, что так делать нельзя. Естественно, что архитектура Centos и Almalinux должны совпадать, а так же должны совпадать мажорные версии Postgrespro.

Немного о том, что за Postgrespro переносим

  • провайдер сортировки ICU

  • размер всех баз составляет 100G

  • в среднем 3000 транзакций в секунду при 21 коннекте

  • для коннектов используется pgbouncer в режиме session (pool_mode = session)

Исходные данные

Postgrespro на сервере с Centos - рабочая база

                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 11.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28), 64-bit

Postgrespro на сервере с Almalinux - чистая установка

                                                 version
---------------------------------------------------------------------------------------------------------
 PostgreSQL 11.18 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), 64-bit

Краткая последовательность действий

  1. Настраиваем физическую репликацию между Postgrespro на Centos (мастер) и Almalinux (слейв).

  2. Стопаем клиентские коннекты в pgbouncer.

  3. Переводим слейв в режим мастера.

  4. Переключаем клиентские коннекты в pgbouncer на новый мастер.

  5. На новом мастере в каждой базе обновляем версию правил сортировки.

Описание действий

Не буду описывать как настроить физическую репликацию, т.к. в интернете много инструкций. Скажу лишь, что у нас настроена потоковая репликация + архивирование wal файлов.

У pgbouncer есть замечательная команда PAUSE для приостановки клиентских коннектов. Но она не совсем подходит (я бы сказал, что совсем не подходит) для базы с постоянными соединениями, т.к. она не отработает до тех пор, пока все активные клиентские коннекты не отключатся. Например, если открыть psql, подлючиться к базе, выполнить любой запрос и оставить psql подключенной к базе, затем (в другом терминале) подлючиться к pgbouncer и выполнить PAUSE, то она замрет в ожидании закрытия psql. В то время как PAUSE будет ждать закрытие соединения psql, новые клиенты не смогут подключаться к базе. Проблема PAUSE еще и в том, что пока она "виснет", сделать на базу KILL так же не выйдет, будет ошибка ERROR: already suspended/paused, т.е. PAUSE вообще никак не прервать - только перезапуск pgbouncer. Поэтому, мы решили стопать клиентские коннекты через KILL, как итог, получили пару седых волос, но об этом позже.

После останова клиентских коннектов ждем пару секунд (чтобы слейв догнал мастер)
и переводим слейв в режим мастера. Способов несколько, мы это делаем через создание триггерного файла. Кто-то скажет, что подождать пару секунд так себе вариант чтобы убедиться в том, что слейв догнал мастер, тогда можно выполнить запрос к pg_stat_replication на текущем мастере и убедится, что sent_lsn, write_lsn, flush_lsn, replay_lsn равны.

После того, как новый мастер готов принимать соединения, в конфиге pgbouncer меняем строки коннекта к текущим базам на новый мастер и в подключении к pgbouncer возобновляем клиентские коннекты командой RESUME.

Поскольку в дистрибутивах Centos и Almalinux разные версии библиотеки ICU, а Postgrespro отслеживает изменение версий ICU в системе, то на новом мастере при каждом коннекте к базе, показывается такое предупреждение:

WARNING:  collation "default" has version mismatch
DETAIL:  The collation in the database was created using version 58.0.6.50, but the operating system provides version 153.80.
HINT:  Check all objects affected by this collation and run ALTER COLLATION pg_catalog."default" REFRESH VERSION

Чтобы избавиться от этого предупреждения, мы написали простенький скрипт на perl, который нужно запустить на новом мастере:

#!/usr/bin/env perl

# https://postgrespro.ru/docs/postgrespro/11/sql-altercollation#SQL-ALTERCOLLATION-NOTES
# Обновляет версии провайдера сортировки ICU во всех базах.
# Запускать на всех базах кластера, кроме template0 (т.к. к ней нельзя подконнектится).
# Запускать от пользователя postgres

use strict;
use warnings;
use DBI;

my @dbs = qw/analytics log postgres template1 testdb/;

# https://edu.postgrespro.ru/dba2-13/dba2_16_admin_localization.html
my $sql = qq/
    SELECT
        c.collname,
        c.collversion AS version,
        pg_collation_actual_version(c.oid) AS actual_version
    FROM
        pg_collation c
    WHERE
        pg_collation_actual_version(c.oid) IS NOT NULL
/;

for my $dbname (@dbs) {
    print "------- $dbname -------\n";
    my $dbh = DBI->connect("dbi:Pg:dbname=$dbname", "", "", { RaiseError=>1});
    my $arr = $dbh->selectall_arrayref($sql, { Slice => {} });
    for (@$arr) {
        if ($_->{version} ne $_->{actual_version}) {
            print "$_->{collname}: $_->{version} to $_->{actual_version}\n";
            $dbh->do('ALTER COLLATION pg_catalog."'.$_->{collname}.'" REFRESH VERSION');
        }
    }
}

Хочу заметить, что у нас в Postgrespro сортировка у всех баз одинаковая en_US.UTF-8@icu и в базах не используется сортировка отличная от default. Если у Вас иначе, то читать до понимания происходящего эту и эту ссылки.

Вот казалось бы и все, задача решена, дистрибутив операционной системы заменен, новый мастер держит нагрузку, ошибок нет. Помните, ранее, я говрил о седых волосах, так вот спустя пару минут работы на новом мастере мы заметили, что порядковый номер заказов прыгнул на 31, т.е. последовательность (первичный ключ) в таблице orders была 1004304, а на новом мастере вдруг стала 1004335. Мы не поверили своим глазам, как так то, ведь перед тем, как мы перевели слейв в режим мастера мы убедились, что sent_lsn, write_lsn, flush_lsn, replay_lsn равны, т.е. мастер и слейв были в одинаковых состояниях. Взглянув на другие посследовательности на новом мастере мы обнаружили, что такой скачок произошел и в других последовательностях. Немного подумав, мы поняли, что на самом деле ничего старшного в этом нет, ну прыгнули они и прыгнули, нас напугал сам факт того, что такой скачок произошел. А может тогда еще что-то где-то сломалось? Ведь мы использовали разные версии дистрибутивов операционной системы. Если коротко, то найти ответ на вопрос о скачке последовательностей нам помог второй слейв, да у нас был второй слейв, который застыл в сотоянии когда мы отрубили коннекты от старого мастера. И вот что показал запрос на втором слейве:

# SELECT * FROM orders_id_seq;
 last_value | log_cnt | is_called 
------------+---------+-----------
    1004304 |      31 | t
(1 row)

Вся фишка в log_cnt, погуглив мы тут же наткнулись на ответ. Если коротко, то да, скачок последовательностей возможен. Прикиньте!

Выводы

  • Простой в работе занял ровно минуту.

  • Скачок последовательностей произошел из-за того, что мы остановили клиентские коннекты на pgbouncer через команду KILL.

  • Возможно (не проверяли), проблема команды PAUSE описанная в этой статье возникает только в режиме session, а в режиме transaction нет.

Теги:
Хабы:
Всего голосов 10: ↑8 и ↓2+9
Комментарии4

Публикации

Истории

Работа

Ближайшие события

7 – 8 ноября
Конференция byteoilgas_conf 2024
МоскваОнлайн
7 – 8 ноября
Конференция «Матемаркетинг»
МоскваОнлайн
15 – 16 ноября
IT-конференция Merge Skolkovo
Москва
22 – 24 ноября
Хакатон «AgroCode Hack Genetics'24»
Онлайн
28 ноября
Конференция «TechRec: ITHR CAMPUS»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань