O Hologres oferece suporte à lixeira de tabelas, recurso que move automaticamente para a lixeira as tabelas excluídas com o comando DROP TABLE. Restaure essas tabelas para evitar perda acidental de dados.
Limitações
A lixeira de tabelas está disponível apenas para instâncias do Hologres V3.1 ou posteriores.
Tabelas na lixeira ainda consomem memória. Por isso, não ative a lixeira para tabelas com índice vetorial. Para mais informações, consulte Trabalhar com índices Proxima Graph.
Como funciona
Os comandos DROP TABLE [CASCADE] e DROP DYNAMIC TABLE [CASCADE] movem automaticamente tabelas internas, tabelas particionadas (incluindo tabelas pai e filho) e Dynamic Tables para a lixeira.
As tabelas na lixeira ficam armazenadas em um schema separado chamado hg_recyclebin. O nome, os dados, as propriedades e os índices da tabela são preservados.
A execução dos comandos TRUNCATE ou INSERT OVERWRITE não move as tabelas para a lixeira.
Não há suporte para tabelas externas, views e materialized views.
Se uma tabela tiver um TTL, a política permanecerá ativa na lixeira e o sistema continuará a limpar os dados conforme definido.
Ativar ou desativar a lixeira
-- Enable the table recycle bin for the specified database.
ALTER DATABASE <db_name> SET hg_enable_recyclebin = ON;
-- Disable the table recycle bin for the specified database.
ALTER DATABASE <db_name> SET hg_enable_recyclebin = OFF;
A lixeira de tabelas vem ativada por padrão em instâncias novas e existentes da versão V3.1 ou posteriores. Tabelas excluídas são movidas automaticamente para a lixeira.
Após desativar a lixeira, ainda é possível recuperar ou limpar tabelas que já estão nela. No entanto, tabelas excluídas posteriormente não serão movidas para a lixeira.
Execute este comando uma vez por banco de dados. Apenas um superusuário da instância atual pode executar este comando SQL.
Recuperar tabelas
Use o comando a seguir para recuperar uma tabela excluída. Se já existir uma tabela com o mesmo nome, especifique o table_id (suportado na V3.1.18 ou posteriores) ou o id (suportado em todas as versões) para identificar a tabela específica a restaurar.
RECOVER TABLE <table_name>;
-- If another table with the same name exists, specify the table_id to restore the target table (V3.1.18 and later).
RECOVER TABLE <table_name> WITH (table_id = xxxx);
-- General syntax (for all versions)
RECOVER TABLE <table_name> [WITH (id = xxxx)];
Observe os seguintes pontos:
-
Durante a recuperação
Os dados, as propriedades e os índices da tabela, como chave primária (PK), clustering key e segment key, são restaurados. Se houver um TTL definido na tabela, ele permanecerá ativo e o sistema limpará os dados periodicamente conforme configurado.
-
Antes da recuperação
Se já existir uma tabela com o mesmo nome no schema, exclua-a ou renomeie-a antes da recuperação. Caso contrário, o comando RECOVER falhará. Contudo, se a tabela existente possuir uma chave primária ou clustering key, mova-a para um schema diferente antes de executar o comando RECOVER. Para mais informações, consulte a seção Exemplos neste tópico.
A operação de recuperação falhará se o schema da tabela tiver sido excluído.
-
Para uma tabela particionada
Uma tabela filho restaurada torna-se uma tabela padrão. Anexe-a manualmente à sua tabela pai usando ATTACH.
Ao recuperar uma tabela pai, tanto ela quanto suas tabelas filho são restauradas com a estrutura particionada original. Não é necessário anexar as tabelas filho manualmente.
Caso o particionamento dinâmico estivesse ativado na tabela pai, ele não será reativado automaticamente após a recuperação. Ative-o manualmente. Para mais informações, consulte Gerenciar particionamento dinâmico.
-
Para uma Dynamic Table
Uma Dynamic Table restaurada torna-se uma tabela padrão. Embora seja possível consultar seus dados, ela não será mais atualizada automaticamente. Para restaurar a atualização automática, recrie a Dynamic Table. Para mais informações, consulte ALTER DYNAMIC TABLE.
Restaurar uma tabela base não recupera a Dynamic Table dependente dela.
-
Para cenários em cascata
O comando
DROP TABLE ... CASCADEtambém exclui objetos dependentes, como views e materialized views. Ao recuperar a tabela, apenas ela é restaurada. Objetos dependentes, como views, materialized views e Dynamic Tables, não são restaurados.Por exemplo, se uma Dynamic Table depende de
view1eview1depende detable1, a execução do comandoDROP TABLE table1 CASCADEtambém excluirá a Dynamic Table e aview1. Ao recuperar atable1, a Dynamic Table e aview1não serão restauradas e precisarão ser recriadas manualmente. -
Permissões para recuperação
São necessárias permissões específicas para executar o comando RECOVER. Para mais informações, consulte Permissões.
Gerenciar a lixeira
Operações suportadas
As tabelas na lixeira suportam as seguintes operações:
RECOVER (recuperar uma tabela) e PURGE (limpar uma tabela).
Visualizar detalhes da tabela consultando
hologres.hg_recyclebin.
Visualizar detalhes das tabelas na lixeira
Execute a instrução a seguir para visualizar os detalhes das tabelas na lixeira:
Os proprietários das tabelas podem visualizar apenas suas próprias tabelas na lixeira. Um superusuário pode visualizar todas as tabelas na lixeira.
SELECT * FROM hologres.hg_recyclebin;
A tabela a seguir descreve os parâmetros nas informações retornadas.
|
Parâmetro |
Descrição |
|
table_id |
ID exclusivo da tabela na lixeira. Este ID identifica a tabela. |
|
schema_name |
Schema original da tabela. |
|
table_name |
Nome da tabela excluída. |
|
table_owner |
Proprietário da tabela antes da exclusão. |
|
dropby |
Usuário que excluiu a tabela. |
|
drop_time |
Momento em que a tabela foi excluída. |
Verificar o uso de armazenamento na lixeira
-
Utilize a sintaxe abaixo para verificar o uso de armazenamento de uma tabela na lixeira. O parâmetro
table_idé opcional. Se houver várias tabelas com o mesmo nome de schema e nome de tabela, especifique otable_idpara identificar uma tabela específica.-- View the storage size of a table in the recycle bin. SELECT hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]); -- Use the following syntax to display the storage size with a unit. SELECT PG_SIZE_PRETTY(hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]));Exemplo de código:
-- Assume that the deleted table is named tbl1 and belongs to the public schema. SELECT hologres.hg_recyclebin_relation_size('public.tbl1'); -- If multiple tables in the recycle bin have the same schema and table name, you must use the table_id to query the storage usage of a specific table. For example: SELECT hologres.hg_recyclebin_relation_size('public.tbl1', 42); -
Monitore o armazenamento ocupado pela lixeira de tabelas para cada banco de dados com base nas métricas de monitoramento.
As métricas de monitoramento de armazenamento para a lixeira de tabelas estão disponíveis nas versões V3.1.32, V3.2.12, V4.0.2 e posteriores do Hologres. Use essas métricas para visualizar o uso de armazenamento da lixeira em cada banco de dados.
Definir o período de retenção da lixeira
Por padrão, as tabelas na lixeira são retidas por um dia antes que o sistema as limpe permanentemente. Tabelas limpas não podem ser recuperadas. É possível ativar ou desativar a lixeira de tabelas ou modificar o período de retenção conforme as necessidades do seu negócio, utilizando a sintaxe a seguir.
-- Change the retention period of tables to 5 days.
ALTER DATABASE <db_name> SET hg_recyclebin_retention_days = 5;
As tabelas na lixeira ainda estão sujeitas à cobrança de armazenamento.
O período de retenção é medido em dias. O valor mínimo é 1 e o máximo é 10.
Apenas um superusuário pode executar esta instrução. A configuração entra em vigor no nível do banco de dados.
Limpar tabelas da lixeira
Limpe manualmente as tabelas da lixeira usando o comando PURGE. Os comandos são os seguintes:
-- Purge a single table.
PURGE TABLE {table_name};
-- Purge all tables from the recycle bin. This command must be run by a superuser.
CALL hologres.hg_purge_all_tables();
Após a execução bem-sucedida do comando, a tabela é excluída imediatamente e não pode ser recuperada.
É possível limpar apenas tabelas, não Dynamic Tables em cascata.
Permissões para limpar uma tabela: São necessárias permissões específicas para executar o comando PURGE. Para mais informações, consulte Permissões.
Após executar PURGE ou
hg_purge_all_tables(), os metadados são removidos imediatamente. No entanto, o armazenamento subjacente está sujeito a um mecanismo de exclusão atrasada (aproximadamente 2 horas por padrão), portanto, o uso real de armazenamento não diminui imediatamente. Esse comportamento é esperado.
Excluir uma tabela sem usar a lixeira
Por padrão, as tabelas excluídas com o comando DROP TABLE ou DROP Dynamic Table [CASCADE] são movidas para a lixeira. Utilize o comando a seguir para ignorar a lixeira e excluir permanentemente uma tabela.
DROP TABLE <table_name> [CASCADE] FORCE;
Após executar DROP TABLE ... FORCE, os metadados são removidos imediatamente. No entanto, o armazenamento subjacente está sujeito a um mecanismo de exclusão atrasada (aproximadamente 2 horas por padrão), portanto, o uso real de armazenamento não diminui imediatamente. Esse comportamento é esperado.
Permissões
Permissões de consulta para a lixeira
O proprietário de uma tabela pode consultar apenas as tabelas que ele próprio excluiu, não as tabelas excluídas por outros usuários.
Um superusuário pode consultar todas as tabelas na lixeira.
Permissões para exclusão, recuperação e limpeza
-
Exclusão de tabelas
Apenas um superusuário, um membro do grupo de usuários Developer ou Admin (no modelo de permissão SPM/SLPM) ou o proprietário da tabela (no Modelo de Autorização Padrão do PostgreSQL) pode executar o comando
DROPpara excluir uma tabela e movê-la para a lixeira. -
Limpeza de tabelas
Somente um superusuário, um membro do grupo de usuários Developer ou Admin (no modelo de permissão SPM/SLPM) ou o proprietário da tabela (no Modelo de Autorização Padrão do PostgreSQL) pode executar o comando
PURGEpara limpar uma tabela da lixeira. -
Recuperação de tabelas
Apenas um superusuário, um membro do grupo de usuários Developer ou Admin (no modelo de permissão SPM/SLPM), o proprietário da tabela (no Modelo de Autorização Padrão do PostgreSQL) ou o usuário que excluiu a tabela pode executar o comando
RECOVERpara restaurar a tabela ao seu estado original.
Nos modelos de permissão SPM/SLPM, apenas os usuários que eram membros do grupo de usuários Developer ou Admin antes de uma tabela ser movida para a lixeira podem gerenciar essa tabela. Se um usuário for adicionado ao grupo de usuários Developer ou Admin depois que a tabela for movida para a lixeira, esse usuário não poderá gerenciar a tabela.
Se você alternar do modelo de permissão SPM/SLPM para o Modelo de Autorização Padrão do PostgreSQL, apenas um superusuário poderá recuperar ou limpar as tabelas existentes na lixeira.
Caso especial
Se user1 for o proprietário de schema1 e user2 for o proprietário de schema1.table2, user1 poderá excluir schema1 e schema1.table2. No entanto, user1 não poderá acessar schema1.table2 porque user2 não concedeu a user1 as permissões necessárias.
-- 1. user1 creates schema1 and grants the CREATE permission on the schema to user2.
CREATE SCHEMA schema1;
GRANT CREATE ON SCHEMA schema1 TO "BASIC$user2";
-- 2. user2 creates schema1.table2 and becomes the table owner.
CREATE TABLE schema1.table2(id INT);
-- user1 can delete schema1 and all objects within it, including table2, but cannot view table2.
SELECT * FROM schema1.table2;
# ERROR: permission denied for table table2
DROP SCHEMA schema1 CASCADE;
# DROP CASCADES TO TABLE schema1.table2
# DROP SCHEMA
Para recuperar table2, existem duas opções:
user1, como o usuário que excluiu a tabela, pode recuperar as tabelas em
schema1.user2, como proprietário da tabela, pode recuperar a tabela.
Exemplos
Excluir e recuperar uma tabela
Exemplo 1: Excluir e recuperar uma tabela
-
Crie uma tabela padrão e exclua-a.
CREATE TABLE tbl1 ( id INT NOT NULL) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'id', event_time_column = 'id'); INSERT INTO tbl1 SELECT i FROM GENERATE_SERIES(1, 1000000) i; DROP TABLE tbl1; -
Verifique a lixeira para confirmar que a tabela foi movida para ela.
SELECT * FROM hologres.hg_recyclebin;Resultado retornado:
table_id | schema_name | table_name | table_owner | dropby | drop_time ---------+-------------+------------+-----------------+-------------+----------------------- 14| public | tbl1 | xx_developer | 1365xxxxxxxx| 2025-04-17 19:23:10+08 (1 row)Verifique o armazenamento da tabela:
SELECT (hologres.hg_recyclebin_relation_size('tbl1')/1024)::text||'KB' AS hg_recyclebin_relation_size;O comando retorna o tamanho de armazenamento da tabela:
hg_recyclebin_relation_size ----------------------------- 1336KB (1 row) -
Recupere a tabela.
-- Recover all data and properties of the standard table tbl1, including its primary key and clustering key. RECOVER TABLE tbl1;
Exemplo 2: Excluir e recuperar uma tabela particionada
-
Crie uma tabela particionada com as tabelas pai e filho correspondentes.
CREATE TABLE tbl2_parent(id INT) PARTITION BY list (id); CREATE TABLE tbl2_child_1 PARTITION OF tbl2_parent FOR VALUES IN (1); CREATE TABLE tbl2_child_2 PARTITION OF tbl2_parent FOR VALUES IN (2); -
Exclua uma das tabelas filho e recupere-a. A tabela filho recuperada torna-se uma tabela padrão e deve ser anexada manualmente à tabela pai original.
-- Delete a child table. DROP TABLE tbl2_child_1; -- The child table is moved to the recycle bin. SELECT * FROM hologres.hg_recyclebin;Resultado retornado:
table_id | schema_name | table_name | table_owner | dropby | drop_time ----------+-------------+--------------+------------------+-----------+------------------------ 16 | public | tbl2_child_1 | xx_developer | 1365xxxxx | 2025-04-17 19:33:30+08 (1 row)Recupere a tabela filho e verifique sua estrutura. Ela agora é uma tabela padrão e não é mais uma tabela filho.
RECOVER TABLE tbl2_child_1; SELECT hg_dump_script('tbl2_child_1');Resultado retornado:
hg_dump_script -------------------------------------------------------------- BEGIN; + + /* + DROP TABLE public.tbl2_child_1; + */ + CREATE TABLE public.tbl2_child_1 ( + id INTEGER + ) WITH ( + orientation = 'column', + storage_format = 'orc', + table_group = 'xxxx_tg_default', + table_storage_mode = 'any', + time_to_live_in_seconds = '3153600000' + ); + + + + COMMENT ON TABLE public.tbl2_child_1 IS NULL; + ALTER TABLE public.tbl2_child_1 OWNER TO "xx_developer"; + + + END; + (1 row) -
Exclua a tabela pai. Após a recuperação, ela permanece como uma tabela particionada.
-- Delete the parent table. DROP TABLE tbl2_parent CASCADE; -- Check the recycle bin. The parent and child tables are both moved to the recycle bin. SELECT * FROM hologres.hg_recyclebin;Resultado retornado:
table_id | schema_name | table_name | table_owner | dropby | drop_time ---------+-------------+--------------+---------------+---------------+------------------------ 17 | public | tbl2_child_2 | xx_developer | 1365xxxxxxxx | 2025-04-17 19:41:04+08 15 | public | tbl2_parent | xx_developer | 1365xxxxxxxx | 2025-04-17 19:41:04+08Recupere a tabela pai.
RECOVER TABLE tbl2_parent;Execute a instrução a seguir em um cliente psql para visualizar o DDL da tabela pai.
\d+ tbl2_parent;O resultado a seguir mostra que a tabela filho também foi recuperada.
Partitioned table "public.tbl2_parent" Column | Type | Collation | Nullable | Default | Storage | Stats target | Description --------+---------+-----------+----------+---------+---------+--------------+------------- id | integer | | | | plain | | Partition key: LIST (id) Partitions: tbl2_child_2 FOR VALUES IN (2)
Exemplo 4: Recuperar uma tabela com nome conflitante
-
Se você excluir uma tabela e depois criar uma nova tabela com o mesmo nome, a recuperação da tabela excluída falhará. Primeiro, renomeie a tabela existente.
-
Crie e exclua
tbl6.CREATE TABLE tbl6(id INT); -- Delete the table and move it to the recycle bin. DROP TABLE tbl6; -
Crie uma nova tabela que também se chame
tbl6e tente recuperar a tabela excluída.CREATE TABLE tbl6(id INT); RECOVER TABLE tbl6;Resultado retornado. A recuperação falha porque já existe uma tabela com o mesmo nome. Exclua ou renomeie a tabela existente.
ERROR: Table public.tbl6 already exists -
Renomeie a tabela existente
tbl6paratbl6_renamee, em seguida, recupere atbl6original. A recuperação agora é bem-sucedida.ALTER TABLE tbl6 RENAME TO tbl6_rename; RECOVER TABLE tbl6;
-
-
Se a tabela existente com o mesmo nome tiver a mesma chave primária e clustering key da tabela excluída, renomeá-la não funcionará. Mova a tabela existente para outro schema ou exclua-a antes de recuperar a tabela excluída.
-
Crie uma tabela chamada
tbl1e exclua-a.-- Create a table and set a PK and a clustering key. CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); -- Delete the table. DROP TABLE tbl1; -- Create a new table with the same name, PK, and clustering key. CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); -- Check the recycle bin. SELECT * FROM hologres.hg_recyclebin;Resultado retornado:
table_id | schema_name | table_name | table_owner | dropby | drop_time ----------+-------------+------------+------------------+------------------+------------------------ 493497 | public | tbl1 | 13659371xxx| 13659371xxx | 2025-04-17 20:11:08+08 -
A tentativa de recuperar a tabela
tbl1da lixeira falha.-- Attempt to recover the dropped table from the recycle bin. The recovery fails. RECOVER TABLE tbl1;Mensagem de erro retornada:
ERROR: Table public.tbl1 already exists -
Renomear a tabela
tbl1e tentar recuperar a tabela original também falha.-- Rename the existing table. ALTER TABLE tbl1 RENAME TO tbl2; -- The recovery still fails because the existing table has a primary key and clustering key. RECOVER TABLE tbl1;Mensagem de erro retornada:
ERROR: relation "tbl1_pkey" already EXISTS IN SCHEMA "public" -
Mova a nova tabela para outro schema. Em seguida, será possível recuperar a tabela original com sucesso.
CREATE SCHEMA test; ALTER TABLE tbl2 SET SCHEMA test; -- The recovery is successful. RECOVER TABLE tbl1;
-
Excluir uma tabela sem usar a lixeira
-- Delete a standard table without moving it to the recycle bin.
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1 FORCE;
Limpar uma tabela da lixeira
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1;
-- Forcibly delete the table from the recycle bin.
PURGE TABLE tbl1;