對于作業系統來說,資料庫算是比較大型的應用,往往需要耗費大量的系統資源,特别是在内部程序間通信這塊的資源。
作業系統預設的配置可能無法滿足資料庫對資源使用的需求。
那麼應該如何根據資料庫的需要,設定作業系統相關資源參數呢?
在講資源配置設定前,大家可以參考閱讀一下
<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 管理 (适用于 < 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 管理 (适用于 >= 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 >= (max_connections + max_worker_processes + autovacuum_max_workers + 5) / 16
需要多少信号量
semmns >= ((max_connections + max_worker_processes + autovacuum_max_workers + 5) / 16) * 17 + 其他程式的需求
每組需要多少信号量
semmsl >= 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共享記憶體段的需求很大,是以要設得比較大,需要使用者注意。
祝大家玩得開心,歡迎随時來 阿裡雲促膝長談業務需求 ,恭候光臨。
阿裡雲的小夥伴們加油,努力 做好核心與服務,打造最貼地氣的雲資料庫 。