1 /* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
2 
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License, version 2.0,
5   as published by the Free Software Foundation.
6 
7   This program is also distributed with certain software (including
8   but not limited to OpenSSL) that is licensed under separate terms,
9   as designated in a particular file or component or in included license
10   documentation.  The authors of MySQL hereby grant you an additional
11   permission to link the program and your derivative works with the
12   separately licensed software that they have included with MySQL.
13 
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License, version 2.0, for more details.
18 
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software
21   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
22 
23 #ifndef DD__BOOTSTRAP_CTX_INCLUDED
24 #define DD__BOOTSTRAP_CTX_INCLUDED
25 
26 #include <set>
27 
28 #include "my_dbug.h"                      // DBUG_ASSERT
29 #include "my_inttypes.h"                  // uint
30 #include "mysql_version.h"                // MYSQL_VERSION_ID
31 #include "sql/dd/dd_version.h"            // DD_VERSION
32 #include "sql/dd/info_schema/metadata.h"  // IS_DD_VERSION
33 #include "sql/mysqld.h"                   // opt_initialize
34 
35 class THD;
36 
37 namespace dd {
38 namespace bootstrap {
39 
40 // Enumeration of bootstrapping stages.
41 enum class Stage {
42   NOT_STARTED,          // Not started.
43   STARTED,              // Started, nothing prepared yet.
44   CREATED_TABLESPACES,  // Created predefined tablespaces.
45   FETCHED_PROPERTIES,   // Done reading DD properties.
46   CREATED_TABLES,       // Tables created, able to store persistently.
47   SYNCED,               // Cached meta data synced with persistent storage.
48   UPGRADED_TABLES,      // Created new table versions and migrated meta data.
49   POPULATED,            // (Re)populated tables with meta data.
50   STORED_DD_META_DATA,  // Stored the hard coded meta data of the DD tables.
51   VERSION_UPDATED,      // The properties in 'dd_properties' are updated.
52   FINISHED              // Completed.
53 };
54 
55 // Individual DD version labels that we can refer to.
56 static constexpr uint DD_VERSION_80011 = 80011;
57 static constexpr uint DD_VERSION_80012 = 80012;
58 static constexpr uint DD_VERSION_80013 = 80013;
59 static constexpr uint DD_VERSION_80014 = 80014;
60 static constexpr uint DD_VERSION_80015 = 80015;
61 static constexpr uint DD_VERSION_80016 = 80016;
62 static constexpr uint DD_VERSION_80017 = 80017;
63 static constexpr uint DD_VERSION_80021 = 80021;
64 
65 /*
66   Set of supported DD version labels. A supported DD version is a version
67   from which we can upgrade. In the case of downgrade, this is not relevant,
68   since the set of supported versions is defined when the server is built,
69   and newer version numbers are not added to this set. in the case of
70   downgrade, we instead have to check the MINOR_DOWNGRADE_THRESHOLD, which is
71   stored in the 'dd_properties' table by the server from which we downgrade.
72 */
73 static std::set<uint> supported_dd_versions = {
74     DD_VERSION_80011, DD_VERSION_80012, DD_VERSION_80013, DD_VERSION_80014,
75     DD_VERSION_80015, DD_VERSION_80016, DD_VERSION_80017, DD_VERSION_80021};
76 
77 // Individual server version labels that we can refer to.
78 static constexpr uint SERVER_VERSION_50700 = 50700;
79 static constexpr uint SERVER_VERSION_80011 = 80011;
80 static constexpr uint SERVER_VERSION_80013 = 80013;
81 static constexpr uint SERVER_VERSION_80014 = 80014;
82 static constexpr uint SERVER_VERSION_80015 = 80015;
83 static constexpr uint SERVER_VERSION_80016 = 80016;
84 
85 /*
86   Set of unsupported server version labels. An unsupported server version is a
87   version from which we can't upgrade.
88 */
89 static std::set<uint> unsupported_server_versions = {};
90 
91 class DD_bootstrap_ctx {
92  private:
93   uint m_did_dd_upgrade_from = 0;
94   uint m_actual_dd_version = 0;
95   uint m_upgraded_server_version = 0;
96   Stage m_stage = Stage::NOT_STARTED;
97 
98   uint m_did_I_S_upgrade_from = 0;
99   uint m_actual_I_S_version = 0;
100 
101  public:
DD_bootstrap_ctx()102   DD_bootstrap_ctx() {}
103 
104   static DD_bootstrap_ctx &instance();
105 
get_stage()106   Stage get_stage() const { return m_stage; }
107 
set_stage(Stage stage)108   void set_stage(Stage stage) { m_stage = stage; }
109 
supported_dd_version()110   bool supported_dd_version() const {
111     return (supported_dd_versions.find(m_actual_dd_version) !=
112             supported_dd_versions.end());
113   }
114 
set_actual_dd_version(uint actual_dd_version)115   void set_actual_dd_version(uint actual_dd_version) {
116     m_actual_dd_version = actual_dd_version;
117   }
118 
set_actual_I_S_version(uint actual_I_S_version)119   void set_actual_I_S_version(uint actual_I_S_version) {
120     m_actual_I_S_version = actual_I_S_version;
121   }
122 
get_actual_dd_version()123   uint get_actual_dd_version() const { return m_actual_dd_version; }
124 
get_actual_I_S_version()125   uint get_actual_I_S_version() const { return m_actual_I_S_version; }
126 
set_dd_upgrade_done()127   void set_dd_upgrade_done() {
128     DBUG_ASSERT(m_did_dd_upgrade_from == 0);
129     DBUG_ASSERT(is_dd_upgrade());
130     m_did_dd_upgrade_from = m_actual_dd_version;
131   }
132 
dd_upgrade_done()133   bool dd_upgrade_done() const { return m_did_dd_upgrade_from != 0; }
134 
set_I_S_upgrade_done()135   void set_I_S_upgrade_done() {
136     DBUG_ASSERT(m_did_I_S_upgrade_from == 0);
137     m_did_I_S_upgrade_from = m_actual_I_S_version;
138   }
139 
I_S_upgrade_done()140   bool I_S_upgrade_done() const { return m_did_I_S_upgrade_from != 0; }
141 
actual_dd_version_is(uint compare_actual_dd_version)142   bool actual_dd_version_is(uint compare_actual_dd_version) const {
143     return (m_actual_dd_version == compare_actual_dd_version);
144   }
145 
supported_server_version(uint version)146   bool supported_server_version(uint version) const {
147     return (unsupported_server_versions.find(version) ==
148             unsupported_server_versions.end()) &&
149            MYSQL_VERSION_ID > version;
150   }
151 
supported_server_version()152   bool supported_server_version() const {
153     return supported_server_version(m_upgraded_server_version);
154   }
155 
set_upgraded_server_version(uint upgraded_server_version)156   void set_upgraded_server_version(uint upgraded_server_version) {
157     m_upgraded_server_version = upgraded_server_version;
158   }
159 
get_upgraded_server_version()160   uint get_upgraded_server_version() const { return m_upgraded_server_version; }
161 
upgraded_server_version_is(uint compare_upgraded_server_version)162   bool upgraded_server_version_is(uint compare_upgraded_server_version) const {
163     return (m_upgraded_server_version == compare_upgraded_server_version);
164   }
165 
is_restart()166   bool is_restart() const {
167     return !opt_initialize && (m_actual_dd_version == dd::DD_VERSION) &&
168            (m_upgraded_server_version == MYSQL_VERSION_ID);
169   }
170 
is_dd_upgrade()171   bool is_dd_upgrade() const {
172     return !opt_initialize && (m_actual_dd_version < dd::DD_VERSION);
173   }
174 
is_server_upgrade()175   bool is_server_upgrade() const {
176     return !opt_initialize && (m_upgraded_server_version < MYSQL_VERSION_ID);
177   }
178 
is_dd_upgrade_from_before(uint compare_actual_dd_version)179   bool is_dd_upgrade_from_before(uint compare_actual_dd_version) const {
180     return (is_dd_upgrade() && m_actual_dd_version < compare_actual_dd_version);
181   }
182 
is_server_upgrade_from_before(uint compare_upgraded_server_version)183   bool is_server_upgrade_from_before(
184       uint compare_upgraded_server_version) const {
185     return (is_server_upgrade() &&
186             m_upgraded_server_version < compare_upgraded_server_version);
187   }
188 
is_server_upgrade_from_after(uint compare_upgraded_server_version)189   bool is_server_upgrade_from_after(
190       uint compare_upgraded_server_version) const {
191     return (is_server_upgrade() &&
192             m_upgraded_server_version > compare_upgraded_server_version);
193   }
194 
is_minor_downgrade()195   bool is_minor_downgrade() const {
196     return !opt_initialize &&
197            (m_actual_dd_version / 10000 == dd::DD_VERSION / 10000) &&
198            (m_actual_dd_version > dd::DD_VERSION);
199   }
200 
201   bool is_above_minor_downgrade_threshold(THD *thd) const;
202 
is_initialize()203   bool is_initialize() const {
204     return opt_initialize && (m_actual_dd_version == dd::DD_VERSION);
205   }
206 };
207 
208 }  // namespace bootstrap
209 }  // namespace dd
210 
211 #endif  // DD__BOOTSTRAP_CTX_INCLUDED
212