sql >> Databasteknik >  >> RDS >> PostgreSQL

Hur återställer man specifik data från tidigare säkerhetskopiering på Postgres Heroku? (T.ex. raderade rader av misstag)

Sammanfattning / TL;DR

I 3 steg kommer du att kunna utföra mycket enkelt:

INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name -- backup_db being remote

Installera först säkerhetskopian lokalt, för det andra skaffa ett SQL-skript, för det tredje öppna din lokala värd mot omvärlden med ngrok .

Låt oss gå?

1. Ladda ner din dumpfil på Heroku och dumpa den någonstans:

  • Du kan göra det på en fjärrdatabas om du har några servrar tillgängliga. Men om du, som jag, inte vill tillhandahålla en annan produktionsdatabas på Heroku eller någon annanstans, så kommer det att göra det lokalt.
  • Jag gillar att använda PGAdmin (tillgängligt på Linux, Mac och Windows), men med kommandoraden och psql kommer också att göra (genom att läsa detta inlägg genom exempel)
  • I PGAdmin skulle du Create a database . Högerklicka sedan på den och använd restore fungera. Välj din dumpfil, klicka på Restore och du är klar :din säkerhetskopia är tillgänglig lokalt! Bra jobbat!

2. Få åtkomst till den från din fjärrdatabas

Jag ville göra följande:

SELECT * FROM backup_db.table_name
-- So I could then do
INSERT INTO production_db.table_name
SELECT * FROM backup_db.table_name

Och jag skulle vara klar. Superenkelt, eller hur? Ganska uppenbart? Detta måste redan ha gjorts hundratals gånger. Tja, nej!

Det finns ett verktyg som heter db_link i Postgres 9.1+, men det är ganska begränsande eftersom följande syntax gäller:

SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)

Varje kolumnnamn måste upprepas två gånger inklusive dess typ. Ganska tunga, vi är långt ifrån den enkla SELECT * FROM backup_db.table_name

Så tanken här är att använda information_schema tabellinnehåll, som beskriver varje tabell med dess kolumnnamn, dess typer etc. Jag hittade den här frågan på SO:Ange dblink kolumndefinitionslista från en lokal befintlig typ vilket hjälpte mig mycket (Tack bentrm ).

Men dess lösning var en process i två steg, först genererade en funktion och sedan frågade den:

SELECT dblink_star_func('dbname=ben', 'public', 'test');
SELECT * FROM star_test() WHERE data = 'success';

Och jag siktade fortfarande på en 1 liner. Efter lite smärta (som inte är en SQL-guru), här är kärnan:https://gist.github. com/augnustin/d30973ea8b5bf0067841

Jag kan nu göra:

SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
-- And also
INSERT INTO users
SELECT * FROM remote_db(NULL::users)

Fantastiskt, eller hur?

3. Få åtkomst till localhost på distans

Om din fjärrdatabas redan är tillgänglig från internet (=har en IP-adress, ett domännamn, t.ex. för Heroku, kommer det att se ut så här:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) du kan hoppa över det här steget . Men om du använder din lokala databas måste du göra den tillgänglig från omvärlden (så att Heroku-databasen kan komma åt den).

För detta använder jag den underbara ngrok .

När jag har installerat behöver jag bara ange följande kommando:

ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
                                                                                                                                                                                                    
Tunnel Status                 online                                                                                                                                                                
Version                       1.7/1.6                                                                                                                                                               
Forwarding                    tcp://ngrok.com:51727 -> 127.0.0.1:5432                                                                                                                               
Web Interface                 127.0.0.1:4040                                                                                                                                                        
# Conn                        0                                                                                                                                                                     
Avg Conn Time                 0.00ms    

Och du behöver bara koppla in db_link (i huvudsak) till host=ngrock.com port=51727 och du är bra att gå !

4. Gå vidare

Det finns många möjliga förbättringar av detta. Här är några jag redan ser:

  • Tänker på skriptet som en standardfunktion för db_link funktion
  • Var mer felsäker om databasstrukturer är olika i säkerhetskopiering och produktion
  • Gör jämförelseverktyg mellan databasresultat och säkerhetskopieringsresultat (för att endast returnera olika rader)
  • Hantera enkla kopplingar
  • Och ännu mer skulle vara att ha en applikationsnivåadapter (t.ex. ActiveRecord in Rails) som skulle kunna tillåta manipulering av backend-objekt istället för rå SQL som nu

Hoppas jag var tydlig! Be om mer information annars




  1. ADF-filtertabell baserad på trädval

  2. var kan man redigera mysql fulltext stoppordslistor?

  3. Deadlock med SELECT ... FÖR UPPDATERING i MySQL

  4. ORACLE:Använder CTE (Common Table Expressions) med PL/SQL