PostgreSQL: 表回收站工具 Pgtrashcan 介绍

今天发现了一个名为 pgtrashcan 垃圾回收工具,当删除 PostgreSQL 表后,表并不立即物理删除,而是先保存到回收站中,在需要时可以恢复表,下载测试下。

Pgtrashcan 原理

DROP TABLE 命令执行后,表会被移到一个名为 “Trash” 的模式下,如果想永久删除此表,可以删除 “Trash” 模式下的这张表或者删除整个 “Trash” 模式,这个模块仅对表有效,其它数据库对像被删除后不会转移到 “Trash” 模式。

Pgtrashcan 安装

下载
https://github.com/petere/pgtrashcan

安装文件

1
2
3
4
5
6
7
[root@db1 soft_bak]# cd pgtrashcan
[root@db1 pgtrashcan]# ll
total 16
-rw-rw-r--. 1 root root 168 Apr 1 19:43 Makefile
-rw-rw-r--. 1 root root 4039 Apr 1 19:43 pgtrashcan.c
-rw-rw-r--. 1 root root 1494 Apr 1 19:43 README.md
drwxrwxr-x. 4 root root 4096 Apr 1 19:43 test

编译并安装

1
2
3
4
5
6
[root@db1 pgtrashcan]# make PG_CONFIG=/opt/pgsql_9.3.3/bin/pg_config
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -I. -I. -I/opt/pgsql_9.3.3/include/server -I/opt/pgsql_9.3.3/include/internal -D_GNU_SOURCE -c -o pgtrashcan.o pgtrashcan.c
gcc -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fpic -shared -o pgtrashcan.so pgtrashcan.o -L/opt/pgsql_9.3.3/lib -Wl,--as-needed -Wl,-rpath,'/opt/pgsql_9.3.3/lib',--enable-new-dtags
[root@db1 pgtrashcan]# make install PG_CONFIG=/opt/pgsql_9.3.3/bin/pg_config
/bin/mkdir -p '/opt/pgsql_9.3.3/lib'
/usr/bin/install -c -m 755 pgtrashcan.so '/opt/pgsql_9.3.3/lib/pgtrashcan.so'

修改 postgresql.conf, 设置以下参数

1
shared_preload_libraries = 'pgtrashcan'         # (change requires restart)

备注:此参数设置后需重启数据库才生效。

重启数据库

1
2
3
4
5
6
7
8
9
[pg93@db1 bin]$ pg_ctl restart -m fast -D $PGDATA
waiting for server to shut down.... done
server stopped
server starting
[pg93@db1 bin]$ LOG: 00000: loaded library "pgtrashcan"
LOCATION: load_libraries, miscinit.c:1296
LOG: 00000: redirecting log output to logging collector process
HINT: Future log output will appear in directory "pg_log".
LOCATION: SysLogger_Start, syslogger.c:649

备注: 根据上述信息, 看到 “pgtrashcan” 模块已被载入。

Pgtrashcan 测试

创建表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
francs=> create table test_trash(id serial primary key, name character varying(64),create_time timestamp(6) without time zone);
CREATE TABLE
francs=> insert into test_trash(name,create_time) select generate_series(1,100000)* random() || 'a',clock_timestamp();
INSERT 0 100000

francs=> create index idx_test_trash_ctime on test_trash using btree (create_time);
CREATE INDEX

francs=> /d test_trash
Table "francs.test_trash"
Column | Type | Modifiers
-------------+--------------------------------+---------------------------------------------------------
id | integer | not null default nextval('test_trash_id_seq'::regclass)
name | character varying(64) |
create_time | timestamp(6) without time zone |
Indexes:
"test_trash_pkey" PRIMARY KEY, btree (id)
"idx_test_trash_ctime" btree (create_time)

francs=> select * from test_trash limit 3;
id | name | create_time
----+--------------------+----------------------------
1 | 0.939794037491083a | 2014-04-02 11:22:09.238519
2 | 1.51998516358435a | 2014-04-02 11:22:09.239463
3 | 1.02361420495436a | 2014-04-02 11:22:09.239518
(3 rows)

以普通用户删除表

1
2
3
4
francs=> /c francs francs
You are now connected to database "francs" as user "francs".
francs=> drop table test_trash ;
ERROR: permission denied for schema Trash

备注:权限不够,删除表后 pgtrashcan 模块需要创建一个名为 “Trash” 的模式,但我已经给 “francs” 用户赋予创建 schema 的权限了,不知为何。

以超级用户删除表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
francs=# drop table francs.test_trash ;
DROP TABLE
francs=# /dn
List of schemas
Name | Owner
--------+----------
Trash | postgres
francs | francs
public | postgres
(3 rows)

francs=# /dt "Trash".*
List of relations
Schema | Name | Type | Owner
--------+------------+-------+--------
Trash | test_trash | table | francs
(1 row)

francs=# /ds "Trash".*
List of relations
Schema | Name | Type | Owner
--------+-------------------+----------+--------
Trash | test_trash_id_seq | sequence | francs
(1 row)

备注:以超级用户登陆后,才可以删除表,之后会在当前库创建 “Trash” 模式,并将删除的表和序列移到 “Trash” 模式下。

恢复删除的表

1
2
3
4
5
6
7
8
9
francs=# alter table "Trash".test_trash set schema francs;
ALTER TABLE

francs=# /dt+ francs.test_trash
List of relations
Schema | Name | Type | Owner | Size | Description
--------+------------+-------+--------+---------+-------------
francs | test_trash | table | francs | 5912 kB |
(1 row)

备注:恢复删除的表只需要更改表的 schema 即可。

函数删除测试

创建函数

1
2
3
4
5
6
francs=> CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS $$
francs$> BEGIN
francs$> RETURN subtotal * 0.06;
francs$> END;
francs$> $$ LANGUAGE plpgsql;
CREATE FUNCTION

删除函数

1
2
3
4
5
6
7
8
francs=> drop function sales_tax(subtotal real) ;
DROP FUNCTION

francs=> /df "Trash".*
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------+------------------+---------------------+------
(0 rows)

备注: 函数删除后,并不会移到 “Trash” 模式下。

永久删除表

如果想永久删除此表,可以删除 “Trash” 模式下的这张表或者删除整个 “Trash” 模式。

1
2
3
4
5
francs=> /c francs  postgres
You are now connected to database "francs" as user "postgres".
francs=# drop schema "Trash" cascade;
NOTICE: drop cascades to table "Trash".test_trash
DROP SCHEMA

备注:这里删除的是 “Trash” 整个模式。

总结

模块 pgtrashcan 上生产需慎用,这里仅介绍使用,并没做太多的测试。

参考

原创文章,作者:kepupublish,如若转载,请注明出处:https://blog.ytso.com/tech/database/238047.html

(0)
上一篇 2022年1月30日 08:12
下一篇 2022年1月30日 08:12

相关推荐

发表回复

登录后才能评论