在 PostgreSQL 中恢复删除的表

7 postgresql

我有 :

CREATE TABLE ketoan_vn.Customers
(
  CustomerId character varying(10) NOT NULL,
  CustomerName character varying(150),
  CONSTRAINT Customers_PK_CustomerID PRIMARY KEY (CustomerId)
);
Run Code Online (Sandbox Code Playgroud)

我在表 ketoan_vn.Customers 中插入了 2 行:

INSERT INTO ketoan_vn.customers(
            customerid, customername)
    VALUES ('C0001','Marry'),
    ('C0002','Tom');
Run Code Online (Sandbox Code Playgroud)

然后我删除了 ketoan_vn.Customers :

drop table ketoan_vn.Customers
Run Code Online (Sandbox Code Playgroud)

现在我想恢复被删除的表的数据。PostgreSQL 9.1 可以做到这一点吗?

Cra*_*ger 10

您不能,该文件已从磁盘中物理删除。我假设您真正的问题是关于您关心的非平凡表,而不是您可以随意重新创建的玩具表。

如果是这样:从备份还原。

如果你没有备份,关闭计算机,现在和接触专业的数据恢复团队,看看他们是否可以从空的空间在文件系统恢复表,如果它没有被盖写呢。期望为这项服务支付数千美元。

由于磁盘没有物理损坏,您可以尝试自己恢复:通过将驱动器插入另一台机器来获取驱动器的磁盘映像。不要进行文件系统级副本,您需要文件系统所在的卷/分区的原始映像。然后,您可以尝试在磁盘映像中定位该表,但请注意它可能是碎片化的,并且用于标识其位置的 inode 信息通常已消失。详细信息需要了解数据库所在的操作系统和文件系统。

更多关于这个主题的信息在这里

演示

运行您的设置:

regress=# CREATE SCHEMA ketoan_vn;
CREATE SCHEMA
regress=# CREATE TABLE ketoan_vn.Customers
regress-# (
regress(#   CustomerId character varying(10) NOT NULL,
regress(#   CustomerName character varying(150),
regress(#   CONSTRAINT Customers_PK_CustomerID PRIMARY KEY (CustomerId)
regress(# );
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "customers_pk_customerid" for table "customers"
CREATE TABLE
regress=# INSERT INTO ketoan_vn.customers(
regress(#             customerid, customername)
regress-#     VALUES ('C0001','Marry'),
regress-#     ('C0002','Tom');
INSERT 0 2
Run Code Online (Sandbox Code Playgroud)

获取表文件在磁盘上的位置:

regress=# SELECT 
  COALESCE(
    pg_catalog.pg_tablespace_location(pg_tablespace.oid),
    current_setting('data_directory')||'/base/'
  )
  || (SELECT oid from pg_database where datname = current_database() )
  || '/' 
  || relfilenode
  AS path_to_table_file
FROM pg_class
INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
LEFT OUTER JOIN pg_tablespace on (reltablespace = pg_tablespace.oid)
WHERE nspname = 'ketoan_vn' AND relname = 'customers';

          path_to_table_file               
------------------------------------------
 /var/lib/pgsql/9.2/data/base/43720/43733
(1 row)
Run Code Online (Sandbox Code Playgroud)

确认外壳上的位置:

$ sudo ls -l /var/lib/pgsql/9.2/data/base/43720/43733
-rw-------. 1 postgres postgres 8192 Apr 18 14:25 /var/lib/pgsql/9.2/data/base/43720/43733
Run Code Online (Sandbox Code Playgroud)

现在回到 psql,删除表:

drop table ketoan_vn.Customers;
Run Code Online (Sandbox Code Playgroud)

并确认它现在已经消失或长度为零:

$ sudo ls -l /var/lib/pgsql/9.2/data/base/43720/43733
-rw-------. 1 postgres postgres 0 Apr 18 14:28 /var/lib/pgsql/9.2/data/base/43720/43733
Run Code Online (Sandbox Code Playgroud)

(实际文件将在稍后由 DB 删除,但它已被截断,或者它会被重新使用。要么对您的数据非常不利。)