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

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В статье описывается один из способов обновления дистибутива операционной системы с работающим кластером баз данных 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 нет.

Источник: https://habr.com/ru/post/711664/


Интересные статьи

Интересные статьи

Поиск по базе объявлений — совсем не то же самое, что поиск по интернету. Он параметрический, а не полнотекстовый: вы можете с помощью фильтров однозначно определить, что вам нужно, сузив область ...
Сейчас мои продукты, написанные для Роспатента, проходят аттестацию по информационной безопасности. Этот "увлекательный и интересный" процесс побудил меня вспомнить несколько баек из моей личной практ...
Если вы — представитель моего поколения, и еще помните, что такое «ждать неделю, пока будет этот фильм по РТР» — то, вероятно, вас в детстве тоже интересовал вопрос «Как уничтожить Т-1000». Еще в школ...
Современная силовая электроника это про большие мощности, преобразуемые на высокой частоте и с высокой удельной плотностью. Проектирование совмещенное с комплексным моделированием, учитывающим максима...
Недавно я читал статью о том, как научиться программировать под Android с нуля за полчаса. Она начиналась со слов «Вы можете даже не догадываться, но миллионы людей во всем мире зарабатывают день...