Usar extensões PostgreSQL com o Amazon RDS para PostgreSQL - Amazon Relational Database Service

Usar extensões PostgreSQL com o Amazon RDS para PostgreSQL

É possível estender a funcionalidade do PostgreSQL instalando uma variedade de extensões e módulos. Por exemplo, para trabalhar com dados espaciais, você pode instalar e usar a extensão PostGIS. Para obter mais informações, consulteGerenciar dados espaciais com a extensão PostGIS Como outro exemplo, se você quiser melhorar a entrada de dados para tabelas muito grandes, considere particionar seus dados usando pg_partman. Para saber mais, consulte Gerenciar partições do PostgreSQL com a extensão pg_partman.

nota

A partir do RDS para PostgreSQL 14.5, o RDS para PostgreSQL é compatível com Trusted Language Extensions para PostgreSQL. Esse recurso é implementado como a extensão pg_tle, que você pode adicionar à sua instância de banco de dados do RDS para PostgreSQL. Ao usar essa extensão, os desenvolvedores podem criar suas próprias extensões do PostgreSQL em um ambiente seguro que simplifique os requisitos de instalação e configuração. Para ter mais informações, consulte Trabalhar com Trusted Language Extensions para PostgreSQL.

Em alguns casos, em vez de instalar uma extensão, você pode adicionar um módulo específico à lista de shared_preload_libraries no grupo de parâmetros de banco de dados personalizado da instância de banco de dados do RDS para PostgreSQL. Normalmente, o grupo de parâmetros padrão do cluster de banco de dados carrega somente as pg_stat_statements, mas vários outros módulos estão disponíveis para serem adicionados à lista. Por exemplo, você pode incluir a capacidade de agendamento adicionando o módulo pg_cron, conforme detalhado em Agendar manutenção com a extensão pg_cron do PostgreSQL. Como outro exemplo, você pode registrar planos de execução de consultas carregando o módulo auto_explain. Para saber mais, consulte Logging execution plans of queries (Registrar em log planos de execução de consultas) no Centro de Conhecimentos da AWS.

Dependendo da versão do RDS para PostgreSQL, a instalação de uma extensão pode exigir permissões de rds_superuser, como a seguir:

  • Para o RDS para PostgreSQL versões 12 e versões anteriores, a instalação de extensões requer privilégios de rds_superuser.

  • Para o RDS para PostgreSQL versão 13 e versões superiores, os usuários (perfis) com permissões de criação em uma determinada instância de banco de dados podem instalar e usar quaisquer extensões confiáveis. Para obter uma lista de extensões confiáveis, consulte Extensões confiáveis do PostgreSQL.

Também é possível especificar com precisão quais extensões podem ser instaladas na instância de banco de dados do RDS para PostgreSQL, listando-as no parâmetro rds.allowed_extensions. Para ter mais informações, consulte Restringir a instalação de extensões do PostgreSQL.

Para saber mais a respeito do perfil de rds_superuser, consulte Noções básicas de perfis e permissões do PostgreSQL.

Usar funções da extensão orafce

A extensão orafce fornece funções e operadores que emulam um subconjunto de funções e pacotes de um banco de dados Oracle. A extensão orafce permite fazer a portabilidade de uma aplicação Oracle para o PostgreSQL com mais facilidade. Essa extensão é compatível com o RDS para PostgreSQL versões 9.6.6 e posteriores. Para obter mais informações sobre a extensão, consulte o orafce no GitHub.

nota

O RDS para PostgreSQL não é compatível com o pacote utl_file que faz parte da extensão orafce. Isso ocorre porque as funções do esquema utl_file fornecem operações de leitura e gravação em arquivos de texto do sistema operacional, o que exige que o superusuário acesse o host subjacente. Como um serviço gerenciado, o RDS para PostgreSQL não fornece acesso ao host.

Para usar a extensão orafce
  1. Conecte-se à instância de banco de dados com o nome do usuário principal que você usou para criar a instância de banco de dados.

    Se você quiser ativar a extensão orafce para um banco de dados diferente na mesma instância de banco de dados, use o comando /c dbname do psql. Usando esse comando, você muda do banco de dados primário depois de iniciar a conexão.

  2. Ativar a extensão orafce com a instrução CREATE EXTENSION.

    CREATE EXTENSION orafce;
  3. Transfira propriedade do esquema oracle para a função rds_superuser com a instrução ALTER SCHEMA.

    ALTER SCHEMA oracle OWNER TO rds_superuser;

    Caso queira ver uma lista de proprietários do esquema oracle, use o comando de psql \dn.

Usar pgactive para comportar a replicação ativa-ativa

A extensão pgactive usa replicação ativa-ativa para comportar e coordenar operações de gravação em vários bancos de dados do RDS para PostgreSQL. O Amazon RDS para PostgreSQL é compatível com a extensão pgactive nas seguintes versões:

  • RDS para PostgreSQL 16.1 e versões 16 posteriores

  • RDS para PostgreSQL 15.4-R2 e versões 15 posteriores

  • RDS para PostgreSQL 14.10 e versões 14 posteriores

  • RDS para PostgreSQL 13.13 e versões 13 posteriores

  • RDS para PostgreSQL 12.17 e versões 12 posteriores

  • RDS para PostgreSQL 11.22

nota

Quando há operações de gravação em mais de um banco de dados em uma configuração de replicação, existe a possibilidade de conflitos. Para ter mais informações, consulte Lidar com conflitos na replicação ativa-ativa.

Inicializar o recurso de extensão pgactive

Para inicializar o recurso de extensão pgactive na instância de banco de dados do RDS para PostgreSQL, defina o valor do parâmetro rds.enable_pgactive como 1 e, em seguida, crie a extensão no banco de dados. Isso ativa automaticamente os parâmetros rds.logical_replication e track_commit_timestamp e define o valor de wal_level como logical.

Você deve ter permissões como a função rds_superuser para realizar essas tarefas.

Você pode usar o AWS Management Console ou a AWS CLI para criar as instâncias necessárias do banco de dados RDS para PostgreSQL. As etapas a seguir pressupõem que a instância de banco de dados do RDS para PostgreSQL esteja associada a um grupo de parâmetros de banco de dados personalizado. Para obter mais informações sobre como criar um grupo de parâmetros de banco de dados personalizado, consulte Grupos de parâmetros para Amazon RDS.

Como inicializar o recurso de extensão pgactive
  1. Faça login no AWS Management Console e abra o console do Amazon RDS em https://console.aws.amazon.com/rds/.

  2. No painel de navegação, escolha a instância de banco de dados do RDS para PostgreSQL.

  3. Abra a guia Configuração para a instância de banco de dados do RDS para PostgreSQL. Nos detalhes da instância, encontre o link do Grupo de parâmetros da instância de banco de dados.

  4. Clique no link para abrir os parâmetros personalizados associados à instância de banco de dados do RDS para PostgreSQL.

  5. Encontre o parâmetro rds.enable_pgactive e configure-o como 1 para inicializar o recurso pgactive.

  6. Escolha Salvar alterações.

  7. No painel de navegação do console do Amazon RDS, escolha Bancos de dados.

  8. Selecione a instância de banco de dados do RDS para PostgreSQL e escolha Reinicializar no menu Ações.

  9. Confirme a reinicialização da instância de banco de dados para que as alterações tenham efeito.

  10. Quando a instância de banco de dados estiver disponível, use psql ou qualquer outro cliente PostgreAQL para se conectar à instância de banco de dados do RDS para PostgreSQL.

    O exemplo a seguir pressupõe que a instância de banco de dados do RDS para PostgreSQL tenha um banco de dados padrão chamado postgres.

    psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  11. Para verificar se pgactive foi inicializada, execute o comando a seguir.

    postgres=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';

    Se pgactive estiver em shared_preload_libraries, o comando anterior retornará o seguinte:

    ?column? ---------- t
  12. Crie a extensão da forma a seguir.

    postgres=> CREATE EXTENSION pgactive;
Como inicializar o recurso de extensão pgactive

Para inicializar pgactive usando a AWS CLI, execute a operação modify-db-parameter-group para modificar determinados parâmetros no grupo parâmetros personalizado, conforme mostrado no procedimento a seguir.

  1. Use o comando AWS CLI a seguir para definir rds.enable_pgactive como 1 para inicializar o recurso pgactive da instância de banco de dados do RDS para PostgreSQL.

    postgres=>aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=rds.enable_pgactive,ParameterValue=1,ApplyMethod=pending-reboot" \ --region aws-region
  2. Use o comando AWS CLI a seguir para reinicializar a instância de banco de dados do RDS para PostgreSQL e inicializar a biblioteca da pgactive.

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. Quando a instância estiver disponível, use psql para se conectar à instância de banco de dados RDS para PostgreSQL.

    psql --host=mydb.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master user --password --dbname=postgres
  4. Crie a extensão da forma a seguir.

    postgres=> CREATE EXTENSION pgactive;

Configurar a replicação lógica para as instâncias de banco de dados do RDS para PostgreSQL

O procedimento a seguir mostra como iniciar a replicação ativa-ativa entre duas instâncias de banco de dados do RDS PostgreSQL executando o PostgreSQL 15.4 ou posterior na mesma região. Para executar o exemplo de alta disponibilidade multirregional, você precisa implantar instâncias do Amazon RDS para PostgreSQL em duas regiões diferentes e configurar o emparelhamento de VPC. Para obter mais informações, consulte Emparelhamento de VPC.

nota

O envio de tráfego entre várias regiões pode gerar custos adicionais.

Estas etapas pressupõem que a instância de banco de dados do RDS para PostgreSQL foi configurada com a extensão pgactive. Para ter mais informações, consulte Inicializar o recurso de extensão pgactive.

Como configurar a primeira instância de banco de dados do RDS para PostgreSQL com a extensão pgactive

O exemplo a seguir ilustra como o grupo pgactive é criado e mostra outras etapas necessárias para criar a extensão pgactive na instância de banco de dados do RDS para PostgreSQL.

  1. Use psql ou outra ferramenta cliente para se conectar à primeira instância de banco de dados do RDS para PostgreSQL.

    psql --host=firstinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. Crie um banco de dados na instância do RDS para PostgreSQL usando o seguinte comando:

    postgres=> CREATE DATABASE app;
  3. Alterne a conexão para o novo banco de dados usando o seguinte comando:

    \c app
  4. Para verificar se o parâmetro shared_preload_libraries contém pgactive, execute o seguinte comando:

    app=>SELECT setting ~ 'pgactive' FROM pg_catalog.pg_settings WHERE name = 'shared_preload_libraries';
    ?column? ---------- t
  5. Crie e preencha uma tabela de exemplo usando a seguinte instrução SQL:

    1. Crie uma tabela de exemplo usando a declaração SQL a seguir.

      app=> CREATE SCHEMA inventory; CREATE TABLE inventory.products ( id int PRIMARY KEY, product_name text NOT NULL, created_at timestamptz NOT NULL DEFAULT CURRENT_TIMESTAMP);
    2. Preencha a tabela com alguns dados de amostra usando a instrução SQL a seguir.

      app=> INSERT INTO inventory.products (id, product_name) VALUES (1, 'soap'), (2, 'shampoo'), (3, 'conditioner');
    3. Verifique se os dados existem na tabela usando a declaração SQL a seguir.

      app=>SELECT count(*) FROM inventory.products; count ------- 3
  6. Crie uma extensão pgactive no banco de dados existente.

    app=> CREATE EXTENSION pgactive;
  7. Crie e inicialize o grupo pgactive usando os seguintes comandos:

    app=> SELECT pgactive.pgactive_create_group( node_name := 'node1-app', node_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=master username password=PASSWORD');

    node1-app é o nome atribuído para identificar de maneira exclusiva um nó no grupo pgactive.

    nota

    Para realizar essa etapa com êxito em uma instância de banco de dados acessível ao público geral, você deve ativar o parâmetro rds.custom_dns_resolution definindo-o como 1.

  8. Para verificar se a instância de banco de dados está pronta, use o seguinte comando:

    app=> SELECT pgactive.pgactive_wait_for_node_ready();

    Se o comando for bem-sucedido, você verá o seguinte resultado:

    pgactive_wait_for_node_ready ------------------------------ (1 row)
Como configurar a segunda instância do RDS para PostgreSQL e juntá-la ao grupo pgactive

O exemplo a seguir mostra como juntar uma instância de banco de dados do RDS para PostgreSQL ao grupo pgactive, bem como outras etapas necessárias para criar a extensão pgactive na instância de banco de dados.

Estas etapas pressupõem que as instâncias de banco de dados do RDS para PostgreSQL tenham sido configuradas com a extensão pgactive. Para ter mais informações, consulte Inicializar o recurso de extensão pgactive.

  1. Use psql para se conectar à instância em que você deseja receber atualizações do editor.

    psql --host=secondinstance.111122223333.aws-region.rds.amazonaws.com --port=5432 --username=master username --password --dbname=postgres
  2. Crie um banco de dados na segunda instância de banco de dados do RDS para PostgreSQL usando o seguinte comando:

    postgres=> CREATE DATABASE app;
  3. Alterne a conexão para o novo banco de dados usando o seguinte comando:

    \c app
  4. Crie a extensão pgactive no banco de dados existente.

    app=> CREATE EXTENSION pgactive;
  5. Junte o a segunda instância de banco de dados do RDS para PostgreSQL ao grupo pgactive da forma a seguir.

    app=> SELECT pgactive.pgactive_join_group( node_name := 'node2-app', node_dsn := 'dbname=app host=secondinstance.111122223333.aws-region.rds.amazonaws.com user=master username password=PASSWORD', join_using_dsn := 'dbname=app host=firstinstance.111122223333.aws-region.rds.amazonaws.com user=postgres password=PASSWORD');

    node2-app é o nome atribuído para identificar de maneira exclusiva um nó no grupo pgactive.

  6. Para verificar se a instância de banco de dados está pronta, use o seguinte comando:

    app=> SELECT pgactive.pgactive_wait_for_node_ready();

    Se o comando for bem-sucedido, você verá o seguinte resultado:

    pgactive_wait_for_node_ready ------------------------------ (1 row)

    Se o primeiro banco de dados RDS para PostgreSQL for relativamente grande, você poderá ver pgactive.pgactive_wait_for_node_ready() emitindo o relatório de progresso da operação de restauração. A saída será semelhante à seguinte:

    NOTICE: restoring database 'app', 6% of 7483 MB complete NOTICE: restoring database 'app', 42% of 7483 MB complete NOTICE: restoring database 'app', 77% of 7483 MB complete NOTICE: restoring database 'app', 98% of 7483 MB complete NOTICE: successfully restored database 'app' from node node1-app in 00:04:12.274956 pgactive_wait_for_node_ready ------------------------------ (1 row)

    Deste ponto em diante, pgactive sincroniza os dados entre as duas instâncias de banco de dados.

  7. Você pode usar o comando a seguir para verificar se o banco de dados da segunda instância de banco de dados tem os dados:

    app=> SELECT count(*) FROM inventory.products;

    Se os dados forem sincronizados com sucesso, você verá a seguinte saída:

    count ------- 3
  8. Execute o seguinte comando para inserir novos valores:

    app=> INSERT INTO inventory.products (id, product_name) VALUES ('lotion');
  9. Conecte-se ao banco de dados da primeira instância de banco de dados e execute a seguinte consulta:

    app=> SELECT count(*) FROM inventory.products;

    Se a replicação ativa-ativa for inicializada, a saída será semelhante à seguinte:

    count ------- 4
Como desanexar e remover uma instância de banco de dados do grupo pgactive

É possível desanexar e remover uma instância de banco de dados do grupo pgactive usando estas etapas:

  1. Você pode separar a segunda instância de banco de dados da primeira instância de banco de dados usando o seguinte comando:

    app=> SELECT * FROM pgactive.pgactive_detach_nodes(ARRAY[‘node2-app']);
  2. Remova a extensão pgactive da segunda instância de banco de dados usando o seguinte comando:

    app=> SELECT * FROM pgactive.pgactive_remove();

    Para remover a extensão forçosamente:

    app=> SELECT * FROM pgactive.pgactive_remove(true);
  3. Descarte a extensão usando o seguinte comando:

    app=> DROP EXTENSION pgactive;

Lidar com conflitos na replicação ativa-ativa

A extensão pgactive funciona por banco de dados e não por cluster. Cada instância de banco de dados que usa pgactive é uma instância independente e pode aceitar alterações de dados de qualquer fonte. Quando uma alteração é enviada a uma instância de banco de dados, o PostgreSQL a confirma localmente e depois usa pgactive para replicar a alteração de forma assíncrona para outras instâncias de banco de dados. Quando duas instâncias de banco de dados do PostgreSQL atualizam o mesmo registro quase ao mesmo tempo, pode ocorrer um conflito.

A extensão pgactive fornece mecanismos para detecção de conflitos e resolução automática. Ela rastreia o carimbo de data/hora em que a transação foi confirmada em ambas as instâncias de banco de dados e aplica automaticamente a alteração com o carimbo de data/hora mais recente. A extensão pgactive também registra em log quando ocorre um conflito na tabela pgactive.pgactive_conflict_history.

O pgactive.pgactive_conflict_history continuará crescendo. Talvez você queira definir uma política de limpeza. Isso pode ser feito excluindo alguns registros regularmente ou definindo um esquema de particionamento para essa relação (e depois separando, descartando e truncando as partições de interesse). Para implementar a política de limpeza regularmente, uma opção é usar a extensão pg_cron. Veja as informações a seguir de um exemplo para a tabela de histórico pg_cron, Agendar manutenção com a extensão pg_cron do PostgreSQL.

Lidar com sequências na replicação ativa-ativa

Uma instância de banco de dados do RDS para PostgreSQL com a extensão pgactive usa dois mecanismos de sequência diferentes para gerar valores exclusivos.

Sequências globais

Para usar uma sequência global, crie uma sequência local com a instrução CREATE SEQUENCE. Use pgactive.pgactive_snowflake_id_nextval(seqname) em vez de usingnextval(seqname) para obter o próximo valor exclusivo da sequência.

O exemplo a seguir cria uma rede global.

postgres=> CREATE TABLE gstest ( id bigint primary key, parrot text );
postgres=>CREATE SEQUENCE gstest_id_seq OWNED BY gstest.id;
postgres=> ALTER TABLE gstest \ ALTER COLUMN id SET DEFAULT \ pgactive.pgactive_snowflake_id_nextval('gstest_id_seq');
Sequências particionadas

Em sequências divididas ou particionadas, uma sequência normal do PostgreSQL é usada em cada nó. Cada sequência é incrementada na mesma quantidade e começa com diferentes deslocamentos. Por exemplo, com a etapa 100, o nó 1 gera a sequência como 101, 201, 301 e assim por diante, e o nó 2 gera a sequência como 102, 202, 302 e assim por diante. Esse esquema funciona bem mesmo que os nós não possam se comunicar por longos períodos, mas exige que o designer especifique um número máximo de nós ao estabelecer o esquema e requer configuração por nó. Erros podem facilmente levar à sobreposição de sequências.

É relativamente simples configurar essa abordagem com pgactive criando a sequência desejada em um nó da seguinte maneira:

CREATE TABLE some_table (generated_value bigint primary key);
postgres=> CREATE SEQUENCE some_seq INCREMENT 100 OWNED BY some_table.generated_value;
postgres=> ALTER TABLE some_table ALTER COLUMN generated_value SET DEFAULT nextval('some_seq');

Em seguida, chame setval em cada nó para fornecer um valor inicial de deslocamento diferente da forma a seguir.

postgres=> -- On node 1 SELECT setval('some_seq', 1); -- On node 2 SELECT setval('some_seq', 2);

Referência de parâmetros da extensão pgactive

É possível usar a consulta a seguir para visualizar todos os parâmetros associados à extensão pgactive.

postgres=> SELECT * FROM pg_settings WHERE name LIKE 'pgactive.%';

Medir o atraso de replicação entre membros pgactive

Você pode usar a consulta a seguir para visualizar o atraso de replicação entre os membros de pgactive. Execute essa consulta em cada nó de pgactive para ter a imagem completa.

postgres=# SELECT *, (last_applied_xact_at - last_applied_xact_committs) AS lag FROM pgactive.pgactive_node_slots; -{ RECORD 1 ]----------------+----------------------------------------------------------------- node_name | node2-app slot_name | pgactive_5_7332551165694385385_0_5__ slot_restart_lsn | 0/1A898A8 slot_confirmed_lsn | 0/1A898E0 walsender_active | t walsender_pid | 69022 sent_lsn | 0/1A898E0 write_lsn | 0/1A898E0 flush_lsn | 0/1A898E0 replay_lsn | 0/1A898E0 last_sent_xact_id | 746 last_sent_xact_committs | 2024-02-06 18:04:22.430376+00 last_sent_xact_at | 2024-02-06 18:04:22.431359+00 last_applied_xact_id | 746 last_applied_xact_committs | 2024-02-06 18:04:22.430376+00 last_applied_xact_at | 2024-02-06 18:04:52.452465+00 lag | 00:00:30.022089

Limitações da extensão pgactive

  • Todas as tabelas exigem uma chave primária; do contrário, atualizações e exclusões não são permitidas. Os valores na coluna Chave primária não devem ser atualizados.

  • As sequências podem ter lacunas e, às vezes, podem não seguir uma ordem. As sequências não são replicadas. Para ter mais informações, consulte Lidar com sequências na replicação ativa-ativa.

  • O DDL e os objetos grandes não são replicados.

  • Índices secundários exclusivos podem causar divergência de dados.

  • O agrupamento precisa ser idêntico em todos os nós do grupo.

  • O balanceamento de carga entre os nós é um antipadrão.

  • Transações grandes podem causar atraso na replicação.

Reduzir o inchaço em tabelas e índices com a extensão pg_repack

É possível usar a extensão pg_repack para remover a sobrecarga de tabelas e índices como uma alternativa a VACUUM FULL. Esta extensão é compatível com o RDS para PostgreSQL versões 9.6.3 e posteriores. Para ter mais informações sobre a extensão pg_repack e a recriação da tabela inteira, consulte a documentação de projetos do GitHub.

Ao contrário de VACUUM FULL, a extensão pg_repack requer um bloqueio exclusivo (AccessExclusiveLock) somente por um curto período durante a operação de recriação da tabela nos seguintes casos:

  • Criação inicial da tabela de logs: uma tabela de logs é criada para registrar as alterações que ocorrem durante a cópia inicial dos dados, conforme mostrado no seguinte exemplo:

    postgres=>\dt+ repack.log_* List of relations -[ RECORD 1 ]-+---------- Schema | repack Name | log_16490 Type | table Owner | postgres Persistence | permanent Access method | heap Size | 65 MB Description |
  • Fase final de troca e descarte.

Para o restante da operação de recriação, ela só precisa de um bloqueio ACCESS SHARE na tabela original para copiar as linhas dela para a nova tabela. Isso ajuda as operações INSERT, UPDATE e DELETE a prosseguir normalmente.

Recomendações

As recomendações a seguir se aplicam ao remover a sobrecarga das tabelas e dos índices usando a extensão pg_repack:

  • Realize a recriação fora do horário comercial ou durante uma janela de manutenção para minimizar o impacto na performance de outras atividades do banco de dados.

  • Monitore atentamente as sessões de bloqueio durante a atividade de recriação e garanta que não haja nenhuma atividade na tabela original que possa bloquear pg_repack, especificamente durante a fase final de troca e descarte, quando ela precisa de um bloqueio exclusivo na tabela original. Para ter mais informações, consulte Como identificar o que está bloqueando uma consulta.

    Ao ver uma sessão de bloqueio, é possível encerrá-la usando o comando a seguir após uma análise cuidadosa. Isso ajuda na continuação da pg_repack para concluir a recriação:

    SELECT pg_terminate_backend(pid);
  • Ao aplicar as alterações acumuladas da tabela de logs de pg_repack's em sistemas com uma taxa de transação muito alta, o processo de aplicação pode não ser capaz de acompanhar a taxa de alterações. Nesses casos, pg_repack não conseguiria concluir o processo de aplicação. Para ter mais informações, consulte Monitorar a nova tabela durante a recriação. Se os índices estiverem muito sobrecarregados, uma solução alternativa será realizar uma recriação somente de índices. Isso também ajuda os ciclos de limpeza do índice do VACUUM a terminar mais rapidamente.

    É possível ignorar a fase de limpeza do índice usando o VACUUM manual do PostgreSQL versão 12, e ela é ignorada automaticamente durante o autovacuum de emergência do PostgreSQL versão 14. Isso ajuda o VACUUM a ser concluído mais rapidamente sem remover a sobrecarga do índice e serve apenas para situações de emergência, como evitar o VACUUM de encapsulamento. Para ter mais informações, consulte Evitar a sobrecarga nos índices no Guia do usuário do Amazon Aurora.

Pré-requisitos

  • A tabela deve ter PRIMARY KEY ou a restrição UNIQUE não nula.

  • A versão da extensão deve ser a mesma para o cliente e para o servidor.

  • Garanta que a instância do RDS tenha mais FreeStorageSpace do que o tamanho total da tabela sem a sobrecarga. Por exemplo, pense no tamanho total da tabela, incluindo TOAST e índices, como 2 TB, e a sobrecarga total na tabela, como 1 TB. O FreeStorageSpace necessário deve ser maior do que o valor exibido pelo seguinte cálculo:

    2TB (Table size) - 1TB (Table bloat) = 1TB

    É possível usar a consulta a seguir para conferir o tamanho total da tabela e usar pgstattuple para gerar a sobrecarga. Para ter mais informações, consulte Diagnosticar a sobrecarga na tabela e no índice no Guia do usuário do Amazon Aurora.

    SELECT pg_size_pretty(pg_total_relation_size('table_name')) AS total_table_size;

    Esse espaço é recuperado após a conclusão da atividade.

  • Garanta que a instância do RDS tenha capacidade computacional e de E/S suficientes para lidar com a operação de recriação. Pense na possibilidade de aumentar a escala da classe de instância verticalmente para conseguir o equilíbrio ideal de performance.

Como usar a extensão pg_repack
  1. Instale a extensão pg_repack na instância de banco de dados RDS for PostgreSQL executando o comando a seguir.

    CREATE EXTENSION pg_repack;
  2. Execute os comandos a seguir para conceder acesso de gravação para recriar as tabelas de logs temporárias criadas pelo pg_repack.

    ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT INSERT ON TABLES TO PUBLIC; ALTER DEFAULT PRIVILEGES IN SCHEMA repack GRANT USAGE, SELECT ON SEQUENCES TO PUBLIC;
  3. Conecte-se ao banco de dados usando o utilitário de cliente pg_repack. Use uma conta que tenha privilégios rds_superuser. Como exemplo, suponha que a função rds_test tenha os privilégios rds_superuser. A sintaxe a seguir realiza a pg_repack para tabelas completas, incluindo todos os índices da tabela no banco de dados postgres.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test -k postgres
    nota

    É necessário se conectar usando a opção -k. Não há suporte para a opção -a.

    A resposta do cliente pg_repack fornece informações sobre as tabelas recriadas na instância de banco de dados.

    INFO: repacking table "pgbench_tellers" INFO: repacking table "pgbench_accounts" INFO: repacking table "pgbench_branches"
  4. A sintaxe a seguir recria uma única tabela orders incluindo índices no banco de dados postgres.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders -k postgres

    A sintaxe a seguir recria somente os índices da tabela orders no banco de dados postgres.

    pg_repack -h db-instance-name.111122223333.aws-region.rds.amazonaws.com -U rds_test --table orders --only-indexes -k postgres

Monitorar a nova tabela durante a recriação

  • O tamanho do banco de dados é aumentado pelo tamanho total da tabela menos a sobrecarga, até a fase de troca e descarte da recriação. É possível monitorar a taxa de crescimento do tamanho do banco de dados, calcular a velocidade da recriação e estimar aproximadamente o tempo necessário para concluir a transferência inicial dos dados.

    Por exemplo, pense no tamanho total da tabela como 2 TB, o tamanho do banco de dados como 4 TB e a sobrecarga total na tabela como 1 TB. O valor do tamanho total do banco de dados exibido pelo cálculo no final da operação de recriação é o seguinte:

    2TB (Table size) + 4 TB (Database size) - 1TB (Table bloat) = 5TB

    É possível calcular aproximadamente a velocidade da operação de recriação criando uma amostra da taxa de crescimento em bytes entre dois pontos no tempo. Se a taxa de crescimento for de 1 GB por minuto, poderá levar mil minutos ou 16,6 horas aproximadamente para concluir a operação inicial de criação da tabela. Além da criação inicial da tabela, a pg_repack também precisa aplicar as alterações acumuladas. O tempo necessário depende da taxa de aplicação das alterações em andamento, além das alterações acumuladas.

    nota

    É possível usar a extensão pgstattuple para calcular a sobrecarga na tabela. Para ter mais informações, consulte pgstattuple.

  • O número de linhas na tabela de logs pg_repack's, no esquema de recriação, representa o volume de alterações pendentes para serem aplicadas à nova tabela após o carregamento inicial.

    É possível conferir a tabela de logs pg_repack's em pg_stat_all_tables para monitorar as alterações aplicadas à nova tabela. pg_stat_all_tables.n_live_tup indica o número de registros pendentes a serem aplicados à nova tabela. Para ter mais informações, consulte pg_stat_all_tables.

    postgres=>SELECT relname,n_live_tup FROM pg_stat_all_tables WHERE schemaname = 'repack' AND relname ILIKE '%log%'; -[ RECORD 1 ]--------- relname | log_16490 n_live_tup | 2000000
  • É possível usar a extensão pg_stat_statements para descobrir o tempo gasto em cada etapa da operação de recriação. Isso é útil na preparação para aplicar a mesma operação de recriação em um ambiente de produção. É possível ajustar a cláusula LIMIT para estender ainda mais a saída.

    postgres=>SELECT SUBSTR(query, 1, 100) query, round((round(total_exec_time::numeric, 6) / 1000 / 60),4) total_exec_time_in_minutes FROM pg_stat_statements WHERE query ILIKE '%repack%' ORDER BY total_exec_time DESC LIMIT 5; query | total_exec_time_in_minutes -----------------------------------------------------------------------+---------------------------- CREATE UNIQUE INDEX index_16493 ON repack.table_16490 USING btree (a) | 6.8627 INSERT INTO repack.table_16490 SELECT a FROM ONLY public.t1 | 6.4150 SELECT repack.repack_apply($1, $2, $3, $4, $5, $6) | 0.5395 SELECT repack.repack_drop($1, $2) | 0.0004 SELECT repack.repack_swap($1) | 0.0004 (5 rows)

A recriação é uma operação extraordinária, portanto, a tabela original não é afetada e não prevemos nenhum desafio inesperado que exija a recuperação da tabela original. Se a recriação falhar inesperadamente, você deverá inspecionar a causa do erro e resolvê-lo.

Depois que o problema for resolvido, descarte e recrie a extensão pg_repack no banco de dados em que a tabela existe e repita a etapa pg_repack. Além disso, a disponibilidade de recursos computacionais e a acessibilidade simultânea da tabela desempenham um papel crucial na conclusão oportuna da operação de recriação.

Atualizar e usar a extensão PLV8

O PLV8 é uma extensão de linguagem Javascript confiável para o PostgreSQL. Você pode usá-lo para procedimentos armazenados, gatilhos e outros códigos processuais que podem ser chamados do SQL. Essa extensão de idioma é compatível com todas as versões atuais do PostgreSQL.

Se você usar o PLV8 e atualizar o PostgreSQL para uma nova versão do PLV8, você poderá aproveitar imediatamente a nova extensão. Tome as medidas a seguir para sincronizar os metadados do catálogo com a nova versão do PLV8. Estas etapas são opcionais, mas recomendamos fortemente que você as conclua para evitar avisos de incompatibilidade dos metadados.

O processo de atualização elimina todas as suas funções PLV8 existentes. Portanto, recomendamos que você crie um snapshot da sua instância de banco de dados do RDS para PostgreSQL antes de atualizar. Para obter mais informações, consulteCriar um snapshot de banco de dados para uma instância de banco de dados de uma única zona de disponibilidade

Para sincronizar os metadados do catálogo com uma nova versão do PLV8
  1. Verifique se você precisa atualizar. Para fazer isso, execute o comando a seguir enquanto conectado à instância.

    SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');

    Se os resultados contiverem valores para uma versão instalada que seja um número menor que a versão padrão, continue com este procedimento para atualizar suas extensões. Por exemplo, o seguinte conjunto de resultados indica que você deve atualizar.

    name | default_version | installed_version | comment --------+-----------------+-------------------+-------------------------------------------------- plls | 2.1.0 | 1.5.3 | PL/LiveScript (v8) trusted procedural language plcoffee| 2.1.0 | 1.5.3 | PL/CoffeeScript (v8) trusted procedural language plv8 | 2.1.0 | 1.5.3 | PL/JavaScript (v8) trusted procedural language (3 rows)
  2. Crie um snapshot da sua instância de banco de dados do RDS para PostgreSQL se você ainda não tiver feito isso. Você pode continuar com as seguintes etapas enquanto o snapshot estiver sendo criado.

  3. Obtenha uma contagem do número de funções do PLV8 em sua instância de banco de dados para que você possa confirmar se todas estão implementadas depois da atualização. Por exemplo, a consulta SQL a seguir retorna o número de funções gravadas em plv8, plcoffee e plls.

    SELECT proname, nspname, lanname FROM pg_proc p, pg_language l, pg_namespace n WHERE p.prolang = l.oid AND n.oid = p.pronamespace AND lanname IN ('plv8','plcoffee','plls');
  4. Use o pg_dump para criar um arquivo de despejo de somente esquema. Por exemplo, crie um arquivo na máquina do cliente no diretório /tmp.

    ./pg_dump -Fc --schema-only -U master postgres >/tmp/test.dmp

    Esse exemplo usa as seguintes opções:

    • -Fc: formato personalizado

    • --schema-only: fará o despejo apenas dos comandos necessários para criar o esquema (funções em nosso caso)

    • -U: o nome do usuário mestre do RDS

    • database: o nome do banco de dados de nossa instância de banco de dados

    Para obter mais informações sobre pg_dump, consulte pg_dump na documentação do PostgreSQL.

  5. Extraia a declaração DDL "CREATE FUNCTION" que está presente no arquivo de despejo. O exemplo a seguir usa o comando grep para extrair a instrução DDL que cria as funções e as salva em um arquivo. Use isso em etapas subsequentes para recriar as funções.

    ./pg_restore -l /tmp/test.dmp | grep FUNCTION > /tmp/function_list/

    Para obter mais informações sobre pg_restore, consulte pg_restore na documentação do PostgreSQL.

  6. Descarte as funções e as extensões. O exemplo a seguir descarta todos os objetos baseados em PLV8. A opção de cascata garante que qualquer dependente seja descartado.

    DROP EXTENSION plv8 CASCADE;

    Se sua instância do PostgreSQL contiver objetos baseados em plcoffee ou plls, repita essa etapa para essas extensões.

  7. Crie as extensões. O exemplo a seguir cria as extensões plv8, plcoffee e plls.

    CREATE EXTENSION plv8; CREATE EXTENSION plcoffee; CREATE EXTENSION plls;
  8. Crie as funções usando o arquivo de despejo e o arquivo do “driver”.

    O exemplo a seguir recria as funções que você extraiu anteriormente.

    ./pg_restore -U master -d postgres -Fc -L /tmp/function_list /tmp/test.dmp
  9. Verifique se todas as suas funções foram recriadas usando a seguinte consulta.

    SELECT * FROM pg_available_extensions WHERE name IN ('plv8','plls','plcoffee');

    A versão 2 do PLV8 adiciona a seguinte linha extra ao conjunto de resultados:

    proname | nspname | lanname ---------------+------------+---------- plv8_version | pg_catalog | plv8

Usar PL/Rust para escrever funções do PostgreSQL na linguagem Rust

O PL/Rust é uma extensão de linguagem Rust confiável para o PostgreSQL. Você pode usá-lo para procedimentos armazenados, funções e outros códigos processuais que podem ser chamados do SQL. A extensão de linguagem PL/Rust está disponível nas seguintes versões:

  • RDS para PostgreSQL 16.1 e versões 16 posteriores

  • RDS para PostgreSQL 15.2-R2 e versões 15 posteriores

  • RDS para PostgreSQL 14.9 e versões 14 posteriores

  • RDS para PostgreSQL 13.12 e versões 13 posteriores

Para obter mais informações, consulte PL/Rust no GitHub.

Configurar o PL/Rust

Para instalar a extensão plrust da instância de banco de dados, adicione o plrust ao parâmetro shared_preload_libraries no grupo de parâmetros de banco de dados associado à instância de banco de dados. Com a extensão plrust instalada, é possível criar funções.

Para modificar o parâmetro shared_preload_libraries, a instância de banco de dados deve estar associada a um grupo de parâmetros personalizado. Para obter mais informações sobre como criar um grupo de parâmetros de banco de dados personalizado, consulte Grupos de parâmetros para Amazon RDS.

É possível instalar a extensão plrust usando o AWS Management Console ou a AWS CLI.

As etapas a seguir pressupõem que a instância de banco de dados esteja associada a um grupo de parâmetros de banco de dados personalizado.

Instalar a extensão plrust no parâmetro shared_preload_libraries

Conclua as etapas a seguir usando uma conta que seja membro do grupo (perfil) rds_superuser.

  1. Faça login no AWS Management Console e abra o console do Amazon RDS em https://console.aws.amazon.com/rds/.

  2. No painel de navegação, escolha Bancos de dados.

  3. Escolha o nome da instância de banco de dados para mostrar os detalhes.

  4. Abra a guia Configuração da instância de banco de dados e encontre o link do grupo de parâmetros da instância de banco de dados.

  5. Clique no link para abrir os parâmetros personalizados associados à instância de banco.

  6. No campo Parameters (Parâmetros), digite shared_pre para encontrar o parâmetro shared_preload_libraries.

  7. Selecione Edit parameters (Editar parâmetros) para acessar os valores das propriedades.

  8. Adicione plrust à lista no campo Valores. Use uma vírgula para separar itens na lista de valores.

  9. Reinicialize a instância de banco de dados para que a alteração no parâmetro shared_preload_libraries tenha efeito. A reinicialização inicial pode exigir mais tempo para ser concluída.

  10. Quando a instância estiver disponível, verifique se plrust foi inicializado. Use psql para se conectar à instância de banco de dados e execute o comando a seguir.

    SHOW shared_preload_libraries;

    Sua saída deve ser semelhante à seguinte:

    shared_preload_libraries -------------------------- rdsutils,plrust (1 row)
Instalar a extensão plrust no parâmetro shared_preload_libraries

Conclua as etapas a seguir usando uma conta que seja membro do grupo (perfil) rds_superuser.

  1. Utilize o comando modify-db-parameter-group da AWS CLI para adicionar plrust ao parâmetro shared_preload_libraries.

    aws rds modify-db-parameter-group \ --db-parameter-group-name custom-param-group-name \ --parameters "ParameterName=shared_preload_libraries,ParameterValue=plrust,ApplyMethod=pending-reboot" \ --region aws-region
  2. Use o comando reboot-db-instance da AWS CLI para reinicializar a instância de banco de dados e inicializar a biblioteca plrust. A reinicialização inicial pode exigir mais tempo para ser concluída.

    aws rds reboot-db-instance \ --db-instance-identifier your-instance \ --region aws-region
  3. Quando a instância estiver disponível, é possível verificar se plrust foi inicializado. Use psql para se conectar à instância de banco de dados e execute o comando a seguir.

    SHOW shared_preload_libraries;

    Sua saída deve ser semelhante à seguinte:

    shared_preload_libraries -------------------------- rdsutils,plrust (1 row)

Criar funções com o PL/Rust

O PL/Rust compilará a função como uma biblioteca dinâmica, a carregará e a executará.

A função do Rust a seguir filtra múltiplos de uma matriz.

postgres=> CREATE LANGUAGE plrust; CREATE EXTENSION
CREATE OR REPLACE FUNCTION filter_multiples(a BIGINT[], multiple BIGINT) RETURNS BIGINT[] IMMUTABLE STRICT LANGUAGE PLRUST AS $$ Ok(Some(a.into_iter().filter(|x| x.unwrap() % multiple != 0).collect())) $$; WITH gen_values AS ( SELECT ARRAY(SELECT * FROM generate_series(1,100)) as arr) SELECT filter_multiples(arr, 3) from gen_values;

Usar caixas com PL/Rust

No RDS para PostgreSQL versões 16.3-R2 e posterior, 15.7-R2 e versões 15 posteriores, 14.12-R2 e versões 14 posteriores e 13.15-R2 e versões 13 posteriores, o PL/Rust é compatível com caixas adicionais:

  • url

  • regex

  • serde

  • serde_json

No RDS para PostgreSQL versões 15.5-R2 e posterior, 14.10-R2 e versões 14 posteriores e 13.13-R2 e versões 13 posteriores, o PL/Rust é compatível com duas caixas adicionais:

  • croaring-rs

  • num-bigint

A partir das versões 15.4, 14.9 e 13.12 do Amazon RDS para PostgreSQL, o PL/Rust comporta as seguintes caixas:

  • aes

  • ctr

  • rand

Somente os recursos padrão são comportados para essas caixas. As novas versões do RDS para PostgreSQL poderão conter versões de caixa atualizadas, ao passo que as mais antigas podem deixar de ter suporte.

Siga as práticas recomendadas para realizar uma atualização de versão principal e testar se suas funções do PL/Rust são compatíveis com a nova versão principal. Para obter mais informações, consulte a publicação de blog Práticas recomendadas para atualizar o Amazon RDS para versões principais e secundárias do PostgreSQL e Atualizar o mecanismo de banco de dados PostgreSQL para Amazon RDS no “Guia do usuário do Amazon RDS”.

Exemplos de uso de dependências ao criar uma função PL/Rust estão disponíveis em Usar dependências.

Limitações do PL/Rust

Por padrão, os usuários do banco de dados não podem usar PL/Rust. Para fornecer acesso ao PL/Rust, conecte-se como usuário com o privilégio rds_superuser e execute o seguinte comando:

postgres=> GRANT USAGE ON LANGUAGE PLRUST TO user;