Uploaded image for project: 'WiredTiger'
  1. WiredTiger
  2. WT-7393

Allow changing the "overwrite" setting on an existing WT cursor

    • Type: Icon: Improvement Improvement
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None

      Right now it is only possible to set the "overwrite" setting at cursor creation time, which means that there are now two kinds of cursors that need to be kept separate. SERVER-55342 is an example of the issues this causes. Since mongo caches cursors in its glue layer, it needs to (but doesn't currently...) keep the cache partitioned based on both the table and the overwrite setting. As an alternative, if we could just set overwrite to the desired value on checkout, it would be both simpler to maintain the cache, and would result in fewer total cursors since we wouldn't need to create duplicate cursors. It is also somewhat unfortunate that cursors that are only used for reading, and therefore don't care about the overwrite setting, still need to pick a setting, which may prevent reuse of that cursor for writing.

      As an additional benefit, it would allow not using a separate cursor if you need to do some subset of operations with a different setting. This happens in mongo when we need to forcibly retry an operation that failed due to duplicate key error when we are in a state where we are supposed to ignore/allow those errors. For example, in a branch where I have pushed the usage of cursors for writing up to the higher mongodb layers there is logic like this where we need to bypass the cursor. If we were able to change the overwrite setting (and change it back after the special-case operation), we would be able to just use the cursor in the if block as well.

          auto cursor = _newInterface->newWriteCursor(
              opCtx, !unique /* dupsAllowed */, options.isForMultikeyMetadataKeys);
          // Add all new keys into the index. The RecordId for each is already encoded in the KeyString.
          for (const auto& keyString : keys) {
              Status status = cursor->insert(keyString);
      
              // When duplicates are encountered and allowed, retry with dupsAllowed. Call
              // onDuplicateKey() with the inserted duplicate key.
              if (ErrorCodes::DuplicateKey == status.code() && options.dupsAllowed) {
                  invariant(unique);
                  // Can't use cursor here since we need to use a different value of dupsAllowed.
                  status = _newInterface->insert(opCtx, keyString, true /* dupsAllowed */);
                  if (status.isOK() && onDuplicateKey)
                      status = onDuplicateKey(keyString);
              }
              uassertStatusOK(status);
          }
      

            Assignee:
            backlog-server-storage-engines [DO NOT USE] Backlog - Storage Engines Team
            Reporter:
            mathias@mongodb.com Mathias Stearn
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: