jstests/replsets/dbcheck.js
// Test the various other parameters.
Test the various other parameters.
Test the various other parameters .
function testDbCheckParameters() {
    let primary = replSet.getPrimary();
    let db = primary.getDB(dbName);
    clearLog();
    let docSize = bsonsize({_id: 10});
    function checkEntryBounds(start, end) {
        forEachNode(function(node) {
            const debugBuild = node.getDB('admin').adminCommand('buildInfo').debug;
            if (!debugBuild) {
                return;
            }
            let healthlog = node.getDB("local").system.healthlog;
            let keyBoundsResult = healthlog.aggregate([
                {$match: {operation: "dbCheckBatch"}},
                {
                    $group:
                        {_id: null, minKey: {$min: "$data.minKey"}, maxKey: {$max: "$data.maxKey"}}
                }
            ]);
            assert(keyBoundsResult.hasNext(), "dbCheck put no batches in health log");
            const bounds = keyBoundsResult.next();
            const counts = healthLogCounts(healthlog);
            assert.eq(bounds.minKey, start, "dbCheck minKey field incorrect");
            assert.gte(bounds.maxKey, end, "dbCheck maxKey field incorrect");
            assert.gte(counts.totalDocs, end - start);
            assert.gte(counts.totalBytes, (end - start) * docSize);
        });
    }
    let start = 1000;
    let end = 9000;
    assert.commandWorked(
        db.runCommand({dbCheck: multiBatchSimpleCollName, minKey: start, maxKey: end}));
    awaitDbCheckCompletion(db, multiBatchSimpleCollName, end);
    checkEntryBounds(start, end);
    clearLog();
    let maxCount = 5000;
    assert.commandWorked(db.runCommand(
        {dbCheck: multiBatchSimpleCollName, minKey: start, maxKey: end, maxCount: maxCount}));
    awaitDbCheckCompletion(db, multiBatchSimpleCollName, undefined, undefined, maxCount);
    checkEntryBounds(start, start + maxCount);
    clearLog();
    let maxSize = maxCount * docSize;
    assert.commandWorked(db.runCommand(
        {dbCheck: multiBatchSimpleCollName, minKey: start, maxKey: end, maxSize: maxSize}));
    awaitDbCheckCompletion(db, multiBatchSimpleCollName, end, maxSize);
    checkEntryBounds(start, start + maxCount);
    const debugBuild = primary.getDB('admin').adminCommand('buildInfo').debug;
    if (!debugBuild) {
        return;
    }
    const healthlog = db.getSiblingDB('local').system.healthlog;
    {
        clearLog();
        const maxDocsPerBatch = 100;
        assert.commandWorked(
            db.runCommand({dbCheck: multiBatchSimpleCollName, maxDocsPerBatch: maxDocsPerBatch}));
        const healthlog = db.getSiblingDB('local').system.healthlog;
        assert.soon(function() {
            const expectedBatches = multiBatchSimpleCollSize / maxDocsPerBatch +
                (multiBatchSimpleCollSize % maxDocsPerBatch ? 1 : 0);
            return (healthlog.find({"operation": "dbCheckBatch"}).itcount() == expectedBatches);
        }, "dbCheck doesn't seem to complete", 60 * 1000);
        assert.eq(
            db.getSiblingDB('local')
                .system.healthlog.find({"operation": "dbCheckBatch", "data.count": maxDocsPerBatch})
                .itcount(),
            multiBatchSimpleCollSize / maxDocsPerBatch);
    }
    {
        clearLog();
        const coll = db.getSiblingDB("maxBytesPerBatch").maxBytesPerBatch;
        const nDocs = 5;
        coll.insertMany([...Array(nDocs).keys()].map(x => ({a: 'a'.repeat(1024 * 1024)})));
        const maxBytesPerBatch = 1024 * 1024;
        assert.commandWorked(db.getSiblingDB("maxBytesPerBatch").runCommand({
            dbCheck: coll.getName(),
            maxBytesPerBatch: maxBytesPerBatch
        }));
        assert.soon(function() {
            return (healthlog.find({"operation": "dbCheckBatch"}).itcount() == nDocs);
        }, "dbCheck doesn't seem to complete", 60 * 1000);
        assert.eq(db.getSiblingDB('local')
                      .system.healthlog.find({"operation": "dbCheckBatch", "data.count": 1})
                      .itcount(),
                  nDocs);
    }
}
function testDbCheckParameters ( ) { let primary = replSet . getPrimary ( ) ; let db = primary . getDB ( dbName ) ; clearLog ( ) ; let docSize = bsonsize ( { _id : 10 } ) ; function checkEntryBounds ( start , end ) { forEachNode ( function ( node ) { const debugBuild = node . getDB ( 'admin' ) . adminCommand ( 'buildInfo' ) . debug ; if ( ! debugBuild ) { return ; } let healthlog = node . getDB ( "local" ) . system . healthlog ; let keyBoundsResult = healthlog . aggregate ( [ { $match : { operation : "dbCheckBatch" } } , { $group : { _id : null , minKey : { $min : "$data.minKey" } , maxKey : { $max : "$data.maxKey" } } } ] ) ; assert ( keyBoundsResult . hasNext ( ) , "dbCheck put no batches in health log" ) ; const bounds = keyBoundsResult . next ( ) ; const counts = healthLogCounts ( healthlog ) ; assert . eq ( bounds . minKey , start , "dbCheck minKey field incorrect" ) ; assert . gte ( bounds . maxKey , end , "dbCheck maxKey field incorrect" ) ; assert . gte ( counts . totalDocs , end - start ) ; assert . gte ( counts . totalBytes , ( end - start ) * docSize ) ; } ) ; } let start = 1000 ; let end = 9000 ; assert . commandWorked ( db . runCommand ( { dbCheck : multiBatchSimpleCollName , minKey : start , maxKey : end } ) ) ; awaitDbCheckCompletion ( db , multiBatchSimpleCollName , end ) ; checkEntryBounds ( start , end ) ; clearLog ( ) ; let maxCount = 5000 ; assert . commandWorked ( db . runCommand ( { dbCheck : multiBatchSimpleCollName , minKey : start , maxKey : end , maxCount : maxCount } ) ) ; awaitDbCheckCompletion ( db , multiBatchSimpleCollName , undefined , undefined , maxCount ) ; checkEntryBounds ( start , start + maxCount ) ; clearLog ( ) ; let maxSize = maxCount * docSize ; assert . commandWorked ( db . runCommand ( { dbCheck : multiBatchSimpleCollName , minKey : start , maxKey : end , maxSize : maxSize } ) ) ; awaitDbCheckCompletion ( db , multiBatchSimpleCollName , end , maxSize ) ; checkEntryBounds ( start , start + maxCount ) ; const debugBuild = primary . getDB ( 'admin' ) . adminCommand ( 'buildInfo' ) . debug ; if ( ! debugBuild ) { return ; } const healthlog = db . getSiblingDB ( 'local' ) . system . healthlog ; { clearLog ( ) ; const maxDocsPerBatch = 100 ; assert . commandWorked ( db . runCommand ( { dbCheck : multiBatchSimpleCollName , maxDocsPerBatch : maxDocsPerBatch } ) ) ; const healthlog = db . getSiblingDB ( 'local' ) . system . healthlog ; assert . soon ( function ( ) { const expectedBatches = multiBatchSimpleCollSize / maxDocsPerBatch + ( multiBatchSimpleCollSize % maxDocsPerBatch ? 1 : 0 ) ; return ( healthlog . find ( { "operation" : "dbCheckBatch" } ) . itcount ( ) == expectedBatches ) ; } , "dbCheck doesn't seem to complete" , 60 * 1000 ) ; assert . eq ( db . getSiblingDB ( 'local' ) . system . healthlog . find ( { "operation" : "dbCheckBatch" , "data.count" : maxDocsPerBatch } ) . itcount ( ) , multiBatchSimpleCollSize / maxDocsPerBatch ) ; } { clearLog ( ) ; const coll = db . getSiblingDB ( "maxBytesPerBatch" ) . maxBytesPerBatch ; const nDocs = 5 ; coll . insertMany ( [ ... Array ( nDocs ) . keys ( ) ] . map ( x => ( { a : 'a' . repeat ( 1024 * 1024 ) } ) ) ) ; const maxBytesPerBatch = 1024 * 1024 ; assert . commandWorked ( db . getSiblingDB ( "maxBytesPerBatch" ) . runCommand ( { dbCheck : coll . getName ( ) , maxBytesPerBatch : maxBytesPerBatch } ) ) ; assert . soon ( function ( ) { return ( healthlog . find ( { "operation" : "dbCheckBatch" } ) . itcount ( ) == nDocs ) ; } , "dbCheck doesn't seem to complete" , 60 * 1000 ) ; assert . eq ( db . getSiblingDB ( 'local' ) . system . healthlog . find ( { "operation" : "dbCheckBatch" , "data.count" : 1 } ) . itcount ( ) , nDocs ) ; } }
Test the various other parameters.
Test the various other parameters .
// Clean up for the test. // These tests only run on debug builds because they rely on dbCheck health-logging // all info-level batch results. // dbCheck evaluates some exit conditions like maxCount and maxBytes at batch boundary. // The batch boundary isn't generally deterministic (e.g. can be time-dependent per // maxBatchTimeMillis) hence the greater-than-or-equal comparisons. // Run a dbCheck on just a subset of the documents // Now, clear the health logs again, // and do the same with a count constraint. // We expect it to reach the count limit before reaching maxKey. // Finally, do the same with a size constraint. // The remaining tests only run on debug builds because they rely on dbCheck health-logging // all info-level batch results. // Validate custom maxDocsPerBatch // Validate custom maxBytesPerBatch // Insert nDocs, each of which being slightly larger than 1MB, and then run dbCheck with // maxBytesPerBatch := 1MB // Confirm dbCheck logs nDocs batches.