Рассмотрим перенос данных базы «l_generator» с помощью Londiste.
Почему Londiste?
Рекомандация использовать Londiste от Amazon:
https://aws.amazon.com/ru/blogs/aws/rds-postgres-read-replicas/ — 2014
Data Import (Londiste)
In order import data using Londiste, you would need to install it on the external PostgreSQL instance (not on RDS), set up RDS PostgreSQL instance as a replica, and enable replication. Londiste would initially do a dump and load of data into RDS PostgreSQL instance while the external instance is still taking write traffic. Over time, the RDS instance will catch up with the updates that are taking place on the external instance. Once the RDS instance is current, you can then point your applications to the RDS PostgreSQL instance, choosing the timing so as to minimize application downtime.
—Data Export (Bucardo)
You can also use the session role to export data from an RDS for PostgreSQL instance to a remote target on-premises or on EC2. There are many ways to do this. For example, you can install Bucardo, an open source trigger-based lazy replication solution on the remote instance and set it up as a replication slave to the master RDS PostgreSQL instance. Bucardo replicates the data on the RDS instance to the remote instance as long as the remote instance is online. With lazy replication, when the remote instance goes offline and comes back online, Bucardo ensures that the remote instance will eventually catch up.
—Инстансы БД Amazon RDS для PostgreSQL, использующие версию PostgreSQL 9.3.5 и более новые, поддерживают роль репликации сессий. Импортировать данные на инстанс БД Amazon RDS для PostgreSQL с минимальным временем простоя можно также путем использования данной роли и запускаемых с помощью событий инструментов репликации с открытым исходным кодом, таких как Londiste.
Терминология:
Skytools — это приложение, написанное на Python и оно использует Python-Postgres драйвер «psycopg2». Версии 2.4.2 и 2.4.3 psycopg2 имеют проблемы с потерей данных и не должны использоваться с Londiste.
Ссылка: http://initd.org/psycopg/. Посленяя доступная версия 2.7.5.
Используем Skytools версии 2, т.к. Skytools3 не подходит — ему нужны права полноценного superadmin в RDS.
PGQ — это реализация очередей от Skytools. Londiste строит свою репликацию на основе очередей PGQ.
Ссылка: https://wiki.postgresql.org/wiki/PGQ_Tutorial
Londiste — это асинхронная система репликации, построенная поверх очередей PGQ. Он может быть запущен на любом сервере, но обычно его запускают на сервере с источником данных для переноса.
Provider — источник для репликации, в нашем случае это БД на ec2 инстансе; Subscriber — приемник для репликации, в нашем случае это AWS RDS с PostgreSQL 10.
Подготовка RDS к пареносу данных:
- Для начала необходимо создать руками базу данных на subscriber-е:
CREATE DATABASE l_generator;
Дать соответсующему пользователю права на эту базу
CREATE USER l_generator WITH ENCRYPTED PASSWORD 'superpassword'; GRANT ALL ON database l_generator to l_generator;
2. Затем нужно перенести схему этой базы с provider-a, чтобы создались все таблицы и индексы:
pg_dump -o -h 127.0.0.1 -U postgres_migrate -d l_generator -n public -s > public_schema_l_generator.dump
где «-n public» — переносить только схему public; «-s» — дампить только схему, без самих данных.
3. Накатываем схему на новую базу subscriber-a:
psql -h database.eu-west-1.rds.amazonaws.com -U l_generator -d l_generator -f public_schema_l_generator.dump
Если возникли ошибки при накатывании схемы в RDS:
CREATE INDEX psql:public_schema_l_generator.dump:2168: ERROR: data type integer has no default operator class for access method "gin" HINT: You must specify an operator class for the index or define a default operator class for the data type. psql:public_schema_l_generator.dump:2175: ERROR: data type integer has no default operator class for access method "gin" HINT: You must specify an operator class for the index or define a default operator class for the data type.
Не могут создаться индексы, поэтому создаём их сами
CREATE INDEX ads_ids_idx ON ads USING gin (ads_ids); CREATE INDEX ads_per_run_id_ids_idx ON ads USING gin (project_run_id, ads_ids); CREATE INDEX ads_per_run_id_ids_idx_1 ON ads USING gin (ads_ids, project_run_id);
Нужно установить необходимые экстеншены
CREATE EXTENSION btree_gin; CREATE EXTENSION btree_gist;
Приступаем к установке londiste из пакета Skytools2.
Будем компилить из исходников последнюю версию.
- Install PostgreSQL:
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
2. Установка psycopg2:
Доступные версии в репозиториях:
python-psycopg2/trusty 2.4.5-1build5 amd64 — (Ubuntu 14.04)
python-psycopg2/stretch-pgdg 2.7.5-2.pgdg90+1 amd64 — (Debian 9)
Debian 9:
apt install python-psycopg2
3. Загружаем последнюю версию Skytools2 с сайта:
http://pgfoundry.org/frs/?group_id=1000206
skytools 2.1.13 (2012-03-13 08:33)
wget http://pgfoundry.org/frs/download.php/3232/skytools-2.1.13.tar.gz tar zxf skytools-2.x.x.tar.gz cd skytools-2.x.x
4. Конфигурируем:
Конфигуратору нужно указать префикс — место, куда будет установлен skytools2 и скрипт для определения установленной версии postgresql:
ищем скрипт:
$ sudo find / -type f -name "pg_config" /usr/bin/pg_config
конфигурируем:
./configure --prefix=/opt/skytools-2.1.13 --with-pgconfig=/usr/bin/pg_config
Возможные ошибки:
error: missing keywords.h:
sudo ln -s /usr/include/postgresql/10/server/common/keywords.h /usr/include/postgresql/10/server/parser/keywords.h
error: ‘SerializableSnapshot’ undeclared:
Ive made another change than, that fixes PG version detection in the sql/txid/Makefile. With this patch I got
skytools
build fine here.
https://www.postgresql.org/message-id/attachment/57157/20171218-skytools-10.diff
pg83 = $(shell [ $( echo -e "$PGVER\n8.3"|sort -gt. -k1 -k2|head -n1 ) = $PGVER ] && echo false || echo true) pg82 = $(shell test $(PGVER) "<" "8.2" && echo "false" || echo "true") sed -ie '/^pg83/s:shell test.*$:shell [ $( echo -e "$PGVER\\n8.3"|sort -gt. -k1 -k2|head -n1 ) = $PGVER ] \&\& echo false || echo true):' Makefile sed -ie '/^pg82/s:shell test.*$:shell [ $( echo -e "$PGVER\\n8.2"|sort -gt. -k1 -k2|head -n1 ) = $PGVER ] \&\& echo false || echo true):' Makefile
error: CRITICAL Job live_master_db crashed: <class ‘psycopg2.OperationalError’
https://jmorano.moretrix.com/2014/11/skytools-2-x-patch-for-postgresql-9-3-5/
The fix:
Add to ”sql/pgq/triggers/common.c” (in the skytools 2.1.13 source directory) the following line:
#include "access/htup_details.h"
5. Выполняем make:
$ sudo apt install postgresql-server-dev-10 $ make
6. Собираем .deb:
$ sudo mkdir /usr/share/doc/postgresql-doc-10 $ sudo checkinstall make install
6. Установим порцию python инструментов из пакета skytools:
$ python setup.py build $ sudo python setup.py install
Конфигурируем:
- Настройка тикера для PGQ:
$ cat ticker.ini [pgqadm] job_name = ticker_for_l_generator db = dbname=l_generator host=127.0.0.1 port=5432 user=postgres_migrate password=xxxxxxxxx # how often to run maintenance [seconds] maint_delay = 600 # how often to check for activity [seconds] loop_delay = 0.1 logfile = log/%(job_name)s.log pidfile = run/%(job_name)s.pid
2. Устанавливаем тикер в базу-источник (создается схема pgq со всем необходимым) и запускаем демон:
$ pgqadm.py ticker.ini install $ pgqadm.py ticker.ini ticker -d
3. Конфигурируем Лондист:
$ cat londiste.ini [londiste] job_name = londiste_l_genertor_migrate_to_rds provider_db = dbname=l_generator port=5432 host=127.0.0.1 user=postgres_migrate password=xxxxxxxxxxx subscriber_db = dbname=l_generator port=5432 host=database.eu-west-1.rds.amazonaws.com user=l_generator password=xxxxxxxxx # max locking time on provider (in seconds, float) # lock_timeout = 100 # it will be used as sql ident so no dots/spaces pgq_queue_name = londiste_queue logfile = log/%(job_name)s.log pidfile = run/%(job_name)s.pid
4. Устанавливаем Лондист в провайдер и сабскрайбер (создается схема londiste со всем необходимым):
Install Londiste:
$ londiste.py londiste.ini provider install $ londiste.py londiste.ini subscriber install
5. Запускаем процесс репликации (пока еще не добавили таблицы для отслеживания):
Launch replication:
$ londiste.py londiste.ini replay -d
6. Добавляем таблицы в репликацию:
londiste.py londiste.ini provider add public.ad_system public.ads londiste.py londiste.ini subscriber add public.ad_system public.ads
можно добавить все таблицы разом (но могут возникнуть ошибки по некоторым):
londiste.py londiste.ini provider tables | xargs londiste.py lonidste.ini subscriber add
Возможные ошибки:
psycopg2.extensions.QueryCanceledError: canceling statement due to statement timeout
Создание триггера не укладывается в заданный интервал statement_timeout. Londiste вызывает SET LOCAL statement_timeout = %d перекрывая тем самым системные настройки.
Изменяется параметр в конфиге лондиста параметром (по умолчанию = 10 сек):
lock_timeout = 100
psycopg2.InternalError: need key column
Нет ни одного индекса в таблице provider-а. Необходмо создать индекс:
ALTER TABLE ONLY ads_tmp ADD CONSTRAINT ads_tmp_pkey PRIMARY KEY (id);
7. Добавляем последовательности (сиквенсы) в репликацию:
londiste.py londiste.ini provider add-seq public.ad_system_id_seq londiste.py londiste.ini subscriber add-seq public.ad_system_id_seq
можно добавить все сиквенсы разом:
londiste.py londiste.ini londiste.ini provider add-seq --all londiste.py londiste.ini londiste.ini subscriber add-seq --all
Наблюдаем за процессом репликации:
Статус на провайдере в консоли psql:
Тут лаг — это отставание subscriber от provider. LastSeen — когда в прошлый раз сверялась очередь, Londiste работает с Batch — так называемыми пачками.
SELECT queue_name, consumer_name, lag, last_seen FROM pgq.get_consumer_info();
queue_name | consumer_name | lag | last_seen ----------------+-----------------------------------------+-----------------+----------------- londiste_queue | londiste_l_genertor_migrate_to_rds | 00:00:52.128794 | 00:00:51.350834 (1 row)
Статус тикера:
$ pgqadm.py ticker.ini status ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Postgres version: 10.1 PgQ version: 2.1.8 Event queue Rotation Ticker TLag ------------------------------------------------------------------------------ londiste_queue 3/7200s 500/3s/60s 27s ------------------------------------------------------------------------------ Consumer Lag LastSeen ------------------------------------------------------------------------------ londiste_queue: londiste_l_genertor_migrate_to_rds 27s 27s londiste_l_genertor_migrate_to_rds_copy 207s 147s ------------------------------------------------------------------------------
Статус subscriber:
$ londiste.py londiste.ini subscriber tables Table State public.ad_system ok public.ads in-copy public.adv_creator - public.adwords_disabled_ads - public.alembic_version -
Какие переносятся последовательности:
$ londiste.py londiste.ini subscriber seqs public.ad_system_id_seq public.ads_id_seq
ССЫЛКИ:
https://wiki.postgresql.org/wiki/Londiste_Tutorial_%28Skytools_2%29
http://www.tothenew.com/blog/postgresql-on-linux-migration-to-aws-postgresql-rds-using-londiste-daemon-no-downtime/
https://wiki.dieg.info/skytools#upravlenie_skytools_2112
http://evtuhovich.ru/blog/2009/05/22/live-table-migration/
https://wiki.postgresql.org/wiki/PGQ_Tutorial
https://wiki.postgresql.org/images/2/28/Moskva_DB_Tools.v3.pdf
https://www.pgcon.org/2009/schedule/attachments/101_Londiste3.pdf
https://aws.amazon.com/ru/rds/postgresql/details/ — используя роль репликации сессий (ALTER ROLE REPLICATION);