Ao contrário de outros sistemas de gerenciamento de banco de dados que possuem seu próprio agendador embutido (como Oracle, MSSQL ou MySQL), o PostgreSQL ainda não possui esse tipo de recurso.
Para fornecer funcionalidade de agendamento no PostgreSQL, você precisará usar uma ferramenta externa como...
- Linux crontab
- Agente pgAgent
- Extensão pg_cron
Neste blog vamos explorar essas ferramentas e destacar como operá-las e seus principais recursos.
Linux crontab
É o mais antigo, porém, uma forma eficiente e útil de executar tarefas de agendamento. Este programa é baseado em um daemon (cron) que permite que tarefas sejam executadas automaticamente em segundo plano periodicamente e verifica regularmente os arquivos de configuração (chamados de arquivos crontab) nos quais são definidos o script/comando a ser executado e seu agendamento.
Cada usuário pode ter seu próprio arquivo crontab e as versões mais recentes do Ubuntu estão localizadas em:
/var/spool/cron/crontabs (for other linux distributions the location could be different):
[email protected]:/var/spool/cron/crontabs# ls -ltr
total 12
-rw------- 1 dbmaster crontab 1128 Jan 12 12:18 dbmaster
-rw------- 1 slonik crontab 1126 Jan 12 12:22 slonik
-rw------- 1 nines crontab 1125 Jan 12 12:23 nines
A sintaxe do arquivo de configuração é a seguinte:
mm hh dd mm day <<command or script to execute>>
mm: Minute(0-59)
hh: Hour(0-23)
dd: Day(1-31)
mm: Month(1-12)
day: Day of the week(0-7 [7 or 0 == Sunday])
Alguns operadores podem ser usados com essa sintaxe para simplificar a definição de agendamento e esses símbolos permitem especificar vários valores em um campo:
Asterisco (*) - significa todos os valores possíveis para um campo
A vírgula (,) - usada para definir uma lista de valores
Traço (-) - usado para definir um intervalo de valores
Separador (/) - especifica um valor de etapa
O script all_db_backup.sh será executado de acordo com cada expressão de agendamento:
0 6 * * * /home/backup/all_db_backup.sh | Às 6h todos os dias |
20 22 * * Seg, Ter, Qua, Qui, Sex /home/backup/all_db_backup.sh | Às 22h20, todos os dias da semana |
0 23 * * 1-5 /home/backup/all_db_backup.sh | Às 23h durante a semana |
0 0/5 14 * * /home/backup/all_db_backup.sh | A cada cinco horas, a partir das 14h. e terminando às 14h55, todos os dias |
Se o arquivo crontab não existir para um usuário, ele pode ser criado pelo seguinte comando:
[email protected]:~$ crontab -e
ou apresentou-o usando o parâmetro -l:
[email protected]:~$ crontab -l
Se for necessário remover este arquivo, o parâmetro apropriado é -r:
[email protected]:~$ crontab -r
O status do daemon cron é mostrado pela execução do seguinte comando:
Agente pgAgent
O pgAgent é um agente de agendamento de tarefas disponível para PostgreSQL que permite a execução de procedimentos armazenados, instruções SQL e scripts de shell. Sua configuração é armazenada no banco de dados postgres no cluster.
O objetivo é fazer com que este agente seja executado como um daemon em sistemas Linux e periodicamente faça uma conexão com o banco de dados para verificar se há algum trabalho a ser executado.
Este agendamento é facilmente gerenciado pelo PgAdmin 4, mas não é instalado por padrão, uma vez que o pgAdmin é instalado, é necessário fazer o download e instalá-lo por conta própria.
A seguir são descritos todos os passos necessários para que o pgAgent funcione corretamente:
Primeiro passo
Instalação do pgAdmin 4
$ sudo apt install pgadmin4 pgadmin4-apache
Passo Dois
Criação de linguagem procedural plpgsql se não definida
CREATE TRUSTED PROCEDURAL LANGUAGE ‘plpgsql’
HANDLER plpgsql_call_handler
HANDLER plpgsql_validator;
Passo Três
Instalação do pgAgent
$ sudo apt-get install pgagent
Passo Quatro
Criação da extensão pgagent
CREATE EXTENSION pageant
Esta extensão irá criar todas as tabelas e funções para a operação do pgAgent e a seguir é mostrado o modelo de dados utilizado por esta extensão:
Agora a interface pgAdmin já possui a opção “pgAgent Jobs” para gerenciar o pgAgent:
Para definir um novo trabalho, basta selecionar "Criar" usando o botão direito em “pgAgent Jobs”, e ele irá inserir uma designação para este trabalho e definir os passos para executá-lo:
Na aba “Schedules” deve ser definido o agendamento para este novo job :
Finalmente, para ter o agente rodando em segundo plano é necessário iniciar o seguinte processo manualmente:
/usr/bin/pgagent host=localhost dbname=postgres user=postgres port=5432 -l 1
No entanto, a melhor opção para este agente é criar um daemon com o comando anterior.
Extensão pg_cron
O pg_cron é um agendador de tarefas baseado em cron para PostgreSQL que roda dentro do banco de dados como uma extensão (semelhante ao DBMS_SCHEDULER no Oracle) e permite a execução de tarefas do banco de dados diretamente do banco de dados, devido a um trabalhador de fundo.
As tarefas a serem executadas podem ser qualquer uma das seguintes:
- procedimentos armazenados
- instruções SQL
- Comandos PostgreSQL (como VACUUM ou VACUUM ANALYZE)
pg_cron pode executar vários trabalhos em paralelo, mas apenas uma instância de um programa pode ser executada por vez.
Se uma segunda execução deve ser iniciada antes que a primeira termine, ela é colocada na fila e será iniciada assim que a primeira execução for concluída.
Esta extensão foi definida para a versão 9.5 ou superior do PostgreSQL.
Instalação do pg_cron
A instalação desta extensão requer apenas o seguinte comando:
[email protected]:~$ sudo apt-get -y install postgresql-10-cron
Atualização de arquivos de configuração
Para iniciar o trabalho em segundo plano pg_cron assim que o servidor PostgreSQL for iniciado, é necessário definir pg_cron para o parâmetro shared_preload_libraries em postgresql.conf:
shared_preload_libraries = ‘pg_cron’
É necessário definir também neste arquivo, o banco de dados no qual a extensão pg_cron será criada, adicionando o seguinte parâmetro:
cron.database_name= ‘postgres’
Por outro lado, no arquivo pg_hba.conf que gerencia a autenticação, é necessário definir o login do postgres como de confiança para as conexões IPV4, pois o pg_cron requer que tal usuário possa se conectar ao banco de dados sem fornecer nenhuma senha, então a seguinte linha precisa ser adicionada a este arquivo:
host postgres postgres 192.168.100.53/32 trust
O método de autenticação de confiança permite que qualquer pessoa se conecte ao(s) banco(s) de dados especificado(s) no arquivo pg_hba.conf, neste caso o banco de dados postgres. É um método usado com frequência para permitir a conexão usando o soquete de domínio Unix em uma máquina de usuário único para acessar o banco de dados e só deve ser usado quando houver uma proteção adequada no nível do sistema operacional nas conexões com o servidor.
Ambas as alterações exigem uma reinicialização do serviço PostgreSQL:
[email protected]:~$ sudo system restart postgresql.service
É importante levar em conta que o pg_cron não executa nenhum trabalho enquanto o servidor estiver em modo de espera ativa, mas inicia automaticamente quando o servidor é promovido.
Criação da extensão pg_cron
Esta extensão criará os metadados e os procedimentos para gerenciá-los, portanto, o seguinte comando deve ser executado no psql:
postgres=#CREATE EXTENSION pg_cron;
CREATE EXTENSION
Agora, os objetos necessários para agendar trabalhos já estão definidos no esquema cron :
Esta extensão é muito simples, apenas a tabela de tarefas é suficiente para gerenciar todos esta funcionalidade:
Definição de novos trabalhos
A sintaxe de agendamento para definir jobs no pg_cron é a mesma usada na ferramenta cron, e a definição de novos jobs é muito simples, bastando chamar a função cron.schedule:
select cron.schedule('*/5 * * * *','CALL reporting.p_compute_client_data(12356,''DAILY_DATA'');')
select cron.schedule('*/5 * * * *','CALL reporting.p_compute_client_data(998934,''WEEKLY_DATA'');')
select cron.schedule('*/5 * * * *','CALL reporting.p_compute_client_data(45678,''DAILY_DATA'');')
select cron.schedule('*/5 * * * *','CALL reporting.p_compute_client_data(1010,''WEEKLY_DATA'');')
select cron.schedule('*/5 * * * *','CALL reporting.p_compute_client_data(1001,''MONTHLY_DATA'');')
select cron.schedule('*/5 * * * *','select reporting.f_reset_client_data(0,''DATA'')')
select cron.schedule('*/5 * * * *','VACUUM')
select cron.schedule('*/5 * * * *','$$DELETE FROM reporting.rep_request WHERE create_dt<now()- interval '60 DAYS'$$)
A configuração do trabalho é armazenada na tabela de trabalhos:
Outra maneira de definir um trabalho é inserindo os dados diretamente no cron .tabela de trabalho:
INSERT INTO cron.job (schedule, command, nodename, nodeport, database, username)
VALUES ('0 11 * * *','call loader.load_data();','postgresql-pgcron',5442,'staging', 'loader');
e use valores personalizados para nodename e nodeport para conectar-se a uma máquina diferente (assim como a outros bancos de dados).
Desativação de um Trabalho
Por outro lado, para desativar um trabalho basta executar a seguinte função:
select cron.schedule(8)
Registro de trabalhos
O registro desses trabalhos pode ser encontrado no arquivo de log do PostgreSQL /var/log/postgresql/postgresql-12-main.log: