一周前 PostgreSQL 社區(qū)發(fā)布了二月度例行小版本更新,。 不過老馮必須提醒各位,最好不要在最近兩周進(jìn)行 PostgreSQL 新增部署與更新,因?yàn)檫@個(gè)例行小版本引入了兩個(gè) BUG。 這兩個(gè) BUG 將在 2026-02-26 的 號外小版本(out-of-cycle release)中修復(fù)。
![]()
表現(xiàn) BUG 1:substring() 對非 ASCII Toast 文本報(bào)錯(cuò)
這次引入的回歸問題可能對業(yè)務(wù)產(chǎn)生影響。第一個(gè)主要問題是 substring() 函數(shù)從 Toast 壓縮列中取出非 ASCII 文本時(shí)會報(bào)錯(cuò)。
![]()
https://www.postgresql.org/message-id/19406-9867fddddd724fca@postgresql.org[1]
如果你存儲了超過 2 KB 的非 ASCII 文本,并在列值上使用 substring(),就可能觸發(fā)這個(gè)問題。substring() 是常用字符串函數(shù),實(shí)際命中概率并不低。
這個(gè)回歸與 CVE-2026-2006 的安全修復(fù)有關(guān),CVE-2026-2006 的修復(fù)加強(qiáng)了多字節(jié)邊界檢查,把“遇到不完整多字節(jié)字符時(shí)停止計(jì)數(shù)”的舊行為,改為直接拋錯(cuò)。
問題出在 text_substring() 的 TOAST detoast 切片邏輯。當(dāng)值來自數(shù)據(jù)庫列時(shí),函數(shù)會按 請求字符數(shù) × 編碼最大字節(jié)數(shù) 預(yù)估解壓長度,再取切片。 該切片可能在多字節(jié)字符中間截?cái)啵f邏輯能容忍,新邏輯會報(bào)“invalid byte sequence for encoding”。
這也解釋了為什么 SELECT substring('中文測試', 1, 2) 正常,而 SELECT substring(col, 1, 2) FROM t 可能報(bào)錯(cuò)。 根據(jù)源碼調(diào)用鏈推斷,left()、right() 等函數(shù)可能走到同一路徑;但官方公告明確點(diǎn)名的是 substring()。
BUG 2:新版本回放舊版本 WAL 時(shí) FATAL 中斷
第二個(gè)問題發(fā)生在跨小版本的 WAL 回放路徑上,報(bào)錯(cuò):“could not access status of transaction”。
![]()
https://www.postgresql.org/message-id/349f9c82-3a8b-48ad-8cc4-fe81553793dd%40iki.fi[2]
這個(gè)問題出現(xiàn)在“新小版本二進(jìn)制回放舊小版本 WAL”場景中。除了主備流復(fù)制追 WAL,還包括使用歸檔做恢復(fù)(PITR)等回放路徑。 但考慮到觸發(fā)條件比較特殊,實(shí)際影響范圍可能相對有限。
影響
受影響版本:18.2、17.8、16.12、15.16、14.21。
如果您的應(yīng)用使用了 substring() 等字符串函數(shù)處理非 ASCII 文本,且已升級到這些小版本,那您已經(jīng)受到第一個(gè) BUG 的影響。 第二個(gè) BUG 觸發(fā)有一個(gè)前提,即“用新版本二進(jìn)制回放舊版本 WAL”。建議檢查流復(fù)制備庫的日志中有無“could not access status of transaction” 報(bào)錯(cuò)。
如果您安裝了 PostgreSQL 18.2/17.8/16.12/15.16/14.21,建議您密切關(guān)注 2026-02-26 的號外小版本發(fā)布,并在發(fā)布后盡快更新到 18.3/17.9/16.13/15.17/14.22。 鑒于 PG 18.2 修復(fù)了一系列 CVE 與 BUG,我們認(rèn)為最佳的部署策略還是等待一周后的 18.3 發(fā)布再進(jìn)行部署。如果您著急需要進(jìn)行提前修復(fù),可以參考官方 Wiki 手工應(yīng)用補(bǔ)丁重新編譯構(gòu)建與安裝。
對于 Pigsty 用戶來說,如果您在最近一周內(nèi)使用“在線安裝”模式,或使用 v4.1 的“離線安裝包”進(jìn)行了新的 PG 部署,那么您很可能已經(jīng)安裝了受影響的 PG 版本。 Pigsty v4.2.0 將與 PG 18.3 同期發(fā)布,提供最新的離線安裝包,以及對現(xiàn)有 PG 小版本升級到最新小版本的遷移手冊。
如果您確實(shí)非常著急要在這兩周內(nèi)部署上新,那么可以使用 Pigsty v4.0 的離線安裝包,安裝 18.1 系列小版本,并在后續(xù)進(jìn)行小版本升級。
老馮評論
最近幾年,PostgreSQL 一共有過四次 out-of-cycle 計(jì)劃外小版本發(fā)布:
① 2026-02-26(計(jì)劃中)
?版本:18.3, 17.9, 16.13, 15.17, 14.22?原因 A(安全修復(fù)相關(guān)):CVE-2026-2006 修復(fù)引入 substring() 回歸?原因 B(非安全變更):multixact WAL 回放路徑回歸,備庫/恢復(fù)可能中斷
② 2025-02-20
?版本:17.4, 16.8, 15.12, 14.17, 13.20?原因:2025-02-13 發(fā)布的 CVE-2025-1094(libpq 客戶端庫漏洞)修復(fù)引入回歸,涉及非空終止字符串處理問題。?
③ 2024-11-21
?版本:17.2, 16.6, 15.10, 14.15, 13.18, 12.22(PG 12 已 EOL,仍破例發(fā)布)?原因 A(安全修復(fù)相關(guān)):CVE-2024-10978 修復(fù)導(dǎo)致 ALTER USER ... SET ROLE 失效?原因 B(獨(dú)立問題):ResultRelInfo ABI 變化導(dǎo)致部分?jǐn)U展兼容性問題?
④ 2022-06-16
?版本:僅 14.4(只針對 PG 14)?原因:PostgreSQL 14.0 以來,CREATE INDEX CONCURRENTLY 和 REINDEX CONCURRENTLY 存在 靜默索引數(shù)據(jù)損壞 問題。
![]()
最近三次的號外小版本模式非常清晰:2024、2025、2026 連續(xù)三年的例行更新之后都緊跟了一次緊急修復(fù),而且主要是安全補(bǔ)丁引入的回歸。我覺得背后有幾個(gè)結(jié)構(gòu)性原因:
第一,安全修復(fù)的時(shí)間壓力與質(zhì)量之間的矛盾。CVE 修復(fù)有保密期(embargo),補(bǔ)丁在公開前只能在極小范圍內(nèi)審查和測試。 不像普通 bug 修復(fù)可以在 pgsql-hackers 上公開討論幾周甚至幾個(gè)月,安全補(bǔ)丁的開發(fā)和審查窗口非常短,參與的人也少,很容易測試不充分。 這三次:CVE-2024-10978 改壞了 SET ROLE、CVE-2025-1094 改壞了 libpq 字符串處理、CVE-2026-2006 改壞了 substring()都是修漏洞時(shí)引入了功能回歸。
第二,PG 的回歸測試體系相對于代碼復(fù)雜度來說是滯后。 PostgreSQL 的 make check 回歸測試套件歷史悠久但覆蓋面有限,特別是對多字節(jié)編碼、跨小版本流復(fù)制場景、擴(kuò)展 ABI 兼容性這些維度的覆蓋不夠。 2024 年那次 ResultRelInfo 結(jié)構(gòu)體大小變化導(dǎo)致 TimescaleDB 等擴(kuò)展崩潰,說明 ABI 穩(wěn)定性都沒有充分自動化檢查。 社區(qū)一直在討論引入更完善的 CI/CD 和更多測試矩陣,但進(jìn)展緩慢,畢竟這是一個(gè)社區(qū)驅(qū)動的項(xiàng)目
第三,也是很關(guān)鍵的一點(diǎn),標(biāo)準(zhǔn)提高了。 以前類似的問題可能就等到下個(gè)季度例行發(fā)布時(shí)一起修,但現(xiàn)在 PostgreSQL 的用戶基數(shù)和關(guān)鍵程度今非昔比,社區(qū)對質(zhì)量的容忍度更低了,更傾向于快速發(fā)布修復(fù)。 所以 out-of-cycle 增多,某種程度上也反映了社區(qū)對用戶負(fù)責(zé)的態(tài)度:發(fā)現(xiàn)問題不拖著,盡快修。這其實(shí)是好事。
老馮覺得,連續(xù)三年栽在坑里,原因是一個(gè)結(jié)構(gòu)性矛盾:安全修復(fù)的封閉開發(fā)流程 vs. 日益復(fù)雜的代碼庫和測試需求。 但好在 PostgreSQL 畢竟是世界上最流行的開源數(shù)據(jù)庫。因此,即使在開發(fā)階段的測試有缺陷,也能很快地在生產(chǎn)環(huán)境中通過冒煙眾測被發(fā)現(xiàn)。
另一個(gè)啟示是 —— 通常我們認(rèn)為升級小版本是足夠安全的,但顯然,這幾次號外版本的發(fā)布也在提醒我們:追新有風(fēng)險(xiǎn)。數(shù)據(jù)庫老司機(jī)當(dāng)然無所謂,但對于普通用戶來說,在沒有 CVE,惡性 bug 的前提下,說不定還是滯后兩個(gè)小版本使用更為穩(wěn)妥。
References
[1]: https://www.postgresql.org/message-id/19406-9867fddddd724fca@postgresql.org[2]: https://www.postgresql.org/message-id/349f9c82-3a8b-48ad-8cc4-fe81553793dd%40iki.fi
數(shù)據(jù)庫老司機(jī)
點(diǎn)一個(gè)關(guān)注 ??,精彩不迷路
對 PostgreSQL, Pigsty,下云 感興趣的朋友
歡迎加入 PGSQL x Pigsty 交流群 QQ 619377403
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺“網(wǎng)易號”用戶上傳并發(fā)布,本平臺僅提供信息存儲服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.