Skip to content

Commit 7b270fe

Browse files
craig[bot]xinhaoz
andcommitted
Merge #152358
152358: storage: fix pebble benchmarks r=xinhaoz a=xinhaoz Some benchmarks copy over initial fs state, which includes the min version file, after fs/env initialization. Make sure to set and validate the store cluster version after the copy. Epic: none Release note: None Co-authored-by: Xin Hao Zhang <[email protected]>
2 parents 95c108d + 24c7464 commit 7b270fe

File tree

4 files changed

+77
-57
lines changed

4 files changed

+77
-57
lines changed

pkg/storage/bench_data_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ func getInitialStateEngine(
107107
require.NoError(b, err)
108108
require.True(b, ok)
109109

110+
// Validate and set the minversion for the env after copy.
111+
settings := cluster.MakeClusterSettings()
112+
env.StoreClusterVersion, err = fs.ValidateMinVersionFile(env.UnencryptedFS, env.Dir, settings.Version)
113+
require.NoError(b, err)
114+
110115
if !inMemory {
111116
// Load all the files into the OS buffer cache for better determinism.
112117
testutils.ReadAllFiles(filepath.Join(env.Dir, "*"))

pkg/storage/fs/fs.go

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -203,54 +203,11 @@ func InitEnv(
203203
return nil, err
204204
}
205205

206-
// Read the current store cluster version.
207-
storeClusterVersion, minVerFileExists, err := GetMinVersion(e.UnencryptedFS, e.Dir)
206+
e.StoreClusterVersion, err = ValidateMinVersionFile(e.UnencryptedFS, e.Dir, cfg.Version)
208207
if err != nil {
209208
return nil, err
210209
}
211210

212-
if minVerFileExists {
213-
v := cfg.Version
214-
if v == nil {
215-
return nil, errors.New("version must not be nil when min-version file exists")
216-
}
217-
// Avoid running a binary too new for this store. This is what you'd catch
218-
// if, say, you restarted directly from v21.2 into v22.2 (bumping the min
219-
// version) without going through v22.1 first.
220-
//
221-
// Note that "going through" above means that v22.1 successfully upgrades
222-
// all existing stores. If v22.1 crashes half-way through the startup
223-
// sequence (so now some stores have v21.2, but others v22.1) you are
224-
// expected to run v22.1 again (hopefully without the crash this time) which
225-
// would then rewrite all the stores.
226-
if storeClusterVersion.Less(v.MinSupportedVersion()) {
227-
if storeClusterVersion.Major < clusterversion.DevOffset && v.LatestVersion().Major >= clusterversion.DevOffset {
228-
return nil, errors.Errorf(
229-
"store last used with cockroach non-development version v%s "+
230-
"cannot be opened by development version v%s",
231-
storeClusterVersion, v.LatestVersion(),
232-
)
233-
}
234-
return nil, errors.Errorf(
235-
"store last used with cockroach version v%s "+
236-
"is too old for running version v%s (which requires data from v%s or later)",
237-
storeClusterVersion, v.LatestVersion(), v.MinSupportedVersion(),
238-
)
239-
}
240-
241-
// Avoid running a binary too old for this store. This protects against
242-
// scenarios where an older binary attempts to open a store created by
243-
// a newer version that may have incompatible data structures or formats.
244-
if v.LatestVersion().Less(storeClusterVersion) {
245-
return nil, errors.Errorf(
246-
"store last used with cockroach version v%s is too high for running "+
247-
"version v%s",
248-
storeClusterVersion, v.LatestVersion(),
249-
)
250-
}
251-
e.StoreClusterVersion = storeClusterVersion
252-
}
253-
254211
// Validate and configure encryption-at-rest. If no encryption-at-rest
255212
// configuration was provided, resolveEncryptedEnvOptions will validate that
256213
// there is no file registry.

pkg/storage/fs/min_version.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package fs
88
import (
99
"io"
1010

11+
"github.com/cockroachdb/cockroach/pkg/clusterversion"
1112
"github.com/cockroachdb/cockroach/pkg/roachpb"
1213
"github.com/cockroachdb/cockroach/pkg/util/protoutil"
1314
"github.com/cockroachdb/errors"
@@ -66,3 +67,57 @@ func GetMinVersion(atomicRenameFS vfs.FS, dir string) (_ roachpb.Version, ok boo
6667
}
6768
return version, true, nil
6869
}
70+
71+
// ValidateMinVersionFile validates the store cluster version found
72+
// in the min-version file in against the provided cluster version.
73+
func ValidateMinVersionFile(
74+
fs vfs.FS, dir string, clusterVersion clusterversion.Handle,
75+
) (roachpb.Version, error) {
76+
// Read the current store cluster version.
77+
storeClusterVersion, minVerFileExists, err := GetMinVersion(fs, dir)
78+
if !minVerFileExists || err != nil {
79+
return storeClusterVersion, err
80+
}
81+
82+
v := clusterVersion
83+
if v == nil {
84+
return storeClusterVersion, errors.New("cluster version must be provided if min version file exists")
85+
}
86+
87+
// Avoid running a binary too new for this store. This is what you'd catch
88+
// if, say, you restarted directly from v21.2 into v22.2 (bumping the min
89+
// version) without going through v22.1 first.
90+
//
91+
// Note that "going through" above means that v22.1 successfully upgrades
92+
// all existing stores. If v22.1 crashes half-way through the startup
93+
// sequence (so now some stores have v21.2, but others v22.1) you are
94+
// expected to run v22.1 again (hopefully without the crash this time) which
95+
// would then rewrite all the stores.
96+
if storeClusterVersion.Less(v.MinSupportedVersion()) {
97+
if storeClusterVersion.Major < clusterversion.DevOffset && v.LatestVersion().Major >= clusterversion.DevOffset {
98+
return storeClusterVersion, errors.Errorf(
99+
"store last used with cockroach non-development version v%s "+
100+
"cannot be opened by development version v%s",
101+
storeClusterVersion, v.LatestVersion(),
102+
)
103+
}
104+
return storeClusterVersion, errors.Errorf(
105+
"store last used with cockroach version v%s "+
106+
"is too old for running version v%s (which requires data from v%s or later)",
107+
storeClusterVersion, v.LatestVersion(), v.MinSupportedVersion(),
108+
)
109+
}
110+
111+
// Avoid running a binary too old for this store. This protects against
112+
// scenarios where an older binary attempts to open a store created by
113+
// a newer version that may have incompatible data structures or formats.
114+
if v.LatestVersion().Less(storeClusterVersion) {
115+
return storeClusterVersion, errors.Errorf(
116+
"store last used with cockroach version v%s is too high for running "+
117+
"version v%s",
118+
storeClusterVersion, v.LatestVersion(),
119+
)
120+
}
121+
122+
return storeClusterVersion, nil
123+
}

pkg/storage/pebble.go

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,20 +1080,23 @@ func newPebble(ctx context.Context, cfg engineConfig) (p *Pebble, err error) {
10801080
// store should already exist or not.
10811081
initFromMinVersionFile := cfg.env.StoreClusterVersion != (roachpb.Version{})
10821082

1083-
if !initFromMinVersionFile && (cfg.opts.ErrorIfNotExists || cfg.opts.ReadOnly) {
1084-
filename := p.cfg.env.UnencryptedFS.PathJoin(cfg.env.Dir, fs.MinVersionFilename)
1085-
return nil, errors.Errorf(
1086-
"pebble: database %q does not exist (missing required file %q)",
1087-
cfg.env.Dir, filename,
1088-
)
1083+
if !initFromMinVersionFile {
1084+
if cfg.opts.ErrorIfNotExists || cfg.opts.ReadOnly {
1085+
filename := p.cfg.env.UnencryptedFS.PathJoin(cfg.env.Dir, fs.MinVersionFilename)
1086+
return nil, errors.Errorf(
1087+
"pebble: database %q does not exist (missing required file %q)",
1088+
cfg.env.Dir, filename,
1089+
)
1090+
}
1091+
// If there is no min version file, there should be no store. If there is
1092+
// one, it's either 1) a store from a very old version (which we don't want
1093+
// to open) or 2) an empty store that was created from a previous bootstrap
1094+
// attempt that failed right before writing out the min version file. We set
1095+
// a flag to disallow the open in case 1.
1096+
cfg.opts.ErrorIfNotPristine = true
1097+
} else {
1098+
cfg.opts.ErrorIfNotExists = true
10891099
}
1090-
cfg.opts.ErrorIfNotExists = cfg.opts.ErrorIfNotExists || initFromMinVersionFile
1091-
// If there is no min version file, there should be no store. If there is
1092-
// one, it's either 1) a store from a very old version (which we don't want
1093-
// to open) or 2) an empty store that was created from a previous bootstrap
1094-
// attempt that failed right before writing out the min version file. We set
1095-
// a flag to disallow the open in case 1.
1096-
cfg.opts.ErrorIfNotPristine = !initFromMinVersionFile
10971100

10981101
if WorkloadCollectorEnabled {
10991102
p.replayer.Attach(cfg.opts)

0 commit comments

Comments
 (0)