IFR: forward IFRContext into internal transactions (txn API)

    • Type: Task
    • Resolution: Unresolved
    • Priority: Minor - P4
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Query Execution
    • None
    • None
    • None
    • None
    • None
    • None
    • None

      Summary

      The internal transaction API (txn_api::SyncTransactionWithRetries / SEPTransactionClient, in src/mongo/db/transaction/sep_transaction_client.cpp) creates a fresh Client + OperationContext for each internally-dispatched command (SEPTransactionClient::_runCommand). The caller's IncrementalFeatureRolloutContext (IFR flags + ifrSenderVersion) is not carried onto that fresh opCtx, so commands issued inside an internal transaction re-derive the IFR context instead of preserving the caller's wire-installed one. On a mongod shard (where isRouter == false), this means an internal transaction that fans out would drop ifrSenderVersion/ifrFlags instead of forwarding the original sender's values.

      Proposed fix

      * Capture the caller's IFRContext in Transaction::_primeTransaction (src/mongo/db/transaction/transaction_api.cpp), guarded on isInstalledFromWire() so only wire-originated contexts are forwarded (a locally-derived forRequestWithoutIfrFlags() context must not be re-forwarded).
      * Thread it through TxnHooks and install it on the child opCtx in SEPTransactionClient::_runCommand via IncrementalFeatureRolloutContext::set(...) so the egress metadata hook stamps the original sender's values.
      * Unit tests already drafted in src/mongo/db/transaction/transaction_api_test.cpp (ForwardsWireInstalledIfrContextToInternalTransaction / DoesNotForwardLocallyDerivedIfrContext).

      NOT needed in 9.0

      Static analysis shows that in 9.0 no IFR flag value is consumed inside any shard-originated internal transaction. IFR flag consumption is confined to the aggregate/query parsing + planning path (via ExpressionContext::getIfrContext()->getSavedFlagValue(...)); the write-execution code that internal transactions actually run (write_ops_exec.cpp, timeseries writes, performUpdates/Inserts/Deletes) never touches the IFRContext (write-path flags use the process-global checkEnabled()). Every observable end-to-end path is either mongos-coordinated (where isRouter re-stamps the local senderVersion, masking the gap) or shard-local (no cross-shard egress). So this is a defensive/future-proofing change only; it has no functional effect in 9.0.

      Epic

      Filed under the IFR epic (SPM-4726) for visibility, but it probably does not belong in that epic since it is not required for the IFR 9.0 rollout — triage may want to move or defer it.

            Assignee:
            Unassigned
            Reporter:
            Mickey Winters
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: