Posted on 2012-03-13 16:54
小明 閱讀(4484)
評論(0) 編輯 收藏 所屬分類:
分布式計算
所謂snapshot就是一個快照,我們可以從快照中讀到舊的數(shù)據(jù)。
先寫一個測試程序來看看snapshot的使用:
#include <iostream>
#include "leveldb/db.h"
using namespace std;
using namespace leveldb;
int main() {
DB *db ;
Options op;
op.create_if_missing = true;
Status s = DB::Open(op,"/tmp/testdb",&db);
if(s.ok()){
cout << "create successfully" << endl;
s = db->Put(WriteOptions(),"abcd","1234");
if(s.ok()){
cout << "put successfully" << endl;
string value;
s = db->Get(ReadOptions(),"abcd",&value);
if(s.ok()){
cout << "get successfully,value:" << value << endl;
}
}
if(s.ok()){
string value;
const Snapshot * ss =db->GetSnapshot();
ReadOptions rop;
db->Put(WriteOptions(),"abcd","123456");
db->Get(rop,"abcd",&value);
if(s.ok()){
cout << "get successfully,value:" << value << endl;
}
rop.snapshot = ss;
db->Get(rop,"abcd",&value);
if(s.ok()){
cout << "get from snapshot successfully,value:" << value << endl;
}
db->ReleaseSnapshot(ss);
}
}
delete db;
return 0;
}
程序運行的輸出結(jié)果是:
create successfully
put successfully
get successfully,value:1234
get successfully,value:123456
get from snapshot successfully,value:1234
可以看出,即使在數(shù)據(jù)更新后,我們?nèi)匀豢梢詮膕napshot中讀到舊的數(shù)據(jù)。
下面我們來分析leveldb中snapshot的實現(xiàn)。
SequenceNumber(db/dbformat.h)
SequenceNumber是leveldb很重要的東西,每次對數(shù)據(jù)庫進行更新操作,都會生成一個新的SequenceNumber,64bits,其中高8位為0,可以跟key的類型(8bits)進行合并成64bits。
typedef uint64_t SequenceNumber;
// We leave eight bits empty at the bottom so a type and sequence#
// can be packed together into 64-bits.
static const SequenceNumber kMaxSequenceNumber =
((0x1ull << 56) - 1);
SnapShot(db/snapshot.h),,可以看出snapshot其實就是一個sequence number
class SnapshotImpl : public Snapshot {
public:
//創(chuàng)建后保持不變
SequenceNumber number_;
private:
friend class SnapshotList;
//雙向循環(huán)鏈表
SnapshotImpl* prev_;
SnapshotImpl* next_;
SnapshotList* list_; // just for sanity checks
};
創(chuàng)建snapshot:
const Snapshot* DBImpl::GetSnapshot() {
MutexLock l(&mutex_);
return snapshots_.New(versions_->LastSequence());
}
刪除snapshot:
void DBImpl::ReleaseSnapshot(const Snapshot* s) {
MutexLock l(&mutex_);
snapshots_.Delete(reinterpret_cast<const SnapshotImpl*>(s));
}