How to restore a single table from a .sql postgresql backup?

前端 未结 7 605
耶瑟儿~
耶瑟儿~ 2020-12-09 04:19

A table\'s rows were mistakenly deleted from the database. We have a db backup which results in a sql file that can restored like so:

psql -h localhost -d pr         


        
相关标签:
7条回答
  • 2020-12-09 04:29

    I've recently written a step by step guide on how to restore individual postgres tables.

    In short it doesn't work with SQL backups, you need to switch to pg_dump to generate backup files:

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

    Then, whenever you need to restore a specific table for data recovery or bug investigating purposes, you'll have to:

    1. Create an empty local database my_database_restored
    2. Create the table that needs to be restored my_table in the empty database
    3. Run pg_restore to selectively import desired table’s data:
    pg_restore.exe -U postgres --data-only -d "my_database_restored" -t "my_table" "my_database.dump"
    
    0 讨论(0)
  • 2020-12-09 04:30

    I'm not aware of any tool for this, but this one-liner extracts precious_table from my_backup.sql file:

    sed -n '/^COPY precious_table /,/^\\\.$/p' my_backup.sql
    
    0 讨论(0)
  • 2020-12-09 04:32

    I've write some commands to restore only the DATA for one table, from a plain text pg_dumpall. Inspired from Zouppen, thanks. That's for french readers.

    Restaurer les DONNÉES d'une table à partir d'une sauvegarde 'plain text SQL' faite, par exemple, avec pg_dumpall

    1. se positionner dans le répertoire [/data/bkp/] contenant le fichier de sauvegarde [pg_full_bak.dmp]
    $ cd /data/bkp/
    $ ls -l
    
    1. extraire les données de la table "ma_table" du schéma "public" dans le fichier {ma_table.sql}
    $ sed -n '/^COPY public.ma_table /,/^\\\.$/p' pg_full_bak.dmp > ma_table.sql
    $ ls -l
    
    1. s'assurer que les données sont bien celles attendues

      $ less ma_table.sql
      
    2. se connecter sur la base [db_name] contenant la table [ma_table] vide à restaurer, avec un compte ayant les droits en écriture sur la table [ma_table]

      $ psql -d db_name
      
    3. vérifier que la table à restaurer [ma_table] est bien vide

    postgres@db_name# select count(*) nb from ma_table ;
    +------+
    |  nb  |
    +------+
    |   0  |
    +------+
    
    1. => importer les données effacées <=

      postgres@db_name# \i ma_table.sql
      
    2. vérifier que les données ont bien été importées

      postgres@db_name# select count(*) nb
      from ma_table
      ;
      +-------+
      |   nb  |
      +-------+
      | 9876  |
      +-------+
      

    That's working for me under pg 9.3

    The easy way : steps 2, 4 & 6

    0 讨论(0)
  • 2020-12-09 04:39

    You can use grep + sed in roder to get table data:

    First, you need to identify boundaries:

    $ 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;
    

    In order to extract data for table test2:

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

    Note, you need to subtract one from the second number (i.e exclude next copy stmt)

    Now, you can load new_table_name.sql and restore data which you need. Now, you can load data into new table

    0 讨论(0)
  • 2020-12-09 04:41

    Don't do SQL backups if you need single table restore, etc. Use pg_dump's -Fc option - the "custom" format. This can be restored using pg_restore. Selective restore is possible, as are all sorts of other handy features. pg_restore can convert a custom-format dump into an SQL dump later if you need it.

    If you're stuck with an existing dump, your only options are:

    • Use a text editor to extract the target table data to a separate file and just restore that; or

    • Restore the dump to a throwaway database then use pg_dump to take a selective dump including just that table. Since it's throwaway, you can use a separate Pg instance on some unloaded fast-but-unsafe machine where you turn on all the "make it fast but eat my data if you like" options like fsync=off. You should NEVER set that in production.

    0 讨论(0)
  • 2020-12-09 04:43

    I happen to have pg_dumpall dump around. And I would like to restore table named users from the database named edc, as you most likely will have equally named tables in different databases and even schemas.

    For my case, the following sed oneliner works:

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

    What it does:

    1. /^\\connect edc/,/^\\connect/ limits the search to be the scope of my database;
    2. {…} will perform all inside commands for the range;
    3. /\susers\(\s\|$\)/ matches all lines with users on it's own, including at the end of the line;
    4. /;\|\\\./ matches lines with ; or containing \.
    5. p forces the matching lines to be outputted (note, that sed is invoked with -n).

    Depending on the complexity of your data, you might need to tweak this.

    All you have to do is to pipe sed output to the psql command with right switches.

    0 讨论(0)
提交回复
热议问题