У меня есть производственный сервер с Postgres 9.4. База данных> 10 ГБ. Возможно ли обновление до Postgres 9.5 без простоев и без потери данных?
В руководствах по обновлению рекомендуется останавливать Postgres во время выполнения sudo pg_upgradecluster 9.4 main
, но это может занять много времени. Обновление кластера 10 ГБ может занять несколько часов!
Я тоже пробовал pg_dump mydb > db.sql
. Удаление базы данных и повторная вставка дампа в PG 9.4 (psql -d mydb -f db.sql
) заняло около 50 минут.
Но вставка дампа в PG 9.5 закончилась только через более чем 7 часов. Особенно создание индекса было очень медленным ...
2016-07-18 00:13:55 CEST [60358-5] ERROR: canceling autovacuum task
2016-07-18 00:13:55 CEST [60358-6] CONTEXT: automatic analyze of table ...
2016-07-18 00:36:20 CEST [60366-1] ERROR: canceling autovacuum task
2016-07-18 00:36:20 CEST [60366-2] CONTEXT: automatic analyze of table ...
2016-07-18 04:21:40 CEST [60361-1] ERROR: canceling autovacuum task
2016-07-18 04:21:40 CEST [60361-2] CONTEXT: automatic analyze of table ...
2016-07-18 07:55:19 CEST [61316-1] ERROR: canceling autovacuum task
2016-07-18 07:55:19 CEST [61316-2] CONTEXT: automatic analyze of table ...
Так что ни pg_upgradecluster
ни pg_dump
приемлемое решение. Даже с PG 4 у вас будет минимум 50 минут простоя. Следовательно: как можно обновить базы данных на производственных серверах или больших кластерах master-slave без простоев и потерь данных?
Без некоторой магии кластеризации простои невозможны.
Некоторые другие возможности:
pg_upgrade
с --link
вариант. При использовании этой опции исходные файлы БД не копируются, а жестко связаны с новым каталогом, что значительно ускоряет процесс. Обратите внимание, что это навсегда изменит исходные файлы БД.pg_dump
и восстановить в новой базе данных. Вы можете значительно сократить необходимое время, отключив синхронную запись в новой базе данных (fsync = false
в конфигурационном файле нового экземпляра PG)pg_dump
загрузить по сети дамп в новый экземпляр. Когда закончите, поменяйте порты местами и используйте новый экземпляр.Я думаю, вы уже решили это, так что, возможно, для других с аналогичными проблемами.
После нескольких лет работы с postgresql с версии 8.4 до последней версии 9.6 я бы порекомендовал для этих случаев - не «обновляться». Если возможно, создайте новую машину или новый облачный экземпляр с последней версией используемой вами ОС (очень важно - предотвращает множество проблем) и новейшей версией pg и дублирующими данными.
Как дублировать данные зависит от вашего приложения, версии PostgreSQL и окружающей среды. База данных ~ 10 ГБ не такая большая, так что вам подойдет. Я работаю с dbs> 400 ГБ, так что представьте себе множество проблем ...
Я видел варианты всех этих сценариев в реальной жизни. Так что веселитесь! Скрещиваю пальцы :-)
Обновление (почти) без простоев должно быть возможно с логический. По крайней мере, для PostgreSQL> = 9.4 и новее он должен работать.
Это относительно новый проект (2016 г.), основанный на коде из Двунаправленная репликация для PostgreSQL. Для установки вам понадобится Репозиторий 2ndQuadrant.
Описание использования в README, требуется перезапуск БД (необходимо обновить конфигурацию репликации), но, по крайней мере, это не должно вызывать простоя в несколько часов.
в отличие репмгр, pglogical
предназначен для одноразовой репликации БД, что займет намного больше времени, чем копирование двоичных файлов WAL.
Сначала включите расширение для каждой БД, которую необходимо скопировать (обновить):
CREATE EXTENSION pglogical;
В настоящее время все команды необходимо выполнять от имени суперпользователя (postgres
). Начнем с создания «главного узла» (provider
):
SELECT pglogical.create_node(
node_name := 'provider1',
dsn := 'host=providerhost port=5432 dbname=db'
);
и пометьте схемы для репликации:
SELECT pglogical.replication_set_add_all_tables('default', ARRAY['public']);
и репликация последовательностей:
SELECT pglogical.replication_set_add_all_sequences('default', ARRAY['public']);
Обратите внимание, что для каждой таблицы требуется первичный ключ, иначе репликация не начнется. В отличие от других методов резервного копирования, здесь важна согласованность таблиц.
Продолжайте с «резервным узлом» (subscriber
)
SELECT pglogical.create_node(
node_name := 'subscriber1',
dsn := 'host=thishost port=5432 dbname=db'
);
и наконец запускаем репликацию:
SELECT pglogical.create_subscription(
subscription_name := 'subscription1',
provider_dsn := 'host=providerhost port=5432 dbname=db'
);