@@ -18,7 +18,6 @@ import (
1818 "github.com/cockroachdb/errors"
1919 "github.com/cockroachdb/pebble/internal/base"
2020 "github.com/cockroachdb/pebble/internal/compact"
21- "github.com/cockroachdb/pebble/internal/invariants"
2221 "github.com/cockroachdb/pebble/internal/keyspan"
2322 "github.com/cockroachdb/pebble/internal/keyspan/keyspanimpl"
2423 "github.com/cockroachdb/pebble/internal/manifest"
@@ -2163,14 +2162,26 @@ func (d *DB) compact1(c *compaction, errChannel chan error) (err error) {
21632162// d.mu must be held when calling this method. The mutex will be released when
21642163// doing IO.
21652164func (d * DB ) runCopyCompaction (
2166- jobID JobID ,
2167- c * compaction ,
2168- inputMeta * fileMetadata ,
2169- objMeta objstorage.ObjectMetadata ,
2170- ve * versionEdit ,
2171- ) error {
2172- ctx := context .TODO ()
2165+ jobID JobID , c * compaction ,
2166+ ) (ve * versionEdit , stats compact.Stats , _ error ) {
2167+ iter := c .startLevel .files .Iter ()
2168+ inputMeta := iter .First ()
2169+ if iter .Next () != nil {
2170+ return nil , compact.Stats {}, base .AssertionFailedf ("got more than one file for a move compaction" )
2171+ }
2172+ if c .cancel .Load () {
2173+ return nil , compact.Stats {}, ErrCancelledCompaction
2174+ }
2175+ ve = & versionEdit {
2176+ DeletedFiles : map [deletedFileEntry ]* fileMetadata {
2177+ {Level : c .startLevel .level , FileNum : inputMeta .FileNum }: inputMeta ,
2178+ },
2179+ }
21732180
2181+ objMeta , err := d .objProvider .Lookup (fileTypeTable , inputMeta .FileBacking .DiskFileNum )
2182+ if err != nil {
2183+ return nil , compact.Stats {}, err
2184+ }
21742185 if ! objMeta .IsExternal () {
21752186 if objMeta .IsRemote () || ! remote .ShouldCreateShared (d .opts .Experimental .CreateOnShared , c .outputLevel .level ) {
21762187 panic ("pebble: scheduled a copy compaction that is not actually moving files to shared storage" )
@@ -2215,14 +2226,6 @@ func (d *DB) runCopyCompaction(
22152226 newMeta .InitPhysicalBacking ()
22162227 }
22172228
2218- c .metrics = map [int ]* LevelMetrics {
2219- c .outputLevel .level : {
2220- BytesIn : inputMeta .Size ,
2221- BytesCompacted : inputMeta .Size ,
2222- TablesCompacted : 1 ,
2223- },
2224- }
2225-
22262229 // Before dropping the db mutex, grab a ref to the current version. This
22272230 // prevents any concurrent excises from deleting files that this compaction
22282231 // needs to read/maintain a reference to.
@@ -2244,11 +2247,12 @@ func (d *DB) runCopyCompaction(
22442247
22452248 // If the src obj is external, we're doing an external to local/shared copy.
22462249 if objMeta .IsExternal () {
2250+ ctx := context .TODO ()
22472251 src , err := d .objProvider .OpenForReading (
22482252 ctx , fileTypeTable , inputMeta .FileBacking .DiskFileNum , objstorage.OpenOptions {},
22492253 )
22502254 if err != nil {
2251- return err
2255+ return nil , compact. Stats {}, err
22522256 }
22532257 defer func () {
22542258 if src != nil {
@@ -2263,7 +2267,7 @@ func (d *DB) runCopyCompaction(
22632267 },
22642268 )
22652269 if err != nil {
2266- return err
2270+ return nil , compact. Stats {}, err
22672271 }
22682272 deleteOnExit = true
22692273
@@ -2287,30 +2291,49 @@ func (d *DB) runCopyCompaction(
22872291 )
22882292 src = nil // We passed src to CopySpan; it's responsible for closing it.
22892293 if err != nil {
2290- return err
2294+ if errors .Is (err , sstable .ErrEmptySpan ) {
2295+ // The virtual table was empty. Just remove the backing file.
2296+ // Note that deleteOnExit is true so we will delete the created object.
2297+ c .metrics = map [int ]* LevelMetrics {
2298+ c .outputLevel .level : {
2299+ BytesIn : inputMeta .Size ,
2300+ },
2301+ }
2302+ return ve , compact.Stats {}, nil
2303+ }
2304+ return nil , compact.Stats {}, err
22912305 }
22922306 newMeta .FileBacking .Size = wrote
22932307 newMeta .Size = wrote
22942308 } else {
22952309 _ , err := d .objProvider .LinkOrCopyFromLocal (context .TODO (), d .opts .FS ,
22962310 d .objProvider .Path (objMeta ), fileTypeTable , newMeta .FileBacking .DiskFileNum ,
22972311 objstorage.CreateOptions {PreferSharedStorage : true })
2298-
22992312 if err != nil {
2300- return err
2313+ return nil , compact. Stats {}, err
23012314 }
23022315 deleteOnExit = true
23032316 }
2304- ve .NewFiles [0 ].Meta = newMeta
2317+ ve .NewFiles = []newFileEntry {{
2318+ Level : c .outputLevel .level ,
2319+ Meta : newMeta ,
2320+ }}
23052321 if newMeta .Virtual {
23062322 ve .CreatedBackingTables = []* fileBacking {newMeta .FileBacking }
23072323 }
2324+ c .metrics = map [int ]* LevelMetrics {
2325+ c .outputLevel .level : {
2326+ BytesIn : inputMeta .Size ,
2327+ BytesCompacted : newMeta .Size ,
2328+ TablesCompacted : 1 ,
2329+ },
2330+ }
23082331
23092332 if err := d .objProvider .Sync (); err != nil {
2310- return err
2333+ return nil , compact. Stats {}, err
23112334 }
23122335 deleteOnExit = false
2313- return nil
2336+ return ve , compact. Stats {}, nil
23142337}
23152338
23162339func (d * DB ) runDeleteOnlyCompaction (
@@ -2334,23 +2357,17 @@ func (d *DB) runDeleteOnlyCompaction(
23342357 return ve , stats , nil
23352358}
23362359
2337- func (d * DB ) runMoveOrCopyCompaction (
2360+ func (d * DB ) runMoveCompaction (
23382361 jobID JobID , c * compaction ,
23392362) (ve * versionEdit , stats compact.Stats , _ error ) {
23402363 iter := c .startLevel .files .Iter ()
23412364 meta := iter .First ()
2342- if invariants .Enabled {
2343- if iter .Next () != nil {
2344- panic ("got more than one file for a move or copy compaction" )
2345- }
2365+ if iter .Next () != nil {
2366+ return nil , stats , base .AssertionFailedf ("got more than one file for a move compaction" )
23462367 }
23472368 if c .cancel .Load () {
23482369 return ve , stats , ErrCancelledCompaction
23492370 }
2350- objMeta , err := d .objProvider .Lookup (fileTypeTable , meta .FileBacking .DiskFileNum )
2351- if err != nil {
2352- return ve , stats , err
2353- }
23542371 c .metrics = map [int ]* LevelMetrics {
23552372 c .outputLevel .level : {
23562373 BytesMoved : meta .Size ,
@@ -2365,12 +2382,8 @@ func (d *DB) runMoveOrCopyCompaction(
23652382 {Level : c .outputLevel .level , Meta : meta },
23662383 },
23672384 }
2368- if c .kind == compactionKindMove {
2369- return ve , stats , nil
2370- }
23712385
2372- err = d .runCopyCompaction (jobID , c , meta , objMeta , ve )
2373- return ve , stats , err
2386+ return ve , stats , nil
23742387}
23752388
23762389// runCompaction runs a compaction that produces new on-disk tables from
@@ -2386,8 +2399,10 @@ func (d *DB) runCompaction(
23862399 switch c .kind {
23872400 case compactionKindDeleteOnly :
23882401 return d .runDeleteOnlyCompaction (jobID , c )
2389- case compactionKindMove , compactionKindCopy :
2390- return d .runMoveOrCopyCompaction (jobID , c )
2402+ case compactionKindMove :
2403+ return d .runMoveCompaction (jobID , c )
2404+ case compactionKindCopy :
2405+ return d .runCopyCompaction (jobID , c )
23912406 case compactionKindIngestedFlushable :
23922407 panic ("pebble: runCompaction cannot handle compactionKindIngestedFlushable." )
23932408 }
0 commit comments