通过ssh同步MongoDB

时间:2013-05-18 00:34:45

标签: mongodb shell ssh

与Mysql不同,我发现尝试同步MongoDB文件非常具有挑战性 他们不能通过管道传输,因为他们不会将数据发送到stdout
(如果我理解正确的话)。

所以,我试图寻找另一种方式,不涉及两个ssh调用 需要做的是:

  • 登录ssh服务器
  • 导出所有MongoDB文件
  • 将它们压缩为gzip
  • 将它们发回本地计算机
  • 提取并导入

然而,关键在于不留下任何痕迹 -
我不希望压缩文件留在远程机器上,
这通常需要我进行另一次ssh登录 因此,将“将文件移入档案”这一行是理想的解决方案 如果以后能够无缝地传回本地机器。

我意识到MongoDB有一种使用mongodump连接服务器凭据的方法,但是端口是关闭atm,所以我需要SSH方法。 任何其他想法都会受到欢迎,BTW。

编辑 - 11.06.14

由于这些问题似乎有些受欢迎,因此我想分享一个脚本,该脚本是从这些问题的答案和其他资源(去年的信用额度)中演变而来的。 该脚本基本上管理来自/到远程服务器的同步,对于任何类型的db都可能(暂时可能是postgres,mysql和mongo)。
它确实有一些假设,比如root用户没有db的密码,但可以根据需要进行更改。

可在此处找到该脚本:https://github.com/iwfmp/zsh/blob/master/scripts/db/db-sync

3 个答案:

答案 0 :(得分:53)

您可以使用SSH隧道完成此操作,将远程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

将是您的本地机器。

现在,既然你在技术上拥有(在LOCALHOST上运行SSH隧道的地方):

  • MongoDB(LOCALHOST)on 27017
  • MongoDB(SERVER1)on 27018

您可以使用MongoDB(LOCALHOST)中的db.copyDatabase()函数来复制数据。

FROM LOCALHOST ON PORT 27017(执行时会丢弃您的数据)

// 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");

您应该能够将这一切都包装到一个可以为您执行所有这些命令的shell脚本中。我自己有一个,但它实际上有一些额外的步骤可能会让它更混乱:)

执行此操作,并使用MongoDB的本机db.copyDatabase()函数将阻止您进行转储/ zip / restore。当然,如果您仍想继续这条路线,那么运行mongodump,导出数据,tar / gzip,然后使用scp TARGETSERVER:/path/to/file /local/path/to/file将其拉下并运行mongorestore就可以了。

看起来更像是工作!

编辑 - 这是一个SH和JS文件,它们共同构成一个shell脚本,您可以使用它来运行它。 在LOCALHOST上运行这些 ,不要在实时运行它们,也不要在实时运行db.dropDatabase。将这两个文件放在同一个文件夹中,并将pull-db.sh中的 YOURSERVERNAME 替换为domain / 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

<强>拉db.js

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

我在shell脚本中添加了一些额外的代码来回显它正在做的事情(sorta)。脚本中的睡眠定时器只是为了在下一行运行之前为SSH连接提供连接时间。基本上,这是发生的事情:

  1. 代码的第一行在您的计算机上创建隧道,并将ECHO,SLEEP,然后EXIT发送到远程SSH会话。
  2. 然后等待5秒,这允许步骤1中的SSH会话连接。
  3. 然后我们将pull-db.js文件传递给本地mongo shell。 (步骤#1应在5秒内完成......)
  4. pull-db.js现在应该在mongo中运行,并且步骤#1中的SSH终端可能在连接打开后运行了10秒,并且EXIT被发送到它的会话。发出命令,但是,在第3步的活动完成之前,SSH会话将实际保持打开状态。
  5. 一旦pull-db.js脚本完成从远程服务器提取所有数据,最终允许远程服务器上步骤1中发出的EXIT命令关闭连接,取消绑定本地主机上的27108。
  6. 您现在应该在本地主机中拥有远程数据库中的所有数据。

答案 1 :(得分:2)

要完成Jesta的完美答案,如果您想要反向(从本地数据库复制到远程数据库),您必须使用-R命令而不是-L命令来绑定端口:

  

ssh -R27018:localhost:27017 YOURSERVERNAME

现在,登录到REMOTE服务器,您可以从本地数据库中复制数据库:

  

蒙戈

     

&GT; db.copyDatabase( '测试', '测试', '本地主机:27018')

答案 2 :(得分:1)

我真的不想让一个数据库连接到另一个数据库 - 恕我直言,它打破了环境的分离,并使这些脚本自动化变得复杂。

我的解决方案是使用mongo dump / restore,它使用&#34;转储目录&#34;并使用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有一个转储到stdout的选项,但我无法弄清楚它使用的格式,我也不明白如何让mongorestore加载