PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Jak przywrócić określone dane z poprzedniej kopii zapasowej na Postgres Heroku? (np. przypadkowo usunięte wiersze)

Podsumowanie / TL;DR

W 3 krokach będziesz w stanie wykonać bardzo prosto:

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

Najpierw zainstaluj kopię zapasową lokalnie, po drugie pobierz skrypt SQL, po trzecie otwórz swój lokalny host na świat zewnętrzny za pomocą ngrok .

Chodźmy?

1. Pobierz plik zrzutu na Heroku i zrzuć to gdzieś:

  • Możesz to zrobić w zdalnej bazie danych, jeśli masz dostępne serwery. Ale jeśli tak jak ja nie chcesz udostępniać innej produkcyjnej bazy danych w Heroku lub w innym miejscu, lokalnie całkowicie to zrobi.
  • Lubię używać PGAdmin (dostępne w systemach Linux, Mac i Windows), ale za pomocą wiersza poleceń i psql też zrobi (czytając ten post przez przykład)
  • W PGAdmin zrobisz Create a database . Następnie kliknij prawym przyciskiem myszy i użyj restore funkcjonować. Wybierz plik zrzutu, kliknij Restore i gotowe:Twoje dane kopii zapasowej są dostępne lokalnie! Dobra robota!

2. Uzyskaj do niego dostęp ze zdalnej bazy danych

Chciałem wykonać następujące czynności:

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

I byłbym gotowy. Super łatwe, prawda? Dość oczywiste? Musiało to być zrobione już setki razy. Cóż, nie!

Istnieje narzędzie o nazwie db_link w Postgresie 9.1+, ale jest to dość ograniczające, ponieważ obowiązuje następująca składnia:

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

Każdą nazwę kolumny należy powtórzyć dwukrotnie, łącznie z jej typem. Dość ciężkie, daleko nam do prostego SELECT * FROM backup_db.table_name

Pomysł polega na tym, aby użyć information_schema zawartość tabeli, która opisuje każdą tabelę z nazwami kolumn, jej typami itp. Znalazłem to pytanie na SO:Określ listę definicji kolumn dblink z lokalnego istniejącego typu co mi bardzo pomogło (Dzięki bentrm ).

Ale jego rozwiązanie było procesem dwuetapowym, najpierw generując funkcję, a następnie wysyłając zapytanie:

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

A ja wciąż celowałem w 1 liniowiec. Po pewnym bólu (nie będąc guru SQL), oto podsumowanie:https://gist.github. com/augnustin/d30973ea8b5bf0067841

Teraz mogę zrobić:

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)

Niesamowite, prawda?

3. Uzyskaj zdalny dostęp do hosta lokalnego

Jeśli twoja zdalna baza danych jest już dostępna w internecie (=ma adres IP, nazwę domeny Np. dla Heroku będzie wyglądać tak:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p ) możesz pominąć ten krok . Ale jeśli korzystasz z lokalnej bazy danych, musisz udostępnić ją ze świata zewnętrznego (aby baza danych Heroku miała do niej dostęp).

W tym celu używam wspaniałego ngrok .

Po zainstalowaniu wystarczy wprowadzić następujące polecenie:

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    

I wystarczy tylko podłączyć db_link (w treści) do host=ngrock.com port=51727 i jesteś gotowy do wyjścia !

4. Idąc dalej

Istnieje wiele możliwych ulepszeń. Oto kilka, które już widzę:

  • Uważanie skryptu za domyślną funkcję db_link funkcja
  • Większa odporność na błędy, jeśli struktury bazy danych są różne w przypadku tworzenia kopii zapasowych i produkcji
  • Tworzenie narzędzia do porównywania wyników bazy danych z wynikami kopii zapasowej (aby zwracać tylko linie różnicujące)
  • Obsługuj proste połączenia
  • A jeszcze dalej byłoby mieć adapter na poziomie aplikacji (np. ActiveRecord w Rails), który umożliwiałby manipulowanie obiektami zaplecza zamiast surowego SQL, jak teraz

Mam nadzieję, że zrozumiałem! W przeciwnym razie poproś o więcej szczegółów




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zwrócić tabelę według typu wiersza w PL/pgSQL?

  2. Postgres:Rozwiń kolumnę JSON do wierszy

  3. Oś czasu z adnotacjami Google Vis z bazy danych SQL przy użyciu problemu PHP JSON

  4. Połącz trygram z wyszukiwaniem według rankingu w django 1.10

  5. Jak obliczyć wzrost z miesiąca na miesiąc w PostgreSQL