学习Ubuntu PostgreSQL内存管理技巧,能显著提升数据库性能吗?
- 内容介绍
- 文章标签
- 相关推荐
数据库的性能调整成为了每个数据库管理员关注的焦点。对于 PostgreSQL 而言,内存管理是提高数据库运行速度的关键所在。
一、内存参数基础
PostgreSQL 的主要配置文件 postgresql.conf 中,以下参数决定了数据库的缓存与临时工作空间大小。合理设置它们可以减少磁盘 I/O,并让查询更快完成。
| 参数 | 描述 | 建议范围 |
|---|---|---|
sharedbuffers | 用于缓存数据和索引的共享内存 | 程序物理内存的 百分之二十五~五十成上下 |
workmem | 控制排序、哈希等操作的临时工作空间 | 64 MB~256 MB |
effectivecachesize | 辅助查询调整器评估磁盘缓存可用性 | 程序物理内存的 五十成左右~七十五成左右 |
warmupmemorylimit | 预热期间允许使用的额外 RAM。避免 OOM 错误 | A few MB 或者根据实际情况设置较大值 |
workmem | VACUUMCREATE INDEX 等维护操作使用的 RAM
|
autovacuumworkmem
使用者痛点的观点是,
- 你是否因为频繁磁盘 I/O 导致查询延迟?通过增大 shared_buffers 可直接减少磁盘访问。
- 你想在有限资源下运行复杂分析,却总被 “Out of Memory” 错误卡住?适当调大 maintenance_work_mem 可以解决。
- 你担心过多共享缓冲导致 OS 换页导致整体降速?记得保持 shared_buffers 在 二十五成上下~百分之五十 范围。
- 你希望在高并发环境下保持排序速度?不要把 work_mem 设置太低,否则排序会变慢。
- 你不确定如何判断哪些参数需要微调?后续章节将教你监控 & 调优技巧。
二、连接数与内存乘法效应
"连接数 * 每个连接所需工作空间 = 总占用 RAM"。如果 work_mem 设置过大,在高并发情况下会瞬间耗尽机器 RAM,从而触发 swap 或 OOM。反之,work_mem 太小会导致排序/哈希缓慢甚至失败。:
- 建议: 先根据峰值连接数估算总需求,例如: 最大连接数 × work_mem ≈ 总占用;若总占用超过机器可用 RAM 的 70%,请降低 work_mem 或减小最大连接数。不过,
- 实践案例: 某电商网站最大同时在线使用者 200 人。work_mem=128 MB 时总共约 25 GB;服务器只有 32 GB,且还有 OS 占用。于是将 work_mem 降至 64 MB 后即可平稳运行。
- 监测工具:
三、Ubuntu 程序层与内核设置影响数据库运行速度
"不只是 PostgreSQL 内部参数,还要考虑 Ubuntu 内核对共享内存和页面回收策略。" 以下两项尤为关键:
- # vm.swappiness: 默认值为 60,表示 Linux 在何种程度上倾向于把页面换出到 swap。对于 DBMS 推荐将其降低到 10-20,以减少因 swap 引起的延迟。
- # vm.dirty_ratio / dirty_background_ratio: 这两个参数决定了写入磁盘之前允许积累多少脏页。较高比例会增加写入延迟,但能减轻 I/O 峰值;建议先测试再调整,再看例如,vm.dirty_ratio = 20 vm.dirty_background_ratio = 10
-
# kernel.shmmax 和 kernel.shmall: 限制单进程共享内存段大小和总共享页数。确保它们至少覆盖 shared_buffers 所需大小。按理说,从例如来看,
echo 'kernel.shmmax=17179869184'>> /etc/sysctl.conf echo 'kernel.shmall=4194304'>> /etc/sysctl.conf sysctl -p
-
# fs.file-max: 最大文件句柄数量。如果出现 “too many open files” 报错,需要增大此阈值。例如:
echo 'fs.file-max=100000'>> /etc/sysctl.conf sysctl -p
-
# tuning tips:
- PAM 检查:sudo sysctl -a | grep shmmax | grep shmall | grep file-max>/dev/null && echo OK || echo 'Need tweak'
- PAM 检查:cat /proc/meminfo | grep -E 'SwapTotal|MemTotal' ` **注意**这方面,所有修改后都需要重新启动才能生效。
编辑 postgresql.conf 后保存,再执行
常见误区警告!
<\/span>
• 将 shared_buffers 设置过大可能导致 OS 换页;• 将 work_mem 设置过小导致大量排序变慢;• 忽略 maintenance_work_mem 会让 VACUUM 成为瓶颈。<\/b>
<\/div>
正确思路:
\t-
\t\t
测量当前物理内存,再分配给 shared_buffers 与 effective_cache_size。\t\t
根据业务峰值估算 max_connections*work_mem 并做。\t\t
最终把维护相关的大量 RAM 留给 maintenance_work_mem 与 autovacuum_work_mem。\t\t
\t<\/li>
\t
<\/ul>"
/>
四、监控与调优流程
"只有持续监控才能发现真实瓶颈。" 以下步骤帮助您建立完整流程:
-
① 收集基准数据 – 使用 pgstatstatements + pgBadger 或 pgbadger‑log‑parser 分析慢查询日志;怎么说呢,top/htop 查看整体 CPU 与 IO 状态;free -m 查看 memory 饱和度。
② 定位热点 – 若 IO 大量来自未命中缓存,则增加 shared_buffers/effective_cache_size;若排序/哈希频繁,则提高 work_mem;若后台维护耗费时间,则扩大 maintenance_work_mem/autovacuum_work_mem。
<
h
r
/
>
<
/
p
>
Sorry。previous section contains formatting errors due to copy-paste artifacts. Below is cleaned-up version of monitoring steps:
...
...
...
...
...
You can replace placeholder comments with actual commands and explanations as needed.
五、快速计算示例 & 常见误区解读
快速计算示例 – 针对 4 GB 内存服务器设定 shared_buffers 为 1 GB :
sql
shared_buffers = ‘1GB’
此处仅作演示,请按实际服务器物理规格自行调整。

➾ ➤ ➸ ➿ ⧆ ⟰ ⟶ ⟹ ⟺ ⟸ ⚛︎⚛︎⚛︎⚛︎⚛︎ ⚜️ ☰ ☷ ☲ ☴ ⚡ ☑️ ☎️ ☑️ ⚙️ 🌐 🌍 🌎 🗺️ ✉️ ✍️ ✳️ ◻️ ◼️ ▶▶◀◀ 📈 📉 📊 📅 📆 📇 🗂️ 🔎 🔍 🔐 🚀 🚁 🕒 🎯 🔧 ⚙🔧🚩🚩🌞🌝🌚🌑📚📓📖📝🗒️✏✒✍🖊🖋🖌🖍🎨✂✂⏰⏱⏲⏳⌛⌚📆📅🕰✨✨💡🔔🔕"
This example is intentionally kept minimal so that you can focus on adjusting parameters according to your own environment.
常见误区汇总:
-
将 shared_buffers 设置过大 ⇒ 操作程序频繁换页,引起大量 IO 开销。
当共享缓冲超过机器物理 RAM 时Linux 会把部分页面写入交换空间,从而造成明显下降。
保持在「总RAM × 25% ~ ×50%」范围,并观察 top/htop 中 swapin/out 指标。其实,
-
\t
-
\t\t
测量当前物理内存,再分配给 shared_buffers 与 effective_cache_size。\t\t
根据业务峰值估算 max_connections*work_mem 并做。\t\t
最终把维护相关的大量 RAM 留给 maintenance_work_mem 与 autovacuum_work_mem。\t\t
\t<\/li>
\t
<\/ul>"
/>
四、监控与调优流程
"只有持续监控才能发现真实瓶颈。" 以下步骤帮助您建立完整流程:
- ① 收集基准数据 – 使用 pgstatstatements + pgBadger 或 pgbadger‑log‑parser 分析慢查询日志;怎么说呢,top/htop 查看整体 CPU 与 IO 状态;free -m 查看 memory 饱和度。
② 定位热点 – 若 IO 大量来自未命中缓存,则增加 shared_buffers/effective_cache_size;若排序/哈希频繁,则提高 work_mem;若后台维护耗费时间,则扩大 maintenance_work_mem/autovacuum_work_mem。 < h r / > < / p >Sorry。previous section contains formatting errors due to copy-paste artifacts. Below is cleaned-up version of monitoring steps:
-
...
... ... ... ...You can replace placeholder comments with actual commands and explanations as needed.
五、快速计算示例 & 常见误区解读
快速计算示例 – 针对 4 GB 内存服务器设定 shared_buffers 为 1 GB : sql shared_buffers = ‘1GB’此处仅作演示,请按实际服务器物理规格自行调整。
➾ ➤ ➸ ➿ ⧆ ⟰ ⟶ ⟹ ⟺ ⟸ ⚛︎⚛︎⚛︎⚛︎⚛︎ ⚜️ ☰ ☷ ☲ ☴ ⚡ ☑️ ☎️ ☑️ ⚙️ 🌐 🌍 🌎 🗺️ ✉️ ✍️ ✳️ ◻️ ◼️ ▶▶◀◀ 📈 📉 📊 📅 📆 📇 🗂️ 🔎 🔍 🔐 🚀 🚁 🕒 🎯 🔧 ⚙🔧🚩🚩🌞🌝🌚🌑📚📓📖📝🗒️✏✒✍🖊🖋🖌🖍🎨✂✂⏰⏱⏲⏳⌛⌚📆📅🕰✨✨💡🔔🔕"This example is intentionally kept minimal so that you can focus on adjusting parameters according to your own environment.
常见误区汇总:
将 shared_buffers 设置过大 ⇒ 操作程序频繁换页,引起大量 IO 开销。
当共享缓冲超过机器物理 RAM 时Linux 会把部分页面写入交换空间,从而造成明显下降。
保持在「总RAM × 25% ~ ×50%」范围,并观察 top/htop 中 swapin/out 指标。其实,
数据库的性能调整成为了每个数据库管理员关注的焦点。对于 PostgreSQL 而言,内存管理是提高数据库运行速度的关键所在。
一、内存参数基础
PostgreSQL 的主要配置文件 postgresql.conf 中,以下参数决定了数据库的缓存与临时工作空间大小。合理设置它们可以减少磁盘 I/O,并让查询更快完成。
| 参数 | 描述 | 建议范围 |
|---|---|---|
sharedbuffers | 用于缓存数据和索引的共享内存 | 程序物理内存的 百分之二十五~五十成上下 |
workmem | 控制排序、哈希等操作的临时工作空间 | 64 MB~256 MB |
effectivecachesize | 辅助查询调整器评估磁盘缓存可用性 | 程序物理内存的 五十成左右~七十五成左右 |
warmupmemorylimit | 预热期间允许使用的额外 RAM。避免 OOM 错误 | A few MB 或者根据实际情况设置较大值 |
workmem | VACUUMCREATE INDEX 等维护操作使用的 RAM
|
autovacuumworkmem
使用者痛点的观点是,
- 你是否因为频繁磁盘 I/O 导致查询延迟?通过增大 shared_buffers 可直接减少磁盘访问。
- 你想在有限资源下运行复杂分析,却总被 “Out of Memory” 错误卡住?适当调大 maintenance_work_mem 可以解决。
- 你担心过多共享缓冲导致 OS 换页导致整体降速?记得保持 shared_buffers 在 二十五成上下~百分之五十 范围。
- 你希望在高并发环境下保持排序速度?不要把 work_mem 设置太低,否则排序会变慢。
- 你不确定如何判断哪些参数需要微调?后续章节将教你监控 & 调优技巧。
二、连接数与内存乘法效应
"连接数 * 每个连接所需工作空间 = 总占用 RAM"。如果 work_mem 设置过大,在高并发情况下会瞬间耗尽机器 RAM,从而触发 swap 或 OOM。反之,work_mem 太小会导致排序/哈希缓慢甚至失败。:
- 建议: 先根据峰值连接数估算总需求,例如: 最大连接数 × work_mem ≈ 总占用;若总占用超过机器可用 RAM 的 70%,请降低 work_mem 或减小最大连接数。不过,
- 实践案例: 某电商网站最大同时在线使用者 200 人。work_mem=128 MB 时总共约 25 GB;服务器只有 32 GB,且还有 OS 占用。于是将 work_mem 降至 64 MB 后即可平稳运行。
- 监测工具:
三、Ubuntu 程序层与内核设置影响数据库运行速度
"不只是 PostgreSQL 内部参数,还要考虑 Ubuntu 内核对共享内存和页面回收策略。" 以下两项尤为关键:
- # vm.swappiness: 默认值为 60,表示 Linux 在何种程度上倾向于把页面换出到 swap。对于 DBMS 推荐将其降低到 10-20,以减少因 swap 引起的延迟。
- # vm.dirty_ratio / dirty_background_ratio: 这两个参数决定了写入磁盘之前允许积累多少脏页。较高比例会增加写入延迟,但能减轻 I/O 峰值;建议先测试再调整,再看例如,vm.dirty_ratio = 20 vm.dirty_background_ratio = 10
-
# kernel.shmmax 和 kernel.shmall: 限制单进程共享内存段大小和总共享页数。确保它们至少覆盖 shared_buffers 所需大小。按理说,从例如来看,
echo 'kernel.shmmax=17179869184'>> /etc/sysctl.conf echo 'kernel.shmall=4194304'>> /etc/sysctl.conf sysctl -p
-
# fs.file-max: 最大文件句柄数量。如果出现 “too many open files” 报错,需要增大此阈值。例如:
echo 'fs.file-max=100000'>> /etc/sysctl.conf sysctl -p
-
# tuning tips:
- PAM 检查:sudo sysctl -a | grep shmmax | grep shmall | grep file-max>/dev/null && echo OK || echo 'Need tweak'
- PAM 检查:cat /proc/meminfo | grep -E 'SwapTotal|MemTotal' ` **注意**这方面,所有修改后都需要重新启动才能生效。
编辑 postgresql.conf 后保存,再执行
常见误区警告!
<\/span>
• 将 shared_buffers 设置过大可能导致 OS 换页;• 将 work_mem 设置过小导致大量排序变慢;• 忽略 maintenance_work_mem 会让 VACUUM 成为瓶颈。<\/b>
<\/div>
正确思路:
\t-
\t\t
测量当前物理内存,再分配给 shared_buffers 与 effective_cache_size。\t\t
根据业务峰值估算 max_connections*work_mem 并做。\t\t
最终把维护相关的大量 RAM 留给 maintenance_work_mem 与 autovacuum_work_mem。\t\t
\t<\/li>
\t
<\/ul>"
/>
四、监控与调优流程
"只有持续监控才能发现真实瓶颈。" 以下步骤帮助您建立完整流程:
-
① 收集基准数据 – 使用 pgstatstatements + pgBadger 或 pgbadger‑log‑parser 分析慢查询日志;怎么说呢,top/htop 查看整体 CPU 与 IO 状态;free -m 查看 memory 饱和度。
② 定位热点 – 若 IO 大量来自未命中缓存,则增加 shared_buffers/effective_cache_size;若排序/哈希频繁,则提高 work_mem;若后台维护耗费时间,则扩大 maintenance_work_mem/autovacuum_work_mem。
<
h
r
/
>
<
/
p
>
Sorry。previous section contains formatting errors due to copy-paste artifacts. Below is cleaned-up version of monitoring steps:
...
...
...
...
...
You can replace placeholder comments with actual commands and explanations as needed.
五、快速计算示例 & 常见误区解读
快速计算示例 – 针对 4 GB 内存服务器设定 shared_buffers 为 1 GB :
sql
shared_buffers = ‘1GB’
此处仅作演示,请按实际服务器物理规格自行调整。

➾ ➤ ➸ ➿ ⧆ ⟰ ⟶ ⟹ ⟺ ⟸ ⚛︎⚛︎⚛︎⚛︎⚛︎ ⚜️ ☰ ☷ ☲ ☴ ⚡ ☑️ ☎️ ☑️ ⚙️ 🌐 🌍 🌎 🗺️ ✉️ ✍️ ✳️ ◻️ ◼️ ▶▶◀◀ 📈 📉 📊 📅 📆 📇 🗂️ 🔎 🔍 🔐 🚀 🚁 🕒 🎯 🔧 ⚙🔧🚩🚩🌞🌝🌚🌑📚📓📖📝🗒️✏✒✍🖊🖋🖌🖍🎨✂✂⏰⏱⏲⏳⌛⌚📆📅🕰✨✨💡🔔🔕"
This example is intentionally kept minimal so that you can focus on adjusting parameters according to your own environment.
常见误区汇总:
-
将 shared_buffers 设置过大 ⇒ 操作程序频繁换页,引起大量 IO 开销。
当共享缓冲超过机器物理 RAM 时Linux 会把部分页面写入交换空间,从而造成明显下降。
保持在「总RAM × 25% ~ ×50%」范围,并观察 top/htop 中 swapin/out 指标。其实,
-
\t
-
\t\t
测量当前物理内存,再分配给 shared_buffers 与 effective_cache_size。\t\t
根据业务峰值估算 max_connections*work_mem 并做。\t\t
最终把维护相关的大量 RAM 留给 maintenance_work_mem 与 autovacuum_work_mem。\t\t
\t<\/li>
\t
<\/ul>"
/>
四、监控与调优流程
"只有持续监控才能发现真实瓶颈。" 以下步骤帮助您建立完整流程:
- ① 收集基准数据 – 使用 pgstatstatements + pgBadger 或 pgbadger‑log‑parser 分析慢查询日志;怎么说呢,top/htop 查看整体 CPU 与 IO 状态;free -m 查看 memory 饱和度。
② 定位热点 – 若 IO 大量来自未命中缓存,则增加 shared_buffers/effective_cache_size;若排序/哈希频繁,则提高 work_mem;若后台维护耗费时间,则扩大 maintenance_work_mem/autovacuum_work_mem。 < h r / > < / p >Sorry。previous section contains formatting errors due to copy-paste artifacts. Below is cleaned-up version of monitoring steps:
-
...
... ... ... ...You can replace placeholder comments with actual commands and explanations as needed.
五、快速计算示例 & 常见误区解读
快速计算示例 – 针对 4 GB 内存服务器设定 shared_buffers 为 1 GB : sql shared_buffers = ‘1GB’此处仅作演示,请按实际服务器物理规格自行调整。
➾ ➤ ➸ ➿ ⧆ ⟰ ⟶ ⟹ ⟺ ⟸ ⚛︎⚛︎⚛︎⚛︎⚛︎ ⚜️ ☰ ☷ ☲ ☴ ⚡ ☑️ ☎️ ☑️ ⚙️ 🌐 🌍 🌎 🗺️ ✉️ ✍️ ✳️ ◻️ ◼️ ▶▶◀◀ 📈 📉 📊 📅 📆 📇 🗂️ 🔎 🔍 🔐 🚀 🚁 🕒 🎯 🔧 ⚙🔧🚩🚩🌞🌝🌚🌑📚📓📖📝🗒️✏✒✍🖊🖋🖌🖍🎨✂✂⏰⏱⏲⏳⌛⌚📆📅🕰✨✨💡🔔🔕"This example is intentionally kept minimal so that you can focus on adjusting parameters according to your own environment.
常见误区汇总:
将 shared_buffers 设置过大 ⇒ 操作程序频繁换页,引起大量 IO 开销。
当共享缓冲超过机器物理 RAM 时Linux 会把部分页面写入交换空间,从而造成明显下降。
保持在「总RAM × 25% ~ ×50%」范围,并观察 top/htop 中 swapin/out 指标。其实,

