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:  starting PostgreSQL 13.18 (Debian 13.18-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
2025-02-02 04:42:42.768 UTC [542] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-02-02 04:42:42.768 UTC [542] LOG:  listening on IPv6 address "::", port 5432
2025-02-02 04:42:42.779 UTC [542] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-02-02 04:42:42.804 UTC [561] LOG:  database system was interrupted; last known up at 2025-02-02 04:37:10 UTC
2025-02-02 04:42:43.209 UTC [561] LOG:  database system was not properly shut down; automatic recovery in progress
2025-02-02 04:42:43.221 UTC [561] LOG:  redo starts at 2/DB0B59D0
2025-02-02 04:42:43.264 UTC [561] LOG:  invalid record length at 2/DB22D540: wanted 24, got 0
2025-02-02 04:42:43.264 UTC [561] LOG:  redo done at 2/DB22D518
2025-02-02 04:42:43.347 UTC [542] LOG:  database system is ready to accept connections
2025-02-02 04:43:49.036 UTC [1273] discourse@discourse LOG:  duration: 584.511 ms  statement: 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 -- 'like'의 action_type
	            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:  duration: 153.751 ms  statement: 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:  duration: 135.675 ms  statement: 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에 나열된 클라이언트 애플리케이션에 미칠 영향을 먼저 파악하는 것이 강력히 권장됩니다.

아래는 nginx와 unicorn을 먼저 중지한 후 app 컨테이너 내부에서 클라이언트 연결을 종료하고 postgres를 중지하기 위해 실행할 수 있는 샘플 명령입니다.

sudo -u postgres psql -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid();" && sv stop postgres
3개의 좋아요

간단한 업데이트를 알려드립니다: 데이터베이스가 정상적으로 종료되지 않은 경우 더 적절한 오류 메시지를 반환하도록 패치를 적용했습니다.

5개의 좋아요

우선 정말 감사합니다! 컨테이너 내부에서 수동으로 서비스를 중지한 것이 효과를 봤는지, 업그레이드를 위해 컨테이너를 두 번 다시 빌드하는 데 성공했습니다(위에서 논의된 대로 로케일 변수를 조정했습니다. 참고로: 설치 문서를 확인해 봤는데 로케일에 대한 언급이 없는 것 같습니다. 이 부분을 추가하면 좋겠다는 생각이 드네요).

불행히도 문제 있는 프로세스에 대한 분석은 결론을 내리지 못했습니다. 제가 볼 수 있는 것은 WalWriter, AutoVacuum 같은 Postgres 관련 항목뿐입니다. 제가 가진 유일한 단서는 시스템을 재부팅하거나 업데이트 시 인덱스를 변경한 후 약 30분 동안 Postgres의 CPU 부하가 높게 나타난다는 점입니다.
그리고 오늘 재부팅 후 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

aforementioned 30분 후, 첫 번째 쿼리는 완료된 것으로 보이며 Postgres의 CPU 부하는 이제 정상 수준입니다.
이 두 쿼리가 왜这么久 걸리는지, 그리고 두 번째 쿼리가 1시간 이상 지난 후에도 pg_stat_activity에 여전히 표시되는 이유는 더 잘 모르겠습니다. 하지만 어쩌면 이러한 장시간 실행 중인 쿼리가 이전에 재빌드 시도를 할 때 Postgres 서비스가 올바르게 종료되는 것을 막았을 수도 있습니다.

이 부분에 대해 단서가 있으시다면 정말 감사하겠습니다. 하지만 이 문제는 별도의 스레드로 이관해야 할 수도 있습니다(그렇다면 알려 주세요. 이 게시글을 수정하겠습니다).

관련 스크린샷:

2개의 좋아요

해결되었다니 다행입니다! 이제 해당 단계를 OP에 포함시켰습니다.

시작 시 postgres의 높은 CPU 사용량 문제에 대해, PG 버전 업데이트 이전부터 동일한 문제를 겪어왔다면 이는 업데이트와 무관할 것입니다. (그럼에도 불구하고, PG 버전 업데이트 후 vacuum을 실행하는 것이 권장됩니다. 업데이트 후 작업을 참고하세요.)

낮은 데이터베이스/쿼리 성능은 다양한 원인으로 발생할 수 있습니다. 데이터베이스의 손상된 인덱스, 자원이 부족한 호스트, 문제적인 쿼리를 도입한 Discourse의 버그 등이 그 원인이 될 수 있습니다. 이 문제를 해결하기 위해 Support 토픽을 여는 것이 도움이 될 수 있습니다.

4개의 좋아요

6개의 게시물이 새로운 주제(재구축 후 사이트 오프라인 (2025년 2월 4일))로 분리되었습니다.

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_*

여러 년이 경과되었고, 다른 사용자 ID를 가진 더 오래된 Ubuntu 버전이 관여되었을 것이라고 확신합니다.

2개의 좋아요

흥미롭네요. 약 1년 동안 업데이트되지 않았던 사이트를 업데이트했는데 완벽하게 순조롭게 진행되었습니다. 당시 버전은 v3.2.0.beta4+253이었습니다.

2개의 좋아요

Discourse 인스턴스를 업데이트하려고 하지만, 데이터베이스는 Postgres 13로 유지하고 싶습니다. 이것이 가능한가요?

1개의 좋아요

네, 공식 설명서의 이 부분을 참고해 주세요:

3개의 좋아요

여기 2컨테이너 인스턴스에 대한 설명서가 있나요? 대충 살펴봐도 보이지 않고, 검색해도 찾지 못했습니다.

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개의 좋아요