@@ -311,6 +311,12 @@ struct kvstats_ctx {
311311 * the persisted VB state before commit
312312 */
313313 size_t onDiskPrepareDelta = 0 ;
314+
315+ /* *
316+ * Delta of onDiskPrepareBytes that we should add to the value tracked in
317+ * the persisted VB state before commit.
318+ */
319+ ssize_t onDiskPrepareBytesDelta = 0 ;
314320};
315321
316322CouchKVStore::CouchKVStore (KVStoreConfig& config)
@@ -948,6 +954,7 @@ static int time_purge_hook(Db* d, DocInfo* info, sized_buf item, void* ctx_p) {
948954 }
949955 if (metadata->isPrepare ()) {
950956 ctx->stats .preparesPurged ++;
957+ ctx->stats .prepareBytesPurged += info->size ;
951958 }
952959 return COUCHSTORE_COMPACT_DROP_ITEM;
953960 } else if (info->deleted ) {
@@ -998,6 +1005,7 @@ static int time_purge_hook(Db* d, DocInfo* info, sized_buf item, void* ctx_p) {
9981005 if (metadata->isPrepare ()) {
9991006 if (info->db_seq <= ctx->highCompletedSeqno ) {
10001007 ctx->stats .preparesPurged ++;
1008+ ctx->stats .prepareBytesPurged += info->size ;
10011009 return COUCHSTORE_COMPACT_DROP_ITEM;
10021010 }
10031011
@@ -1232,6 +1240,8 @@ bool CouchKVStore::compactDBInternal(compaction_ctx* hook_ctx,
12321240 cachedDeleteCount[vbid.get ()] = info.deleted_count ;
12331241 cachedDocCount[vbid.get ()] = info.doc_count ;
12341242 state->onDiskPrepares -= hook_ctx->stats .preparesPurged ;
1243+ state->updateOnDiskPrepareBytes (
1244+ -int64_t (hook_ctx->stats .prepareBytesPurged ));
12351245 }
12361246
12371247 logger.debug (" INFO: created new couch db file, name:{} rev:{}" ,
@@ -1269,7 +1279,8 @@ couchstore_error_t CouchKVStore::compactPrecommitCallback(Db& db,
12691279
12701280 // we need to update the _local/vbstate to update the number of
12711281 // on_disk_prepared to match whatever we purged
1272- if (ctx.stats .preparesPurged != 0 ) {
1282+ if ((ctx.stats .preparesPurged != 0 ) ||
1283+ (ctx.stats .prepareBytesPurged != 0 )) {
12731284 LocalDoc* ldoc = nullptr ;
12741285 sized_buf id{(char *)" _local/vbstate" , sizeof (" _local/vbstate" ) - 1 };
12751286 auto err = couchstore_open_local_document (
@@ -1296,12 +1307,27 @@ couchstore_error_t CouchKVStore::compactPrecommitCallback(Db& db,
12961307 }
12971308 couchstore_free_local_document (ldoc);
12981309
1299- auto iter = json.find (" on_disk_prepares" );
1300- // only update if it's there..
1301- if (iter != json.end ()) {
1302- auto onDiskPrepares = std::stoull (iter->get <std::string>()) -
1310+ bool updateVbState = false ;
1311+
1312+ auto prepares = json.find (" on_disk_prepares" );
1313+ if (prepares != json.end ()) {
1314+ auto onDiskPrepares = std::stoull (prepares->get <std::string>()) -
13031315 ctx.stats .preparesPurged ;
1304- json[" on_disk_prepares" ] = std::to_string (onDiskPrepares);
1316+ *prepares = std::to_string (onDiskPrepares);
1317+ updateVbState = true ;
1318+ }
1319+
1320+ auto prepareBytes = json.find (" on_disk_prepare_bytes" );
1321+ if (prepareBytes != json.end ()) {
1322+ auto onDiskPrepareBytes =
1323+ std::stoull (prepareBytes->get <std::string>()) -
1324+ ctx.stats .prepareBytesPurged ;
1325+ *prepareBytes = std::to_string (onDiskPrepareBytes);
1326+ updateVbState = true ;
1327+ }
1328+
1329+ // only update if at least one of the prepare stats is already there
1330+ if (updateVbState) {
13051331 const auto doc = json.dump ();
13061332 LocalDoc newDoc{};
13071333 newDoc.id = id;
@@ -2230,6 +2256,12 @@ static void saveDocsCallback(const DocInfo* oldInfo,
22302256 std::to_string (itemCountDelta));
22312257 }
22322258
2259+ if (newKey.isPrepared ()) {
2260+ const ssize_t newSize = newInfo->size ;
2261+ const ssize_t oldSize = oldInfo ? oldInfo->size : 0 ;
2262+ cbCtx->onDiskPrepareBytesDelta += (newSize - oldSize);
2263+ }
2264+
22332265 // Do not need to update high seqno if we are calling this for a prepare and
22342266 // it will error if we do so return early.
22352267 if (!newKey.isCommitted ()) {
@@ -2326,6 +2358,7 @@ couchstore_error_t CouchKVStore::saveDocs(Vbid vbid,
23262358 std::placeholders::_2));
23272359
23282360 state->onDiskPrepares += kvctx.onDiskPrepareDelta ;
2361+ state->updateOnDiskPrepareBytes (kvctx.onDiskPrepareBytesDelta );
23292362 errCode = saveVBState (db, *state);
23302363 if (errCode != COUCHSTORE_SUCCESS) {
23312364 logger.warn (" CouchKVStore::saveDocs: saveVBState error:{} [{}]" ,
0 commit comments