web-dev-qa-db-ja.com

ssh経由でMongoDBを同期する

Mysqlとは異なり、MongoDBファイルを同期するのは非常に困難でした。
データをstdoutに送信しないため、パイプで戻すことはできません
(私が正しく理解している場合)。

それで、私は別の方法を見つけようとしています、それは2つのssh呼び出しを必要としません。
実行する必要があるのはこれです:

  • Sshサーバーにログインします。
  • すべてのMongoDBファイルをエクスポートする
  • それらをgzipに圧縮します
  • ローカルマシンに送り返す
  • 抽出してインポート

ただし、ここで重要なのは、痕跡を残さないことです。
圧縮されたファイルをリモートマシンに残したくない
通常は別のsshログインが必要です。
したがって、「ファイルをアーカイブに移動する」という流れに沿ったものが理想的なソリューションです。
後でそれをシームレスにローカルマシンにパイプで戻すことができる場合。

MongoDBにはmongodumpを使用してサーバーの資格情報に接続する方法があるが、ポートがatmで閉じているため、SSHメソッドが必要であることを理解しています。ところで、他のアイデアも歓迎します。

編集-11.06.14

この質問はやや人気があるようですので、この質問の回答から発展したスクリプトと、昨年のその他のリソースを共有したいと思います(クレジットの期限はクレジットです)。
基本的に、スクリプトはリモートサーバーとの間の同期を管理します。可能なデータベースのタイプはどちらかです(おそらく、当面はpostgres、mysql、mongo)。
rootユーザーがdbのパスワードを持たないなど、いくつかの前提がありますが、必要に応じて変更できます。

スクリプトはここにあります: https://github.com/iwfmp/zsh/blob/master/scripts/db/db-sync

25
CrimsonKing

これは、SSHトンネリングを使用して、ローカルポートの1つで実行するようにリモートMongoDBインスタンスを設定することで実現できます。デフォルトでは、MongoDBは27017で実行されるため、以下の例では、リモートのMongoDBインスタンスをローカルの27018ポートにマップすることを選択しています。

データベースをSERVER1からLOCALHOSTにコピーする場合、LOCALHOSTで次のコマンドを実行できます。

_ssh -L27018:localhost:27017 SERVER1_

(明らかにSERVER1を実際のサーバーまたはSSHエイリアスに置き換えます)

これにより、SERVER1へのSSH接続が開かれますが、LOCALHOSTのポート27018もSERVER1のリモートポート27017にマップされます。そのSSH接続を閉じないで、次のようにポート27018でローカルホストマシン上のMongoDBに接続してみます。

_mongo --port 27018_

ローカルマシンからアクセスしている場合を除いて、これがSERVER1のデータになっていることに気づくでしょう。

MongoDBを通常どおり実行するだけです。

mongo(または_mongo --port 27107_)

ローカルマシンになります。

今、あなたは技術的に持っているので(SSHトンネルを実行したLOCALHOST上に):

  • 27017上のMongoDB(LOCALHOST)
  • 27018上のMongoDB(SERVER1)

MongoDB(LOCALHOST)内でdb.copyDatabase()関数を使用するだけで、データをコピーできます。

ポート27017のLOCALHOSTから(ライブで実行するとデータが削除されます)

_// Use the right DB
use DATABASENAME; 
// Drop the Existing Data on LOCALHOST
db.dropDatabase();
// Copies the entire database from 27018
db.copyDatabase("DATABASENAME", "DATABASENAME", "localhost:27018");
_

これをすべて、これらのコマンドをすべて実行できるシェルスクリプトにラップできるはずです。私は自分自身を持っていますが、実際には少し混乱するでしょう:)

これを実行し、MongoDBのネイティブdb.copyDatabase()関数を使用すると、ダンプ/ Zip /復元する必要がなくなります。もちろん、それでもそのルートを使いたい場合は、mongodumpを実行し、データをエクスポートしてtar/gzipし、_scp TARGETSERVER:/path/to/file /local/path/to/file_を使用してプルダウンして実行することはそれほど難しくありません。上のmongorestore

もう少し仕事のようです!

編集-これを組み合わせて実行できるシェルスクリプトを作成するSHファイルとJSファイルを次に示します。 これらをLOCALHOSTで実行します。ライブで実行しないか、ライブでdb.dropDatabaseを実行します。これら2つのファイルを同じフォルダーに入れ、_pull-db.sh_の[〜#〜] yourservername [〜#〜]をドメイン/ ip/sshエイリアス、次に_pull-db.js_でDBNAMEHEREをデータベース名に変更します。

私は通常、プロジェクトにscriptsというフォルダーを作成し、Textmateを使用して、_⌘+R_を押し、_pull-db.sh_を開いて編集し、実行します。

pull-db.sh

_ssh -L27018:localhost:27017 YOURSERVERNAME '
    echo "Connected on Remote End, sleeping for 10"; 
    sleep 10; 
    exit' &
echo "Waiting 5 sec on local";
sleep 5;
echo "Connecting to Mongo and piping in script";
cat pull-db.js | mongo
_

pull-db.js

_use DBNAMEHERE;
db.dropDatabase();
use DBNAMEHERE;
db.copyDatabase("DBNAMEHERE","DBNAMEHERE","localhost:27018");
_

シェルスクリプトに追加のコードを追加して、何をしているのかをエコーし​​ます(ちょっと)。スクリプトのスリープタイマーは、次の行が実行される前にSSH接続に接続する時間を与えるだけです。基本的に、これは何が起こるかです:

  1. コードの最初の行は、マシン上にトンネルを作成し、ECHO、SLEEP、次にEXITをリモートSSHセッションに送信します。
  2. 次に5秒間待機します。これにより、手順1のSSHセッションが接続できるようになります。
  3. 次に、pull-db.jsファイルをローカルのmongoシェルにパイプします。 (ステップ#1は5秒以内に完了する必要があります...)
  4. これでpull-db.jsがmongoで実行されているはずです。ステップ1のSSHターミナルは、接続が開かれてから10秒間実行され、EXITがそのセッションに送信されます。コマンドが発行されますが、SSHセッションは、ステップ3のアクティビティが完了するまで実際には開いたままです。
  5. Pull-db.jsスクリプトがリモートサーバーからすべてのデータのプルを完了するとすぐに、リモートサーバーでステップ1で発行されたEXITコマンドが接続を閉じ、ローカルホストの27108をバインド解除します。

これで、リモートデータベースのすべてのデータがローカルホストにあるはずです。

57
Jesta

Jestaのすばらしい答えを完成させるには、逆(ローカルデータベースから遠隔データベースへのコピー)を実行したい場合、-Lコマンドの代わりに-Rコマンドを使用して、ポートを逆にバインドする必要があります。

ssh -R27018:localhost:27017 YOURSERVERNAME

これで、リモートサーバーにログが記録されるので、ローカルデータベースからデータベースをコピーできます。

モンゴ

> db.copyDatabase( 'test'、 'test'、 'localhost:27018')

2
JulienFr

あるデータベースを別のデータベースに接続するのは本当に嫌いです。IMHOは環境の分離を壊し、そのようなスクリプトの自動化を複雑にします。

私の解決策は、「ダンプディレクトリ」を使用するmongoダンプ/復元を使用し、ファイルのストリーミングにtarを使用することです。簡単な実装(あるリモートから別のリモートにコピーするため)は次のようになります。

ssh remote1 'mongodump > /dev/null && tar -zc dump && rm -rf dump' | \
  ssh remote2 'tar -zx && mongorestore dump && rm -rf dump'

ノート:

  1. mongodumpmongorestoreはどちらも非常に詳細な出力を持っていますが、mongodumpは両方ともtarストリーミングを混乱させ、明らかにmongodumpは実際には動作を拒否します疑似端末なしで、出力リダイレクトなしで実行します。
  2. mongodumpには標準出力にダンプするオプションがありますが、それがどのような形式を使用しているかを理解できず、mongorestoreにそれをロードする方法を理解できませんでした。
2
Guss