1. 数据库故障恢复概述
数据库的可恢复性:
-
DBMS能把数据库从被破坏、不正确的状态、恢复到最近一个正确的状态。
恢复管理任务的种类:
-
一是在未发生故障而系统正常运行时,采取一些必要措施为恢复工作打基础。
-
二是在发生故障后进行恢复处理。
转储和建立日志:
-
周期地(比如一周一次)对整个数据进行复制,转储到另一个磁盘或磁带一类的存储介质上。
-
建立日志数据库。记录事务的开始、结束标志,记录事务对数据库的每一次插入、删除和修改前后的值,写到日志库中,以便有案可查。
数据库系统基本的共同恢复方法:
-
优先写日志。
任何对数据库中数据元素的变更都必须先写入日志;将变更的数据写入磁盘前,日志中的所有相关记录必须写入磁盘。
-
REDO(重做)已提交事务的操作。
当发生故障而使系统崩溃后,对那些已提交但其结果尚未真写到磁盘上去的事务操作要重做,使数据库恢复到崩溃时所处理状态。
-
UNDO(撤销)未提交事务的操作。
系统崩溃时,那些未提交事务操作所产生的数据库变更必须恢复到原状,使数据库只反映已提交事务的操作结果。
2. 故障分类
2.1 事务故障
可预期的事务故障:
-
即在程序中可以预先估计到的错误,可由程序本身解决。
非预期的事务故障:
-
事务内部更多的故障是非预期的,不能由应用程序处理。
-
非预期的情况:
-
运算溢出;
-
并发事务发生死锁而被选中撤销的事务;
-
违反某些完整性限制而被终止。
-
-
解决方案:
作事务撤消(UNDO)处理。
2.2 系统故障
系统故障指造成系统停止运转的任何事件,使得系统要重新启动。
系统故障的情况:
-
硬件错误(CPU故障);
-
操作系统故障;
-
系统断电。
系统故障可能导致事务的两种情况:
-
未完成的事务:
系统重启后作撤销(UNDO)处理。
-
已提交的事务,但更新还留在内存缓冲区:
系统重启后作重作(REDO)处理。
2.3 介质故障
介质故障也称为硬故障,指外存故障,破坏性最大。
介质故障的情况:
-
磁盘损坏;
-
磁头碰撞;
-
瞬时强磁场干扰;
-
地震、火灾、爆炸等自然灾害造成外存的严重毁坏。
解决方案:
-
装入最新的数据库后备副本。
-
装入相应的日志文件副本,重做REDO已完成的事务。
3. 恢复的实现技术
3.1 数据备份
-
海量转储:每次复制整个数据库。
-
增量转储:每次只转储上次转储后被更新过的数据。
-
动态转储:指转储期间允许对数据库进行存取或修改的转储操作。
-
静态转储:指在系统中无运行事务时进行的转储操作。
3.2 登记日志文件
日志记录类型:
-
关于事务活动的记录。
-
事务的唯一标识符。
-
事务的输入数据。
-
事务的开始。
-
事务的提交。但它所作的变更不一定写到磁盘上。
-
事务的夭折。要保证事务的任何变更不能出现在磁盘上。
-
事务完全结束。仅有COMMIT或ABORT日志记录是不够的,因为此后还有一些活动必须要完成,如收回事务所占有的工作缓冲区等。
-
事务在数据对象上进行的操作。如插入、删除、读取、修改操作。
-
-
关于数据库变更的记录。
-
更新前数据的旧值(对于插入操作而言,此项为空值)。
-
更新后数据的新值(对于删除操作而言,此项为空值)。
-
登记日志文件:
-
登记的次序严格按并发事务执行的时间次序。
-
必须先写日志文件,后写数据库。
4. 恢复策略
4.1 事务故障的恢复
引起事务故障原因:
-
事务无法执行而中止。
-
用户主动撤销事务。
-
因系统调度差错而中止。
事务故障恢复步骤:
-
从后向前的扫描日志,找到故障事务。
-
撤消该事务已做的所有更新操作。
-
从正在运行的事务列表中删除该事务,释放该事务所占资源
4.2 系统故障的恢复
系统故障导致数据不一致状态的原因:
-
未提交事务对数据库的更新已写入数据库。
-
已提交事务对数据库的更新还留在内存缓冲区中,没来得及写入数据库
系统故障恢复步骤:
-
重新启动OS和DBMS。
-
从前向后扫描日志,将已提交的事务记入重做(REDO)队列。未提交的事务记入撤销(UNDO)队列。
-
对撤销队列中的各个事务进行撤销回退操作。
-
对重做队列中的每个事务重新执行日志文件登记的操作。
4.3 介质故障的恢复
介质故障恢复步骤:
-
重新启动系统。
-
装入最近的数据库后备副本,使数据库恢复到最近一次转储时的一致性数据库状态。
-
装入有关的日志副本,重做(REDO)已提交的事务。
-
介质故障的恢复需要DBA的干预
-
DBA的任务是重装最近转储的数据库后备副本和有关的日志副本,发出系统恢复的命令
-
具体的恢复操作仍由DBMS来完成。
5. 具有检查点的恢复技术
利用日志技术进行数据库恢复时,恢复子系统必须查阅日志,确定哪些事务需要REDO,哪些事务需要UNDO。
-
查阅日志从头检查所有日志记录。
利用日志技术进行数据库恢复的缺点:
-
搜索整个日志将耗费大量时间。
-
很多需要REDO处理的事务已将更新操作结果写到数据库中,而恢复子系统又重新执行了这些操作,浪费大量时间。
引入检查点机制以解决上述问题。
引入检查点机制数据的恢复过程:
-
从故障发生前的最后一个检查点处开始正向扫描日志文件;
-
将提交的事务放入REDO队列,未提交的事务放入UNDO队列;
-
对队列中每个事务执行REDO或UNDO处理。
6. MySQL的备份与恢复
6.1 数据库的备份与恢复
使用mysqldump命令备份数据:
-
备份单个数据库或表:
mysqldump -u 用户名 -h 主机名 -p 密码 数据库名 [表名 [表名…]] >备份文件名.sql
-
备份多个数据库:
mysqldump -u 用户名 -h 主机名 -p 密码 --databases 数据库名 数据库名 … >备份文件名.sql
-
备份所有数据库:
mysqldump -u 用户名 -h 主机名 -p 密码 --all-databases >备份文件名.sql
使用mysql命令恢复数据:
mysql -u 用户名 -p 数据库名 < 备份文件名.sql
执行mysql命令前,必须在MySQL服务器中创建命令中的数据库。
6.2 表数据的导出与导入
-
FIELDS后的TERMINATED BY '字符':
设置字段之间的分隔字符,可以为单个或多个字符,默认是制表符'\t'。
-
[OPTIONALLY] ENCLOSED BY '字符':
设置字段的包围字符,只能为单个字符。如果使用OPTIONALLY选项,只在CHAR和VARCAHR等字符串类型的字段值两边添加字段包围符。
-
ESCAPED BY '字符':
设置如何写入或读取特殊字符,只能为单个字符,即设置转义字符,默认值为''。
-
STARTING BY '字符串':
设置每行开头的字符,可以为单个或多个字符,默认情况下不使用任何字符。
-
LINES后的TERMINATED BY '字符串':
设置每行的结束符,可以为单个或多个字符,默认值是'\n'。
FIELDS和LINES两个子句都是可选的,如果两个都被指定了,则FIELDS就必须位于LINES前面。
由于MySQL默认对导出的目录有权限限制,在使用SELECT …INTO OUTFILE语句进行导出时,导出的文本文件的路径需要指定为MySQL的secure_file_priv参数所指定的位置。
使用LOAD DATA INFILE语句导入表数据:
LOAD DATA INFILE '文本文件' INTO TABLE 表名 [FIELDS [TERMINATED BY '字符'][[OPTIONALLY] ENCLOSED BY '字符'][ESCAPED BY '字符'] ] [LINES [STARTING BY '字符串'][TERMINATED BY '字符串'] ] [IGNORE n LINES];
-
FIELDS和LINES选项功能与“
SELECT …INTO OUTFILE
”语句中选项的功能相同。 -
IGNORE n LINES:忽略文本文件中的前n条记录。
-
使用“
SELECT …INTO OUTFILE
”语句将数据从一个数据库表导出到一个文本文件,再使用“LOAD DATA INFILE
”语句从文本文件中将数据导入到数据库表时,两个命令的选项参数必须匹配,否则“LOAD DATA INFILE
”语句无法解析文本文件的内容。
使用mysqldump命令导出表数据:
mysqldump -u root -p -T "目标路径" 数据库名 表名 [--fields-terminated-by=字符] [--fields-enclose-by=字符] [--fields-optionally-enclosed-by=字符] [--fields-escaped-by=字符] [--lines-terminated-by=字符串]
-
只有指定
-T
参数,才能导出纯文本文件。
-
导出生成的文件有两个,一个是包含创建表的
CREATE TABLE
语句的“表名.sql
”文件,一个是包含其数据的“表名.txt
”文件。 -
目标路径必须是MySQL的secure_file_priv参数所指定的位置。
-
各选项功能对应“
SELECT …INTO OUTFILE
”语句中的各对应项功能。
使用mysqlimport命令导入表数据:
mysqlimport -u root -p 数据库名 "文本文件名.txt"[--fields-terminated-by=字符][--fields-enclose-by=字符][--fields-optionally-enclosed-by=字符][--fields-escaped-by=字符][--lines-terminated-by=字符串][--ignore-lines=n]
-
各选项功能对应“
LOAD DATA INFILE
”语句中的各对应项功能。 -
--ignore-lines=n
:忽略文本文件的前n行。
6.3 使用二进制日志文件恢复数据
错误日志:
-
记录MySQL服务的启动、运行或停止服务时出现的问题。
查询日志:
-
记录建立的客户端连接和执行的语句。
二进制日志:
-
记录所有更改数据的语句,可以用于数据恢复。
慢查询日志:
-
记录所有执行时间超过long_query_time的所有查询或不使用索引的查询。
查看二进制日志开启状态:
SHOW GLOBAL VARIABLES;
查看二进制日志:
SHOW BINARY LOGS;
使用二进制日志恢复数据库:
mysqlbinlog [option] "日志文件" | mysql -u root -p
-
option选项:
-
start-datetime
:指定恢复数据库的起始时间点。
-
stop-datetime
:指定恢复数据库的结束时间点。
-