我正在努力在 RDS 上设置
pg_partman
和 pg_cron
,但是当我的 pg_cron
作业运行时,它们返回此错误:
ERROR: The protected role of rds_super doesn't provide permission to schedule a job.
从错误文本来看,我似乎错过了目录或资源中包含
pg_cron
的内容的简单权限问题,但我找不到问题的根源。而且,这可能是别的东西。大量的谷歌搜索、寻找资源和反复试验都没有给我带来任何答案,我希望得到帮助。
作为背景,这是 Postgres 13.4 和
pg_cron
1.3。这些是 RDS 上现在可用的最新版本。我的目标是让pg_cron
在此集群中的各个数据库中运行作业,但我已将问题示例简化为cron
中的postgres
模式。
RDS 定义了一个名为
rds_superuser
的角色,该角色没有登录名,然后您可以将其授予其他用户。我们正在使用名为 rds_super
的自定义角色,并且已经使用多年了。
当您在 RDS 上
create extension pg_cron
时,默认情况下会安装到 postgres
数据库中,并创建一个名为 cron
的新架构。没关系。作为问题的“hello world”版本,这里有一个简单的表格和任务,用于将每分钟的当前时间插入到文本字段中。
DROP TABLE IF EXISTS cron.foo;
CREATE TABLE IF NOT EXISTS cron.foo (
bar text
);
GRANT INSERT ON TABLE cron.foo TO rds_super;
INSERT INTO cron.foo VALUES (now()::text);
select * from cron.foo;
-- Run every minute
SELECT cron.schedule('postgres.populate.foo','*/1 * * * *',
$$INSERT INTO cron.foo VALUES (now()::text) $$);
当直接以
INSERT INTO cron.foo VALUES (now()::text)
用户身份连接时,裸语句 rds_super
工作正常。但是当它通过上面定义的cron.job
执行时,cron.job_run_details
输出具有正确的代码,预期的用户,但失败结果如下错误:
ERROR: The protected role of rds_super doesn't provide permission to schedule a job.
这对任何人来说都敲响了警钟吗?我已经删除,重新安装,明确设置权限。没有任何改善。
这可能是关闭的,但我遇到了一些事情,看起来我需要提供对
public
的访问。我从 PG 9.4 或 9.5 开始,无法集中精力保护公众……并剥夺了所有地方的所有权利。这里可能需要放一些回去?
以下是我能想到的权限检查。
select grantor,
grantee,
table_schema,
table_name,
string_agg (privilege_type, ',' order by privilege_type) as grants
from information_schema.role_table_grants
where table_catalog = 'postgres'
and table_schema = 'cron'
and grantee = 'rds_super'
group by 1,2,3,4
order by 1,2,3,4;
我授予用户所有表的所有权限,只是为了看看是否可以解决问题。没有喜悦。
grantor grantee table_schema table_name grants
rds_super rds_super cron foo DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE
rds_super rds_super cron job_run_details_plus DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE
rds_superuser rds_super cron job DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE
rds_superuser rds_super cron job_run_details DELETE,INSERT,REFERENCES,SELECT,TRIGGER,TRUNCATE,UPDATE
架构权限没有明显问题:
select pg_catalog.has_schema_privilege('rds_super', 'cron', 'CREATE') AS create,
pg_catalog.has_schema_privilege('rds_super', 'cron', 'USAGE') AS usage;
create usage
t t
同样,当我检查函数执行权限时,也没有弹出任何内容:
select proname, proargnames
from pg_proc
where has_function_privilege('rds_super',oid,'execute')
and pronamespace::regnamespace::text = 'cron'
order by 1,2
proname proargnames
job_cache_invalidate
schedule {job_name,schedule,command}
schedule {schedule,command}
unschedule {job_id}
unschedule {job_name}
我不知道这是否是答案,但它似乎解决了我的问题。 剧透:以 pg_cron scheduler
后台工作程序运行的用户身份登录。我烧掉了所有东西并重新启动,然后发现我的作业根本无法运行。没有错误,没有结果。我检查了后台工作人员的状态,如下所示:
select application_name,
usename,
backend_type,
query,
state,
wait_event_type,
age(now(),backend_start) as backend_start_age,
age(now(),query_start) as query_start_age,
age(now(),state_change) state_change_age
from pg_stat_activity
where backend_type != 'client backend';
我注意到后台工作程序已经运行了一天多(它作为共享库加载),并且似乎被卡住了。我重新启动了服务器,并重新以 dbadmin
(而不是我的自定义用户)身份登录的所有内容。在本例中,这是
pg_cron scheduler
进程运行的用户名。我不记得
dbadmin
是否是 RDS Postgres 软件包的一部分,或者是否是我几年前添加的东西。 RDS
pg_cron
说明中没有任何关于此的内容,所以也许只是我的问题。我需要设置它的
search_path
和权限才能让一切按照我需要的方式工作,但这很正常。
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html
pg_cron
后台线程相同的用户身份运行作业。我已在原始问题的末尾发布了更多详细信息。