如何修复 PostgreSQL “剩余连接槽位保留给超级用户” 错误

如何修复 PostgreSQL “剩余连接槽位保留给超级用户” 错误



❌ 错误: 您的应用可能会出现如下报错:
remaining connection slots are reserved for roles with the SUPERUSER attribute
这通常意味着 PostgreSQL 数据库的连接数已达到上限,部分连接可能是空闲事务会话,占用了可用槽位。

问题分析

PostgreSQL 通过 max_connections 限制并发连接数量。当所有普通槽位被占满时,只有超级用户可以连接。应用中长时间运行或空闲事务会话(idle-in-transaction)会占用连接,阻止新连接建立。

检查当前连接

ℹ️ 提示: 在终止任何连接之前,请先检查当前连接状态。
SELECT pid, usename, application_name, state, backend_start
FROM pg_stat_activity
ORDER BY backend_start;

注意查找 stateidle in transaction 的应用用户连接。

终止过期的空闲事务连接

⚠️ 警告: 仅终止应用用户连接。不要操作 postgres 系统用户或后台工作进程。
SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction'
  AND usename = 'your_app_user'
  AND now() - backend_start > interval '5 minutes';

your_app_user 替换为应用使用的数据库用户名。此操作可以安全释放连接而不会影响正在执行的查询。

注意事项

  • ❌ 不要终止系统连接(如 TimescaleDB 工作进程、pg_cron 等)
  • ✅ 保留当前会话(pid <> pg_backend_pid()
  • 💡 建议在应用中使用连接池,避免未来出现连接耗尽问题

长期解决方案

  • 使用连接池,例如 PgBouncer 或应用框架自带的池(Prisma、TypeORM 等)
  • 设置 idle_in_transaction_session_timeout 自动清理长时间空闲事务:
    ALTER DATABASE your_db SET idle_in_transaction_session_timeout = '1min';
    ALTER ROLE your_app_user SET idle_in_transaction_session_timeout = '1min';
  • 定期监控 pg_stat_activity,及时发现挂起事务

总结

通过终止旧的空闲事务连接并使用连接池,你可以快速解决 PostgreSQL “剩余连接槽位” 错误,确保应用稳定连接数据库。结合颜色提示和图标,可以让关键步骤更加清晰,操作更安全。

❤️ Support This Blog


If this post helped you, you can support my writing with a small donation. Thank you for reading.


Comments

Popular posts from this blog

fixed: embedded-redis: Unable to run on macOS Sonoma

Copying MDC Context Map in Web Clients: A Comprehensive Guide

Reset user password for your own Ghost blog