升級 PostgreSQL 主要版本

PostgreSQL 的版本從 8.3 之後,就是以 X.Y 當成是主要版本(major release),而每個版本都會有小修正的次要版本 X.Y.Z (minor release)。若要升級主要版本,例如從 9.3 升級至 9.4 ,因為主要版本升級會加入一些新功能,而系統資料表的配置(layout of system tables)則會改變,所以需要使用 dump / restore 來重新構建系統資料表(是的,很麻煩),在 PostgreSQL 升級主要版本前,可以用 pg_upgrade 來升級。升級的流程如下,以 MacOS X 底下 homebrew 安裝為例:

  1. 停止 postgres daemon 傳統用法是透過 service 來控制 /etc/rc.d/ (或 /usr/local/etc/rc.d) 底下的 scripts 來控制 daemons,例如
    $ service stop postgres
    
    但 MacOS X 則是使用 /Library/LaunchAgents/Library/LaunchDaemons 底下的 plist 來控制,所以先將其 unload (同時也會呼叫 pg_ctl 去停止 postgres 運作):
    $ launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist
    
  2. 將舊資料庫儲存位置更名 homebrew 預設會將 PostgreSQL 的資料庫儲存於 /usr/local/var/postgres 底下,因為我是從 9.3 升級至 9.4,所以複製為 postgres93 (whatever)
    $ mv /usr/local/var/postgres /usr/local/var/postgres93 
    
  3. 升級現有版本之 postgres 及相關函式庫 如果你有使用相關延伸函式庫(例如 postgis),請記得也一起升級
    $ brew upgrade postgresql postgis
    
  4. 備份 雖說可以用 pg_upgrade 更新,但還是把所有資料庫備份出來比較保險
    $ pg_dumpall > postgres93.dbout
    
  5. 建立新的主要版本資料儲存庫 新建儲存庫
    $ mkdir /usr/local/var/postgres
    $ initdb -D /usr/local/var/postgres
    
    使用 launchctl 載入 postgresql (記得不要在 tmux or screen 內執行,否則會有 permission 的問題)
    $ launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist 
    
  6. 使用 pg_upgrade 升級主要版本 因為需要用到舊版執行檔,所以記得不要太快移除舊版本(這也就是使用 homebrew 的好處,每個第三方套件都會裝在 /usr/local/Cellar 底下,再連結到 /usr/local 中相關的目錄位置) 四個參數如下: --old-datadir: 舊版本的資料儲存目錄, --new-datadir: 新版本的資料儲存目錄, --old-bindir: 舊版本的執行檔目錄, --new-bindir: 新版本的執行檔目錄。 確認上述的目錄和版本後,接下來就可以使用 pg_upgrade 來升級
    pg_upgrade
    --old-datadir /usr/local/var/postgres93
    --new-datadir /usr/local/var/postgres 
    --old-bindir /usr/local/Cellar/postgresql/9.3.5_1/bin 
    --new-bindir /usr/local/Cellar/postgresql/9.4.0/bin
    
    升級過程會確認版本,然後 dump 舊有資料庫,並轉成新版本:
    Performing Consistency Checks
    -----------------------------
    Checking cluster versions                                   ok
    Checking database user is a superuser                       ok
    Checking for prepared transactions                          ok
    Checking for reg* system OID user data types                ok
    Checking for contrib/isn with bigint-passing mismatch       ok
    Checking for invalid "line" user columns                    ok
    Creating dump of global objects                             ok
    Creating dump of database schemas
                                                            ok
    Checking for presence of required libraries                 ok
    Checking database user is a superuser                       ok
    Checking for prepared transactions                          ok
    ...(略)
    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
    
  7. 新版本資料庫最佳化及刪除舊版本資料 升級完畢之後,會在你執行 pg_upgrade 的目錄底下自動產生兩個 shell script 檔案, 執行 analyze_new_cluster.sh 可以最佳化資料庫($PATH_TO_POSTGRESQL/bin/vacuumdb" --all --analyze-in-stages),執行 delete_old_cluster.sh 則會把舊版本的目錄刪除(其實就是`rm -rf postgres.old)
    ./analyze_new_cluster.sh && delete_old_cluster.sh
    
  8. 升級 Postgis extension 若有安裝 postgis extension,所以就順便升級
    spatial_db=# ALTER EXTENSION postgis UPDATE TO "2.1.5";
    spatial_db=# ALTER EXTENSION postgis_topology UPDATE TO "2.1.5";
    

References:

pg_upgrade

Comments

comments powered by Disqus