mysqlhotcopy是一个Perl脚本,最初由Tim Bunce编写并提供。它使用LOCK TABLES、FLUSH TABLES和cp或scp来快速备份数据库。它是备份数据库或单个表的最快的途径,但它只能运行在数据库目录所在的机器上。mysqlhotcopy只用于备份MyISAM。它运行在Unix和NetWare中。
使用mysqlhotcopy,需要先安装perl的连接mysql的驱动
perl-DBI
perl-DBD-MySQL
查询是否安装
1 2 3 4 5 | #rpm -qa|grep perl-DBI perl-DBI-1.52-2.el5 #rpm -qa|grep perl-DBD perl-DBD-MySQL-3.0007-2.el5.x86_64 |
注意:根据操作系统的版本来决定是安装32位的还是64位的。
我这里的环境用RPM包安装依赖较多,就采用了下面的源码方式来自己编译所需的PERL模块。
编译安装PERL模块
1 2 3 4 5 6 7 | wget http://search.cpan.org/CPAN/authors/id/C/CA/CAPTTOFU/DBD-mysql-4.019.tar.gz tar xvf DBD-mysql-4.019.tar.gz cd DBD-mysql-4.019 perl Makefile.PL --mysql_config=/usr/local/webserver/mysql/bin/mysql_config make make test make install |
注;我的环境中MySQL是编译安装的,请根据自己情况调整–mysql_config选项位置。
创建一个用于备份数据库用户
1 2 | grant select,reload,lock tables on *.* to 'hotcopyer'@'localhost' identified by '000000'; flush privileges; |
mysqlhotcopy用法详解
常用参数
–allowold 如果目标存在不放弃(加上一个_old后缀重新命名它)。
–addtodest 增量备份,新的备份自动覆盖掉原來的数据,相对于allowold
–checkpoint=db_name.tbl_name 在指定的数据库.表中插入检查点条目。
–debug 启用调试输出。
–dryrun,-n 报告动作而不执行它们。
–flushlog 所有表锁定后刷新日志。
–keepold 完成后不删除以前(重新命名的)的目标。
–method=command 复制方法(cp或scp)。
–noindices 备份中不包括全部索引文件。这样使备份更小、更快。可以在以后用myisamchk -rq重新构建索引。
–user=user_name,-u user_name 当连接服务器时使用的MySQL用户名。
–password=password,-p password 当连接服务器时使用的密码。请注意该选项的密码值是不可选的,不象其它MySQL程序。
–port=port_num,-P port_num 当连接本地服务器时使用的TCP/IP端口号。
–quiet,-q 除了出现错误时保持沉默。
–regexp=expr 复制所有数据库名匹配给出的正则表达式的数据库。
–socket=path,-S path 用于连接的Unix套接字文件。
–suffix=str 所复制的数据库名的后缀。
–tmpdir=path 临时目录(代替/tmp)。
查看mysqlhotcopy使用帮助
1 2 | perldoc mysqlhostcopy mysqlhostcopy -h |
1)、mysqlhotcopy 原数据库名 新数据库名
1 2 3 4 5 6 7 | ./mysqlhotcopy --user=hotcopyer --password=000000 test test1 Locked 40 tables in 0 seconds. Flushed tables (`test`.`hehun_love`, `test`.`wp_2_commentmeta`, `test`.`wp_2_comments`, `test`.`wp_2_links`, `test`.`wp_2_mobilepress`, `test`.`wp_2_options`, `test`.`wp_2_postmeta`, `test`.`wp_2_posts`, `test`.`wp_2_term_relationships`, `test`.`wp_2_term_taxonomy`, `test`.`wp_2_terms`, `test`.`wp_2_usermeta`, `test`.`wp_2_users`, `test`.`wp_2_w3tc_cdn_queue`, `test`.`wp_ak_popularity`, `test`.`wp_ak_popularity_options`, `test`.`wp_blog_versions`, `test`.`wp_blogs`, `test`.`wp_commentmeta`, `test`.`wp_comments`, `test`.`wp_links`, `test`.`wp_mobilepress`, `test`.`wp_options`, `test`.`wp_postmeta`, `test`.`wp_posts`, `test`.`wp_ratings`, `test`.`wp_registration_log`, `test`.`wp_sabre_table`, `test`.`wp_signups`, `test`.`wp_site`, `test`.`wp_sitemeta`, `test`.`wp_statpress`, `test`.`wp_term_relationships`, `test`.`wp_term_taxonomy`, `test`.`wp_terms`, `test`.`wp_threadtwitter`, `test`.`wp_threadtwitter_users`, `test`.`wp_usermeta`, `test`.`wp_users`, `test`.`wp_w3tc_cdn_queue`) in 0 seconds. Copying 120 files... Copying indices for 0 files... Unlocked tables. mysqlhotcopy copied 40 tables (120 files) in 0 seconds (1 seconds overall). |
2)、mysqlhotcopy 原数据库名 备份的目录
1 2 3 4 5 6 7 | ./mysqlhotcopy --user=hotcopyer --password=000000 test /home/testhotcopy/ Locked 40 tables in 0 seconds. Flushed tables (`test`.`hehun_love`, `test`.`wp_2_commentmeta`, `test`.`wp_2_comments`, `test`.`wp_2_links`, `test`.`wp_2_mobilepress`, `test`.`wp_2_options`, `test`.`wp_2_postmeta`, `test`.`wp_2_posts`, `test`.`wp_2_term_relationships`, `test`.`wp_2_term_taxonomy`, `test`.`wp_2_terms`, `test`.`wp_2_usermeta`, `test`.`wp_2_users`, `test`.`wp_2_w3tc_cdn_queue`, `test`.`wp_ak_popularity`, `test`.`wp_ak_popularity_options`, `test`.`wp_blog_versions`, `test`.`wp_blogs`, `test`.`wp_commentmeta`, `test`.`wp_comments`, `test`.`wp_links`, `test`.`wp_mobilepress`, `test`.`wp_options`, `test`.`wp_postmeta`, `test`.`wp_posts`, `test`.`wp_ratings`, `test`.`wp_registration_log`, `test`.`wp_sabre_table`, `test`.`wp_signups`, `test`.`wp_site`, `test`.`wp_sitemeta`, `test`.`wp_statpress`, `test`.`wp_term_relationships`, `test`.`wp_term_taxonomy`, `test`.`wp_terms`, `test`.`wp_threadtwitter`, `test`.`wp_threadtwitter_users`, `test`.`wp_usermeta`, `test`.`wp_users`, `test`.`wp_w3tc_cdn_queue`) in 0 seconds. Copying 120 files... Copying indices for 0 files... Unlocked tables. mysqlhotcopy copied 40 tables (120 files) in 1 second (1 seconds overall). |
3)、对单个表支持正则表达式(除了wp_2开头的表外)
1 2 3 4 5 6 7 8 | ./mysqlhotcopy --user=hotcopyer --password=000000 test./~wp_2/ Using copy suffix '_copy' Locked 27 tables in 0 seconds. Flushed tables (`test`.`hehun_love`, `test`.`wp_ak_popularity`, `test`.`wp_ak_popularity_options`, `test`.`wp_blog_versions`, `test`.`wp_blogs`, `test`.`wp_commentmeta`, `test`.`wp_comments`, `test`.`wp_links`, `test`.`wp_mobilepress`, `test`.`wp_options`, `test`.`wp_postmeta`, `test`.`wp_posts`, `test`.`wp_ratings`, `test`.`wp_registration_log`, `test`.`wp_sabre_table`, `test`.`wp_signups`, `test`.`wp_site`, `test`.`wp_sitemeta`, `test`.`wp_statpress`, `test`.`wp_term_relationships`, `test`.`wp_term_taxonomy`, `test`.`wp_terms`, `test`.`wp_threadtwitter`, `test`.`wp_threadtwitter_users`, `test`.`wp_usermeta`, `test`.`wp_users`, `test`.`wp_w3tc_cdn_queue`) in 0 seconds. Copying 81 files... Copying indices for 0 files... Unlocked tables. mysqlhotcopy copied 27 tables (81 files) in 0 seconds (0 seconds overall). |
4)、支持增量备份
1 2 3 4 5 6 7 | ./mysqlhotcopy test./~wp_2/ --addtodest test1 Locked 26 tables in 0 seconds. Flushed tables (`test`.`wp_ak_popularity`, `test`.`wp_ak_popularity_options`, `test`.`wp_blog_versions`, `test`.`wp_blogs`, `test`.`wp_commentmeta`, `test`.`wp_comments`, `test`.`wp_links`, `test`.`wp_mobilepress`, `test`.`wp_options`, `test`.`wp_postmeta`, `test`.`wp_posts`, `test`.`wp_ratings`, `test`.`wp_registration_log`, `test`.`wp_sabre_table`, `test`.`wp_signups`, `test`.`wp_site`, `test`.`wp_sitemeta`, `test`.`wp_statpress`, `test`.`wp_term_relationships`, `test`.`wp_term_taxonomy`, `test`.`wp_terms`, `test`.`wp_threadtwitter`, `test`.`wp_threadtwitter_users`, `test`.`wp_usermeta`, `test`.`wp_users`, `test`.`wp_w3tc_cdn_queue`) in 0 seconds. Copying 78 files... Copying indices for 0 files... Unlocked tables. mysqlhotcopy copied 26 tables (78 files) in 0 seconds (0 seconds overall). |
小技巧:
如果不想写密码在shell中的话,可在/etc/my.cnf或者登陆用户的个人主目录.my.cnf里面添加[mysqlhotcopy],以便让mysqlhotcopy从中读取用户名/密码。
1 2 3 4 5 | [mysqlhotcopy] interactive-timeout user=hotcopyer password=000000 port=3306 |
修改权限
1 | chmod 600 ~/.my.cnf |
mysqlhotcopy从选项文件读取[client]和[mysqlhotcopy]选项组。要想执行mysqlhotcopy,你必须可以访问备份的表文件,具有那些表的SELECT权限和RELOAD权限(以便能够执行FLUSH TABLES)。
定期自动备份脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | vi /data0/mysql/mysqlbakup.sh #!/bin/sh # Name:mysqlbackup.sh # PS:MySQL DataBase Backup,Use mysqlhotcopy script. # Last Modify:2011-05-27 # 定义变量,请根据具体情况修改 # 定义脚本所在目录 scriptsDir=`pwd` # 数据库的数据目录 dataDir=/data0/mysql/data/ # 数据备份目录 tmpBackupDir=/tmp/mysqlbackup backupDir=/backup/mysql # 用来备份数据库的用户名和密码 mysqlUser=hotcopyer mysqlPWD='000000' # 如果临时备份目录存在,清空它,如果不存在则创建它 if [[ -e $tmpBackupDir ]]; then rm -rf $tmpBackupDir/* else mkdir $tmpBackupDir fi # 如果备份目录不存在则创建它 if [[ ! -e $backupDir ]];then mkdir $backupDir fi # 得到数据库备份列表,在此可以过滤不想备份的数据库 for databases in `find $dataDir -type d | \ sed -e "s/\/data0\/mysql\/data\///" | \ sed -e "s/performance_schema//"`; do if [[ $databases == "" ]]; then continue else # 备份数据库 /usr/local/webserver/mysql/bin/mysqlhotcopy --user=$mysqlUser --password=$mysqlPWD -q "$databases" $tmpBackupDir dateTime=`date "+%Y.%m.%d %H:%M:%S"` echo "$dateTime Database:$databases backup success!" >>MySQLBackup.log fi done # 压缩备份文件 date=`date -I` cd $tmpBackupDir tar czf $backupDir/mysql-$date.tar.gz ./ #End完成 |
加入到crontab中设置每周5运行
1 | 0 0 * * 5 /backup/mysqlbakup.sh |
注意:恢复数据库到备份时的状态
mysqlhotcopy备份出来的是整个数据库目录,使用时可以直接拷贝到mysqld指定的datadir目录下即可,同时要注意权限的问题,如下例:
1 2 | cp -rf db_name /data0/mysql/data/ chown -R mysql:mysql /data0/mysql/data/ (将db_name目录的属主改成 mysqld 运行用户) |
本套备份策略只能恢复数据库到最后一次备份时的状态,要想在崩溃时丢失的数据尽量少应该更频繁的进行备份,要想恢复数据到崩溃时的状态请使用主从复制机制(replication)。
参考文档
http://fred.oracle1.com/weblog/2006/12/12/trouble-about-dbdmysql-perl-module/
http://www.cublog.cn/u/29134/showart_493525.html
http://www.phpabc.cn/hao-yong-de-mysql-bei-fen-gong-ju-mysqlhotcopy.html
俺表示看不懂。。。
[回复]