PostgreSQL逻辑复制时触发器访问lookup_table报错原因查询
报错原因分析
- 最核心的原因是触发器函数内对
lookup_table的引用没有使用全限定名(schema名.表名),PostgreSQL逻辑复制的worker进程默认的search_path(schema搜索路径)仅包含pg_catalog和public,和你本地psql登录使用的用户的search_path配置不一致。如果lookup_table存储在非public的自定义schema下,worker进程就无法找到该表,触发不存在的报错。 - 若
lookup_table确实存放在publicschema下,需要检查订阅的所属角色是否拥有publicschema的USAGE权限,以及lookup_table的SELECT权限。PostgreSQL触发器函数默认是SECURITY INVOKER模式,会用调用者(也就是逻辑复制worker进程的运行角色)的权限访问对象,权限不足也可能衍生出表不存在的报错。
修复建议
- 触发器函数内所有表引用都加上schema前缀,示例:
SELECT INTO a_id id from your_schema.lookup_table where your_schema.lookup_table.id = NEW.id;
- 也可以在触发器函数开头显式指定搜索路径,避免遗漏全限定名:
CREATE OR REPLACE FUNCTION record_filter() RETURNS trigger AS $$ DECLARE a_id integer; BEGIN SET search_path = your_schema, public; -- 替换为lookup_table实际所在的schema SELECT INTO a_id id from lookup_table where lookup_table.id = NEW.id; IF (a_id IS NOT NULL) AND (other logic) THEN RETURN NEW; END IF; RETURN null; END; $$ LANGUAGE plpgsql;
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

