官方有說明,依照說明進行就可以:https://wiki.archlinux.org/title/PostgreSQL#Upgrading_PostgreSQL
但,我太久沒去注意,所以依照程序進行時,發現我舊的資料庫是 16,目前版本是 18。升級程序需要舊的 16 的檔案才可以,所以這邊紀錄過程:
取得資料庫檔案所使用的版本
cat /var/lib/postgres/data/PG_VERSION
停止服務
因為是服務無法啟動才發現 postgresql 需要升級,所以就不需要停止服務。
安裝新版的檔案
這步驟也跳過了,因為每次都是全機升級,所以已經安裝好了。
搬移檔案
主要是把原來的 /var/lib/postgres/data 更名,並建立新的資料目錄。
sudo mv /var/lib/postgres/data /var/lib/postgres/olddata
sudo mkdir /var/lib/postgres/data /var/lib/postgres/tmp
sudo chown postgres:postgres /var/lib/postgres/data /var/lib/postgres/tmp
改用 postgres 使用者身份建立資料庫
sudo -u postgres -H /bin/bash
cd /var/lib/postgres/tmp
initdb -D /var/lib/postgres/data --locale=C.UTF-8 --encoding=UTF8 --data-checksums
升級
一樣是 postgres 使用者身份,執行 pg_upgrade 來升級
pg_upgrade -b /opt/pgsql-16/bin -B /usr/bin -d /var/lib/postgres/olddata -D /var/lib/postgres/data
我是在這步驟出錯的,因為我已經升級到 18。 /opt/pgsql-16/bin 這個目錄是安裝 postgresql-old-upgrade 套件才會有的,通常安裝了 postgresql 18,postgresql-old-upgrade 裡面的檔案就是 /opt/pgsql-17/bin
參考了 Grok 的回答,對 postgresql-old-upgrade 進行降級了,先到 https://archive.archlinux.org/packages/p/postgresql-old-upgrade/ 下載舊版的檔案 postgresql-old-upgrade-16.10-1-x86_64.pkg.tar.zst ,然後安裝
sudo pacman -U postgresql-old-upgrade-16.10-1-x86_64.pkg.tar.zst
再次執行 pg_upgrade,會發現有以下錯誤
error while loading shared libraries: libicui18n.so.76
error while loading shared libraries: libicuuc.so.76
只能再次安裝 icu76,Grok 說可以用 yay 安裝,此時要離開 postgres 身份來安裝。
yay -Ss icu76
安裝後,再次切換為 postgres 使用者帳號執行 pg_upgrade,這時候是說少了 libLLVM.so.20.1。又再離開 postgres 身份,用以下指令安裝 llvm 20
yay -Syu llvm20
再切換為 postgres 身份,執行 pg_upgrade,就順利完成了。
啟動服務
執行 exit 離開 postgres 身份,檢查以下檔案,主要是跟之前 /var/lib/postgres/olddata 目錄下的做比對。
/var/lib/postgres/data/postgresql.conf
/var/lib/postgres/data/pg_hba.conf
設定改好以後,啟動 postgresql 服務。
sudo systemctl start postgresql
清理
切換為 postgres 身份,執行清理
/usr/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
/usr/bin/vacuumdb --all --analyze-only
依照升級後的指令,執行
./delete_old_cluster.sh
刪除 olddata 跟 tmp
sudo rm -rf /var/lib/postgres/olddata
sudo rm -rf /var/lib/postgres/tmp
至此,大功告成。