2025年9月25日: PostgreSQL 18 釋出!

PostgreSQL 每週新聞 - 2021 年 11 月 28 日

釋出於 2021-11-29,作者:PWN
PWN

PostgreSQL 每週新聞 - 2021 年 11 月 28 日

本週人物

11月 PostgreSQL 工作機會

https://archives.postgresql.org/pgsql-jobs/2021-11/

PostgreSQL 本地活動

2022 Nordic PGDay 將於2022年3月22日在芬蘭赫爾辛基的希爾頓赫爾辛基斯特蘭德酒店舉行。論文徵集(CfP)將於2021年12月31日截止,請 在此 提交。

PostgreSQL 相關新聞

Planet PostgreSQL:https://planet.postgresql.org/

本週 PostgreSQL 週報由 David Fetter 提供。

請在太平洋標準時間(PST8PDT)週日晚上3:00之前將新聞和公告發送至 david@fetter.org。

已應用補丁

Peter Geoghegan 提交

  • 移除 lazy_scan_heap 並行 VACUUM 的註釋塊。該註釋塊不應出現在關於 lazy_scan_heap 執行任務的非常高層次的討論旁邊。在 vacuumlazy.c 的頂部已經有一個類似的、更長的註釋塊,其中直接提到了 lazy_scan_heap。 https://git.postgresql.org/pg/commitdiff/97f5aef609ce51422934b7dbdba599a7de4dbafd

  • 恢復對標記為 full 的頁面的 HOT 考慮。Commit 2fd8685e7f 簡化了 heap_update() 中對已修改屬性的檢查。其中包括了一個微最佳化,影響了標記為 PD_PAGE_FULL 的頁面:為了節省幾個週期用於確定 HOT 安全性,甚至不嘗試使用 HOT。假設是這次不會成功,因為它上次也不會成功。移除此微最佳化。它只能節省大部分 heap_update() 呼叫所消耗的週期,這似乎不值得增加的複雜性。儘管短期內平均節省了一些週期,但對於某些工作負載來說,隨著時間的推移,反覆應用微最佳化可能會導致更差的結果。作者:Peter Geoghegan pg@bowt.ie 審閱者:Álvaro Herrera alvherre@alvh.no-ip.org 討論:https://postgr.es/m/CAH2-WznU1L3+DMPr1F7o2eJBT7=3bAJoY6ZkWABAxNt+-afyTA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/1a6f5a0e876306293fda697e7820b404d5b93693

  • 更新 vacuumlazy.c 的高層次註釋。更新 vacuumlazy.c 檔案頭部的註釋(以及 lazy_scan_heap 函式上方的註釋),這些註釋大部分是在引入 HOT 最佳化之前編寫的,當時 lazy_scan_heap 做的事情少得多,並且在第一次堆掃描時並沒有真正進行剪枝。由於 lazy_scan_heap 現在將更多工作外包給了低階函式,因此透過討論決定每個階段發生順序的高層不變數來介紹該函式是有意義的。同時,淡化了我們耗盡 TID 記憶體的情況,因為推遲討論這個問題可以更容易地討論核心問題。最後,移除頭部註釋中關於並行 VACUUM 的討論。這些內容並沒有太多價值,而且位置不對。 https://git.postgresql.org/pg/commitdiff/12b5ade9023f3ecaddcbc423a22dc284c91c79f6

  • vacuumlazy.c:優先使用“cleanup lock”一詞。“super-exclusive lock”是“cleanup lock”的一個可接受的同義詞。即使如此,在同一個檔案中來回切換術語會引起混淆。在 vacuumlazy.c 中標準化為“cleanup lock”。根據 Andres Freund 的反饋。 https://git.postgresql.org/pg/commitdiff/276db875d4f9be2911582f367596d444d6986c77

Fujii Masao 提交

Peter Eisentraut 提交

Álvaro Herrera 提交

Tom Lane 提交

  • 在檢查 TAP 測試所需的模組時,探測 $PROVE 而不是 $PERL。通常,“prove”和“perl”來自同一個 Perl 安裝,但我們支援它們不來自同一個安裝的情況(主要是因為 MSys 的 buildfarm 機器需要這個)。在這種情況下,AX_PROG_PERL_MODULES 是完全錯誤的,因為它檢查的是“perl”擁有的內容。相反,建立一個包含所需模組的小型 TAP 測試指令碼,並在“prove”下執行它。此更改後,我們不再需要 ax_prog_perl_modules.m4,因此將其移除。回溯到所有支援的分支,以方便 buildfarm。 (在 v10 中,這還回溯了 commit 264eb03aa 的效果。)Andrew Dunstan 和 Tom Lane,根據 Noah Misch 的觀察。討論:https://postgr.es/m/E1moZHS-0002Cu-Ei@gemulon.postgresql.org https://git.postgresql.org/pg/commitdiff/c4fe3199a6d65212537a59eb0d7e6fad22b9e903

  • 修復 pg_dump --inserts 模式對帶有已刪除列的生成列。如果一個表包含一個生成列,該列前面有一個已刪除的列,則 dumpTableData_insert 沒有考慮已刪除的列,並在錯誤的列中發出 DEFAULT 佔位符。這導致還原時失敗。預設的 COPY 程式碼路徑沒有這個 bug,這可能解釋了為什麼它沒有更早被注意到。在修復此問題時,我們可以更智慧地處理這種情況:(1)避免不必要地獲取生成列的值,(2)如果我們使用 --column-inserts,也從輸出中省略生成列。儘管這些模式的效能預計不如 COPY 路徑,但我們也可以儘可能高效;這並沒有增加太多複雜性。根據 Дмитрий Иванов 的報告。回溯到 v12(生成列在此版本中引入)。討論:https://postgr.es/m/CAPL5KHrkBniyQt5e1rafm5DdXvbgiiqfEQEJ9GjtVzN71Jj5pA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/0b126c6a4b00972f2f3533e1718bbe297e2851c2

  • 使 perlcritic 保持安靜。根據 buildfarm。 https://git.postgresql.org/pg/commitdiff/db3a660c6327a6df81a55c4aa86e6c0837ecd505

  • 調整 pg_dump 中 cast 的優先順序排序。當儲存的表示式依賴於使用者定義的 cast 時,後端會將依賴記錄為對 cast 的實現函式——或者,如果沒有涉及 cast 函式,只是 RelabelType 或 CoerceViaIO,則不會記錄任何依賴。這對於 pg_dump 來說是問題的,因為其傾倒順序可能不正確,導致還原失敗。鑑於之前沒有報告,風險並不高,但如果 cast 用於某個檢視,而該檢視的行型別隨後用作其他函式的輸入或結果型別,則可以證明這一點。(這會導致檢視被提升到 dump 的函式部分,位於 cast 之前。)一個邏輯上萬無一失的修復需要將 cast 的 OID 包含在表示式的解析形式中,然後 dependency.c 可以從中提取,之後儲存的依賴關係將強制 pg_dump 做正確的事情。這樣的更改將是相當大的入侵,肯定無法回溯。此外,由於我們希望使用 cast 語法的表示式等於(equal())透過顯式函式呼叫做同樣事情的表示式,因此 cast OID 欄位必須具有特殊的忽略比較語義,這會使事情變得混亂。所以,讓我們透過一個非常簡單的 hack 來修復 pg_dump:更改物件型別的優先順序順序,使 cast 最初排在函式之前,緊隨型別之後。這以一種相當直接的方式修復了沒有實現函式的 cast 的問題。對於那些有實現函式的,實現函式將在依賴排序步驟中被提升到 cast 之前,因此我們仍然擁有有效的 dump 順序。(我不確定這是否能提供完全沒有問題的保證;但由於這種情況已經存在很多年了,之前沒有任何報告,這可能在實踐中足夠了。)根據 Дмитрий Иванов 的報告。回溯到所有支援的分支。討論:https://postgr.es/m/CAPL5KHoGa3uvyKp6z6m48LwCnTsK+LRQ_mcA4uKGfqAVSEjV_A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/b55f2b6926556115155930c4b2d006c173f45e65

  • 文件:改進 nextval()/setval() 的文件說明。澄清 nextval 和 setval 的結果在呼叫事務提交之前不保證持久。有些人似乎從“這些函式永遠不會回滾”的陳述中得出相反的結論,因此重新措辭以避免這樣說。討論:https://postgr.es/m/CAKU4AWohO=NfM-4KiZWvdc+z3c1C9FrUBR6xnReFJ6sfy0i=Lw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/4ac452e2285da347c75f5960ae211e183a87b57b

Michaël Paquier 提交

David Rowley 提交

  • 允許 Memoize 在二進位制比較模式下執行。Memoize 始終使用快取鍵型別的雜湊相等運算子來確定當前引數集是否與之前快取的某個集合相同。某些型別(如浮點數),其中 -0.0 和 +0.0 在其二進位制表示中不同,但被雜湊相等運算子視為相等,可能會導致問題,因為除非連線使用相同的運算子,否則有可能正在使用的連線運算子可以區分這兩個值。在這種情況下,我們可能會意外地從快取中返回不正確的行。為了解決這個問題,我們在此添加了一個二進位制模式到 Memoize,允許它透過按位比較而不是使用雜湊相等運算子來將當前引數集與先前快取的值進行比較。此二進位制模式始終用於 LATERAL 連線,並且當任何連線運算子不可雜湊時,它用於普通連線。報告者:Tom Lane 作者:David Rowley 討論:https://postgr.es/m/3004308.1632952496@sss.pgh.pa.us 回溯到:14(Memoize 新增的版本) https://git.postgresql.org/pg/commitdiff/e502150f7d0be41e3c8784be007fa871a32d8a7f

  • 當非鍵引數更改時重新整理 Memoize 快取。Memoize 節點下方的子計劃可能包含來自 Memoize 節點上方的引數。如果此引數發生更改,快取條目可能會因新的引數值而過時。以前 Memoize 錯誤地沒有意識到這一點。我們在此透過在任何不是快取鍵一部分的引數更改時重新整理快取來修復此問題。Bug:#17213 報告者:Elvis Pranskevichus 作者:David Rowley 討論:https://postgr.es/m/17213-988ed34b225a2862@postgresql.org 回溯到:14(Memoize 新增的版本) https://git.postgresql.org/pg/commitdiff/1050048a315790a505465bfcceb26eaf8dbc7e2e

  • 撤銷“當非鍵引數更改時重新整理 Memoize 快取”。此操作撤銷 commit 1050048a315790a505465bfcceb26eaf8dbc7e2e。 https://git.postgresql.org/pg/commitdiff/dad20ad4709f602b4827a1ab2b0e715f36c548c3

  • 當非鍵引數更改時重新整理 Memoize 快取,第二版。Memoize 節點下方的子計劃可能包含來自 Memoize 節點上方的引數。如果此引數發生更改,快取條目可能會因新的引數值而過時。以前 Memoize 錯誤地沒有意識到這一點。我們在此透過在任何不是快取鍵一部分的引數更改時重新整理快取來修復此問題。Bug:#17213 報告者:Elvis Pranskevichus 作者:David Rowley 討論:https://postgr.es/m/17213-988ed34b225a2862@postgresql.org 回溯到:14(Memoize 新增的版本) https://git.postgresql.org/pg/commitdiff/411137a429210e432f923264a8e313a9872910ca

Amit Kapila 提交

Robert Haas 提交

  • 修復檢測不當時間線切換的邊界情況失敗。rescanLatestTimeLine() 包含一個保護機制,可以防止切換到從當前時間線在當前恢復點之前分叉的時間線,但如果時間線切換髮生在第一個 WAL 記錄(必須是檢查點記錄)被讀取之前,該保護機制就不起作用。沒有這個補丁,在這種情況下就可能發生不當的時間線切換。這是因為 rescanLatestTimeLine() 依賴於全域性變數 EndRecPtr 來了解 WAL 重放的當前位置。然而,此時程式碼中的 EndRecPtr 儲存的是最後一個已重放記錄的終點,而不是當前正在重放的記錄的起點或終點。因此,在任何記錄被重放之前,它是零,這導致健全性檢查總是透過。為了解決這個問題,明確地傳遞正確的時間線。我們想要的 EndRecPtr 值是來自 xlogreader 的值,它將是我們即將嘗試讀取的記錄的起始位置,而不是全域性變數,後者是我們成功讀取的最後一條記錄的結束位置。它們通常是相同的,但在上面描述的邊界情況下並非如此。不回溯,因為在 v14 及更早版本的分支中,我們在這裡使用了錯誤 TLI 和錯誤的 LSN。在 master 中,這由 commit 4a92a1c3d1c361ffb031ed05bf65b801241d7cdd 修復,但它及其先決補丁對於如此小的錯誤來說過於入侵,無法回溯。作者:我,審閱者:Amul Sul。討論:http://postgr.es/m/CA+Tgmoao96EuNeSPd+hspRKcsCddu=b1h-QNRuKfY8VmfNQdfg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/e7ea2fa342b008ae97e794b0fa2ee538ddcee3b7

  • xlog.c:移除全域性變數 ReadRecPtr 和 EndRecPtr。在大多數地方,這些變數必然儲存著 WAL 重放期間使用的 XLogReaderState 的同名成員的值,因為 ReadRecord() 在 XLogReadRecord() 返回後立即將結構成員的值賦給全域性變數。然而,XLogBeginRead() 調整了結構成員但沒有調整全域性變數,因此在 XLogBeginRead() 之後和 XLogReadRecord() 完成之前,值可能不同。否則,它們必須是相同的。根據我的分析,唯一一個變數被引用但可能與其結構成員值不同的地方是 XLogPageRead 中對 EndRecPtr 的引用。因此,在其他所有使用全域性變數的地方,我們可以直接切換到使用結構成員,並移除全域性變數。然而,我們也可以,而且事實上應該,在 XLogPageRead() 中這樣做,因為在該程式碼點,全域性變數將實際儲存我們要讀取的記錄的開始位置——要麼是因為它是最後一個 WAL 記錄的結束位置,要麼是因為在讀取最後一個記錄後使用了 XLogBeginRead 來更改讀取位置。另一方面,結構成員已經被更新為指向我們剛剛讀取的記錄的末尾。在其他地方,後者是我們傳遞給 emode_for_corrupt_record() 的引數,所以我們在這裡也應該這樣做。此補丁部分可能是一個 bug 修復,但我認為它沒有重要的後果,所以不回溯。這裡的重點是繼續減少 xlog.c 中對全域性變數的過度使用。討論:http://postgr.es/m/CA+Tgmoao96EuNeSPd+hspRKcsCddu=b1h-QNRuKfY8VmfNQdfg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/d2ddfa681db27a138acb63c8defa8cc6fa588922

Heikki Linnakangas 提交

Andres Freund 提交

Daniel Gustafsson 提交