前段时间,我的个人小程序在服务器上磁盘空间满,导致MongoDB挂掉。清理掉一些无用的数据后,我重启了MongoDB,但是启动失败。折腾了很久(20分钟),终于修好了。这让我意识到:虽然是个人的一个小项目,但是一定要定期备份,不然数据丢了就尴尬了。我不是MongoDB的高手。之所以选择MongoDB,是因为需求不明确——MongoDB非常适合需求不明确的场景开发。我比较熟悉Elasticsearch,Elasticsearch也很适合需求不确定的业务开发;但是我个人的服务器只有1G内存,还得花大价钱用Elasticsearch升级服务器。MongoDB备份比较简单,使用自带的mongodump即可,命令格式如下:mongodump-h{mongodb主机名}:{端口}-u{账户}-p{密码}-d{数据库名}-o{存储路径}但是我给MongoDB设置的密码里面有特殊字符,比如@#$\,如果直接按照上面的形式执行命令,会报错!所以我选择不带-p参数执行命令,即:mongodump-h{mongodb主机名}:{端口}-u{账户}-d{数据库名}-o{存储路径}然后,命令提示符会提示密码。例如#mongodump-h127.0.0.1-uuser-ditmuch-o/tmp/somepathEnterpassword:MongoDB备份至此已经实现。不过手动备份还是比较麻烦的。如何自动备份?通常情况下,自动备份比较简单——将手动备份命令做成Shell脚本,设置定时任务即可。但是在笔者的场景下,命令是需要交互输入密码的!如何自动输入密码?Expect就在这里——一个提供自动交互的工具。安装expectyuinstall-yexpect并编写expect脚本expect语法非常简单,几乎和Shell一样。作者的脚本是这样写的:#!/bin/expect#spawn是expect的语句,setDATE[execdate"+%Y-%m-%d"]setDIR/xxxxx/dbbak-$DATEspawnrm-这句话需要在执行命令之前添加rf$DIRspawnecho'removing...$DIR'spawnmongodump-h{host:port}-u{user}-d{dbname}-o$DIR#Interactiveacquisitionreturnspassword:keywordexpect"password:"#密码发过来,注意***的换行一定不能少,不然得手动输入回车。send"password\r"#留在远程控制台,没有这行,会直接回到本地控制台,不等待shell执行完interact注释。评论很全面。如果你很聪明,你一定没有压力去读它。最终备份的文件会存放在/xxxxx/dbbak-backupdate目录下。自动备份笔者使用Linux定时任务实现自动执行。crontab-e在新窗口中添加如下内容:001**?/usr/bin/expect上面expectshell的完整路径本来以为可以定时执行,结果无法正常执行。经过百度,修改脚本如下,终于可以正常执行了。#!/bin/expect#spawn是expect的语句,需要在前面加上setDATE[execdate"+%Y-%m-%d"]setDIR/xxxxx/dbbak-$DATEspawnrm-rf$DIRspawnecho'removing执行命令。..$DIR'spawnmongodump-h{host:port}-u{user}-d{dbname}-o$DIR#交互获取是否返回密码:关键字expect"password:"#发送密码,注意***的换行不能少,否则得手动输入回车。send"password\r"settimeout120expecteofexitsummary这篇文章没有难度,只是一些细节——因为密码包含特殊字符,所以需要交互输入密码;因为需要交互输入密码,所以用expect写出来主要是为了总结下面的步骤另外,expect是一个提供自动交互的通用工具,用来实现ssh的自动登录,自动登录sftp的实现,mysql的自动登录等。脚本套路基本与本文所示结构类似。
