恢复sqlite数据库中使用delete命令删除的记录

本文介绍了一个用Python实现的简单数据库记录恢复程序。该程序能够读取一个损坏的SQLite数据库文件,并尝试恢复其中的数据记录。通过解析数据库页面并重构被删除或部分保留的数据,最终将恢复后的数据写入新的数据库文件中。
部署运行你感兴趣的模型镜像

恢复数据库记录源代码:

import os.path
dbfilename="test.db"
f=file(dbfilename, "rb")
fout=file("out.db", "wb")

def readpage(f,ind):
    f.seek(ind*0x400)
    return f.read(0x400)
def recover(dat):
    lenmap={}
    cleanpos=ord(dat[1])*0x100+ord(dat[2])
    if cleanpos==0: return dat
    newdat = bytearray(dat)
    newdat[1]=0
    newdat[2]=0
    recovnode=[]    
    while cleanpos!=0:
        nextpos=ord(dat[cleanpos])*0x100+ord(dat[cleanpos+1])
        datlen=ord(dat[cleanpos+3])
        
        for n in xrange(4,datlen):
            if dat[cleanpos+n]==dat[cleanpos] and dat[cleanpos+n+1]==dat[cleanpos+1]:
                nextpos=cleanpos+n
                datlen=nextpos-cleanpos
                break
        recovnode.append(cleanpos)
        lenmap[cleanpos]=datlen
        newdat[cleanpos]=datlen
        newdat[cleanpos+1]=0
        newdat[cleanpos+2]=newdat[cleanpos]-4
        newdat[cleanpos+2]=0
        cleanpos=nextpos
    reccnt=ord(dat[3])*0x100+ord(dat[4])    
    recstart=ord(dat[5])*0x100+ord(dat[6])
    for i in xrange(0,reccnt):
        datpos=ord(dat[8+2*i])*0x100+ord(dat[9+2*i])
        lenmap[datpos]=ord(dat[datpos])+2
        recovnode.append(datpos)
    firstrec=ord(dat[8+2*reccnt])*0x100+ord(dat[9+2*reccnt])
    cleanpos=firstrec
    while cleanpos!=0 and cleanpos<0x400:
        if cleanpos in recovnode:
            cleanpos+=lenmap[cleanpos]
            continue
        nextpos=cleanpos+ord(dat[cleanpos+2])*0x100+ord(dat[cleanpos+3])
        lenmap[cleanpos]=ord(dat[cleanpos+3])
        recovnode.append(cleanpos)
        newdat[cleanpos]=ord(dat[cleanpos+3])-2
        cleanpos=nextpos
    recovnode.sort()
    recovnode.reverse()
    idcnt=0
    newdat[3]=len(recovnode)>>8
    newdat[4]=len(recovnode)&0xff
    newdat[5]=recovnode[-1]>>8
    newdat[6]=recovnode[-1]&0xff

    for node in recovnode: 
        newdat[8+2*idcnt]=node>>8
        newdat[9+2*idcnt]=node&0xff
        idcnt+=1
        newdat[node]=lenmap[node]-2
        newdat[node+1]=idcnt
        newdat[node+2]=4
        newdat[node+3]=0
        
    return newdat

dat=readpage(f, 0)
fout.write(dat)

for ind in xrange(1, os.path.getsize(dbfilename)/0x400):
    dat=readpage(f, ind)
    fout.write(recover(dat))
    



实验步骤:


D:\lzf\dbrecover>sqlite3 test.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .echo on
sqlite> .read test.sql
.read test.sql
CREATE TABLE test (_id INTEGER PRIMARY KEY AUTOINCREMENT, nameid Integer, name text);
INSERT INTO test (nameid, name) VALUES (1, "lzf");
INSERT INTO test (nameid, name) VALUES (2, "luozf");
INSERT INTO test (nameid, name) VALUES (3, "lzhif");
INSERT INTO test (nameid, name) VALUES (4, "lzfan");
INSERT INTO test (nameid, name) VALUES (5, "l");
INSERT INTO test (nameid, name) VALUES (6, "zephyrluo");
INSERT INTO test (nameid, name) VALUES (7, "2B");
DELETE FROM test WHERE nameid=1 OR nameid=3 OR nameid=7 OR nameid=4 or nameid=2;


sqlite> select * from test;
select * from test;
5|5|l
6|6|zephyrluo
sqlite> .exit
.exit


D:\lzf\dbrecover>recovery.py


D:\lzf\dbrecover>sqlite3 out.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select * from test;
1|1|lzf
2|2|luozf
3|3|lzhif
4|4|lzfan
5|5|l
6|6|zephyrluo
7|7|2B

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

SQLite 数据库中,使用 `DELETE` 命令删除的数据通常不会立即从磁盘上物理删除SQLite 会将这些数据标记为“可重用空间”,直到新的数据写入或数据库被压缩(如执行 `VACUUM` 命令)[^1]。 要恢复通过 `DELETE` 删除的数据,有以下几种方法可以尝试: ### 1. 使用 WAL 日志文件 如果数据库启用了 **WAL(Write-Ahead Logging)模式**,则 SQLite 会在 `database.db-wal` 文件中保留事务日志。这些日志可能包含最近的更改记录,包括被删除的数据。可以通过以下方式查看是否启用了 WAL 模式: ```sql PRAGMA journal_mode; ``` 如果返回值是 `wal`,则说明 WAL 模式已启用。此时可以使用工具如 [SQLite Viewer](https://github.com/see--/sqlite_wal_parser) 或手动解析 `.db-wal` 文件来查找被删除的数据。 ### 2. 使用备份或镜像文件 SQLite 支持使用 `.backup` 命令进行数据库备份。如果之前做过完整备份,可以从备份文件中恢复数据。例如: ```sql -- 将当前数据库备份到 backup.db .backup main backup.db ``` 之后可以从 `backup.db` 中提取旧数据[^2]。 ### 3. 利用未提交的事务 如果删除操作尚未提交(即在 `BEGIN;` 和 `COMMIT;` 之间),可以通过回滚事务来撤销删除操作: ```sql BEGIN; DELETE FROM table_name WHERE condition; -- 发现误删后 ROLLBACK; ``` 这样可以避免数据真正被删除。 ### 4. 使用第三方恢复工具 有一些专门用于恢复 SQLite 数据的工具,例如: - **SQLite Database Recovery**:商业软件,支持从损坏或修改过的 `.db` 文件中恢复数据。 - **SQLite Forensic Tools**:开源工具包,适合高级用户,能解析 SQLite 的页结构和原始数据。 ### 5. 修改数据库文件的原始内容 SQLite 数据库是以二进制格式存储的。如果熟悉 SQLite 的页结构和 B-tree 存储机制,可以直接使用十六进制编辑器打开 `.db` 文件,查找并恢复删除的数据行。这种方法复杂度较高,建议仅在其他方法无效时尝试。 ### 6. 避免进一步写入操作 一旦发现误删数据,应立即停止对数据库的任何写入操作,以防止 SQLite 覆盖被删除数据所占用的空间。这可以显著提高恢复成功的几率。 ---
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值