Postgres 12 Docker容器启动失败:popen内存分配错误与initdb异常
Postgres 12+ Docker容器启动失败问题排查与解决
问题场景
在AWS Ubuntu 20.04实例上,使用postgres:12镜像的特定Docker容器启动失败,错误提示内存分配失败及postgres程序未找到,但同一机器上另一个postgres:12容器运行正常。
Docker Compose配置
postgres-tests: image: "postgres:12" restart: always command: postgres -c 'max_connections=200' environment: POSTGRES_DB: "${POSTGRES_DATABASE}" POSTGRES_USER: "${POSTGRES_USER}" POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}" ports: - "8396:5432"
启动错误日志
postgres-tests_1 | popen failure: Cannot allocate memory postgres-tests_1 | initdb: error: The program "postgres" is needed by initdb but was not found in the postgres-tests_1 | same directory as "/usr/lib/postgresql/12/bin/initdb". postgres-tests_1 | Check your installation.
已尝试的无效方案
- 调整系统共享内存参数
shmall/shmmax至最大值,问题未解决:ubuntu@ip-172-31-10-246:/var/www$ cat /proc/sys/kernel/shmall 18446744073692774399 ubuntu@ip-172-31-10-246:/var/www$ cat /proc/sys/kernel/shmmax 18446744073692774399 - 升级Postgres镜像至13.0、14.0版本,问题依旧;降级至11版本可正常运行,但生产环境无法降级。
- 重启实例、清理Docker缓存及卷,问题未解决。
软硬件环境信息
软件环境
Ubuntu 20.04.2 Docker version 20.10.8, build 3967b7d
硬件环境
- CPU: Intel(R) Xeon(R) Platinum 8124M CPU @ 3.00GHz
- RAM: 4/8GB(系统及其他服务占用)
- Swap: 4.5/20GB(系统及其他服务占用)
可行解决建议
1. 为容器分配明确的内存资源
虽然系统剩余内存充足,但Docker可能未给该容器分配足够内存,导致初始化时内存不足。在docker-compose.yml的postgres-tests服务中添加内存限制:
postgres-tests: # 其他配置不变 mem_limit: 2g mem_reservation: 1g
2. 修正启动命令格式
原命令使用shell字符串形式可能导致解析异常,改用数组形式避免shell干扰,同时确保初始化流程正常执行:
command: ["postgres", "-c", "max_connections=200"]
若容器是首次启动,可先移除command字段,待初始化完成后再添加该参数。
3. 重新拉取完整镜像
镜像文件可能损坏,执行以下命令重新拉取无缓存的镜像:
docker pull postgres:12 --no-cache
4. 检查并调整系统PID限制
popen failure可能与系统PID资源不足有关,查看当前PID最大值:
cat /proc/sys/kernel/pid_max
若值较低(如默认32768),可临时调高:
echo 65536 > /proc/sys/kernel/pid_max
或在docker-compose.yml中为容器设置PID限制:
postgres-tests: # 其他配置不变 pids_limit: 1024
5. 使用全新数据卷
旧数据卷可能存在权限或残留数据问题,定义新的数据卷并挂载:
postgres-tests: # 其他配置不变 volumes: - postgres-tests-new-data:/var/lib/postgresql/data volumes: postgres-tests-new-data:
内容的提问来源于stack exchange,提问作者arturkuchynski
相关产品推荐
相关产品推荐

