6

状況は次のとおりです。Heroku と Postgres を使用すると、バックアップ ダンプ ファイルを自動的に生成できます。しかし、それで何ができますか?

  1. バックアップ状態に完全に戻したい場合は、データベースにダンプします
  2. ローカルにダンプして「見てみる」か、開発環境で本番データを使用する
  3. データベースの特定の行を以前の状態に戻す (例: 誤って削除した行を復元する)

私は後者の点について非常に苦労していることに気付いたので、私がそれをどのように行ったかを共有したいと思いました.

Postgres Heroku で以前のバックアップから特定のデータを復元する方法は?

4

1 に答える 1

8

まとめ / TL;DR

3 つのステップで、非常に簡単に実行できます。

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

最初にバックアップをローカルにインストールし、2 番目に SQL スクリプトを取得し、3 番目にngrokを使用してローカルホストを外の世界に開きます。

さあ行こう?

1. Herokuでダンプ ファイルをダウンロードし、どこかにダンプします。

  • 利用可能なサーバーがいくつかある場合は、リモートデータベースでこれを行うことができます。しかし、私のように、Heroku や他の場所で別の本番データベースをプロビジョニングしたくない場合は、ローカルで十分です。
  • 私はPGAdmin (Linux、Mac、および Windows で利用可能) を使用するのが好きですが、コマンドラインを使用psqlすることもできます (この投稿を例で読むことにより)
  • PGAdmin では、Create a database. 次に、それを右クリックして、restore機能を使用します。ダンプ ファイルを選択してクリックRestoreすると、すべての設定が完了します。バックアップ データはローカルで利用できます。よくできた!

2. リモート データベースからアクセスする

私は次のことをしたかった:

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

そして、私はすべて準備ができているでしょう。とても簡単ですよね?かなり明白?これはすでに何百回も行われているに違いありません。うーん、ダメ!

Postgres 9.1+ で呼び出されるユーティリティがありますがdb_link、次の構文が適用されるため、かなり制約があります。

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

すべての列名は、その型を含めて 2 回繰り返す必要があります。かなり重い、私たちは単純ではありませんSELECT * FROM backup_db.table_name

したがって、ここでのアイデアは、information_schema各テーブルをその列名、そのタイプなどで説明するテーブルコンテンツを使用することです.SOでこの質問を見つけました:ローカル既存のタイプからdblink列定義リストを指定してください .

しかし、その解決策は、最初に関数を生成し、次にクエリを実行するという 2 つのステップのプロセスでした。

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

そして、まだ1ライナーを目指していました。少し苦労した後(SQLの第一人者ではない)、ここに要点があります:https://gist.github.com/augnustin/d30973ea8b5bf0067841

私は今できる:

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)

すごいですよね?

3. localhost にリモートでアクセスする

リモート データベースが既にインターネットから利用できる場合 (= IP アドレス、ドメイン名、たとえば Heroku の場合は次のようになりますec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9p)がある場合は、この手順をスキップできます。ただし、ローカル データベースを使用する場合は、外部から使用できるようにする必要があります (Heroku データベースがアクセスできるようにするため)。

このために、素晴らしいngrokを使用します。

インストールしたら、次のコマンドを入力するだけです。

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    

db_linkそして、(要旨に)プラグインするだけで、準備完了host=ngrock.com port=51727です!

4. さらに先へ

これには多くの可能な改善があります。ここに私がすでに見ているものがあります:

  • スクリプトをdb_link機能するデフォルト機能と見なす
  • データベース構造がバックアップと本番で異なる場合のエラー防止の強化
  • データベースの結果とバックアップの結果を比較するツールを作成する (差分行のみを返す)
  • 単純な結合を処理する
  • さらに、現在のように生の SQL の代わりにバックエンド オブジェクトの操作を可能にするアプリケーション レベルのアダプター (Rails の ActiveRecord など) が必要です。

私が明確だったことを願っています!それ以外の場合は詳細をお尋ねください

于 2014-09-09T09:43:21.850 に答える