<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Thu Feb 08 05:15:58 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-48044] FCV::isVersion should invariant if FCV is unset</title>
                <link>https://jira.mongodb.org/browse/SERVER-48044</link>
                <project id="10000" key="SERVER">Core Server</project>
                    <description>&lt;p&gt;A &lt;a href=&quot;https://github.com/mongodb/mongo/blob/a709403384c88487ed34c940be1f5e3b7d12646e/src/mongo/db/server_options.h#L229-L231&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;new way&lt;/a&gt; was introduced to read the FCV variable, but it did not carry over the check that the FCV value was initialized.&lt;/p&gt;</description>
                <environment></environment>
        <key id="1344684">SERVER-48044</key>
            <summary>FCV::isVersion should invariant if FCV is unset</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="3">Duplicate</resolution>
                                        <assignee username="lingzhi.deng@mongodb.com">Lingzhi Deng</assignee>
                                    <reporter username="daniel.gottlieb@mongodb.com">Daniel Gottlieb</reporter>
                        <labels>
                    </labels>
                <created>Fri, 8 May 2020 15:37:22 +0000</created>
                <updated>Wed, 22 Jul 2020 19:05:28 +0000</updated>
                            <resolved>Wed, 22 Jul 2020 19:05:28 +0000</resolved>
                                                                    <component>Replication</component>
                                        <votes>0</votes>
                                    <watches>6</watches>
                                                                                                                <comments>
                            <comment id="3297405" author="lingzhi.deng" created="Wed, 22 Jul 2020 19:04:55 +0000"  >&lt;p&gt;The reason we might want to always invariant that the FCV is set (i.e. not kUnsetDefault44Behavior) both from clean startup and from restart is because we want to fail loudly if we write (i.e. persist data) based on FCV before having a FCV. By invarianting isVersionInitialized(), we force a crash and force the engineer to think about whether their code is supposed to run before having a FCV. And even if yes, the engineer need to figure out what the default behavior should be. The default behavior is not necessarily 44 (last stable) behavior and should be determine case by case (e.g. creating a collection/index before initializing a node as replSet will follow newer behavior when FCV is kUnsetDefault44Behavior).&lt;/p&gt;

&lt;p&gt;In order to make sure callers of isVersionInitialized() are safe, we will probably need to evaluate callers of isVersionInitialized before each release, making sure they are not defaulting to a behavior that would cause unexpected behavior after upgrade/downgrade. This is tracked by &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48106&quot; title=&quot;Remove all callers of FCV isVersionInitialized()&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48106&quot;&gt;&lt;del&gt;SERVER-48106&lt;/del&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;After &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-49070&quot; title=&quot;Add FCV gating helpers&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-49070&quot;&gt;&lt;del&gt;SERVER-49070&lt;/del&gt;&lt;/a&gt;, isVersion() is gone. And for new FCV helpers being added in &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-49070&quot; title=&quot;Add FCV gating helpers&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-49070&quot;&gt;&lt;del&gt;SERVER-49070&lt;/del&gt;&lt;/a&gt;, we will also add an invariant for isVersionInitialized(). So I think we can close this.&lt;/p&gt;</comment>
                            <comment id="3275478" author="siyuan.zhou@10gen.com" created="Wed, 8 Jul 2020 18:19:44 +0000"  >&lt;p&gt;Discussed with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=lingzhi.deng&quot; class=&quot;user-hover&quot; rel=&quot;lingzhi.deng&quot;&gt;lingzhi.deng&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jason.chan&quot; class=&quot;user-hover&quot; rel=&quot;jason.chan&quot;&gt;jason.chan&lt;/a&gt;&#160;and &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;&#160;offline. I have a better understanding of Lingzhi&apos;s proposal now.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The FCV could still be uninitialized (i.e.&#160;&lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt;) even if the FCV has finished loading.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I thought FCV is only&#160;uninitialized during startup, but it&apos;s not the case. For example, it remains&#160;uninitialized when a node started with &lt;tt&gt;--replSet&lt;/tt&gt;&#160;but hasn&apos;t received &lt;tt&gt;replSetInitiate&lt;/tt&gt; or finished initial sync.&lt;/p&gt;

&lt;p&gt;Because of this subtle difference, Lingzhi is proposing to add a new variable&#160;to distinguish startup from uninitialized. The new variable is set during startup and will be checked as an invariant when comparing FCV&apos;s.&lt;/p&gt;

&lt;p&gt;As mentioned before,&#160;kUnsetDefault44Behavior should be treated the same as kFullyDowngradedTo44 in most cases. The new isFCVGreaterThanOrEqualTo() helper encourages developers to follow this pattern.&lt;/p&gt;</comment>
                            <comment id="3267804" author="lingzhi.deng" created="Thu, 2 Jul 2020 04:43:43 +0000"  >&lt;p&gt;I dont think we change to &lt;tt&gt;kFullyDowngradedTo44&lt;/tt&gt; after loading from disk if the FCV has never been set before. &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; still return false in that case, &lt;a href=&quot;https://github.com/mongodb/mongo/blob/c593d0fb6eec6b4f3c7ae02a5c3de73ad6e3af95/src/mongo/db/server_options.h#L209&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;which means FCV == &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt;&lt;/a&gt;.&lt;br/&gt;
Option 2 is to invariant that we only do FCV comparisons after the FCV has finished loading. Note: The FCV could still be uninitialized (i.e. &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt;) even if the FCV has finished loading. On restart, we have timelines like:&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;mongod startup -------------- load fcv ------------------------- &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;loadedFCV=false                 loadedFCV=true&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;Option 2 is to add an invariant similar to &lt;tt&gt;invariant(loadedFCV)&lt;/tt&gt; (instead of &lt;tt&gt;invariant(isVersionInitialized())&lt;/tt&gt;) in FCV helpers to make sure we only do FCV comparisons after the FCV has finished loading. As I said, it is not a bug if we do FCV comparisons before FCV is ever initialized, but it is a bug if we do FCV comparisons before FCV is loaded from disk after restart. So option 2 helps to detect the latter.&lt;/p&gt;

&lt;p&gt;EDIT: By the way, we probably should stop using the term &quot;uninitialized&quot; to mean both default &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt; and &quot;not yet been loaded after restart&quot; because they are fundamentally different. And we could have &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt; even if we finish loading after restarts (e.g. Start a node with --replSet and restart it before running replSetInitiate). Having a &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt; FCV value is not an issue, the real issue is reading the in-memory FCV value when it has &quot;not yet been loaded after restart&quot;.&lt;/p&gt;</comment>
                            <comment id="3267733" author="siyuan.zhou@10gen.com" created="Thu, 2 Jul 2020 04:06:53 +0000"  >&lt;p&gt;Nice write-up! I don&apos;t follow how different would option 2 be from the current behavior + adding the invariant. IIUC, the FCV &lt;a href=&quot;https://github.com/mongodb/mongo/blob/c593d0fb6eec6b4f3c7ae02a5c3de73ad6e3af95/src/mongo/db/server_options.h#L186-L190&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;changes to kFullyDowngradedTo44 after initialization&lt;/a&gt;. In the case of shutdownTask() mentioned above, do we have to add the check of initialization for it?&lt;/p&gt;</comment>
                            <comment id="3263876" author="jason.chan" created="Wed, 1 Jul 2020 17:43:01 +0000"  >&lt;p&gt;Discussed this offline with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=lingzhi.deng&quot; class=&quot;user-hover&quot; rel=&quot;lingzhi.deng&quot;&gt;lingzhi.deng&lt;/a&gt;, we agree that option 2 would be most ideal because it draws the clearest contract of only checking FCV when the FCV value has been loaded from disk. If there is a codepath that checks FCV before we have loaded it from disk, we will crash always, and it will be up to the developer to decide between the following:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;move their logic to only run after the FCV has finished loading (we believe this to be a possibility for most cases)&lt;/li&gt;
	&lt;li&gt;add a isVersionInitialized() check along with their FCV helper to gate their feature
	&lt;ul&gt;
		&lt;li&gt;we believe this case to be extremely rare, and so we think we can eliminate the number of sources that use this pattern. We hope this will decrease the chances of people copy and pasting.&lt;/li&gt;
	&lt;/ul&gt;
	&lt;/li&gt;
	&lt;li&gt;decide if there is an alternative to FCV to choose whether to run old/new behaviour&lt;/li&gt;
&lt;/ul&gt;

</comment>
                            <comment id="3261492" author="lingzhi.deng" created="Wed, 1 Jul 2020 14:33:08 +0000"  >&lt;p&gt;After thinking about this a bit more, I think ideally we should not need to worry about if FCV is initialized in FCV helpers. The reasons is that in case 1 (clean startup) I posted above, we need to allow general comparison against &lt;tt&gt;kUnsetDefaultXXBehavior&lt;/tt&gt; (the smallest FCV constant) so that we can use FCV checks to choose default behaviors before FCV is initialized from a clean startup.&lt;/p&gt;

&lt;p&gt;In fact, two (&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-34523&quot; title=&quot;Invariant failure isVersionInitialized() src/mongo/db/server_options.h 207&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-34523&quot;&gt;&lt;del&gt;SERVER-34523&lt;/del&gt;&lt;/a&gt;, &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-46791&quot; title=&quot;Fix incorrect FCV initialisation check to allow compound hashed index&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-46791&quot;&gt;&lt;del&gt;SERVER-46791&lt;/del&gt;&lt;/a&gt;) out of the three tickets Siyuan mentioned as &quot;bugs&quot; due to FCV initialization problems were actually expected to run at clean startup with default old stable FCV. They became bugs because we got false positive from the invariant. If we had a helper like &lt;tt&gt;isFCVGreaterThanOrEqualTo()&lt;/tt&gt; as proposed in this project (without the invariant), &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-34523&quot; title=&quot;Invariant failure isVersionInitialized() src/mongo/db/server_options.h 207&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-34523&quot;&gt;&lt;del&gt;SERVER-34523&lt;/del&gt;&lt;/a&gt; could had been written as &lt;tt&gt;isFCVGreaterThanOrEqualTo(kFullyUpgradedTo40)&lt;/tt&gt; and &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-46791&quot; title=&quot;Fix incorrect FCV initialisation check to allow compound hashed index&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-46791&quot;&gt;&lt;del&gt;SERVER-46791&lt;/del&gt;&lt;/a&gt; could had been written as &lt;tt&gt;isFCVGreaterThanOrEqualTo(kFullyUpgradedTo44)&lt;/tt&gt;. And this would handle the default behaviors as well.&lt;/p&gt;

&lt;p&gt;That said, I do understand that loading the FCV from disk after a restart makes things a bit trickier. And I believe we wanted an invariant at the first place because we wanted to catch bugs where we do FCV comparisons before FCV is loaded (&lt;b&gt;Note: I believe it is not a bug if we do FCV comparisons before FCV is ever initialized, but it is a bug if we do FCV comparisons before FCV is loaded from disk after restart&lt;/b&gt;). But I could argue that in an ideal world, we should always load FCV as (one of) the very first thing during restart so we don&apos;t need to worry about this problem in subsystem that start up after. Currently, we load FCV in &lt;tt&gt;repairDatabasesAndCheckVersion()&lt;/tt&gt;, so this would only be a problem to start up logic that&apos;s run before &lt;a href=&quot;https://github.com/mongodb/mongo/blob/51d7101f5eeee0c1b26dd0c035be47effc6373b7/src/mongo/db/repair_database_and_check_version.cpp#L581&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;this line&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So here are the options:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Add invariants on &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; to FCV helpers and check for uninitialized FCV explicitly (This includes having an extra argument to the helpers to control the invariant).&lt;br/&gt;
 I think this actually makes FCV helpers harder to use for the reasons I stated above and because we have quite a few common code paths that could be run before FCV is ever set after a clean startup. &lt;/li&gt;
	&lt;li&gt;Add a global variable indicating whether necessary startup steps has completed and we invariant FCV helpers are only used after startup completes (i.e. after FCV finishes loading).&lt;br/&gt;
 This is because, it is fine to have an uninitialized (default) FCV after startup if the FCV has never been set. But this will catch bugs like &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48050&quot; title=&quot;FCV should be initialized before attempting to restart in-progress index builds&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48050&quot;&gt;&lt;del&gt;SERVER-48050&lt;/del&gt;&lt;/a&gt; because that compares FCV before FCV is loaded from disk after restart.&lt;/li&gt;
	&lt;li&gt;Do nothing and ensure that FCV is loaded early enough after restart.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Either 2 or 3 sounds good to me. &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; &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;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jason.chan&quot; class=&quot;user-hover&quot; rel=&quot;jason.chan&quot;&gt;jason.chan&lt;/a&gt; what do you think?&lt;/p&gt;</comment>
                            <comment id="3232139" author="siyuan.zhou@10gen.com" created="Tue, 30 Jun 2020 23:21:30 +0000"  >&lt;p&gt;Discussed with &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=lingzhi.deng&quot; class=&quot;user-hover&quot; rel=&quot;lingzhi.deng&quot;&gt;lingzhi.deng&lt;/a&gt; offline. My understanding is that upgrade / downgrade is done in two-phase.&#160;&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Support both old and new behaviors by upgrading the binary.&lt;/li&gt;
	&lt;li&gt;Enable the new behavior actively by using FCV.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Because FCV is only used to enable a new behavior, it&apos;s desired to treat uninitialized FCV as the lowest FCV. In other words, both old and new behaviors are accepted, it&apos;s just the matter of choice. &lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/db/mongod_main.cpp#L1086&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;shutdownTask()&lt;/a&gt; and &lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp#L181&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;ReplSetHeartbeatArgsV1::addToBSON()&lt;/a&gt; are good examples.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48050&quot; title=&quot;FCV should be initialized before attempting to restart in-progress index builds&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48050&quot;&gt;&lt;del&gt;SERVER-48050&lt;/del&gt;&lt;/a&gt; diverged from the two-phase pattern mentioned above. It uses FCV to decide whether to &lt;a href=&quot;https://github.com/mongodb/mongo/blob/a709403384c88487ed34c940be1f5e3b7d12646e/src/mongo/db/index/index_descriptor.cpp#L198-L201&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;support&lt;/b&gt; the new behavior&lt;/a&gt;. We&apos;ve seen problems in mixed-version testing in the safe reconfig project following this pattern, so I&apos;m wondering whether this use case is prone to similar errors.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=lingzhi.deng&quot; class=&quot;user-hover&quot; rel=&quot;lingzhi.deng&quot;&gt;lingzhi.deng&lt;/a&gt;, do you think it&apos;s preferable to add the invariant and check for uninitialized FCV explicit?&lt;/p&gt;</comment>
                            <comment id="3231252" author="lingzhi.deng" created="Tue, 30 Jun 2020 21:45:44 +0000"  >&lt;p&gt;Agreed. But I think there are two parts of it.&lt;br/&gt;
1. The FCV is not initialized because it is a clean startup. In this case, I would argue that defaulting FCV to &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt; is correct. In the new upgrade/downgrade project, if we are planning to introduce less-than and greater-than operators rather than equality comparison, I think all these will start to make sense and server behaviors will default to last-lts. Most of the current callers of &lt;tt&gt;isVersion()&lt;/tt&gt; fall into this category I believe.&lt;br/&gt;
2. The FCV is initialized but not yet loaded after a restart. I believe this is the case that you think that&apos;s error-prone. If we use &lt;tt&gt;kUnsetDefault44Behavior&lt;/tt&gt; temporarily before the FCV doc is loaded, then it will be problematic because that doesn&apos;t necessarily match what&apos;s on-disk and/or what existing clients expect. And I believe &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48050&quot; title=&quot;FCV should be initialized before attempting to restart in-progress index builds&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48050&quot;&gt;&lt;del&gt;SERVER-48050&lt;/del&gt;&lt;/a&gt; falls into this category.&lt;/p&gt;

&lt;p&gt;What&apos;s even more interesting is that, hypothetically, if there is a piece of code which is fine with defaulting to older behaviors in case 1 but would like to avoid flipping the behaviors in case 2, then it seems hard for the same logic to differentiate the two cases.  Maybe instructing WT to load FCV earlier like Dan.G mentioned above is the ultimate solution for case 2, but until then, I dont know if it is even doable?&lt;/p&gt;</comment>
                            <comment id="3231155" author="siyuan.zhou@10gen.com" created="Tue, 30 Jun 2020 21:07:14 +0000"  >&lt;p&gt;Great auditing! If it&apos;s the common pattern to allow uninitialized FCV, how could developers support cross-version behavior? If they have to rely on some other subtle assumptions, like timing, ordering or specific locking, I&apos;m afraid it&apos;s error-prone and a major limitation of FCV. Perhaps it&apos;s fine to follow the old or new behavior blindly before FCV initialization, then we need to include it into our best practice and design the FCV interface for that.&lt;/p&gt;

&lt;p&gt;For a developer, it&apos;s hard to know whether their code could run before FCV initialization or not. It would be unfortunate if every developer has to know the implementation details of FCV. In reality, they&apos;d probably wait until it fails in patch builds or more likely in build failures of mixed version testing to realize the problem.&lt;/p&gt;

&lt;p&gt;On a side note, if we need to change the interface of FCV checking, I&apos;d prefer to leverage the type system, like adding an argument or &lt;a href=&quot;https://github.com/mongodb/mongo/blob/e4139a8394fb7d35503a0b559fc90723f7ab9de7/src/mongo/db/concurrency/replication_state_transition_lock_guard.h#L53&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;defining a class&lt;/a&gt;, than smart naming.&lt;/p&gt;</comment>
                            <comment id="3231102" author="lingzhi.deng" created="Tue, 30 Jun 2020 20:37:50 +0000"  >&lt;p&gt;Interestingly, currently all &lt;a href=&quot;http://10.1.2.40/mongodb/search?q=%2Bfunction-ref%3Amongo%3A%3AServerGlobalParams%3A%3AFeatureCompatibility%3A%3AisVersion%28mongo%3A%3AServerGlobalParams%3A%3AFeatureCompatibility%3A%3AVersion%29&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;callers&lt;/a&gt; of &lt;tt&gt;FeatureCompatibility::isVersion()&lt;/tt&gt; kind of &quot;expect&quot; an uninitialized FCV (except 1 which I believe is a bug and 4 on mongos). So I am not sure if there is any value fixing isVersion() at this point as having an uninitialized FCV seems to be a common case here (surprisingly).&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/db/index/index_descriptor.cpp#L182&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;IndexDescriptor::compareIndexOptions()&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 I believe this one is a bug, see &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48050&quot; title=&quot;FCV should be initialized before attempting to restart in-progress index builds&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48050&quot;&gt;&lt;del&gt;SERVER-48050&lt;/del&gt;&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/db/mongod_main.cpp#L1086&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;&lt;tt&gt;shutdownTask()&lt;/tt&gt;&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 We don&apos;t necessarily have an initialized FCV if we shut down before a replica set is initialized.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/db/repl/repl_set_heartbeat_args_v1.cpp#L181&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;&lt;tt&gt;ReplSetHeartbeatArgsV1::addToBSON()&lt;/tt&gt;&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 We could send heartbeat to fetch config before we initialize the server as a node in a replSet (i.e. before the FCV is initialized).&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d3367bd91ff4d2e61bb7a25b38769a6c68e5722/src/mongo/s/mongos_main.cpp#L292&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;&lt;tt&gt;cleanupTask()&lt;/tt&gt; on mongos&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 This one is probably irrelevant because mongos always initialize FCV to &lt;tt&gt;kFullyUpgradedTo46&lt;/tt&gt; I think?&lt;/li&gt;
&lt;/ol&gt;
</comment>
                            <comment id="3230535" author="lingzhi.deng" created="Tue, 30 Jun 2020 16:52:35 +0000"  >&lt;p&gt;Yes, that would work too. The goal here is to make it very explicit that engineers should avoid using FCV checks this way unless they have reasons to. I think we can add that argument for &lt;tt&gt;isVersion()&lt;/tt&gt; for now as an example that we might follow later when we add more helpers in this project. (Though we will need to skip invarianting FCV for &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-48050&quot; title=&quot;FCV should be initialized before attempting to restart in-progress index builds&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-48050&quot;&gt;&lt;del&gt;SERVER-48050&lt;/del&gt;&lt;/a&gt; as a TODO)&lt;/p&gt;</comment>
                            <comment id="3230490" author="jason.chan" created="Tue, 30 Jun 2020 16:34:55 +0000"  >&lt;p&gt;&lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=lingzhi.deng&quot; class=&quot;user-hover&quot; rel=&quot;lingzhi.deng&quot;&gt;lingzhi.deng&lt;/a&gt; Thanks for looking into this, I think adding a new helper makes sense. I believe our goal should be to make it more obvious to developers that we should only be checking &lt;tt&gt;isVersionInitialized&lt;/tt&gt; for codepaths that expect to run when FCV is not yet initialized. We can replace the existing callers of &lt;tt&gt;isVersionInitialized&lt;/tt&gt; with this new helper to prevent future copy and pasting.&lt;/p&gt;

&lt;p&gt;EDIT: Or instead of adding a &quot;_EXPECT_UNINITIALIZED_FCV&quot; version of each new helper, how about passing in an argument flag that denotes whether we should check that the version is initialized?&lt;/p&gt;</comment>
                            <comment id="3230380" author="lingzhi.deng" created="Tue, 30 Jun 2020 15:51:47 +0000"  >&lt;p&gt;I am not sure if there is anything else that needs to be done as part of this ticket. And I am not sure if we can really get rid of this pattern completely even if we do what Dan.G recommended above to load the FCV earlier. In the two cases I posted above, we don&apos;t initialize the FCV&#160;on purpose because the replica set is not initialized yet. But we allow commands like &lt;tt&gt;serverStatus&lt;/tt&gt; and&#160;&lt;tt&gt;isMaster&lt;/tt&gt; to run. If some common code paths like these need to check FCV, they will certainly have to differentiate whether the FCV is initialized.&lt;/p&gt;

&lt;p&gt;Even if the &lt;tt&gt;isVersion()&lt;/tt&gt; is going away, new helpers would likely still have similar issues if they are used in code paths that run before the FCV is initialized / loaded. Maybe we can have a special version of these helpers that have a &quot;_EXPECT_UNINITIALIZED_FCV&quot; suffix and hopefully we can minimize the use of them?  &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jason.chan&quot; class=&quot;user-hover&quot; rel=&quot;jason.chan&quot;&gt;jason.chan&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; any thoughts?&lt;/p&gt;</comment>
                            <comment id="3230318" author="lingzhi.deng" created="Tue, 30 Jun 2020 15:32:39 +0000"  >&lt;p&gt;Here are the current &lt;a href=&quot;http://10.1.2.40/mongodb/search?q=%2Bfunction-ref%3A%22mongo%3A%3AServerGlobalParams%3A%3AFeatureCompatibility%3A%3AisVersionInitialized%28%29+const%22&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;callers&lt;/a&gt; of &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; on the master branch as of 2d910ef unless we want to audit 4.4 (which I think it&apos;s probably not worth doing at this point).&lt;br/&gt;
 As the master branch is relatively new compared to 4.4, there are only two places where we call &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; with &lt;tt&gt;getVersion()&lt;/tt&gt;:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d910ef001820ede2d16e597947a4e0893040030/src/mongo/db/vector_clock.cpp#L189&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;&lt;tt&gt;VectorClock::GossipFormat::OnlyGossipOutOnNewFCV::out()&lt;/tt&gt;&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 This one is needed because this is part of how we append operationTime to request responses. If a request (e.g. &lt;tt&gt;isMaster&lt;/tt&gt;) comes before the node is initialized as a replSet (or added as a new node in a replSet), the fcv is not initialized and thus we will need to check &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; before using the &lt;tt&gt;getVersion()&lt;/tt&gt;. An example call stack looks like:
&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; #4  0x0000557e66129179 in mongo::ServerGlobalParams::FeatureCompatibility::getVersion (this=0x557e6c011cb8 &amp;lt;mongo::serverGlobalParams+472&amp;gt;) at src/mongo/db/server_options.h:214&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;#5  0x0000557e693020ac in mongo::VectorClock::GossipFormat::OnlyGossipOutOnNewFCV&amp;lt;mongo::VectorClock::GossipFormat::Plain&amp;gt;::out (this=0x7f1e9b8d5c20, service=0x7f1e9b830620, opCtx=&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;    0x7f1e9b7a6720, permitRefresh=false, out=0x7f1e8341c460, time=..., component=mongo::VectorClock::Component::ConfigTime) at src/mongo/db/vector_clock.cpp:190&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;#6  0x0000557e692ff1b0 in mongo::VectorClock::_gossipOutComponent (this=0x7f1e9b55b7b0, opCtx=0x7f1e9b7a6720, out=0x7f1e8341c460, time=...,&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;    component=mongo::VectorClock::Component::ConfigTime) at src/mongo/db/vector_clock.cpp:389&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;#7  0x0000557e66de7059 in mongo::(anonymous namespace)::VectorClockMongoD::_gossipOutInternal (this=0x7f1e9b55b7b0, opCtx=0x7f1e9b7a6720, out=0x7f1e8341c460, time=...)&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;    at src/mongo/db/vector_clock_mongod.cpp:114&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;#8  0x0000557e692fefb0 in mongo::VectorClock::gossipOut (this=0x7f1e9b55b7b0, opCtx=0x7f1e9b7a6720, outMessage=0x7f1e8341c460, defaultClientSessionTags=0)                                         at src/mongo/db/vector_clock.cpp:361&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;#9  0x0000557e66933e6b in mongo::(anonymous namespace)::appendClusterAndOperationTime (opCtx=0x7f1e9b7a6720, commandBodyFieldsBob=0x7f1e8341c460, metadataBob=0x7f1e8341c460, startTime=...)&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;    at src/mongo/db/service_entry_point_common.cpp:448&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;#10 0x0000557e66937227 in mongo::(anonymous namespace)::runCommandImpl (opCtx=0x7f1e9b7a6720, invocation=0x7f1e95118160, request=..., replyBuilder=0x7f1e9b51d020, startOperationTime=...,&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;    behaviors=warning: RTTI symbol not found for class &apos;mongo::ServiceEntryPointMongod::Hooks&apos;&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;..., extraFieldsBuilder=0x7f1e8341c800, sessionOptions=...) at src/mongo/db/service_entry_point_common.cpp:887&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;#11 0x0000557e66939812 in mongo::(anonymous namespace)::execCommandDatabase (opCtx=0x7f1e9b7a6720, command=0x557e6bfd8280 &amp;lt;mongo::repl::(anonymous namespace)::cmdismaster&amp;gt;, request=...,&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;    replyBuilder=0x7f1e9b51d020, behaviors=warning: RTTI symbol not found for class &apos;mongo::ServiceEntryPointMongod::Hooks&apos;&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;...) at src/mongo/db/service_entry_point_common.cpp:1176&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;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d910ef001820ede2d16e597947a4e0893040030/src/mongo/db/storage/storage_engine_impl.cpp#L861-L862&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;&lt;b&gt;&lt;tt&gt;StorageEngineImpl::supportsResumableIndexBuilds()&lt;/tt&gt;&lt;/b&gt;&lt;/a&gt;&lt;br/&gt;
 This one is called &lt;a href=&quot;https://github.com/mongodb/mongo/blob/2d910ef001820ede2d16e597947a4e0893040030/src/mongo/db/storage/storage_init.cpp#L74&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;as part of &lt;tt&gt;serverStatus&lt;/tt&gt;&lt;/a&gt;. Thus, similarly, if &lt;tt&gt;serverStatus&lt;/tt&gt; is called (or by FTDC) before the node is initialized, we will need to check &lt;tt&gt;isVersionInitialized()&lt;/tt&gt; before using the &lt;tt&gt;getVersion()&lt;/tt&gt;. An example call stack looks like:
&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;#4  0x000055a271cf3a5a in mongo::ServerGlobalParams::FeatureCompatibility::getVersion (this=0x55a277be1db8 &amp;lt;mongo::serverGlobalParams+472&amp;gt;) at src/mongo/db/server_options.h:214&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;#5  0x000055a272ec121c in mongo::StorageEngineImpl::supportsResumableIndexBuilds (this=0x7fdaeec35560) at src/mongo/db/storage/storage_engine_impl.cpp:857&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;#6  0x000055a271faa1d0 in mongo::(anonymous namespace)::StorageSSS::generateSection (this=0x55a277ba2720 &amp;lt;mongo::(anonymous namespace)::storageSSS&amp;gt;, opCtx=0x7fdae8898e20, configElement=...)&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;    at src/mongo/db/storage/storage_init.cpp:60&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;#7  0x000055a271c29206 in mongo::ServerStatusSection::appendSection (this=0x55a277ba2720 &amp;lt;mongo::(anonymous namespace)::storageSSS&amp;gt;, opCtx=0x7fdae8898e20, configElement=...,&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;    result=0x7fdadf88d480) at src/mongo/db/commands/server_status.h:100&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;#8  0x000055a2734c9ba7 in mongo::CmdServerStatus::run (this=0x55a277bc53c0 &amp;lt;mongo::(anonymous namespace)::CmdServerStatusInstantiator::getInstance()::instance&amp;gt;, opCtx=0x7fdae8898e20,&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;    dbname=&quot;&quot;, cmdObj=..., result=...) at src/mongo/db/commands/server_status.cpp:127&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;#9  0x000055a271ffec52 in mongo::BasicCommand::runWithReplyBuilder (this=0x55a277bc53c0 &amp;lt;mongo::(anonymous namespace)::CmdServerStatusInstantiator::getInstance()::instance&amp;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;    opCtx=0x7fdae8898e20, db=&quot;&quot;, cmdObj=..., replyBuilder=0x7fdadf88d670) at src/mongo/db/commands.h:807&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;#10 0x000055a2736b5b60 in mongo::BasicCommandWithReplyBuilderInterface::Invocation::run (this=0x7fdae8575600, opCtx=0x7fdae8898e20, result=0x7fdadf88d670) at src/mongo/db/commands.cpp:778&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;#11 0x000055a2736ac8de in mongo::CommandHelpers::runCommandDirectly (opCtx=0x7fdae8898e20, request=...) at src/mongo/db/commands.cpp:157&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;#12 0x000055a2725a8270 in mongo::FTDCServerStatusCommandCollector::collect (this=0x7fdaeed78860, opCtx=0x7fdae8898e20, builder=...) at src/mongo/db/ftdc/ftdc_server.cpp:234&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;#13 0x000055a2725ec08e in mongo::FTDCCollectorCollection::collect (this=0x7fdae318e168, client=0x7fdae6c99d40) at src/mongo/db/ftdc/collector.cpp:91&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;#14 0x000055a2725f145e in mongo::FTDCController::doLoop (this=0x7fdae318e020) at src/mongo/db/ftdc/controller.cpp:249&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;#15 0x000055a2725f0b6d in mongo::FTDCController::&amp;lt;lambda()&amp;gt;::operator()(void) const (__closure=0x7fdaeec0b200) at src/mongo/db/ftdc/controller.cpp:145&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;#16 0x000055a2725f2186 in std::__invoke_impl&amp;lt;void, mongo::FTDCController::start()::&amp;lt;lambda()&amp;gt; &amp;gt;(std::__invoke_other, mongo::FTDCController::&amp;lt;lambda()&amp;gt; &amp;amp;&amp;amp;) (__f=...)&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;    at /usr/include/c++/8/bits/invoke.h:60&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;/li&gt;
&lt;/ol&gt;
</comment>
                            <comment id="3217881" author="steven.vannelli" created="Mon, 22 Jun 2020 17:24:04 +0000"  >&lt;p&gt;This helper will likely be removed. So we will close this ticket, assuming that is the case.&lt;/p&gt;

&lt;p&gt;*Even if this helper goes away, we should still audit whether the FCV is initialized. &lt;/p&gt;</comment>
                            <comment id="3208569" author="siyuan.zhou@10gen.com" created="Mon, 15 Jun 2020 18:02:39 +0000"  >&lt;p&gt;Good point,&#160;&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;! I&apos;m convinced we should add the invariant and I agree we should audit all of the copy and paste. I&apos;m afraid we won&apos;t know whether it&apos;s possible to remove them until we do the auditing. However, at this time of the beginning of 4.6, we&apos;d better do it now than later.&lt;/p&gt;

&lt;p&gt;As we will be using FCV more often than before with quarterly releases, it may be worth considering a better design/implementation of FCV initialization. I &lt;a href=&quot;https://jira.mongodb.org/issues/?jql=text%20~%20%22FCV%20initialized%22%20and%20project%3D%22Core%20Server%22&quot; class=&quot;external-link&quot; rel=&quot;nofollow&quot;&gt;found&lt;/a&gt; at least three bugs fixed by Execution, Query and Replication team due to the late initialization:&#160;&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-34523&quot; title=&quot;Invariant failure isVersionInitialized() src/mongo/db/server_options.h 207&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-34523&quot;&gt;&lt;del&gt;SERVER-34523&lt;/del&gt;&lt;/a&gt;,&#160;&lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-46791&quot; title=&quot;Fix incorrect FCV initialisation check to allow compound hashed index&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-46791&quot;&gt;&lt;del&gt;SERVER-46791&lt;/del&gt;&lt;/a&gt; and &lt;a href=&quot;https://jira.mongodb.org/browse/SERVER-32630&quot; title=&quot;Minimize reads of the featureCompatibilityVersion parameter that occur prior to the featureCompatibilityVersion document being read/created&quot; class=&quot;issue-link&quot; data-issue-key=&quot;SERVER-32630&quot;&gt;&lt;del&gt;SERVER-32630&lt;/del&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;CC &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;&#160;and &lt;a href=&quot;https://jira.mongodb.org/secure/ViewProfile.jspa?name=jason.chan&quot; class=&quot;user-hover&quot; rel=&quot;jason.chan&quot;&gt;jason.chan&lt;/a&gt; since they are working on upgrade / downgrade for quarterly versions.&lt;/p&gt;</comment>
                            <comment id="3117969" author="daniel.gottlieb@10gen.com" created="Tue, 26 May 2020 23:56:17 +0000"  >&lt;blockquote&gt;
&lt;p&gt;I understand the goal is to force developers to keep the initialization in mind, but people tend to copy and paste it. I don&apos;t think the caller of FCV should always worry about the initialization of FCV.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The goal is not to force developers to keep initialization in mind, and you&apos;re right the caller shouldn&apos;t care, which is why only a &lt;a href=&quot;http://10.1.2.40/mongodb_v4.4/source/src/mongo/db/commands/feature_compatibility_version.cpp#159&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;select&lt;/a&gt; &lt;a href=&quot;http://10.1.2.40/mongodb_v4.4/source/src/mongo/db/db.cpp#474&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;http://10.1.2.40/mongodb_v4.4/source/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp#141&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;things&lt;/a&gt; &lt;a href=&quot;http://10.1.2.40/mongodb_v4.4/source/src/mongo/db/storage/wiredtiger/wiredtiger_kv_engine.cpp#173&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;should&lt;/a&gt; ever ask if FCV is initialized and the rest should crash the node if it&apos;s not. Those cases can then be better understood by looping in the appropriate stakeholders to figure out what the right solution is. I understand that copy/paste is a problem; this ticket should remove all of those uses as well. But there&apos;s always a risk the pattern is reintroduced; FCV and startup seem simple which empowers people to make mistakes. I&apos;d love to fix that with code, but I find that&apos;s typically futile. I think we can only hope for education to work.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I feel the fundamental problem is that the order of FCV initialization and the code in development isn&apos;t clear or FCV initialization should be earlier&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;I agree FCV should be set earlier, but there are limits to how early it can be set. FCV has a fundamental design flaw; because it&apos;s in a collection, WT has to first startup and the catalog has to be loaded. There are a handful of usages at catalog startup that may not be right, but do legitimately have to consider what to do. &lt;/p&gt;

&lt;p&gt;Alternatively we could have storage learn about namespaces and how to find the FCV document (pushing things even earlier, but not early enough for the logging changes with recoverable rollback in 4.0), but I don&apos;t think we&apos;re at the point of giving that serious consideration.&lt;/p&gt;</comment>
                            <comment id="3117783" author="siyuan.zhou@10gen.com" created="Tue, 26 May 2020 23:21:55 +0000"  >&lt;p&gt;&lt;tt&gt;getVersion()&lt;/tt&gt; has the invariant, but I realized almost all the equality comparison of &lt;tt&gt;getVersion()&lt;/tt&gt; also checks FCV is initialized, so we added this new way to avoid the duplication.&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;    auto isFullyUpgradedTo44 =&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;        (serverGlobalParams.featureCompatibility.isVersionInitialized() &amp;amp;&amp;amp;&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;         serverGlobalParams.featureCompatibility.getVersion() ==&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;             ServerGlobalParams::FeatureCompatibility::Version::kFullyUpgradedTo44);&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;I understand the goal is to force developers to keep the initialization in mind, but people tend to copy and paste it. I don&apos;t think the caller of FCV should always worry about the initialization of FCV.&lt;/p&gt;

&lt;p&gt;It&apos;s a good idea to enforce this invariant, but I think we also need to address the reason why &lt;a href=&quot;http://10.1.2.40/mongodb_v4.4/search?q=%2Bfunction-ref%3A%22mongo%3A%3AServerGlobalParams%3A%3AFeatureCompatibility%3A%3AisVersionInitialized%28%29+const%22&quot; class=&quot;external-link&quot; target=&quot;_blank&quot; rel=&quot;nofollow noopener&quot;&gt;isVersionInitialized() is almost always used with version comparison&lt;/a&gt;. Perhaps most of them are unnecessary. I feel the fundament problem is that the order of FCV initialization and the code in development isn&apos;t clear or FCV initialization should be earlier as seen in BF-17214.&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10420">
                    <name>Backports</name>
                                            <outwardlinks description="backported by">
                                                        </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10010">
                    <name>Duplicate</name>
                                            <outwardlinks description="duplicates">
                                        <issuelink>
            <issuekey id="1388367">SERVER-49070</issuekey>
        </issuelink>
                            </outwardlinks>
                                                        </issuelinktype>
                            <issuelinktype id="10012">
                    <name>Related</name>
                                                                <inwardlinks description="is related to">
                                        <issuelink>
            <issuekey id="1344779">SERVER-48050</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="481135">SERVER-32630</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>18.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>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10055" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>Date of 1st Reply</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Tue, 26 May 2020 23:21:55 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10052" key="com.atlassian.jira.toolkit:dayslastcommented">
                        <customfieldname>Days since reply</customfieldname>
                        <customfieldvalues>
                                        3 years, 29 weeks 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-1781</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>lingzhi.deng@mongodb.com</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_11151" key="com.atlassian.jira.toolkit:LastCommentDate">
                        <customfieldname>Last public comment date</customfieldname>
                        <customfieldvalues>
                            3 years, 29 weeks ago
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_16465" key="com.onresolve.jira.groovy.groovyrunner:scripted-field">
                        <customfieldname>Linked BF Score</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>6.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>daniel.gottlieb@mongodb.com</customfieldvalue>
            <customfieldvalue>jason.chan@mongodb.com</customfieldvalue>
            <customfieldvalue>lingzhi.deng@mongodb.com</customfieldvalue>
            <customfieldvalue>siyuan.zhou@mongodb.com</customfieldvalue>
            <customfieldvalue>steven.vannelli@mongodb.com</customfieldvalue>
    
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                        <customfield id="customfield_14254" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Product Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>1|hxkc8n:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hx7mqn:</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="3934">Repl 2020-06-01</customfieldvalue>
    <customfieldvalue id="3935">Repl 2020-06-15</customfieldvalue>
    <customfieldvalue id="4034">Repl 2020-07-27</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|hxjyhz:</customfieldvalue>

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