ClickHouse Managed Postgres 導入排程升級,維護窗口不再由平台片面決定
ClickHouse Blog · 2026-09-03
背景:單一維護窗口難以兼顧所有工作負載
ClickHouse 於 2026-09-03 在其 Managed Postgres 服務加入排程升級功能,讓使用者自行決定平台維護窗口的時段。在此之前,所有客戶的 minor version 更新與安全修補都套用同一組全域窗口,與各自的工作負載尖峰完全無關。官方在文章中直言,單一窗口對某些客戶而言必然會撞上重負載時段,全域統一的維護時段無法兼顧不同客戶的尖峰模式,這正是本次改動要解決的問題。
核心改動:依方案分級的排程選項
新功能開放路徑為主控台 Settings → Configuration → Scheduled upgrades → Configure schedule,使用者可隨時編輯或清除已設定的窗口。排程的彈性依訂閱方案而不同:Scale 方案只能選擇一組兩小時的 UTC 區間,Enterprise 方案除了兩小時區間外還能額外指定星期幾執行。以下整理兩者差異:
| 方案 | 可設定窗口長度 | 可指定星期 |
|---|---|---|
Scale | 2 小時(UTC) | 否 |
Enterprise | 2 小時(UTC) | 是 |
此功能對 Scale 與 Enterprise 組織即時生效,不需要另外申請或 opt-in;Basic 方案的使用者則只能在介面上看到這是進階需求項目,須升級方案才能實際設定排程。
影響範圍:哪些操作仍不受窗口保護
排程窗口只涵蓋平台主動發起的升級與修補,並非涵蓋所有異動行為。使用者自行觸發的操作完全不受窗口保護,手動 resize、版本升級與重啟都會立即執行。當儲存空間使用率超過 90% 需要緊急擴容時,平台同樣會立刻介入而不等待排程;read replica 的升級時間則固定跟隨其 primary 節點的排程窗口,不能單獨設定。
- 不受窗口保護:使用者手動觸發的 resize
- 不受窗口保護:使用者手動觸發的版本升級
- 不受窗口保護:使用者手動觸發的重啟
- 不受窗口保護:磁碟使用率超過 90% 的緊急擴容
- 跟隨 primary 排程:read replica 的升級時間
原始來源:ClickHouse Blog、ClickHouse Docs: Managed Postgres Upgrades
拆解複雜 T-SQL 邏輯:用 Decomposition、Encapsulation 與 Statelessness 簡化資料庫程式碼
Microsoft Azure SQL DevBlog · 2026-09-03
原本的問題:巨大的預存程序難以測試與維護
Azure SQL DevBlog 在 2026-09-03 發布的 SQL Decomposition in a Nutshell 指出,許多資料庫邏輯會隨時間把越來越多職責塞進同一支預存程序,最終變成難以閱讀、難以獨立測試、也難以安全修改的龐然大物。作者 Jerry Nixon 以混合搜尋(結合全文檢索與向量搜尋)為例,說明當排序、過濾與分數融合全部寫在同一支程序裡時,任何一段邏輯的修改都可能牽動整體行為。職責混雜是複雜 T-SQL 難以維護的根本原因,這也是文章要處理的核心問題。
採用的方法:Decomposition、Encapsulation、Statelessness
文章借用軟體工程的三個原則來重構資料庫程式碼。Decomposition(拆解)把單一巨大程序切成職責單一的小單元,例如把上例拆成 ProductSearch_FullText、ProductSearch_Vector 與負責分數融合的 ProductSearch_Fuse 三支獨立程序。Encapsulation(封裝)要求呼叫端只需理解每個單元的輸入、輸出與行為契約,不必知道內部實作;文章用 User-Defined Table Type 定義一致的回傳結果形狀,並用 inline table-valued function(如 ProductSearch_RrfScore)封裝可重複使用的計算邏輯。Statelessness(無狀態)則要求避免依賴 session 內的隱藏狀態,改為把所有需要的狀態明確當作參數傳入。
實際效果:可獨立測試,但仍受限於 T-SQL 本身
拆解後的每支程序都能獨立測試與替換,例如切換排序演算法或替換其中一種檢索方式,都不需要牽動其他元件。ProductSearch_RrfScore 對應的是 reciprocal rank fusion(RRF)——一種只看排名位置、不看原始分數的排序融合演算法,公式是把每份結果依 1/(k+rank) 加總,k 通常取 60;因為不依賴分數尺度,RRF 適合用來融合全文檢索與向量搜尋這類分數量綱完全不同的來源。文章也坦言 SQL 環境的限制並未消失:INSERT...EXEC 不能巢狀呼叫、table variable 缺乏 temporary table 才有的欄位統計資訊,且資料量夠大時,近似向量搜尋的效果有時反而優於精確距離計算。拆解降低的是認知與維護成本,而不是規避掉 T-SQL 平台本身既有的限制。
原始來源:Microsoft Azure SQL DevBlog: SQL Decomposition in a Nutshell、Microsoft Learn: Hybrid Search Scoring (RRF)
零停機修改正式環境 Schema:Azure SQL 的六階段變更法
Microsoft Azure SQL DevBlog · 2026-09-03
原本的問題:直接改欄位就是在賭運氣
同樣由 Jerry Nixon 撰寫、發布於 2026-09-03 的 Advocating for Uptime: The 6 Phases of Change,處理的是正式環境資料庫要如何在不停機的前提下修改 schema。文章指出單一 SQL 陳述式本身通常不困難,真正的風險在於新舊應用程式版本、資料回填與依賴關係之間的執行順序。破壞性的不是語法而是執行順序,這是全文反覆強調的重點。
採用的方法:expand-and-contract 的六個階段
文章以一張 User 資料表要把單一 Name 欄位拆成 FirstName 與 LastName 為例,展開成六個循序階段。每個階段都刻意只做一件事,藉此把單次高風險變更拆成多次低風險步驟:
| 階段 | 動作 | 目的 |
|---|---|---|
| 1. Add New Columns | 新增可為 NULL 的新欄位 | 不影響既有功能 |
| 2. Dual-Write | 新舊欄位同時寫入 | 新舊版本應用程式並存 |
| 3. Backfill | 分批回填既有資料列 | 避免鎖表與 transaction log 壓力 |
| 4. Move Reads | 逐步改讀新欄位 | 舊欄位仍保留供其他消費者使用 |
| 5. Stop Writing Old Columns | 移除雙寫邏輯 | 舊欄位標記淘汰但暫不刪除 |
| 6. Validate and Remove | 確認無依賴後刪除舊欄位 | 完成 schema 收斂 |
第一階段的 DDL 相當直接:
ALTER TABLE dbo.[User]
ADD FirstName nvarchar(100) NULL, LastName nvarchar(100) NULL;新欄位刻意設為 nullable,目的是避免既有資料列因為新增 NOT NULL 欄位而觸發整表重寫或違反約束檢查。
實際效果:紀律在於排序而非語法本身
走完六階段後,最後一步刪除舊欄位的語法同樣簡單:
ALTER TABLE dbo.[User] DROP COLUMN Name;文章強調「individual SQL statements are easy, the discipline is in the sequencing」。六階段方法把風險從單一次高風險變更分散成多次低風險步驟,讓 Dual-Write 與 Backfill 階段成為新舊程式碼共存的緩衝期,第六階段才真正刪除舊欄位。這種模式的代價是變更週期被拉長,且必須在每個階段之間確認是否仍有消費者依賴舊欄位,才能安全推進到下一階段。
原始來源:Microsoft Azure SQL DevBlog: Advocating for Uptime: The 6 Phases of Change