Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions pebble.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ var _ DB = (*PebbleDB)(nil)

func NewPebbleDB(name string, dir string) (*PebbleDB, error) {
opts := &pebble.Options{}
// EnsureDefaults would settle on FormatMostCompatible and leave it there
// for the database's whole life, which pebble v2 refuses to open -- and
// refuses before it would migrate anything, so no v2 build can do this for
// itself. Upgrading here readies a node for that bump instead of failing
// to start after it.
//
// FlushableIngest rather than FormatNewest is exactly what v2 needs: the
// next version up holds the open until every table predating the Pebblev1
// format has been rewritten, which here is all of them. Stopping short
// leaves those to ordinary compaction.
opts.FormatMajorVersion = pebble.FormatFlushableIngest
opts.EnsureDefaults()
return NewPebbleDBWithOpts(name, dir, opts)
}
Expand Down
40 changes: 40 additions & 0 deletions pebble_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,52 @@ package db
import (
"fmt"
"os"
"path/filepath"
"testing"

"github.com/cockroachdb/pebble"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// TestPebbleRatchetsFormatMajorVersion covers the upgrade this option exists
// for. NewPebbleDB has to move an existing database forward, not just new
// ones, since every node already has one from before this.
//
// The test goes when the migration does: v2 deleted FormatMostCompatible, so
// none of it compiles there. Delete it rather than repair it -- but carry the
// ceiling assertion over. Staying below FormatNewest is not about the
// migration; it is what leaves a database readable by the release before, and
// it stays true on v2. Dropping the test takes that with it and nothing says
// so.
func TestPebbleRatchetsFormatMajorVersion(t *testing.T) {
dir := t.TempDir()

// What a node that has never run this code has on disk.
old, err := pebble.Open(filepath.Join(dir, "test.db"), &pebble.Options{})
require.NoError(t, err)
require.Equal(t, pebble.FormatMostCompatible, old.FormatMajorVersion(),
"pebble's own default is the version v2 refuses")
require.NoError(t, old.Set([]byte("key"), []byte("value"), pebble.Sync))
require.NoError(t, old.Close())

db, err := NewPebbleDB("test", dir)
require.NoError(t, err)
defer db.Close()

// FlushableIngest is pebble v2's FormatMinSupported, which is the point.
// Staying below FormatNewest is the other half: the next version up would
// not return from the open above until every table had been rewritten.
vers := db.DB().FormatMajorVersion()
require.Equal(t, pebble.FormatFlushableIngest, vers)
require.Less(t, vers, pebble.FormatNewest,
"going further would put a full rewrite in front of the node's first start")

got, err := db.Get([]byte("key"))
require.NoError(t, err)
require.Equal(t, []byte("value"), got, "the upgrade must carry the data over")
}

func TestPebbleDBBackend(t *testing.T) {
name := fmt.Sprintf("test_%x", randStr(12))
dir := os.TempDir()
Expand Down
Loading