Windows专用服务器Node.js无法持续运行及PostgreSQL连接报错求助
解决PostgreSQL连接槽耗尽问题:remaining connection slots are reserved for non-replication superuser connections
这个错误我之前帮好几个开发者解决过,本质就是PostgreSQL的普通用户可用连接槽被完全占满了,剩下的槽位是专门预留超级用户(比如postgres)用来应急操作的。咱们一步步来搞定:
1. 先搞清楚当前连接状态
首先得用超级用户登录PostgreSQL,查看总连接数配置和已使用的连接数:
- Windows下打开命令提示符,找到PostgreSQL的bin目录(比如
C:\Program Files\PostgreSQL\15\bin),执行登录命令:psql.exe -U postgres - 然后执行以下查询:
-- 查看最大连接数配置 SHOW max_connections; -- 查看当前已使用的连接数 SELECT count(*) FROM pg_stat_activity; -- 查看预留的超级用户连接数 SHOW superuser_reserved_connections;
默认情况下superuser_reserved_connections是3,也就是说总连接数减去这个值,就是普通用户能使用的最大连接数。如果当前已用连接数接近或等于max_connections - superuser_reserved_connections,就会触发这个错误。
2. 临时应急:杀掉闲置连接
如果现在需要立刻恢复服务,可以先杀掉闲置的连接来释放槽位:
- 先找出所有闲置的普通用户连接:
SELECT pid, usename, state, query_start FROM pg_stat_activity WHERE state = 'idle' AND usename != 'postgres'; - 批量杀掉这些闲置连接:
SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE state = 'idle' AND usename != 'postgres';
注意:不要杀掉正在执行查询的连接(state为active的),避免影响正常业务。
3. 长期方案1:调整PostgreSQL连接数配置
如果业务确实需要更多连接,可以修改PostgreSQL的配置文件:
- 找到
postgresql.conf文件,Windows下通常在C:\Program Files\PostgreSQL\[你的版本号]\data\postgresql.conf - 找到
max_connections参数,默认是100,可以根据服务器内存调整(比如改成200,但不要盲目改太大,每个PostgreSQL连接大概占用几MB内存,太多会导致服务器内存不足) - 同时可以根据需要调整
superuser_reserved_connections(比如改成5,确保超级用户有足够应急槽位) - 修改后保存文件,然后重启PostgreSQL服务:打开Windows服务管理器,找到PostgreSQL服务,右键选择“重启”
4. 长期方案2:优化Node.js的连接池配置
你用的是pg模块连接PostgreSQL,一定要合理配置连接池,避免创建过多连接:
- 在代码里初始化连接池时,设置
max属性,这个值不要超过PostgreSQL的max_connections - superuser_reserved_connections,比如:const { Pool } = require('pg'); const pool = new Pool({ user: '你的数据库用户名', host: 'localhost', database: '你的数据库名', password: '你的数据库密码', port: 5432, max: 20, // 这里设置合理的最大值,比如20-50,根据业务量调整 idleTimeoutMillis: 30000, // 闲置连接30秒后自动释放 }); - 确保代码里正确使用连接池:优先用
pool.query(),它会自动管理连接的获取和释放;如果手动获取client,一定要记得在使用完后调用client.release(),哪怕是在异常情况下(可以用try/finally包裹):async function queryExample() { let client; try { client = await pool.connect(); const result = await client.query('SELECT * FROM your_table'); return result.rows; } finally { if (client) client.release(); // 确保释放连接 } }
5. 排查连接泄漏问题
如果经常出现连接耗尽,大概率是代码里存在连接泄漏(连接被获取后没有释放):
- 用以下查询查看长时间处于
idle或active状态的连接:SELECT pid, usename, state, query, query_start FROM pg_stat_activity WHERE usename = '你的普通数据库用户名'; - 对应这些连接的
query内容,检查代码里的相关逻辑,看是不是有未释放的连接,或者长时间运行的查询(比如没有加索引导致查询变慢,占用连接时间过长)
内容的提问来源于stack exchange,提问作者vishnu vigneshwar
相关产品推荐
相关产品推荐

