首页 > shell programming > 使用expect和crontab定期远程备份mysql数据库

使用expect和crontab定期远程备份mysql数据库

2010年2月21日 admin 发表评论 阅读评论

我的这个博客是在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

  1. 2010年8月19日16:30 | #1

    需要用expect吗?直接shell中就可以ftp备份啊

  2. admin
    2010年8月22日00:07 | #2

    @胡子
    刚搜了一下,发现ftp命令确实支持这种方式阿,谢了,长见识了!

  3. admin
    2010年8月27日19:25 | #3

    不过貌似使用ssh的话,就有点麻烦了。如果不是用秘匙的话,需要输入密码的。

  1. 2010年4月24日16:27 | #1