执行pg_restore后运行Django管理命令出现Postgres relation not found错误
问题原因分析
- PgBouncer连接池缓存旧连接(最高概率):你执行删库重建操作后,Azure PgBouncer的连接池中还留存了大量绑定旧
my_db实例的长连接,后续的restore、查询请求如果被分配到这些旧连接上,就会出现逻辑上的表不存在错误(旧连接指向的库实例已经被删除,内存元数据失效)。这也解释了你为什么查询pg_tables能看到表,但查询业务表报错——两次请求被分配到了连接池中不同的新旧连接。你手动exec进Pod时等待时间较长,旧连接已经被超时回收,新建的连接指向新的my_db实例,所以执行正常;本地测试不经过PgBouncer,自然不会触发该问题。 - Schema搜索路径不匹配:如果restore操作将业务表写入了非
public的自定义Schema,但连接默认的search_path没有包含该Schema,也会触发表不存在错误。 - 脚本异步执行时序问题:如果shell脚本中没有等待
pg_restore完全执行完毕就发起后续查询请求,表还未完成写入也会触发该报错。
解决思路
- 重建库后强制刷新PgBouncer连接池
在执行完recreate_db.sql之后,立即连接PgBouncer的管理库执行重连操作,清空旧连接:
# 连接pgbouncer管理库执行重连,替换为你的pgbouncer管理员账号 psql -h localhost -U pgbouncer_admin -d pgbouncer -c "RECONNECT my_db;" # 也可以直接杀掉所有指向my_db的旧连接 psql -h localhost -U pgbouncer_admin -d pgbouncer -c "KILL my_db;"
如果使用Azure托管PgBouncer没有管理员权限,可以在重建库后增加30~60秒的等待时间,等待旧连接自动超时回收后再执行restore操作。
- 显式指定Schema搜索路径
在执行查询、运行Django命令前,先显式设置Schema路径:
- psql查询时增加路径设置:
psql -h localhost -U user -d my_db -c "SET search_path TO public; SELECT COUNT(*) FROM myapp_sometable;"
- Django配置文件中增加Schema配置:
DATABASES = { 'default': { # 其他配置保持不变 'OPTIONS': { 'options': '-c search_path=public' }, } }
- 完善脚本同步逻辑
给pg_restore命令增加-v --wait参数,同时开启shell的错误中止模式,确保所有操作执行完成后再走后续流程:
# 开启错误中止,确保restore出错就终止脚本 set -euo pipefail pg_restore -h localhost -U user -d my_db -v --wait /path/to/dumpfile
内容的提问来源于stack exchange,提问作者everspader
相关产品推荐
相关产品推荐

