Limitações de DDL e outras informações do Aurora PostgreSQL Limitless Database - Amazon Aurora

Limitações de DDL e outras informações do Aurora PostgreSQL Limitless Database

Os tópicos a seguir descrevem as limitações ou fornecem mais informações sobre os comandos SQL para DDL no Aurora PostgreSQL Limitless Database.

ALTER TABLE

O comando ALTER TABLE geralmente é compatível com o Aurora PostgreSQL Limitless Database. Consulte ALTER TABLE na documentação do PostgreSQL para obter mais informações.

Limitações

ALTER TABLE tem as limitações a seguir para as opções compatíveis.

Remover uma coluna
  • Em tabelas fragmentadas, não é possível remover colunas que fazem parte da chave de fragmento.

  • Em tabelas de referência, não é possível remover colunas de chave primária.

Alterar um tipo de dado da coluna
  • A expressão USING não é compatível.

  • Em tabelas fragmentadas, não é possível alterar o tipo das colunas que fazem parte da chave de fragmento.

Adicionar ou remover uma restrição

Consulte Restrições para obter detalhes sobre o que não é compatível.

Alterar o valor padrão de uma coluna

Há suporte para valores padrão. Para ter mais informações, consulte Valores padrão.

Opções não compatíveis

Algumas opções não são compatíveis porque elas dependem de recursos incompatíveis, como gatilhos.

As seguintes opções no nível de tabela para ALTER TABLE não são compatíveis:

  • ALL IN TABLESPACE

  • ATTACH PARTITION

  • DETACH PARTITION

  • sinalizador ONLY

  • RENAME CONSTRAINT

As seguintes opções no nível de coluna para ALTER TABLE não são compatíveis:

  • ADD GENERATED

  • DROP EXPRESSION [ IF EXISTS ]

  • DROP IDENTITY [ IF EXISTS ]

  • RESET

  • RESTART

  • SET

  • SET COMPRESSION

  • SET STATISTICS

CREATE DATABASE

No Aurora PostgreSQL Limitless Database, somente bancos de dados ilimitados são compatíveis.

Enquanto CREATE DATABASE estiver em execução, os bancos de dados que foram criados com sucesso em um ou mais nós podem falhar em outros nós, visto que a criação do banco de dados é uma operação não transacional. Nesse caso, os objetos do banco de dados que foram criados com sucesso são automaticamente removidos de todos os nós em um período predeterminado para manter a consistência no grupo de fragmentos do banco de dados. Durante esse período, a recriação de um banco de dados com o mesmo nome pode resultar em um erro indicando que o banco de dados já existe.

Há compatibilidade com as seguintes opções:

  • Agrupamento:

    CREATE DATABASE name WITH [LOCALE = locale] [LC_COLLATE = lc_collate] [LC_CTYPE = lc_ctype] [ICU_LOCALE = icu_locale] [ICU_RULES = icu_rules] [LOCALE_PROVIDER = locale_provider] [COLLATION_VERSION = collation_version];
  • CREATE DATABASE WITH OWNER:

    CREATE DATABASE name WITH OWNER = user_name;

As seguintes opções não são compatíveis:

  • CREATE DATABASE WITH TABLESPACE:

    CREATE DATABASE name WITH TABLESPACE = tablespace_name;
  • CREATE DATABASE WITH TEMPLATE:

    CREATE DATABASE name WITH TEMPLATE = template;

CREATE INDEX

CREATE INDEX CONCURRENTLY é compatível com tabelas fragmentadas:

CREATE INDEX CONCURRENTLY index_name ON table_name(column_name);

CREATE UNIQUE INDEX é compatível com todos os tipos de tabela:

CREATE UNIQUE INDEX index_name ON table_name(column_name);

CREATE UNIQUE INDEX CONCURRENTLY não é compatível:

CREATE UNIQUE INDEX CONCURRENTLY index_name ON table_name(column_name);

Para obter mais informações, consulte UNIQUE. Para obter informações gerais sobre a criação de índices, consulte CREATE INDEX na documentação do PostgreSQL.

Exibir índices

Nem todos os índices são visíveis nos roteadores ao usar \d table_name ou comandos semelhantes. Em vez disso, use a exibição pg_catalog.pg_indexes para obter índices, conforme mostrado no exemplo a seguir.

SET rds_aurora.limitless_create_table_mode='sharded'; SET rds_aurora.limitless_create_table_shard_key='{"id"}'; CREATE TABLE items (id int PRIMARY KEY, val int); CREATE INDEX items_my_index on items (id, val); postgres_limitless=> SELECT * FROM pg_catalog.pg_indexes WHERE tablename='items'; schemaname | tablename | indexname | tablespace | indexdef ------------+-----------+----------------+------------+------------------------------------------------------------------------ public | items | items_my_index | | CREATE INDEX items_my_index ON ONLY public.items USING btree (id, val) public | items | items_pkey | | CREATE UNIQUE INDEX items_pkey ON ONLY public.items USING btree (id) (2 rows)

CREATE SCHEMA

Não há suporte para CREATE SCHEMA com um elemento de esquema:

CREATE SCHEMA my_schema CREATE TABLE (column_name INT);

Isso gera um erro semelhante ao seguinte:

ERROR: CREATE SCHEMA with schema elements is not supported

CRIAR TABELA

Não há suporte para relações em declarações CREATE TABLE, por exemplo:

CREATE TABLE orders (orderid int, customerId int, orderDate date) WITH (autovacuum_enabled = false);

Não há suporte para colunas IDENTITY, por exemplo:

CREATE TABLE orders (orderid INT GENERATED ALWAYS AS IDENTITY);

CREATE TABLE AS

Para criar uma tabela usando CREATE TABLE AS, use a variável rds_aurora.limitless_create_table_mode. Para tabelas fragmentadas, você também deve usar a variável rds_aurora.limitless_create_table_shard_key. Para ter mais informações, consulte Criação de tabelas ilimitadas usando variáveis.

-- Set the variables. SET rds_aurora.limitless_create_table_mode='sharded'; SET rds_aurora.limitless_create_table_shard_key='{"a"}'; CREATE TABLE ctas_table AS SELECT 1 a; -- "source" is the source table whose columns and data types are used to create the new "ctas_table2" table. CREATE TABLE ctas_table2 AS SELECT a,b FROM source;

Não é possível usar CREATE TABLE AS para criar tabelas de referência porque elas exigem restrições de chave primária. CREATE TABLE AS não propaga chaves primárias para novas tabelas.

Para obter informações gerais, consulte CREATE TABLE AS na documentação do PostgreSQL.

DROP DATABASE

É possível descartar bancos de dados que você criou.

O comando DROP DATABASE é executado de forma assíncrona em segundo plano. Enquanto estiver em execução, um erro será retornado se você tentar criar um banco de dados com o mesmo nome.

SELECT INTO

SELECT INTO é funcionalmente semelhante a CREATE TABLE AS. Você deve usar a variável rds_aurora.limitless_create_table_mode. Para tabelas fragmentadas, você também deve usar a variável rds_aurora.limitless_create_table_shard_key. Para ter mais informações, consulte Criação de tabelas ilimitadas usando variáveis.

-- Set the variables. SET rds_aurora.limitless_create_table_mode='sharded'; SET rds_aurora.limitless_create_table_shard_key='{"a"}'; -- "source" is the source table whose columns and data types are used to create the new "destination" table. SELECT * INTO destination FROM source;

Atualmente, a operação SELECT INTO é realizada por meio do roteador, não diretamente pelos fragmentos. Portanto, o desempenho pode ser lento.

Para obter informações gerais, consulte SELECT INTO na documentação do PostgreSQL.

Restrições

As limitações a seguir se aplicam às restrições no Aurora PostgreSQL Limitless Database.

CHECK

Há suporte para restrições simples que envolvem operadores de comparação com literais. Não há suporte para expressões e restrições mais complexas que exigem validações de funções, conforme mostrado nos exemplos a seguir.

CREATE TABLE my_table ( id INT CHECK (id > 0) -- supported , val INT CHECK (val > 0 AND val < 1000) -- supported , tag TEXT CHECK (length(tag) > 0) -- not supported: throws "Expression inside CHECK constraint is not supported" , op_date TIMESTAMP WITH TIME ZONE CHECK (op_date <= now()) -- not supported: throws "Expression inside CHECK constraint is not supported" );

Você pode dar nomes explícitos às restrições, conforme mostrado no exemplo a seguir.

CREATE TABLE my_table ( id INT CONSTRAINT positive_id CHECK (id > 0) , val INT CONSTRAINT val_in_range CHECK (val > 0 AND val < 1000) );

É possível utilizar a sintaxe de restrição em nível de tabela com a restrição CHECK, conforme mostrado no exemplo a seguir.

CREATE TABLE my_table ( id INT CONSTRAINT positive_id CHECK (id > 0) , min_val INT CONSTRAINT min_val_in_range CHECK (min_val > 0 AND min_val < 1000) , max_val INT , CONSTRAINT max_val_in_range CHECK (max_val > 0 AND max_val < 1000 AND max_val > min_val) );
EXCLUDE

Não há suporte para restrições de exclusão no Aurora PostgreSQL Limitless Database.

FOREIGN KEY

Para ter mais informações, consulte Chaves externas.

NOT NULL

Há suporte para restrições NOT NULL sem limitações.

PRIMARY KEY

A chave primária implica restrições únicas e, portanto, as mesmas restrições aplicadas às restrições únicas se aplicam à chave primária. Isso significa que:

  • Se uma tabela for convertida em uma tabela fragmentada, a chave de fragmento deve ser um subconjunto da chave primária. Ou seja, a chave primária contém todas as colunas da chave de fragmento.

  • Se uma tabela for convertida em uma tabela de referência, ela deverá ter uma chave primária.

Os exemplos a seguir ilustram o uso de chaves primárias.

-- Create a standard table. CREATE TABLE public.my_table ( item_id INT , location_code INT , val INT , comment text ); -- Change the table to a sharded table using the 'item_id' and 'location_code' columns as shard keys. CALL rds_aurora.limitless_alter_table_type_sharded('public.my_table', ARRAY['item_id', 'location_code']);

Tentando adicionar uma chave primária que não contém uma chave de fragmento:

-- Add column 'item_id' as the primary key. -- Invalid because the primary key doesnt include all columns from the shard key: -- 'location_code' is part of the shard key but not part of the primary key ALTER TABLE public.my_table ADD PRIMARY KEY (item_id); -- ERROR -- add column "val" as primary key -- Invalid because primary key does not include all columns from shard key: -- item_id and location_code iare part of shard key but not part of the primary key ALTER TABLE public.my_table ADD PRIMARY KEY (item_id); -- ERROR

Tentando adicionar uma chave primária que contém uma chave de fragmento:

-- Add the 'item_id' and 'location_code' columns as the primary key. -- Valid because the primary key contains the shard key. ALTER TABLE public.my_table ADD PRIMARY KEY (item_id, location_code); -- OK -- Add the 'item_id', 'location_code', and 'val' columns as the primary key. -- Valid because the primary key contains the shard key. ALTER TABLE public.my_table ADD PRIMARY KEY (item_id, location_code, val); -- OK

Alterar uma tabela padrão para uma tabela de referência.

-- Create a standard table. CREATE TABLE zipcodes (zipcode INT PRIMARY KEY, details VARCHAR); -- Convert the table to a reference table. CALL rds_aurora.limitless_alter_table_type_reference('public.zipcode');

Consulte Criação de tabelas do Aurora PostgreSQL Limitless Database para obter mais informações sobre a criação de tabelas fragmentadas e de referência.

UNIQUE

Em tabelas fragmentadas, a chave única deve conter a chave de fragmento. Ou seja, a chave de fragmento deve ser um subconjunto da chave única. Isso é verificado ao alterar o tipo de tabela para fragmentada. Não há restrição nas tabelas de referência.

CREATE TABLE customer ( customer_id INT NOT NULL , zipcode INT , email TEXT UNIQUE );

Há suporte para restrições em nível de tabela UNIQUE, conforme mostrado no exemplo a seguir.

CREATE TABLE customer ( customer_id INT NOT NULL , zipcode INT , email TEXT , CONSTRAINT zipcode_and_email UNIQUE (zipcode, email) );

O exemplo a seguir mostra o uso de uma chave primária e uma chave única juntas. Ambas as chaves devem incluir a chave de fragmento.

SET rds_aurora.limitless_create_table_mode='sharded'; SET rds_aurora.limitless_create_table_shard_key='{"p_id"}'; CREATE TABLE t1 ( p_id BIGINT NOT NULL, c_id BIGINT NOT NULL, PRIMARY KEY (p_id), UNIQUE (p_id, c_id) );

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

Valores padrão

O Aurora PostgreSQL Limitless Database oferece suporte a expressões em valores padrão.

O exemplo a seguir mostra o uso de valores padrão.

CREATE TABLE t ( a INT DEFAULT 5, b TEXT DEFAULT 'NAN', c NUMERIC ); CALL rds_aurora.limitless_alter_table_type_sharded('t', ARRAY['a']); INSERT INTO t DEFAULT VALUES; SELECT * FROM t; a | b | c ---+-----+--- 5 | NAN | (1 row)

Há suporte para expressões, conforme mostrado no exemplo a seguir.

CREATE TABLE t1 (a NUMERIC DEFAULT random());

O exemplo a seguir adiciona uma nova coluna que é NOT NULL e tem um valor padrão.

ALTER TABLE t ADD COLUMN d BOOLEAN NOT NULL DEFAULT FALSE; SELECT * FROM t; a | b | c | d ---+-----+---+--- 5 | NAN | | f (1 row)

O exemplo a seguir altera uma coluna existente com um valor padrão.

ALTER TABLE t ALTER COLUMN c SET DEFAULT 0.0; INSERT INTO t DEFAULT VALUES; SELECT * FROM t; a | b | c | d ---+-----+-----+----- 5 | NAN | | f 5 | NAN | 0.0 | f (2 rows)

O exemplo a seguir descarta um valor padrão.

ALTER TABLE t ALTER COLUMN a DROP DEFAULT; INSERT INTO t DEFAULT VALUES; SELECT * FROM t; a | b | c | d ---+-----+-----+----- 5 | NAN | | f 5 | NAN | 0.0 | f | NAN | 0.0 | f (3 rows)

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

Extensões

Há suporte para as seguintes extensões do PostgreSQL no Aurora PostgreSQL Limitless Database:

Atualmente, a maioria das extensões do PostgreSQL não é compatível com o Aurora PostgreSQL Limitless Database. No entanto, ainda é possível usar a configuração shared_preload_librarie (SPL) para carregar extensões no cluster de banco de dados primário do Aurora PostgreSQL. Elas também são carregadas no Aurora PostgreSQL Limitless Database, mas podem não funcionar corretamente.

Por exemplo, você pode carregar a extensão pg_hint_plan, mas carregá-la não garante que as dicas passadas nos comentários da consulta sejam usadas.

nota

Não é possível modificar objetos associados à extensão pg_stat_statements. Para obter informações sobre a instalação de pg_stat_statements, consulte limitless_stat_statements.

Você pode usar as funções pg_available_extensions e pg_available_extension_versions para encontrar extensões compatíveis com o Aurora PostgreSQL Limitless Database.

As seguintes DDLs são compatíveis com extensões:

CRIAR EXTENSÃO

É possível criar extensões, como no PostgreSQL.

CREATE EXTENSION [ IF NOT EXISTS ] extension_name [ WITH ] [ SCHEMA schema_name ] [ VERSION version ] [ CASCADE ]

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

ALTERAR EXTENSÃO

As seguintes DDLs são compatíveis:

ALTER EXTENSION name UPDATE [ TO new_version ] ALTER EXTENSION name SET SCHEMA new_schema

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

EXTENSÃO DROP

É possível descartar extensões, como no PostgreSQL.

DROP EXTENSION [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]

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

As seguintes DDLs não são compatíveis com extensões:

ALTERAR EXTENSÃO

Não é possível adicionar ou descartar objetos membros das extensões.

ALTER EXTENSION name ADD member_object ALTER EXTENSION name DROP member_object

Diferenças do pg_buffercache no Aurora PostgreSQL Limitless Database

No Aurora PostgreSQL Limitless Database, ao instalar a extensão pg_buffercache e usar a visualização pg_buffercache, você recebe informações relacionadas ao buffer somente do nó ao qual está conectado atualmente: o roteador. Da mesma forma, o uso da função pg_buffercache_summary ou pg_buffercache_usage_counts fornece informações somente do nó conectado.

É possível ter vários nós. Talvez seja preciso acessar as informações do buffer de qualquer nó para diagnosticar problemas de forma eficaz. Portanto, o Limitless Database fornece as seguintes funções:

  • rds_aurora.limitless_pg_buffercache(subcluster_id)

  • rds_aurora.limitless_pg_buffercache_summary(subcluster_id)

  • rds_aurora.limitless_pg_buffercache_usage_counts(subcluster_id)

Ao inserir o ID do subcluster de qualquer nó, seja um roteador ou um fragmento, é possível acessar facilmente as informações do buffer específicas desse nó. Essas funções estão diretamente disponíveis ao instalar a extensão pg_buffercache no Limitless Database.

nota

O Aurora PostgreSQL Limitless Database oferece suporte a essas funções na versão 1.4 e superiores da extensão pg_buffercache.

As colunas mostradas na exibição limitless_pg_buffercache diferem um pouco das da exibição pg_buffercache:

  • bufferid: permanece inalterado em relação a pg_buffercache.

  • relname: em vez de exibir o número do nó do arquivo como em pg_buffercache, o limitless_pg_buffercache apresenta o relname associado, se disponível no banco de dados atual ou nos catálogos do sistema compartilhado. Caso contrário, exibe NULL.

  • parent_relname: essa nova coluna, não presente em pg_buffercache, exibe o relname pai se o valor na coluna relname representar uma tabela particionada (no caso de tabelas fragmentadas). Caso contrário, exibe NULL.

  • spcname: em vez de exibir o identificador de objeto (OID) do espaço de tabela como em pg_buffercache, limitless_pg_buffercache exibe o nome do espaço de tabela.

  • datname: em vez de exibir o OID do banco de dados como em pg_buffercache, limitless_pg_buffercache exibe o nome do banco de dados.

  • relforknumber: permanece inalterado em relação a pg_buffercache.

  • relblocknumber: permanece inalterado em relação a pg_buffercache.

  • isdirty: permanece inalterado em relação a pg_buffercache.

  • usagecount: permanece inalterado em relação a pg_buffercache.

  • pinning_backends: permanece inalterado em relação a pg_buffercache.

As colunas nas exibições limitless_pg_buffercache_summary e limitless_pg_buffercache_usage_counts são as mesmas que nas exibições regulares pg_buffercache_summary e pg_buffercache_usage_counts, respectivamente.

Ao usar essas funções, é possível acessar informações detalhadas do cache de buffer em todos os nós no ambiente do Limitless Database, o que facilita o diagnóstico e o gerenciamento mais eficazes dos sistemas de banco de dados.

Diferenças do pgstattuple no Aurora PostgreSQL Limitless Database

No Aurora PostgreSQL, a extensão pgstattuple atualmente não é compatível com tabelas externas, tabelas particionadas ou índices particionados. No entanto, no Aurora PostgreSQL Limitless Database, objetos criados pelo usuário geralmente estão entre esses tipos que não têm suporte. Embora existam tabelas e índices regulares (por exemplo, tabelas de catálogo e seus índices), a maioria dos objetos reside em nós externos, o que o roteador considera como objetos externos.

Reconhecemos a importância dessa extensão para obter estatísticas no nível da tupla, o que é crucial para tarefas como remoção de sobrecarga e coleta de informações de diagnóstico. Portanto, o Aurora PostgreSQL Limitless Database fornece suporte para a extensão pgstattuple em bancos de dados ilimitados.

O Aurora PostgreSQL Limitless Database inclui as seguintes funções no esquema rds_aurora:

Funções estatísticas no nível da tupla

rds_aurora.limitless_pgstattuple(relation_name)

  • Objetivo: extrair estatísticas no nível da tupla para tabelas padrão e seus índices

  • Entrada: relation_name (texto) — o nome da relação

  • Saída: colunas consistentes com as retornadas pela função pgstattuple no Aurora PostgreSQL

rds_aurora.limitless_pgstattuple(relation_name, subcluster_id)

  • Objetivo: extrair estatísticas no nível da tupla para tabelas de referência, tabelas fragmentadas, tabelas de catálogo e seus índices

  • Entrada:

    • relation_name (texto) — o nome da relação

    • subcluster_id (texto) — o ID do subcluster do nó de onde as estatísticas devem ser extraídas

  • Saída:

    • Em tabelas de referência e de catálogo (incluindo seus índices), as colunas são consistentes com as do Aurora PostgreSQL.

    • Em tabelas fragmentadas, as estatísticas representam somente a partição da tabela fragmentada que reside no subcluster especificado.

Funções das estatísticas de índice

rds_aurora.limitless_pgstatindex(relation_name)

  • Objetivo: extrair estatísticas para índices de árvore B em tabelas padrão

  • Entrada: relation_name (texto) — o nome do índice de árvore B

  • Saída: todas as colunas, exceto root_block_no, são retornadas. As colunas retornadas são consistentes com a função pgstatindex no Aurora PostgreSQL.

rds_aurora.limitless_pgstatindex(relation_name, subcluster_id)

  • Objetivo: extrair estatísticas para índices de árvore B em tabelas de referência, tabelas fragmentadas e tabelas de catálogo.

  • Entrada:

    • relation_name (texto) — o nome do índice de árvore B

    • subcluster_id (texto) — o ID do subcluster do nó de onde as estatísticas devem ser extraídas

  • Saída:

    • Em índices de tabelas de referência e catálogo, todas as colunas (exceto root_block_no) são retornadas. As colunas retornadas são consistentes com o Aurora PostgreSQL.

    • Em tabelas fragmentadas, as estatísticas representam somente a partição do índice da tabela fragmentada que reside no subcluster especificado. A coluna tree_level mostra a média de todas as partes da tabela no subcluster solicitado.

rds_aurora.limitless_pgstatginindex(relation_name)

  • Objetivo: extrair estatísticas para Índices invertidos generalizados (GINs) em tabelas padrão

  • Entrada: relation_name (texto) — o nome do GIN

  • Saída: colunas consistentes com as retornadas pela função pgstatginindex no Aurora PostgreSQL

rds_aurora.limitless_pgstatginindex(relation_name, subcluster_id)

  • Objetivo: extrair estatísticas para GINs em tabelas de referência, tabelas fragmentadas e tabelas de catálogo.

  • Entrada:

    • relation_name (texto) — o nome do índice

    • subcluster_id (texto) — o ID do subcluster do nó de onde as estatísticas devem ser extraídas

  • Saída:

    • Nos GINs das tabelas de referência e de catálogo, as colunas são consistentes com as do Aurora PostgreSQL.

    • Em tabelas fragmentadas, as estatísticas representam somente a partição do índice da tabela fragmentada que reside no subcluster especificado.

rds_aurora.limitless_pgstathashindex(relation_name)

  • Objetivo: extrair estatísticas para índices de hash em tabelas padrão

  • Entrada: relation_name (texto) — o nome do índice de hash

  • Saída: colunas consistentes com as retornadas pela função pgstathashindex no Aurora PostgreSQL

rds_aurora.limitless_pgstathashindex(relation_name, subcluster_id)

  • Objetivo: extrair estatísticas para índices de hash em tabelas de referência, tabelas fragmentadas e tabelas de catálogo.

  • Entrada:

    • relation_name (texto) — o nome do índice

    • subcluster_id (texto) — o ID do subcluster do nó de onde as estatísticas devem ser extraídas

  • Saída:

    • Para índices de hash em tabelas de referência e catálogo, as colunas são consistentes com as do Aurora PostgreSQL.

    • Em tabelas fragmentadas, as estatísticas representam somente a partição do índice da tabela fragmentada que reside no subcluster especificado.

Funções de contagem de páginas

rds_aurora.limitless_pg_relpages(relation_name)

  • Objetivo: extrair a contagem de páginas em tabelas padrão e seus índices

  • Entrada: relation_name (texto) — o nome da relação

  • Saída: contagem de páginas da relação especificada

rds_aurora.limitless_pg_relpages(relation_name, subcluster_id)

  • Objetivo: extrair a contagem de páginas das tabelas de referência, tabelas fragmentadas e tabelas de catálogo (incluindo seus índices)

  • Entrada:

    • relation_name (texto) — o nome da relação

    • subcluster_id (texto) — o ID do subcluster do nó de onde a contagem de páginas deve ser extraída

  • Saída: em tabelas fragmentadas, a contagem de páginas é a soma das páginas em todas as partes da tabela no subcluster especificado.

Funções estatísticas aproximadas no nível da tupla

rds_aurora.limitless_pgstattuple_approx(relation_name)

  • Objetivo: extrair estatísticas aproximadas no nível da tupla para tabelas padrão e seus índices

  • Entrada: relation_name (texto) — o nome da relação

  • Saída: colunas consistentes com as retornadas pela função pgstattuple_approx no Aurora PostgreSQL

rds_aurora.limitless_pgstattuple_approx(relation_name, subcluster_id)

  • Objetivo: extrair estatísticas aproximadas no nível da tupla em tabelas de referência, tabelas fragmentadas e tabelas de catálogo (incluindo seus índices)

  • Entrada:

    • relation_name (texto) — o nome da relação

    • subcluster_id (texto) — o ID do subcluster do nó de onde as estatísticas devem ser extraídas

  • Saída:

    • Em tabelas de referência e de catálogo (incluindo seus índices), as colunas são consistentes com as do Aurora PostgreSQL.

    • Em tabelas fragmentadas, as estatísticas representam somente a partição da tabela fragmentada que reside no subcluster especificado.

nota

Atualmente, o Aurora PostgreSQL Limitless Database não oferece suporte à extensão pgstattuple em visões materializadas, tabelas TOAST ou tabelas temporárias.

No Aurora PostgreSQL Limitless Database, você deve fornecer a entrada como texto. O Aurora PostgreSQL oferece suporte a outros formatos.

Chaves externas

Há suporte para restrições de chave externa (FOREIGN KEY) com algumas limitações:

  • Há suporte para CREATE TABLE com FOREIGN KEY somente para tabelas padrão. Para criar uma tabela fragmentada ou de referência com FOREIGN KEY, primeiro crie a tabela sem uma restrição de chave externa. Em seguida, modifique-a usando a seguinte instrução:

    ALTER TABLE ADD CONSTRAINT;
  • Não há suporte para a conversão de uma tabela padrão em uma tabela fragmentada ou de referência quando a tabela tem uma restrição de chave externa. Descarte a restrição e adicione-a após a conversão.

  • As seguintes limitações se aplicam aos tipos de tabela para restrições de chave externa:

    • Uma tabela padrão pode ter uma restrição de chave externa para outra tabela padrão.

    • Uma tabela fragmentada pode ter uma restrição de chave externa se as tabelas pai e filha tiverem localização compartilhada e a chave externa for um superconjunto da chave de fragmento.

    • Uma tabela fragmentada pode ter uma restrição de chave externa para uma tabela de referência.

    • Uma tabela de referência pode ter uma restrição de chave externa para outra tabela de referência.

Opções de chave externa

Há suporte para chaves externas no Aurora PostgreSQL Limitless Database para algumas opções de DDL. A tabela a seguir lista as opções com suporte e sem suporte entre as tabelas do Aurora PostgreSQL Limitless Database.

Opção de DDL Referência para referência Fragmentada para fragmentada (colocalizado) Fragmentada para referência Padrão para padrão

DEFERRABLE

Sim Sim Sim Sim

INITIALLY DEFERRED

Sim Sim Sim Sim

INITIALLY IMMEDIATE

Sim Sim Sim Sim

MATCH FULL

Sim Sim Sim Sim

MATCH PARTIAL

Não Não Não Não

MATCH SIMPLE

Sim Sim Sim Sim

NOT DEFERRABLE

Sim Sim Sim Sim

NOT VALID

Sim Não Não Sim

ON DELETE CASCADE

Sim Sim Sim Sim

ON DELETE NO ACTION

Sim Sim Sim Sim

ON DELETE RESTRICT

Sim Sim Sim Sim

ON DELETE SET DEFAULT

Não Não Não Não

ON DELETE SET NULL

Sim Não Não Sim

ON UPDATE CASCADE

Não Não Não Sim

ON UPDATE NO ACTION

Sim Sim Sim Sim

ON UPDATE RESTRICT

Sim Sim Sim Sim

ON UPDATE SET DEFAULT

Não Não Não Não

ON UPDATE SET NULL

Sim Não Não Sim

Exemplos

  • Padrão para padrão:

    set rds_aurora.limitless_create_table_mode='standard'; CREATE TABLE products( product_no integer PRIMARY KEY, name text, price numeric ); CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer REFERENCES products (product_no), quantity integer ); SELECT constraint_name, table_name, constraint_type FROM information_schema.table_constraints WHERE constraint_type='FOREIGN KEY'; constraint_name | table_name | constraint_type -------------------------+-------------+----------------- orders_product_no_fkey | orders | FOREIGN KEY (1 row)
  • Fragmentada para fragmentada (colocalizado):

    set rds_aurora.limitless_create_table_mode='sharded'; set rds_aurora.limitless_create_table_shard_key='{"product_no"}'; CREATE TABLE products( product_no integer PRIMARY KEY, name text, price numeric ); set rds_aurora.limitless_create_table_shard_key='{"order_id"}'; set rds_aurora.limitless_create_table_collocate_with='products'; CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer, quantity integer ); ALTER TABLE orders ADD CONSTRAINT order_product_fk FOREIGN KEY (product_no) REFERENCES products (product_no);
  • Fragmentada para referência:

    set rds_aurora.limitless_create_table_mode='reference'; CREATE TABLE products( product_no integer PRIMARY KEY, name text, price numeric ); set rds_aurora.limitless_create_table_mode='sharded'; set rds_aurora.limitless_create_table_shard_key='{"order_id"}'; CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer, quantity integer ); ALTER TABLE orders ADD CONSTRAINT order_product_fk FOREIGN KEY (product_no) REFERENCES products (product_no);
  • Referência para referência:

    set rds_aurora.limitless_create_table_mode='reference'; CREATE TABLE products( product_no integer PRIMARY KEY, name text, price numeric ); CREATE TABLE orders ( order_id integer PRIMARY KEY, product_no integer, quantity integer ); ALTER TABLE orders ADD CONSTRAINT order_product_fk FOREIGN KEY (product_no) REFERENCES products (product_no);

Funções

As funções são compatíveis no Aurora PostgreSQL Limitless Database.

As seguintes DDLs são compatíveis com funções:

CREATE FUNCTION

Assim como no Aurora PostgreSQL, é possível criar funções, com exceção de alterar sua volatilidade ao substituí-las.

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

ALTER FUNCTION

Assim como no Aurora PostgreSQL, é possível alterar funções, com exceção de alterar sua volatilidade.

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

DROP FUNCTION

Assim como no Aurora PostgreSQL, é possível descartar funções.

DROP FUNCTION [ IF EXISTS ] name [ ( [ [ argmode ] [ argname ] argtype [, ...] ] ) ] [, ...] [ CASCADE | RESTRICT ]

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

Distribuição de funções

Quando todas as instruções de uma função são direcionadas a um único fragmento, é vantajoso enviar a função inteira para o fragmento de destino. Em seguida, o resultado é propagado de volta ao roteador, em vez de descompactar a função no próprio roteador. O recurso de envio de funções e procedimentos armazenados é útil para clientes que desejam executar sua função ou seu procedimento armazenado mais próximo à fonte de dados, ou seja, o fragmento.

Para distribuir uma função, primeiro crie a função e, em seguida, chame o procedimento rds_aurora.limitless_distribute_function para distribuí-la. Esta função usa a seguinte sintaxe:

SELECT rds_aurora.limitless_distribute_function('function_prototype', ARRAY['shard_key'], 'collocating_table');

A função usa os seguintes parâmetros:

  • function_prototype: a função a ser distribuída. Mencione apenas os argumentos de entrada e nenhum dos argumentos de saída.

    Se algum dos argumentos for definido como parâmetros OUT, não inclua seu tipo nos argumentos de function_prototype.

  • ARRAY['shard_key']: a lista de argumentos da função identificados como a chave de fragmento da função.

  • collocating_table: a tabela fragmentada que contém o intervalo de dados no fragmento de destino.

Para identificar o fragmento no qual inserir essa função para execução, o sistema pega o argumento ARRAY['shard_key'], faz o hash e encontra o fragmento de collocating_table que hospeda o intervalo que contém esse valor de hash.

Restrições

Ao distribuir uma função ou um procedimento, ele lida apenas com dados limitados pelo intervalo de chaves de fragmento nesse fragmento. Nos casos em que a função ou o procedimento tentar acessar dados de um fragmento diferente, os resultados retornados pela função ou pelo procedimento distribuído serão diferentes em comparação com um que não está distribuído.

Por exemplo, você cria uma função que contém consultas que têm relação com vários fragmentos, mas depois chama o procedimento rds_aurora.limitless_distribute_function para distribuí-la. Quando você invoca essa função fornecendo argumentos para uma chave de fragmento, é provável que os resultados dessa execução sejam limitados pelos valores presentes nesse fragmento. Esses resultados são diferentes dos que são produzidos sem a distribuição da função.

Exemplos

Considere a função a seguir, func em que temos a tabela fragmentada customers com a chave de fragmento customer_id.

postgres_limitless=> CREATE OR REPLACE FUNCTION func(c_id integer, sc integer) RETURNS int language SQL volatile AS $$ UPDATE customers SET score = sc WHERE customer_id = c_id RETURNING score; $$;

Agora, distribuímos essa função:

SELECT rds_aurora.limitless_distribute_function('func(integer, integer)', ARRAY['c_id'], 'customers');

Veja a seguir exemplos de planos de consulta.

EXPLAIN(costs false, verbose true) SELECT func(27+1,10); QUERY PLAN -------------------------------------------------- Foreign Scan Output: (func((27 + 1), 10)) Remote SQL: SELECT func((27 + 1), 10) AS func Single Shard Optimized (4 rows)
EXPLAIN(costs false, verbose true) SELECT * FROM customers,func(customer_id, score) WHERE customer_id=10 AND score=27; QUERY PLAN --------------------------------------------------------------------- Foreign Scan Output: customer_id, name, score, func Remote SQL: SELECT customers.customer_id, customers.name, customers.score, func.func FROM public.customers, LATERAL func(customers.customer_id, customers.score) func(func) WHERE ((customers.customer_id = 10) AND (customers.score = 27)) Single Shard Optimized (10 rows)

O exemplo a seguir mostra um procedimento com os parâmetros IN e OUT como argumentos.

CREATE OR REPLACE FUNCTION get_data(OUT id INTEGER, IN arg_id INT) AS $$ BEGIN SELECT customer_id, INTO id FROM customer WHERE customer_id = arg_id; END; $$ LANGUAGE plpgsql;

O exemplo a seguir distribui o procedimento usando somente parâmetros IN.

EXPLAIN(costs false, verbose true) SELECT * FROM get_data(1); QUERY PLAN ----------------------------------- Foreign Scan Output: id Remote SQL: SELECT customer_id FROM get_data(1) get_data(id) Single Shard Optimized (6 rows)

Volatilidade da função

É possível determinar se uma função é imutável, estável ou volátil verificando o valor provolatile na exibição pg_proc. O valor provolatile indica se o resultado da função depende somente de seus argumentos de entrada ou se é afetado por fatores externos.

O valor é um dos seguintes:

  • i: funções imutáveis, que sempre fornecem o mesmo resultado para as mesmas entradas

  • s: funções estáveis, cujos resultados (para entradas fixas) não mudam em uma varredura

  • v: funções voláteis, cujos resultados podem mudar a qualquer momento. Use também v para funções com efeitos colaterais, para que as chamadas para elas não possam ser otimizadas.

Os exemplos a seguir mostram funções voláteis.

SELECT proname, provolatile FROM pg_proc WHERE proname='pg_sleep'; proname | provolatile ----------+------------- pg_sleep | v (1 row) SELECT proname, provolatile FROM pg_proc WHERE proname='uuid_generate_v4'; proname | provolatile ------------------+------------- uuid_generate_v4 | v (1 row) SELECT proname, provolatile FROM pg_proc WHERE proname='nextval'; proname | provolatile ---------+------------- nextval | v (1 row)

Não há suporte para alterar a volatilidade de uma função existente no Aurora PostgreSQL Limitless Database. Isso se aplica aos comandos ALTER FUNCTION e CREATE OR REPLACE FUNCTION, conforme mostrado nos exemplos a seguir.

-- Create an immutable function CREATE FUNCTION immutable_func1(name text) RETURNS text language plpgsql AS $$ BEGIN RETURN name; END; $$IMMUTABLE; -- Altering the volatility throws an error ALTER FUNCTION immutable_func1 STABLE; -- Replacing the function with altered volatility throws an error CREATE OR REPLACE FUNCTION immutable_func1(name text) RETURNS text language plpgsql AS $$ BEGIN RETURN name; END; $$VOLATILE;

É altamente recomendável atribuir as volatilidades corretas às funções. Por exemplo, se sua função usa SELECT de várias tabelas ou faz referência a objetos de banco de dados, não a defina como IMMUTABLE. Se o conteúdo da tabela mudar, a imutabilidade será quebrada.

O Aurora PostgreSQL permite SELECT dentro de funções imutáveis, mas os resultados podem ser incorretos. O Aurora PostgreSQL Limitless Database pode retornar tanto erros quanto resultados incorretos. Para obter mais informações sobre volatilidade de funções, consulte Function volatility categories na documentação do PostgreSQL.

Sequências

As sequências nomeadas são objetos do banco de dados que geram números exclusivos em ordem crescente ou decrescente. CREATE SEQUENCE cria um gerador de números de sequência. Os valores da sequência são exclusivos.

Ao criar uma sequência nomeada no Aurora PostgreSQL Limitless Database, um objeto de sequência distribuída é criado. Em seguida, o Aurora PostgreSQL Limitless Database distribui partes não sobrepostas de valores de sequência em todos os Roteadores de transações distribuídas (roteadores). Essas partes são representadas como objetos de sequência local em roteadores; portanto, operações de sequência, como nextval e currval, são executadas localmente. Os roteadores operam de forma independente e solicitam novas partes da sequência distribuída quando necessário.

Para obter mais informações sobre sequências, consulte CREATE SEQUENCE na documentação do PostgreSQL.

Solicitar uma nova parte

É possível configurar o tamanho das partes alocadas nos roteadores usando o parâmetro rds_aurora.limitless_sequence_chunk_size. O valor padrão é 250000. Cada roteador possui inicialmente duas partes: ativa e reservada. As partes ativas são usadas para configurar objetos de sequência local (definindo minvalue e maxvalue), e as partes reservadas são armazenadas em uma tabela de catálogo interna. Quando uma parte ativa atinge o valor mínimo ou máximo, ela é substituída pela parte reservada. Para fazer isso, ALTER SEQUENCE é usado internamente, o que significa que AccessExclusiveLock é adquirido.

Os processos em segundo plano são executados a cada 10 segundos nos nós do roteador para verificar as sequências em busca de partes reservadas usadas. Se uma parte usada for encontrada, o processo solicitará uma nova parte da sequência distribuída. Certifique-se de definir o tamanho da parte grande o suficiente para que os processos em segundo plano tenham tempo suficiente para solicitar novas partes. As solicitações remotas nunca acontecem no contexto das sessões do usuário, o que significa que não é possível solicitar uma nova sequência diretamente.

Limitações

As seguintes limitações se aplicam às sequências no Aurora PostgreSQL Limitless Database:

  • O catálogo pg_sequence, a função pg_sequences e a instrução SELECT * FROM sequence_name mostram apenas o estado da sequência local, não o estado distribuído.

  • Os valores de sequência têm garantia de serem únicos e monotônicos dentro de uma sessão. Mas eles podem estar fora de ordem com instruções nextval executadas em outras sessões, se essas sessões estiverem conectadas a outros roteadores.

  • Verifique se o tamanho da sequência (número de valores disponíveis) é grande o suficiente para ser distribuído entre todos os roteadores. Use o parâmetro rds_aurora.limitless_sequence_chunk_size para configurar o chunk_size. (Cada roteador tem duas partes.)

  • Há suporte para a opção CACHE, mas o cache deve ser menor que o chunk_size.

Opções não compatíveis

As opções a seguir não são compatíveis com sequências no Aurora PostgreSQL Limitless Database.

Funções de manipulação de sequências

A função setval não é compatível. Para obter mais informações, consulte Sequence Manipulation Functions na documentação do PostgreSQL.

CREATE SEQUENCE

As opções a seguir não são compatíveis.

CREATE [{ TEMPORARY | TEMP} | UNLOGGED] SEQUENCE [[ NO ] CYCLE]

Para ter mais informações, consulte CREATE SEQUENCE na documentação do PostgreSQL.

ALTER SEQUENCE

As opções a seguir não são compatíveis.

ALTER SEQUENCE [[ NO ] CYCLE]

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

ALTER TABLE

O comando ALTER TABLE não é compatível com sequências.

Exemplos

CREATE/DROP SEQUENCE
postgres_limitless=> CREATE SEQUENCE s; CREATE SEQUENCE postgres_limitless=> SELECT nextval('s'); nextval --------- 1 (1 row) postgres_limitless=> SELECT * FROM pg_sequence WHERE seqrelid='s'::regclass; seqrelid | seqtypid | seqstart | seqincrement | seqmax | seqmin | seqcache | seqcycle ----------+----------+----------+--------------+--------+--------+----------+---------- 16960 | 20 | 1 | 1 | 10000 | 1 | 1 | f (1 row) % connect to another router postgres_limitless=> SELECT nextval('s'); nextval --------- 10001 (1 row) postgres_limitless=> SELECT * FROM pg_sequence WHERE seqrelid='s'::regclass; seqrelid | seqtypid | seqstart | seqincrement | seqmax | seqmin | seqcache | seqcycle ----------+----------+----------+--------------+--------+--------+----------+---------- 16959 | 20 | 10001 | 1 | 20000 | 10001 | 1 | f (1 row) postgres_limitless=> DROP SEQUENCE s; DROP SEQUENCE
ALTER SEQUENCE
postgres_limitless=> CREATE SEQUENCE s; CREATE SEQUENCE postgres_limitless=> ALTER SEQUENCE s RESTART 500; ALTER SEQUENCE postgres_limitless=> SELECT nextval('s'); nextval --------- 500 (1 row) postgres_limitless=> SELECT currval('s'); currval --------- 500 (1 row)
Funções de manipulação de sequências
postgres=# CREATE TABLE t(a bigint primary key, b bigint); CREATE TABLE postgres=# CREATE SEQUENCE s minvalue 0 START 0; CREATE SEQUENCE postgres=# INSERT INTO t VALUES (nextval('s'), currval('s')); INSERT 0 1 postgres=# INSERT INTO t VALUES (nextval('s'), currval('s')); INSERT 0 1 postgres=# SELECT * FROM t; a | b ---+--- 0 | 0 1 | 1 (2 rows) postgres=# ALTER SEQUENCE s RESTART 10000; ALTER SEQUENCE postgres=# INSERT INTO t VALUES (nextval('s'), currval('s')); INSERT 0 1 postgres=# SELECT * FROM t; a | b -------+------- 0 | 0 1 | 1 10000 | 10000 (3 rows)

Exibições de sequências

O Aurora PostgreSQL Limitless Database fornece as seguintes exibições para sequências.

rds_aurora.limitless_distributed_sequence

Esta exibição mostra o estado e a configuração de uma sequência distribuída. As colunas minvalue, maxvalue, start, inc e cache têm o mesmo significado que na exibição pg_sequences e mostram as opções com as quais a sequência foi criada. A coluna lastval mostra o último valor alocado ou reservado em um objeto de sequência distribuída. Isso não significa que o valor já tenha sido usado, pois os roteadores mantêm partes da sequência localmente.

postgres_limitless=> SELECT * FROM rds_aurora.limitless_distributed_sequence WHERE sequence_name='test_serial_b_seq'; schema_name | sequence_name | lastval | minvalue | maxvalue | start | inc | cache -------------+-------------------+---------+----------+------------+-------+-----+------- public | test_serial_b_seq | 1250000 | 1 | 2147483647 | 1 | 1 | 1 (1 row)
rds_aurora.limitless_sequence_metadata

Esta exibição mostra metadados de sequência distribuídos e agrega metadados de sequência dos nós do cluster. Ela usa as seguintes colunas:

  • subcluster_id: o ID do nó do cluster que possui uma parte.

  • Parte ativa: uma parte de uma sequência que está sendo usada (active_minvalue, active_maxvalue).

  • Parte reservada: a parte local que será usada em seguida (reserved_minvalue, reserved_maxvalue).

  • local_last_value: o último valor observado de uma sequência local.

  • chunk_size: o tamanho de uma parte, conforme configurado na criação.

postgres_limitless=> SELECT * FROM rds_aurora.limitless_sequence_metadata WHERE sequence_name='test_serial_b_seq' order by subcluster_id; subcluster_id | sequence_name | schema_name | active_minvalue | active_maxvalue | reserved_minvalue | reserved_maxvalue | chunk_size | chunk_state | local_last_value ---------------+-------------------+-------------+-----------------+-----------------+-------------------+-------------------+------------+-------------+------------------ 1 | test_serial_b_seq | public | 500001 | 750000 | 1000001 | 1250000 | 250000 | 1 | 550010 2 | test_serial_b_seq | public | 250001 | 500000 | 750001 | 1000000 | 250000 | 1 | (2 rows)

Solucionar problemas de sequência

Os problemas a seguir podem ocorrer em sequências.

Tamanho da parte não é grande o suficiente

Se o tamanho da parte não for grande o suficiente e a taxa de transação for alta, os processos em segundo plano talvez não tenham tempo suficiente para solicitar novas partes antes que as partes ativas se esgotem. Isso pode levar a eventos de contenção e espera, como LIMITLESS:AuroraLimitlessSequenceReplace, LWLock:LockManager, Lockrelation e LWlock:bufferscontent.

Aumente o valor do parâmetro rds_aurora.limitless_sequence_chunk_size.

Cache de sequência definido como muito alto

No PostgreSQL, o armazenamento em cache da sequência ocorre no nível da sessão. Cada sessão aloca valores de sequência sucessivos durante um acesso ao objeto de sequência e aumenta o last_value do objeto de sequência adequadamente. Em seguida, os próximos usos de nextval dentro dessa sessão simplesmente retornam os valores pré-alocados, sem tocar no objeto de sequência.

Quaisquer números alocados, mas não usados em uma sessão, são perdidos quando essa sessão termina, resultando em "lacunas" na sequência. Isso pode consumir o sequence_chunk rapidamente e levar a eventos de contenção e espera, como LIMITLESS:AuroraLimitlessSequenceReplace, LWLock:LockManager, Lockrelation e LWlock:bufferscontent.

Reduza a configuração do cache de sequência.

A figura a seguir mostra eventos de espera causados por problemas de sequência.

Eventos de espera causados por problemas de sequência.