Repository: cockroachdb/pebble
Pull request #4064 (2024-10-17 02:24:09)

db: fix a few instances of the wrong table format
Fix a couple instances where the format of a sstable was solely a function of the format major version's maximum supported format, and settings like EnableColumnarBlocks and EnableValueBlocks were not respected.

cockroach-teamcity: 

<!-- Reviewable:start -->
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/cockroachdb/pebble/4064)
<!-- Reviewable:end -->


Patch:
diff --git a/compaction.go b/compaction.go
index d6a516be..ca3d7749 100644
--- a/compaction.go
+++ b/compaction.go
@@ -2174,6 +2174,53 @@ func (d *DB) compact(c *compaction, errChannel chan error) {
 	})
 }
 
+// cleanupVersionEdit cleans up any on-disk artifacts that were created
+// for the application of a versionEdit that is no longer going to be applied.
+//
+// d.mu must be held when calling this method.
+func (d *DB) cleanupVersionEdit(ve *versionEdit) {
+	obsoleteFiles := make([]*fileBacking, 0, len(ve.NewFiles))
+	deletedFiles := make(map[base.FileNum]struct{})
+	for key := range ve.DeletedFiles {
+		deletedFiles[key.FileNum] = struct{}{}
+	}
+	for i := range ve.NewFiles {
+		if ve.NewFiles[i].Meta.Virtual {
+			// We handle backing files separately.
+			continue
+		}
+		if _, ok := deletedFiles[ve.NewFiles[i].Meta.FileNum]; ok {
+			// This file is being moved in this ve to a different level.
+			// Don't mark it as obsolete.
+			continue
+		}
+		obsoleteFiles = append(obsoleteFiles, ve.NewFiles[i].Meta.PhysicalMeta().FileBacking)
+	}
+	for i := range ve.CreatedBackingTables {
+		if ve.CreatedBackingTables[i].IsUnused() {
+			obsoleteFiles = append(obsoleteFiles, ve.CreatedBackingTables[i])
+		}
+	}
+	for i := range obsoleteFiles {
+		// Add this file to zombie tables as well, as the versionSet
+		// asserts on whether every obsolete file was at one point
+		// marked zombie.
+		d.mu.versions.zombieTables[obsoleteFiles[i].DiskFileNum] = tableInfo{
+			fileInfo: fileInfo{
+				FileNum:  obsoleteFiles[i].DiskFileNum,
+				FileSize: obsoleteFiles[i].Size,
+			},
+			// TODO(bilal): This is harmless if it's wrong, as it only causes
+			// incorrect accounting for the size of it in metrics. Currently
+			// all compactions only write to local files anyway except with
+			// disaggregated storage; if this becomes the norm, we should do
+			// an objprovider lookup here.
+			isLocal: true,
+		}
+	}
+	d.mu.versions.addObsoleteLocked(obsoleteFiles)
+}
+
 // compact1 runs one compaction.
 //
 // d.mu must be held when calling this, but the mutex may be dropped and
@@ -2204,8 +2251,11 @@ func (d *DB) compact1(c *compaction, errChannel chan error) (err error) {
 			// as only the holder of the manifest lock will ever write to it.
 			if c.cancel.Load() {
 				err = firstError(err, ErrCancelledCompaction)
-			}
-			if err != nil {
+				// This is the first time we've seen a cancellation during the
+				// life of this compaction (or the original condition on err == nil
+				// would not have been true). We should delete any tables already
+				// created, as d.runCompaction did not do that.
+				d.cleanupVersionEdit(ve)
 				// logAndApply calls logUnlock. If we didn't call it, we need to call
 				// logUnlock ourselves.
 				d.mu.versions.logUnlock()
@@ -2390,7 +2440,7 @@ func (d *DB) runCopyCompaction(
 			var err error
 			wrote, err = sstable.CopySpan(ctx,
 				src, r.UnsafeReader(), d.opts.MakeReaderOptions(),
-				w, d.opts.MakeWriterOptions(c.outputLevel.level, d.FormatMajorVersion().MaxTableFormat()),
+				w, d.opts.MakeWriterOptions(c.outputLevel.level, d.TableFormat()),
 				start, end,
 			)
 			return err
@@ -2735,7 +2785,7 @@ func (d *DB) runCompaction(
 	// The table is typically written at the maximum allowable format implied by
 	// the current format major version of the DB, but Options may define
 	// additional constraints.
-	tableFormat := d.tableFormat()
+	tableFormat := d.TableFormat()
 
 	// Release the d.mu lock while doing I/O.
 	// Note the unusual order: Unlock and then Lock.
@@ -2748,9 +2798,27 @@ func (d *DB) runCompaction(
 	}
 	if result.Err != nil {
 		// Delete any created tables.
+		obsoleteFiles := make([]*fileBacking, 0, len(result.Tables))
+		d.mu.Lock()
 		for i := range result.Tables {
-			_ = d.objProvider.Remove(fileTypeTable, result.Tables[i].ObjMeta.DiskFileNum)
+			backing := &fileBacking{
+				DiskFileNum: result.Tables[i].ObjMeta.DiskFileNum,
+				Size:        result.Tables[i].WriterMeta.Size,
+			}
+			obsoleteFiles = append(obsoleteFiles, backing)
+			// Add this file to zombie tables as well, as the versionSet
+			// asserts on whether every obsolete file was at one point
+			// marked zombie.
+			d.mu.versions.zombieTables[backing.DiskFileNum] = tableInfo{
+				fileInfo: fileInfo{
+					FileNum:  backing.DiskFileNum,
+					FileSize: backing.Size,
+				},
+				isLocal: true,
+			}
 		}
+		d.mu.versions.addObsoleteLocked(obsoleteFiles)
+		d.mu.Unlock()
 	}
 	// Refresh the disk available statistic whenever a compaction/flush
 	// completes, before re-acquiring the mutex.
diff --git a/format_major_version.go b/format_major_version.go
index 434cef71..09607996 100644
--- a/format_major_version.go
+++ b/format_major_version.go
@@ -338,8 +338,11 @@ func (d *DB) FormatMajorVersion() FormatMajorVersion {
 	return FormatMajorVersion(d.mu.formatVers.vers.Load())
 }
 
-// tableFormat returns the TableFormat that new sstables should use.
-func (d *DB) tableFormat() sstable.TableFormat {
+// TableFormat returns the TableFormat that the database is currently using when
+// writing sstables. The table format is determined by the database's format
+// major version, as well as experimental settings like EnableValueBlocks and
+// EnableColumnarBlocks.
+func (d *DB) TableFormat() sstable.TableFormat {
 	// The table is typically written at the maximum allowable format implied by
 	// the current format major version of the DB.
 	f := d.FormatMajorVersion().MaxTableFormat()
diff --git a/internal/manifest/version.go b/internal/manifest/version.go
index abf61e31..45e5c7cf 100644
--- a/internal/manifest/version.go
+++ b/internal/manifest/version.go
@@ -470,6 +470,12 @@ func (b *FileBacking) Ref() {
 	b.refs.Add(1)
 }
 
+// IsUnused returns if the backing is not being used by any tables in a version
+// or btree.
+func (b *FileBacking) IsUnused() bool {
+	return b.refs.Load() == 0
+}
+
 // Unref decrements the backing's ref count (and returns the new count).
 func (b *FileBacking) Unref() int32 {
 	v := b.refs.Add(-1)
diff --git a/internal/manifest/virtual_backings.go b/internal/manifest/virtual_backings.go
index 110b9f31..e3aa97a3 100644
--- a/internal/manifest/virtual_backings.go
+++ b/internal/manifest/virtual_backings.go
@@ -99,7 +99,7 @@ type backingWithMetadata struct {
 }
 
 // AddAndRef adds a new backing to the set and takes a reference on it. Another
-// backing for the same DiskFilNum must not exist.
+// backing for the same DiskFileNum must not exist.
 //
 // The added backing is unused until it is associated with a table via AddTable
 // or protected via Protect.
diff --git a/metamorphic/ops.go b/metamorphic/ops.go
index 7c5ff02f..3d3438ff 100644
--- a/metamorphic/ops.go
+++ b/metamorphic/ops.go
@@ -2048,7 +2048,7 @@ func (r *replicateOp) run(t *Test, h historyRecorder) {
 		h.Recordf("%s // %v", r, err)
 		return
 	}
-	w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), t.opts.MakeWriterOptions(0, dest.FormatMajorVersion().MaxTableFormat()))
+	w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), t.opts.MakeWriterOptions(0, dest.TableFormat()))
 
 	// NB: In practice we'll either do shared replicate or external replicate,
 	// as ScanInternal does not support both. We arbitrarily choose to prioritize
diff --git a/tool/db.go b/tool/db.go
index da63cc96..499c954d 100644
--- a/tool/db.go
+++ b/tool/db.go
@@ -615,7 +615,7 @@ func (d *dbT) runExcise(cmd *cobra.Command, args []string) {
 		return
 	}
 	writable := objstorageprovider.NewFileWritable(f)
-	writerOpts := dbOpts.MakeWriterOptions(0, db.FormatMajorVersion().MaxTableFormat())
+	writerOpts := dbOpts.MakeWriterOptions(0, db.TableFormat())
 	w := sstable.NewWriter(writable, writerOpts)
 	err = w.DeleteRange(span.Start, span.End)
 	err = errors.CombineErrors(err, w.RangeKeyDelete(span.Start, span.End))


Test patch:
diff --git a/compaction_picker_test.go b/compaction_picker_test.go
index 148a2785..2272457b 100644
--- a/compaction_picker_test.go
+++ b/compaction_picker_test.go
@@ -1355,6 +1355,7 @@ func TestCompactionPickerPickFile(t *testing.T) {
 		FormatMajorVersion: FormatNewest,
 		FS:                 fs,
 	}
+	opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 
 	d, err := Open("", opts)
 	require.NoError(t, err)
@@ -1473,6 +1474,7 @@ func TestCompactionPickerScores(t *testing.T) {
 		FormatMajorVersion:          FormatNewest,
 		FS:                          fs,
 	}
+	opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 
 	d, err := Open("", opts)
 	require.NoError(t, err)
diff --git a/compaction_test.go b/compaction_test.go
index bce7f962..00a1d30d 100644
--- a/compaction_test.go
+++ b/compaction_test.go
@@ -2102,7 +2102,7 @@ func TestCompactionErrorCleanup(t *testing.T) {
 		require.NoError(t, err)
 
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		for _, k := range keys {
 			require.NoError(t, w.Set([]byte(k), nil))
@@ -2797,7 +2797,7 @@ func TestCompactionErrorStats(t *testing.T) {
 		require.NoError(t, err)
 
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		for _, k := range keys {
 			require.NoError(t, w.Set([]byte(k), nil))
diff --git a/data_test.go b/data_test.go
index 894f4290..b6bfb5a5 100644
--- a/data_test.go
+++ b/data_test.go
@@ -543,7 +543,7 @@ func runBuildRemoteCmd(td *datadriven.TestData, d *DB, storage remote.Storage) e
 	path := td.CmdArgs[0].String()
 
 	// Override table format, if provided.
-	tableFormat := d.opts.FormatMajorVersion.MaxTableFormat()
+	tableFormat := d.TableFormat()
 	var blockSize int64
 	for _, cmdArg := range td.CmdArgs[1:] {
 		switch cmdArg.Key {
@@ -646,7 +646,7 @@ func runBuildCmd(td *datadriven.TestData, d *DB, fs vfs.FS) error {
 	path := td.CmdArgs[0].String()
 
 	// Override table format, if provided.
-	tableFormat := d.opts.FormatMajorVersion.MaxTableFormat()
+	tableFormat := d.TableFormat()
 	for _, cmdArg := range td.CmdArgs[1:] {
 		switch cmdArg.Key {
 		case "format":
diff --git a/db_test.go b/db_test.go
index c47e6900..81be1645 100644
--- a/db_test.go
+++ b/db_test.go
@@ -1178,7 +1178,7 @@ func TestDBConcurrentCompactClose(t *testing.T) {
 			f, err := mem.Create(path, vfs.WriteCategoryUnspecified)
 			require.NoError(t, err)
 			w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-				TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+				TableFormat: d.TableFormat(),
 			})
 			require.NoError(t, w.Set([]byte(fmt.Sprint(j)), nil))
 			require.NoError(t, w.Close())
@@ -1638,7 +1638,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.Set([]byte("cc"), []byte("foo")))
 		require.NoError(t, w.Close())
@@ -1649,7 +1649,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.Set([]byte("bb"), []byte("foo2")))
 		require.NoError(t, w.Set([]byte("cc"), []byte("foo2")))
@@ -1661,7 +1661,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.Set([]byte("bb"), []byte("foo3")))
 		require.NoError(t, w.Close())
@@ -1672,7 +1672,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.Set([]byte("bb"), []byte("foo4")))
 		require.NoError(t, w.Close())
@@ -1751,7 +1751,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.DeleteRange([]byte("cc"), []byte("e")))
 		require.NoError(t, w.Close())
@@ -1785,7 +1785,7 @@ func TestMemtableIngestInversion(t *testing.T) {
 		f, err := memFS.Create(path, vfs.WriteCategoryUnspecified)
 		require.NoError(t, err)
 		w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-			TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+			TableFormat: d.TableFormat(),
 		})
 		require.NoError(t, w.Set([]byte("cc"), []byte("doesntmatter")))
 		require.NoError(t, w.Close())
diff --git a/event_listener_test.go b/event_listener_test.go
index 286f701c..4746570a 100644
--- a/event_listener_test.go
+++ b/event_listener_test.go
@@ -141,7 +141,7 @@ func TestEventListener(t *testing.T) {
 				return err.Error()
 			}
 			w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-				TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+				TableFormat: d.TableFormat(),
 			})
 			if err := w.Set([]byte("a"), nil); err != nil {
 				return err.Error()
@@ -175,7 +175,7 @@ func TestEventListener(t *testing.T) {
 					return err
 				}
 				w := sstable.NewWriter(objstorageprovider.NewFileWritable(f), sstable.WriterOptions{
-					TableFormat: d.FormatMajorVersion().MaxTableFormat(),
+					TableFormat: d.TableFormat(),
 				})
 				if err := w.Set([]byte{key}, nil); err != nil {
 					return err
diff --git a/external_iterator_test.go b/external_iterator_test.go
index 3b7012ad..66fa57ff 100644
--- a/external_iterator_test.go
+++ b/external_iterator_test.go
@@ -24,6 +24,7 @@ func TestExternalIterator(t *testing.T) {
 		FormatMajorVersion: internalFormatNewest,
 		Comparer:           testkeys.Comparer,
 	}
+	o.Experimental.EnableColumnarBlocks = func() bool { return true }
 	o.testingRandomized(t)
 	o.EnsureDefaults()
 	d, err := Open("", o)
diff --git a/ingest_test.go b/ingest_test.go
index 4cd922c2..e8f5da50 100644
--- a/ingest_test.go
+++ b/ingest_test.go
@@ -468,6 +468,7 @@ func TestOverlappingIngestedSSTs(t *testing.T) {
 			FormatMajorVersion:          internalFormatNewest,
 			Logger:                      testLogger{t},
 		}).WithFSDefaults()
+		opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 		if testing.Verbose() {
 			lel := MakeLoggingEventListener(DefaultLogger)
 			opts.EventListener = &lel
@@ -1124,7 +1125,7 @@ func testIngestSharedImpl(
 			startKey := []byte(td.CmdArgs[2].Key)
 			endKey := []byte(td.CmdArgs[3].Key)
 
-			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.opts.FormatMajorVersion.MaxTableFormat())
+			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.TableFormat())
 			sstPath := fmt.Sprintf("ext/replicate%d.sst", replicateCounter)
 			f, err := to.opts.FS.Create(sstPath, vfs.WriteCategoryUnspecified)
 			require.NoError(t, err)
@@ -1372,7 +1373,7 @@ func TestSimpleIngestShared(t *testing.T) {
 		fn := base.FileNum(2)
 		f, meta, err := provider2.Create(context.TODO(), fileTypeTable, base.PhysicalTableDiskFileNum(fn), objstorage.CreateOptions{PreferSharedStorage: true})
 		require.NoError(t, err)
-		w := sstable.NewWriter(f, d.opts.MakeWriterOptions(0, d.opts.FormatMajorVersion.MaxTableFormat()))
+		w := sstable.NewWriter(f, d.opts.MakeWriterOptions(0, d.TableFormat()))
 		w.Set([]byte("d"), []byte("shared"))
 		w.Set([]byte("e"), []byte("shared"))
 		w.Close()
@@ -1625,7 +1626,7 @@ func TestConcurrentExcise(t *testing.T) {
 			startKey := []byte(td.CmdArgs[2].Key)
 			endKey := []byte(td.CmdArgs[3].Key)
 
-			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.opts.FormatMajorVersion.MaxTableFormat())
+			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.TableFormat())
 			sstPath := fmt.Sprintf("ext/replicate%d.sst", replicateCounter)
 			f, err := to.opts.FS.Create(sstPath, vfs.WriteCategoryUnspecified)
 			require.NoError(t, err)
@@ -1879,6 +1880,7 @@ func TestIngestExternal(t *testing.T) {
 			FormatMajorVersion: majorVersion,
 			Logger:             testLogger{t},
 		}
+		opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 		opts.Experimental.RemoteStorage = remote.MakeSimpleFactory(map[remote.Locator]remote.Storage{
 			"external-locator": remoteStorage,
 		})
@@ -2061,7 +2063,7 @@ func TestIngestExternal(t *testing.T) {
 			startKey := []byte(td.CmdArgs[2].Key)
 			endKey := []byte(td.CmdArgs[3].Key)
 
-			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.opts.FormatMajorVersion.MaxTableFormat())
+			writeOpts := d.opts.MakeWriterOptions(0 /* level */, to.TableFormat())
 			sstPath := fmt.Sprintf("ext/replicate%d.sst", replicateCounter)
 			f, err := to.opts.FS.Create(sstPath, vfs.WriteCategoryUnspecified)
 			require.NoError(t, err)
@@ -2413,6 +2415,7 @@ func TestIngest(t *testing.T) {
 			}},
 			FormatMajorVersion: internalFormatNewest,
 		}
+		opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 		opts.Experimental.IngestSplit = func() bool {
 			return split
 		}
diff --git a/iterator_test.go b/iterator_test.go
index 110265d0..d83b986c 100644
--- a/iterator_test.go
+++ b/iterator_test.go
@@ -612,6 +612,7 @@ func TestIteratorStats(t *testing.T) {
 		opts := &Options{Comparer: testkeys.Comparer, FS: mem, FormatMajorVersion: internalFormatNewest}
 		// Automatic compactions may make some testcases non-deterministic.
 		opts.DisableAutomaticCompactions = true
+		opts.Experimental.EnableColumnarBlocks = func() bool { return true }
 		var err error
 		d, err = Open("", opts)
 		require.NoError(t, err)
@@ -2718,10 +2719,10 @@ func BenchmarkSeekPrefixTombstones(b *testing.B) {
 		Comparer:           testkeys.Comparer,
 		FormatMajorVersion: FormatNewest,
 	}).EnsureDefaults()
-	wOpts := o.MakeWriterOptions(numLevels-1, FormatNewest.MaxTableFormat())
 	d, err := Open("", o)
 	require.NoError(b, err)
 	defer func() { require.NoError(b, d.Close()) }()
+	wOpts := o.MakeWriterOptions(numLevels-1, d.TableFormat())
 
 	// Keep a snapshot open for the duration of the test to prevent elision-only
 	// compactions from removing the ingested files containing exclusively
diff --git a/testdata/compaction_picker_pick_file b/testdata/compaction_picker_pick_file
index d9991fd7..6fb3891b 100644
--- a/testdata/compaction_picker_pick_file
+++ b/testdata/compaction_picker_pick_file
@@ -16,9 +16,9 @@ L2:
 file-sizes
 ----
 L1:
-  000004:[b#11,SET-c#11,SET]: 597 bytes (597B)
+  000004:[b#11,SET-c#11,SET]: 743 bytes (743B)
 L2:
-  000005:[c#0,SET-d#0,SET]: 596 bytes (596B)
+  000005:[c#0,SET-d#0,SET]: 730 bytes (730B)
 
 pick-file L1
 ----
@@ -131,12 +131,12 @@ L6:
 file-sizes
 ----
 L5:
-  000004:[c#11,SET-e#11,SET]: 99086 bytes (97KB)
-  000005:[f#11,SET-f#11,SET]: 57942 bytes (57KB)
+  000004:[c#11,SET-e#11,SET]: 99369 bytes (97KB)
+  000005:[f#11,SET-f#11,SET]: 58090 bytes (57KB)
 L6:
-  000006:[c#0,SET-c#0,SET]: 66134 bytes (65KB)
-  000007:[e#0,SET-e#0,SET]: 66134 bytes (65KB)
-  000008:[f#0,SET-f#0,SET]: 66134 bytes (65KB)
+  000006:[c#0,SET-c#0,SET]: 66284 bytes (65KB)
+  000007:[e#0,SET-e#0,SET]: 66284 bytes (65KB)
+  000008:[f#0,SET-f#0,SET]: 66284 bytes (65KB)
 
 # Sst 5 is picked since 65KB/57KB is less than 130KB/97KB.
 pick-file L5
@@ -166,14 +166,14 @@ L6:
 file-sizes
 ----
 L5:
-  000010:[c#11,SET-c#11,SET]: 32796 bytes (32KB)
-  000011:[e#11,SET-e#11,SET]: 126 bytes (126B)
-  000005:[f#11,SET-f#11,SET]: 57942 bytes (57KB)
+  000010:[c#11,SET-c#11,SET]: 32862 bytes (32KB)
+  000011:[e#11,SET-e#11,SET]: 191 bytes (191B)
+  000005:[f#11,SET-f#11,SET]: 58090 bytes (57KB)
 L6:
-  000006:[c#0,SET-c#0,SET]: 66134 bytes (65KB)
+  000006:[c#0,SET-c#0,SET]: 66284 bytes (65KB)
   000009:[d#13,SET-d#13,SET]: 728 bytes (728B)
-  000007:[e#0,SET-e#0,SET]: 66134 bytes (65KB)
-  000008:[f#0,SET-f#0,SET]: 66134 bytes (65KB)
+  000007:[e#0,SET-e#0,SET]: 66284 bytes (65KB)
+  000008:[f#0,SET-f#0,SET]: 66284 bytes (65KB)
 
 # Superficially, sst 10 causes write amp of 65KB/32KB which is worse than sst
 # 5. But the garbage of ~64KB in the backing sst 4 is equally distributed
@@ -206,13 +206,13 @@ L6:
 file-sizes
 ----
 L5:
-  000011:[e#11,SET-e#11,SET]: 126 bytes (126B)
-  000005:[f#11,SET-f#11,SET]: 57942 bytes (57KB)
+  000011:[e#11,SET-e#11,SET]: 191 bytes (191B)
+  000005:[f#11,SET-f#11,SET]: 58090 bytes (57KB)
 L6:
   000012:[c#15,SET-c#15,SET]: 728 bytes (728B)
   000009:[d#13,SET-d#13,SET]: 728 bytes (728B)
-  000007:[e#0,SET-e#0,SET]: 66134 bytes (65KB)
-  000008:[f#0,SET-f#0,SET]: 66134 bytes (65KB)
+  000007:[e#0,SET-e#0,SET]: 66284 bytes (65KB)
+  000008:[f#0,SET-f#0,SET]: 66284 bytes (65KB)
 
 # Even though picking sst 11 seems to cause poor write amp of 65KB/126B, it is
 # picked because it is blamed for all the garbage in backing sst 4 (~96KB),
diff --git a/testdata/compaction_picker_scores b/testdata/compaction_picker_scores
index bc047323..c56a3a4d 100644
--- a/testdata/compaction_picker_scores
+++ b/testdata/compaction_picker_scores
@@ -24,7 +24,7 @@ L1  	0B     0.0
 L2  	0B     0.0
 L3  	0B     0.0
 L4  	0B     0.0
-L5  	631B   0.0
+L5  	720B   0.0
 L6  	321KB  -
 
 enable-table-stats
@@ -37,7 +37,7 @@ num-entries: 1
 num-deletions: 1
 num-range-key-sets: 0
 point-deletions-bytes-estimate: 0
-range-deletions-bytes-estimate: 328447
+range-deletions-bytes-estimate: 328865
 
 scores
 ----
@@ -47,7 +47,7 @@ L1  	0B     0.0
 L2  	0B     0.0
 L3  	0B     0.0
 L4  	0B     0.0
-L5  	631B   4.5
+L5  	720B   4.5
 L6  	321KB  -
 
 # Ensure that point deletions in a higher level result in a compensated level
@@ -80,7 +80,7 @@ L1  	0B     0.0
 L2  	0B     0.0
 L3  	0B     0.0
 L4  	0B     0.0
-L5  	643B   0.0
+L5  	774B   0.0
 L6  	321KB  -
 
 enable-table-stats
@@ -92,7 +92,7 @@ wait-pending-table-stats
 num-entries: 5
 num-deletions: 5
 num-range-key-sets: 0
-point-deletions-bytes-estimate: 164509
+point-deletions-bytes-estimate: 164784
 range-deletions-bytes-estimate: 0
 
 scores
@@ -103,7 +103,7 @@ L1  	0B     0.0
 L2  	0B     0.0
 L3  	0B     0.0
 L4  	0B     0.0
-L5  	643B   2.3
+L5  	774B   2.3
 L6  	321KB  -
 
 # Run a similar test as above, but this time the table containing the DELs is
@@ -145,7 +145,7 @@ wait-pending-table-stats
 num-entries: 5
 num-deletions: 5
 num-range-key-sets: 0
-point-deletions-bytes-estimate: 164583
+point-deletions-bytes-estimate: 164792
 range-deletions-bytes-estimate: 0
 
 maybe-compact
@@ -206,17 +206,17 @@ L1  	0B     0.0
 L2  	0B     0.0
 L3  	0B     0.0
 L4  	0B     0.0
-L5  	641KB  6.3
-L6  	385KB  -
+L5  	642KB  6.3
+L6  	386KB  -
 
 lsm verbose
 ----
 L5:
-  000004:[aa#2,SET-dd#2,SET] seqnums:[2-2] points:[aa#2,SET-dd#2,SET] size:525021
-  000005:[e#2,SET-e#2,SET] seqnums:[2-2] points:[e#2,SET-e#2,SET] size:131670
+  000004:[aa#2,SET-dd#2,SET] seqnums:[2-2] points:[aa#2,SET-dd#2,SET] size:525373
+  000005:[e#2,SET-e#2,SET] seqnums:[2-2] points:[e#2,SET-e#2,SET] size:131828
 L6:
-  000006:[a#1,SET-d#1,SET] seqnums:[1-1] points:[a#1,SET-d#1,SET] size:262869
-  000007:[e#1,SET-e#1,SET] seqnums:[1-1] points:[e#1,SET-e#1,SET] size:131670
+  000006:[a#1,SET-d#1,SET] seqnums:[1-1] points:[a#1,SET-d#1,SET] size:263225
+  000007:[e#1,SET-e#1,SET] seqnums:[1-1] points:[e#1,SET-e#1,SET] size:131828
 
 # Attempting to schedule a compaction should begin a L5->L6 compaction.
 
diff --git a/testdata/metrics b/testdata/metrics
index c6f42ede..40a74b22 100644
--- a/testdata/metrics
+++ b/testdata/metrics
@@ -476,32 +476,32 @@ metrics
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     4  2.7KB     0B       0 |  0.50 |  187B |     3  2.1KB |     0     0B |     6  3.8KB |    0B |   2 20.6
+    0 |     4  2.3KB     0B       0 |  0.50 |  187B |     3  1.7KB |     0     0B |     6  3.8KB |    0B |   2 20.6
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     6 |     3  2.0KB    41B       0 |     - | 3.2KB |     0     0B |     0     0B |     3  2.0KB | 3.2KB |   1  0.6
-total |     7  4.7KB    41B       0 |     - | 2.3KB |     3  2.1KB |     0     0B |     9  8.1KB | 3.2KB |   3  3.5
+total |     7  4.3KB    41B       0 |     - | 1.9KB |     3  1.7KB |     0     0B |     9  7.7KB | 3.2KB |   3  4.0
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 176B  written: 187B (6% overhead)
 Flushes: 8
-Compactions: 2  estimated debt: 4.7KB  in progress: 0 (0B)
+Compactions: 2  estimated debt: 4.3KB  in progress: 0 (0B)
              default: 2  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 0  multi-level: 0
 MemTables: 1 (1.0MB)  zombie: 1 (1.0MB)
 Zombie tables: 0 (0B, local: 0B)
 Backing tables: 0 (0B)
 Virtual tables: 0 (0B)
-Local tables size: 4.7KB
+Local tables size: 4.3KB
 Compression types: snappy: 7
-Block cache: 8 entries (417B)  hit rate: 9.1%
+Block cache: 8 entries (204B)  hit rate: 9.1%
 Table cache: 1 entries (816B)  hit rate: 53.8%
 Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
 Table iters: 0
 Filter utility: 0.0%
-Ingestions: 2  as flushable: 2 (2.1KB in 3 tables)
+Ingestions: 2  as flushable: 2 (1.7KB in 3 tables)
 Cgo memory usage: 0B  block cache: 0B (data: 0B, maps: 0B, entries: 0B)  memtables: 0B
 Iter category stats:
                    b,     latency: {BlockBytes:44 BlockBytesInCache:0 BlockReadDuration:10ms}
@@ -540,32 +540,32 @@ metrics
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     7  4.5KB     0B       0 |  0.50 |  245B |     3  2.1KB |     0     0B |     9  5.5KB |    0B |   2 23.1
+    0 |     7  4.1KB     0B       0 |  0.50 |  245B |     3  1.7KB |     0     0B |     9  5.5KB |    0B |   2 23.1
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     6 |     3  2.0KB    41B       0 |     - | 3.2KB |     0     0B |     0     0B |     3  2.0KB | 3.2KB |   1  0.6
-total |    10  6.5KB    41B       0 |     - | 2.4KB |     3  2.1KB |     0     0B |    12  9.9KB | 3.2KB |   3  4.2
+total |    10  6.1KB    41B       0 |     - | 2.0KB |     3  1.7KB |     0     0B |    12  9.5KB | 3.2KB |   3  4.8
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 223B  written: 245B (10% overhead)
 Flushes: 9
-Compactions: 2  estimated debt: 6.5KB  in progress: 0 (0B)
+Compactions: 2  estimated debt: 6.1KB  in progress: 0 (0B)
              default: 2  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 0  multi-level: 0
 MemTables: 1 (1.0MB)  zombie: 1 (1.0MB)
 Zombie tables: 0 (0B, local: 0B)
 Backing tables: 0 (0B)
 Virtual tables: 0 (0B)
-Local tables size: 6.5KB
+Local tables size: 6.1KB
 Compression types: snappy: 10
-Block cache: 8 entries (417B)  hit rate: 9.1%
+Block cache: 8 entries (204B)  hit rate: 9.1%
 Table cache: 1 entries (816B)  hit rate: 53.8%
 Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
 Table iters: 0
 Filter utility: 0.0%
-Ingestions: 2  as flushable: 2 (2.1KB in 3 tables)
+Ingestions: 2  as flushable: 2 (1.7KB in 3 tables)
 Cgo memory usage: 0B  block cache: 0B (data: 0B, maps: 0B, entries: 0B)  memtables: 0B
 Iter category stats:
                    b,     latency: {BlockBytes:44 BlockBytesInCache:0 BlockReadDuration:10ms}
@@ -618,24 +618,24 @@ metrics zero-cache-hits-misses
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     7  3.4KB     0B       2 |  0.50 |  245B |     3  2.1KB |     0     0B |     9  5.5KB |    0B |   2 23.1
+    0 |     7  3.0KB     0B       2 |  0.50 |  245B |     3  1.7KB |     0     0B |     9  5.5KB |    0B |   2 23.1
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
-    6 |     4  2.7KB    41B       0 |     - | 3.2KB |     1   728B |     0     0B |     3  2.0KB | 3.2KB |   1  0.6
-total |    11  6.1KB    41B       2 |     - | 3.1KB |     4  2.8KB |     0     0B |    12   11KB | 3.2KB |   3  3.5
+    6 |     4  2.6KB    41B       0 |     - | 3.2KB |     1   589B |     0     0B |     3  2.0KB | 3.2KB |   1  0.6
+total |    11  5.6KB    41B       2 |     - | 2.5KB |     4  2.3KB |     0     0B |    12   10KB | 3.2KB |   3  4.0
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 223B  written: 245B (10% overhead)
 Flushes: 9
-Compactions: 2  estimated debt: 6.1KB  in progress: 0 (0B)
+Compactions: 2  estimated debt: 5.6KB  in progress: 0 (0B)
              default: 2  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 0  multi-level: 0
 MemTables: 1 (1.0MB)  zombie: 1 (1.0MB)
 Zombie tables: 0 (0B, local: 0B)
 Backing tables: 2 (1.2KB)
 Virtual tables: 2 (102B)
-Local tables size: 7.2KB
+Local tables size: 6.7KB
 Compression types: snappy: 9 unknown: 2
 Block cache: 0 entries (0B)  hit rate: 0.0%
 Table cache: 0 entries (0B)  hit rate: 0.0%
@@ -643,7 +643,7 @@ Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
 Table iters: 0
 Filter utility: 0.0%
-Ingestions: 3  as flushable: 2 (2.1KB in 3 tables)
+Ingestions: 3  as flushable: 2 (1.7KB in 3 tables)
 Cgo memory usage: 0B  block cache: 0B (data: 0B, maps: 0B, entries: 0B)  memtables: 0B
 Iter category stats:
                    b,     latency: {BlockBytes:44 BlockBytesInCache:0 BlockReadDuration:10ms}
@@ -721,14 +721,14 @@ metrics zero-cache-hits-misses
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     0     0B     0B       0 |  0.00 |  245B |     3  2.1KB |     0     0B |     9  5.5KB |    0B |   0 23.1
+    0 |     0     0B     0B       0 |  0.00 |  245B |     3  1.7KB |     0     0B |     9  5.5KB |    0B |   0 23.1
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
-    6 |     6  4.1KB    41B       0 |     - | 6.6KB |     2  1.4KB |     0     0B |     4  2.6KB | 6.6KB |   1  0.4
-total |     6  4.1KB    41B       0 |     - | 3.8KB |     5  3.5KB |     0     0B |    13   12KB | 6.6KB |   1  3.2
+    6 |     6  3.8KB    41B       0 |     - | 6.2KB |     2  1.2KB |     0     0B |     4  2.6KB | 6.2KB |   1  0.4
+total |     6  3.8KB    41B       0 |     - | 3.1KB |     5  2.9KB |     0     0B |    13   11KB | 6.2KB |   1  3.6
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 223B  written: 245B (10% overhead)
 Flushes: 9
@@ -738,7 +738,7 @@ MemTables: 1 (1.0MB)  zombie: 1 (1.0MB)
 Zombie tables: 0 (0B, local: 0B)
 Backing tables: 0 (0B)
 Virtual tables: 0 (0B)
-Local tables size: 4.1KB
+Local tables size: 3.8KB
 Compression types: snappy: 6
 Block cache: 0 entries (0B)  hit rate: 0.0%
 Table cache: 0 entries (0B)  hit rate: 0.0%
@@ -746,12 +746,12 @@ Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
 Table iters: 0
 Filter utility: 0.0%
-Ingestions: 4  as flushable: 2 (2.1KB in 3 tables)
+Ingestions: 4  as flushable: 2 (1.7KB in 3 tables)
 Cgo memory usage: 0B  block cache: 0B (data: 0B, maps: 0B, entries: 0B)  memtables: 0B
 Iter category stats:
                    b,     latency: {BlockBytes:44 BlockBytesInCache:0 BlockReadDuration:10ms}
                    c, non-latency: {BlockBytes:44 BlockBytesInCache:44 BlockReadDuration:0s}
-   pebble-compaction, non-latency: {BlockBytes:890 BlockBytesInCache:589 BlockReadDuration:70ms}
+   pebble-compaction, non-latency: {BlockBytes:677 BlockBytesInCache:376 BlockReadDuration:70ms}
        pebble-ingest,     latency: {BlockBytes:272 BlockBytesInCache:72 BlockReadDuration:30ms}
 
 # Create a DB where lower levels are written as shared tables. All ingests also
@@ -863,18 +863,18 @@ metrics
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     1   728B     0B       0 |  0.25 |   38B |     1   728B |     0     0B |     1   604B |    0B |   1 15.9
+    0 |     1   589B     0B       0 |  0.25 |   38B |     1   589B |     0     0B |     1   604B |    0B |   1 15.9
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     6 |     1   604B     0B       0 |     - |  604B |     0     0B |     0     0B |     1   604B |    0B |   1  1.0
-total |     2  1.3KB     0B       0 |     - |  766B |     1   728B |     0     0B |     2  1.9KB |    0B |   2  2.6
+total |     2  1.2KB     0B       0 |     - |  627B |     1   589B |     0     0B |     2  1.8KB |    0B |   2  2.9
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 27B  written: 38B (41% overhead)
 Flushes: 1
-Compactions: 1  estimated debt: 1.3KB  in progress: 0 (0B)
+Compactions: 1  estimated debt: 1.2KB  in progress: 0 (0B)
              default: 0  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 1  multi-level: 0
 MemTables: 1 (256KB)  zombie: 1 (256KB)
 Zombie tables: 0 (0B, local: 0B)
@@ -882,7 +882,7 @@ Backing tables: 0 (0B)
 Virtual tables: 0 (0B)
 Local tables size: 0B
 Compression types: snappy: 2
-Block cache: 4 entries (187B)  hit rate: 0.0%
+Block cache: 4 entries (116B)  hit rate: 0.0%
 Table cache: 1 entries (816B)  hit rate: 50.0%
 Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
@@ -912,18 +912,18 @@ metrics
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     2  1.3KB     0B       0 |  0.50 |   66B |     1   728B |     0     0B |     2  1.2KB |    0B |   2 18.1
+    0 |     2  1.2KB     0B       0 |  0.50 |   66B |     1   589B |     0     0B |     2  1.2KB |    0B |   2 18.1
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     6 |     1   604B     0B       0 |     - |  604B |     0     0B |     0     0B |     1   604B |    0B |   1  1.0
-total |     3  1.9KB     0B       0 |     - |  794B |     1   728B |     0     0B |     3  2.5KB |    0B |   3  3.3
+total |     3  1.7KB     0B       0 |     - |  655B |     1   589B |     0     0B |     3  2.4KB |    0B |   3  3.7
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 44B  written: 66B (50% overhead)
 Flushes: 2
-Compactions: 1  estimated debt: 1.9KB  in progress: 0 (0B)
+Compactions: 1  estimated debt: 1.7KB  in progress: 0 (0B)
              default: 0  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 1  multi-level: 0
 MemTables: 1 (256KB)  zombie: 1 (256KB)
 Zombie tables: 0 (0B, local: 0B)
@@ -931,7 +931,7 @@ Backing tables: 0 (0B)
 Virtual tables: 0 (0B)
 Local tables size: 589B
 Compression types: snappy: 3
-Block cache: 4 entries (187B)  hit rate: 0.0%
+Block cache: 4 entries (116B)  hit rate: 0.0%
 Table cache: 1 entries (816B)  hit rate: 50.0%
 Secondary cache: 0 entries (0B)  hit rate: 0.0%
 Snapshots: 0  earliest seq num: 0
@@ -952,18 +952,18 @@ metrics zero-cache-hits-misses
       |                             |       |       |   ingested   |     moved    |    written   |       |    amp
 level | tables  size val-bl vtables | score |   in  | tables  size | tables  size | tables  size |  read |   r   w
 ------+-----------------------------+-------+-------+--------------+--------------+--------------+-------+---------
-    0 |     2  1.3KB     0B       0 |  0.50 |    0B |     0     0B |     0     0B |     0     0B |    0B |   2  0.0
+    0 |     2  1.2KB     0B       0 |  0.50 |    0B |     0     0B |     0     0B |     0     0B |    0B |   2  0.0
     1 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     2 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     6 |     1   604B     0B       0 |     - |    0B |     0     0B |     0     0B |     0     0B |    0B |   1  0.0
-total |     3  1.9KB     0B       0 |     - |    0B |     0     0B |     0     0B |     0     0B |    0B |   3  0.0
+total |     3  1.7KB     0B       0 |     - |    0B |     0     0B |     0     0B |     0     0B |    0B |   3  0.0
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 0B  written: 0B (0% overhead)
 Flushes: 1
-Compactions: 0  estimated debt: 1.9KB  in progress: 0 (0B)
+Compactions: 0  estimated debt: 1.7KB  in progress: 0 (0B)
              default: 0  delete: 0  elision: 0  move: 0  read: 0  tombstone-density: 0  rewrite: 0  copy: 0  multi-level: 0
 MemTables: 1 (512KB)  zombie: 1 (256KB)
 Zombie tables: 0 (0B, local: 0B)
@@ -997,8 +997,8 @@ level | tables  size val-bl vtables | score |   in  | tables  size | tables  siz
     3 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     4 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
     5 |     0     0B     0B       0 |  0.00 |    0B |     0     0B |     0     0B |     0     0B |    0B |   0  0.0
-    6 |     1   603B     0B       0 |     - | 1.3KB |     0     0B |     0     0B |     1   603B | 1.9KB |   1  0.5
-total |     1   603B     0B       0 |     - |    0B |     0     0B |     0     0B |     1   603B | 1.9KB |   1  0.0
+    6 |     1   603B     0B       0 |     - | 1.2KB |     0     0B |     0     0B |     1   603B | 1.7KB |   1  0.5
+total |     1   603B     0B       0 |     - |    0B |     0     0B |     0     0B |     1   603B | 1.7KB |   1  0.0
 -------------------------------------------------------------------------------------------------------------------
 WAL: 1 files (0B)  in: 0B  written: 0B (0% overhead)
 Flushes: 1
@@ -1019,4 +1019,4 @@ Filter utility: 0.0%
 Ingestions: 0  as flushable: 0 (0B in 0 tables)
 Cgo memory usage: 0B  block cache: 0B (data: 0B, maps: 0B, entries: 0B)  memtables: 0B
 Iter category stats:
-   pebble-compaction, non-latency: {BlockBytes:218 BlockBytesInCache:0 BlockReadDuration:30ms}
+   pebble-compaction, non-latency: {BlockBytes:147 BlockBytesInCache:0 BlockReadDuration:30ms}