Skip to content

Commit d38f16c

Browse files
committed
prevent panic after mmap failure
1 parent 3eac9d3 commit d38f16c

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

db.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -247,10 +247,14 @@ func Open(path string, mode os.FileMode, options *Options) (*DB, error) {
247247
},
248248
}
249249

250-
// Memory map the data file.
251-
if err := db.mmap(options.InitialMmapSize); err != nil {
252-
_ = db.close()
253-
return nil, err
250+
// Memory-map the data file as a byte slice.
251+
if err := mmap(db, size); err != nil {
252+
// mmap failed; the system may have run out of space. Fallback to
253+
// mapping the bare minimum needed for the current db size.
254+
if err2 := mmap(db, db.datasz); err2 != nil {
255+
panic(fmt.Sprintf("failed to revert db size after failed mmap: %v", err2))
256+
}
257+
return MmapError(err.Error())
254258
}
255259

256260
if db.readOnly {

errors.go

+7
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,10 @@ var (
6969
// non-bucket key on an existing bucket key.
7070
ErrIncompatibleValue = errors.New("incompatible value")
7171
)
72+
73+
// MmapError represents an error resulting from a failed mmap call. Typically,
74+
// this error means that no further database writes will be possible. The most
75+
// common cause is insufficient disk space.
76+
type MmapError string
77+
78+
func (e MmapError) Error() string { return string(e) }

0 commit comments

Comments
 (0)