Как стать автором
Поиск
Написать публикацию
Обновить

Наш опыт миграции PostgreSQL с AWS RDS на свою (self-hosted) инсталляцию

Время на прочтение15 мин
Количество просмотров6.9K
Всего голосов 18: ↑17 и ↓1+20
Комментарии11

Комментарии 11

Некоторые моменты перепутали.
max_replication_slots должно быть достаточно, но нет никакой необходимости их делать по числу таблиц. Их должно быть достаточно для физических реплик если они используют слоты (внутри rds), логического apply по одному на каждую активную подписку и на временных sync воркеров смотря сколько их может запустить каждая подписка + некоторый запас, потому что подписка может запустить следующего воркера раньше чем предыдущий освободит слот репликации.
max_logical_replication_workers — это настройка подписчика (см. доку, настройка недвусмысленно выделена в отдельный раздел). Поэтому на стороне RDS откуда вы уезжаете её крутить смысла нет.
Зато вы не упомянули max_sync_workers_per_subscription. Если у вас одна подписка (а далее вы создаёт только одну подписку) — то это важно, сюда начальный процесс копирования данных и упрётся.
Один sync воркер стягивает только одну таблицу. При том для sync воркеров скорее будет важен не CPU, а дисковое io. На rds всё-таки не очень быстрые EBS.

А вот logical_decoding_work_mem на стороне как раз подписки может быть нелишним поднять чтобы брать побольше памяти на logical decoding и писать поменьше временных файлов.

Конечно, было бы проще сразу сделать надежную потоковую реплику из RDS, но этому препятствуют ограничения в AWS.

Может быть весьма нетривиально даже если бы RDS давали replication пользователя. Достаточно вспомнить, что физическая репликация именно физическая и налагает серьёзные требования на бинарную совместимость, а RDS, как известно, нифига не postgresql, а закрытый форк с неизвестным объёмом собственных изменений.

Здравствуйте! Спасибо огромное за ваши замечания, вы совершенно правы. На ус намотано, и пост исправим asap.

RDS, как известно, нифига не postgresql, а закрытый форк

Для Aurora да, но RDS Postgres разве не настоящий Postgres?

Нет, тоже патченый. Может быть объём их своих патчей там невелик, но они точно есть. Просто без изменения кода postgresql невозможно сделать роль rds_superuser с такими привилегиями. В тех операциях, что позволено выполнять обладателю роли rds_superuser, в оригинальном postgresql проверяет именно атрибут superuser выполняющего этот запроса пользователя, а он через роли наследоваться не может (это специально так ограничено). Например, create extension pg_repack
А, кстати, ещё момент специфики pub/sub в postgresql, на котором уже не раз видел аварии:
A published table must have a “replica identity” configured in order to be able to replicate UPDATE and DELETE operations, so that appropriate rows to update or delete can be identified on the subscriber side. By default, this is the primary key, if there is one. Another unique index (with certain additional requirements) can also be set to be the replica identity.


Перед добавлением таблиц в подписку (т.е. до CREATE PUBLICATION pub_all_tables FOR ALL TABLES) обязательно проверьте, что у всех таблиц есть primary key (мы себе вот такой запрос сохранили для этого). Очень чревато тем, что база перестанет выполнять update и delete запросы на такой таблице сразу после создания публикации. Вообще перестанет, потому что непонятно как искать необходимые строки на подписчике. Но отказывает в операциях именно на стороне публикации, то есть где обычно в это время работает прод, что в общем ощущается как авария…
Для целей уникальной идентификации записей база может использовать уникальный индекс, но сама автоматически этого делать не будет пока не попросят явно через
alter table tablename REPLICA IDENTITY USING INDEX indexname;

Оффтопик - “slave” уже давно не говорят, говорят “replica”. Жаргон сразу же выдает. Уже году в 2015-м говорили. А вот “master” как ни пытались выпилить, так и не выпилили, так что будет оно всегда «master-replica» теперь.

Что касается RDS, то один из главных его недостатков - невозможность сделать failover с автоматической переподпиской всех реплик на нового мастера. Поэтому все это превращается в тыкву «при первом же шухере».

Вот в Aurora это решено, но там другая проблема: за 3 последних года она у нас падала 6 раз по вине Амазона. И на починку у них уходило до 6 часов, причем в половине случаев висела даже консоль. Ну и супердорого еще, конечно. Такой вот он, революционный крейсер. Прохудился-с. Г-код там тот еще под капотом, видимо (судя по тому, как отвечал суппорт, когда я его доставал требованиями рассказать о технических причинах аутаджа, да и просто по логам было видно, что там костыль на костыле при потери связности или чуть большем времени crash recovery; просто в ходит в restart loop).

Так что ванильный постгрес и repmgr - наш выбор. Дешевле раза в 3, да и работает раза в 2 быстрее на тех же типах инстансов (что удивительно), плюс можно компрессию включить для диска и еще раза в 3 сэкономить на месте.

По терминологии есть куда более широкий диапазон вариантов.

Только вот во всем этом многообразии по-настоящему устоявшихся терминов (единых, общепринятых, универсальных) до сих пор скорее нет, чем есть. А в русскоязычном сообществе эта проблема, по моим ощущениям, не особо о(б)суждается.

Как раз таки в русскоязычном сообществе и есть единственный вариант - мастер-реплика, потому что это транслит-калька с master-replica. И в большинстве других языков, я думаю, тоже будет калька. А значит, этот вариант заведомо выигрышнее в том числе и в теоретическом плане (он даже лучше, чем master-slave, потому что приходится slave транслитерировать как «слэйв», что криво). А учитывая, что русскоязычные (ок, славяноязычные) инженеры сильно выделяются в индустрии (сложилась такая карма «спартанцев, делающих дело, а не жующих попусту сопли»), то я делаю ставку и в долгосрочной перспективе.

К слову, у Amazon есть сервис для миграций БД - AWS DMS.

Использовал его для миграции БД из одного региона в другой. Тоже простой был только на период рестарта source-инстанса RDS для включения логической репликации.

Нюансы, который заметил: не переносятся кастомные индексы и не проставляются DEFAULT в DDL

Было бы интересно узнать, какого размера была RDS база и сколько времени заняла в вашем случае репликация на два новых инстанса.

С учётом того, что на RDS базе за это время не должно быть изменения в схемах, структурах таблиц, пользователях и ролях, процесс репликации данных выглядит как-будто уязвимым всё это время.

А что делать в случае, если такие изменения на master произошли, придётся начинать процесс заново?

Как Вы проверяли, что изменений не было и новая база консистентна с оригиналом?

Пользователи и роли без разницы, можно менять как нравится. Только иметь в виду, что они не реплицируются. Структуру таблиц менять в целом тоже можно, но здесь уже необходимо понимание, что у нас есть логическая репликация и нужно осознавать, как именно вносить изменения структуры. В простом случае добавления новой колонки default null (или константа) — сперва вносится на логическую подписку, затем на публикацию.
Если в очередной раз забыли (хочется мне на паре подконтрольных баз отобрать кое у кого права на внесение миграций) — то зависит от того, что именно меняли. Если такое же простое «добавили колону» — то просто добавляется колонка на стороне подписки и репликация самостоятельно продолжается с того места где остановилась.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий