jstests/replsets/libs/tenant_migration_util.js
/**
     * Compares the hashes for DBs that belong to the specified tenant between the donor and
     * recipient primaries.
     */
Compares the hashes for DBs that belong to the specified tenant between the donor and
recipient primaries.
Compares the hashes for DBs that belong to the specified tenant between the donor and recipient primaries .
function checkTenantDBHashes(donorRst,
                                 recipientRst,
                                 tenantId,
                                 excludedDBs = [],
                                 msgPrefix = 'checkTenantDBHashes',
                                 ignoreUUIDs = false) {
        excludedDBs = [...excludedDBs, "config", "admin", "local"];
        while (true) {
            try {
                const donorPrimaryConn = donorRst.getPrimary();
                const recipientPrimaryConn = recipientRst.getPrimary();
                const donorAllowsReadsAfterMigration =
                    assert
                        .commandWorked(donorPrimaryConn.adminCommand({
                            getParameter: 1,
                            "failpoint.tenantMigrationDonorAllowsNonTimestampedReads": 1
                        }))["failpoint.tenantMigrationDonorAllowsNonTimestampedReads"]
                        .mode;
                if (!donorAllowsReadsAfterMigration) {
                    assert.commandWorked(donorPrimaryConn.adminCommand({
                        configureFailPoint: "tenantMigrationDonorAllowsNonTimestampedReads",
                        mode: "alwaysOn"
                    }));
                }
                let combinedDBNames =
                    [...donorPrimaryConn.getDBNames(), ...recipientPrimaryConn.getDBNames()];
                combinedDBNames =
                    combinedDBNames.filter(dbName => (isNamespaceForTenant(tenantId, dbName) &&
                                                      !excludedDBs.includes(dbName)));
                combinedDBNames = new Set(combinedDBNames);
                for (const dbName of combinedDBNames) {
                    const donorDBHash =
                        assert.commandWorked(donorRst.getHashes(dbName, []).primary);
                    const recipientDBHash =
                        assert.commandWorked(recipientRst.getHashes(dbName, []).primary);
                    const donorCollections = Object.keys(donorDBHash.collections);
                    const donorCollInfos = new CollInfos(donorPrimaryConn, 'donorPrimary', dbName);
                    donorCollInfos.filter(donorCollections);
                    const recipientCollections = Object.keys(recipientDBHash.collections);
                    const recipientCollInfos =
                        new CollInfos(recipientPrimaryConn, 'recipientPrimary', dbName);
                    recipientCollInfos.filter(recipientCollections);
                    print(`checking db hash between donor: ${donorPrimaryConn} and recipient: ${
                        recipientPrimaryConn}`);
                    const collectionPrinted = new Set();
                    const success = DataConsistencyChecker.checkDBHash(donorDBHash,
                                                                       donorCollInfos,
                                                                       recipientDBHash,
                                                                       recipientCollInfos,
                                                                       msgPrefix,
                                                                       ignoreUUIDs,
                                                                       true, 
                                                                       collectionPrinted);
                    if (!success) {
                        print(`checkTenantDBHashes dumping donor and recipient primary oplogs`);
                        donorRst.dumpOplog(donorPrimaryConn, {}, 100);
                        recipientRst.dumpOplog(recipientPrimaryConn, {}, 100);
                    }
                    assert(success, 'dbhash mismatch between donor and recipient primaries');
                }
                if (!donorAllowsReadsAfterMigration) {
                    donorRst.nodes.forEach(node => {
                        assert.commandWorked(node.adminCommand({
                            configureFailPoint: "tenantMigrationDonorAllowsNonTimestampedReads",
                            mode: "off"
                        }));
                    });
                }
                break;
            } catch (e) {
                if (!checkIfRetryableErrorForTenantDbHashCheck(e)) {
                    throw e;
                } else {
                    print(`Got error: ${tojson(e)}. Failover occurred during tenant dbhash check,` +
                          ` retrying tenant dbhash check.`);
                }
            }
        }
    }
function checkTenantDBHashes ( donorRst , recipientRst , tenantId , excludedDBs = [ ] , msgPrefix = 'checkTenantDBHashes' , ignoreUUIDs = false ) { excludedDBs = [ ... excludedDBs , "config" , "admin" , "local" ] ; while ( true ) { try { const donorPrimaryConn = donorRst . getPrimary ( ) ; const recipientPrimaryConn = recipientRst . getPrimary ( ) ; const donorAllowsReadsAfterMigration = assert . commandWorked ( donorPrimaryConn . adminCommand ( { getParameter : 1 , "failpoint.tenantMigrationDonorAllowsNonTimestampedReads" : 1 } ) ) [ "failpoint.tenantMigrationDonorAllowsNonTimestampedReads" ] . mode ; if ( ! donorAllowsReadsAfterMigration ) { assert . commandWorked ( donorPrimaryConn . adminCommand ( { configureFailPoint : "tenantMigrationDonorAllowsNonTimestampedReads" , mode : "alwaysOn" } ) ) ; } let combinedDBNames = [ ... donorPrimaryConn . getDBNames ( ) , ... recipientPrimaryConn . getDBNames ( ) ] ; combinedDBNames = combinedDBNames . filter ( dbName => ( isNamespaceForTenant ( tenantId , dbName ) && ! excludedDBs . includes ( dbName ) ) ) ; combinedDBNames = new Set ( combinedDBNames ) ; for ( const dbName of combinedDBNames ) { const donorDBHash = assert . commandWorked ( donorRst . getHashes ( dbName , [ ] ) . primary ) ; const recipientDBHash = assert . commandWorked ( recipientRst . getHashes ( dbName , [ ] ) . primary ) ; const donorCollections = Object . keys ( donorDBHash . collections ) ; const donorCollInfos = new CollInfos ( donorPrimaryConn , 'donorPrimary' , dbName ) ; donorCollInfos . filter ( donorCollections ) ; const recipientCollections = Object . keys ( recipientDBHash . collections ) ; const recipientCollInfos = new CollInfos ( recipientPrimaryConn , 'recipientPrimary' , dbName ) ; recipientCollInfos . filter ( recipientCollections ) ; print ( ` ${ donorPrimaryConn } ${ recipientPrimaryConn } ` ) ; const collectionPrinted = new Set ( ) ; const success = DataConsistencyChecker . checkDBHash ( donorDBHash , donorCollInfos , recipientDBHash , recipientCollInfos , msgPrefix , ignoreUUIDs , true , collectionPrinted ) ; if ( ! success ) { print ( ` ` ) ; donorRst . dumpOplog ( donorPrimaryConn , { } , 100 ) ; recipientRst . dumpOplog ( recipientPrimaryConn , { } , 100 ) ; } assert ( success , 'dbhash mismatch between donor and recipient primaries' ) ; } if ( ! donorAllowsReadsAfterMigration ) { donorRst . nodes . forEach ( node => { assert . commandWorked ( node . adminCommand ( { configureFailPoint : "tenantMigrationDonorAllowsNonTimestampedReads" , mode : "off" } ) ) ; } ) ; } break ; } catch ( e ) { if ( ! checkIfRetryableErrorForTenantDbHashCheck ( e ) ) { throw e ; } else { print ( ` ${ tojson ( e ) } ` + ` ` ) ; } } } }
Compares the hashes for DBs that belong to the specified tenant between the donor and
 recipient primaries.
Compares the hashes for DBs that belong to the specified tenant between the donor and recipient primaries .
// Always skip db hash checks for the config, admin, and local database. // Allows listCollections and listIndexes on donor after migration for consistency // checks. // Only turn on the failpoint if it is not already. // Filter out all dbs that don't belong to the tenant. // Pass in an empty array for the secondaries, since we only wish to compare // the DB hashes between the donor and recipient primary in this test. /* syncingHasIndexes */ // Reset failpoint on the donor after consistency checks if it wasn't enabled // before. // We unset the failpoint for every node in case there was a failover at some // point before this.