MySQL、PostgreSQL、Redis 多实例的内存参数(innodb_buffer_pool_size、shared_buffers、maxmemory)均按进程独立生效,依赖OS级隔离与cgroups围栏防越界。
MySQL 多实例用
启动时,
是按实例独立分配的
每个
进程启动时加载自己的配置文件(如
),
只作用于当前实例的 innodb 缓冲池,不会跨进程共享或泄漏。只要端口、socket、数据目录、配置文件完全隔离,内存空间天然隔离。
常见错误现象:
里看到缓冲池大小和配置不一致;多个实例共用同一份
导致参数被覆盖;启动脚本硬编码了全局配置路径。
每个实例必须指定独立的
,不能依赖默认搜索路径
、
、
、
四者必须全部不同,缺一不可
避免在配置中使用
或环境变量拼接,容易意外复用同一份 buffer pool 配置
PostgreSQL 多实例需用
分别初始化 + 启动,
不会越界
PostgreSQL 没有“多实例”原生概念,靠多个独立的
目录 + 不同端口实现。每个
进程只读取自己
中的
,操作系统级进程隔离保证内存不互通。
使用场景:容器化部署、开发机本地跑测试库、生产中按业务线拆分集群。
初始化必须用
,不能 cp 整个
目录后改配置——wal 目录和 pg_control 会冲突
启动命令必须显式指定
,不能只改 conf 文件后 reload
值超过系统
会导致启动失败,错误信息是
,需同步调大内核参数
Redis 多实例靠
加载不同配置文件,
是硬隔离边界
Redis 实例间完全无共享内存,
是 per-process 的 RSS 上限,由
分配,不受其他 Redis 进程影响。越权读取只可能发生在客户端连错端口,而非内存泄漏。
性能影响:若多个实例部署在同一台机器且总内存超物理限制,Linux OOM Killer 可能杀掉任意一个
进程,错误日志里会出现
。
必须为每个实例写独立的
,禁用
引入公共配置(防止
被覆盖)
启动命令必须带绝对路径:
,不能 cd 进目录后执行
用
实时验证,避免配置热加载未生效
所有数据库都绕不开 Linux cgroups v2 —— 真正防越权得靠进程级资源围栏
配置文件里的内存参数只是应用层建议值,真正阻止越界的是 OS 层的 cgroups。比如 MySQL 实例即使配了
,若没用 cgroups 限制,它仍可能因临时排序、连接缓冲等吃满 16G 内存,挤占其他实例。
容易被忽略的地方:Docker 默认用 cgroups v2,但 systemd service 启动的
默认不在任何 slice 下,等于裸跑。
用
启动可即时生效
检查是否生效:
,看到
才算落进围栏
Redis 和 PostgreSQL 同理,但注意
子进程(如 PG 的 backend、Redis 的 RDB fork)也会继承 memory.max 限制
mysqldinnodb_buffer_pool_sizemysqldmy.cnfinnodb_buffer_pool_sizeSHOW ENGINE INNODB STATUSmy.cnf--defaults-file=/path/to/my_instance1.cnfdatadirsocketportpid-file!includepg_ctlshared_buffersPGDATApostgrespostgresql.confshared_bufferspg_ctl -D /data/pg_instance_a initdbPGDATA-D /data/pg_instance_a -c port=5433shared_buffersshmmaxcould not create shared memory segmentredis-servermaxmemorymaxmemorymallocredis-serverKilled process [pid] (redis-server)redis.confincludemaxmemoryredis-server /etc/redis/instance_a.confredis-serverredis-cli -p 6380 CONFIG GET maxmemoryinnodb_buffer_pool_size = 4Gmysqldsystemctl --scope -p MemoryMax=4G /usr/bin/mysqld --defaults-file=/etc/mysql/inst_a.cnfcat /proc//cgroup | grep memory memory.maxfork()