设为首页 加入收藏

TOP

Sqlite数据库解析以及恢复(一)(一)
2015-11-21 01:31:23 来源: 作者: 【 】 浏览:0
Tags:Sqlite 数据库 解析 以及 恢复

sqlite 数据库文件用处非常广泛,是一种轻量型的本地数据库。在电脑上以文件的形式存在。当删除记录的时候会修改本地的文件,由于考虑到效率的问题,当删除一条记录的时候,这条记录的二进制内容大部分都还保留着,仅仅是修改了某些标志位。这就使得sqlite 数据库在删除的时候可以被恢复。我们需要解析sqlite 的物理结构,然后分析删除的数据,再通过统计分析等等手段把已经删除的数据分段解析出来。所以第一个是必须要了解sqlite 的物理结构。网上有很多技术型的文章,非常的枯燥。我这里说一下我在开发中感受

--- 数据库中的表信息在哪里

大家都知道既然是数据库,肯定有表信息。比如我们创建表的语句

create table student(id int,name text) 这些信息当然也存在这个文件里面了。所以第一步我们得找到存储表信息的。

sqlite 存储数据是用页来存储的。 一个db 文件最大的单位是页,是由很多个页组成的。每一个页的大小相同,并且在创建DB 的时候就已经固定下来了,所有的数据都存储在页上面。然后根据不同的数据类型,页的形式也不一样。每一个页都有一个号码,一开始的页是1,后面依次累加2,3.... 。数据库的基本信息就存储在第1页上,当然如果信息比较多的话,那还会占用其他的页,因为页的大小是固定的,装不下的话那就自然要到另外的页了。第1页的前100字节保存了数据库的信息。我们来看看前100字节

#pragma pack(1) // 1字节对齐
struct SQLiteDataHead
{
public:
char identify[16]; // 0
private:
//这个字段需要试用4字节来放
unsigned short pageSize; // 页大小 16 3007000 版本之后,如果是1 代表 65536,放不下了
public:
char formatVersionWrite; // 文件格式版本(写) 18
char formatVersionRead; // 文件格式版本(读) 19
char reserver1; // Bytes of unused "reserved" space at the end of each page. Usually 0. 20
char maxPayloadFraction; //Maximum embedded payload fraction. Must be 64. 21
char minPayloadFraction;//Minimum embedded payload fraction. Must be 32. 22
char leafPayloadFraction;//Leaf payload fraction. Must be 32. 23
int fileChangeCount; // File change counter. 24
int databasePagesSize;//Size of the database file in pages. The "in-header database size". 28
int freeBlockHead; // Page number of the first freelist trunk page.. 32
int freeBlockNumber; // 空闲块数量 36
int schemaVersion; // schema版本 40
int fileFormatSchema; // The schema format number. Supported schema formats are 1, 2, 3, and 4. 44
int cacheSize; // Default page cache size. 48
int largestRootPage; // The page number of the largest root b-tree page when in auto-vacuum or incremental-vacuum modes, or zero otherwise. 52
int characterCode; // The database text encoding. A value of 1 means UTF-8. A value of 2 means UTF-16le. A value of 3 means UTF-16be. 56
int userVersion; // The "user version" as read and set by the user_version pragma. 60
int incrementVacuumMode; // True (non-zero) for incremental-vacuum mode. False (zero) otherwise. 64
int userAPPID; //The "Application ID" set by PRAGMA application_id. 68
char reserver2[20]; //Reserved for expansion. Must be zero. 72
int versionValid; //The version-valid-for number. 92
int sqlVersionNumber;//SQLITE_VERSION_NUMBER 96


//这个必须要放在最后面
int extPageSize;
void Read(CBinaryBufferReader& binaryReader)
{
binaryReader.Read((byte*)this,100);
Swap();
}
private:
void Swap()
{
endian_swap(pageSize);
endian_swap(fileChangeCount);
endian_swap(databasePagesSize);
endian_swap(freeBlockHead);
endian_swap(freeBlockNumber);
endian_swap(schemaVersion);
endian_swap(fileFormatSchema);
endian_swap(cacheSize);
endian_swap(largestRootPage);
endian_swap(characterCode);
endian_swap(userVersion);
endian_swap(incrementVacuumMode);
endian_swap(userAPPID);
endian_swap(versionValid);
endian_swap(sqlVersionNumber);
extPageSize = pageSize;
// For SQLite versions 3.7.0.1 and earlier, this value is interpreted as a big-endian integer and must be a power of two between 512 and 32768, inclusive.
//Beginning with SQLite version 3.7.1, a page size of 65536 bytes is supported
if ((sqlVersionNumber>= 30070010) && (extPageSize == 1))
{
extPageSize = 6553
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇postgresql按日期范围查询 下一篇MongoDB初探系列之二:认识MongoD..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: