1. Berkeley DB的簡介
Berkeley DB(BDB)是一個高性能的嵌入式數據庫編程庫(引擎),它可以用來保存任意類型的鍵/值對 (Key/Value Pair),而且可以爲一個鍵保存多個數據。Berkeley DB可以支持數千的併發線程同時操作數據庫,支持最大256TB的數據。
BDB提供諸如C語言,C++,Java,Perl,Python,Tcl等多種編程語言的API,並且廣泛支持大多數類Unix操作系統和Windows操作系統以及實時操作系統(如 VxWorks)。
1991年,Berkeley DB的第一個版發行(Linux系統也在這一年誕生),其最初的開發目的是以新的HASH訪問算法來代替舊的hsearch函數和大量的dbm實現,該版本還包含了B+樹數據訪問算法。
1992年,BSD UNIX第4.4發行版中包含了Berkeley DB1.85版。基本上認爲這是Berkeley DB的第一個正式版。
1996年,Sleepycat軟件公司成立,提供對Berkeley DB的商業支持。
2006年,Sleepycat被Oracle收購,當時最新版本是4.7.25。
2. 直觀瞭解Berkeley DB軟件包
Berkeley DB是一款開源軟件,我們可以從Oracle的官方網站得到其源代碼包。其源代碼目錄是由一系列子目錄組成,從BDB的實現角度按照功能層次可將它們簡單歸類,劃分如下:
a. DB核心模塊(db);
b. 各子系統模塊(存儲管理子系統:btree/hash/qam;內存池管理子系統:mp;事務子系統:txn;鎖子系統:mutex;日誌子系統:log);
c. 操作系統抽象層(os_brew/os_s60/os_windows等);
d. Build目錄(build_brew/build_s60/build_windows等);
e. 工具程序(db_archive/db_checkpoint等);
f. 語言API支持;
g. 例子(examples_c/examples_csharp等);
h. 其它;
通過源代碼編譯安裝BDB很簡單,代碼如下:
cd ./db-4.8.30/build_unix
../disk/configure --prefix=<dir>
make && make install
安裝目標目錄(/usr/local/BerkeleyDB.4.8)包含四個子目錄:
A. bin 一些實用工具
B. docs 文檔
C. include 包含了使用BDB庫開發程序時的頭文件
D. lib 包含了使用BDB庫開發程序時需要連接的庫文件
3. 如何獲得BDB的相關知識
BDB提供裏非常詳細的文檔,可以官方網站獲得html或pdf版本的文檔。這裏對pdf版本的一些文檔簡介如下:
BDB_Installation.pdf: BDB的安裝文檔,涵蓋了不同操作系統,不同的編譯工具,不同編程語言等多方面的詳細信息;
BDB_Prog_Reference.pdf: 該文檔是使用BDB的開發人員的參考手冊,主要從BDB的各種功能和機制的原理進行闡述,供使用BDB作爲存儲引擎來編寫程序的各類程序員(C、Java、C#、Perl)閱讀;
BDB-Porting-Guide.pdf: 該文檔是給需要將BDB移植到一個新的平臺開發人員準備的;
InMemoryDBApplication.pdf: 基於內存的BDB應用的相關知識;
BDB-C_APIReference.pdf: C API參考手冊,跟BDB_Prog_Reference.pdf結合使用;
BerkeleyDB-Core-C-GSG.pdf: 爲C語言開發人員提供的BDB的入門手冊;
BerkeleyDB-Core-C-Txn.pdf: 爲C語言開發人員提供的BDB事務方面的手冊;
Replication-C-GSG.pdf: 爲C語言開發人員提供的BDB複製方面的手冊;
4. 以上對源碼目錄的分類是從實現角度按照層次進行劃分的,如果從BDB的功能模塊,或者說是從系統結構角度進行劃分,可將其分爲幾個子系統:
存儲管理子系統 (Storage Subsystem)
內存池管理子系統 (Memory Pool Subsystem)
事務子系統 (Transaction Subsystem)
鎖子系統 (Locking Subsystem)
日誌子系統 (Logging Subsystem)
5. 以上的五個子系統完成了BDB作爲一個Database所需要的大部分功能,如何駕馭以上子系統來完成我們需要的任務是關鍵。像MySQL這種獨立的RDBMS,我們可以通過配置和SQL語句來控制和使用它的各種功能。由於BDB是一個嵌入式的數據庫,最終還是需要程序員通過調用API來完成。所以要使用好BDB,需要先了解其原理,然後在合適的位置上調用合適的API。
寫一個BDB程序的一般步驟:
a. 創建、設置和打開Environment;b. 創建、設置和打開Database;c. 訪問Database;d.關閉Database;e. 關閉Environment。
此處的Database是從屬於Environment,即db是在env這個環境上面建立起來的。爲了便於快速把握重點,可以用BDB跟一般的RDBMS做個類比,這裏的Database相當於數據表,Environment相當於數據庫。
DB_ENV *dbenv;
DB *dbp;
int ret;
if ((ret = db_env_create(&dbenv, 0)) != 0) {
fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
return (1);
}
dbenv->set_errfile(dbenv, errfp);
dbenv->set_errpfx(dbenv, progname);
if ((ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0)) != 0) {
dbenv->err(dbenv, ret, "set_cachesize");
dbenv->close(dbenv, 0);
return (1);
}
(void)dbenv->set_data_dir(dbenv, data_dir);
if ((ret = dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0644)) != 0) {
dbenv->err(dbenv, ret, "environment open: %s", home);
dbenv->close(dbenv, 0);
return (1);
}
if ((ret = db_create(&dbp, dbenv, 0)) != 0){
fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
return (1);
}
if ((ret = dbp->open(dbp, NULL, "exenv_db1.db", NULL, DB_BTREE, DB_CREATE,0644)) != 0){
fprintf(stderr, "database open: %s\n", db_strerror(ret));
return (1);
}
if ((ret = dbp->close(dbp, 0)) != 0) {
fprintf(stderr, "database close: %s\n", db_strerror(ret));
return (1);
}
if ((ret = dbenv->close(dbenv, 0)) != 0) {
fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
return (1);
}
return (0);
數據文件:
一個BDB的實例會產生數據存儲文件,數據文件的目錄由dbenv->set_data_dir(dbenv, data_dir);這條語句來指定。涉及的文件類型有:Data Files,Log Files,Region Files,Temporary Files。
Data Files:數據文件,存儲實際的數據;
Log Files:日誌文件;
Region Files:是各個子系統保存信息的文件,如果在Env中設置了DB_PRIVATE選項,這些信息是被一個進程私有,即它們保存在內存中,這些文件在此種情況下不產生;
Temporary Files: 臨時文件,特使情況會被創建;
數據的存數格式:
Berkeley DB提供了以下四種文件存儲方法:哈希文件、B樹、定長記錄(隊列)和變長記錄(基於記錄號的簡單存儲方式),應用程序可以從中選擇最適合的文件組織結構。以上代碼通過db->open函數中設置了DB_BTREE這個選項指定其使用B樹方式存儲。其它的三種存儲格式對應的類型爲:DB_HASH,DB_QUEUE,DB_RECNO。
事務提交:
BDB中的事務提交有兩種方式:DB_AUTO_COMMIT和顯式提交事務。如果設置爲DB_AUTO_COMMIT,則每步操作多作爲單獨的事務自動提交;如果需要顯示提交,則需要顯示調用具體事務相關的begin/end API(相見文檔BerkeleyDB-Core-C-Txn.pdf)。
BDB在事務提交時也是遵循先寫日誌並刷新到磁盤的方式,但是爲了提高性能,其又引入了兩個選項:DB_TXN_NOSYNC和DB_TXN_WRITE_NOSYNC。DB_TXN_NOSYNC的作用是使BDB在事務提交的時候不嚴格要求日誌到磁盤,刷新與否取決於日誌緩衝;DB_TXN_WRITE_NOSYNC會比DB_TXN_NOSYNC稍顯嚴格,其含義是要求事務提交刷新日誌,但只是刷到操作系統文件緩存當中。
BDB的事務隔離性級別有三個:READ UNCOMMITED、READ COMMITED、SERIALIZABLE
CheckPoint:
執行一個檢查點會完成的工作有:Flushes all dirty pages from the in-memory cache to database files;Writes a checkpoint record;Flushes the log to log files;Writes a list of open databases.
調用API DB_ENV->txn_checkpoint(); 即可完成,如果是非DB_PRIVATE的Env,也可以使用BDB自帶的工具db_checkpoint。爲了避免出現一個檢查點提交大量數據的情況,BDB還提供了輕量級刷新髒頁的API:DB_ENV->memp_trickle();
Replication:
BDB中提供了兩種方式來支持複製技術:Replication Base API和Replication Manager。可以說Replication Base API是最基礎的API,實現方式靈活,功能強大,但是編碼量大;Replication Manager相當於框架,使用方式簡單,編碼量小。Replication Manager可能能夠滿足大部分用戶的需求,但不是所有需求,所以靈活性不足。如果您的需要是Replication Manager不能滿足的,請使用Replication Base API自己實現複製策略。Replication Manager的主從策略有兩種:指定主從、自動推舉主從。
分區:
BDB的分區機制是從db-4.8.x之後剛引入的新功能,涉及到的API有兩個:
DB->set_partition() 設置分區方式,包含了一個分區方式的回調函數,用戶可以通過編寫代碼來自己實現分區方式,非常靈活。(詳見API手冊BDB-C_APIReference.pdf)
DB->set_partition_dirs() 設置分區目錄。(詳見API手冊BDB-C_APIReference.pdf)
備份:
BDB有三種備份方式:
Offline Backups:離線備份,停服務拷貝數據目錄;
Hot Backups:使用API或者BDB自帶工具db_backup在DB在使用情況做備份;
Incremental Backups:增量備份;
具體細節詳見BerkeleyDB-Core-C-Txn.pdf。
6. 以下是可能獲取到Berkeley DB資源的鏈接:
官方主頁:
http://www.oracle.com/database/berkeley-db/db/index.html
產品下載:
http://www.oracle.com/technology/software/products/berkeley-db/index.html
官方開發者文檔中心:
http://www.oracle.com/technology/documentation/berkeley-db/db/index.html