summaryrefslogtreecommitdiff
path: root/src/mongo/s/config_upgrade.h
blob: c32f3b3945df110df2d5a5ab027167e1f5965abc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/**
 *    Copyright (C) 2012 10gen Inc.
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *    As a special exception, the copyright holders give permission to link the
 *    code of portions of this program with the OpenSSL library under certain
 *    conditions as described in each individual source file and distribute
 *    linked combinations including the program with the OpenSSL library. You
 *    must comply with the GNU Affero General Public License in all respects
 *    for all of the code used other than as permitted herein. If you modify
 *    file(s) with this exception, you may extend this exception to your
 *    version of the file(s), but you are not obligated to do so. If you do not
 *    wish to do so, delete this exception statement from your version. If you
 *    delete this exception statement from all source files in the program,
 *    then also delete it in the license file.
 */

#pragma once

#include "mongo/client/dbclientinterface.h"
#include "mongo/s/type_config_version.h"

namespace mongo {

    /**
     *
     * UPGRADE HISTORY
     *
     * The enum below documents the version changes to *both* the config server data layout
     * and the versioning protocol between clients (i.e. the set of calls between mongos and
     * mongod).
     *
     * Friendly notice:
     *
     * EVERY CHANGE EITHER IN CONFIG LAYOUT AND IN S/D PROTOCOL MUST BE RECORDED HERE BY AN INCREASE
     * IN THE VERSION AND BY TAKING THE FOLLOWING STEPS. (IF YOU DON'T UNDERSTAND THESE STEPS, YOU
     * SHOULD PROBABLY NOT BE UPGRADING THE VERSIONS BY YOURSELF.)
     *
     * + A new entry in the UpgradeHistory enum is created
     * + The CURRENT_CONFIG_VERSION below is incremented to that version
     * + There should be a determination if the MIN_COMPATIBLE_CONFIG_VERSION should be increased or
     *   not. This means determining if, by introducing the changes to layout and/or protocol, the
     *   new mongos/d can co-exist in a cluster with the old ones.
     * + If layout changes are involved, there should be a corresponding layout upgrade routine. See
     *   for instance config_upgrade_vX_to_vY.cpp.
     * + Again, if a layout change occurs, the base upgrade method, config_upgrade_v0_to_vX.cpp must
     *   be upgraded. This means that all new clusters will start at the newest versions.
     *
     */
    enum UpgradeHistory {

        /**
         * The empty version, reported when there is no config server data
         */
        UpgradeHistory_EmptyVersion = 0,

        /**
         * The unreported version older mongoses used before config.version collection existed
         *
         * If there is a config.shards/databases/collections collection but no config.version
         * collection, version 1 is assumed
         */
        UpgradeHistory_UnreportedVersion = 1,

        /**
         * NOTE: We skip version 2 here since it is very old and we shouldn't see it in the wild.
         *
         * Do not skip upgrade versions in the future.
         */

        /**
         * Base version used by pre-2.4 mongoses with no collection epochs.
         */
        UpgradeHistory_NoEpochVersion = 3,

        /**
         * Version upgrade which added collection epochs to all sharded collections and
         * chunks.
         *
         * Also:
         * + Version document in config.version now of the form:
         *   { minVersion : X, currentVersion : Y, clusterId : OID(...) }
         * + Mongos pings include a "mongoVersion" field indicating the mongos version
         * + Mongos pings include a "configVersion" field indicating the current config version
         * + Mongos explicitly ignores any collection with a "primary" field
         */
        UpgradeHistory_MandatoryEpochVersion = 4,

        /**
         * Version upgrade with the following changes:
         *
         * + Dropping a collection from mongos now waits for the chunks to be removed from the
         *   config server before contacting each shard. Because of this, mongos should be
         *   upgraded first before mongod or never drop collections during upgrade.
         */
        UpgradeHistory_DummyBumpPre2_6 = 5
    };

    //
    // CURRENT VERSION CONSTANTS
    // Note: We must modify these constants we add new upgrades, otherwise we will fail on startup
    //

    // Earliest version we're compatible with
    const int MIN_COMPATIBLE_CONFIG_VERSION = UpgradeHistory_MandatoryEpochVersion;

    // Latest version we know how to communicate with
    const int CURRENT_CONFIG_VERSION = UpgradeHistory_DummyBumpPre2_6;

    //
    // DECLARATION OF UPGRADE FUNCTIONALITY
    // These functions must also be wired explicitly to the upgrade path in
    // config_upgrade.cpp::createRegistry()
    //

    bool doUpgradeV0ToV5(const ConnectionString& configLoc,
                         const VersionType& lastVersionInfo,
                         string* errMsg);

    bool doUpgradeV4ToV5(const ConnectionString& configLoc,
                         const VersionType& lastVersionInfo,
                         string* errMsg);

    //
    // Utilities for upgrading a config database to a new config version and checking the status of
    // the config version.
    //

    enum VersionStatus {

        // No way to upgrade the test version to be compatible with current version
        VersionStatus_Incompatible,

        // Current version is compatible with test version
        VersionStatus_Compatible,

        // Test version must be upgraded to be compatible with current version
        VersionStatus_NeedUpgrade
    };

    /**
     * Checks whether or not a particular cluster version is compatible with our current
     * version and mongodb version.  The version is compatible if it falls between the
     * MIN_COMPATIBLE_CONFIG_VERSION and CURRENT_CONFIG_VERSION and is not explicitly excluded.
     *
     * @return a VersionStatus enum indicating compatibility
     */
    VersionStatus isConfigVersionCompatible(const VersionType& versionInfo, string* whyNot);

    /**
     * Returns the config version of the cluster pointed at by the connection string.
     *
     * @return OK if version found successfully, error status if something bad happened.
     */
    Status getConfigVersion(const ConnectionString& configLoc, VersionType* versionInfo);

    /**
     * Checks the config version and ensures it's the latest version, otherwise tries to update.
     *
     * @return true if the config version is now compatible.
     * @return initial and finalVersionInfo indicating the start and end versions of the upgrade.
     *         These are the same if no upgrade occurred.
     */
    bool checkAndUpgradeConfigVersion(const ConnectionString& configLoc,
                                      bool upgrade,
                                      VersionType* initialVersionInfo,
                                      VersionType* finalVersionInfo,
                                      string* errMsg);

} // end namespace