如何从 .sql postgresql 备份恢复单个表?

问题描述 投票:0回答:7

一个表的行被错误地从数据库中删除。我们有一个数据库备份,它生成一个可以像这样恢复的 sql 文件:

psql -h localhost -d proddump -f /Users/U/Desktop/prod_db_backup/PostgreSQL/site_prod.sql

这最终会在本地进行完全恢复。但我们需要的是将单个表的行恢复到生产环境。关于如何使用 PostgreSQL 9.1 进行此操作的任何提示?

谢谢

postgresql sed postgresql-9.1
7个回答
26
投票

我不知道有任何工具可以做到这一点,但是这个单行从

precious_table
文件中提取
my_backup.sql

sed -n '/^COPY precious_table /,/^\\\.$/p' my_backup.sql

17
投票

如果需要单表还原等,请不要进行 SQL 备份。使用

pg_dump
-Fc
选项
- “自定义”格式。这可以使用
pg_restore
恢复。选择性恢复是可能的,就像其他各种方便的功能一样。
pg_restore
可以在以后需要时将自定义格式的转储转换为 SQL 转储。

如果您受困于现有的转储,您唯一的选择是:

  • 使用文本编辑器将目标表数据提取到一个单独的文件中,然后将其还原;或

  • 将转储恢复到一次性数据库,然后使用

    pg_dump
    进行选择性转储,仅包括该表。由于它是一次性的,您可以在一些卸载的快速但不安全的机器上使用单独的 Pg 实例,您可以在其中打开所有“使其快速但如果你喜欢就吃掉我的数据”选项,如
    fsync=off
    。你应该NEVER在生产中设置它。


11
投票

有一个简单的方法。

'pg_restore' 有一个 '--table/-t' 选项。

pg_restore -a -t your_table /path/to/dump.sql

对远程主机使用“-h”。 查看其他选项在这里


9
投票

可以在roder中使用grep + sed获取表数据:

首先,您需要确定边界:

$ fgrep -Ehn '^(COPY |CREATE TABLE )' db.sql
49:CREATE TABLE test (
60:CREATE TABLE test2 (
71:CREATE TABLE test3 (
82:COPY test (i) FROM stdin;
100090:COPY test2 (i) FROM stdin;
200098:COPY test3 (i) FROM stdin;

为了提取表test2的数据:

sed -n '100090,200097p' < db.sql | sed -e 's/^COPY test2/COPY new_table_name/' > new_table_name.sql

注意,你需要从第二个数字中减去一个(即排除下一个副本stmt)

现在,您可以加载

new_table_name.sql
并恢复您需要的数据。 现在,您可以将数据加载到新表


4
投票

我最近写了一篇关于如何恢复个人 postgres 表的分步指南。

简而言之,它不适用于SQL备份,您需要切换到

pg_dump
来生成备份文件:

pg_dump.exe --host localhost --port 5432 --username "postgres" --schema "public" --format custom --blobs --verbose --file "my_database.dump" "my_database"

然后,每当您需要恢复特定表以进行数据恢复或错误调查时,您必须:

  1. 创建一个空的本地数据库
    my_database_restored
  2. 在空数据库中创建需要恢复
    my_table
    的表
  3. 运行
    pg_restore
    有选择地导入所需表的数据:
pg_restore.exe -U postgres --data-only -d "my_database_restored" -t "my_table" "my_database.dump"

0
投票

我碰巧有

pg_dumpall
四处转转。我想从名为
users
的数据库中恢复名为
edc
的表,因为您很可能 will 在不同的数据库甚至模式中具有相同名称的表。

就我而言,以下

sed
oneliner 有效:

sed -ne '/^\\connect edc/,/^\\connect/{/\susers\(\s\|$\)/,/;\|\\\./p}' pg92.dump

它的作用:

  1. /^\\connect edc/,/^\\connect/
    将搜索限制在我的数据库范围内;
  2. {…}
    将执行该范围内的所有内部命令;
  3. /\susers\(\s\|$\)/
    单独匹配所有带有
    users
    的行,包括行尾;
  4. /;\|\\\./
    匹配带有
    ;
    或包含
    \.
  5. 的行
  6. p
    强制输出匹配行(注意,sed 是用
    -n
    调用的)。

根据数据的复杂性,您可能需要对此进行调整。

您所要做的就是将

sed
输出通过管道传递给带有右侧开关的
psql
命令。


0
投票

我写了一些命令来从纯文本 pg_dumpall 中只恢复一个表的数据。灵感来自 Zouppen,谢谢。

从备份纯文本 SQL 恢复表的数据,例如使用 pg_dumpall 完成。

  1. 转到备份所在的目录
    /data/bkp/
    (
    pg_full_bak.dmp
    )
cd /data/bkp/
ls -l
  1. 从模式
    my_table
    中提取表
    public
    的数据到文件中
    my_table.sql
sed -n '/^COPY public.my__table /,/^\\\.$/p' pg_full_bak.dmp > my_table.sql
ls -l
  1. 检查数据是否正确
less my_table.sql
  1. 连接到包含我们要恢复的空表
    db_name
    的数据库
    my_table
    ,使用对表具有写权限的帐户
psql -d db_name
  1. 检查 my_table 是否为空
select count(*) nb from my_table ;
+------+
|  nb  |
+------+
|   0  |
+------+
  1. 导入数据
\i my_table.sql
  1. 检查它是否正常工作
select count(*) nb from my_table;
+-------+
|   nb  |
+-------+
| 9876  |
+-------+

这在 pg 9.3

下对我有用

简单的方法:步骤 2、4 和 6

© www.soinside.com 2019 - 2024. All rights reserved.