親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

在遙遠的將來的某個時候,自動刪除不必要的數據將成為DBMS的重要任務之一[1]。 與此同時,我們自己需要負責刪除不必要的數據或將不必要的數據移動到更便宜的存儲系統。 假設您決定刪除幾百萬行。 這是一個相當簡單的任務,特別是如果條件已知並且有合適的索引。 “DELETE FROM table1 WHERE col1 = :value” - 還有什麼更簡單的,對吧?

視頻:

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

  • 我從第一年(即 2007 年)起就一直是 Highload 項目委員會的成員。

  • 我自 2005 年以來一直在 Postgres 工作。 在很多項目中都使用過它。

  • 自 2007 年起也與 RuPostges 合作。

  • Meetup 的參與者已增至 2100 多人。 僅次於紐約,位居世界第二,長期被舊金山超越。

  • 我在加利福尼亞州生活了幾年。 我更多地與美國公司打交道,包括大公司。 他們是 Postgres 的活躍用戶。 還有各種各樣有趣的事情。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/ 是我的公司。 我們致力於自動化任務,以消除開發放緩。

如果你正在做某事,那麼有時 Postgres 周圍會有某種插件。 假設您需要等待管理員為您設置測試台,或者您需要等待 DBA 回复您。 我們在開發、測試和管理過程中發現了此類瓶頸,並嘗試借助自動化和新方法來消除它們。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf

我最近在洛杉磯的 VLDB。 這是最大的數據庫會議。 並且有報導稱,未來DBMS不僅會存儲數據,還會自動刪除數據。 這是一個新話題。

ZB 世界中的數據越來越多 - 即 1 PB。 據估計,現在全世界已經存儲了超過 000 ZB 的數據。 而且這樣的人越來越多。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://vldb2019.github.io/files/VLDB19-keynote-2-slides.pdf

該怎麼辦? 顯然它需要被刪除。 這是這份有趣報告的鏈接。 但到目前為止,這還沒有在 DBMS 中實現。

會數錢的人想要兩件事。 他們希望我們刪除,所以從技術上來說我們應該能夠做到。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

接下來我要講的是一些抽象的情況,其中包括一堆真實的情況,即對我和周圍數據庫多年來實際發生的事情的一種彙編。 耙子無處不在,每個人都無時無刻不在踩著耙子。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

假設我們有一個或多個正在成長的基地。 而且有些記錄顯然是垃圾。 例如,用戶開始在那裡做某事,但沒有完成。 一段時間後我們知道這個未完成的東西不能再被存儲了。 也就是說,我們想清理一些垃圾東西,以節省空間、提高性能等。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

一般來說,任務是自動刪除某些表中的特定事物、特定行。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

而我們有這樣一個要求,今天我們要講的就是垃圾清除。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

我們請了一位經驗豐富的開發人員來做這件事。 他接受了這個請求,親自檢查了它 - 一切正常。 經過分期測試 - 一切都很好。 推出 - 一切正常。 我們每天運行一次 - 一切都很好。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

數據庫不斷增長。 每日刪除的速度開始變慢。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

然後我們了解到,我們現在有了營銷公司,流量會大幾倍,所以我們決定暫時暫停一些不必要的事情。 並忘記返回。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

幾個月後,他們想起來了。 該開發人員退出或忙於其他事情,指示另一個人將其退回。

他檢查了開發、舞台——一切都很好。 當然,積累的東西還是需要清理的。 他檢查一切正常。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

接下來發生什麼? 然後一切對我們來說都崩潰了。 它會下降,以至於在某個時候一切都會下降。 所有人都震驚了,沒有人明白髮生了什麼。 然後事實證明,問題出在這個DELETE上。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

出了些問題? 以下是可能出現問題的列表。 其中哪一個是最重要的?

  • 比如沒有review,即DBA專家沒有看。 他會立即以經驗豐富的眼光發現問題,此外,他還可以訪問已經積累了數百萬行的產品。

  • 也許他們檢查出了問題。

  • 也許硬件已經過時,你需要升級這個底座。

  • 或者數據庫本身有問題,我們需要從Postgres遷移到MySQL。

  • 或者是操作有問題。

  • 也許工作安排出現了一些錯誤,你需要解僱某人並僱用最好的人?

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

沒有DBA檢查。 如果有一個 DBA,他會看到這幾百萬行,即使沒有任何實驗也會說:“他們不這樣做。” 假設如果這段代碼在GitLab、GitHub上,並且會有一個代碼審查過程,並且沒有這樣的事情,沒有DBA的批准,這個操作就會在產品上進行,那麼顯然DBA會說:“這不能完成” 。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

他會說你會遇到磁盤 IO 問題,所有進程都會變得瘋狂,可能會有鎖,而且你還會阻塞 autovacuum 幾分鐘,所以這不好。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

http://bit.ly/nancy-hl2018-2

第二個錯誤——他們檢查錯地方了。 我們事後看到,prod 上積累了大量的垃圾數據,但開發者並沒有在這個數據庫中積累數據,也沒有人在 staging 時創建這些垃圾數據。 因此,很快就有了 1 行代碼。

我們知道我們的測試很弱,也就是說,構建的過程無法發現問題。 沒有進行充分的數據庫實驗。

理想的實驗最好在相同的設備上進行。 並不總是可以在同一設備上執行此操作,但它是數據庫的完整大小的副本非常重要。 這就是我多年來一直宣揚的。 一年前我談到過這個,你可以在 YouTube 上觀看。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

也許是我們的裝備不好? 如果你看一下,就會發現延遲大幅增加。 我們看到利用率是100%。 當然,如果這些是現代 NVMe 驅動器,那麼對我們來說可能會容易得多。 也許我們不會就此罷手。

如果您有云,那麼升級就可以輕鬆完成。 在新硬件上提出新的副本。 切換。 一切都很好。 挺容易。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

是否有可能以某種方式接觸較小的磁盤? 在這裡,在 DBA 的幫助下,我們深入探討了一個名為檢查點調優的主題。 事實證明我們沒有進行檢查點調整。

什麼是檢查點? 它存在於任何 DBMS 中。 當內存中的數據發生變化時,它不會立即寫入磁盤。 數據發生變化的信息首先寫入預寫日誌。 在某些時候,DBMS 決定是時候將實際頁轉儲到磁盤,這樣如果出現故障,我們可以執行更少的 REDO。 它就像一個玩具。 如果我們被殺了,我們將從最後一個檢查點開始遊戲。 所有的 DBMS 都實現了它。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

Postgres 中的設置滯後。 它們專為 10-15 年的數據和交易量而設計。 檢查點也不例外。

這是我們的 Postgres 檢查報告中的信息,即自動健康檢查。 這是一些幾 TB 的數據庫。 可以看出,幾乎90%的情況下都強制檢查點。

這是什麼意思? 那裡有兩個設置。 檢查點可以超時,例如 10 分鐘。 或者當相當多的數據被填充時它可能會出現。

默認情況下 max_wal_saze 設置為 1 GB。 事實上,這種情況在 Postgres 中確實發生在 300-400 MB 之後。 您已經更改瞭如此多的數據,並且您的檢查點發生了。

如果沒有人調整它,服務增長了,公司賺了很多錢,有很多交易,那麼檢查點每分鐘出現一次,有時每 30 秒一次,有時甚至重疊。 這很糟糕。

我們需要確保它出現的頻率較低。 也就是說,我們可以提高 max_wal_size。 而且它的頻率會降低。

但我們已經開發了一套完整的方法論,如何更正確地做到這一點,即如何根據具體數據做出有關選擇設置的決定。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

因此,我們正在對數據庫進行兩個系列的實驗。

第一個系列 - 我們更改 max_wal_size。 我們正在進行大規模行動。 首先,我們使用 1 GB 的默認設置。 我們對數百萬行進行了大規模刪除。

你可以看到我們有多難。 我們看到磁盤IO非常糟糕。 我們看看我們生成了多少個 WAL,因為這非常重要。 讓我們看看檢查點發生了多少次。 我們看到這並不好。

接下來我們增加 max_wal_size。 我們重複一遍。 我們增加,我們重複。 還有很多次。 原則上,10 分即可,其中 1、2、4、8 GB。 我們觀察特定係統的行為。 很明顯,這裡的設備應該像產品上的那樣。 您必須具有相同的磁盤、相同的內存量和相同的 Postgres 設置。

通過這種方式,我們將交換我們的系統,並且我們知道 DBMS 在發生不良批量刪除時將如何表現,它將如何檢查點。

俄語中的檢查站是檢查站。

示例:通過索引刪除幾百萬行,行“分散”在頁面上。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

這是一個例子。 這是一些基礎。 並且 max_wal_size 默認設置為 1 GB,很明顯我們的磁盤會上架進行記錄。 這張圖是一個病得很重的病人的典型症狀,就是他真的感覺很糟糕。 而且只有一個操作,只是刪除了幾百萬行。

如果prod中允許這樣的操作,那麼我們就躺著吧,因為很明顯,一個DELETE就會在團裡殺死我們。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

此外,16 GB 的地方,很明顯牙齒已經消失了。 牙齒已經好多了,也就是說,我們正在敲天花板,但還沒有那麼糟糕。 那裡有一些自由。 右邊是記錄。 以及操作數量 - 第二張圖。 很明顯,當我們達到 16 GB 時,呼吸已經輕鬆了一些。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

而64G的地方可以看到它已經變得完全好了。 牙齒已經明顯,有更多的機會在其他手術中倖存下來並用磁盤做一些事情。

為什麼這樣?

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

我會稍微深入一些細節,但是這個主題,如何進行檢查點調整,可以產生一個完整的報告,所以我不會加載太多,但我會概述一下存在的困難。

如果檢查點發生得太頻繁,並且我們不是按順序更新行,而是通過索引查找,這很好,因為我們不刪除整個表,那麼可能會發生首先我們觸及第一頁,然後是千分之一,然後又回到了第一個。 如果在對第一頁的這些訪問之間,檢查點已經將其保存到磁盤,那麼它將再次保存它,因為我們第二次弄髒了它。

並且我們會多次強制檢查點保存它。 怎麼會有多餘的操作給他呢。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

但這還不是全部。 Postgres 中的頁面為 8 KB,Linux 中的頁面為 4 KB。 還有一個 full_page_writes 設置。 默認情況下它是啟用的。 這是正確的,因為如果我們將其關閉,那麼存在崩潰時僅保存一半頁面的危險。

寫入前向日誌的 WAL 的行為是這樣的,當我們有一個檢查點並且我們第一次更改頁面時,整個頁面(即所有 8 KB)都會進入前向日誌,儘管我們只更改了行,重100 字節。 我們必須寫下整個頁面。

在後續的更改中,只會有一個特定的元組,但我們第一次寫下所有內容。

因此,如果檢查點再次發生,那麼我們必須再次從頭開始並推送整個頁面。 通過頻繁的檢查點,當我們遍歷相同的頁面時,full_page_writes = on 將超出其應有的數量,即我們生成更多的 WAL。 更多內容被發送到副本、存檔、磁盤。

因此,我們進行了兩次裁員。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

如果我們增加 max_wal_size,事實證明我們會讓檢查點和 wal writer 變得更容易。 那太好了。

讓我們投入 XNUMX TB 並接受它。 這有什麼不好呢? 這很糟糕,因為萬一發生故障,我們將爬上幾個小時,因為檢查點是很久以前的事了,很多事情已經發生了變化。 我們需要重做所有這些。 所以我們做了第二系列的實驗。

我們執行一個操作,看看檢查點何時即將完成,我們故意殺死 -9 Postgres。

之後我們再次啟動它,看看它會在該設備上上升多長時間,即在這種糟糕的情況下它會重做多少。

我會兩次指出情況很糟糕。 首先,我們在檢查站結束前就墜毀了,所以我們有很多損失。 其次,我們進行了大規模的行動。 如果檢查點超時,那麼自上一個檢查點以來很可能會生成更少的 WAL。 也就是說,這是雙輸。

我們針對不同的 max_wal_size 大小測量了這種情況,並了解到如果 max_wal_size 為 64 GB,那麼在雙重最壞情況下,我們將爬升 10 分鐘。 我們會考慮它是否適合我們。 這是一個商業問題。 我們需要把這張圖拿給負責業務決策的人看,問:“如果出現問題,我們最多能躺多久? 最壞的情況下能躺3-5分鐘嗎? 然後你做出決定。

這是一個有趣的點。 我們在會議上收到了一些關於帕特羅尼的報導。 也許你正在使用它。 這是 Postgres 的自動故障轉移。 GitLab 和 Data Egret 對此進行了討論。

如果你有一個 30 秒內發生的自動故障轉移,那麼也許我們可以躺 10 分鐘? 因為此時我們將切換到副本,一切都會好起來的。 這是一個有爭議的問題。 我不知道一個明確的答案。 我只是覺得這個話題不僅僅是關於崩潰恢復。

如果我們在失敗後有很長時間的恢復,那麼我們在許多其他情況下都會感到不舒服。 例如,在同樣的實驗中,當我們做某件事時,有時需要等待10分鐘。

即使我們有自動故障轉移,我仍然不會走得太遠。 一般來說,64、100 GB 等值都是不錯的值。 有時甚至值得選擇更少。 總的來說,這是一門微妙的科學。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

要做迭代,比如max_wal_size =1, 8,需要重複大量操作很多次。 你做到了。 在相同的基礎上,您想再做一次,但您已經刪除了所有內容。 該怎麼辦?

稍後我將討論我們的解決方案,以及我們在這種情況下如何進行迭代。 而這才是最正確的做法。

但在這種情況下,我們很幸運。 如果像這裡所說的“BEGIN、DELETE、ROLLBACK”,那麼我們就可以重複DELETE。 也就是說,如果我們自己取消了,那麼我們可以重複。 在您的物理位置上,數據將位於同一個位置。 你甚至沒有任何腫脹。 您可以迭代此類 DELETE。

即使您沒有正確部署的數據庫實驗室,這種帶有 ROLLBACK 的 DELETE 也非常適合檢查點調整。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

我們製作了一個帶有一列“i”的盤子。 Postgres 有實用程序列。 除非特別要求,否則它們是不可見的。 它們是:ctid、xmid、xmax。

Ctid 是物理地址。 零頁,頁面中的第一個元組。

可以看出,ROOLBACK 之後元組仍保留在同一位置。 也就是說,我們可以再試一次,它會以同樣的方式表現。 這是主要的事情。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

Xmax是元組的死亡時間。 它被標記了,但 Postgres 知道事務已回滾,因此無論它是 0 還是回滾事務都沒有關係。 這表明可以迭代 DELETE 並檢查系統行為的批量操作。 您可以為窮人建立數據庫實驗室。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

這是關於程序員的。 關於DBA也是如此,他們總是為此責罵程序員:“你為什麼要做這麼長而困難的操作?”。 這是一個完全不同的垂直話題。 以前有行政,現在有發展。

顯然,我們還沒有分裂。 天氣晴朗。 不可能不將數百萬行的 DELETE 分解為多個部分。 做20分鐘,一切就都躺好了。 但不幸的是,即使是經驗豐富的開發人員也會犯錯誤,即使是在非常大的公司中。

為什麼打破很重要?

  • 如果我們發現磁盤很硬,那麼讓我們放慢速度。 如果我們被破壞了,那麼我們可以添加暫停,我們可以放慢限制。

  • 而且我們不會長期封鎖別人。 在某些情況下,這並不重要,如果您要刪除沒有人在處理的真正垃圾,那麼很可能您不會阻止除 autovacuum 工作之外的任何人,因為它將等待事務完成。 但如果你刪除了其他人可以請求的東西,那麼他們就會被阻止,就會出現某種連鎖反應。 應避免在網站和移動應用程序上進行長時間交易。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://postgres.ai/products/joe/

這很有趣。 我經常看到開發人員問:“我應該選擇什麼包裝尺寸?”。

顯然,bundle 大小越大,交易開銷(即交易的額外開銷)就越小。 但與此同時,這筆交易的時間也增加了。

我有一個非常簡單的規則:盡可能多地獲取,但每秒不要超過可執行文件。

為什麼要等一秒鐘? 解釋非常簡單,每個人都可以理解,即使是非技術人員。 我們看到了反應。 我們以 50 毫秒為例。 如果事情發生了變化,我們的眼睛就會做出反應。 如果少了,那就更難了。 如果 100 毫秒後有響應,例如,您單擊鼠標,它在 100 毫秒後響應您,您已經感受到了這種輕微的延遲。 第二個已經被認為是剎車。

因此,如果我們將大規模操作分成 10 秒的突發事件,那麼我們就有屏蔽某人的風險。 它會起作用幾秒鐘,人們就會注意到它。 因此,我寧願做的事情不超過一秒鐘。 但同時,不要將其分解得非常細,因為事務開銷會很明顯。 基礎會更硬,並且可能會出現其他不同的問題。

我們選擇包裝的尺寸。 在每種情況下,我們都可以採取不同的做法。 可以自動化。 我們對一包的處理效率深信不疑。 也就是說,我們刪除一個包或更新。

順便說一下,我所說的一切不僅僅是關於刪除。 正如您所猜測的,這些是對數據的任何批量操作。

我們看到這個計劃非常好。 可以看到索引掃描,僅索引掃描就更好了。 而且我們涉及的數據量很小。 不到一秒鐘就滿足了。 極好的。

我們仍然需要確保沒有退化。 碰巧第一批很快就解決了,然後情況變得越來越糟。 這個過程是這樣的,你需要進行很多測試。 這正是數據庫實驗室的用途。

我們仍然需要準備一些東西,以便我們能夠在生產中正確遵循這一點。 例如,我們可以在日誌中寫入時間,我們可以寫入我們現在在哪里以及我們現在刪除了誰。 這將使我們能夠了解稍後發生的事情。 並且一旦出現問題,能夠快速找到問題所在。

如果我們需要檢查請求的效率並且需要迭代多次,那麼就存在“同伴機器人”這樣的東西。 他已經準備好了。 每天有數十名開發人員使用它。 他知道如何在 30 秒內根據請求提供一個巨大的 TB 數據庫,您自己的副本。 您可以在那裡刪除某些內容並說“重置”,然後再次刪除它。 你可以用這種方法進行實驗。 我看到了這件事的未來。 我們已經在這樣做了。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://docs.gitlab.com/ee/development/background_migrations.html

什麼是分區策略? 我看到包的開發人員正在使用 3 種不同的分區策略。

第一個很簡單。 我們有一個數字 ID。 讓我們將其分解為不同的時間間隔並進行處理。 缺點是顯而易見的。 在第一個段中,我們可能有 100 行真正的垃圾,在第二個 5 行中或者根本沒有,或者所有 1 行都將變成垃圾。 做工很不均勻,但很容易斷裂。 他們拿走了最大的ID並把它砸碎了。 這是一種幼稚的做法。

第二個策略是平衡的方法。 它在 Gitlab 中使用。 他們拿起並掃描了桌子。 我們找到了 ID 包的邊界,以便每個包恰好有 10 條記錄。 並將它們放入隊列中。 然後我們進行處理。 您可以在多個線程中執行此操作。

順便說一句,在第一個策略中,您也可以在多個線程中執行此操作。 這並不難。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

https://medium.com/@samokhvalov/how-partial-indexes-affect-update-performance-in-postgres-d05e0052abc

但還有一種更酷、更好的方法。 這是第三個策略。 並且在可能的情況下,最好選擇它。 我們根據一個特殊的索引來做到這一點。 在這種情況下,根據我們的垃圾條件和ID,它很可能是一個索引。 我們將包含 ID,以便它是僅索引掃描,這樣我們就不會進入堆。

通常,僅索引掃描比索引掃描更快。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

我們很快就找到了要刪除的 ID。 BATCH_SIZE 我們提前選擇。 我們不僅得到它們,而且以一種特殊的方式得到它們並立即破解它們。 但我們正在鎖定,這樣如果它們已經被鎖定,我們就不會鎖定它們,而是繼續前進並獲取下一個。 這是為了更新跳過鎖定。 如果需要,Postgres 的這個超級功能允許我們在多個線程中工作。 在一個流中這是可能的。 這裡有一個 CTE——這是一個請求。 我們在這個 CTE 的二樓進行了真正的刪除 - returning *。 你可以返回 id,但這樣更好 *如果每行沒有太多數據。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

為什麼我們需要它? 這就是我們需要回報的。 實際上我們現在已經刪除了很多行。 我們有 ID 或created_at 的邊界,如下所示。 你可以做最小、最大。 還可以做點別的事。 這裡可以放很多東西。 而且監控非常方便。

關於該索引還有一項註釋。 如果我們決定為此任務需要一個特殊索引,那麼我們需要確保它不會破壞僅堆元組更新。 也就是說Postgres有這樣的統計數據。 這可以在表的 pg_stat_user_tables 中看到。 您可以查看是否正在使用熱更新。

在某些情況下,您的新索引可以簡單地切斷它們。 而且所有其他更新都已經在起作用,放慢速度。 不僅僅是因為索引出現了(每個索引都會減慢更新速度,但是一點點),但在這裡它仍然破壞了它。 並且不可能對這個表進行專門的優化。 有時會發生這種情況。 這種微妙之處很少有人記得。 而且這個耙子很容易踩到。 有時會出現這樣的情況,你需要從對方找辦法,但仍然不用這個新的索引,或者再做一個索引,或者用其他的方式,比如可以使用第二種方法。

但這是最優化的策略,如何分批,一個請求批量拍攝,刪掉一點點等等。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

長交易 https://gitlab.com/snippets/1890447

阻止自動清理 - https://gitlab.com/snippets/1889668

阻塞問題—— https://gitlab.com/snippets/1890428

錯誤#5 是一個很大的錯誤。 來自 Okmeter 的 Nikolai 談到了 Postgres 監控。 遺憾的是,理想的 Postgres 監控並不存在。 有的更近,有的更遠。 Okmeter 已經足夠接近完美,但是還缺少很多內容,需要添加。 你需要為此做好準備。

例如,最好監控死元組。 如果桌子上有很多死東西,那就有問題了。 最好現在就反應,不然可能會退化,我們就可以躺下了。 它發生了。

如果有很大的IO,那麼顯然這樣不好。

交易時間也長。 OLTP 上不應允許長事務。 這裡有一個代碼片段的鏈接,您可以使用該代碼片段並已經對長交易進行一些跟踪。

為什麼長交易不好? 因為所有的鎖只有到最後才會被釋放。 我們搞砸了所有人。 另外,我們阻止所有表的自動清理。 這一點都不好。 即使您在副本上啟用了熱備用,它仍然很糟糕。 一般來說,最好避免長時間交易。

如果我們有很多表沒有被清理,那麼我們需要有一個警報。 這裡這種情況是可能的。 我們可以間接影響autovacuum的運行。 這是 Avito 的一個片段,我對其稍加改進。 事實證明,這是一個有趣的工具,可以讓我們了解 autovacuum 的功能。 例如,有些桌子在那裡等候,不會等待輪到他們。 您還需要將其置於監控並發出警報。

並發出區塊。 塊樹森林。 我喜歡從別人那裡獲取一些東西並改進它。 在這裡,我從 Data Egret 中獲取了一個很酷的遞歸 CTE,它顯示了鎖樹森林。 這是一個很好的診斷工具。 並且在它的基礎上,還可以構建監控。 但這必須謹慎進行。 你需要為自己制定一個小的statement_timeout。 並且lock_timeout是可取的。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

有時所有這些錯誤都會同時發生。

在我看來,這裡的主要錯誤是組織上的。 它是有組織的,因為技術不會拉動。 這是第二個——他們檢查錯地方了。

我們檢查錯了地方,因為我們沒有易於檢查的生產克隆。 開發人員可能根本無法訪問生產環境。

我們檢查了那裡不存在。 如果我們在那裡檢查過,我們自己就會看到它。 即使沒有 DBA,開發人員也能看到這一切,只要他在一個良好的環境中檢查它,那裡有相同的數據量和相同的位置。 他會看到這一切的墮落,他會感到羞愧。

有關自動真空的更多信息。 在我們完成了數百萬行的大規模掃描之後,我們仍然需要進行 REPACK。 這對於索引尤其重要。 我們清理完那裡的所有東西後,他們會感覺很糟糕。

如果你想恢復日常清潔工作,那麼我建議更頻繁地進行,但規模較小。 可以是每分鐘一次,也可以是更頻繁一點。 你需要監控兩件事:這個東西沒有錯誤,並且它沒有落後。 我展示的技巧就能解決這個問題。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

我們所做的是開源的。 它發佈在 GitLab 上。 我們這樣做是為了讓人們即使沒有 DBA 也可以進行檢查。 我們正在做一個數據庫實驗室,也就是說,我們稱之為 Joe 目前正在開發的基礎組件。 您還可以獲取一份製作副本。 現在有 Joe for slack 的實現,您可以在那裡說:“解釋這樣那樣的請求”,然後立即獲取數據庫副本的結果。 你甚至可以刪除那裡,沒有人會注意到它。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

假設您有 10 TB,我們將數據庫實驗室也設置為 10 TB。 借助同時 10 TB 的數據庫,10 名開發人員可以同時工作。 每個人都可以做自己想做的事。 可以刪除、刪除等等。這真是天方夜譚。 我們明天再討論這個。

親愛的刪除。 Nikolay Samokhvalov (Postgres.ai)

這稱為精簡配置。 這是微妙的配置。 這是某種幻想,可以極大地消除開發和測試方面的延遲,並使世界在這方面變得更加美好。 也就是說,它只是讓您避免批量操作出現問題。

示例:5 TB 數據庫,在 30 秒內獲得副本。 而且它甚至不取決於大小,也就是說,多少 TB 並不重要。

今天你可以去 postgres.ai 並深入研究我們的工具。 您可以註冊看看有什麼。 您可以安裝這個機器人。 免費。 寫。

問題

在實際情況中,經常會發現表中應保留的數據遠少於需要刪除的數據。 也就是說,在這種情況下,當更容易創建新對象、僅複製必要的數據併中繼舊表時,實現這種方法通常更容易。 很明顯,在您即將進行切換時,此時需要一種程序化的方法。 這個方法怎麼樣?

這是一個非常好的做法,也是一個非常好的任務。 它與 pg_repack 所做的非常相似,與將 ID 設為 4 字節時必須執行的操作非常相似。 幾年前很多框架都是這麼做的,只是板塊長大了,需要轉換成8字節。

這個任務是相當困難的。 我們做到了。 你必須非常小心。 有鎖等等。但是正在做。 也就是說,標準方法是使用 pg_repack。 你聲明了這樣一個標籤。 在開始將快照數據上傳到其中之前,您還需要聲明一個跟踪所有更改的板。 有一個技巧,您甚至可能無法跟踪某些更改。 其中有微妙之處。 然後通過滾動更改進行切換。 當我們關閉所有設備時,會有短暫的停頓,但總的來說,這是正在完成的。

如果你查看 GitHub 上的 pg_repack,就會發現,當有一個任務將 ID 從 int 4 轉換為 int 8 時,就會有使用 pg_repack 本身的想法。 這也是可能的,但有點麻煩,但它也適用於此。 您可以乾預 pg_repack 使用的觸發器並在那裡說:“我們不需要這些數據”,即我們只傳輸我們需要的數據。 然後他就切換了,僅此而已。

通過這種方法,我們仍然獲得表的第二個副本,其中數據已經被索引,並且通過漂亮的索引非常均勻地堆疊。

不存在膨脹,這是一個好方法。 但我知道有人嘗試為此開發自動化,即制定通用解決方案。 我可以讓您接觸這種自動化。 它是用 Python 編寫的,這是一件好事。

我對 MySQL 的世界還很陌生,所以我來聽聽。 我們使用這種方法。

但前提是我們達到了 90%。 如果我們有5%,那麼就不太好用了。

感謝您的報告! 如果沒有資源來製作完整的 prod 副本,是否有任何算法或公式來計算負載或大小?

好問題。 到目前為止,我們能夠找到數 TB 的數據庫。 即使那裡的硬件不一樣,例如內存少,處理器少,磁盤不完全相同,但我們仍然這樣做。 如果絕對無處可去,那麼你就需要思考了。 讓我想想,直到明天,你來了,我們再談談,這是個好問題。

感謝您的報告! 你一開始就知道有一個很酷的 Postgres,它有這樣那樣的局限性,但它正在發展。 總的來說,這都是一個拐杖。 這不是與 Postgres 本身的開發相衝突嗎?在 Postgres 中,會出現一些 DELETE deferent 或其他應該將我們試圖用一些奇怪的手段塗抹的內容保持在較低水平的東西?

如果我們在SQL中說在一個事務中刪除或更新多條記錄,那麼Postgres如何在那里分發它呢? 我們的行動受到物理限制。 我們仍將長期這樣做。 而我們此時會鎖定等等。

完成索引。

我可以假設相同的檢查點調整可以自動化。 有一天可能會這樣。 但後來我真的不明白這個問題。

問題是,是否存在這樣一個發展向量,到處都是,而你的卻是平行的? 那些。 他們還沒想過嗎?

我講了現在可以用的原則。 還有另一個機器人 南希,這樣您就可以進行自動檢查點調整。 有一天它會出現在 Postgres 中嗎? 我不知道,甚至還沒有討論過。 我們離那還很遠。 但有些科學家製造了新系統。 他們將我們推入自動索引。 有進展。 例如,您可以查看自動調整。 它自動選擇參數。 但他還不會為你做檢查點調整。 也就是說,它會提高性能、shell 緩衝區等。

對於檢查點調整,您可以這樣做:如果您有一千個集群和不同的硬件,雲中的不同虛擬機,您可以使用我們的機器人 南希 做自動化。 max_wal_size 將根據您的目標設置自動選擇。 但不幸的是,到目前為止,這在核心方面還沒有接近。

下午好您談到了長期交易的危險。 你說在刪除的情況下自動清理會被阻止。 它還如何傷害我們? 因為我們更多地談論釋放空間並能夠使用它。 我們還缺少什麼?

自動真空可能不是這裡最大的問題。 而且長事務可能會鎖定其他事務,這種可能性更加危險。 她可能會也可能不會。 如果她遇到了,那就很糟糕了。 對於 autovacuum - 這也是一個問題。 OLTP 中長事務存在兩個問題:鎖和 autovacuum。 如果您在副本上啟用了熱備用反饋,那麼您仍然會在主服務器上收到自動真空鎖,它將從副本到達。 但至少不會有鎖。 並且會有洛克。 我們正在討論數據更改,因此鎖是這裡的一個重要點。 如果這一切持續很長很長一段時間,那麼越來越多的交易將被鎖定。 他們可以偷別人的東西。 樂樹出現了。 我提供了該片段的鏈接。 而且這個問題比 autovacuum 的問題變得更加明顯,而 autovacuum 只會累積。

感謝您的報告! 您在報告一開始就說您的測試不正確。 我們繼續我們的想法,即我們需要採用相同的設備,並以相同的方式建立基礎。 假設我們為開發人員提供了一個基礎。 他答應了這個要求。 而且他看起來很好。 但他不檢查直播,而是直播,比如我們負載有60-70%。 而且即使我們使用這種調整,效果也不是很好。

團隊中擁有專家並使用能夠預測真實後台負載會發生什麼情況的 DBA 專家非常重要。 當我們剛剛進行乾淨的更改時,我們看到了圖片。 但更先進的方法是,當我們再次做同樣的事情時,但使用模擬生產的負載。 這很酷。 在那之前,你必須長大。 這就像一個成年人。 我們只看我們擁有什麼,也看我們是否有足夠的資源。 這是個好問題。

當我們已經在進行垃圾選擇並且我們有一個已刪除標誌時

這就是 Postgres 中 autovacuum 自動執行的操作。

哦,他會做嗎?

Autovacuum 是垃圾收集器。

謝謝!

感謝您的報告! 是否有一個選項可以立即設計一個分區數據庫,使所有垃圾都從主表的某個地方變髒?

當然有。

如果我們鎖定了不應該使用的表,是否可以保護自己?

當然有。 但這就像一個先有雞還是先有蛋的問題。 如果我們都知道未來會發生什麼,那麼我們當然會做得很酷。 但業務正在發生變化,有新的欄目、新的要求。 然後 - 哎呀,我們想刪除它。 但這種理想的情況,在生活中確實會發生,但並不總是如此。 但總的來說這是一個好主意。 只需截斷即可。

來源: www.habr.com

添加評論