级别: 初级
软件工程师, IBM Cloudscape Group
2005 年 3 月
确保 Cloudscape 数据的可恢复性。了解 IBM® Cloudscape™ 和 Apache Derby 中备份、恢复和前滚恢复这些特性的工作原理。通过例子,学习如何恢复数据库。
简介
对于任何数据库管理系统来说,备份和恢复功能是确保数据可恢复性的关键。应用程序可能会崩溃,磁盘可能出故障,用户也经常会犯错误,以致损坏数据。由于这些原因,理解数据库管理系统中备份和恢复功能的工作原理,并实施经过精心规划的备份策略,就显得至关重要了。
注意: IBM Cloudscape 是开放源代码 Apache Derby 关系数据库的商业版本。当本文引用 "Derby" 时,它指的是 Cloudscape 和 Apache Derby 中的某一个。 Derby 提供了两种恢复机制:- 一种是使用数据库的全备份,使数据库返回到备份时的状态。
- 另一种机制通过使用全备份,并前滚事务日志,使数据库恢复到最近的状态,这种机制也叫前滚恢复。
SYSCS_UTIL.SYSCS_BACKUP_DATABASE(IN BACKUPDIR VARCHAR(32762)) 系统过程在线执行。为了执行这个备份过程,必须有到所备份数据库的一个连接。 什么是事务日志?
事务日志存储着对数据库作出的更改,当停电或者应用程序崩溃的时候,为了从备份恢复数据库,就需要事务日志。Derby 将事务日志以文件的形式按顺序存放在文件系统中,事务日志文件的文件名都有前缀 log 以及后缀 dat ,另外,前缀的后面还会加上一个数字,每当创建新的事务日志文件时这个数据就会递增,例如 log1.dat、log2.dat,等等。事务日志文件存储在数据库目录下的 log 目录中,或者存储在用户指定的一个位置。
在 Derby 中,在进行备份的时候,那些要求对磁盘进行写操作的语句,例如 insert、delete 和 update,将被阻塞。而那些只需要读磁盘的语句,例如 select,则不会被阻塞。一旦备份完成,系统将让所有被阻塞的语句完成它们的执行。在线备份可能会降低系统的吞吐量和增加用户响应时间,因此,应该尽可能在更新操作比较少的时候执行备份。
清单 1: 通过 IJ 对 salesdb 数据库进行备份
ij>connect 'jdbc:derby:salesdb'; ij>CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE('D:/dbbackups/');
嵌入式应用程序可以使用 JDBC API 来执行备份,而应用程序客户机不需要管理备份。在 Derby 中,所有系统过程也都可以通过 JDBC API 来调用。
清单 2: 使用 JDBC 调用执行备份
private void backUpDatabase(Connection conn) throws SQLException { String sqlstmt = "CALL SYSCS_UTIL.SYSCS_BACKUP_DATABASE(?)"; CallableStatement cs = conn.prepareCall(sqlstmt); cs.setString(1,"D:/dbbackups/"); cs.execute(); cs.close(); }
该备份在指定的备份位置创建一个目录,目录名与数据库名相同。这个目录包含数据库目录中的所有文件/目录。数据库目录通常有一个数据目录(seg0)来存储用于表和索引的所有数据文件,有一个事务日志目录(log)来存储所有的事务日志文件,还有一个 service.properties 文件,该文件包含用于启动数据库的信息。
离线备份
当系统离线时,可以使用操作系统命令复制整个数据库目录。如果事务日志目录与数据库目录有不同之处,那么应确保同时复制了事务日志目录。在执行恢复操作时,需要使用事务日志使数据库处于一致状态。
也可以在数据库系统没有离线的情况下执行离线备份,方法是当复制数据库目录的时候冻结系统(阻塞所有写操作)。这里所用的系统过程是 SYSCS_UTIL.SYSCS_FREEZE_DATABASE() 。一旦复制完成,就可以使用 SYSCS_UTIL.SYSCS_UNFREEZE_DATABASE() 过程解冻系统(允许写操作)。该过程调用将把系统设置回正常状态。
使用备份进行恢复
数据库的在线/离线备份镜像可用于将数据库恢复到备份时所处的状态。通过在到数据库的第一个连接的连接 URL 中指定属性 restoreFrom=<backup path> ,可以从备份中恢复数据库。注意,backup path 必须包括备份中的数据库名,而不只是包含备份路径。数据库将被恢复到连接 URL 中指定的位置,或者,如果在连接 URL 中没有指定路径,则恢复到当前 derby.system.home 位置。如果在当前数据库位置已经有一个具有相同名称的数据库,那么首先会删除这个数据库,然后再从备份恢复数据库。
清单 3: 从备份恢复 salesdb 数据库:
String dbURL = "jdbc:derby:salesdb;restoreFrom=D:/dbbackups/salesdb"; Connection conn = DriverManager.getConnection(dbURL);
默认情况下,事务日志将被复制回当初备份时所在位置。假如存放事务日志的磁盘有问题,也可以修改事务日志的存放位置。为此,可以指定连接 URL 属性 logDevice=<log dir> 。
String dbURL = "jdbc:derby:salesdb;restoreFrom=D:/dbbackups/saleddb;logDevice=E:/salesdbLog"; Connection conn = DriverManager.getConnection(dbURL);
转移或克隆数据库
在 Derby 中,将数据库从一个系统转移到另一个系统,克隆测试用的数据库,以及增大数据库,这些都很容易。在第一次连接到数据库时,通过使用连接 URL 属性 createFrom=<backup path> ,可以从备份重建数据库。数据库将被创建在连接 URL 中指定的位置上,或者,如果连接 URL 中没有指定位置,则创建在当前 derby.system.home 位置上。默认情况下,事务日志存放在数据库目录下,可以通过在连接 URL 中指定 logDevice=<log dir > 属性来更改事务日志位置。
String dbURL = "jdbc:derby:salesdb;createFrom=D:/dbbackups/salesdb;logDevice=E:/salesdbLog"; Connection conn = DriverManager.getConnection(dbURL);
对于 Derby,可以从任何支持 Java 的操作系统或硬件上重建数据库。新的系统不一定需要与备份时数据库所在的系统拥有相同的配置。
前滚恢复
仅仅使用在线/离线备份镜像,可以将数据库恢复到采取备份时所处的状态。但是,通过使用前滚恢复,可以将数据库恢复到最近的状态。前滚恢复首先从备份做一次恢复,然后应用自进行备份起记录的所有事务日






