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

恢复数据库记录源代码:

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

你可能感兴趣的:(恢复sqlite数据库中使用delete命令删除的记录)