quorum/raft/snapshot.go

83 lines
2.2 KiB
Go
Raw Normal View History

package raft
import (
"github.com/coreos/etcd/raft/raftpb"
"github.com/coreos/etcd/snap"
"github.com/coreos/etcd/wal/walpb"
"github.com/ethereum/go-ethereum/logger"
"github.com/ethereum/go-ethereum/logger/glog"
)
func (pm *ProtocolManager) saveSnapshot(snap raftpb.Snapshot) error {
if err := pm.snapshotter.SaveSnap(snap); err != nil {
return err
}
walSnap := walpb.Snapshot{
Index: snap.Metadata.Index,
Term: snap.Metadata.Term,
}
if err := pm.wal.SaveSnapshot(walSnap); err != nil {
return err
}
return pm.wal.ReleaseLockTo(snap.Metadata.Index)
}
func (pm *ProtocolManager) maybeTriggerSnapshot() {
if pm.appliedIndex-pm.snapshotIndex < snapshotPeriod {
return
}
pm.triggerSnapshot()
}
func (pm *ProtocolManager) triggerSnapshot() {
glog.V(logger.Info).Infof("start snapshot [applied index: %d | last snapshot index: %d]", pm.appliedIndex, pm.snapshotIndex)
snapData := pm.blockchain.CurrentBlock().Hash().Bytes()
snap, err := pm.raftStorage.CreateSnapshot(pm.appliedIndex, &pm.confState, snapData)
if err != nil {
panic(err)
}
if err := pm.saveSnapshot(snap); err != nil {
panic(err)
}
// Discard all log entries prior to appliedIndex.
if err := pm.raftStorage.Compact(pm.appliedIndex); err != nil {
panic(err)
}
glog.V(logger.Info).Infof("compacted log at index %d", pm.appliedIndex)
pm.snapshotIndex = pm.appliedIndex
}
// For persisting cluster membership changes correctly, we need to trigger a
// snapshot before advancing our persisted appliedIndex in LevelDB.
//
// See handling of EntryConfChange entries in raft/handler.go for details.
func (pm *ProtocolManager) triggerSnapshotWithNextIndex(index uint64) {
pm.appliedIndex = index
pm.triggerSnapshot()
}
func (pm *ProtocolManager) loadSnapshot() *raftpb.Snapshot {
snapshot, err := pm.snapshotter.Load()
if err != nil && err != snap.ErrNoSnapshot {
glog.Fatalf("error loading snapshot: %v", err)
}
return snapshot
}
func (pm *ProtocolManager) applySnapshot(snap raftpb.Snapshot) {
if err := pm.raftStorage.ApplySnapshot(snap); err != nil {
glog.Fatalln("failed to apply snapshot: ", err)
}
snapMeta := snap.Metadata
pm.confState = snapMeta.ConfState
pm.snapshotIndex = snapMeta.Index
pm.advanceAppliedIndex(snapMeta.Index)
}