一种数据恢复的方法、装置及Android设备与流程

文档序号:11829268阅读:291来源:国知局
本发明属于数据处理
技术领域
:,尤其涉及一种数据恢复的方法、装置及Android设备。
背景技术
::自2011年以来,国内外手机市场以安卓Android手机占有率最高。Android系统中,数据存储都是采用SQLite数据库。大多数的传统方法采用直接调用Android框架层的应用程序编程接口(ApplicationProgrammingInterface,API)来提取Android设备中存储的信息,该方法简便易操作,但不能恢复Android设备中已删除的数据。而现有方法,可以恢复误操作或故意删除的数据信息,但各有其优缺点。例如,芯片拆除恢复法,恢复率最高,但要求技术高、实现难度大;暴力估算法,可很好地恢复已删除的数据,但只可对整个存储单元整体解析后恢复提取,当删除数据之前所在页面部分或者完全被新写入的数据覆盖时,无法恢复已删除的数据。技术实现要素:本发明实施例提供了一种数据恢复的方法、装置及Android设备,旨在解决现有技术提供的数据恢复的方法,实现难度大,或者当删除数据之前所在页面部分或者完全被新写入的数据覆盖时,无法恢复已删除的数据的问题。一方面,提供一种数据恢复的方法,所述方法包括:判断是否满足预设的检查点条件,所述的检查点条件在预写日志WAL文件满足清空条件之前;如果预设的检查点条件成立,则判断第一数据库是否有删除记录,如果是, 则根据所述WAL文件恢复已删除的记录至第二数据库的表中;在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库中。进一步地,在所述的步骤在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库的表中之前还包括:如果预设的检查点条件成立,则判断第一数据库是否有修改记录,如果是,则根据所述WAL文件恢复已修改的记录至第二数据库的表中。进一步地,所述判断第一数据库是否有删除记录,包括:获取第一数据库变化前的B+tree叶子页键值对列表大小;监听第一数据库中的数据是否发生变化;当监听到第一数据库中的数据发生变化时,获取第一数据库变化后的B+tree叶子页键值对列表大小;将第一数据库变化前后获取到的B+tree叶子页键值对列表大小进行比较,如果第一数据库变化后的B+tree叶子页键值对列表大小小于第一数据库变化前的B+tree叶子页键值对列表大小,则判定第一数据库有删除记录。进一步地,所述监听第一数据库中的数据是否发生变化,包括:通过函数ContentResolver.registerContentObserver()注册需要监听的第一数据库;当监听到回调函数onChange()被执行时,判定所监听的第一数据库中的数据发生变化。进一步地,所述获取第一数据库变化前后的B+tree叶子页键值对列表大小,包括:获取第一数据库文件,所述第一数据库文件是所述第一数据库的表对应的数据库文件;获取所述第一数据库文件中的系统表;根据第一数据库表的表名在所述系统表中查询,得到第一数据库表的根页 编号;根据所述根页编号定位到相应的根页后,分析Btree中所有的页节点,根据页头中的页类型标志查找到第一数据库表的B+tree叶子页;获取所述B+tree叶子页的键值对列表大小。进一步地,所述获取所述B+tree叶子页的键值对列表大小,包括:创建一个指向所述B+tree叶子页的游标;获取所述游标从第一条记录移动到最后一条记录所迭代的次数,将所述迭代的次数作为所述B+tree叶子页的键值对列表大小。进一步地,所述系统表中包括第一数据库表的表名和建立所述第一数据库表的语句,所述根据所述WAL文件恢复已删除的记录至第二数据库的表中,包括:根据所述第一数据库表的表名、所述建立所述第一数据库表的语句以及所述WAL日志文件,构建第二数据库文件,所述第二数据库文件是所述第二数据库的表对应的数据库文件;对比第一数据库文件和所述第二数据库文件,根据所述第二数据库文件找到第一数据库文件中已删除的记录,并将所述第二数据库的表中在第一数据库文件中存储在记录删除。另一方面,提供一种数据恢复的装置,所述装置包括:第一判断单元,用于判断是否满足预设的检查点条件,所述的检查点条件在预写日志WAL文件满足清空条件之前;第二判断单元,用于如果预设的检查点条件成立,则判断第一数据库是否有删除记录;第一恢复单元,用于如果第一数据库有删除记录,则根据所述WAL文件恢复已删除的记录至第二数据库的表中;第二恢复单元,用于在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库中。进一步地,所述装置,还包括:第三恢复单元,用于如果预设的检查点条件成立,则判断第一数据库是否有修改记录,如果是,则根据所述WAL文件恢复已修改的记录至第二数据库的表中。进一步地,所述第二判断单元,包括:第一获取模块,用于获取第一数据库变化前的B+tree叶子页键值对列表大小;监听模块,用于监听第一数据库中的数据是否发生变化;第二获取模块,用于当监听到第一数据库中的数据发生变化时,获取第一数据库变化后的B+tree叶子页键值对列表大小;判断模块,用于将第一数据库变化前后获取到的B+tree叶子页键值对列表大小进行比较,如果第一数据库变化后的B+tree叶子页键值对列表大小小于第一数据库变化前的B+tree叶子页键值对列表大小,则判定第一数据库有删除记录。进一步地,所述监听模块,包括:注册子模块,用于通过函数ContentResolver.registerContentObserver()注册需要监听的第一数据库;判断子模块,用于当监听到回调函数onChange()被执行时,判定所监听的第一数据库中的数据发生变化。进一步地,所述获取模块,包括:第一获取子模块,用于获取第一数据库文件,所述第一数据库文件是所述第一数据库的表对应的数据库文件;第二获取子模块,用于获取所述第一数据库文件中的系统表;第三获取子模块,用于根据第一数据库表的表名在所述系统表中查询,得到第一数据库表的根页编号;第四获取子模块,用于根据所述根页编号定位到相应的根页后,分析Btree 中所有的页节点,根据页头中的页类型标志查找到第一数据库表的B+tree叶子页;第五获取子模块,用于获取所述B+tree叶子页的键值对列表大小。进一步地,所述第五获取子模块,包括:创建微模块,用于创建一个指向所述B+tree叶子页的游标;获取微模块,用于获取所述游标从第一条记录移动到最后一条记录所迭代的次数,将所述迭代的次数作为所述B+tree叶子页的键值对列表大小。进一步地,所述系统表中包括第一数据库表的表名和建立所述第一数据库表的语句,所述第一恢复单元,包括:构建模块,用于根据所述第一数据库表的表名、所述建立所述第一数据库表的语句以及所述WAL日志文件,构建第二数据库文件,所述第二数据库文件是所述第二数据库的表对应的数据库文件;恢复模块,用于对比第一数据库文件和所述第二数据库文件,根据所述第二数据库文件找到第一数据库文件中已删除的记录,并将所述第二数据库的表中在第一数据库文件中存储在记录删除。再一方面,提供一种Android设备,所述Android设备包括如上所述的数据恢复的装置。在本发明实施例,在预写日志WAL文件满足预设的检查点条件之前,也就是在WAL文件清空之前,发现第一数据库有删除记录,则先根据WAL文件,将WAL文件中关于删除记录的数据及时恢复至第二数据库的表中,在确定需要数据恢复时候,再根据所述的第二数据库恢复数据至第一数据库中。可以先于WAL日志文件清空前将WAL文件中关于删除记录的数据恢复,从而避免因WAL文件已清空且有数据删除的情况下,无法恢复该删除数据的问题。并且,相比现有的数据恢复的方法,实现简单,且不会出现当删除数据之前所在页面部分或者完全被新写入的数据覆盖时,无法恢复已删除的数据的问题。附图说明图1是本发明实施例一提供的数据恢复的方法的实现流程图;图2是本发明实施例一中提供的判断第一数据库是否有删除记录的实现流程图;图3是本发明实施例一中提供的获取第一数据库更新前后B+tree叶子叶键值对列表大小的实现流程图;图4是本发明实施例二提供的数据恢复的装置的结构框图。具体实施方式为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。在本发明实施例中,判断预写日志WAL文件是否满足预设的检查点条件;如果否,则判断第一数据库是否有删除记录;如果是,则先根据所述WAL文件恢复已删除的记录至第二数据库的表中,在确定需要数据恢复时候,再根据所述的第二数据库恢复数据至第一数据库中。以下结合具体实施例对本发明的实现进行详细描述:实施例一图1示出了本发明实施例一提供的数据恢复的方法的实现流程,详述如下:在步骤S101中,判断是否满足预设的检查点条件,所述的检查点条件在预写日志WAL文件满足清空条件之前,如果预设的检查点条件成立,则执行步骤S102,否则,执行步骤S105。在本发明实施例中,同步预写日志(WriteAheadLog,WAL)文件和数据库文件的行为被称为检查点checkpoint,它由SQLite自动执行,默认是在WAL文件积累到1000页修改的时候;当然,在适当的时候,也可以手动执行 checkpoint,SQLite提供了相关的接口。若预设的检查点条件是WAL文件积累到1000页,则检测到WAL文件积累到1000页时,系统会将WAL文件中的内容修改到数据库文件中。其中,SQLite在3.7.0之前的版本中采用回滚日志文件保证事务提交的原子性,而SQLite3.7.0版本之后,SQLite提供了WAL,WAL是用于实现原子事务的一种机制。目前,Android平台集成的SQLite版本都是基于3.7.0以上的,可在shell终端通过sqlite3命令查询,如下:root@android:/#sqlite3SQLiteversion3.7.112012-03-2011:35:50Enter".help"forinstructionsEnterSQLstatementsterminatedwitha";"。WAL工作原理如下:传统的操作模式中,SQLite使用回滚日志,从SQL状态集中捕获预修改数据,然后修改数据库文件。使用WAL时,将反过来处理。取代写入原始信息模式,预修改数据放入回滚日志,利用WAL放弃原始未关联数据库文件的数据。WAL用来记录给定事务导致的数据变化。一个提交操作变为特殊的写进WAL的记录,以表明前面的修改确实完成,并实现了原子性(Atomicity,ACID)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)原则。数据库文件和日志文件之间的角色变化会立刻改变事务的动态性能。不用在数据库文件中竞争相同的数据库页,在WAL中,多事务可以同时记录它们数据的改变,并能够持续从数据库中读取未改变的数据。在引入WAL机制之前,SQLite使用rollbackjournal机制实现原子事务。rollbackjournal机制的原理是:在修改数据库文件中的数据之前,先将修改所在分页中的数据备份在另外一个地方,然后才将修改写入到数据库文件中;如果事务失败,则将备份数据拷贝回来,撤销修改;如果事务成功,则删除备份数据,提交修改。WAL机制的原理是:修改并不直接写入到数据库文件中,而是写入到另外一个称为WAL的文件中;如果事务失败,WAL中的记录会被忽略,撤销修改;如果事务成功,它将在随后的某个时间被写回到数据库文件中,提交修改。一个正在写入且不断增长的WAL文件的没有结束的数据变化流,无法扩展或无法承担难以预测的文件系统故障。WAL使用检查点函数将修改写回数据库。这个处理自动进行,所以开发者无须关注自己如何管理检查点和数据库写回处理。默认情况下,当WAL文件发现有1000页被修改时,将调用检查点。可修改检查点执行标准的参数以适应不同的操作场合。在读的时候,SQLite将在WAL文件中搜索,找到最后一个写入点,记住它,并忽略在此之后的写入点(这保证了读写和读读可以并行执行);随后,它确定所要读的数据所在页是否在WAL文件中,如果在,则读WAL文件中的数据,如果不在,则直接读数据库文件中的数据。在写的时候,SQLite将数据写入到WAL文件中即可,但是必须保证独占写入,因此不同进程的写与写之间不能并行执行。WAL在实现的过程中,使用了共享内存技术,因此,所有的读写进程必须在同一个机器上,否则,无法保证数据一致性。WAL优点:1.读和写可以完全地并发执行,不会互相阻塞(但是写之间仍然不能并发)。2.WAL在大多数情况下,拥有更好的性能(因为无需每次写入时都要写两个文件)。3.磁盘I/O行为更容易被预测。WAL缺点:1.访问数据库的所有程序必须在同一主机上,且支持共享内存技术。2.每个数据库现在对应3个文件:<xxx>.db,<xxx>-wal,<xxx>-shm。3.当写入数据达到GB级的时候,数据库性能将下降。4.3.7.0之前的SQLite无法识别启用了WAL机制的数据库文件。一般基于Android平台的应用开发基本都满足上面缺点中条件,不会因为开启WAL带来额外的性能影响,反而会带来如上所述的优点。激活和配置WAL的方法:同其他编译指示PRAGMA不同,启用WAL是数据库级持久性改变。这意味着,可以在程序里启动WAL,或从SQLite命令shell启动,并且之后其他程序将在WAL模式下使用数据库。设置PRAGMAjournal_mode=WAL是激活WAL的必要命令,该编译指示的调用将以字符串形式返回数据库最终的日志模式。SQLiteversion3.7.112012-03-2011:35:50Enter".help"forinstructionsEnterSQLstatementsterminatedwitha";"sqlite>PRAGMAjournal_mode=WAL;walsqlite>如果WAL改变成功,将返回字符串wal,如上所示。如果由于某种原因失败了,诸如底层主机不支持必要的共享内存要求,日志模式将不会改变。例如,在默认的数据库中,这意味着命令将返回字符串delete,即回滚日志依然有效。在Android系统应用开发过程中,使用数据库之前都需要借助SQLiteDatabaseopenDatabase()函数来连接数据库,而在openDatabase()函数中利用setJournalMode()函数设置日志模式。查看Android源码SQLiteDatabase.java文件,发现系统默认开启的是回滚日志模式,即sqliteDatabase.setJournalMode(path,"TRUNCATE"),而上面的开启WAL模式命令则需要手动执行,可以通过修改setJournalMode()函数,设置系统开机默认日志模式为WAL,即setJournalMode(path,"WAL")。其中,文件SQLiteDatabase.java路径是:android_frameworks_base/core/java/android/database/sqlite/SQLiteDatabase.java。在步骤S102中,判断第一数据库是否有删除记录,如果是,则执行步骤S103。在本发明实施例中,如图2所示,通过以下步骤判断第一数据库是否有删除记录:步骤1、获取第一数据库变化前的B+tree叶子页键值对列表大小。步骤2、监听第一数据库中的数据是否发生变化。步骤3、当监听到第一数据库中的数据发生变化时,获取第一数据库变化后的B+tree叶子页键值对列表大小。步骤4、将第一数据库变化前后获取到的B+tree叶子页键值对列表大小进行比较,如果第一数据库变化后的B+tree叶子页键值对列表大小小于第一数据库变化前的B+tree叶子页键值对列表大小,则判定第一数据库有删除记录。具体的,通过下述步骤监听第一数据库中的数据是否发生变化:步骤21、通过函数ContentResolver.registerContentObserver()注册需要监听的第一数据库。步骤22、当监听到回调函数onChange()被执行时,判定所监听的第一数据库中的数据发生变化。具体的,通过安卓Android系统中的函数ContentResolver.registerContentObserver(Uriuri,booleannotifyForDescendents,ContentObserverobserver)注册需要监听的第一数据库,注册成功后,可以监听到第一数据库中的数据的变化。其中参数uri是Uri类型,是需要监听的第一数据库的Uri。每一个数据库文件中可以创建多个数据库表,可以根据不同的数据库表的表名组成不同的路径部分从而构成不同的Uri,Uri与所监听的第一数据库的表一一对应,可以实现对多个第一数据库的表进行监控。其中,可以通过系统表sqliet_mastar中table字段获取到相应的数据库表的表名,参数notifyForDescendents需设置为true,即使能监听功能,参数observer则是需要的ContentObserver。当第一数据库中的数据有变化时,ContentObserver 的onChange(booleanselfChange,Uriuri)回调函数就会被执行。当监听到回调函数被执行后,可以判断得出第一数据库中的数据发生变化,这时,可以获取第一数据库更新后的B+tree叶子页键值对列表大小,因为当新数据插入第一数据库时,此时的B+tree叶子页的键值对列表就会增大,所以通过比较第一数据库更新前后的B+tree叶子页的键值对列表大小即可判断第一数据库是否有删除记录,当第一数据库更新后的B+tree叶子页的键值对列表大小小于第一数据库更新前的B+tree叶子页的键值对列表大小时,则认为第一数据库有删除记录。具体的,如图3所示,可以通过以下步骤获取到第一数据库更新前后B+tree叶子叶键值对列表大小:步骤31、获取第一数据库文件,所述第一数据库文件是所述第一数据库的表对应的数据库文件。由于Android系统中数据库文件以.databases、.tables、.db、和.sqlite作为后缀名,而数据库文件存储的目录一般是/data/data/某应用/database/中,所以通过扫描系统/data/data目录中所有后缀为以上的文件,可以获取到系统中的数据库文件。步骤32、获取系统表sqlite_master。在SQLite数据库文件中,一旦建表,就会在系统目录(SystemCatalogue)下自动生成系统表sqlite_master。SQLite数据库中的系统sqlite_master表中的记录具有固定格式,每条记录包含五个字段,包括type、name、tbl_name、rootpage和sql字段,如下所示:CREATETABLEsqlite_master(typeTEXT,nameTEXT,tbl_nameTEXT,rootpageINTEGER,sqlTEXT);其中,字段type取值是table(表)或者index(索引),字段name和tbl_name是对应的表名或者索引名,字段rootpage是根页编号,当字段type是表时,字段sql就是相应的建表语句,当字段type是索引时,字段sql则是相应的建索引语句。由于每一数据库文件都有系统表sqlite_master。如上所述,若type字段是‘table’,则name字段就是数据库表的名字。所以,要获得数据库中所有数据库表的列表,可使用SELECT语句查询系统表sqlite_master。举例如下:建立一数据库表,并在/data/data/xxx/database/执行以下命令:如上所示,可获取到系统表sqlite_master的各个字段值,也即数据库文件中的数据库表的表名为ChannelRecordTable,表列字段为_id、channel_name、channel_id与channel_code。步骤33、根据第一数据库表的表名在所述系统表中查询,得到第一数据库表的根页编号。具体的,根据数据库表的表名(name字段),可在系统表sqlite_master中查找字段rootpage的值,从而得到数据库表的根页编号。步骤34、根据所述根页编号定位到相应的根页后,分析Btree中所有的页节点,根据页头中的页类型标志查找到第一数据库表的B+tree叶子页。具体的,根据所述根页编号定位到相应的根页后,分析Btree中所有的页 节点,根据页头中的页类型标志查找到所有B+tree叶子页,即可依据页的大小偏移量定位到所要查找的表名的数据的所在页。根据Sqlite中的规定,页类型标志如下:页头中第1个字节是区分B+tree和B-tree的内部页和叶子页的标志位。该字节的值是OxOD时,表示该页为B+tree的叶子页,该字节的值为0x05时,表示该页为B+tree的内部页;该字节的值为OxOA时,表示该页为B-tree的叶子页;该字节的值为0x02时,表示该页为B-tree的内部页。要查找到数据库表的所有B+tree叶子页,根据页类型标志,找到页起始为“0D”的标志,即可找到该数据库表的所有数据存储区域。步骤35、获取所述B+tree叶子页的键值对列表大小。具体的,创建一个指向所述B+tree叶子页的游标后,获取所述游标从第一条记录移动到最后一条记录所迭代的次数,将所述迭代的次数作为所述B+tree叶子页的键值对列表大小。更详细的,可以根据函数sqlite3BtreeCursor()创建一个指向当前B+tree的游标,然后根据函数sqlite3BtreeFirst()和函数sqlite3BtreeLast()可获取到所述游标从第一条记录移动到最后一条记录所迭代的次数,将所述迭代的次数作为获取到的当前B+tree叶子页的键值对列表大小。其中,函数sqlite3BtreeFirst()是移动游标至B+tree第一条记录,函数sqlite3BtreeLast()是移动游标至B+tree最后一条记录。在步骤S103中,根据所述WAL文件恢复已删除的记录至第二数据库的表中。在本发明实施例中,步骤S102中获取到的系统表中包括第一数据库表的表名和建立所述第一数据库表的语句,可以根据所述第一数据库表的表名、所述建立所述第一数据库表的语句以及所述WAL日志文件,构建第二数据库文件,所述第二数据库文件是所述第二数据库的表对应的数据库文件;再对比第一数据库文件和所述第二数据库文件,根据所述第二数据库文件找到第一数据 库文件中已删除的记录,并将所述第二数据库的表中在第一数据库文件中存储在记录删除。详细的,根据系统表中包括第一数据库表的表名和建立所述第一数据库表的语句建立第二数据库文件,比如执行步骤S102中获取的sql建表语句CREATETABLEChannelRecordTable(_idintegerprimarykeyautoincrement,channel_nametextnotnull,channel_idtextnotnull,channel_codetextnotnull)生成xxx.db数据库表。如前所述,SQLite中WAL文件是用于实现原子事务的一种机制,即WAL文件中记录了数据库所有事务操作记录,因此,可以根据WAL文件在第二数据库表xxx.db中构建历史数据,即原数据库文件中的数据,其中xxx.db是第二数据库的表的表名,根据当前监听到的有删除操作的第一数据库表来命名,且为了不影响上层应用对第一数据库表的相关操作,结合以上两点来命名xxx.db。举例说明,原数据库表为ChannelRecordTable,则可将xxx.db命名为ChannelRecordTable_WAL_DeleteRecord.db,并将该数据库文件保存在与第一数据库表同一路径下以备恢复删除数据。当有数据删除时,WAL日志文件中记录了删除数据的相关事务操作。如上所述,应用层查询数据库的时候,调用的数据库表名还是原来的数据库表名,即ChannelRecordTable,显示结果是删除后的相关数据,并不影响当前用户对该数据库表的操作。如上所述,第二数据库表xxx.db中包含了原数据库文件中的数据,通过对比第一数据库文件和所述第二数据库文件的记录,根据所述第二数据库文件找出第一数据库文件中已删除的记录,并将第二数据库表xxx.db中在第一数据库文件中存在的数据删除,则第二数据库表xxx.db中仅仅包含已删除的数据,实现了将删除的记录恢复至第二数据库表xxx.db中。需要说明的是:在第一次建立好与有删除记录的第一数据库表对应的第二数据库表后,后面再不需要建立,只需将每次删除的记录增加至第二数据库表中即可。优选地,如果预设的检查点条件成立,本发明实施例还可以判断第一数据库是否有修改记录,如果是,则根据所述WAL文件恢复已修改的记录至第二数据库的表中,以恢复已修改的记录。具体的,与判断第一数据库中是否有删除记录时相似,可以先通过ContentResolver.registerContentObserver监听第一数据库是否有变化,当监听到第一数据库发生变化时,函数onChange被回调。数据库支持增删查改操作,除了查询记录操作外,数据库变化时候,如增加记录、删除记录、修改记录,函数onChange都会被回调。当函数onChange被回调的时候,可以通过对比第一数据库变化前后B+tree叶子页键值对列表大小,如果第一数据库变化后的B+tree叶子页键值对列表大小大于变换前的B+tree叶子页键值对列表大小,则判断第一数据库有增加记录;如果第一数据库变化后的B+tree叶子页键值对列表大小小于变换前的B+tree叶子页键值对列表大小,则判断第一数据库有删除记录;否则判断第一数据库有修改记录。详细的,首先分别提取每个数据库文件中的记录,然后存储到CSV格式的文件中,再通过对比两个CSV格式的文件中的记录,最后区分出经过插入、修改和删除前的历史记录。优选的,在当前数据库文件被完整恢复出来后,需要提取其中的数据库记录进行取证分析。可利用数据库shell命令.tables[pattern]查看并提取其中的数据库表。再利用命令select提取数据库中包含的所有数据库表的记录。由于SQLite数据库文件属于结构化的文件,一旦文件不完整或部分拼装错误,则不能正确解码。本发明实施例中采用SQL命令提取数据库文件中的记录则恰好可以验证其完整性以及数据库文件恢复算法的有效可用性。进一步地,在已删除的记录成功恢复后,还可以继续监测预写日志WAL文件是否满足预设的检查点条件,如果,预写日志WAL文件满足预设的检查点条件,则将WAL文件中的内容修改到数据库文件中去,同时将WAL文件清空。在步骤S104中,在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库中。在本发明实施例中,将第一数据库中已删除的记录恢复至第二数据库的表中之后,可以生成一个提示框,提示用户是否将已删除的记录恢复至第一数据库中,如果用户选择是,则可以将第二数据库恢复数据至第一数据库中。在步骤S105中,将所述WAL文件中的内容修改到数据库文件中。在本发明实施例中,若预设的检查点条件是WAL文件积累到1000页,则检测到WAL文件积累到1000页时,系统会将WAL文件中的内容修改到数据库文件中。本实施例,在预写日志WAL文件满足预设的检查点条件之前,也就是在WAL文件清空之前,发现第一数据库有删除记录,则先根据WAL文件,将WAL文件中关于删除记录的数据及时恢复至第二数据库的表中,再在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库中。可以先于WAL日志文件清空前将WAL文件中关于删除记录的数据恢复,从而避免因WAL文件已清空且有数据删除的情况下,无法恢复该删除数据的问题,可实现基于Android平台的设备进行数据恢复。并且,相比现有的数据恢复的方法,实现简单,且不会出现当删除数据之前所在页面部分或者完全被新写入的数据覆盖时,无法恢复已删除的数据的问题。本领域普通技术人员可以理解实现上述各实施例方法中的全部或部分步骤是可以通过程序来指令相关的硬件来完成,相应的程序可以存储于一计算机可读取存储介质中,所述的存储介质,如ROM/RAM、磁盘或光盘等。实施例二图4示出了本发明实施例二提供的数据恢复的装置的具体结构框图,为了便于说明,仅示出了与本发明实施例相关的部分。该数据恢复的装置可以是内置于Android设备的软件单元、硬件单元或者软硬件结合的单元,该数据恢复的装置4包括:第一判断单元41、第二判断单元42、第一恢复单元43和第二 恢复单元44。其中,第一判断单元41,用于判断是否满足预设的检查点条件,所述的检查点条件在预写日志WAL文件满足清空条件之前;第二判断单元42,用于如果预设的检查点条件成立,则判断第一数据库是否有删除记录;第一恢复单元43,用于如果第一数据库有删除记录,则根据所述WAL文件恢复已删除的记录至第二数据库的表中;第二恢复单元44,用于在确定需要数据恢复时候,根据所述的第二数据库恢复数据至第一数据库中。进一步地,所述装置4,还包括:第三恢复单元,用于如果预设的检查点条件成立,则判断第一数据库是否有修改记录,如果是,则根据所述WAL文件恢复已修改的记录至第二数据库的表中。具体的,所述第二判断单元42,包括:第一获取模块,用于获取第一数据库变化前的B+tree叶子页键值对列表大小;监听模块,用于监听第一数据库中的数据是否发生变化;第二获取模块,用于当监听到第一数据库中的数据发生变化时,获取第一数据库变化后的B+tree叶子页键值对列表大小;判断模块,用于将第一数据库变化前后获取到的B+tree叶子页键值对列表大小进行比较,如果第一数据库变化后的B+tree叶子页键值对列表大小小于第一数据库变化前的B+tree叶子页键值对列表大小,则判定第一数据库有删除记录。具体的,所述监听模块,包括:注册子模块,用于通过函数ContentResolver.registerContentObserver()注册需要监听的第一数据库;判断子模块,用于当监听到回调函数onChange()被执行时,判定所监听的第一数据库中的数据发生变化。具体的,所述获取模块,包括:第一获取子模块,用于获取第一数据库文件,所述第一数据库文件是所述第一数据库的表对应的数据库文件;第二获取子模块,用于获取所述第一数据库文件中的系统表;第三获取子模块,用于根据第一数据库表的表名在所述系统表中查询,得到第一数据库表的根页编号;第四获取子模块,用于根据所述根页编号定位到相应的根页后,分析Btree中所有的页节点,根据页头中的页类型标志查找到第一数据库表的B+tree叶子页;第五获取子模块,用于获取所述B+tree叶子页的键值对列表大小。具体的,所述第五获取子模块,包括:创建微模块,用于创建一个指向所述B+tree叶子页的游标;获取微模块,用于获取所述游标从第一条记录移动到最后一条记录所迭代的次数,将所述迭代的次数作为所述B+tree叶子页的键值对列表大小。具体的,所述系统表中包括第一数据库表的表名和建立所述第一数据库表的语句,所述第一恢复单元,包括:构建模块,用于根据所述第一数据库表的表名、所述建立所述第一数据库表的语句以及所述WAL日志文件,构建第二数据库文件,所述第二数据库文件是所述第二数据库的表对应的数据库文件;恢复模块,用于对比第一数据库文件和所述第二数据库文件,根据所述第二数据库文件找到第一数据库文件中已删除的记录,并将所述第二数据库的表中在第一数据库文件中存储在记录删除。本发明实施例提供的数据恢复的装置可以应用在前述对应的方法实施例一中,详情参见上述实施例一的描述,在此不再赘述。值得注意的是,上述装置实施例中,所包括的各个单元只是按照功能逻辑进行划分的,但并不局限于上述的划分,只要能够实现相应的功能即可;另外,各功能单元的具体名称也只是为了便于相互区分,并不用于限制本发明的保护范围。以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。当前第1页1 2 3 当前第1页1 2 3 
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1