为何\connect mydb可解决PostgreSQL刷新物化视图时的unaccent函数不存在错误?
PostgreSQL恢复后REFRESH MATERIALIZED VIEW报错的根本原因
问题回顾
在一个集群上成功恢复数据库后,执行REFRESH MATERIALIZED VIEW操作正常;但在另一个使用相同自定义PostgreSQL镜像的集群执行相同流程时,仅在REFRESH MATERIALIZED VIEW环节出现两个报错:
function unaccent(text) does not existsrelation "banners_text_search" does not exist
连接恢复后的数据库能正常查询到这两个对象,说明恢复过程本身无问题。在REFRESH MATERIALIZED VIEW语句前添加\connect mydb重新连接数据库后,操作顺利完成。
根本原因:会话元数据缓存未同步
PostgreSQL的每个数据库会话都会维护一份本地元数据缓存,用来缓存数据库对象(函数、表、视图等)的信息,减少频繁查询系统目录的开销,提升执行效率。
当你在同一个会话内完成数据库恢复后,该会话的本地缓存仍然保留着恢复前的旧元数据状态——它不知道新恢复的unaccent函数和banners_text_search关系已经存在。此时执行REFRESH MATERIALIZED VIEW,PostgreSQL会优先使用会话本地缓存解析语句,自然找不到这些新对象,从而抛出“不存在”的错误。
而执行\connect mydb会创建一个全新的会话,新会话会重新从系统目录加载最新的元数据,此时就能正确识别到恢复出来的对象,REFRESH MATERIALIZED VIEW也就可以正常执行。
替代解决方案(无需重新连接)
如果不想重新连接,也可以通过以下方式刷新会话的元数据缓存:
- 执行
RESET ALL重置会话状态; - 调用
pg_stat_clear_snapshot()清除会话的快照缓存,强制重新读取系统目录。
不过重新连接是最直观且稳妥的方式,尤其在自动化脚本场景中。
内容的提问来源于stack exchange,提问作者Eugen Konkov
相关产品推荐
相关产品推荐

