Version the leveldb (and keep compatibility with pre-versioned uncompressed databases.
This commit is contained in:
parent
0e98349c98
commit
3640f6d37c
5 changed files with 72 additions and 2 deletions
|
@ -16,13 +16,16 @@ import (
|
||||||
func TestEmptyDB(t *testing.T) {
|
func TestEmptyDB(t *testing.T) {
|
||||||
|
|
||||||
dbname := "tstdbempty"
|
dbname := "tstdbempty"
|
||||||
|
dbnamever := dbname + ".ver"
|
||||||
_ = os.RemoveAll(dbname)
|
_ = os.RemoveAll(dbname)
|
||||||
|
_ = os.RemoveAll(dbnamever)
|
||||||
db, err := btcdb.CreateDB("leveldb", dbname)
|
db, err := btcdb.CreateDB("leveldb", dbname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to open test database %v", err)
|
t.Errorf("Failed to open test database %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dbname)
|
defer os.RemoveAll(dbname)
|
||||||
|
defer os.RemoveAll(dbnamever)
|
||||||
|
|
||||||
sha, height, err := db.NewestSha()
|
sha, height, err := db.NewestSha()
|
||||||
if !sha.IsEqual(&btcwire.ShaHash{}) {
|
if !sha.IsEqual(&btcwire.ShaHash{}) {
|
||||||
|
|
|
@ -11,5 +11,12 @@ The performance is generally high although it goes down with database
|
||||||
size.
|
size.
|
||||||
|
|
||||||
Many of the block or tx specific functions for btcdb are in this subpackage.
|
Many of the block or tx specific functions for btcdb are in this subpackage.
|
||||||
|
|
||||||
|
Database version number is stored in a flat file <dbname>.ver
|
||||||
|
Currently a single (littlendian) integer in the file. If there is
|
||||||
|
additional data to save in the future, the presense of additional
|
||||||
|
data can be indicated by changing the version number, then parsing the
|
||||||
|
file differently.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
package ldb
|
package ldb
|
||||||
|
|
|
@ -46,13 +46,16 @@ func TestUnspentInsert(t *testing.T) {
|
||||||
func testUnspentInsert(t *testing.T, mode int) {
|
func testUnspentInsert(t *testing.T, mode int) {
|
||||||
// Ignore db remove errors since it means we didn't have an old one.
|
// Ignore db remove errors since it means we didn't have an old one.
|
||||||
dbname := fmt.Sprintf("tstdbuspnt1.%d", mode)
|
dbname := fmt.Sprintf("tstdbuspnt1.%d", mode)
|
||||||
|
dbnamever := dbname + ".ver"
|
||||||
_ = os.RemoveAll(dbname)
|
_ = os.RemoveAll(dbname)
|
||||||
|
_ = os.RemoveAll(dbnamever)
|
||||||
db, err := btcdb.CreateDB("leveldb", dbname)
|
db, err := btcdb.CreateDB("leveldb", dbname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to open test database %v", err)
|
t.Errorf("Failed to open test database %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dbname)
|
defer os.RemoveAll(dbname)
|
||||||
|
defer os.RemoveAll(dbnamever)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package ldb
|
package ldb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/conformal/btcdb"
|
"github.com/conformal/btcdb"
|
||||||
"github.com/conformal/btcutil"
|
"github.com/conformal/btcutil"
|
||||||
|
@ -129,9 +130,13 @@ blocknarrow:
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var CurrentDBVersion int32 = 1
|
||||||
|
|
||||||
func openDB(dbpath string, flag opt.OptionsFlag) (pbdb btcdb.Db, err error) {
|
func openDB(dbpath string, flag opt.OptionsFlag) (pbdb btcdb.Db, err error) {
|
||||||
var db LevelDb
|
var db LevelDb
|
||||||
var tlDb *leveldb.DB
|
var tlDb *leveldb.DB
|
||||||
|
var dbversion int32
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
db.lDb = tlDb
|
db.lDb = tlDb
|
||||||
|
@ -156,14 +161,60 @@ func openDB(dbpath string, flag opt.OptionsFlag) (pbdb btcdb.Db, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tlDb, err = leveldb.OpenFile(dbpath, &opt.Options{Flag: flag,
|
needVersionFile := false
|
||||||
|
verfile := dbpath + ".ver"
|
||||||
|
fi, ferr := os.Open(verfile)
|
||||||
|
if ferr == nil {
|
||||||
|
defer fi.Close()
|
||||||
|
|
||||||
|
ferr = binary.Read(fi, binary.LittleEndian, &dbversion)
|
||||||
|
if ferr != nil {
|
||||||
|
dbversion = ^0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if flag&opt.OFCreateIfMissing != 0 {
|
||||||
|
needVersionFile = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := &opt.Options{Flag: flag,
|
||||||
BlockCache: cache.EmptyCache{},
|
BlockCache: cache.EmptyCache{},
|
||||||
MaxOpenFiles: 256,
|
MaxOpenFiles: 256,
|
||||||
CompressionType: opt.NoCompression})
|
CompressionType: opt.NoCompression,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch dbversion {
|
||||||
|
case 0:
|
||||||
|
opts = &opt.Options{Flag: flag}
|
||||||
|
case 1:
|
||||||
|
// uses defaults from above
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("unsupported db version %v", dbversion)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tlDb, err = leveldb.OpenFile(dbpath, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we opened the database successfully on 'create'
|
||||||
|
// update the
|
||||||
|
if needVersionFile {
|
||||||
|
fo, ferr := os.Create(verfile)
|
||||||
|
if ferr != nil {
|
||||||
|
// TODO(design) close and delete database?
|
||||||
|
err = ferr
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer fo.Close()
|
||||||
|
dbversion = CurrentDBVersion
|
||||||
|
err = binary.Write(fo, binary.LittleEndian, dbversion)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,13 +42,16 @@ func testOperationalMode(t *testing.T, mode int) {
|
||||||
|
|
||||||
// Ignore db remove errors since it means we didn't have an old one.
|
// Ignore db remove errors since it means we didn't have an old one.
|
||||||
dbname := fmt.Sprintf("tstdbop1.%d", mode)
|
dbname := fmt.Sprintf("tstdbop1.%d", mode)
|
||||||
|
dbnamever := dbname + ".ver"
|
||||||
_ = os.RemoveAll(dbname)
|
_ = os.RemoveAll(dbname)
|
||||||
|
_ = os.RemoveAll(dbnamever)
|
||||||
db, err := btcdb.CreateDB("leveldb", dbname)
|
db, err := btcdb.CreateDB("leveldb", dbname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to open test database %v", err)
|
t.Errorf("Failed to open test database %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dbname)
|
defer os.RemoveAll(dbname)
|
||||||
|
defer os.RemoveAll(dbnamever)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
|
@ -177,13 +180,16 @@ func testBackout(t *testing.T, mode int) {
|
||||||
t.Logf("mode %v", mode)
|
t.Logf("mode %v", mode)
|
||||||
// Ignore db remove errors since it means we didn't have an old one.
|
// Ignore db remove errors since it means we didn't have an old one.
|
||||||
dbname := fmt.Sprintf("tstdbop2.%d", mode)
|
dbname := fmt.Sprintf("tstdbop2.%d", mode)
|
||||||
|
dbnamever := dbname + ".ver"
|
||||||
_ = os.RemoveAll(dbname)
|
_ = os.RemoveAll(dbname)
|
||||||
|
_ = os.RemoveAll(dbnamever)
|
||||||
db, err := btcdb.CreateDB("leveldb", dbname)
|
db, err := btcdb.CreateDB("leveldb", dbname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to open test database %v", err)
|
t.Errorf("Failed to open test database %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer os.RemoveAll(dbname)
|
defer os.RemoveAll(dbname)
|
||||||
|
defer os.RemoveAll(dbnamever)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
switch mode {
|
switch mode {
|
||||||
|
|
Loading…
Reference in a new issue