天天看點

如何度量Kernel Resources for PostgreSQL

對于作業系統來說,資料庫算是比較大型的應用,往往需要耗費大量的系統資源,特别是在内部程序間通信這塊的資源。

作業系統預設的配置可能無法滿足資料庫對資源使用的需求。

那麼應該如何根據資料庫的需要,設定作業系統相關資源參數呢?

在講資源配置設定前,大家可以參考閱讀一下

<a href="https://www.postgresql.org/docs/9.5/static/kernel-resources.html#sysvipc">https://www.postgresql.org/docs/9.5/static/kernel-resources.html#sysvipc</a>

<a href="https://www.postgresql.org/docs/9.5/static/runtime-config-resource.html#runtime-config-resource-memory">https://www.postgresql.org/docs/9.5/static/runtime-config-resource.html#runtime-config-resource-memory</a>

kernel-doc-xxx/documentation/sysctl/kernel.txt

<a href="https://en.wikipedia.org/wiki/unix_system_v">https://en.wikipedia.org/wiki/unix_system_v</a>

這一篇主要講的是程序間通信

<a href="https://docs.oracle.com/cd/e19455-01/806-4750/6jdqdflta/index.html">https://docs.oracle.com/cd/e19455-01/806-4750/6jdqdflta/index.html</a>

關于postgresql的共享記憶體管理,早期的 postgresql 版本共享記憶體配置設定隻支援sysv的方式,資料庫啟動時,需要配置設定一塊共享記憶體段,這個需求主要與配置多大的shared_buffers 有關。

社群在9.3的版本做了一個變動,使用mmap配置設定共享記憶體,大幅降低了系統對system v共享記憶體的需求量。

<a href="https://www.postgresql.org/docs/9.3/static/release-9-3.html">https://www.postgresql.org/docs/9.3/static/release-9-3.html</a>

但是mmap并不好,會帶來額外的io開銷,是以postgresql 9.4開始,又做了一個變動,支援動态配置設定共享記憶體,主要是為多核并行計算做的鋪墊,而且預設的共享記憶體配置設定的方法變成了posix(如果環境支援),同樣不需要啟動時配置設定大的共享記憶體段 。

<a href="https://www.postgresql.org/docs/9.4/static/release-9-4.html">https://www.postgresql.org/docs/9.4/static/release-9-4.html</a>

從9.4開始,共享記憶體配置設定方法通過參數 dynamic_shared_memory_type 控制。

不同的值,建立共享記憶體段的方法也不一樣,例如posix使用shm_open,sysv使用shmget,mmap使用mmap。

正是由于建立共享記憶體段的方法不一樣,是以需要配置的作業系統核心參數也不一樣。

不同的共享記憶體配置設定方法,對作業系統的核心參數配置要求也不一樣。

涉及的資源以及計算方法如下

| name | description | reasonable values |

| ---- | ---- | ---- |

| shmmax | 單個共享記憶體段最大允許多大 (bytes) | 見另一張表,或者直接設定為記憶體的80% |

| shmmin | 單個共享記憶體段最小允許多小 (bytes) | 1 |

| shmall | 整個系統允許配置設定多少共享記憶體,(所有共享記憶體段相加) (bytes or pages) | 需考慮其他需要配置設定共享記憶體的應用,確定大于所有應用的需求量,通常可以設定為實際記憶體大小 |

| shmseg | 每個程序允許配置設定多少個共享記憶體段 | only 1 segment is needed, but the default is much higher, 是以不需要設定 |

| shmmni | 整個系統允許配置設定多少個共享記憶體段 | 需要配置設定共享記憶體的程序數 * shmseg |

| semmni | 允許配置設定多少組信号量id (i.e., sets) | at least ceil((max_connections + autovacuum_max_workers + 5) / 16) ,postgresql每16個程序一組 |

| semmns | 允許配置設定多少個信号量 | ceil((max_connections + autovacuum_max_workers + 5) / 16) 17 plus room for other applications,每組信号量需要17位元組,加上其他軟體的需求。實際設定時設定為semmnisemmsl |

| semmsl | 每組允許開多少信号量 | at least 17 |

| semmap | number of entries in semaphore map | see text |

| semvmx | maximum value of semaphore | at least 1000 (the default is often 32767; do not change unless necessary) |

共享記憶體 sysv 管理 (适用于 &lt; 9.3 的版本)

<a href="https://www.postgresql.org/docs/9.2/static/kernel-resources.html">https://www.postgresql.org/docs/9.2/static/kernel-resources.html</a>

是以對于9.2以及更低版本的共享記憶體sysv管理的情況,shmmax的需求計算方法如下,将所有項相加。

usage

approximate shared memory bytes required (as of 8.3)

connections

(1800 + 270 max_locks_per_transaction) max_connections

autovacuum workers

(1800 + 270 max_locks_per_transaction) autovacuum_max_workers

prepared transactions

(770 + 270 max_locks_per_transaction) max_prepared_transactions

shared disk buffers

(block_size + 208) * shared_buffers

wal buffers

(wal_block_size + 8) * wal_buffers

fixed space requirements

770 kb

共享記憶體 sysv 管理 (适用于 &gt;= 9.3 的版本)

對于9.3以及更高版本的postgresql, 即使使用sysv,也不需要這麼多共享記憶體。後面會有實測。

通常需要4kb左右。

共享記憶體 posix, mmap, none 管理

一個postgresql叢集隻需要56位元組(實測)的共享記憶體段大小

小結

9.3 以下版本,設定這3個核心參數

(9.3 以及以上版本,需要的shmmax沒那麼大,是以也可以使用以上設定。 )

如果一台伺服器中要啟動多個postgresql叢集,則每個叢集都需要

shmmin和shmseg不需要設定,從shmget的開發者手冊也可以得到證明

系統頁大小(未使用huge page時)

man shmget

信号量的需求,和資料庫版本無關,計算方法如下。

需要多少組

semmni &gt;= (max_connections + max_worker_processes + autovacuum_max_workers + 5) / 16

需要多少信号量

semmns &gt;= ((max_connections + max_worker_processes + autovacuum_max_workers + 5) / 16) * 17 + 其他程式的需求

每組需要多少信号量

semmsl &gt;= 17

對應系統核心配置舉例

含義分别為

如何檢視目前系統設定的sysv資源限制

如何檢視已使用的sysv資源

shmmax與信号量實測

共享記憶體管理方法 posix, mmap, none 實測 shmmax 需求 如下

啟動資料庫, 檢視ipc

共享記憶體管理方法 sysv 實測 shmmax 需求 如下

如果設定低于資料庫的需求,會報錯

報錯

把shm加到到20gb,

9.5的版本,啟動時實際需要的記憶體并不多,如果你在9.2或者更低版本測試,那會需要很多

postgresql 9.2 shared_buffer=16gb , 啟動時需要申請大量的記憶體.

ulimit 設定主要是限制程序級别對系統資源的使用。

配置檔案舉例

/etc/security/limits.conf

檢視程序設定

# cat /proc/$pid/limits

檢視目前使用者的limit配置

postgresql 推薦設定

core dump 相關核心設定

postgresql 的守護程序是postgres,如果它挂了,資料庫就挂了,其他程序挂了它會負責crash recovery,自動重新開機資料庫(預設設定了 restart_after_crash = on )

是以如果要防止系統oom時殺掉postgres主程序,需要在啟動資料庫前,使用root使用者設定self腳本程序的oom_score_adj,然後啟動資料庫。

例子

man shm_open, shmget, mmap, semctl, sem_overview

本文主要幫助大家了解postgresql資料庫對作業系統資源的需求,以及計算方法。

如果使用者需要在一個系統中運作多個資料庫叢集,則需要将所有叢集的需求加起來。

postgresql 9.2以及以前的版本,在資料庫啟動時對sysv共享記憶體段的需求很大,是以要設得比較大,需要使用者注意。

祝大家玩得開心,歡迎随時來 阿裡雲促膝長談業務需求 ,恭候光臨。

阿裡雲的小夥伴們加油,努力 做好核心與服務,打造最貼地氣的雲資料庫 。