Docker環境下升級PostgreSQL


前段時間接到了要升級數據庫的需求,在公司大佬的指導下搞定了升級的方案,在此記錄一下。


查閱PostgreSQL官方文檔可以得知,官方提供了兩種方式對數據庫進行升級——pg_dumpall與pg_upgrade。

pg_dumpall是將數據庫轉儲成一個腳本文件,然后在新版數據庫中可以直接導入。這種方式操作簡單,跟着官方文檔就能輕松操作,但是明顯只適用於數據量較少的情況,在我的測試環境里,導入一個2g的數據庫用了將近10分鍾。

所以我這里選用的是pg_upgrade,這種方式是直接將數據文件升級到高版本,2g數據用時一分多鍾。

目前我手上的項目的PgSql是跑在在Docker上面的,版本是10.x,需求是升級到13.x,簡單講一下步驟:

  1. pg_upgrade需要用到新舊容器的bin跟data,所以首先將舊數據庫容器的bin還有data文件復制到服務器;
  2. 開啟一個PG13的容器,這個是后面用於服務的正式容器(下文稱為正式容器),然后另外開啟一個臨時容器(下文稱為臨時容器)用於升級數據文件,將這兩個容器的數據庫目錄映射到同一個目錄;
  3. PG13的容器內部會缺少很多PG10的運行庫,所以需要從舊容器中復制到臨時容器里;
  4. 臨時容器將數據升級后,由於跟正式容器的數據文件目錄映射到了同一個目錄,所以數據可以正常使用;

首先自然是拉取一個PG13的鏡像,然后放好別動:

docker pull postgres:13.1

創建升級目錄:

#創建備份目錄
mkdir /db_update/new_data

cd /db_update

#將舊數據庫容器的bin跟data復制出來
docker cp pgdb:/usr/local old_bin
docker cp pgdb:/usr/local old_share
docker cp pgdb:/var/lib/postgresql/data old_data

#授權
chmod -R 777 /db_update/old_data

此時目錄結構應該是這樣的:

 

  #新建一個正式容器,並映射data目錄,初始化完成后ctrl+c 退出
  docker run --name="pg13_new" -v "/db_update/new_data:/var/lib/postgresql/data/pgdata" -e POSTGRES_USER=dbuser -e POSTGRES_PASSWORD=123456 -e PGDATA=/var/lib/postgresql/data/pgdata postgres:13.1
#新建一個臨時容器,用於升級數據,映射PG10的bin跟data目錄,容器內的data跟正式容器映射到同一個目錄 docker run -dti --name="tmp" -v $(pwd)/old_bin:/usr/lib/postgresql/10 -v $(pwd)/old_share:/usr/share/postgresql/10 -v $(pwd)/new_data:/data/new_data -v $(pwd)/old_data:/data/old_data -e PGDATA:/data/new_data --privileged=true postgres:13.1 /bin/bash

容器創建完畢先放着,接下來做別的操作。在PG13內會缺失不少PG10所需運行文件(血淚教訓),可以從舊容器將相關文件復制過來。

#將舊容器的文件復制到本機
docker cp pgdb:/usr/lib /old_lib
docker cp pgdb:/lib /old_lib2

此時的目錄結構:

#將文件復制到升級容器
docker cp /old_lib tmp:/old_lib docker cp /old_lib2 tmp:/old_lib2 #將文件復制到對應目錄 docker exec -it tmp /bin/bash cp /old_lib/* /usr/lib/x86_64-linux-gnu/ cp /old_lib/* /usr/lib cp /old_lib2/* /lib

將文件復制完畢后即可以嘗試升級數據庫,不過仍有可能出現缺少運行庫的問題,同時也會有權限的問題,下面會展示如何解決這兩個問題。

 #切換數據庫用戶
su -postgres

#檢查是否可以升級,一連串的ok即表示可以執行數據庫文件的升級
/usr/lib/postgresql/13/bin/pg_upgrade -b /usr/lib/postgresql/10/bin -B /usr/lib/postgresql/13/bin -d /data/old_data -D /data/new_data -U dbuser -p 5433 -P 5434 -c

如果出現下圖的提示,那就是權限問題,授權一下即可解決。

 

 解決方法:

#在root用戶下執行
chown -R postgres/data/old_data

如果之后包權限錯誤 需權限 0700 則再執行
chmod -R 0700  /data/old_data

再次執行檢查升級命令,錯誤也再次出現:

 已經很多個ok了,所以別慌,執行more pg_upgrade_server.log可以查看具體錯誤

 圖中可以看出缺少了libstdc++.so.6這個文件,我們可以手動從舊容器里獲取這個文件復制到臨時容器里面去。

#新打開一個shell 窗口
cd /var/lib/docker/overlay2
#這條命令會顯示多個目錄的路徑,選擇其中之一就行了
find -name libstdc++.so.6
#創建一個文件夾
mkdir /old_lib3
#將庫文件復制過去
cp ./0928cba045d2d4cabf1f02fc2d4007e302c925393131c743390dc2266e0f1353/diff/usr/lib/x86_64-linux-gnu/libstdc++.so.6 /old_lib3
#復制到容器
docker cp /old_lib3/ tmp:/old_lib3/
docker exec -it tmp /bin/bash
cp /old_lib3/* /usr/lib/x86_64-linux-gnu/

 

 完成上面的步驟后,再次檢查是否可升級:

 

 看到這一連串ok並且沒有返回錯誤即代表可以正常升級,如果仍然有錯誤,可以重復上述步驟。

 執行升級:

/usr/lib/postgresql/13/bin/pg_upgrade -b /usr/lib/postgresql/11/bin -B /usr/lib/postgresql/13/bin -d /data/old_data -D /data/new_data -U dbuser

 至此數據庫文件升級完成。

 升級完成之后將 new_data目錄按照正常的數據庫目錄映射到 docker postgres:13.1 容器 啟動即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM