Postgresql

Postgres 是否保護硬碟驅動器免受重複寫入相同的記憶體單元?

  • November 13, 2021

如果我在同一張表的同一列中有同一行,我每天寫入 4 個字節(整數)100,000 次,那會磨損 SSD 嗎?對於 SSD 來說,每天 400 kb 不算什麼,但將它寫入同一個儲存單元就會彈出它。

  • Postgres 數據庫管理系統是否以某種方式在後台處理這些單元?
  • 還是現代 SSD 晶片在硬體中做到這一點?
  • 還是它們都被寫入同一個儲存單元,我們只是隨著時間的推移交換死掉的 SSD?

介紹:

必須讚賞的是 PostgreSQL對底層磁碟一無所知(無論它們是旋轉 rust 還是 SSD、RAID 配置或其他任何東西)。PostgreSQL 將數據交給作業系統並信任作業系統來照顧它(有時不是一個好主意)!

對於 SSD,這裡需要考慮兩個因素:

  • 磨損均衡
  • 修明

重要的是要注意,這些與系統上執行的應用程序(即 PostgreSQL、任何其他數據庫伺服器或任何應用程序)無關!前者嚴格來說是 SSD 本身的屬性/能力,後者是 OS 和 SSD 之間的“合作方式”。

磨損均衡:

帶回家的資訊:SSD 將寫入均勻地分配到不同的塊,因為 SSD 塊只能經歷一個limited number of erase cycles before becoming unreliable

來自維基

磨損均衡嘗試通過排列數據來解決這些限制,以便擦除和重寫在介質上均勻分佈。以這種方式,不會因為寫入周期的高度集中而導致單個擦除塊過早失效。3在快閃記憶體中,晶片上的單個塊被設計為比其他塊更長的壽命,因此記憶體控制器可以儲存操作數據而損壞的可能性更小。4

因此,SSD 決定將來自作業系統的數據實際放在哪裡(注意:沒有提及這些數據可能來自哪個應用程序)。簡單的想法是,它將這些寫入分佈在驅動器周圍,以平衡所有磁碟塊的磨損,這樣一些塊就不會過早失效!

這可能會很快變得複雜 - 請參閱 wiki 了解更多詳細資訊:

在此處輸入圖像描述

修剪明:

帶回家的資訊:由於 SSD 的底層結構,只能寫入空塊 - 如果塊中已有數據,則必須讀取這些舊數據並將其與新數據一起重寫回塊 - 這有助於放大。

如果作業系統告訴磁碟(刪除後)塊 x 中的數據不再需要,磁碟可以執行垃圾收集(可以調度)並且塊將是空的,然後準備寫入而無需寫入放大. 與對 HDD 進行碎片整理並沒有完全不同。

(再次來自維基- 為長引用道歉,但這是必要的):

SSD 將數據儲存在快閃記憶體單元中,這些單元通常分為 4 到 16 kiB 的頁面,一起分為通常 128 到 512 個頁面的塊。範例:512 kiB 塊,將 128 頁分組,每頁 4 kiB。7個NAND快閃記憶體單元只有在它們為空時才能被直接寫入。如果它們碰巧包含數據,則必須在寫入操作之前擦除內容。SSD 寫入操作可以對單個頁面進行,但由於硬體限制,擦除命令總是會影響整個塊;7因此,將數據寫入 SSD 上的空頁面非常快,但一旦需要覆蓋之前寫入的頁面,速度就會大大降低。由於在再次寫入之前需要擦除頁面中的單元格,但只能擦除整個塊,因此覆蓋將啟動讀取-擦除-修改-寫入周期:

$$ 7 $$$$ 12 $$整個塊的內容儲存在記憶體中,然後從SSD中擦除整個塊,然後將覆蓋的頁面寫入記憶體塊,然後才能將整個更新塊寫入快閃記憶體介質。這種現象稱為寫放大。$$ 13 $$$$ 14 $$ 操作 TRIM 命令使作業系統能夠通知 SSD 頁面不再包含有效數據。對於文件刪除操作,作業系統會將文件的扇區標記為可用於新數據,然後向 SSD 發送 TRIM 命令。修整後,SSD在將新數據寫入快閃記憶體頁面時不會保留塊的任何內容,從而導致寫入放大更少(寫入更少),寫入吞吐量更高(無需讀取-擦除-修改序列),從而增加驅動器壽命。

儲存的未來:

有很多有趣的研究正在進行中。儲存,並且出於顯而易見的原因,儲存在數據庫中。雖然這在專業知識方面超出了我的薪酬等級,但如果您搜尋諸如“字節定址磁碟”之類的術語,您會遇到像這裡這樣的網站,它是持久記憶體(字節定址)工具包的所在地( Intel Optane顯然可以支持他的),那麼按塊讀寫數據的日子可能屈指可數了?

關於為什麼我們首先有塊的解釋,請參閱軟體工程上的這個執行緒,並在這裡查看有關使用者模式直接訪問硬體的有趣討論,“繞過”作業系統……所有有趣的東西!io_uring(和 eBPF)似乎是 Linux 領域的新手,但您可以在閒暇時仔細閱讀。

回答問題:

如果我在同一張表的同一列中有同一行,我每天寫入 4 個字節(整數)100,000 次,那會磨損 SSD 嗎?對於 SSD 來說,每天 400 kb 不算什麼,但將它寫入同一個儲存單元就會彈出它。

我對上述內容的看法是,SSD 會將寫入分散到許多塊上——這會導致大量工作。具體如何完成將取決於 SSD 的磨損均衡算法。

Postgres 數據庫管理系統是否以某種方式在後台處理這些單元?

絕對不是!PostgreSQL 只是將數據交給文件系統,並讓 FS 和 OS 負責儲存(儘管請參閱此處了解由於 Linux 中的缺陷而導致該過程中斷的地方)。這是應該的——關注點分離

還是現代 SSD 晶片在硬體中做到這一點?

我在這方面的閱讀讓我相信是 SSD 韌體負責磨損均衡和 TRIM-ming。

還是它們都被寫入同一個儲存單元,我們只是隨著時間的推移交換死掉的 SSD?

SSD 上通常有一個小的高耐磨區域,用於保存塊寫入數據,其中一些可以為塊開始失敗時保留區域 - 顯然,您的 SSD 越複雜,您支付的費用就越多它。

重申一下:PostgreSQL 不知道控制一旦將數據交給作業系統後會發生什麼——它是緩衝的、直接到磁碟的、所有人都失去了嗎?

這將取決於作業系統自己的調度算法和它所承受的負載——電腦科學的另一個完整領域!:-) ps +1 提出了一個有趣的問題,讓我了解了這一點(在待辦事項清單上!)。

引用自:https://dba.stackexchange.com/questions/302221