通过ssh同步MongoDB

通过ssh同步MongoDB,mongodb,shell,ssh,Mongodb,Shell,Ssh,与Mysql不同,我发现尝试同步MongoDB文件非常具有挑战性- 它们不能通过管道传回,因为它们不会将数据发送到标准输出 (如果我理解正确的话) 因此,我正在尝试另一种方法,它不涉及两个ssh调用。 需要做的是: 登录到ssh服务器 导出所有MongoDB文件 将它们压缩到gzip 将它们发送回本地计算机 提取和导入 然而,这里的关键是不留下任何痕迹- 我不希望压缩文件留在远程计算机中, 这通常需要我进行另一次ssh登录。 因此,类似“将文件移动到存档”的做法是理想的解决方案, 如果以后可

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

因此,我正在尝试另一种方法,它不涉及两个ssh调用。
需要做的是:

  • 登录到ssh服务器
  • 导出所有MongoDB文件
  • 将它们压缩到gzip
  • 将它们发送回本地计算机
  • 提取和导入
然而,这里的关键是不留下任何痕迹-
我不希望压缩文件留在远程计算机中,
这通常需要我进行另一次ssh登录。
因此,类似“将文件移动到存档”的做法是理想的解决方案,
如果以后可以无缝地通过管道传回本地机器

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

编辑-11.06.14 由于这个问题似乎有点流行,我想分享一个从这个问题的答案演变而来的脚本,以及去年的其他资源(积分是应该积分的地方)。
该脚本基本上管理从远程服务器到远程服务器的同步,这两种类型的数据库都是可能的(目前可能是.postgres、mysql和mongo)。
它确实有一些假设,比如根用户没有db的密码,但是可以根据需要进行更改


可以在这里找到脚本:

您可以通过SSH隧道实现这一点,将远程MongoDB实例设置为在一个本地端口上运行。默认情况下,MongoDB在27017上运行,因此在下面的示例中,我选择将远程MongoDB实例映射到本地27018端口

如果在服务器上尝试将数据库从SERVER1复制到LOCALHOST,则可以在LOCALHOST上运行以下命令:

ssh-L27018:localhost:27017 SERVER1

(显然,用实际的服务器或ssh别名替换SERVER1)

这会打开到SERVER1的SSH连接,但也会将LOCALHOST上的端口27018映射到SERVER1上的远程端口27017。不要关闭该SSH连接,现在尝试使用端口27018连接到本地主机上的MongoDB,如下所示:

mongo——端口27018

您会注意到,现在这是SERVER1上的数据,只是您正在从本地计算机访问它

只是正常运行MongoDB:

mongo
(或
mongo-端口27107

将是您的本地机器

现在,由于您已经(在您运行SSH隧道的本地主机上)完成了以下操作:

  • 27017上的MongoDB(本地主机)
  • 27018上的MongoDB(服务器1)
您只需使用MongoDB(LOCALHOST)中的
db.copyDatabase()
函数即可复制数据

从端口27017上的本地主机(在live上执行将删除您的数据)

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

这样做,并使用MongoDB的原生db.copyDatabase()函数将避免您必须转储/zip/restore。当然,如果您仍然想这样做,那么运行
mongodump
,导出数据,tar/gzip,然后使用
scp TARGETSERVER:/path/to/file/local/path/to/file
将其下拉并在其上运行
mongorestore

只是看起来需要更多的工作

编辑-这里有一个SH和JS文件,它们一起组成了一个shell脚本,您可以用它运行这个脚本在本地主机上运行这些,不要在live上运行,否则会在live上运行db.dropDatabase。将这两个文件放在同一个文件夹中,并将
pull db.sh
中的servername替换为domain/ip/ssh别名,然后在
pull db.js
中将DBNAMEHERE更改为您的数据库名称

我通常在我的项目中创建一个名为
scripts
的文件夹,使用Textmate,我只需点击
⌘+R
打开以编辑以执行它时,将db.sh拉入

拉力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");
我在shell脚本中添加了一些额外的代码,以反映它正在做什么(sorta)。脚本中的睡眠计时器只是为了让SSH连接在下一行运行之前有时间连接。基本上,情况如下:

  • 代码的第一行在您的机器上创建隧道,并将ECHO、SLEEP和EXIT发送到远程SSH会话
  • 然后等待5秒钟,这允许步骤1中的SSH会话连接
  • 然后我们将pull-db.js文件通过管道传输到本地mongo shell中。(步骤1应在5秒内完成…)
  • pull-db.js现在应该在mongo中运行,步骤#1中的SSH终端在连接打开后可能已经运行了10秒,退出被发送到它的会话。命令发出后,SSH会话实际上将保持打开状态,直到步骤3中的活动完成
  • 一旦pull-db.js脚本完成从远程服务器提取所有数据,在远程服务器上的步骤#1中发出的EXIT命令最终允许关闭连接,解除本地主机上的27108绑定

  • 现在,您应该将远程数据库中的所有数据都保存在本地主机中。

    要完成Jesta great answer,如果要执行相反的操作(从本地数据库复制到远程数据库),则必须以另一种方式绑定端口,使用-R命令而不是-L命令:

    ssh-R27018:localhost:27017 YOURSERVERNAME

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

    蒙戈

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

    我真的不喜欢
    use DBNAMEHERE;
    db.dropDatabase();
    use DBNAMEHERE;
    db.copyDatabase("DBNAMEHERE","DBNAMEHERE","localhost:27018");
    
    ssh remote1 'mongodump > /dev/null && tar -zc dump && rm -rf dump' | \
      ssh remote2 'tar -zx && mongorestore dump && rm -rf dump'