PolarDBforPostgreSQL/docs/zh/features/v11/availability/resource-manager.md

84 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
author: 学有
date: 2022/11/25
minute: 20
---
# Resource Manager
<Badge type="tip" text="V11 / v1.1.1-" vertical="top" />
<ArticleInfo :frontmatter=$frontmatter></ArticleInfo>
[[toc]]
## 背景
PolarDB for PostgreSQL 的内存可以分为以下三部分:
- 共享内存
- 进程间动态共享内存
- 进程私有内存
进程间动态共享内存和进程私有内存是 **动态分配** 的,其使用量随着实例承载的业务运行情况而不断变化。过多使用动态内存,可能会导致内存使用量超过操作系统限制,触发内核内存限制机制,造成实例进程异常退出,实例重启,引发实例不可用的问题。
进程私有内存 MemoryContext 管理的内存可以分为两部分:
- 工作计算区域内存:业务运行所需的内存,此部分内存会影响业务的正常运行;
- Cache 内存:数据库会把部分内部元数据存放在进程内,此部分内存只会影响数据库性能;
## 目标
为了解决以上问题PolarDB for PostgreSQL 增加了 **Resource Manager** 资源限制机制,能够在实例运行期间,周期性检测资源使用情况。对于超过资源限制阈值的进程,强制进行资源限制,降低实例不可用的风险。
Resource Manager 主要的限制资源有:
- 内存
- CPU
- I/O
当前仅支持对内存资源进行限制。
## 内存限制原理
内存限制依赖 Cgroup如果不存在 Cgroup则无法有效进行资源限制。Resource Manager 作为 PolarDB for PostgreSQL 一个后台辅助进程,周期性读取 Cgroup 的内存使用数据作为内存限制的依据。当发现存在进程超过内存限制阈值后会读取内核的用户进程内存记账按照内存大小排序依次对内存使用量超过阈值的进程发送中断进程信号SIGTERM或取消操作信号SIGINT
### 内存限制方式
Resource Manager 守护进程会随着实例启动而建立,同时对 RW、RO 以及 Standby 节点起作用。可以通过修改参数改变 Resource Manager 的行为。
- `enable_resource_manager`:是否启动 Resource Manager取值为 `on` / `off`,默认值为 `on`
- `stat_interval`:资源使用量周期检测的间隔,单位为毫秒,取值范围为 `10`-`10000`,默认值为 `500`
- `total_mem_limit_rate`:限制实例内存使用的百分比,当实例内存使用超过该百分比后,开始强制对内存资源进行限制,默认值为 `95`
- `total_mem_limit_remain_size`:实例内存预留值,当实例空闲内存小于预留值后,开始强制对内存资源进行限制,单位为 kB取值范围为 `131072`-`MAX_KILOBYTES`(整型数值最大值),默认值为 `524288`
- `mem_release_policy`:内存资源限制的策略
- `none`:无动作
- `default`:缺省策略(默认值),优先中断空闲进程,然后中断活跃进程
- `cancel_query`:中断活跃进程
- `terminate_idle_backend`:中断空闲进程
- `terminate_any_backend`:中断所有进程
- `terminate_random_backend`:中断随机进程
### 内存限制效果
```log:no-line-numbers
2022-11-28 14:07:56.929 UTC [18179] LOG: [polar_resource_manager] terminate process 13461 release memory 65434123 bytes
2022-11-28 14:08:17.143 UTC [35472] FATAL: terminating connection due to out of memory
2022-11-28 14:08:17.143 UTC [35472] BACKTRACE:
postgres: primary: postgres postgres [local] idle(ProcessInterrupts+0x34c) [0xae5fda]
postgres: primary: postgres postgres [local] idle(ProcessClientReadInterrupt+0x3a) [0xae1ad6]
postgres: primary: postgres postgres [local] idle(secure_read+0x209) [0x8c9070]
postgres: primary: postgres postgres [local] idle() [0x8d4565]
postgres: primary: postgres postgres [local] idle(pq_getbyte+0x30) [0x8d4613]
postgres: primary: postgres postgres [local] idle() [0xae1861]
postgres: primary: postgres postgres [local] idle() [0xae1a83]
postgres: primary: postgres postgres [local] idle(PostgresMain+0x8df) [0xae7949]
postgres: primary: postgres postgres [local] idle() [0x9f4c4c]
postgres: primary: postgres postgres [local] idle() [0x9f440c]
postgres: primary: postgres postgres [local] idle() [0x9ef963]
postgres: primary: postgres postgres [local] idle(PostmasterMain+0x1321) [0x9ef18a]
postgres: primary: postgres postgres [local] idle() [0x8dc1f6]
/lib64/libc.so.6(__libc_start_main+0xf5) [0x7f888afff445]
postgres: primary: postgres postgres [local] idle() [0x49d209]
```