<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 04:48:02 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-38132] Aborting a transaction must always update config.transactions and write an abort oplog entry</title>
                <link>https://jira.mongodb.org/browse/SERVER-38132</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;In FCV 4.2, the &lt;tt&gt;TransactionParticipant&lt;/tt&gt; must always update &lt;tt&gt;config.transactions&lt;/tt&gt; and write an abort oplog entry when aborting a transaction. It must do so before updating the in-memory state. We should test that secondaries can apply abort oplog entries for unprepared transactions. Secondaries performing read-only transactions must not attempt to write abort oplog entries.&lt;/p&gt;

&lt;p&gt;Note that it might be technically difficult and unnecessary to update &lt;tt&gt;config.transactions&lt;/tt&gt; and write an abort oplog entry when aborting a transaction due to hearing of a higher transaction number. Once the client uses a higher transaction number, they forgo the right to recover the state of older transactions.&lt;/p&gt;

&lt;p&gt;We will only write an abort oplog entry in FCV 4.2, since 4.0 nodes cannot process abort oplog entries. This is fine, since it is only necessary to perform a write when aborting a transaction when using the session through multiple mongoses.&lt;/p&gt;</description>
                <environment></environment>
        <key id="633970">SERVER-38132</key>
            <summary>Aborting a transaction must always update config.transactions and write an abort oplog entry</summary>
                <type id="3" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14718&amp;avatarType=issuetype">Task</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="2">Won&apos;t Fix</resolution>
                                        <assignee username="tess.avitabile@mongodb.com">Tess Avitabile</assignee>
                                    <reporter username="tess.avitabile@mongodb.com">Tess Avitabile</reporter>
                        <labels>
                            <label>prepare_durability</label>
                    </labels>
                <created>Wed, 14 Nov 2018 20:44:27 +0000</created>
                <updated>Tue, 8 Jan 2019 15:20:59 +0000</updated>
                            <resolved>Fri, 4 Jan 2019 21:46:54 +0000</resolved>
                                                                    <component>Replication</component>
                                        <votes>0</votes>
                                    <watches>6</watches>
                                                                                                                <comments>
                            <comment id="2106160" author="tess.avitabile" created="Fri, 4 Jan 2019 21:46:54 +0000"  >&lt;p&gt;Closing in favor of&#160;&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-38850&quot; title=&quot;Perform noop write before returning NoSuchTransaction error&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-38850&quot;&gt;&lt;del&gt;SERVER-38850&lt;/del&gt;&lt;/a&gt;.&#160;&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-38850&quot; title=&quot;Perform noop write before returning NoSuchTransaction error&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-38850&quot;&gt;&lt;del&gt;SERVER-38850&lt;/del&gt;&lt;/a&gt; fixes all known problematic cases in 4.2. It is simpler, since it does not have upgrade/downgrade concerns, it does not require changes to rollback-via-refetch, it does not have concerns for secondary read-only transactions, and it does not have the question of how internal maintenance operations should handle the need to perform writes.&lt;/p&gt;</comment>
                            <comment id="2105508" author="tess.avitabile" created="Fri, 4 Jan 2019 15:26:59 +0000"  >&lt;p&gt;Yes, secondary transactions are only used for background dbhash today.&lt;/p&gt;

&lt;p&gt;We would need to be careful, since it&apos;s only acceptable to skip writing an abort oplog entry if the transaction did no writes &lt;b&gt;and&lt;/b&gt; we received startTransaction for the transaction. We would still need to write an abort oplog entry if we receive a higher transaction number than we have heard of without startTransaction.&lt;/p&gt;</comment>
                            <comment id="2105504" author="esha.maharishi@10gen.com" created="Fri, 4 Jan 2019 15:24:46 +0000"  >&lt;p&gt;Though, even read-only transactions will have to perform the &quot;linearizable read&quot; equivalent in order for using a recovery router to recover a sharded transaction&apos;s decision to be correct.&lt;/p&gt;</comment>
                            <comment id="2105501" author="esha.maharishi@10gen.com" created="Fri, 4 Jan 2019 15:23:10 +0000"  >&lt;p&gt;Only writing an abort oplog entry if aborting a transaction that performed a write may also make enabling transactions on secondaries in the future easier.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=tess.avitabile&quot; class=&quot;user-hover&quot; rel=&quot;tess.avitabile&quot;&gt;tess.avitabile&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=siyuan.zhou&quot; class=&quot;user-hover&quot; rel=&quot;siyuan.zhou&quot;&gt;siyuan.zhou&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="2105498" author="esha.maharishi@10gen.com" created="Fri, 4 Jan 2019 15:20:53 +0000"  >&lt;p&gt;Is the dbhash check the only complication?&lt;/p&gt;

&lt;p&gt;Also, have we thought about what aborting a read-only transaction should mean? Perhaps it is acceptable to only write an abort oplog entry if aborting a transaction that performed a write?&lt;/p&gt;</comment>
                            <comment id="2105486" author="tess.avitabile" created="Fri, 4 Jan 2019 15:05:53 +0000"  >&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=esha.maharishi&quot; class=&quot;user-hover&quot; rel=&quot;esha.maharishi&quot;&gt;esha.maharishi&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=judah.schvimer&quot; class=&quot;user-hover&quot; rel=&quot;judah.schvimer&quot;&gt;judah.schvimer&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=schwerin&quot; class=&quot;user-hover&quot; rel=&quot;schwerin&quot;&gt;schwerin&lt;/a&gt;, please consider &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=siyuan.zhou&quot; class=&quot;user-hover&quot; rel=&quot;siyuan.zhou&quot;&gt;siyuan.zhou&lt;/a&gt;&apos;s argument above that writing an abort oplog entry is overly complex, since performing a noop write fixes the original problem in all cases except for one-shot transactions, which are not supported in 4.2. I am on the fence about which solution is preferable. One the one hand, I feel more confident that writing an abort oplog entry will cover any counterexamples we have not yet thought of. On the other hand, the implementation for writing an abort oplog entry is complex, since there are certain cases where we cannot write an abort oplog entry (e.g. because we are a secondary) and instead invalidate the session, and we argue that that is correct based on the fact that the next time the transaction is used, we will write an abort oplog entry before returning NoSuchTransaction. The implementation and correctness argument for the noop write is simpler.&lt;/p&gt;</comment>
                            <comment id="2105063" author="siyuan.zhou@10gen.com" created="Fri, 4 Jan 2019 00:44:08 +0000"  >&lt;p&gt;Also to summarize the discussion with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=tess.avitabile&quot; class=&quot;user-hover&quot; rel=&quot;tess.avitabile&quot;&gt;tess.avitabile&lt;/a&gt; about the choice between writing &quot;abort&quot; oplog entry and linearizable read style waiting: linearizable read will fix the original problem described in this ticket, because a returned&#160;&lt;tt&gt;NoSuchTransaction&lt;/tt&gt;&#160;is either from the original primary or from a new primary that knows previous transaction can never survive failover.&#160;Thus the transaction can safely retry with a higher transaction number.&#160;&lt;/p&gt;

&lt;p&gt;The multi-statement transaction protocol guarantees once the server sees &lt;tt&gt;commitTransaction&lt;/tt&gt;, the client will never restart the transaction with the same transaction number, making the retry safe. One-shot transactions will effectively change this assumption and cause the problem Tess mentioned earlier. However we won&apos;t support one-shot transaction in 4.2. Given the complexity of writing &quot;abort&quot; oplog entry than reusing linearizable read, it&apos;s worth considering the minimal change to fix the problem.&lt;/p&gt;</comment>
                            <comment id="2104996" author="max.hirschhorn@10gen.com" created="Thu, 3 Jan 2019 23:12:58 +0000"  >&lt;p&gt;Just to summarize what &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=tess.avitabile&quot; class=&quot;user-hover&quot; rel=&quot;tess.avitabile&quot;&gt;tess.avitabile&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=siyuan.zhou&quot; class=&quot;user-hover&quot; rel=&quot;siyuan.zhou&quot;&gt;siyuan.zhou&lt;/a&gt;, and I discussed in-person: Given that the &lt;tt&gt;run_check_repl_dbhash_background.js&lt;/tt&gt; hook only performs reads within a transaction, it should always be safe to retry and doesn&apos;t face the same risk for &lt;em&gt;exactly once&lt;/em&gt; semantics around retrying an entire transaction on &lt;tt&gt;TransientTransactionError&lt;/tt&gt;. Tess is going to look into how much work it&apos;d be to have the &lt;tt&gt;abortTransaction&lt;/tt&gt; command not write an oplog entry if the transaction did no writes. We can otherwise consider having the &lt;tt&gt;run_check_repl_dbhash_background.js&lt;/tt&gt; hook kill the sessions to abort the transaction rather than &lt;a href=&quot;https://github.com/mongodb/mongo/blob/4be5caeab1810c7c58f205f5eaf66cf97fb07b9e/jstests/hooks/run_check_repl_dbhash_background.js#L281&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;running the &lt;tt&gt;abortTransaction&lt;/tt&gt; command directly&lt;/a&gt;.&lt;/p&gt;</comment>
                            <comment id="2104616" author="tess.avitabile" created="Thu, 3 Jan 2019 18:54:40 +0000"  >&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=max.hirschhorn&quot; class=&quot;user-hover&quot; rel=&quot;max.hirschhorn&quot;&gt;max.hirschhorn&lt;/a&gt;, I am interested in removing support for secondary read-only transactions as part of this work. With this work, we guarantee that we write an abort oplog entry whenever we transition a transaction&apos;s state to &quot;aborted&quot; in memory. However, we cannot write oplog entries when aborting transactions on secondaries. It would be complex and risky to make an exception for aborting transactions on secondaries when test commands are enabled. Of course, removing support for secondary read-only transactions would mean removing our background dbhash testing in master. Does this sound acceptable to you?&lt;/p&gt;</comment>
                            <comment id="2103489" author="tess.avitabile" created="Wed, 2 Jan 2019 19:10:44 +0000"  >&lt;p&gt;Justification for this work:&lt;/p&gt;

&lt;p&gt;It is necessary to perform a write when aborting a transaction so that commands which return &lt;tt&gt;NoSuchTransaction&lt;/tt&gt;&#160;and wait for &lt;tt&gt;writeConcern&lt;/tt&gt;&#160;are guaranteed that a write was done since the transaction was aborted. Otherwise, we could have a scenario where we have term 4 primary which has committed all the writes in its term and a term 5 primary which has committed transaction 10. A command for transaction 10 targeting the term 4 primary would respond with &lt;tt&gt;NoSuchTransaction&lt;/tt&gt;&#160;with no &lt;tt&gt;writeConcern&lt;/tt&gt;&#160;error and with a &lt;tt&gt;TransientTransactionError&lt;/tt&gt;&#160;label, since the term 4 primary had committed all of the writes in its term. The application could then retry the entire transaction and it would be committed twice. This cannot occur in 4.0, since transactions are only supported on single replica sets and drivers will never target an older primary unless they are restarted, in which case they will use a different session. However, it could occur in 4.2, since mongos does not make this guarantee, and if commands are routed through multiple mongoses, a later command could certainly target an older primary.&lt;/p&gt;

&lt;p&gt;One solution is to perform a noop write on abort, similar to a linearizable read. This would address the scenario described above. However, it would be insufficient in the case of one-shot transactions (currently the test-only &lt;tt&gt;doTxn&lt;/tt&gt;&#160;command) and delayed messages. Consider this scenario: The application sends &lt;tt&gt;doTxn&lt;/tt&gt;&#160;for transaction 10 to a 1-node replica set. The message is delayed, and the application times out waiting for a response. The application sends &lt;tt&gt;commitTransaction&lt;/tt&gt;&#160;for transaction 10 to see if the transaction was committed. The node begins and aborts transaction 10 and performs a noop write, then returns &lt;tt&gt;NoSuchTransaction&lt;/tt&gt;&#160;with no &lt;tt&gt;writeConcern&lt;/tt&gt;&#160;error and with a &lt;tt&gt;TransientTransactionError&lt;/tt&gt;&#160;label. Then the node restarts, so all record of transaction 10 is gone. Finally, the &lt;tt&gt;doTxn&lt;/tt&gt;&#160;command arrives, and the node commits transaction 10. However, since the application believes the transaction was definitively not committed, it may attempt to retry the entire transaction. For this reason, we choose to write an abort oplog entry and update &lt;tt&gt;config.transactions&lt;/tt&gt;, so that there is a durable record of the aborted transaction.&lt;/p&gt;

&lt;p&gt;CC &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=siyuan.zhou&quot; class=&quot;user-hover&quot; rel=&quot;siyuan.zhou&quot;&gt;siyuan.zhou&lt;/a&gt;&lt;/p&gt;</comment>
                            <comment id="2087690" author="william.schultz" created="Tue, 11 Dec 2018 21:57:02 +0000"  >&lt;p&gt;If we are now writing abortTransaction oplog entries for single replica set transactions, we may need to consider supporting this in rollbackViaRefetch, since replica set transactions are supported in 4.2 when enableMajorityReadConcern=false, and we use rollbackViaRefetch in this case. I&apos;m not sure if we actually have any existing test coverage of rolling back an aborted transaction, since previously an aborted transaction would have put nothing into the oplog. For easy, broad test coverage of this, we could consider adding transaction aborts to the rollback fuzzer. We already added transactions to it as a part of TIG-871.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                            <outwardlinks description="related to">
                                        <issuelink>
            <issuekey id="665836">SERVER-38850</issuekey>
        </issuelink>
                            </outwardlinks>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="633972">SERVER-38133</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="633973">SERVER-38134</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="633976">SERVER-38135</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>11.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_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Tue, 11 Dec 2018 21:57:02 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        5 years, 5 weeks, 5 days 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_10857" key="com.pyxis.greenhopper.jira:gh-epic-link">
                        <customfieldname>Epic Link</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>PM-1032</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>esha.maharishi@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            5 years, 5 weeks, 5 days ago
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                    <customfield id="customfield_10051" key="com.atlassian.jira.toolkit:participants">
                        <customfieldname>Participants</customfieldname>
                        <customfieldvalues>
                                        <customfieldvalue>esha.maharishi@mongodb.com</customfieldvalue>
            <customfieldvalue>max.hirschhorn@mongodb.com</customfieldvalue>
            <customfieldvalue>siyuan.zhou@mongodb.com</customfieldvalue>
            <customfieldvalue>tess.avitabile@mongodb.com</customfieldvalue>
            <customfieldvalue>william.schultz@mongodb.com</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hucwiv:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|htzevz:</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_23361" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Requested By</customfieldname>
                        <customfieldvalues>
                                

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_10557" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue id="2606">Repl 2018-12-03</customfieldvalue>
    <customfieldvalue id="2607">Repl 2018-12-17</customfieldvalue>
    <customfieldvalue id="2701">Repl 2019-01-14</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|hucis7:</customfieldvalue>

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