Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-92710

Report an error if an _id index is missing at startup rather than failing to build it

    • Type: Icon: Improvement Improvement
    • Resolution: Unresolved
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Storage Execution
    • Fully Compatible
    • Execution Team 2024-09-02, Execution Team 2024-09-16, Execution Team 2024-10-28, Execution Team 2024-11-11, Execution Team 2024-11-25, Execution Team 2024-12-09, Execution Team 2024-12-23
    • 200

      If a collection is missing an _id index at startup, we attempt to build it. This test demonstrates the behavior on a standalone, but not on a replica set.

      Modifying this test to use a replica set, diff below, shows that the server will fail to start up because we cannot perform an untimestamped write to the timestamped catalog.

      diff --git a/jstests/noPassthrough/startup_with_missing_id_index.js b/jstests/noPassthrough/startup_with_missing_id_index.js
      index e73b62082f0..d221f3bb483 100644
      --- a/jstests/noPassthrough/startup_with_missing_id_index.js
      +++ b/jstests/noPassthrough/startup_with_missing_id_index.js
      @@ -5,7 +5,11 @@
        */
       import {IndexCatalogHelpers} from "jstests/libs/index_catalog_helpers.js";
      
      -let conn = MongoRunner.runMongod();
      +let replSet = new ReplSetTest({nodes: 1});
      +replSet.startSet();
      +replSet.initiate();
      +
      +let conn = replSet.getPrimary();
      
       const dbName = jsTestName();
       const collName = "coll";
      @@ -16,17 +20,15 @@ let coll = testDB.getCollection(collName);
       assert.commandWorked(testDB.adminCommand({configureFailPoint: "skipIdIndex", mode: "alwaysOn"}));
       assert.commandWorked(testDB.createCollection(collName));
      
      -for (let i = 0; i < 1500; ++i) {
      -    assert.commandWorked(coll.insert({_id: i, a: 1}));
      -}
      +assert.commandWorked(coll.insert({_id: 0, a: 1}));
      
       let indexSpec = IndexCatalogHelpers.findByName(coll.getIndexes(), "_id_");
       assert.eq(indexSpec, null);
      
      -MongoRunner.stopMongod(conn);
      +replSet.restart(conn);
      +conn = replSet.getPrimary();
      
       // We should be able to successfully restart the server even though 'coll' is missing an id index.
      -conn = MongoRunner.runMongod({dbpath: conn.dbpath, noCleanData: true});
       assert(conn);
      

      This produces the following logs:

      [js_test:startup_with_missing_id_index] d20040| {"t":{"$date":"2024-07-22T17:25:35.119+00:00"},"s":"I",  "c":"STORAGE",  "id":21001,   "ctx":"initandlisten","msg":"Collection is missing an _id index","attr":{"namespace":"startup_with_missing_id_index.coll","uuid":{"uuid":{"$uuid":"38d59dd1-8fba-4b12-adea-5284f6529cde"}}}}
      [js_test:startup_with_missing_id_index] d20040| {"t":{"$date":"2024-07-22T17:25:35.119+00:00"},"s":"I",  "c":"STORAGE",  "id":4805002, "ctx":"initandlisten","msg":"Building missing _id index","attr":{"namespace":"startup_with_missing_id_index.coll","uuid":{"uuid":{"$uuid":"38d59dd1-8fba-4b12-adea-5284f6529cde"}}}}
      [js_test:startup_with_missing_id_index] d20040| {"t":{"$date":"2024-07-22T17:25:35.138+00:00"},"s":"I",  "c":"INDEX",    "id":20384,   "ctx":"initandlisten","msg":"Index build: starting","attr":{"buildUUID":null,"collectionUUID":{"uuid":{"$uuid":"38d59dd1-8fba-4b12-adea-5284f6529cde"}},"namespace":"startup_with_missing_id_index.coll","properties":{"v":2,"key":{"_id":1},"name":"_id_"},"specIndex":0,"numSpecs":1,"method":"Foreground","ident":"index-0-10018277863432587308","collectionIdent":"collection-38-2690690076013692306","maxTemporaryMemoryUsageMB":200}}
      [js_test:startup_with_missing_id_index] d20040| {"t":{"$date":"2024-07-22T17:25:35.138+00:00"},"s":"E",  "c":"WT",       "id":22435,   "ctx":"initandlisten","msg":"WiredTiger error message","attr":{"error":22,"message":{"ts_sec":1721669135,"ts_usec":138747,"thread":"33342:0xffff9c45a040","session_name":"WT_SESSION.commit_transaction","category":"WT_VERB_DEFAULT","category_id":12,"verbose_level":"ERROR","verbose_level_id":-3,"msg":"int __txn_timestamp_usage_check(WT_SESSION_IMPL *, WT_TXN_OP *, WT_UPDATE *):1000:file:_mdb_catalog.wt: unexpected timestamp usage: no timestamp provided for an update to a table configured to always use timestamps once they are first used","error_str":"Invalid argument","error_code":22}}}
      [js_test:startup_with_missing_id_index] d20040| {"t":{"$date":"2024-07-22T17:25:35.138+00:00"},"s":"F",  "c":"ASSERT",   "id":23083,   "ctx":"initandlisten","msg":"Invariant failure","attr":{"expr":"wtRet","error":"BadValue: 22: Invalid argument","file":"src/mongo/db/storage/wiredtiger/wiredtiger_recovery_unit.cpp","line":399}}
      

      Rather than attempting to build the _id index and failing in this way, we should instead refuse to start up with a more useful error message, recommending a full resync.

            Assignee:
            binh.vo@mongodb.com Binh Vo
            Reporter:
            louis.williams@mongodb.com Louis Williams
            Votes:
            0 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated: