与Mysql不同,我发现try 同步MongoDB文件非常困难-

所以,我正在try 另一种方法,它不涉及两个ssh调用

  • 登录ssh服务器
  • 导出所有MongoDB文件
  • 将它们压缩到gzip
  • 把它们送回本地机器
  • 提取和导入

不过,这里的关键是不留痕迹——

我意识到MongoDB有一种使用mongodump连接到服务器凭据的方法,但是端口是封闭的atm,所以我需要SSH方法.

Edit - 11.06.14

由于这个问题似乎有点流行,我想分享一个从这个问题的答案演变而来的脚本,以及go 年的其他资源(信用是应得的)

脚本可以在这里找到:https://github.com/iwfmp/zsh/blob/master/scripts/db/db-sync

推荐答案

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

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

ssh -L27018:localhost:27017 SERVER1

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

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

mongo --port 27018

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

只是正常运行MongoDB:

mongo(或mongo --port 27107)

将成为你的本地机器.

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

  • 27017上的MongoDB(本地主机)
  • 27018上的MongoDB(服务器1)

只需使用MongoDB(LOCALHOST)中的db.copyDatabase()函数就可以复制数据.

FROM LOCALHOST ON PORT 27017 (Executing on live will DROP YOUR DATA)

// 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的原生数据库.copyDatabase()函数将防止您必须转储/zip/restore.当然,如果你仍然想走这条路,运行mongodump,导出数据,tar/gzip,然后用scp TARGETSERVER:/path/to/file /local/path/to/file把它拉下来,在上面运行mongorestore也不难.

好像还有更多的工作要做!

Edit-这里有一个SH和JS文件,它们一起组成一个shell脚本,你可以用它来运行它.Run these on your LOCALHOST,不要在现场运行,否则会影响数据库.实时下载数据库.将这两个文件放在同一个文件夹中,用domain/ip/ssh别名替换YOURSERVERNAME in pull-db.sh,然后在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");

我在shell脚本中添加了一些额外的代码,以反映它正在做什么(sorta).脚本中的睡眠计时器只是为了让SSH连接在下一行运行之前有时间连接.基本上,发生的情况如下:

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

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

Mongodb相关问答推荐

如何拉平mongo DB中的对象并在根目录中保存时有条件地重命名字段?

查找/查找单个深度嵌套文档的多个集合

无法在Ubuntu 22.04上安装MongoDB 7.0

如何在Golang保存到MongoDB时排除空数据值的问题?

MongoDB获取所有文档谁的S子文档只包含一个特定值?

Mongo Aggregate管道-另一个集合中的多个查找

MongoDB $lookup 查找字段值数组

为什么 mongoose 在 mongodb 中找不到我的数据

如何过滤查找mongodb的结果

MongoDB 是否重用已删除的空间?

在 Heroku 上使用 Node 读取、写入和存储 JSON

使用 brew upgrade Mongo update from 3.4 to 4.0 报错:在try 升级到 4.0 之前,数据文件需要完全升级到 3.6 版

Mongoose:填充填充字段

MongoDB:自动生成的 ID 为零

java.lang.IncompatibleClassChangeError:Implementing class Mongo

在 MongoDB 上分片 GridFS

mongoose字符串到 ObjectID

如何在 MongoDB 中删除此弃用警告,为什么会这样?

mongo中的稀疏索引和空值

Mongodb 查找除一两个条件之外的所有内容