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

Каков вывод команды:

tail /var/discourse/shared/standalone/log/var-log/postgres/current
root@ubuntu-s-1vcpu-1gb-nyc3-01:/var/discourse# tail /var/discourse/shared/standalone/log/var-log/postgres/current
	                INNER JOIN (SELECT topic_id, GREATEST(COUNT(*), 1) AS count
	             FROM posts
	             WHERE created_at >= '2025-02-01 04:44:07.521324'
	               AND deleted_at IS NULL
	               AND NOT hidden
	               AND post_type = 1
	               AND user_id <> -1
	             GROUP BY topic_id) c ON tt.topic_id = c.topic_id
	                WHERE tt.topic_id = top_topics.topic_id
	                  AND tt.daily_posts_count <> c.count
root@ubuntu-s-1vcpu-1gb-nyc3-01:/var/discourse# vim shared/standalone/log/var-log/postgres/current
root@ubuntu-s-1vcpu-1gb-nyc3-01:/var/discourse#
root@ubuntu-s-1vcpu-1gb-nyc3-01:/var/discourse#
root@ubuntu-s-1vcpu-1gb-nyc3-01:/var/discourse# cat shared/standalone/log/var-log/postgres/current
2025-02-02 04:42:42.765 UTC [542] LOG:  запуск PostgreSQL 13.18 (Debian 13.18-1.pgdg120+1) на архитектуре x86_64-pc-linux-gnu, скомпилирован компилятором gcc (Debian 12.2.0-14) 12.2.0, 64-разрядная
2025-02-02 04:42:42.768 UTC [542] LOG:  прослушивание IPv4-адреса "0.0.0.0", порт 5432
2025-02-02 04:42:42.768 UTC [542] LOG:  прослушивание IPv6-адреса "::", порт 5432
2025-02-02 04:42:42.779 UTC [542] LOG:  прослушивание Unix-сокета "/var/run/postgresql/.s.PGSQL.5432"
2025-02-02 04:42:42.804 UTC [561] LOG:  система баз данных была прервана; последнее известное состояние активности на 2025-02-02 04:37:10 UTC
2025-02-02 04:42:43.209 UTC [561] LOG:  система баз данных была некорректно завершена; выполняется автоматическое восстановление
2025-02-02 04:42:43.221 UTC [561] LOG:  повторное применение начинается с позиции 2/DB0B59D0
2025-02-02 04:42:43.264 UTC [561] LOG:  недопустимая длина записи в позиции 2/DB22D540: ожидалось 24, получено 0
2025-02-02 04:42:43.264 UTC [561] LOG:  повторное применение завершено в позиции 2/DB22D518
2025-02-02 04:42:43.347 UTC [542] LOG:  система баз данных готова принимать подключения
2025-02-02 04:43:49.036 UTC [1273] discourse@discourse LOG:  длительность: 584.511 мс  оператор: UPDATE topic_hot_scores thsOrig
	SET
	    recent_likes = COALESCE(new_values.likes_count, 0),
	    recent_posters = COALESCE(new_values.unique_participants, 0),
	    recent_first_bumped_at = COALESCE(new_values.first_bumped_at, ths.recent_first_bumped_at)
	FROM
	  topic_hot_scores ths
	  LEFT OUTER JOIN
	  (
	    SELECT
	        t.id AS topic_id,
	        COUNT(DISTINCT p.user_id) AS unique_participants,
	        (
	          SELECT COUNT(distinct pa.user_id)
	          FROM post_actions pa
	          JOIN posts p2 ON p2.id = pa.post_id
	          WHERE p2.topic_id = t.id
	            AND p2.post_type = 1
	            AND p2.deleted_at IS NULL
	            AND p2.user_deleted = false
	            AND pa.post_action_type_id = 2 -- тип действия для 'лайк'
	            AND pa.created_at >= '2025-01-26 04:43:48.403603'
	            AND pa.deleted_at IS NULL
	        ) AS likes_count,
	        MIN(p.created_at) AS first_bumped_at
	    FROM
	        topics t
	    JOIN
	        posts p ON t.id = p.topic_id
	    WHERE
	        p.created_at >= '2025-01-26 04:43:48.403603'
	        AND t.archetype <> 'private_message'
	        AND t.deleted_at IS NULL
	        AND p.deleted_at IS NULL
	        AND p.user_deleted = false
	        AND t.created_at <= '2025-02-02 04:43:48.403603'
	        AND t.bumped_at >= '2025-01-26 04:43:48.403603'
	        AND p.created_at < '2025-02-02 04:43:48.403603'
	        AND p.created_at >= '2025-01-26 04:43:48.403603'
	        AND p.post_type = 1
	    GROUP BY
	        t.id
	  ) AS new_values
	ON ths.topic_id = new_values.topic_id

	WHERE thsOrig.topic_id = ths.topic_id

2025-02-02 04:44:04.629 UTC [1273] discourse@discourse LOG:  длительность: 153.751 мс  оператор: WITH x AS (SELECT
	                    u.id user_id,
	                    SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 2 THEN 1 ELSE 0 END) likes_received,
	                    SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 1 THEN 1 ELSE 0 END) likes_given,
	                    COALESCE((SELECT COUNT(topic_id) FROM topic_views AS v WHERE v.user_id = u.id AND v.viewed_at > '2025-02-01 04:44:04.456893'), 0) topics_entered,
	                    COALESCE((SELECT COUNT(id) FROM user_visits AS uv WHERE uv.user_id = u.id AND uv.visited_at > '2025-02-01 04:44:04.456893'), 0) days_visited,
	                    COALESCE((SELECT SUM(posts_read) FROM user_visits AS uv2 WHERE uv2.user_id = u.id AND uv2.visited_at > '2025-02-01 04:44:04.456893'), 0) posts_read,
	                    SUM(CASE WHEN t2.id IS NOT NULL AND ua.action_type = 4 THEN 1 ELSE 0 END) topic_count,
	                    SUM(CASE WHEN p.id IS NOT NULL AND t.id IS NOT NULL AND ua.action_type = 5 THEN 1 ELSE 0 END) post_count
	                  FROM users AS u
	                  LEFT OUTER JOIN user_actions AS ua ON ua.user_id = u.id AND COALESCE(ua.created_at, '2025-02-01 04:44:04.456893') > '2025-02-01 04:44:04.456893'
	                  LEFT OUTER JOIN posts AS p ON ua.target_post_id = p.id AND p.deleted_at IS NULL AND p.post_type = 1 AND NOT p.hidden
	                  LEFT OUTER JOIN topics AS t ON p.topic_id = t.id AND t.archetype = 'regular' AND t.deleted_at IS NULL AND t.visible
	                  LEFT OUTER JOIN topics AS t2 ON t2.id = ua.target_topic_id AND t2.archetype = 'regular' AND t2.deleted_at IS NULL AND t2.visible
	                  LEFT OUTER JOIN categories AS c ON t.category_id = c.id
	                  WHERE u.active
	                    AND u.silenced_till IS NULL
	                    AND u.id > 0
	                  GROUP BY u.id)
	      UPDATE directory_items di SET
	               likes_received = x.likes_received,
	               likes_given = x.likes_given,
	               topics_entered = x.topics_entered,
	               days_visited = x.days_visited,
	               posts_read = x.posts_read,
	               topic_count = x.topic_count,
	               post_count = x.post_count
	      FROM x
	      WHERE
	        x.user_id = di.user_id AND
	        di.period_type = 5 AND (
	        di.likes_received <> x.likes_received OR
	        di.likes_given <> x.likes_given OR
	        di.topics_entered <> x.topics_entered OR
	        di.days_visited <> x.days_visited OR
	        di.posts_read <> x.posts_read OR
	        di.topic_count <> x.topic_count OR
	        di.post_count <> x.post_count )


2025-02-02 04:44:07.657 UTC [1400] discourse@discourse LOG:  длительность: 135.675 мс  оператор: UPDATE top_topics
	                SET daily_posts_count = c.count
	                FROM top_topics tt
	                INNER JOIN (SELECT topic_id, GREATEST(COUNT(*), 1) AS count
	             FROM posts
	             WHERE created_at >= '2025-02-01 04:44:07.521324'
	               AND deleted_at IS NULL
	               AND NOT hidden
	               AND post_type = 1
	               AND user_id <> -1
	             GROUP BY topic_id) c ON tt.topic_id = c.topic_id
	                WHERE tt.topic_id = top_topics.topic_id
	                  AND tt.daily_posts_count <> c.count

Если вы видите такой вывод после остановки контейнера app, это может означать, что к базе данных всё ещё что-то подключено. Проверьте pg_stat_activity, чтобы попытаться изолировать источник подключения. Вы можете попробовать остановить эти службы в контейнере app, чтобы сузить круг поиска.

./launcher start app
./launcher enter app
sv stop nginx
sv stop unicorn
1 лайк

Я только что проверил, и вижу только

2025-02-02 12:06:05.808 UTC [48] LOG:  received smart shutdown request

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

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

Альтернативно, можно попытаться завершить все установленные сессии базы данных и быстро остановить службу postgres (в идеале до того, как клиентские приложения переподключатся), а затем попробовать выполнить повторную сборку после подтверждения чистой остановки базы данных по логам. Однако я настоятельно рекомендую сначала определить влияние на ваши клиентские приложения, перечисленные в pg_stat_activity, прежде чем завершать их подключения.

Вот пример команды, которую можно выполнить для завершения клиентских подключений и остановки postgres внутри контейнера app после предварительной остановки nginx и unicorn.

sudo -u postgres psql -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid();" && sv stop postgres
3 лайка

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

5 лайков

Сначала большое спасибо! Ручная остановка служб внутри контейнера, судя по всему, помогла, и я смог выполнить двойную пересборку контейнера для обновления (с корректировкой переменных локали, как обсуждалось выше — примечание: я проверил документацию по установке и не думаю, что там упоминаются локали; возможно, это стоило бы добавить).

К сожалению, анализ проблемных процессов не дал однозначных результатов. Единственное, что я вижу, — это процессы, связанные с Postgres, такие как WalWriter, AutoVacuum и т. д. Единственная зацепка: после перезагрузки системы, а также после изменений индексов при обновлениях, я обычно наблюдаю высокую нагрузку на CPU от postgres примерно в течение получаса.
И когда я сегодня после перезагрузки проверил pg_stat_activity, я увидел два долго выполняющихся запроса (по крайней мере, если я правильно понимаю значения столбцов):

SELECT "posts"."id" FROM "posts" INNER JOIN "topics" ON "topics"."deleted_at" IS NULL AND "topics"."id" = "posts"."topic_id" LEFT JOIN post_search_data ON post_id = posts.id WHERE "posts"."deleted_at" IS NULL AND (posts.raw != '') AND (topics.deleted_at IS NULL) AND (post_search_data.locale IS NULL OR post_search_data.locale != 'de' OR post_search_data.version != 5) ORDER BY posts.id DESC LIMIT 20000

и

SELECT "optimized_images".* FROM "optimized_images" WHERE "optimized_images"."upload_id" = 13 AND "optimized_images"."height" = 32 AND "optimized_images"."width" = 32 LIMIT 1

После упомянутых 30 минут первый запрос, судя по всему, завершился, и нагрузка на CPU от postgres теперь в норме.
Я не понимаю, почему эти два запроса выполняются так долго, и ещё меньше — почему второй запрос всё ещё отображается в pg_stat_activity более чем через час, но возможно, именно такие долго выполняющиеся запросы мешали службе postgres корректно завершить работу при попытке её пересобрать ранее.

Если у вас есть какие-либо идеи по этому поводу, буду очень признателен. Но возможно, это также стоит обсудить в отдельной теме (если так, просто дайте знать, и я отредактирую этот пост).

Связанные скриншоты:

2 лайка

Рады слышать, что это сработало! Я теперь включил эти шаги в первый пост.

Что касается высокой нагрузки на процессор postgres при запуске, похоже, вы сталкивались с той же проблемой даже до обновления версии PG. Если так, то это не связано с обновлением. (В любом случае, после обновления версии PG рекомендуется выполнить vacuum. См. задачи после обновления.)

Низкая производительность базы данных/запросов может быть вызвана множеством причин. Это могут быть повреждённые индексы в базе данных, недостаточно мощный хост, ошибка в Discourse, приведшая к появлению проблемного запроса и т. д. Возможно, поможет создание темы в канале Support для решения этой проблемы.

4 лайка

6 сообщений были перенесены в новую тему: Сайт недоступен после обновления (4 февраля 2025)

13 сообщений были перенесены в новую тему: Ошибка обновления PostgreSQL в Китае

Для меня ничего не работает.
Я создал тему: Errno::ENOENT: No such file or directory @ rb_sysopen - /etc/postgresql/15/main/postgresql.conf

Может кто-нибудь подсказать, как это исправить?

2 лайка

На нескольких сайтах на старых серверах сегодня мне пришлось выполнить

chown -R 101:104 /var/discourse/shared/standalone/postgres_*

Я почти уверен, что речь шла о нескольких годах и более старых версиях Ubuntu (где были другие идентификаторы пользователей).

2 лайка

Это интересно. Я обновил сайт, который не обновлялся около года, и всё прошло идеально гладко. Версия была v3.2.0.beta4+253.

2 лайка

Я хочу обновить свой экземпляр Discourse, но хочу оставить базу данных на Postgres 13. Это возможно?

1 лайк

Да, см. этот раздел официальных инструкций:

3 лайка

Есть ли здесь инструкции для экземпляра с двумя контейнерами? При беглом просмотре я этого не увидел, и поиск тоже ничего не дал.

1 лайк

Это уже описано в разделе “Настройка контейнера данных” выше.

1 лайк

Эта команда ничего не меняет

1 лайк

Как проверить, какая версия PostgreSQL у меня установлена?

Редактирование: неважно, я разобрался.

У меня есть несколько серверов с локали en_GB.UTF-8, и следуя инструкциям в начале темы, я не продвигаюсь далеко:

./launcher stop app 
x86_64 arch detected.
+ /usr/bin/docker stop -t 600 app
app
discourse@sands:/var/discourse$ docker run --rm --entrypoint=/bin/bash -e LANG='en_GB.UTF-8' -v /var/discourse/shared/standalone/postgres_data:/var/lib/postgresql/13/data -v /var/discourse/shared/standalone/postgres_data_new:/var/lib/postgresql/15/data tianon/postgres-upgrade:13-to-15 -c 'sed -i "s/^# $LANG/$LANG/" /etc/locale.gen && locale-gen && apt-get update && apt-get install -y postgresql-13-pgvector postgresql-15-pgvector && docker-upgrade'
Generating locales (this might take a while)...
  en_GB.UTF-8... done
  en_US.UTF-8... done
Generation complete.
Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]
Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Get:4 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg InRelease [129 kB]
Get:5 http://deb.debian.org/debian bookworm/main amd64 Packages [8,792 kB]
Get:6 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [13.5 kB]
Get:7 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [243 kB]
Get:8 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg/main amd64 Packages [360 kB]
Get:9 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg/13 amd64 Packages [2,571 B]
Get:10 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg/15 amd64 Packages [2,584 B]
Fetched 9,798 kB in 2s (4,547 kB/s)
Reading package lists...
Reading package lists...
Building dependency tree...
Reading state information...
The following NEW packages will be installed:
  postgresql-13-pgvector postgresql-15-pgvector
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 597 kB of archives.
After this operation, 1,540 kB of additional disk space will be used.
Get:1 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg/main amd64 postgresql-13-pgvector amd64 0.8.0-1.pgdg120+1 [297 kB]
Get:2 http://apt.postgresql.org/pub/repos/apt bookworm-pgdg/main amd64 postgresql-15-pgvector amd64 0.8.0-1.pgdg120+1 [300 kB]
debconf: delaying package configuration, since apt-utils is not installed
Fetched 597 kB in 0s (1,274 kB/s)
Selecting previously unselected package postgresql-13-pgvector.
(Reading database ... 13891 files and directories currently installed.)
Preparing to unpack .../postgresql-13-pgvector_0.8.0-1.pgdg120+1_amd64.deb ...
Unpacking postgresql-13-pgvector (0.8.0-1.pgdg120+1) ...
Selecting previously unselected package postgresql-15-pgvector.
Preparing to unpack .../postgresql-15-pgvector_0.8.0-1.pgdg120+1_amd64.deb ...
Unpacking postgresql-15-pgvector (0.8.0-1.pgdg120+1) ...
Setting up postgresql-13-pgvector (0.8.0-1.pgdg120+1) ...
Setting up postgresql-15-pgvector (0.8.0-1.pgdg120+1) ...
Processing triggers for postgresql-common (267.pgdg120+1) ...
debconf: unable to initialize frontend: Dialog
debconf: (TERM is not set, so the dialog frontend is not usable.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
Building PostgreSQL dictionaries from installed myspell/hunspell packages...
Removing obsolete dictionary files:
Performing Consistency Checks
-----------------------------
Checking cluster versions                                   ok

*failure*
Consult the last few lines of "/var/lib/postgresql/15/data/pg_upgrade_output.d/20250207T165542.724/log/pg_upgrade_server.log" for
the probable cause of the failure.

connection to server on socket "/var/lib/postgresql/.s.PGSQL.50432" failed: No such file or directory
	Is the server running locally and accepting connections on that socket?

could not connect to source postmaster started with the command:
"/usr/lib/postgresql/13/bin/pg_ctl" -w -l "/var/lib/postgresql/15/data/pg_upgrade_output.d/20250207T165542.724/log/pg_upgrade_server.log" -D "/var/lib/postgresql/13/data" -o "-p 50432 -b  -c listen_addresses='' -c unix_socket_permissions=0700 -c unix_socket_directories='/var/lib/postgresql'" start
Failure, exiting

Сталкивался ли кто-то ещё с этой проблемой? Есть ли у кого-нибудь какие-либо предложения?

3 лайка