<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 05:36:05 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[SERVER-55305] Retryable write may execute more than once if primary had transitioned through rollback to stable</title>
                <link>https://jira.mongodb.org/browse/SERVER-55305</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/9d601c939bca2a4304dca2d3c8abd195c1f070af/src/mongo/db/repl/session_update_tracker.cpp#L217-L221&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;SessionUpdateTracker::&amp;#95;updateSessionInfo()&lt;/a&gt; is used by secondary oplog application to coalesce multiple updates to the same config.transactions record into a single update of the most recent retryable write statement. The changes from &lt;a href=&quot;https://github.com/mongodb/mongo/commit/02020fa91c62562cb08f30c8130baf0791cc0a67&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;02020fa&lt;/a&gt; as part of &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-47844&quot; title=&quot;Update _setStableTimestampForStorage to set the stable timestamp without using the stable optime candidates set when EMRC=true&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-47844&quot;&gt;&lt;del&gt;SERVER-47844&lt;/del&gt;&lt;/a&gt; made it possible for a secondary to choose its stable&amp;#95;timestamp as a majority-committed timestamp from &lt;em&gt;within&lt;/em&gt; an oplog batch rather than always being on a batch boundary. The combination of these two can lead to the following sequence:&lt;/p&gt;

&lt;ol&gt;
	&lt;li&gt;During single batch of oplog application:
	&lt;ol&gt;
		&lt;li&gt;User data write for stmtId=0 at t=10.&lt;/li&gt;
		&lt;li&gt;User data write for stmtId=1 at t=11.&lt;/li&gt;
		&lt;li&gt;User data write for stmtId=2 at t=12.&lt;/li&gt;
		&lt;li&gt;Session txn record write at t=12 with stmtId=2 as lastWriteOpTime.
		&lt;ul&gt;
			&lt;li&gt;In particular, no session txn record write for t=10 with stmtId=0 as lastWriteOpTime or for t=11 with stmtId=1 as lastWriteOpTime because they were coalseced by the SessionUpdateTracker.&lt;/li&gt;
		&lt;/ul&gt;
		&lt;/li&gt;
	&lt;/ol&gt;
	&lt;/li&gt;
	&lt;li&gt;Rollback to stable timestamp t=10.&lt;/li&gt;
	&lt;li&gt;The session txn record won&apos;t exist with stmtId=0 as lastWriteOpTime (because the write was entirely skipped by oplog application) despite the user data write for stmtId=0 being reflected on-disk. This allows stmtId=0 to be re-executed by this node if it became primary.&lt;/li&gt;
&lt;/ol&gt;


&lt;h6&gt;&lt;a name=&quot;Impacton4.0%2C4.2%2Cand4.4branches&quot;&gt;&lt;/a&gt;Impact on 4.0, 4.2, and 4.4 branches&lt;/h6&gt;

&lt;p&gt;The stable optime candidates list prevents this issue for retryable inserts, updates, and deletes applied during secondary oplog application.&lt;/p&gt;

&lt;p&gt;However, retryable inserts on primaries also coalesce multiple updates to the same config.transactions record into a single update of the most recent retryable write statement. This happens through &lt;a href=&quot;https://github.com/mongodb/mongo/blob/9d601c939bca2a4304dca2d3c8abd195c1f070af/src/mongo/db/op_observer_impl.cpp#L494&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;OpObserverImpl::onInserts() calling TransasctionParticipant::onWriteOpCompletedOnPrimary() once&lt;/a&gt; for a batch of insert statements (aka vectored insert).&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Only retryable inserts are impacted.&lt;/li&gt;
	&lt;li&gt;A retry attempt fails with a DuplicateKey error so long as the document wasn&apos;t deleted by another client in the meantime. (The document is re-inserted otherwise.)&lt;/li&gt;
&lt;/ul&gt;


&lt;h6&gt;&lt;a name=&quot;Impacton4.9andmasterbranches&quot;&gt;&lt;/a&gt;Impact on 4.9 and master branches&lt;/h6&gt;

&lt;p&gt;The stable optime candidates list was removed and so this issue exists for retryable inserts, updates, and deletes applied during secondary oplog application. Retryable inserts on primaries continue to coalesce multiple updates to the same config.transactions record into a single update of the most recent retryable write statement.&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;All of retryable inserts, updates, and deletes are impacted.&lt;/li&gt;
	&lt;li&gt;A retry attempt for an update can execute more than once (e.g. double increment a counter).&lt;/li&gt;
&lt;/ul&gt;


&lt;hr /&gt;

&lt;p&gt;This issue was discovered while reasoning through why the atClusterTime read on config.transactions to fix &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-54626&quot; title=&quot;Retryable writes may execute more than once in resharding if statements straddle the fetchTimestamp&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-54626&quot;&gt;&lt;del&gt;SERVER-54626&lt;/del&gt;&lt;/a&gt; was insufficient (hence &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-55214&quot; title=&quot;Resharding txn cloner can miss config.transactions entry when fetching&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-55214&quot;&gt;&lt;del&gt;SERVER-55214&lt;/del&gt;&lt;/a&gt;). Shout out to &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=daniel.gottlieb&quot; class=&quot;user-hover&quot; rel=&quot;daniel.gottlieb&quot;&gt;daniel.gottlieb&lt;/a&gt; for the assist!&lt;/p&gt;</description>
                <environment></environment>
        <key id="1652773">SERVER-55305</key>
            <summary>Retryable write may execute more than once if primary had transitioned through rollback to stable</summary>
                <type id="1" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14703&amp;avatarType=issuetype">Bug</type>
                                            <priority id="3" iconUrl="https://jira.mongodb.org/images/icons/priorities/major.svg">Major - P3</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="13201">Fixed</resolution>
                                        <assignee username="jason.chan@mongodb.com">Jason Chan</assignee>
                                    <reporter username="max.hirschhorn@mongodb.com">Max Hirschhorn</reporter>
                        <labels>
                    </labels>
                <created>Thu, 18 Mar 2021 16:46:25 +0000</created>
                <updated>Sun, 29 Oct 2023 21:56:08 +0000</updated>
                            <resolved>Wed, 5 May 2021 13:10:43 +0000</resolved>
                                    <version>4.0.0</version>
                    <version>4.2.0</version>
                    <version>4.4.0</version>
                                    <fixVersion>5.0.0-rc0</fixVersion>
                                    <component>Replication</component>
                    <component>Sharding</component>
                                        <votes>0</votes>
                                    <watches>18</watches>
                                                                                                                <comments>
                            <comment id="3755485" author="xgen-internal-githook" created="Tue, 4 May 2021 22:29:34 +0000"  >&lt;p&gt;Author:&lt;/p&gt;
{&apos;name&apos;: &apos;Jason Chan&apos;, &apos;email&apos;: &apos;jason.chan@mongodb.com&apos;, &apos;username&apos;: &apos;jasonjhchan&apos;}
&lt;p&gt;Message: &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-55305&quot; title=&quot;Retryable write may execute more than once if primary had transitioned through rollback to stable&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-55305&quot;&gt;&lt;del&gt;SERVER-55305&lt;/del&gt;&lt;/a&gt; Add new step to replication rollback to restore the txns table to be consistent with the stableTimestamp&lt;br/&gt;
Branch: master&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo/commit/320e2d28396c250dfd69640dcf865dff50ea0b55&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo/commit/320e2d28396c250dfd69640dcf865dff50ea0b55&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="3742711" author="xgen-internal-githook" created="Tue, 27 Apr 2021 22:55:19 +0000"  >&lt;p&gt;Author:&lt;/p&gt;
{&apos;name&apos;: &apos;Jason Chan&apos;, &apos;email&apos;: &apos;jason.chan@mongodb.com&apos;, &apos;username&apos;: &apos;jasonjhchan&apos;}
&lt;p&gt;Message: &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-55305&quot; title=&quot;Retryable write may execute more than once if primary had transitioned through rollback to stable&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-55305&quot;&gt;&lt;del&gt;SERVER-55305&lt;/del&gt;&lt;/a&gt; Do not coalesce updates across different txnNumbers for retryableWrites&lt;br/&gt;
Branch: master&lt;br/&gt;
&lt;a href=&quot;https://github.com/mongodb/mongo/commit/70a27d12642793fed2b05da116910799ea67c4f6&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;https://github.com/mongodb/mongo/commit/70a27d12642793fed2b05da116910799ea67c4f6&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="3687654" author="max.hirschhorn@10gen.com" created="Sat, 27 Mar 2021 14:58:50 +0000"  >&lt;p&gt;Reassigning this ticket to the Replication team based on the Slack discussion on what the proposed fix would look like. The idea is to add another step to the rollback&amp;#45;to&amp;#45;stable procedure to fix up the config.transactions collection. Putting the onus on rollback avoids any performance impact on the write path on primaries and secondaries. Note that the following proposal won&apos;t address how atClusterTime reads on a primary and secondary may return different results for the config.transactions collection. But it will fully address the implications of updates to a config.transactions record being coalesced into a single write on primaries and secondaries on retryable writes&apos; exactly&amp;#45;once semantics. (I have also filed &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-55578&quot; title=&quot;Disallow atClusterTime reads on the config.transactions collection&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-55578&quot;&gt;&lt;del&gt;SERVER-55578&lt;/del&gt;&lt;/a&gt; to disallow atClusterTime reads on the config.transactions collection outside of resharding.)&lt;/p&gt;

&lt;p&gt;(Before rollback) A config.transactions record with a lastWriteOpTime.ts &amp;gt; stable&amp;#95;timestamp may have been coalesced with other updates to the config.transactions record where the user data write was timestamped &amp;lt;= stable&amp;#95;timestamp. Such a config.transactions record need to be fixed up because rollback&amp;#45;to&amp;#45;stable would effectively restore the config.transactions record to a timestamp from before the timestamp of the most recent user data write &amp;lt;= stable&amp;#95;timestamp.&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;                 ST&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;                 v&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;+--------+-------|-------+&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;|   A1   |   A2     A3   |&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;+------------------------+&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;Let&apos;s say A1, A2, and A3 are 3 statements performed in the same retryable write with A1 applied in its own batch and A2 and A3 applied in another batch together. At stable&amp;#95;timestamp, the config.transactions record&apos;s lastWriteOpTime would be A1. This is because secondary oplog application only did a single write to the config.transactions record timestamped at A3. However, the user data write for A2 is reflected in the stable&amp;#95;timestamp and therefore the config.transactions record&apos;s lastWriteOpTime must be updated to A2 to prevent the A2 statement from being re-executed if the node became primary.&lt;/p&gt;

&lt;p&gt;(After rolling back the data to stable&amp;#95;timestamp and before truncating the oplog) The rollback&amp;#45;to&amp;#45;stable procedure would scan forward through the oplog starting from [stable&amp;#95;timestamp + 1] (these are the oplog entries being rolled back):&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;(a) If the oplog entry isn&apos;t for a retryable write, then skip over it. Notably, &lt;a href=&quot;https://github.com/mongodb/mongo/blob/f05a11cfa32ff12c1110aa3657ec80a80de05dc3/src/mongo/db/repl/session_update_tracker.cpp#L174-L185&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;multi-statement transactions do not coalsece any writes to the config.transactions collection&lt;/a&gt; and so any write to the config.transactions record from an earlier retryable write statement would have been timestamped &amp;lt;= stable&amp;#95;timestamp already.&lt;/li&gt;
	&lt;li&gt;(b) If the oplog entry has a null prevOpTime (these are oplog entries which begin a retryable write), then skip over it.&lt;/li&gt;
	&lt;li&gt;(c) If the oplog entry has prevOpTime &amp;lt;= stable&amp;#95;timestamp, then attempt to look up oplog entry:
	&lt;ul&gt;
		&lt;li&gt;(c.i) If the oplog entry is found, then restore the lastWriteOpTime, lastWriteDate, and txnNum from the {t, ts}, wall, and txnNumber of the oplog entry found via prevOpTime, respectively.&lt;/li&gt;
		&lt;li&gt;(c.ii) If the oplog entry isn&apos;t found due to the oplog having been truncated before the stable&amp;#95;timestamp (via the OplogCapMaintainerThread), then restore the lastWriteOpTime and txnNum from the prevOpTime and txnNumber of the oplog entry being scanned, respectively. A value for the lastWriteDate must be faked because the true value has already been truncated from the oplog. A lastWriteOpTime value that isn&apos;t present in the node&apos;s oplog would cause it to return IncompleteTransactionHistory as a primary if more statements for the txnNum retryable write were performed (thereby preventing multiple executing without being able to answer if the write had happened at all), while still allowing oplog application of more statements for a txnNum retryable write as a secondary (where the primary generating the oplog entries must still have had enough oplog to prove each retryable write statement executed only once).&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;(d) If the oplog entry has prevOpTime &amp;gt; stable&amp;#95;timestamp, then skip over it. These oplog entries are safe to ignore because case (c) above would have already handled updating the config.transactions record from an earlier scanned oplog entry.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The correctness of case (b) requires also updating secondary oplog application to &lt;a href=&quot;https://github.com/mongodb/mongo/blob/79951c2fe99ab96ca340ff5f51ba63f129643507/src/mongo/db/repl/session_update_tracker.cpp#L218&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;not coalesce multiple updates to the same config.transactions record across different txnNumbers&lt;/a&gt;.&lt;/p&gt;

&lt;p/&gt;
&lt;div id=&quot;syntaxplugin&quot; class=&quot;syntaxplugin&quot; style=&quot;border: 1px dashed #bbb; border-radius: 5px !important; overflow: auto; max-height: 30em;&quot;&gt;
&lt;table cellspacing=&quot;0&quot; cellpadding=&quot;0&quot; border=&quot;0&quot; width=&quot;100%&quot; style=&quot;font-size: 1em; line-height: 1.4em !important; font-weight: normal; font-style: normal; color: black;&quot;&gt;
		&lt;tbody &gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;  margin-top: 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;                 ST&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;                 v&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;+--------+-------|-------+&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;|   A1   |   A2     B1   |&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
				&lt;tr id=&quot;syntaxplugin_code_and_gutter&quot;&gt;
						&lt;td  style=&quot; line-height: 1.4em !important; padding: 0em; vertical-align: top;&quot;&gt;
					&lt;pre style=&quot;font-size: 1em; margin: 0 10px;   margin-bottom: 10px;  width: auto; padding: 0;&quot;&gt;&lt;span style=&quot;color: black; font-family: &apos;Consolas&apos;, &apos;Bitstream Vera Sans Mono&apos;, &apos;Courier New&apos;, Courier, monospace !important;&quot;&gt;+------------------------+&lt;/span&gt;&lt;/pre&gt;
			&lt;/td&gt;
		&lt;/tr&gt;
			&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p/&gt;

&lt;p&gt;Let&apos;s say instead of A3 as a third statement in the same retryable write, it was actually B1 of a single statement in the subsequent txnNumber. At stable&amp;#95;timestamp, the config.transactions record&apos;s lastWriteOpTime would still be A1. The config.transactions record&apos;s lastWriteOpTime must still be updated to A2 to prevent the A2 statement from being re-executed if the node became primary. While a well&amp;#45;behaved driver wouldn&apos;t knowingly resend the txnNumber for A2 again, retryable writes are also designed to protect against multiple execution of writes from a delayed message that had gotten stuck in a network switch. Moreover, replica sets are not guaranteed to retain oplog entries from before stable&amp;#95;timestamp and so the rollback&amp;#45;to&amp;#45;stable procedure must be able to have the config.transactions collection become correct without knowing the true lastWriteOpTime and txnNum for the config.transactions record at stable&amp;#95;timestamp from its oplog entries.&lt;/p&gt;

&lt;p&gt;Changing SessionUpdateTracker to not coalesce multiple updates to the same config.transactions record across different txnNumbers would mean that secondary oplog application did two writes to the config.transactions record - the first timestamped at A2 and the second timestamped at B1. There is no additional work for rollback&amp;#45;to&amp;#45;stable to do because there is already a write to the config.transactions record timestamped at A2. While patch builds as part of &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-55214&quot; title=&quot;Resharding txn cloner can miss config.transactions entry when fetching&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-55214&quot;&gt;&lt;del&gt;SERVER-55214&lt;/del&gt;&lt;/a&gt; demonstrated a 70-80% performance regression for vectored insert when coalescing updates to the same config.transactions record was turned completely off, it is believed that multiple retryable writes on the same logical session are unlikely to end up in the same oplog batch and so there wouldn&apos;t be a noticeable performance impact. It may be valuable to test the SessionUpdateTracker change first in isolation and confirm this belief before starting work on the rest of the changes to the rollback&amp;#45;to&amp;#45;stable procedure.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10420">
                    <name>Backports</name>
                                            <outwardlinks description="backported by">
                                                        </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10520">
                    <name>Problem/Incident</name>
                                            <outwardlinks description="causes">
                                                        </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                            <outwardlinks description="related to">
                                        <issuelink>
            <issuekey id="1660948">SERVER-55578</issuekey>
        </issuelink>
                            </outwardlinks>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="1628188">SERVER-54626</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="1649421">SERVER-55214</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="1700958">SERVER-56631</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="1708611">SERVER-56796</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="1333345">SERVER-47844</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="1333350">SERVER-47845</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                <customfield id="customfield_10050" key="com.atlassian.jira.toolkit:comments">
                        <customfieldname># Replies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>3.0</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18555" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname># of Sprints</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>3.0</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_12450" key="com.atlassian.jira.plugin.system.customfieldtypes:multicheckboxes">
                        <customfieldname>Backport Requested</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="18953"><![CDATA[v4.4]]></customfieldvalue>
    <customfieldvalue key="16775"><![CDATA[v4.2]]></customfieldvalue>
    <customfieldvalue key="15640"><![CDATA[v4.0]]></customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10011" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Backwards Compatibility</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10038"><![CDATA[Fully Compatible]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                            <customfield id="customfield_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Tue, 27 Apr 2021 14:15:11 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        2 years, 40 weeks, 1 day ago
    
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_18254" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Dependencies</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue><![CDATA[]]></customfieldvalue>


                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                        <customfield id="customfield_17050" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Downstream Team Attention</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="16941"><![CDATA[Not Needed]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                <customfield id="customfield_10057" key="com.atlassian.jira.toolkit:lastusercommented">
                        <customfieldname>Last comment by Customer</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>true</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                            <customfield id="customfield_10056" key="com.atlassian.jira.toolkit:lastupdaterorcommenter">
                        <customfieldname>Last commenter</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>luke.bonanomi@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            2 years, 40 weeks, 1 day ago
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_16465" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Linked BF Score</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>70.0</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                        <customfield id="customfield_10032" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>Operating System</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10026"><![CDATA[ALL]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>xgen-internal-githook</customfieldvalue>
            <customfieldvalue>jason.chan@mongodb.com</customfieldvalue>
            <customfieldvalue>max.hirschhorn@mongodb.com</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hz04r3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hylcr3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>9223372036854775807</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                <customfield id="customfield_10557" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue id="4853">Repl 2021-04-19</customfieldvalue>
    <customfieldvalue id="4858">Repl 2021-05-03</customfieldvalue>
    <customfieldvalue id="4859">Repl 2021-05-17</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10053" key="com.atlassian.jira.ext.charting:timeinstatus">
                        <customfieldname>Time In Status</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_22870" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Triagers</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_14350" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>serverRank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hyzr07:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                    </customfields>
    </item>
</channel>
</rss>