使用expect和crontab定期远程备份mysql数据库
我的这个博客是在unix-center上安家的。使用了unix-center提供的apache服务器以及php5和mysql数据库。
在这个博客上写了不少东西之后,觉得为了安全起见,需要定时的将数据库的内容拷贝到我自己的NAS上做一下备份。
如何实现这个功能呢?
我考虑使用下面的工具组合来完成这个工作:
- 备份数据库可以使用mysqldump命令将数据库备份为.sql文件
- 可以使用expect命令将备份的.sql文件通过ftp上传到的我的NAS机
- 可以使用cron工具定期的完成上述两步
就是这么简单,cron的使用是比较的熟悉了,但是对于mysqldump命令和expect命令我都不是很熟,但是mysqldump命令其实不需要我们了解什么,用法和简单。
但是对于expect工具,比较为难,关于这个工具网络上的系统的介绍并不是很多。而且对于这个工具到底需要了解到什么程度,心里面没有底。
根据wikipedia上的描述,对于简单的应用,比如自动的登录ftp等等,使用起来都很简单,基本上只要需要send和expect就可以了,但是在下面的参考文档中,发现对于expect工具,简单的有简单的使用方法,复杂起来的话,也会比较的复杂。
我比较纠结的是,我到底需要了解到什么程度呢?
想了想,算了,对于工具,还是没哟必要了解的太深入,需要用多少就了解多少吧,了解的再深入,不使用,过一段时间还是会忘的精光。
关于expect,最基本的语法包括下面的这几个(从wikipedia摘抄):
# 向远程服务器请求打开一个FTP会话,并等待服务器询问用户名 spawn ftp $remote_server expect "username:" # 输入用户名,并等待服务器询问密码 send "$my_user_id\r" expect "password:" # 输入密码,并等待FTP提示符的出现 send "$my_password\r" expect "ftp>" # 切换到二进制模式,并等待FTP提示符的出现 send "bin\r" expect "ftp>" # 关闭ftp的提示符 send "prompt\r" expect "ftp>" # 下载所有文件 send "mget *\r" expect "ftp>" # 退出此次ftp会话,并等待服务器的退出提示EOF send "bye\r" expect eof
上面的脚本很好理解,甚至不需要解释,其中spawn触发了一个交互的开始(如ssh,ftp等等),以ftp为例,expect即希望从ftp程序收到的字串,send即向ftp发送的字串,如此往复,完成用户名,密码,接收文件,发送文件等等交互。
需要注意的是,如上面所示,在send中,需要加入\r,来模拟用户键入Enter按键。而且我所看到的几个例子中,都需要要在脚本的最后使用expect eof来完成最后的交互,退出脚本。
对于expect,我所需要的也就差不多是这么多了。还有一个需要补充的是,我在写expect脚本的时候,需要往expect脚本中传入参数。
在expect中,参数的传递有着和bash不同的方式,如下所示:
set file [lindex $argv 0]
上述的语句的含义是将传入的第一个参数赋值给file变量。
这是跟bash的$0,$1的使用方法不一样的。
OK,至此已经获得了我们所需要了解的关于expect工具的知识,下面是我参考wiki自己写的登录我的NAS服务器的expect脚本.
#!/usr/bin/expect -f set file [lindex $argv 0] //ftp到storyer.9966.org spawn ftp storyer.9966.org expect "Name (storyer.9966.org:xiaoshe):" send "youruserid\r" expect "Password:" send "yourpassowrd\r" expect "ftp>" send "bin\r" expect "ftp>" send "prompt\r" expect "ftp>" send "cd db_xiaoshe\r" expect "ftp>" send "put $file\r" expect "ftp>" send "bye\r" expect eof
上面的程序的内容也是一看即明了。
下面我们来写真正的backup的脚本,脚本如下所示:
#!/bin/bash DB_SERVER="server" DB_NAME="server" DB_USER="userid" DB_PASSWD="password" BACKUP_DIR="backupdir" DATE=$(/bin/date +%F) FILE_NAME="db_$DATE.sql.gz" echo "starting to backup database" #使用mysqldump命令备份我的mysql数据库,并存为文件 exec /usr/bin/mysqldump -hmysql -uxiaoshe -pxiaoshesql xiaoshe | gzip > $BACKUP_DIR/$FILE_NAME cd $BACKUP_DIR #执行expect脚本,完成将备份的mysql文件传送到我的NAS机上 exec /home/r/o/xiaoshe/code/ftp.expt $FILE_NAME echo "end of backup of database"
如上,执行上述脚本就能够完成一次将mysql数据备份,并将备份数据上传到NAS的功能。
如果我们需要定期自动的完成上述功能的时候,就需要借助cron来帮忙了,如下:
使用crontab -e命令编辑自己的crontab任务。
在打开的编辑器中,加入下面的一行
*/5 * * * * xiaoshe /home/r/o/xiaoshe/code/db_backup.sh
然后保存,退出即可。
上面的crontab任务表示,每5分钟执行一次db_backup.sh脚本。实际上这个时间是太频繁了,我所使用的是下面的:
01 4 * * 0 xiaoshe /home/r/o/xiaoshe/code/db_backup.sh
表示在每周日的夜里4点01分支行db_backup.sh脚本,这个备份频率是合适的。
OK,大功告成!
参考文档:
http://fanqiang.chinaunix.net/a4/b8/20010912/1000001278.html
http://www.osnews.com/story/10929/Command-line_interactive_programs_in_UNIX_shell-scripts/page1/
http://zh.wikipedia.org/wiki/Expect
http://www.21andy.com/blog/20071102/655.html

需要用expect吗?直接shell中就可以ftp备份啊
@胡子
刚搜了一下,发现ftp命令确实支持这种方式阿,谢了,长见识了!
不过貌似使用ssh的话,就有点麻烦了。如果不是用秘匙的话,需要输入密码的。