PostgreSQL 15恢复时函数创建疑似竞争条件问题求助
pg_restore恢复时生成列二级依赖函数找不到的竞争条件分析
可能的原因
- pg_restore的依赖解析漏洞:虽然日志显示
clean_text_for_search函数提前两分钟创建,但pg_restore对间接依赖的处理可能存在顺序问题。am_locations表的生成列依赖zip_code_to_tsvector,后者又依赖clean_text_for_search,这种二级依赖可能没被pg_restore的依赖检测正确识别,导致表创建和数据导入的时机早于函数的实际可用状态。 - 事务隔离导致的可见性问题:如果恢复过程不是在单事务中执行,函数创建和表数据导入可能分属不同事务。PostgreSQL默认的
READ COMMITTED隔离级别下,只有提交后的对象才会被其他事务可见。如果函数创建的事务在COPY操作之后才提交,导入数据时自然找不到该函数。 - 生成列的即时计算特性:COPY数据到带生成列的表时,PostgreSQL会实时计算生成列值,这对依赖函数的可见性要求极高。哪怕函数创建的日志已经输出,只要事务未提交或者元数据缓存未刷新,COPY操作就会触发函数不存在的错误。
可行的解决方案
- 使用单事务恢复:执行
pg_restore时添加--single-transaction参数,让整个恢复流程在一个事务内完成。这样所有对象的创建和数据导入都会在同一事务中,依赖关系的可见性完全一致,避免跨事务的可见性问题。 - 手动调整恢复顺序:
- 先单独恢复所有自定义函数:
pg_restore --include='function' --dbname=your_db backup_file.dump - 再恢复
am_locations表及其数据:pg_restore --include='table am_locations' --dbname=your_db backup_file.dump
- 先单独恢复所有自定义函数:
- 验证函数依赖关系:在数据库中执行
\df+ zip_code_to_tsvector,检查函数的依赖列表是否包含clean_text_for_search,确认没有拼写错误或依赖定义缺失。 - 检查数据库事务日志:查看PostgreSQL的
pg_log日志,确认clean_text_for_search函数创建的事务提交时间,是否确实早于COPY操作的执行时间,排除pg_restore日志和实际数据库操作的时间差问题。
内容的提问来源于stack exchange,提问作者d-vine
相关产品推荐
相关产品推荐

