Обновление PostgreSQL 13

:warning: ВНИМАНИЕ! Если ваша база данных очень большая, вам потребуется много дополнительного дискового пространства (в 2 раза больше размера базы данных), и вы должны быть предельно осторожны при этом обновлении!

Мы только что внедрили изменения для обновления нашего Docker-образа до PostgreSQL 13. Любой администратор сайта, собирающий Discourse из командной строки, будет обновлен с предыдущей версии PostgreSQL 12 до PostgreSQL 13. Обратите внимание, что если вы откладывали обновление, когда выходило обновление PostgreSQL 12 еще в мае, вы можете пропустить это обновление и сразу перейти к PostgreSQL 13.

Если вы ранее откладывали обновление, измените шаблон PostgreSQL в app.yml с templates/postgres.10.template.yml на templates/postgres.template.yml.

Как и при любом обновлении, настоятельно рекомендуется сделать резервную копию перед выполнением любых действий.

Обновление

Официальное руководство по установке (один контейнер)

При следующей пересборке в конце вы увидите следующее сообщение:

-------------------------------------------------------------------------------------
ОБНОВЛЕНИЕ POSTGRES ЗАВЕРШЕНО

Старая база данных 12 сохранена в /shared/postgres_data_old

Чтобы завершить обновление, выполните повторную сборку с помощью команды:

./launcher rebuild app
-------------------------------------------------------------------------------------

Это означает, что обновление прошло успешно! Вам нужно просто выполнить новую пересборку, чтобы ваш сайт снова заработал.

Установка с использованием контейнера данных

Если вы работаете в среде с выделенным контейнером данных, основанным на образце, предоставленном в нашем репозитории discourse_docker, убедитесь, что вы корректно и безопасно останавливаете PostgreSQL.

В настоящее время у нас выполняются фоновые задания, выполняющие запросы длительностью в несколько минут, поэтому остановка веб-контейнера поможет контейнеру данных завершить работу безопасно.

./launcher stop web_only
./launcher stop data
./launcher rebuild data
./launcher rebuild data
./launcher rebuild web_only

Перед выполнением первой пересборки контейнера данных вы можете проследить за журналом PostgreSQL, чтобы убедиться, что он был остановлен корректно.

Выполнение команды tail -f shared/data/log/var-log/postgres/current должно вывести следующий журнал, если остановка прошла корректно:

2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

Ручное обновление / среды с ограниченным дисковым пространством

:warning::warning::warning:
ВЫ ДОЛЖНЫ СОЗДАТЬ РЕЗЕРВНУЮ КОПИЮ POSTGRES_DATA ПЕРЕД ПОПЫТКОЙ ЭТОГО
:warning::warning::warning:

Если вы работаете в среде с ограниченным дисковым пространством и у вас нет возможности получить больше места, вы можете попробовать следующее:

./launcher stop app #(или оба: web_only и data, если это ваш случай)
mkdir -p /var/discourse/shared/standalone/postgres_data_new
docker run --rm \
	-v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/12/data \
	-v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/13/data \
	tianon/postgres-upgrade:12-to-13
mv /var/discourse/shared/standalone/postgres_data /var/discourse/shared/standalone/postgres_data_old
mv /var/discourse/shared/standalone/postgres_data_new /var/discourse/shared/standalone/postgres_data
./launcher rebuild app #(или сначала data, а затем web_only, если это ваш случай)

По моим тестам, эта процедура требует менее 1x текущего размера базы данных в свободном пространстве.

Откладывание обновления

Если вам нужно отложить обновление при следующей пересборке, вы можете заменить шаблон PostgreSQL в файле app.yml, изменив "templates/postgres.template.yml" на "templates/postgres.12.template.yml".

Это не рекомендуется, так как некоторые администраторы сайтов могут забыть вернуть изменение обратно.

Дополнительные задачи после обновления

Оптимизация статистики PostgreSQL

После обновления новый PostgreSQL не будет иметь актуальной статистики таблиц. Вы можете сгенерировать её с помощью:

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
VACUUM VERBOSE ANALYZE;
\q
exit
exit

Или однострочная версия вышеуказанной команды:

/var/discourse/launcher run app "echo 'vacuum verbose analyze;' | su postgres -c 'psql discourse'"

Пересоздание индексов

Главной особенностью этого обновления является значительная экономия места в самой большой таблице каждого экземпляра — таблице post_timings и её индексах. После успешного обновления вам нужно будет выполнить команду для перестроения индексов и получить выгоду от этого.

cd /var/discourse
./launcher enter app
su postgres
psql
\connect discourse
REINDEX SCHEMA CONCURRENTLY public;
\q
exit
exit

Если вы сможете проверить размер post_timings до и после REINDEX, это будет отличной статистикой для публикации здесь!

Вы можете использовать следующий запрос для проверки 20 крупнейших объектов данных. Запустите его до и после перестроения индексов:

WITH RECURSIVE pg_inherit(inhrelid, inhparent) AS
    (select inhrelid, inhparent
    FROM pg_inherits
    UNION
    SELECT child.inhrelid, parent.inhparent
    FROM pg_inherit child, pg_inherits parent
    WHERE child.inhparent = parent.inhrelid),
pg_inherit_short AS (SELECT * FROM pg_inherit WHERE inhparent NOT IN (SELECT inhrelid FROM pg_inherit))
SELECT table_schema
    , TABLE_NAME
    , row_estimate
    , pg_size_pretty(total_bytes) AS total
    , pg_size_pretty(index_bytes) AS INDEX
    , pg_size_pretty(toast_bytes) AS toast
    , pg_size_pretty(table_bytes) AS TABLE
  FROM (
    SELECT *, total_bytes-index_bytes-COALESCE(toast_bytes,0) AS table_bytes
    FROM (
         SELECT c.oid
              , nspname AS table_schema
              , relname AS TABLE_NAME
              , SUM(c.reltuples) OVER (partition BY parent) AS row_estimate
              , SUM(pg_total_relation_size(c.oid)) OVER (partition BY parent) AS total_bytes
              , SUM(pg_indexes_size(c.oid)) OVER (partition BY parent) AS index_bytes
              , SUM(pg_total_relation_size(reltoastrelid)) OVER (partition BY parent) AS toast_bytes
              , parent
          FROM (
                SELECT pg_class.oid
                    , reltuples
                    , relname
                    , relnamespace
                    , pg_class.reltoastrelid
                    , COALESCE(inhparent, pg_class.oid) parent
                FROM pg_class
                    LEFT JOIN pg_inherit_short ON inhrelid = oid
                WHERE relkind IN ('r', 'p')
             ) c
             LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
  ) a
  WHERE oid = parent
) a
ORDER BY total_bytes DESC LIMIT 20;

Очистка старых данных

Для стандартной установки вы можете удалить старые данные в формате PG12 с помощью следующей команды:

cd /var/discourse
./launcher cleanup

Если у вас отдельный контейнер данных, вам нужно удалить резервную копию следующим образом:

rm -fr /var/discourse/shared/data/postgres_data_old/

Часто задаваемые вопросы

Исходный кластер не был остановлен корректно

Если вы получили ошибку обновления с вышеуказанным сообщением, вы можете попробовать более простой подход, чтобы вернуть систему в лучшее состояние.

Перезапустите старый контейнер с помощью ./launcher start app. Подождите несколько минут, пока он снова не запустится.

Теперь остановите его снова с помощью ./launcher stop app. После этого просмотрите логи, чтобы убедиться, что остановка была корректной:

tail -f shared/data/log/var-log/postgres/current
2020-05-13 18:33:33.457 UTC [36] LOG:  received smart shutdown request
2020-05-13 18:33:33.464 UTC [36] LOG:  worker process: logical replication launcher (PID 52) exited with exit code 1
2020-05-13 18:33:33.465 UTC [47] LOG:  shutting down
2020-05-13 18:33:33.479 UTC [36] LOG:  database system is shut down

Если логи выглядят как выше, вы можете снова попробовать выполнить обновление с помощью ./launcher rebuild app.

Значения lc_collate для базы данных “postgres” не совпадают

Эта ошибка возникает, если вы используете нестандартные локали для вашей базы данных. Было сообщено, что для успешного завершения необходимы 3 переменные. Убедитесь, что в секции env: вашего файла app.yml есть следующие 3 строки:

  LC_ALL: en_US.UTF-8
  LANG: en_US.UTF-8
  LANGUAGE: en_US.UTF-8

Замените en_US.UTF-8 на вашу локаль.

Каждое обновление запускает процесс обновления снова, т.е. цикл обновления

Когда это происходит, логи обновления содержат:

mv: cannot move '/shared/postgres_data' to '/shared/postgres_data_old/postgres_data': Directory not empty
mv: cannot move '/shared/postgres_data_new' to '/shared/postgres_data/postgres_data_new': Directory not empty

Это означает, что файлы от предыдущего обновления все еще остались. Переместите их в другое место перед продолжением.

Скрипты предложения после завершения обновления — нужно ли мне что-то делать?

После завершения обновления вы увидите вывод сообщения pg_upgrade:

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh

Вы можете безопасно проигнорировать это сообщение.

Я пропустил обновление PostgreSQL 12, что делать теперь?

Вы можете следовать стандартным инструкциям в начале этого руководства, и они обновят вашу версию до 13 без проблем.

Если вы следуете инструкциям для сред с ограниченным дисковым пространством, адаптируйте номера версий соответствующим образом.

38 лайков
PostgreSQL Details
Discourse 2.7.0.beta2 Release Notes
Forum offline due to failed rebuilds on Tests-Pass
Nginx upstream timed out (110: Connection timed out)
Firewall issue with running multiple containers after upgrade
Help! Problem with firewall/permissions and postgre?
PostgreSQL 13 update from PostgreSQL 10 fails
PostgreSQL 13 update from PostgreSQL 10 fails
Unrecognized error type (ActiveRecord::StatementInvalid: PG::ProgramLimitExceeded
Recover from filesystem backup: can't rebuild nor start
Rebuild error: Errno::ENOENT: No such file or directory @ rb_sysopen - /e tc/postgresql/13/main/pg_hba.conf
Discourse broken after upgrade
Upgrade Failed from 2.7.0.beta1 to 2.7.0.beta3
Invalid location error after update
Upgrade failed!
Upgrade failed: PostgreSQL version 13 ... not compatible with ... version 10.12
Improved Bookmarks with Reminders
Importing old database to latest version
Errors encountered when uploading images
What else do I need to take care of when self hosting?
Rebuild freezing when attempting to stop container
Backup failed due to PG/SQL errors
Restore Failing - Check Free Disk Space
Supported postgresql versions
Wrong Error Message for too short replies for Reply-by-Email
Upgrade Postgres with REALLY limited space
Upgrade Postgres with REALLY limited space
Postgres has 100% CPU for large databases, Discourse 2.7.7
Upgrade failing with FAILED TO BOOTSTRAP
Stuck in an update loop after PostgreSQL 13 update
Problem with rebuild Discourse at Docker
After Rebuild got error: postgres:10/main, Causes CPU to go high
Call AdminDashboardGeneralData.refresh_stats at boot?
ERROR: You are running an old version of the Discourse image
Failed to upgrade to v2.9.0beta3
Failed to upgrade to v2.9.0beta3
SMTP Settings in app.yml reset?
Upgrade container - keeping config and data
Site down after failed update: permission denied to create extension "unaccent"
Rebuild fails on db:migrate w/PG12
Update from 2.9.0 beta2 to beta4 failed (my site is down)
Performance optimisation tips
Upgrading from 2.4 to 2.9. Need slight assistance on what order to run the final commands & reboot in
Problem when updating Discourse Forum
Troubleshooting severe performance issues with latest Discourse?
Slow Profile Loads with 100GB+ database
Use Nginx Proxy Manager to manage multiple sites with Discourse
Horizontal loading slider
Upgrading Discourse from 2.6.0.beta2
PostgreSQL 15 update
Got a lot of "Failed to backfill 'Reader' badge" errors
Trouble updating discourse after some time - UPGRADE OF POSTGRES FAILED
Database size/maintenance
Upgrade gone sideways [deprecated Guest Gate plugin]
Upgrade Issues: Failed Upgrade due to Duplicate Key, Failed Snapshot Restore
2.7.0.beta2 upgrade failed with ERROR: duplicate key
Problem, rebuild to latest version
Urgent, upgraded build failed UniqueViolation