Hologres はテーブルのごみ箱機能をサポートしており、DROP TABLE コマンドで削除されたテーブルはごみ箱に自動的に移動されます。これらのテーブルを復元することで、誤ったデータ損失を防ぐことができます。
制限事項
-
テーブルのごみ箱機能は、V3.1 以降のバージョンの Hologres インスタンスでのみ利用可能です。
-
ごみ箱内のテーブルは引き続きメモリを消費します。そのため、ベクトルインデックスを持つテーブルに対してごみ箱を有効にすることは推奨されません。詳細については、「Proxima Graph インデックスの操作」をご参照ください。
仕組み
DROP TABLE [CASCADE] および DROP DYNAMIC TABLE [CASCADE] コマンドは、内部テーブル、パーティションテーブル (親テーブルと子テーブルを含む)、およびダイナミックテーブルをごみ箱に自動的に移動します。
ごみ箱内のテーブルは hg_recyclebin という名前の別のスキーマに格納されます。テーブルの名前、データ、プロパティ、およびインデックスは保持されます。
-
TRUNCATE または INSERT OVERWRITE コマンドを実行した場合、テーブルはごみ箱に移動されません。
-
外部テーブル、ビュー、マテリアライズドビューはサポートしていません。
-
テーブルに TTL が設定されている場合、そのポリシーはごみ箱内でも有効です。システムはそれに応じてデータのパージを継続します。
ごみ箱の有効化または無効化
-- 指定されたデータベースのテーブルのごみ箱を有効にします。
ALTER DATABASE <db_name> SET hg_enable_recyclebin = ON;
-- 指定されたデータベースのテーブルのごみ箱を無効にします。
ALTER DATABASE <db_name> SET hg_enable_recyclebin = OFF;
-
テーブルのごみ箱機能は、V3.1 以降のバージョンの新規および既存のインスタンスでデフォルトで有効になっています。削除されたテーブルは自動的にテーブルのごみ箱に移動されます。
-
ごみ箱を無効にした後でも、ごみ箱にすでにあるテーブルのリカバリやパージは可能です。ただし、その後に削除したテーブルはごみ箱に移動されません。
-
このコマンドはデータベースごとに 1 回実行します。現在のインスタンスのスーパーユーザーのみがこの SQL コマンドを実行できます。
テーブルのリカバリ
次のコマンドを使用して、削除されたテーブルを復元できます。 同じ名前のテーブルがすでに存在する場合、table_id (V3.1.18 以降でサポート) または id (すべてのバージョンでサポート) を指定して、特定のテーブルを復元できます。
RECOVER TABLE <table_name>;
-- 同じ名前の別のテーブルが存在する場合、table_id を指定して対象のテーブルをリカバリします (V3.1.18 以降)。
RECOVER TABLE <table_name> WITH (table_id = xxxx);
-- 一般的な構文 (すべてのバージョン)
RECOVER TABLE <table_name> [WITH (id = xxxx)];
次の点にご注意ください:
-
リカバリ中
テーブルのデータ、プロパティ、およびプライマリキー (PK)、クラスタリングキー、セグメントキーなどのインデックスがリカバリされます。テーブルに TTL が設定されている場合、その設定は引き続き有効で、システムはそれに応じて定期的にデータをパージします。
-
リカバリ前
-
スキーマ内に同じ名前のテーブルがすでに存在する場合、リカバリ前にそのテーブルを削除または名前変更する必要があります。そうしないと、RECOVER コマンドは失敗します。ただし、既存のテーブルにプライマリキーまたはクラスタリングキーがある場合は、RECOVER コマンドを実行する前に、そのテーブルを別のスキーマに移動する必要があります。詳細については、本トピックの「例」セクションをご参照ください。
-
テーブルのスキーマが削除されている場合、リカバリ操作は失敗します。
-
-
パーティションテーブルの場合
-
リカバリされた子テーブルは標準テーブルになります。手動で親テーブルに ATTACH する必要があります。
-
親テーブルをリカバリすると、親テーブルとその子テーブルの両方が元のパーティション構造にリカバリされます。子テーブルを手動でアタッチする必要はありません。
-
親テーブルで動的パーティショニングが有効になっていた場合、リカバリ後に自動的に再有効化されません。手動で有効にする必要があります。詳細については、「動的パーティショニングの管理」をご参照ください。
-
-
ダイナミックテーブルの場合
-
リカバリされたダイナミックテーブルは標準テーブルになります。そのデータをクエリできますが、自動的には更新されなくなります。自動更新をリカバリするには、ダイナミックテーブルを再作成する必要があります。詳細については、「ALTER DYNAMIC TABLE」をご参照ください。
-
ベーステーブルをリカバリしても、そのテーブルに依存するダイナミックテーブルはリカバリされません。
-
-
カスケードシナリオの場合
DROP TABLE ... CASCADEコマンドを使用すると、ビューやマテリアライズドビューなどの依存オブジェクトも削除されます。テーブルを復元すると、テーブル自体のみが復元されます。ビュー、マテリアライズドビュー、Dynamic Tables などの依存オブジェクトは復元されません。たとえば、動的テーブルが
view1に依存し、view1がtable1に依存する場合、DROP TABLE table1 CASCADEコマンドを実行すると、動的テーブルとview1も削除されます。table1を復元しても、動的テーブルとview1は復元されず、手動で再作成する必要があります。 -
リカバリの権限
RECOVER コマンドを実行するには、特定の権限が必要です。詳細については、「権限」をご参照ください。
ごみ箱の管理
サポートされる操作
ごみ箱内のテーブルでは、次の操作がサポートされています:
-
RECOVER (テーブルのリカバリ) および PURGE (テーブルのパージ)
-
hologres.hg_recyclebinにクエリを実行すると、テーブルの詳細が表示されます。
ごみ箱内のテーブル詳細の表示
次のステートメントを実行して、ごみ箱内のテーブルの詳細を表示できます:
テーブルの所有者は、ごみ箱内で自分が削除したテーブルのみを表示できます。スーパーユーザーは、ごみ箱内のすべてのテーブルを表示できます。
SELECT * FROM hologres.hg_recyclebin;
返される情報のパラメーターを、次の表で説明します。
|
パラメーター |
説明 |
|
table_id |
ごみ箱内のテーブルの一意の ID。この ID はテーブルを識別するために使用します。 |
|
schema_name |
テーブルの元のスキーマ。 |
|
table_name |
削除されたテーブルの名前。 |
|
table_owner |
削除される前のテーブルの所有者。 |
|
dropby |
テーブルを削除したユーザー。 |
|
drop_time |
テーブルが削除された時刻。 |
ごみ箱のストレージ使用量の確認
-
ごみ箱内のテーブルのストレージ使用量を確認するには、次の構文を使用します。
table_idパラメーターはオプションです。複数のテーブルが同じスキーマ名とテーブル名を持つ場合、table_idを指定して特定のテーブルを識別できます。-- ごみ箱内のテーブルのストレージサイズを表示します。 SELECT hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]); -- 次の構文を使用して、単位付きでストレージサイズを表示します。 SELECT PG_SIZE_PRETTY(hologres.hg_recyclebin_relation_size('<schema_name.table_name>'[,<table_id>]));次のコードに例を示します:
-- 削除されたテーブルが `public` スキーマの `tbl1` という名前であると仮定します。 SELECT hologres.hg_recyclebin_relation_size('public.tbl1'); -- ごみ箱内に同じスキーマ名とテーブル名を持つ複数のテーブルがある場合は、table_id を使用して特定のテーブルのストレージ使用量をクエリします。例: SELECT hologres.hg_recyclebin_relation_size('public.tbl1', 42); -
監視メトリクスに基づいて、各データベースのテーブルのごみ箱が占有するストレージを確認できます。
テーブルのごみ箱のストレージ監視メトリクスは、Hologres バージョン V3.1.32、V3.2.12、V4.0.2 以降で利用できます。これらのメトリクスを使用して、各データベースのごみ箱のストレージ使用量を表示できます。
ごみ箱の保持期間の設定
デフォルトでは、ごみ箱内のテーブルは 1 日間保持された後、システムによって完全にパージされます。パージされたテーブルはリカバリできません。次の構文を使用して、テーブルのごみ箱を有効または無効にしたり、ビジネスニーズに応じて保持期間を変更したりできます。
-- テーブルの保持期間を 5 日間に変更します。
ALTER DATABASE <db_name> SET hg_recyclebin_retention_days = 5;
-
ごみ箱内のテーブルは、引き続きストレージ課金の対象となります。
-
保持期間は日数単位で指定します。最小値は 1、最大値は 10 です。
-
スーパーユーザーのみがこのステートメントを実行できます。この設定はデータベースレベルで有効になります。
ごみ箱からのテーブルのパージ
PURGE コマンドを使用して、ごみ箱から手動でテーブルをパージできます。コマンドは次のとおりです:
-- 単一のテーブルをパージします。
PURGE TABLE {table_name};
-- ごみ箱からすべてのテーブルをパージします。このコマンドはスーパーユーザーが実行する必要があります。
CALL hologres.hg_purge_all_tables();
-
コマンドが正常に実行されると、テーブルは直ちに削除され、リカバリできなくなります。
-
パージできるのはテーブルのみで、カスケードされたダイナミックテーブルはパージできません。
-
テーブルのパージ権限:PURGE コマンドを実行するには、特定の権限が必要です。詳細については、「権限」をご参照ください。
-
PURGE または
hg_purge_all_tables()を実行すると、メタデータはすぐに削除されます。しかし、基盤となるストレージは遅延削除メカニズム (デフォルトで約 2 時間) の対象となるため、実際のストレージ使用量はすぐには減少しません。これは想定される動作です。
ごみ箱を使用しないテーブルの削除
デフォルトでは、DROP TABLE または DROP Dynamic Table [CASCADE] コマンドで削除されたテーブルはごみ箱に移動されます。 ごみ箱を経由せずにテーブルを完全に削除するには、次のコマンドを使用できます。
DROP TABLE <table_name> [CASCADE] FORCE;
DROP TABLE ... FORCE を実行すると、メタデータはすぐに削除されます。しかし、基盤となるストレージは遅延削除メカニズム (デフォルトで約 2 時間) の対象となるため、実際のストレージ使用量はすぐには減少しません。これは想定される動作です。
権限
ごみ箱のクエリ権限
-
テーブルの所有者は、自分が削除したテーブルのみをクエリでき、他のユーザーが削除したテーブルはクエリできません。
-
スーパーユーザーは、ごみ箱内のすべてのテーブルをクエリできます。
削除、リカバリ、パージの権限
テーブルの削除
スーパーユーザー、Developer または Admin ユーザーグループのメンバー(SPM/SLPM 権限モデルの場合)、またはテーブル所有者(標準 PostgreSQL 認可モデルの場合)のみが、
DROPコマンドを実行してテーブルを削除し、ごみ箱に移動できます。-
テーブルのパージ
スーパーユーザー、(SPM/SLPM 権限モデル) の Developer または Admin ユーザーグループのメンバー、または (標準 PostgreSQL 認証モデル) のテーブル所有者のみが、
PURGEコマンドを実行してごみ箱からテーブルをパージできます。 -
テーブルのリカバリ
スーパーユーザー、(SPM/SLPM 権限モデルにおける) Developer または Admin ユーザーグループのメンバー、(標準 PostgreSQL 認可モデルにおける) テーブル所有者、またはテーブルを削除したユーザーのみが、
RECOVERコマンドを実行してテーブルを元の状態に復元できます。
-
SPM/SLPM 権限モデルでは、テーブルがごみ箱に移動される前に Developer または Admin ユーザーグループのメンバーであったユーザーのみがそのテーブルを管理できます。テーブルがごみ箱に移動された後にユーザーが Developer または Admin ユーザーグループに追加された場合、そのユーザーはテーブルを管理できません。
-
SPM/SLPM 権限モデルから標準 PostgreSQL 権限モデルに切り替えた場合、スーパーユーザーのみがごみ箱内の既存のテーブルをリカバリまたはパージできます。
特殊なケース
user1 が schema1 の所有者であり、user2 が schema1.table2 の所有者である場合、user1 は schema1 と schema1.table2 を削除できます。ただし、user2 が user1 に必要な権限を付与していないため、user1 は schema1.table2 にアクセスできません。
-- 1. user1 が schema1 を作成し、そのスキーマに対する CREATE 権限を user2 に付与します。
CREATE SCHEMA schema1;
GRANT CREATE ON SCHEMA schema1 TO "BASIC$user2";
-- 2. user2 が schema1.table2 を作成し、テーブルの所有者になります。
CREATE TABLE schema1.table2(id INT);
-- user1 は schema1 とその中のすべてのオブジェクト (table2 を含む) を削除できますが、table2 を表示することはできません。
SELECT * FROM schema1.table2;
# ERROR: permission denied for table table2
DROP SCHEMA schema1 CASCADE;
# DROP CASCADES TO TABLE schema1.table2
# DROP SCHEMA
table2 をリカバリするには、2 つのオプションがあります:
-
テーブルを削除した user1 は、
schema1内のテーブルをリカバリできます。 -
テーブルの所有者である user2 は、テーブルをリカバリできます。
例
テーブルの削除とリカバリ
例 1:テーブルの削除とリカバリ
-
標準テーブルを作成して削除します。
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; -
ごみ箱を確認し、テーブルがごみ箱に移動されたことを確認します。
SELECT * FROM hologres.hg_recyclebin;次の結果が返されます:
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)テーブルのストレージを確認します:
SELECT (hologres.hg_recyclebin_relation_size('tbl1')/1024)::text||'KB' AS hg_recyclebin_relation_size;このコマンドは、テーブルのストレージサイズを返します:
hg_recyclebin_relation_size ----------------------------- 1336KB (1 row) -
テーブルをリカバリします。
-- 標準テーブル tbl1 のすべてのデータとプロパティ (プライマリキーとクラスタリングキーを含む) をリカバリします。 RECOVER TABLE tbl1;
例 2:パーティションテーブルの削除とリカバリ
-
親テーブルと子テーブルから成るパーティションテーブルを作成します。
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); -
子テーブルの 1 つを削除してリカバリします。リカバリされた子テーブルは標準テーブルになり、元の親テーブルに手動でアタッチする必要があります。
-- 子テーブルを削除します。 DROP TABLE tbl2_child_1; -- 子テーブルがごみ箱に移動されます。 SELECT * FROM hologres.hg_recyclebin;次の結果が返されます:
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)子テーブルをリカバリし、その構造を確認します。このテーブルは標準テーブルであり、もはや子テーブルではありません。
RECOVER TABLE tbl2_child_1; SELECT hg_dump_script('tbl2_child_1');次の結果が返されます:
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) -
親テーブルを削除します。リカバリ後も、パーティションテーブルのままです。
-- 親テーブルを削除します。 DROP TABLE tbl2_parent CASCADE; -- ごみ箱を確認します。親テーブルと子テーブルの両方がごみ箱に移動されます。 SELECT * FROM hologres.hg_recyclebin;次の結果が返されます:
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+08親テーブルをリカバリします。
RECOVER TABLE tbl2_parent;psql クライアントで次のステートメントを実行して、親テーブルの DDL を表示します。
\d+ tbl2_parent;次の結果が返され、その子テーブルもリカバリされたことが示されます。
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)
例 4:名前が競合するテーブルのリカバリ
-
テーブルを削除した後に同じ名前の新しいテーブルを作成した場合、削除されたテーブルのリカバリは失敗します。まず既存のテーブルの名前を変更する必要があります。
-
tbl6を作成して削除します。CREATE TABLE tbl6(id INT); -- テーブルを削除してごみ箱に移動します。 DROP TABLE tbl6; -
同じく
tbl6という名前の新しいテーブルを作成し、削除されたテーブルのリカバリを試みます。CREATE TABLE tbl6(id INT); RECOVER TABLE tbl6;次の結果が返されます。同じ名前のテーブルがすでに存在するため、リカバリは失敗します。既存のテーブルを削除または名前変更する必要があります。
ERROR: Table public.tbl6 already exists -
既存のテーブル
tbl6の名前をtbl6_renameに変更してから、元のtbl6をリカバリします。これでリカバリは成功します。ALTER TABLE tbl6 RENAME TO tbl6_rename; RECOVER TABLE tbl6;
-
-
同じ名前の既存のテーブルが、削除されたテーブルと同じプライマリキーとクラスタリングキーを持っている場合、名前の変更は機能しません。削除されたテーブルをリカバリする前に、既存のテーブルを別のスキーマに移動するか、削除する必要があります。
-
tbl1という名前のテーブルを作成して削除します。-- テーブルを作成し、PK とクラスタリングキーを設定します。 CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); -- テーブルを削除します。 DROP TABLE tbl1; -- 同じ名前、PK、クラスタリングキーを持つ新しいテーブルを作成します。 CREATE TABLE tbl1 ( col1 INT, col2 INT, col3 INT, PRIMARY KEY (col1, col2) ) WITH ( clustering_key = 'col1' ); -- ごみ箱を確認します。 SELECT * FROM hologres.hg_recyclebin;次の結果が返されます。
table_id | schema_name | table_name | table_owner | dropby | drop_time ----------+-------------+------------+------------------+------------------+------------------------ 493497 | public | tbl1 | 13659371xxx| 13659371xxx | 2025-04-17 20:11:08+08 -
ごみ箱から
tbl1テーブルをリカバリしようとすると失敗します。-- ごみ箱から削除されたテーブルをリカバリしようとします。リカバリは失敗します。 RECOVER TABLE tbl1;次のエラーメッセージが返されます。
ERROR: Table public.tbl1 already exists -
tbl1テーブルの名前を変更してから元のテーブルをリカバリしようとしても、同様に失敗します。-- 既存のテーブルの名前を変更します。 ALTER TABLE tbl1 RENAME TO tbl2; -- 既存のテーブルにはプライマリキーとクラスタリングキーがあるため、リカバリはまだ失敗します。 RECOVER TABLE tbl1;次のエラーメッセージが返されます。
ERROR: relation "tbl1_pkey" already EXISTS IN SCHEMA "public" -
新しいテーブルを別のスキーマに移動します。そうすれば、元のテーブルを正常にリカバリできます。
CREATE SCHEMA test; ALTER TABLE tbl2 SET SCHEMA test; -- リカバリは成功します。 RECOVER TABLE tbl1;
-
ごみ箱を使用しないテーブルの削除
-- 標準テーブルをごみ箱に移動せずに削除します。
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1 FORCE;
ごみ箱からのテーブルのパージ
CREATE TABLE tbl1(id INT);
DROP TABLE tbl1;
-- ごみ箱からテーブルを強制的に削除します。
PURGE TABLE tbl1;