업그레이드 실습#

작은 클러스터에서 2.17을 2.18로 업그레이드한 전 과정이며, 실행한 명령과 그 출력을 함께 담았습니다. 레퍼런스는 2.18로 업그레이드하기이고, 이 페이지는 실제로 해 보면 어떤 모습인지를 보여 줍니다.

여기 클러스터에는 그래프 하나와 평범한 테이블 하나가 있어, 둘 다 넘어오는 것을 볼 수 있습니다:

CREATE GRAPH social;
SET graph_path = social;
CREATE VLABEL person;
CREATE ELABEL knows;
CREATE (:person {name: 'Ann', age: 30}), (:person {name: 'Bo', age: 41});
MATCH (a:person {name: 'Ann'}), (b:person {name: 'Bo'}) CREATE (a)-[:knows {since: 2019}]->(b);
CREATE PROPERTY INDEX ON person (name);
CREATE TABLE audit (id serial primary key, note text);
INSERT INTO audit(note) VALUES ('before upgrade');

2.17에서 그것을 읽으면 이렇습니다:

MATCH (n:person)-[r:knows]->(m:person) RETURN n.name, r.since, m.name;
 name  | since | name
-------+-------+------
 "Ann" | 2019  | "Bo"

1. 옛 클러스터의 체크섬 설정 확인#

이것이 다음 단계의 플래그 하나를 좌우하며, 틀리면 업그레이드가 시작도 하기 전에 멈춥니다.

$OLD/bin/pg_controldata -D $OLDDATA | grep checksum
Data page checksum version:           0

0은 체크섬이 꺼져 있다는 뜻이며, PostgreSQL 17의 기본값입니다.

2. 옛 서버 정지#

$OLD/bin/ag_ctl -D $OLDDATA stop

3. 2.18 클러스터 초기화#

옛 클러스터가 0으로 나왔으므로 새 클러스터는 --no-data-checksums로 초기화해야 합니다. PostgreSQL 18은 체크섬을 기본으로 켜므로, 이 플래그를 빼는 것이 다음 절의 실패를 만듭니다.

$NEW/bin/initdb -D $NEWDATA -U postgres --encoding=UTF8 --no-data-checksums
$NEW/bin/pg_controldata -D $NEWDATA | grep checksum
Data page checksum version:           0

이제 두 클러스터가 서로 맞습니다.

맞지 않으면 어떻게 되는가#

그 플래그 없이 초기화한 2.18 클러스터를 상대로 pg_upgrade --check를 돌린 전체 출력입니다:

Performing Consistency Checks
-----------------------------
Checking cluster versions                                     ok

old cluster does not use data checksums but the new one does
Failure, exiting

두 번째 검사에서 멈추고 아무것도 바꾸지 않으므로, 새 클러스터를 다시 초기화하기만 하면 됩니다.

4. 호환성 확인#

$NEW/bin/pg_upgrade -b $OLD/bin -B $NEW/bin -d $OLDDATA -D $NEWDATA -U postgres --check
Performing Consistency Checks
-----------------------------
Checking cluster versions                                     ok
Checking database connection settings                         ok
Checking database user is the install user                    ok
Checking for prepared transactions                            ok
Checking for contrib/isn with bigint-passing mismatch          ok
Checking for valid logical replication slots                  ok
Checking for subscription state                               ok
Checking data type usage                                      ok
Checking for objects affected by Unicode update               ok
Checking for not-null constraint inconsistencies              ok
Checking for presence of required libraries                   ok
Checking database user is the install user                    ok
Checking for prepared transactions                            ok
Checking for new cluster tablespace directories               ok

*Clusters are compatible*

5. 업그레이드 실행#

$NEW/bin/pg_upgrade -b $OLD/bin -B $NEW/bin -d $OLDDATA -D $NEWDATA -U postgres

출력의 끝부분입니다:

Copying old pg_multixact/offsets to new server                ok
Deleting files from new pg_multixact/members                  ok
Copying old pg_multixact/members to new server                ok
Setting next multixact ID and offset for new cluster          ok
Resetting WAL archives                                        ok
Setting frozenxid and minmxid counters in new cluster         ok
Restoring global objects in the new cluster                   ok
Restoring database schemas in the new cluster                 ok
Copying user relation files                                   ok
Setting next OID for new cluster                              ok
Sync data directory to disk                                   ok
Creating script to delete old cluster                         ok
Checking for extension updates                                ok

Upgrade Complete
----------------
Some statistics are not transferred by pg_upgrade.
Once you start the new server, consider running these two commands:
    .../bin/vacuumdb -U postgres --all --analyze-in-stages --missing-stats-only
    .../bin/vacuumdb -U postgres --all --analyze-only
Running this script will delete the old cluster's data files:
    ./delete_old_cluster.sh

6. 새 서버를 기동하고 무엇이 넘어왔는지 확인#

$NEW/bin/ag_ctl -D $NEWDATA -l $NEW/logfile start
SELECT version();
 PostgreSQL 18.6 (AgensGraph 2.18.6.0) on x86_64-pc-linux-gnu, compiled by gcc ...

간선 속성까지 포함한 그래프입니다:

SET graph_path = social;
MATCH (n:person)-[r:knows]->(m:person) RETURN n.name, r.since, m.name;
 name  | since | name
-------+-------+------
 "Ann" | 2019  | "Bo"

속성 인덱스입니다:

\d social.person
                              Table "social.person"
   Column   |  Type   | Nullable |                     Default
------------+---------+----------+-------------------------------------------------
 id         | graphid | not null | graphid(graph_labid('social.person'), nextval(…))
 properties | jsonb   | not null | jsonb_build_object()
Indexes:
    "person_pkey" PRIMARY KEY, btree (id)
    "person_name_idx" btree ((properties.'name'))

그리고 평범한 테이블입니다:

SELECT * FROM audit;
 id |      note
----+----------------
  1 | before upgrade

7. 업그레이드 뒤에 할 일 셋#

통계#

$NEW/bin/vacuumdb -U postgres --all --analyze-in-stages

그래프 메타데이터#

바이너리 업그레이드는 ag_graphmeta를 빈 채로 두고 그래프를 무효로 표시하므로, 플래너의 스캔 쳐내기가 꺼져 있습니다:

SELECT graphname, graphmeta_valid FROM pg_catalog.ag_graph;
 graphname | graphmeta_valid
-----------+-----------------
 social    | f

그래프마다 한 번씩 다시 만드십시오:

SET graph_path = social;
SELECT regather_graphmeta();
NOTICE:  regathering graphmeta...
 regather_graphmeta
--------------------
 t
SELECT graphname, graphmeta_valid FROM pg_catalog.ag_graph;
 graphname | graphmeta_valid
-----------+-----------------
 social    | t

간선 레이블 통계#

업그레이드는 옛 통계 목표치를 그대로 가져오며, 그것은 2.17이 쓰던 값입니다:

SELECT attname, attstattarget FROM pg_attribute
WHERE attrelid = 'social.knows'::regclass AND attname IN ('start', 'end')
ORDER BY 1;
 attname | attstattarget
---------+---------------
 end     |         10000
 start   |         10000

10000은 큰 간선 레이블에서 실제로 계획 시간을 잡아먹을 만큼 높은 값이고, 2.18은 새 간선 레이블을 1000으로 만듭니다. 업그레이드한 레이블도 그에 맞추십시오:

ALTER TABLE social.knows ALTER COLUMN start SET STATISTICS 1000;
ALTER TABLE social.knows ALTER COLUMN "end" SET STATISTICS 1000;
ANALYZE social.knows;

8. 옛 클러스터 제거#

새 클러스터가 잘 돈다고 확신한 뒤에만 하십시오:

./delete_old_cluster.sh

그것을 실행하기 전까지 2.17 데이터 디렉터리는 그대로이므로, 새 서버를 정지하고 옛 서버를 기동해 되돌릴 수 있습니다. --link를 쓰지 않았다면 말입니다.