@@ -9,13 +9,16 @@ import (
99 "time"
1010
1111 "github.com/cockroachdb/crlib/crtime"
12+ "github.com/cockroachdb/pebble/internal/invariants"
1213)
1314
1415// deletionPacerInfo contains any info from the db necessary to make deletion
1516// pacing decisions (to limit background IO usage so that it does not contend
1617// with foreground traffic).
1718type deletionPacerInfo struct {
18- freeBytes uint64
19+ freeBytes uint64
20+ // obsoleteBytes is the total size of obsolete files in the latest version;
21+ // these are files that have not yet been enqueued for deletion.
1922 obsoleteBytes uint64
2023 liveBytes uint64
2124}
@@ -44,6 +47,10 @@ type deletionPacer struct {
4447 // history keeps rack of recent deletion history; it used to increase the
4548 // deletion rate to match the pace of deletions.
4649 history history
50+
51+ // bytesToDelete is the sum of pacing bytes for all deletions that were
52+ // reported but not yet performed.
53+ bytesToDelete uint64
4754 }
4855
4956 targetByteDeletionRate func () int
@@ -83,17 +90,33 @@ func newDeletionPacer(
8390 return d
8491}
8592
86- // ReportDeletion is used to report a deletion to the pacer. The pacer uses it
87- // to keep track of the recent rate of deletions and potentially increase the
88- // deletion rate accordingly.
93+ // DeletionEnqueued is used to report a new deletion request to the pacer. The
94+ // pacer uses it to keep track of the recent rate of deletions and potentially
95+ // increase the deletion rate accordingly.
8996//
90- // ReportDeletion is thread-safe.
91- func (p * deletionPacer ) ReportDeletion (now crtime.Mono , bytesToDelete uint64 ) {
97+ // DeletionEnqueued is thread-safe.
98+ func (p * deletionPacer ) DeletionEnqueued (now crtime.Mono , bytesToDelete uint64 ) {
9299 p .mu .Lock ()
93100 defer p .mu .Unlock ()
101+ p .mu .bytesToDelete += bytesToDelete
94102 p .mu .history .Add (now , int64 (bytesToDelete ))
95103}
96104
105+ // DeletionPerformed is used to report that a deletion was performed. The pacer
106+ // uses it to keep track of how many bytes are in the queue.
107+ func (p * deletionPacer ) DeletionPerformed (bytesToDelete uint64 ) {
108+ p .mu .Lock ()
109+ defer p .mu .Unlock ()
110+ if p .mu .bytesToDelete < bytesToDelete {
111+ if invariants .Enabled {
112+ panic ("underflow" )
113+ }
114+ p .mu .bytesToDelete = 0
115+ } else {
116+ p .mu .bytesToDelete -= bytesToDelete
117+ }
118+ }
119+
97120// PacingDelay returns the recommended pacing wait time (in seconds) for
98121// deleting the given number of bytes.
99122//
@@ -108,10 +131,10 @@ func (p *deletionPacer) PacingDelay(now crtime.Mono, bytesToDelete uint64) (wait
108131 baseRate := float64 (targetByteDeletionRate )
109132 // If recent deletion rate is more than our target, use that so that we don't
110133 // fall behind.
111- historicRate := func () float64 {
134+ historicRate , totalBytesToDelete := func () ( float64 , uint64 ) {
112135 p .mu .Lock ()
113136 defer p .mu .Unlock ()
114- return float64 (p .mu .history .Sum (now )) / deletePacerHistory .Seconds ()
137+ return float64 (p .mu .history .Sum (now )) / deletePacerHistory .Seconds (), p . mu . bytesToDelete
115138 }()
116139 if historicRate > baseRate {
117140 baseRate = historicRate
@@ -128,7 +151,7 @@ func (p *deletionPacer) PacingDelay(now crtime.Mono, bytesToDelete uint64) (wait
128151 // We don't know the obsolete bytes ratio. Disable pacing altogether.
129152 return 0.0
130153 }
131- obsoleteBytesRatio := float64 (info .obsoleteBytes ) / float64 (info .liveBytes )
154+ obsoleteBytesRatio := float64 (info .obsoleteBytes + totalBytesToDelete ) / float64 (info .liveBytes )
132155 if obsoleteBytesRatio >= p .obsoleteBytesMaxRatio {
133156 // Increase the rate so that we can free up enough bytes within the timeframe.
134157 r := (obsoleteBytesRatio - p .obsoleteBytesMaxRatio ) * float64 (info .liveBytes ) / p .obsoleteBytesTimeframe .Seconds ()
0 commit comments