存档
之前就已经研发成功了能够从Sybase SQL Anywhere的DB文件中恢复数据的工具,现在公布一下。
此工具支持ASA v5.0,v6.0,v7.0,v8.0,v9.0,v10.0,v11.0,v12.0等版本。恢复Sybase SQL Anywhere的工具在国内应该算首创。
本工具的应用场景:
1.因为物理磁盘故障、操作系统、系统软件方面或者掉电等等原因导致的Sybase SQL Anywhere数据库无法打开的情况;
2.误操作,包括truncate table,drop table,不正确的where条件导致的误删除等;
Sybase SQL Anywhere无法打开时,比较常见的错误是:Assertion failed。
如:
1、Internal database error *** ERROR *** Assertion failed:201819 (8.0.1.2600) Checkpoint log: invalid bitmap page -- transaction rolled back
2、Internal database error *** ERROR *** Assertion failed:201819 (8.0.1.2600) Page number on page does not match page requested -- transaction rolled back
3、Internal database error *** ERROR *** Assertion failed:200502 (9.0.2.2451) Checksum failure on page 23 -- transaction rolled back
4、File is shorter than expected
5、Internal database error *** ERROR *** Assertion failed: 201116 Invalid free list index page found while processing checkpoint log -- transaction rolled back
6、*** ERROR *** Assertion failed: 51901 Page for requested record not a table page or record not present on page
7、*** ERROR *** Assertion failed: 201417 (7.0.4.3541) Invalid count or free space offset detected on a table page
8、Internal database error *** ERROR *** Assertion failed: 201425 (8.0.3.5594) Invalid count or free space offset detected on a free list page -- transaction rolled back.
9、Internal database error *** ERROR *** Assertion failed: 100702 (8.0.1.2600) Unable to modify indexes for a row referenced in rollback log -- transaction rolled back
等等。报错的同时可能会在db文件相同目录下生成assert.dmp文件。
关于Assertion Failure,大家可以参考Sybase官方技术文章:I've got an assertion! What should I do?
本博中有两篇文章介绍Sybase SQL Anywhere数据库db文件的物理存储结构的分析过程,可以参考一下:
本人不提供此工具的下载。如想了解使用本工具恢复损坏db文件的过程,可以观看下面的视频:
-- 创建测试数据库
CREATE DATABASE Db
GO
-- 对数据库进行备份
BACKUP DATABASE Db TO DISK = ' c:\db.bak ' WITH FORMAT
GO
-- 创建测试表
CREATE TABLE Db.dbo.TB_test(ID int )
-- 延时1秒钟,再进行后面的操作(这是由于SQL Server的时间精度最大为百分之三秒,不延时的话,可能会导致还原到时间点的操作失败)
WAITFOR DELAY ' 00:00:01 '
GO
-- 假设我们现在误操作删除了 Db.dbo.TB_test 这个表
DROP TABLE Db.dbo.TB_test
-- 保存删除表的时间
SELECT dt = GETDATE () INTO #
GO
-- 在删除操作后,发现不应该删除表 Db.dbo.TB_test
-- 下面演示了如何恢复这个误删除的表 Db.dbo.TB_test
-- 首先,备份事务日志(使用事务日志才能还原到指定的时间点)
BACKUP LOG Db TO DISK = ' c:\db_log.bak ' WITH FORMAT
GO
-- 接下来,我们要先还原完全备份(还原日志必须在还原完全备份的基础上进行)
RESTORE DATABASE Db FROM DISK = ' c:\db.bak ' WITH REPLACE ,NORECOVERY
GO
-- 将事务日志还原到删除操作前(这里的时间对应上面的删除时间,并比删除时间略早
DECLARE @dt datetime
SELECT @dt = DATEADD (ms, - 20 ,dt) FROM # -- 获取比表被删除的时间略早的时间
RESTORE LOG Db FROM DISK = ' c:\db_log.bak ' WITH RECOVERY,STOPAT = @dt
GO
-- 查询一下,看表是否恢复
SELECT * FROM Db.dbo.TB_test
/* --结果:
ID
-----------
(所影响的行数为 0 行)
-- */
-- 测试成功
GO
-- 最后删除我们做的测试环境
DROP DATABASE Db
DROP TABLE #