狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

PostgreSQL 數據庫服務器內存不足?可以這么做

admin
2024年11月18日 8:53 本文熱度 568

大型的數據庫系統,往往都需要消耗大量的內存資源,如果資源配置不合理,很容易出現系統可用內存不足的問題。

內存使用是數據庫系統最重要的方面之一。內存不足會直接影響每個性能指標,并對性能產生負面影響。這反過來又會影響我們的用戶和業務。在本文中,我們將了解 PostgreSQL 數據庫如何管理內存,以及如何排查可用內存不足的問題。

數據庫如何讀取數據

要了解如何處理內存,我們需要了解事情是如何運作的。讓我們來看一些基本的數據庫和操作系統機制。

內存頁

數據庫組織數據的方式,需要能提高性能,并使讀取和寫入更易于處理。為了實現最佳性能,業務負載必須是可預測的,并劃分為可管理的塊。數據庫通過頁面來實現這一點。

數據庫上下文中的頁是一個固定長度的數據塊,它表示數據庫系統處理的最小存儲單位。頁面允許數據庫有效地組織磁盤上的數據,這反過來又可以提高性能,并使業務負載可預測。

頁面大小參數決定頁面的大小。通常,它設置為 8192 字節(8kB),某些數據庫允許用戶對其進行配置,例如,PostgreSQL 中的 block_size。頁面可以分組到所謂的區中,這使得頁面管理更容易。

數據庫有效地存儲在頁面中。每次磁盤讀取或寫入,最終都會讀取或寫入整個頁面,這意味著會寫入 8 KB 的數據。即使我們想讀取一個字節的數據(比如表中一行的單個比特位的列),我們也需要將整個頁面加載到內存中。

碎片化

通常,數據庫將一個表行僅存儲在一個頁面上。它們不允許將行存儲在多個頁面上。這會導致一種稱為碎片化的現象。每行可能具有不同的長度,特別是如果我們使用可變長度類型,例如varchar。為了有效地利用內存,數據庫會嘗試一行接一行地進行存儲。如果我們現在修改位于其他兩行之間的一行,則修改后的行可能會變大,并且無法再存儲在頁面上。要解決此問題,數據庫必須將行移動到其他位置,并且原始的空間將變為空(或將具有指向新位置的指針)。此空間現在被浪費并產生了碎片化。

預讀和性能

當訪問的頁面構成一個連續的內存塊時,讀取和寫入的速度要快得多。這利用了內存預取機制,其中內存管理單元(MMU)會進行預測,在不久的將來可能訪問哪些內存頁,并更早地加載它們。如果預測正確,則整體性能會隨著 MMU 更早地讀取數據而提高。為了更好地進行預測,內存頁必須構成一個連續的塊(因此頁面必須一個接一個地出現在物理內存中)。

典型的頁面大小為 8 KB。這在大多數情況下都很有效,但是,有時我們希望擁有更大的頁面,以減少讀寫操作的次數。頁面大小主要由操作系統和 CPU 架構決定。由于操作系統通常使用 8kB 頁面,因此數據庫系統希望使用相同的設置。為了減少 I/O 操作的次數,我們需要使頁面更大。為此,我們可以使用長度為 2MB、1GB 甚至 16GB 的所謂大頁面。我們需要在操作系統中啟用它們,然后在數據庫中啟用它們。例如,PostgreSQL 為此提供了 huge_page_size 參數。通過啟用大頁面,數據庫可以獲得更大的頁面,從而減少數據庫必須執行的 I/O 讀取和寫入次數。這也使頁面能構成更大的連續塊,從而提高預取和整體性能。

但是,操作系統可能會動態調整頁面大小。例如,Linux 支持透明大頁面(THP),它會自動提升和降低頁面大小。這會對應用程序隱藏大頁面,理論上可以在應用程序沒有使用大頁面時提高性能,因為操作系統可能會將多個應用程序的頁面合并為一個大頁面。遺憾的是,當應用程序顯式使用大頁面,而操作系統在后臺將大頁面表示為常規頁面時,性能會很快下降。如果您在數據庫中啟用了大頁面,請在操作系統中禁用 THP。

內存過量使用

在為應用程序分配的內存量方面,操作系統也可能會作弊。當應用程序嘗試分配內存時,即使沒有可用的內存,操作系統也始終會確認內存已分配。這稱為內存過量使用。

此方法可在許多應用程序運行時提高系統的可用性。在準備處理輸入的數據時,應用程序分配的緩沖區通常比所需的緩沖區更大。即使應用程序不使用這些內存,操作系統也需要分配大塊內存,這會很快耗盡資源,并且能夠運行的應用程序更少。

為避免此問題,操作系統假裝所有內存分配都已完成,并且內存是可用的。只有當應用程序嘗試訪問數據時,操作系統才會引發內存不足的異常。在這種情況下,可能會啟動 Out-of-Memory-Killer,并殺死其中一個進程。當應用程序不想使用比機器物理內存更多的內存時,這一切都很好。如果他們想使用它,那么問題就開始了。

數據庫通常就是這種情況。他們希望在開始時分配大塊內存,以便為任何業務負載做好準備。不幸的是,即使內存不可用,操作系統也會簡單地假裝內存已分配。因此,請在您的操作系統中禁用內存過量使用。在 Linux 中,您可以使用 vm.overcommit_memory 參數。

PostgreSQL 如何分配內存

當 PostgreSQL 服務器啟動時,它會分配許多不同的內存塊。讓我們一一看看。

共享緩沖區

最重要的內存塊稱為共享緩沖區。它是用于緩存最常用的頁面的內存塊(涵蓋了數據庫中的行、索引和其他內容)。數據庫會使用幾個指標,來識別最受歡迎的頁面,但它們主要歸結為對讀取和寫入進行計數。有趣的是,您甚至可以讀取頁面,并將其重定向到/dev/null,使其緩存在共享緩沖區中,因為 PostgreSQL 還會檢查操作系統指標。

共享緩沖區在開始時分配,在運行期間無法更改它們的大小。因此,要更改大小,您需要重新啟動數據庫。

共享緩沖區是數據庫內存中最重要的部分。默認大小設置為 128MB,一般建議將其設置為機器內存的 25%。但是,這是一個非常古老且不準確的建議,因此請繼續閱讀以了解如何調整它,也可參閱我們另一篇文章,關于如何處理緩存命中率低的問題,以了解更多信息。

工作內存

另一個內存塊是,為每個查詢中的每個執行節點分配的工作內存。此內存用于處理節點的輸出,并生成結果。因此,我們擁有的查詢和節點越多,我們使用的內存就會越多。

要了解其工作原理,我們需要了解查詢是如何執行的。每當我們運行查詢時,數據庫必須分階段執行它。首先,它從表中提取數據并進行連接。接下來,數據庫執行過濾和其他處理。最后,對結果進行排序。在每個階段,數據庫可能需要生成一大塊數據(比如一個表的內容),這會消耗大量內存。

無需過多的論述,每一個此類型的操作都可能是執行計劃中的一個節點。因此,要從多個表進行讀取的一個查詢,可能具有多個執行計劃節點。對于每個這樣的節點,數據庫都會分配工作內存。如果節點的結果集大于工作內存,則會溢出到磁盤(這比將數據保存在內存中要慢得多)。

PostgreSQL 中的 work_mem 設置,控制為每個查詢中的每個執行節點分配的內存量。默認情況下,它設置為 4MB。通常建議將此參數設置為總內存量除以連接數,然后再除以 4 或 16。這取決于您正在運行的業務負載,因此請繼續閱讀以了解如何對其進行優化。

維護工作內存

我們要考慮的下一個內存塊是維護工作內存。該內存塊用于執行后臺操作,如清理(碎片整理)、索引創建或 DDL 操作(比如添加外鍵)。

每個后臺任務都有自己的內存塊,因此,如果有許多 autovacuum 進程正在運行,則每個進程都會有自己的內存塊。默認情況下,該內存塊的大小設置為 64MB。如果您的服務器有足夠的內存,通常建議將其設置為更高的值,例如 1GB。

臨時緩沖區

每個會話還會獲得另一個用于會話本地緩沖區的內存塊。該內存塊用于創建臨時數據,如臨時表。會話會根據需要分配臨時緩沖區。

默認情況下,允許每個會話分配 8MB 的臨時緩沖區。此內存不與其他會話共享,并且是會話專用的。如果您處理的會話需要分配許多臨時表,則可以考慮調整此參數。

內存調優

現在讓我們看看,如何對 PostgreSQL 服務器中的內存進行調優。

靜態配置

首先,您需要做配置的調優。

shared_buffers

shared_buffers參數的典型建議是,將其設置為內存的 25%。這是一個很好的起點,但它并不能說明問題。

內存利用率在很大程度上取決于您與數據的交互方式。如果您運行的是一個 OLTP 系統,那么我們可以假設,許多事務將在短時間內觸及相同的行。在這種情況下,緩存這些行而不是一遍又一遍地從磁盤中檢索它們會是有益的。在這種情況下,增加緩存大小是一個好主意。

但是,如果您運行的是數倉或報表分析數據庫,則不太可能在短時間內讀取任何行兩次。這意味著緩存數據沒有意義。相反,我們應該讓緩存更小!

如果運行的是 OLTP 業務,則優化 shared_buffers 參數的實際過程應如下所示:

  • ? 從數據庫的共享緩沖區內存初始值開始,比如 1GB

  • ? 使用 pg_buffercache 檢查命中率和未命中率

  • ? 再添加 1GB 的共享緩沖區內存

  • ? 再次檢查命中率和未命中率。此時命中率應該會增加

  • ? 繼續添加內存,直到您看到命中率不再增加

如果您運行 OLAP 或數倉,則可以使用相同的策略,來減小緩存的內存大小,而不會降低系統的性能。請參閱我們關于如何處理緩存命中率低的問題的文章,以了解更多信息。

work_mem

應根據您在數據庫中配置的連接數,來設置 work_mem 參數。在獲得連接數后,可這樣計算

work_mem = TOTAL_RAM / #connections / 16

如果您觀察到仍然有許多查詢會溢出到磁盤,請將 work_mem 參數值繼續加倍,直到您的查詢不再經常溢出。

maintenance_work_mem

maintenace_work_mem參數初始設置為 1GB。如果您發現清理操作或其他后臺進程太慢,請將大小加倍。

temp_buffers

temp_buffers參數設置為 2GB 除以連接數的值,作為初始值。如果您觀察到有許多查詢在創建臨時表,則將大小加倍。

連接

每個連接都會消耗一些內存。連接過多會降低系統性能,并消耗大量內存。因此,您應該限制連接數,并盡可能使用連接池。

請參閱我們的配置連接池指南,了解如何配置它們。

查詢優化

很明顯,慢查詢可能會影響到可用的內存量。低效的查詢可能會讀取過多數據(通過掃描表而不是使用索引)、溢出到磁盤(通過使用低效的連接策略)或降低緩存命中率(通過更新未使用的索引)。

因此,請始終優化好查詢。分析他們的連接策略、查詢參數、過濾器、溢出到磁盤,以及會降低性能的其他方面。

索引

未使用的索引可能會降低您的可用內存。每次更新表中的數據時,可能還需要更新索引。即使未使用的索引,它們也需要與表保持同步。這意味著更新表中的行,可能會導致執行更多的更新。

此處的一般建議是,刪除所有未使用的索引。在查找未使用的索引時,請考慮以下事項:

  • ? 為什么索引未被使用?也許應該使用它,但您的查詢有問題。在這種情況下,請不要修改索引,而是修復查詢

  • ? 索引是否在所有地方都未被使用?也許它在只讀副本上用到了?保持副本之間的數據庫配置一致是有益的,因此在這種情況下不要刪除索引。

  • ? 索引是否未被使用?也許它用于一些罕見的場景,比如月度的報告。在這種情況下,請考慮刪除索引,并且僅在有幫助的情況下,每月為報表重新創建一次索引。

如果您確定該索引未被使用,則只需將其刪除即可。如果您觀察到某些查詢的性能下降,請分析其歷史性能(如果它們在刪除索引時,速度會變慢)。如果是這樣的話,那么也許他們還是使用了索引。

操作系統配置

如前所述,您的操作系統配置可能會影響數據庫的性能。一般建議禁用內存過量使用和透明大頁面。請查閱您的操作系統的文檔,以了解如何執行此操作。

緩存命中率

通常,提高緩存命中率的所有步驟,也都可能改善可用內存不足的情況。請參閱我們關于如何處理緩存命中率低的問題的指南。

表分區

請對表進行分析,是否可以對表進行分區。有很多方法可以進行分區,您可以按照我們的表分區指南,了解更多信息。

擴展

如果都沒有什么幫助,您可以考慮擴展服務器。您可以使機器更大(垂直擴展)或將負載分布到多臺機器(水平擴展)。可以從垂直擴展開始,因為它要容易得多。如果這沒有幫助,請考慮水平擴展,但請記住,這可能需要更改數據庫客戶端。

總結

可用內存低的問題可能會很難處理。我們需要明白,許多活動的部分是相互關聯的。我們需要分析我們的操作系統配置、數據庫配置和我們應對的業務負載。OLTP 和 OLAP 系統的情況不同,沒有通用的解藥。


該文章在 2024/11/18 9:00:16 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved