Skip to content

Commit 7149af5

Browse files
committed
manifest: include *BlobFileMetadata for deleted blob files
Adjust the VersionEdit to include a pointer to deleted blob files' *BlobFileMetadata struct. During runtime when a blob file is deleted, this pointer will be populated. During MANIFEST replay, it will not. This mirrors the mechanics of VersionEdit.DeletedTables. It will be used to faciliate that accounting of zombie blob files at runtime.
1 parent bf1dcd0 commit 7149af5

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

internal/manifest/version_edit.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"encoding/binary"
1212
"fmt"
1313
"io"
14+
"maps"
1415
"slices"
1516
"strings"
1617
"time"
@@ -162,7 +163,10 @@ type VersionEdit struct {
162163
// DeletedBlobFiles holds all blob files that became unreferenced during the
163164
// version edit. These blob files must not be referenced by any sstable in
164165
// the resulting Version.
165-
DeletedBlobFiles []base.DiskFileNum
166+
//
167+
// While replaying a MANIFEST, the values are nil. Otherwise the values must
168+
// not be nil.
169+
DeletedBlobFiles map[base.DiskFileNum]*BlobFileMetadata
166170
}
167171

168172
// Decode decodes an edit from the specified reader.
@@ -536,7 +540,10 @@ func (v *VersionEdit) Decode(r io.Reader) error {
536540
if err != nil {
537541
return err
538542
}
539-
v.DeletedBlobFiles = append(v.DeletedBlobFiles, base.DiskFileNum(fileNum))
543+
if v.DeletedBlobFiles == nil {
544+
v.DeletedBlobFiles = make(map[base.DiskFileNum]*BlobFileMetadata)
545+
}
546+
v.DeletedBlobFiles[base.DiskFileNum(fileNum)] = nil
540547

541548
case tagPrevLogNumber:
542549
n, err := d.readUvarint()
@@ -572,10 +579,7 @@ func (v *VersionEdit) string(verbose bool, fmtKey base.FormatKey) string {
572579
if v.LastSeqNum != 0 {
573580
fmt.Fprintf(&buf, " last-seq-num: %d\n", v.LastSeqNum)
574581
}
575-
entries := make([]DeletedTableEntry, 0, len(v.DeletedTables))
576-
for df := range v.DeletedTables {
577-
entries = append(entries, df)
578-
}
582+
entries := slices.Collect(maps.Keys(v.DeletedTables))
579583
slices.SortFunc(entries, func(a, b DeletedTableEntry) int {
580584
if v := stdcmp.Compare(a.Level, b.Level); v != 0 {
581585
return v
@@ -604,7 +608,9 @@ func (v *VersionEdit) string(verbose bool, fmtKey base.FormatKey) string {
604608
for _, f := range v.NewBlobFiles {
605609
fmt.Fprintf(&buf, " add-blob-file: %s\n", f.String())
606610
}
607-
for _, df := range v.DeletedBlobFiles {
611+
deletedBlobFiles := slices.Collect(maps.Keys(v.DeletedBlobFiles))
612+
slices.Sort(deletedBlobFiles)
613+
for _, df := range deletedBlobFiles {
608614
fmt.Fprintf(&buf, " del-blob-file: %s\n", df)
609615
}
610616
return buf.String()
@@ -686,7 +692,10 @@ func ParseVersionEditDebug(s string) (_ *VersionEdit, err error) {
686692
ve.NewBlobFiles = append(ve.NewBlobFiles, meta)
687693

688694
case "del-blob-file":
689-
ve.DeletedBlobFiles = append(ve.DeletedBlobFiles, p.DiskFileNum())
695+
if ve.DeletedBlobFiles == nil {
696+
ve.DeletedBlobFiles = make(map[base.DiskFileNum]*BlobFileMetadata)
697+
}
698+
ve.DeletedBlobFiles[p.DiskFileNum()] = nil
690699

691700
default:
692701
return nil, errors.Errorf("field %q not implemented", field)
@@ -821,7 +830,7 @@ func (v *VersionEdit) Encode(w io.Writer) error {
821830
e.writeUvarint(x.ValueSize)
822831
e.writeUvarint(x.CreationTime)
823832
}
824-
for _, x := range v.DeletedBlobFiles {
833+
for x := range v.DeletedBlobFiles {
825834
e.writeUvarint(tagDeletedBlobFile)
826835
e.writeUvarint(uint64(x))
827836
}
@@ -937,7 +946,7 @@ type BulkVersionEdit struct {
937946
// any sstables, making them obsolete within the resulting version (a
938947
// zombie if still referenced by previous versions). Deleted file
939948
// numbers must not exist in Added.
940-
Deleted []base.DiskFileNum
949+
Deleted map[base.DiskFileNum]*BlobFileMetadata
941950
// DeletedReferences holds metadata of blob files referenced by tables
942951
// deleted in the accumulated version edits. This is used during replay
943952
// to populate the *BlobFileMetadata pointers of new blob references,
@@ -1015,8 +1024,8 @@ func (b *BulkVersionEdit) Accumulate(ve *VersionEdit) error {
10151024
b.BlobFiles.Added[nbf.FileNum] = nbf
10161025
}
10171026

1018-
b.BlobFiles.Deleted = slices.Grow(b.BlobFiles.Deleted, len(ve.DeletedBlobFiles))
1019-
for _, dbf := range ve.DeletedBlobFiles {
1027+
b.BlobFiles.Deleted = make(map[base.DiskFileNum]*BlobFileMetadata, len(ve.DeletedBlobFiles))
1028+
for dbf, blobMeta := range ve.DeletedBlobFiles {
10201029
// If the blob file was added in a prior, accumulated version edit we
10211030
// can resolve the deletion by removing it from the added files map.
10221031
// Otherwise the blob file deleted was added prior to this bulk edit,
@@ -1025,7 +1034,7 @@ func (b *BulkVersionEdit) Accumulate(ve *VersionEdit) error {
10251034
if b.BlobFiles.Added != nil && b.BlobFiles.Added[dbf] != nil {
10261035
delete(b.BlobFiles.Added, dbf)
10271036
} else {
1028-
b.BlobFiles.Deleted = append(b.BlobFiles.Deleted, dbf)
1037+
b.BlobFiles.Deleted[dbf] = blobMeta
10291038
}
10301039
}
10311040

@@ -1307,7 +1316,10 @@ func (b *BulkVersionEdit) Apply(curr *Version, readCompactionRate int64) (*Versi
13071316
for _, deletedLevel := range b.DeletedTables {
13081317
for _, dt := range deletedLevel {
13091318
for _, ref := range dt.BlobReferences {
1310-
if ref.Metadata.ActiveRefs.count == 0 && !slices.Contains(b.BlobFiles.Deleted, ref.FileNum) {
1319+
if ref.Metadata.ActiveRefs.count != 0 {
1320+
continue
1321+
}
1322+
if _, ok := b.BlobFiles.Deleted[ref.FileNum]; !ok {
13111323
panic(errors.AssertionFailedf("blob file %s has no active refs, but was not deleted in the version edit", ref.FileNum))
13121324
}
13131325
}

0 commit comments

Comments
 (0)