Persists Term in the (bbolt) Backend.

Additional layer of protection, that allows to validate whether we
start replaying log not only from the proper 'index', but also of the
right 'term'.
This commit is contained in:
Piotr Tabor
2021-05-13 21:02:02 +02:00
parent e44fb40be5
commit ab586cd463
12 changed files with 89 additions and 53 deletions

View File

@@ -124,7 +124,7 @@ func handleBackup(c *cli.Context) error {
walsnap := saveSnap(lg, destSnap, srcSnap, &desired)
metadata, state, ents := translateWAL(lg, srcWAL, walsnap, withV3)
saveDB(lg, destDbPath, srcDbPath, state.Commit, &desired, withV3)
saveDB(lg, destDbPath, srcDbPath, state.Commit, state.Term, &desired, withV3)
neww, err := wal.Create(lg, destWAL, pbutil.MustMarshal(&metadata))
if err != nil {
@@ -265,7 +265,7 @@ func raftEntryToNoOp(entry *raftpb.Entry) {
}
// saveDB copies the v3 backend and strips cluster information.
func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, desired *desiredCluster, v3 bool) {
func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, term uint64, desired *desiredCluster, v3 bool) {
// open src db to safely copy db state
if v3 {
@@ -322,7 +322,7 @@ func saveDB(lg *zap.Logger, destDB, srcDB string, idx uint64, desired *desiredCl
tx.Lock()
defer tx.Unlock()
cindex.UnsafeCreateMetaBucket(tx)
cindex.UnsafeUpdateConsistentIndex(tx, idx, false)
cindex.UnsafeUpdateConsistentIndex(tx, idx, term, false)
} else {
// Thanks to translateWAL not moving entries, but just replacing them with
// 'empty', there is no need to update the consistency index.

View File

@@ -82,7 +82,7 @@ func migrateCommandFunc(cmd *cobra.Command, args []string) {
writer, reader, errc = defaultTransformer()
}
st, index := rebuildStoreV2()
st, index, term := rebuildStoreV2()
be := prepareBackend()
defer be.Close()
@@ -92,7 +92,7 @@ func migrateCommandFunc(cmd *cobra.Command, args []string) {
}()
readKeys(reader, be)
cindex.UpdateConsistentIndex(be.BatchTx(), index, true)
cindex.UpdateConsistentIndex(be.BatchTx(), index, term, true)
err := <-errc
if err != nil {
fmt.Println("failed to transform keys")
@@ -127,8 +127,7 @@ func prepareBackend() backend.Backend {
return be
}
func rebuildStoreV2() (v2store.Store, uint64) {
var index uint64
func rebuildStoreV2() (st v2store.Store, index uint64, term uint64) {
cl := membership.NewCluster(zap.NewExample())
waldir := migrateWALdir
@@ -147,6 +146,7 @@ func rebuildStoreV2() (v2store.Store, uint64) {
if snapshot != nil {
walsnap.Index, walsnap.Term = snapshot.Metadata.Index, snapshot.Metadata.Term
index = snapshot.Metadata.Index
term = snapshot.Metadata.Term
}
w, err := wal.OpenForRead(zap.NewExample(), waldir, walsnap)
@@ -160,7 +160,7 @@ func rebuildStoreV2() (v2store.Store, uint64) {
ExitWithError(ExitError, err)
}
st := v2store.New()
st = v2store.New()
if snapshot != nil {
err := st.Recovery(snapshot.Data)
if err != nil {
@@ -191,12 +191,13 @@ func rebuildStoreV2() (v2store.Store, uint64) {
applyRequest(req, applier)
}
}
if ent.Index > index {
if ent.Index >= index {
index = ent.Index
term = ent.Term
}
}
return st, index
return st, index, term
}
func applyConf(cc raftpb.ConfChange, cl *membership.RaftCluster) {

View File

@@ -265,7 +265,7 @@ func (s *v3Manager) Restore(cfg RestoreConfig) error {
return err
}
if err := s.updateCIndex(hardstate.Commit); err != nil {
if err := s.updateCIndex(hardstate.Commit, hardstate.Term); err != nil {
return err
}
@@ -475,10 +475,10 @@ func (s *v3Manager) saveWALAndSnap() (*raftpb.HardState, error) {
return &hardState, w.SaveSnapshot(snapshot)
}
func (s *v3Manager) updateCIndex(commit uint64) error {
func (s *v3Manager) updateCIndex(commit uint64, term uint64) error {
be := backend.NewDefaultBackend(s.outDbPath())
defer be.Close()
cindex.UpdateConsistentIndex(be.BatchTx(), commit, false)
cindex.UpdateConsistentIndex(be.BatchTx(), commit, term, false)
return nil
}