在基于Rust和SQLx进行后端开发时,经常需要彻底重置数据库环境。这个过程通常包括删除旧库、创建新库,并重新运行迁移脚本,是一个标准的本地开发工作流。
然而,当你信心十足地执行 dropdb 命令时,终端可能会返回一个令人沮丧的错误:“数据库正在被其他用户访问”。这通常是因为之前的数据库客户端(如 psql 或 pgcli)、未正确退出的测试进程,甚至是IDE的数据库插件仍然保持着连接。

本文将介绍如何定位并优雅地清理这些残留连接,从而顺利完成数据库的重置操作。
问题复现
尝试删除名为 chat 的数据库时,遇到了以下错误:
➜ dropdb chat
dropdb: error: database removal failed: ERROR: database "chat" is being accessed by other users
DETAIL: There are 2 other sessions using the database.
原因分析:
这是PostgreSQL的一项安全机制。为了防止数据损坏,PostgreSQL禁止在任何活动连接(Active Sessions)存在的情况下删除数据库。错误详情明确指出了当前有2个会话正在使用目标数据库。因此,解决问题的关键在于终止这些活动连接。理解数据库连接的管理是后端与架构开发中的基础技能。
方案一:常规排查法(适用于所有版本)
如果你想明确知道是哪些进程占用了数据库,可以使用此方法进行精细操作。
第一步:查询活动连接
通过查询 pg_stat_activity 系统视图,可以找出所有连接到目标数据库的会话。
执行以下命令检查连接到 chat 数据库的会话:
psql -U postgres -c "SELECT pid, usename, application_name, client_addr, state FROM pg_stat_activity WHERE datname = 'chat';"
输出示例:
pid | usename | application_name | client_addr | state
------+----------+------------------+-------------+-------
3086 | postgres | | ::1 | idle
5406 | postgres | | ::1 | idle
(2 rows)
输出显示有两个进程(PID 3086 和 5406)处于 idle(空闲)状态,这很可能是之前未关闭的数据库客户端会话。
第二步:终止目标会话
使用 pg_terminate_backend() 函数来强制结束这些连接。
执行以下命令终止所有连接到 chat 数据库的会话(排除当前执行命令的连接自身):
psql -U postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'chat' AND pid <> pg_backend_pid();"
输出示例:
pg_terminate_backend
----------------------
t
t
(2 rows)
返回结果为 t (true) 表示对应会话已成功终止。
第三步:删除数据库
连接清理完毕后,即可安全地删除数据库。
dropdb chat
方案二:一行命令强制删除法(推荐,PostgreSQL 13+)
如果你的PostgreSQL版本在13及以上,并且希望快速完成操作,可以使用 DROP DATABASE ... WITH (FORCE) 命令。该命令会自动终止所有相关连接并删除数据库,一步到位。
直接执行:
psql -U postgres -c "DROP DATABASE chat WITH (FORCE);"
请注意: WITH (FORCE) 是强制操作,在生产环境中需极其谨慎地使用。但在本地开发环境进行数据重置时,它是最高效的选择。
后续步骤:重建数据库与环境
成功删除旧数据库后,可以重新为你的Rust项目初始化数据库环境。
1. 创建新数据库
createdb chat
2. 运行SQLx迁移脚本
在项目根目录下,执行迁移命令来创建表结构。
sqlx migrate run
命令输出类似 Applied ...,表示迁移已成功应用。至此,一个全新的数据库环境已准备就绪,可以继续你的开发工作。对于使用Rust等语言进行数据密集型应用开发的场景,掌握高效的数据库环境管理方法至关重要。
总结与速查命令
遇到 database "xxx" is being accessed by other users 错误的核心原因是PostgreSQL在有活动连接时拒绝删除操作。
解决方案速查:
方法A:通用组合命令(适合加入项目的Makefile或脚本中)
# 终止连接并删除数据库
psql -U postgres -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'chat' AND pid <> pg_backend_pid();" && dropdb chat
方法B:极简强制命令(仅限 PostgreSQL 13+)
psql -U postgres -c "DROP DATABASE chat WITH (FORCE);"
核心要点:
- 若想探查原因,请查询
pg_stat_activity 系统表。
- 若只想快速解决问题,在支持的环境下直接使用
DROP DATABASE ... WITH (FORCE)。
将上述命令封装到你的项目脚本中,下次需要重置开发数据库时,即可实现一键操作。
参考