0

0

/dev/shm 被塞满导致 Redis/PostgreSQL 崩溃的业务场景与限制方法

舞夢輝影

舞夢輝影

发布时间:2026-01-25 17:41:03

|

175人浏览过

|

来源于php中文网

原创

/dev/shm 空间耗尽会导致 Redis 和 PostgreSQL 崩溃,因其 RDB 快照、并行查询、WAL 共享内存等依赖该 tmpfs 文件系统;默认 64MB 容易被占满,引发 ENOSPC 错误,造成服务拒绝连接或退出。

/dev/shm 被塞满导致 redis/postgresql 崩溃的业务场景与限制方法

为什么 /dev/shm 满了会让 Redis 和 PostgreSQL 崩溃

Redis 默认用 fork() 做 RDB 快照,PostgreSQL 的并行查询、WAL 共享内存、甚至某些客户端连接(如使用 unix_socket_directories 时的 socket 文件)都可能依赖 /dev/shm。它本质是基于 tmpfs 的内存文件系统,默认大小通常只有 64MB(取决于内核版本和发行版),而 fork 时子进程会复制父进程的虚拟内存页(写时复制),但某些共享内存段(如 PostgreSQL 的 shared_memory_type = mmap 或 Redis 的 AOF rewrite 过程中临时缓冲)会直接在 /dev/shm 创建文件——一旦空间耗尽,open()shm_open() 返回 ENOSPC,服务就卡在初始化或 checkpoint 阶段,表现为拒绝新连接、主从同步中断、甚至进程直接退出。

检查 /dev/shm 是否真成瓶颈

别只看 df -h /dev/shm,那只是 tmpfs 总大小;更要确认实际被哪些进程占用了:

  • 运行 ls -l /dev/shm/,重点关注以 redisPostgreSQLpg_sem.shmem. 开头的文件
  • find /dev/shm -type f -size +1M -ls 找大文件
  • 查 Redis 日志是否含 Failed to open the temp file for AOF rewriteCannot allocate memory
  • 查 PostgreSQL 日志是否含 could not resize shared memory segmentout of memory(注意:这不一定是物理内存不足,可能是 shm 限额)

临时扩容与永久配置 /dev/shm 大小

临时改法立竿见影但重启失效;永久改法需配合挂载参数,且必须避开 systemd-tmpfiles 的覆盖逻辑:

Miniflow
Miniflow

AI工作流自动化平台

下载
  • 临时扩容(立刻生效):sudo mount -o remount,size=2G /dev/shm
  • 永久生效(推荐):编辑 /etc/fstab,把原 tmpfs /dev/shm tmpfs defaults 0 0 改成 tmpfs /dev/shm tmpfs defaults,size=2G 0 0,然后 sudo mount -o remount /dev/shm
  • 避免 systemd 干扰:确保 /usr/lib/tmpfiles.d/tmp.conf/etc/tmpfiles.d/*.conf 中没有对 /dev/shmdZ 类型定义(它们会重置权限和大小)

更治本:让 Redis 和 PostgreSQL 少用 /dev/shm

扩容只是兜底,关键要减少对它的依赖:

  • Redis:设 stop-writes-on-bgsave-error no 只是掩盖问题;真正有效的是关掉 AOF(如果业务允许),或把 appendfilename 改到普通磁盘路径(AOF 文件本身不走 shm,但 rewrite 临时文件会);升级到 7.0+ 后可用 replica-announce-ip + replica-announce-port 避免某些 shm 通信路径
  • PostgreSQL:将 shared_memory_type 从默认的 mmap 改为 sysv(需重启),它用 System V IPC 而非 /dev/shm;同时调低 max_connectionswork_mem,减少共享内存总需求
  • 通用:禁用不需要的扩展(如 pg_stat_statements 在高并发下会频繁写 shm)、定期清理僵尸 socket 文件(find /dev/shm -name "PostgreSQL.*" -mmin +60 -delete

最常被忽略的是:容器环境里 /dev/shm 默认只有 64MB 且不会继承宿主机配置,docker run --shm-size=2g 或 Kubernetes 的 securityContext.shmSize 必须显式设置。

相关专题

更多
scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

188

2023.10.18

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

291

2023.10.25

数据库Delete用法
数据库Delete用法

数据库Delete用法:1、删除单条记录;2、删除多条记录;3、删除所有记录;4、删除特定条件的记录。更多关于数据库Delete的内容,大家可以访问下面的文章。

274

2023.11.13

drop和delete的区别
drop和delete的区别

drop和delete的区别:1、功能与用途;2、操作对象;3、可逆性;4、空间释放;5、执行速度与效率;6、与其他命令的交互;7、影响的持久性;8、语法和执行;9、触发器与约束;10、事务处理。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.12.29

k8s和docker区别
k8s和docker区别

k8s和docker区别有抽象层次不同、管理范围不同、功能不同、应用程序生命周期管理不同、缩放能力不同、高可用性等等区别。本专题为大家提供k8s和docker区别相关的各种文章、以及下载和课程。

257

2023.07.24

docker进入容器的方法有哪些
docker进入容器的方法有哪些

docker进入容器的方法:1. Docker exec;2. Docker attach;3. Docker run --interactive --tty;4. Docker ps -a;5. 使用 Docker Compose。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

495

2024.04.08

docker容器无法访问外部网络怎么办
docker容器无法访问外部网络怎么办

docker 容器无法访问外部网络的原因和解决方法:配置 nat 端口映射以将容器端口映射到主机端口。根据主机兼容性选择正确的网络驱动(如 host 或 overlay)。允许容器端口通过主机的防火墙。配置容器的正确 dns 服务器。选择正确的容器网络模式。排除主机网络问题,如防火墙或连接问题。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

401

2024.04.08

docker镜像有什么用
docker镜像有什么用

docker 镜像是预构建的软件组件,用途广泛,包括:应用程序部署:简化部署,提高移植性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

438

2024.04.08

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

45

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.4万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号