POSTGRESQL 小版本升級失敗後的原因分析

張哥說技術發表於2023-01-05

POSTGRESQL  小版本升級失敗後的原因分析

隨著問問題的同學越來越多,公眾號內部私信回答問題已經很困難了,所以建立了一個群,關於各種資料庫的問題都可以,目前主要是 POSTGRESQL, MYSQL ,MONGODB ,POLARDB ,REDIS 等,期待你的加入,加群請新增微信liuaustin3.

事情是最近我們的PG13.1在邏輯複製槽上出現了問題,而我們需要針對PG進行小版本升級,小版本升級看似很簡單,但是其中的問題也不少,今天我升級中就失敗了,那麼我們們就捋一捋POSTGRESQL 小版本升級中失敗是那些問題導致的。

首先先說說這次小版本升級的工作步驟

1  備份資料庫,透過pg_basebackup 對資料庫進行plain 方式的備份

2  停止資料庫服務

3  編譯新版本的資料庫安裝檔案

4  啟動資料庫,升級完成

但之前的postgresql的資料庫是rpm包安裝的,對於一些安裝的引數部分並不清晰,所以產生了後面的問題。

下圖就是在最後一步啟動資料庫後,遇到的錯誤

 The database cluster was initialized with RELSEG_SIZE 131072, but the server was compiled with RELSEG_SIZE 524288.

POSTGRESQL  小版本升級失敗後的原因分析

資料庫無法啟動,那麼到底是哪裡產生的問題。

POSTGRESQL  小版本升級失敗後的原因分析

POSTGRESQL  小版本升級失敗後的原因分析

在資料庫啟動時會對資料檔案的初始化大小進行判斷,當發現資料檔案的初始化大小與現有的資料庫大小不一致時,會產生報錯資訊 relseg_size.

實際上這個問題主要出在升級時對於編譯檔案的引數設定上的--with-segsize=SEGSIZE。

預設資料庫檔案編譯時是可以針對這個資料檔案的初始化最大的大小進行設定的,如果第一次編譯和第二次編制時的引數不一致就會報上面的錯誤。

RELSEG_SIZE = (1024 * 1024 * segsize) / blocksize 

這裡 blocksize 預設為8KB 則 RELSEG_SIZE  的變化值在 segsize中如

(1024 * 1024 * 1 ) /8 =  131,072

(1024 * 1024 * 4) /8 =  524,288

我們對比這兩個數字,在報錯資訊的數字是對的上的,這裡的意思是,你之前的資料檔案大小是 1G 一個,但是你新編譯的資料庫執行檔案是 4G 一個,資料庫初始化出現問題。所以無法啟動資料庫。

解決方案

重新編譯,將編譯的引數調整和之前進行資料庫編譯在這個位置的數值一致即可。但問題是,怎麼知道之前的編譯的引數的問題,又被提出了。

 select name,setting from pg_settings where category = 'Preset Options' order by name;
       

POSTGRESQL  小版本升級失敗後的原因分析

在升級資料庫小版本前,注意三個位置 

1  block_size 一般是不會對這個引數在編譯的時候,進行改變的,但是也要注意,一般是 8K 

2 segment_size   這個是必須要注意的,很多編譯中,對這個位置有改變,因為一些大表幾十個G ,如果這個位置不變,則一個表將產生幾十個資料檔案,所以這個位置對於大型的資料庫,還是要調整一下的。所以升級時要主要這個位置的數值。segment_size /1024 /1024 = 最大一個資料檔案的尺寸。

3 wal_block_size * wal_segment_size = 一個實際的wal檔案的大小

這三個位置,在PG 11 後,只需要注意 1 和 2 兩個位置即可。也就是編譯後,和新升級的編譯檔案在這兩個引數要一致。

同時還可以調取當前系統之前編譯的命令

 pg_config --configure

'--prefix=/usr/local/postgres' '--bindir=/usr/local/postgres/bin' '--sysconfdir=/etc' '--libdir=/usr/local/postgres/libs' '--includedir=/usr/local/postgres/includes' '--datadir=/pgdata' '--datarootdir=/pgdata/root' '--with-pgport=5432' '--with-openssl' '--with-pam' '--with-systemd' '--with-libxml' '--with-segsize=1' '--with-ossp-uuid' '--with-lz4' '--with-zstd'

POSTGRESQL  小版本升級失敗後的原因分析

這裡重新編譯引數將 --with-segsize=4 變為 --with-segsize=1 後,重新編譯檔案後,問題解決。

從此問題中,發現細節有的時候也是一個工作成敗的關鍵,學習一個知識,需要持續和系統化的學習後,也需要不斷在工作中積累,和發現細節的問題。

註明:早期的PG 在wal 上是可以在編譯中調整引數的,PG11 後則在資料庫初始化中進行 wal segsize 的設定。

--with-wal-blocksize= kB [--with-wal-segsize=

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2930949/,如需轉載,請註明出處,否則將追究法律責任。

相關文章