#postgresql #amazon-rds #pg-cron
Вопрос:
все задания pg_cron завершаются с ошибкой «роль….не предоставляет разрешения на планирование задания».
Я работаю над получением pg_partman
и pg_cron
настройкой RDS, но когда мои 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
, и так было уже много лет.
Когда вы create extension pg_cron
подключаетесь к RDS, установка postgres
по умолчанию выполняется в базе данных, и она создает новую схему с именем cron
. Все это прекрасно. В качестве версии проблемы «привет, мир», вот простая таблица и задача для вставки текущего времени каждую минуту в текстовое поле.
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
. Я начал с 9.4 или 9.5 страницы, не мог сосредоточиться на обеспечении безопасности общественности…и лишил ее всех прав везде. Может быть, здесь понадобится положить немного обратно?
Permissions checks
Here are the permissions checks that I could think of.
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;
I gave the user all privileges on all of the tables, just to see if that cleared things up. No joy.
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
Nothing is obviously wrong with the schema rights:
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
Likewise, nothing pops out when I check function execution rights:
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, или это что-то, что я добавил много лет назад. В pg_cron
инструкциях RDS об этом ничего нет, так что, может быть, это только я. Мне нужно было немного настроить его search_path
и разрешения, чтобы все работало так, как мне нужно, но это нормально.
https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/PostgreSQL_pg_cron.html
Ответ №1:
По крайней мере, в моем случае ответ заключается в том, чтобы запускать задания от имени того же пользователя, pg_cron
что и фоновый поток. Я опубликовал более подробную информацию в конце первоначального вопроса.