Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem: memiavl minQueryState logic is unnesserary #1064

Merged
merged 6 commits into from
Jun 15, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
- [#1034](https://github.com/crypto-org-chain/cronos/pull/1034) Support memiavl snapshot strategy configuration.
- [#1035](https://github.com/crypto-org-chain/cronos/pull/1035) Support caching in memiavl directly, ignore inter-block cache silently.
- [#1050](https://github.com/crypto-org-chain/cronos/pull/1050) nativebyteorder mode will check endianness on startup, binaries are built with nativebyteorder by default.
- [#]() Simplify memiavl snapshot switching.
yihuang marked this conversation as resolved.
Show resolved Hide resolved

*April 13, 2023*

Expand Down
10 changes: 6 additions & 4 deletions app/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ type MemIAVLConfig struct {
// AsyncCommitBuffer defines the size of asynchronous commit queue, this greatly improve block catching-up
// performance, -1 means synchronous commit.
AsyncCommitBuffer int `mapstructure:"async-commit-buffer"`
// SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are taken.
// SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are
// taken, defaults to 1 to make sure ibc relayers work.
SnapshotKeepRecent uint32 `mapstructure:"snapshot-keep-recent"`
// SnapshotInterval defines the block interval the memiavl snapshot is taken, default to 1000.
SnapshotInterval uint32 `mapstructure:"snapshot-interval"`
Expand All @@ -32,8 +33,9 @@ type MemIAVLConfig struct {

func DefaultMemIAVLConfig() MemIAVLConfig {
return MemIAVLConfig{
CacheSize: DefaultCacheSize,
SnapshotInterval: memiavl.DefaultSnapshotInterval,
ZeroCopy: true,
CacheSize: DefaultCacheSize,
SnapshotInterval: memiavl.DefaultSnapshotInterval,
ZeroCopy: true,
SnapshotKeepRecent: 1,
}
}
3 changes: 2 additions & 1 deletion app/config/toml.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ zero-copy = {{ .MemIAVL.ZeroCopy }}
# performance, -1 means synchronous commit.
async-commit-buffer = {{ .MemIAVL.AsyncCommitBuffer }}
# SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are taken.
# SnapshotKeepRecent defines what many old snapshots (excluding the latest one) to keep after new snapshots are
# taken, defaults to 1 to make sure ibc relayers work.
snapshot-keep-recent = {{ .MemIAVL.SnapshotKeepRecent }}
# SnapshotInterval defines the block interval the memiavl snapshot is taken, default to 1000.
Expand Down
4 changes: 1 addition & 3 deletions app/memiavl.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ func SetupMemIAVL(logger log.Logger, homePath string, appOpts servertypes.AppOpt
ZeroCopy: cast.ToBool(appOpts.Get(FlagZeroCopy)),
SnapshotKeepRecent: cast.ToUint32(appOpts.Get(FlagSnapshotKeepRecent)),
SnapshotInterval: cast.ToUint32(appOpts.Get(FlagSnapshotInterval)),
// make sure a few queryable states even with pruning="nothing", needed for ibc relayer to work.
MinQueryStates: 3,
CacheSize: cast.ToInt(appOpts.Get(FlagCacheSize)),
CacheSize: cast.ToInt(appOpts.Get(FlagCacheSize)),
})
baseAppOptions = append([]func(*baseapp.BaseApp){setCMS(cms)}, baseAppOptions...)
}
Expand Down
39 changes: 11 additions & 28 deletions memiavl/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,6 @@ type DB struct {
snapshotInterval uint32
// make sure only one snapshot rewrite is running
pruneSnapshotLock sync.Mutex
// might need to wait for a few blocks before actual snapshot switching.
minQueryStates int
pendingForSwitch *MultiTree

// invariant: the LastIndex always match the current version of MultiTree
wal *wal.Log
Expand Down Expand Up @@ -83,8 +80,6 @@ type Options struct {
AsyncCommitBuffer int
// ZeroCopy if true, the get and iterator methods could return a slice pointing to mmaped blob files.
ZeroCopy bool
// for ibc relayer to work, we need to make sure at least a few queryable states exists even with pruning="nothing" setting.
MinQueryStates int
// CacheSize defines the cache's max entry size for each memiavl store.
CacheSize int
}
Expand Down Expand Up @@ -147,7 +142,6 @@ func Load(dir string, opts Options) (*DB, error) {
walChanSize: opts.AsyncCommitBuffer,
snapshotKeepRecent: opts.SnapshotKeepRecent,
snapshotInterval: opts.SnapshotInterval,
minQueryStates: opts.MinQueryStates,
}

if db.logger == nil {
Expand Down Expand Up @@ -236,32 +230,21 @@ func (db *DB) checkBackgroundSnapshotRewrite() error {
return fmt.Errorf("background snapshot rewriting failed: %w", result.err)
}

db.pendingForSwitch = result.mtree
default:
}

if db.pendingForSwitch == nil {
return nil
}

// catchup the remaining wal
if err := db.pendingForSwitch.CatchupWAL(db.wal, 0); err != nil {
return fmt.Errorf("catchup failed: %w", err)
}
// catchup the remaining wal
if err := result.mtree.CatchupWAL(db.wal, 0); err != nil {
return fmt.Errorf("catchup failed: %w", err)
}

// make sure there are at least a few queryable states after switch
if db.pendingForSwitch.Version() < db.pendingForSwitch.SnapshotVersion()+int64(db.minQueryStates) {
return nil
}
// do the switch
if err := db.reloadMultiTree(result.mtree); err != nil {
return fmt.Errorf("switch multitree failed: %w", err)
}
db.logger.Info("switched to new snapshot", "version", db.MultiTree.Version())

// do the switch
if err := db.reloadMultiTree(db.pendingForSwitch); err != nil {
return fmt.Errorf("switch multitree failed: %w", err)
db.pruneSnapshots()
default:
}
db.logger.Info("switched to new snapshot", "version", db.MultiTree.Version())

db.pendingForSwitch = nil
db.pruneSnapshots()
return nil
}

Expand Down