学习网考试学习资料

Gzu521.com

MySQL简易备份方法

MySQL教程   点击:次   发布时间:2005-7-29   【字体: 】   来源:
Gzu521.com我的学习网
适用对象: MySQL db管理员. 
适用条件: 对 LINUX 环境有基础的管理及操作能力. 
特别注意: 1.本篇文章提供之程式及设定*不一定*符合您的环境, 
请依您的系统环境适当地修改程式及设定. 
2.在执行任何具破坏性的动作及行为前, 
请确认您已作好完整可用的资料备份工作. 

目录内容 
一.前言 
二.错误修正 
三.开始备份 
四.如何回存 
五.mysql线上备份 
六.mysql线上回存 七.开始排定备份 
八.结语 
九.参考资料 
十.附录-备份script原始档 

一.前言 

        前几周,正当我在网上快乐的冲浪,在酷!学园快乐的灌口水时, 竟蹦出一页 "phpbb critical error",查询 database 出现错误的讯息,中断了各学员在各系版唇枪舌战,热烈的讨论,虽然过了不久,系统管理工友把网页修好,但开始连续几个星期,phpbb 讨论区有时还是很容易挂掉,频率大约是一至二周一次,通常都是在周末大家最闲的时侯发生的,幸好此时刚好世界杯足球赛正好开打,不能到学园灌水,最少还有足球赛可以看. 

当时修护的方式,是将 mysql 服务停止,再把前一次可用的db档案盖回去, 然後再重新启动 mysql 服务来测试 phpbb 是否正常,这样子的作法通常都有效, 但总是会遗失某一段时间内的文章,这不是大家所希望的... 

为了保存许多珍贵的资料和学园们恶心的口水,我开始著手准备 db 的备份工作,准备重建这个有问题 db ,更为将来校园的迁址作 db 移转准备. 

(db: database的简称,以下都以 db 取代 database, phpbb: 酷!学园讨论区系统的软体名称) 


二.错误修正 

花了一些时间熟悉主机的环境後,我开始寻找错误在那里... 

检测 mysql 内 phpbb 的 db 後发现,有个 users 的 table 是有问题的, 使用 myisamchk 尝试去修护,发现还不行用预设方式修护,还要多加个 "-o" 的参数才行,在使用myisamchk 时,为避免还有用户来存取 db ,最好是能够将 mysql 服务停止,不然最少也要下个 "mysqladmin flush-tables" 後, 再作 myisamchk 指令,像: 

myisamchk -o phpbb2_users.myi 

这个动作,可能要作个2~3次,直到没有错误的讯息出现! 

修护完,重新启动 mysql 服务後,就可以用 mysql 这个 client 的指令, 去 query 一下 db 内容,测试看是否正常.很幸运的,db的部份在此时, 运作是正常的. 

当然,在你要备份之前,假如能先检测资料是否正确,那是最好不过了, 假如有需要,可以把检测的工作,排定在备份工作之前,但是记得,这个检测db 的动作不要排定在 db 高用量的那段时间,深夜无人上线的时段是个不错的选择! 


三.开始备份 

phpbb 讨论区的资料档,主要有两个部份,就是 php 主程式和 db 内容, php 主程式的备份就比较简单,只要把全部档案 tar 起来就行了,就像: 

tar cvfz phpbb2_20020601.tgz phpbb 

(上面的 phpbb 是指 phpbb 的 php 网页程式存放目录.) 

以後有改到 phpbb 网页程式部份再重新备份一次就行,它的内容资料都写在db 内,所以 php 程式档部份异动性应该不大. 

再来就是 mysql db 部份了,预设 mysql 的 db 档案是存在 /var/lib/mysql 内, 以 db 名称为目录,目录内就是该 db 的所有资料,像 phpbb2 这个 db, 就是存在 /var/lib/mysql/phpbb2 内,在备份前,因为怕资料尚未完全写入磁碟, 而且 mysql 会 lock 在使用的 db 档案,所以应该是要先把 mysql 先 shutdown 一下, 整个备份的程序可以下像下面的指令去完成: 

/etc/rc.d/init.d/mysqld stop 
tar cvfz phpbb2_db_20020601.tgz phpbb2 
/etc/rc.d/init.d/mysqld start 

(上面的 phpbb2 是指存放 phpbb2 这个 db 的目录.) 

ok!这样就完成了! (什麽?就这样! 3行就结束了?!) 

对!这样就可以了! 不过要注意的是,怕 db 内每个 tables 间的资料有关关联性, 所以最好是把整个 db 一次备起来,单独只备哪个 tables 的档案,以後回存时, 怕会有资料关联不一致的问题! 

以酷!学园的口水讨论区为例,有21000笔左右的文章加上1200名注册会员,资料库整个 tar 起来大约30几 mb 左右,每天备份,以一周为周期来计算,备份大约只需要(35*7=245) 200 多 mb 左右的空间,一星期的备份烧在一张光碟还够! 

四.如何回存 

phpbb 讨论区的回存,只需把档案解回原来存放网页的路径就可以,用以下指令解开: 

tar xvfz phpbb2_20020601.tgz 

db 发生错误而要回存时,其实也不难,先找出最近一次完整正常的备份,先把现在错误的网页或 db 先更名或 tar 起来,再把好的备份给解开回原来目录位置就行了,需要注意的是, mysql 服务最好也是要先停止,回存完成後再启动服务,回存 db 的整个程序可能像下面: 

/etc/rc.d/init.d/mysqld.stop 
mv phpbb2 phpbb2_error 
tar xvfz phpbb2_db_20020601.tgz 
/etc/rc.d/init.d/mysqld.start 

然後再去测试一下网页及资料库! 看使用上是否正常就行了... 


五.mysql线上备份 

使用像上面的"档案"方式备份是个不错的方法,它最少可以保持该主机某个时间点的完整档案备份,但还是有一些问题需要考虑到,有些主机就不只建立一个 db 而已, 总不能为了备份某个 db 而把整个 mysql 服务停止,备份档案的方式,回存在原主机上一定适用,但假如 mysql 版本升级,或是在那天,该网页空间需迁机移机到别的主机时, 那就没人敢保证备出来的资料档可以用,所以我们可以考虑另一种备份的方式,是使用mysql 本身提供的功能: "mysql data dump",指令是 "mysqldump". 

使用 mysql 的 dump 功能可以把 db 的"结构","资料"或"结构加资料" dump 成文字档, mysqldump 指令提供的弹性很大,你可以选择把整个 db dump 成一个档, 或是每个 table 为一个档,甚至是把结构档和资料分开储存都可以. 

检测酷!学园的 phpbb 资料库後发现,以结构加资料 full dump 成一个档案, 档案的大小大约也是30几mb左右. 在 dump 之前最好多下个 flush-logs 更新 log, 所以整个 dump 的指令如下: 

mysqladmin -uroot -p flush-logs 
mysqldump phpbb2 -uroot -p opt > phpbb2_20020601.sql 

(phpbb2 是 db 名称, opt 是一个使用完整 dump 参数) 

再使用 time 指令去测试执行时间,这个30几 mb 的 db , dump 出来竟只要15秒左右, query 的速度还真是快,假如只是要单独 dump 某个 table 时,只要在上面的指令後, 转出符号 ">" 前加个 table 名称就可以,如只要 phpbb2_users 这个 table 的 dump 时, 只要下: 

mysqldump phpbb2 -uroot -p opt phpbb2_users > phpbb2_users_20020601.sql 

dump 出来的档案是个纯文字档,你可以用 tar 把它压起来,以上面30几 mb 的 db 为例, 大约可以把档案大小压到1/3左右的大小,因为 dump 出是文字档,所有的资料都是以明文 
显示,所以必须注意一下备份档保存的安全性,而且建议备份档最好再另外储存於异地以及其他易於保存的媒体上,像光碟片或磁带,这样的备份才有意义. 


六.mysql线上回存 

若要回存整个资料库,只需将压缩的备份档还原成 dump 的档案,再用下面的指令回存: 

mysql phpbb2 -uroot -p < phpbb2_20020601.sql 

这边需注意的是,若建立备份时是以"opt"或"add-drop-table"为参数时,回存的动作是先将旧的 table 先删除,重建 table 的结构後再把 data 汇入,所以回存後, 所有的资料会回到你当时备份那个时间点,因此在回存资料时,可以考虑把现有错误或不完整的 db 先备份一份下来,以备不时之需,或是拿来比对错误的地方在那里,当然你也可以把资料回存到另一个测试用的 db 内,只要把上面指令的 db 名称改成你的测试用 db 名称即可. 

使用这种回存方式, mysql 服务不需停止,也不会动到其他正在使用的 db ,在一些提供mysql 服务的虚拟主机,可用这种方式作你自己的 db 备份及回存. 

另外,假如你是系统重建或是移机时,切需在新的 mysql 内,新建一个空白 db 後,才行作回存的工作,你可以用下面的指令建立: 

mysql -uroot -p -e "create database phpbb2" 

(上面的phpbb2是你要新建的 db 名称) 

另一种作法,先用 "mysql" 指令进入 "mysql client console", 然後再用: 

create database phpbb2; 

这样就行了,记得尾端要加个 ";" 符号该行指令才会执行.

七.开始排定备份 

知道备份的方法之後,就可以把整个备份的动作作成一个 scirpt ,指定 db 相关参数後, 便可利用 crontab 排定备份的周期和时间,可以把下面的指令加入 crontab 内: 

00 04 * * * /home/dbadmin/backup 

(backup 是 script 的档名) 

排定的时间当然最好是夜间离峰时. 以本文附录提供的 script 作备份规则说明,每日执行备份作业,以一周为一个周期,所以最近的资料是昨天,最久的资料是一星期前,每次备份是将指定的 db full dump 成一个档, 用 tar 压缩後存入指定的路径. 备份档以 db 的名称加上星期来命名,星期的表示为"0" 代表星期日,"1"代表星期一,以此类推. 

目前该 scirpt 一次只能备份一个 db 而已,你可以加以修改以符合你的系统环境及需求. 


八.结语 

目前这个 script 在测试机上测试的效果还不错,以酷!学园讨论区的2万多篇讨论文章, db 总大小有30几 mb, 跑这个 script 大约只需要30几秒就完成,下面是以 time 指令测试 
数次计算的结果: 

[root@demo tmp]# time backup 

real 0m32.788s 
user 0m22.770s 
sys 0m4.610s 
[root@demo tmp]# time backup 

real 0m33.898s 
user 0m24.740s 
sys 0m4.590s 
[root@demo tmp]# time backup 

real 0m32.808s 
user 0m23.710s 
sys 0m4.750s 

测试机的硬体配备是intel celeron 600 + 256mb sdram, 作业系统是cle linux 1.0. 

因为 dump 备份的速度很快,大部份作 mysql 的备份都是这样作的,假如是大型大量的db 环境时,就需要考虑以 incremental 的备份方式,而 mysql 本身也提供这种备份方式, 这种备份方式,一周作一次完整的备份,每天只要作异动作业档(log)的备份就行,在备份的成本上,可以节省备份时间和储存空间. 

完成了备份的工作安排,现在又可以和学园们一起快乐的上网冲浪去了... 


九.参考资料 

1.mysql中文参考手册 
http://cnpa.yzu.edu.tw/~cfc/docs/mysqldoc_big5/manual_toc.html ;

2.mysql man page 

3.study-area - shell和shell script 
http://www.study-area.org/linux/linuxfr1.htm ;


十.附录-备份script原始档 

#!/bin/sh 

# title: mysql backup script 
# created: 2002.06.01 
# current: 2002.06.23 
# contact: duncan lo  
# note: this script just only backup one database! 



# variables define for your server 


# database name 
dbname="phpbb2" 

# database admins name 
dbuser="root" 

# database admins password 
dbpass="password" 

# mysql commands path 
# default: /usr/bin 
binpath="/usr/bin" 

# backup date format 
bakdate=`date +%w` 

# path for backup files save to 
bakpath="/usr/backup/phpbb" 

# temp directorys name 
tmpdir="tmp.db_bak".$bakdate 

# backup filess directory 
bakdir="$dbname"_$bakdate 

# database tables list files name 
tablst="tables_list" 

# backup type 
# 0: all tables in one dump file 
# 1: pre table in one dump file 
baktype="0" 


# script start 



# create backup temp directory 

cd /tmp 
rm -rf $tmpdir 
mkdir $tmpdir 
cd $tmpdir 
mkdir $bakdir 
cd $bakdir 


# create databases table list 

$binpath/mysql $dbname -u$dbuser -p$dbpass -n -e "show tables" > $tablst 


# flush databases log before dump 

$binpath/mysqladmin -u$dbuser -p$dbpass flush-logs 


# choice one type to dump datebase 

case $baktype in 
0) 

# dump database all table in one file 

$binpath/mysqldump $dbname -u$dbuser -p$dbpass opt > $dbname.sql 
;; 
1) 

# dump database pre table in one file 

awk { print binpath"/mysqldump "dbname" -u"dbuser" -p"dbpass" \ 
opt " $1 " > " $1".sql" } \ 
binpath="$binpath" dbname="$dbname" dbuser="$dbuser" dbpass="$dbpass" \ 
$tablst \ 
| /bin/sh 
;; 
*);; 
esac 

cd .. 


# compress backup files 

tar cfz $bakdir.tgz $bakdir 


# move file to backup directory 

mv $bakdir.tgz $bakpath 

cd .. 

# clean temp files and directory 

rm -rf $tmpdir 


# script end 
#

责任编辑:gzu521

网络编程分类
ASP教程
.Net教程
Java教程
PHP教程
数据库基础
ACCESS教程
SQL Server教程
MySQL教程
Oracle教程
分类推荐信息
更多...
大类最新文章
更多...