1 /*
2 Copyright (c) 2003, 2021, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #ifndef NODE_STATE_HPP
26 #define NODE_STATE_HPP
27
28 #include <NdbOut.hpp>
29 #include <NodeBitmask.hpp>
30
31 #define JAM_FILE_ID 1
32
33
34 struct NodeStatePOD
35 {
36 enum StartLevel {
37 /**
38 * SL_NOTHING
39 * Nothing is started
40 */
41 SL_NOTHING = 0,
42
43 /**
44 * SL_CMVMI
45 * CMVMI is started
46 * Listening to management server
47 * Qmgr knows nothing...
48 */
49 SL_CMVMI = 1,
50
51 /**
52 * SL_STARTING
53 * All blocks are starting
54 * Initial or restart
55 * During this phase is <b>startPhase</b> valid
56 */
57 SL_STARTING = 2,
58
59 /**
60 * The database is started open for connections
61 */
62 SL_STARTED = 3,
63
64 SL_SINGLEUSER = 4,
65
66 /**
67 * SL_STOPPING_1 - Inform API
68 * API is informed not to start transactions on node
69 * The database is about to close
70 *
71 * New TcSeize(s) are refused (TcSeizeRef)
72 */
73 SL_STOPPING_1 = 5,
74
75 /**
76 * SL_STOPPING_2 - Close TC
77 * New transactions(TC) are refused
78 */
79 SL_STOPPING_2 = 6,
80
81
82
83
84 /**
85 * SL_STOPPING_3 - Wait for reads in LQH
86 * No transactions are running in TC
87 * New scans(s) and read(s) are refused in LQH
88 * NS: The node is not Primary for any fragment
89 * NS: No node is allow to start
90 */
91 SL_STOPPING_3 = 7,
92
93 /**
94 * SL_STOPPING_4 - Close LQH
95 * Node is out of DIGETNODES
96 * Insert/Update/Delete can still be running in LQH
97 * GCP is refused
98 * Node is not startable w.o Node Recovery
99 */
100 SL_STOPPING_4 = 8
101 };
102
103 enum StartType {
104 ST_INITIAL_START = 0,
105 ST_SYSTEM_RESTART = 1,
106 ST_NODE_RESTART = 2,
107 ST_INITIAL_NODE_RESTART = 3,
108 ST_ILLEGAL_TYPE = 4
109 };
110
111 /**
112 * Length in 32-bit words
113 */
114 STATIC_CONST( DataLength = 8 + NodeBitmask::Size );
115
116 /**
117 * Constructor(s)
118 */
119 void init();
120
121 /**
122 * Current start level
123 */
124 Uint32 startLevel;
125
126 /**
127 * Node group
128 */
129 Uint32 nodeGroup; // valid when startLevel == SL_STARTING
130
131 /**
132 * Dynamic id
133 */
134 union {
135 Uint32 dynamicId; // valid when startLevel == SL_STARTING to API
136 Uint32 masterNodeId; // When from cntr
137 };
138
139 /**
140 *
141 */
142 union {
143 struct {
144 Uint32 startPhase; // valid when startLevel == SL_STARTING
145 Uint32 restartType; // valid when startLevel == SL_STARTING
146 } starting;
147 struct {
148 Uint32 systemShutdown; // valid when startLevel == SL_STOPPING_{X}
149 Uint32 timeout;
150 Uint32 alarmTime;
151 } stopping;
152
153
154 };
155 Uint32 singleUserMode;
156 Uint32 singleUserApi; //the single user node
157
158 BitmaskPOD<NodeBitmask::Size> m_connected_nodes;
159
160 void setDynamicId(Uint32 dynamic);
161 void setNodeGroup(Uint32 group);
162 void setSingleUser(Uint32 s);
163 void setSingleUserApi(Uint32 n);
164
165
166 /**
167 * Is a node restart in progress (ordinary or initial)
168 */
169 bool getNodeRestartInProgress() const;
170
171 /**
172 * Is a system restart ongoing
173 */
174 bool getSystemRestartInProgress() const;
175
176 /**
177 * Are we started
178 */
getStartedNodeStatePOD179 bool getStarted() const {
180 return startLevel == SL_STARTED || startLevel == SL_SINGLEUSER;
181 }
182
183 /**
184 * Is in single user mode?
185 */
186 bool getSingleUserMode() const;
187
188 /**
189 * Is in single user mode
190 */
191 Uint32 getSingleUserApi() const;
192 };
193
194 class NodeState : public NodeStatePOD
195 {
196 public:
197 NodeState();
198 NodeState(StartLevel);
199 NodeState(StartLevel, bool systemShutdown);
200 NodeState(StartLevel, Uint32 startPhase, StartType);
201
202 NodeState& operator=(const NodeStatePOD&);
203 };
204
205 inline
NodeState()206 NodeState::NodeState(){
207 init();
208 }
209
210 inline
211 void
init()212 NodeStatePOD::init(){
213 startLevel = SL_CMVMI;
214 nodeGroup = 0xFFFFFFFF;
215 dynamicId = 0xFFFFFFFF;
216 singleUserMode = 0;
217 singleUserApi = 0xFFFFFFFF;
218 m_connected_nodes.clear();
219 }
220
221 inline
NodeState(StartLevel sl)222 NodeState::NodeState(StartLevel sl){
223 init();
224 startLevel = sl;
225 singleUserMode = 0;
226 singleUserApi = 0xFFFFFFFF;
227 }
228
229 inline
NodeState(StartLevel sl,Uint32 sp,StartType typeOfStart)230 NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){
231 init();
232 startLevel = sl;
233 starting.startPhase = sp;
234 starting.restartType = typeOfStart;
235 singleUserMode = 0;
236 singleUserApi = 0xFFFFFFFF;
237 }
238
239 inline
NodeState(StartLevel sl,bool sys)240 NodeState::NodeState(StartLevel sl, bool sys){
241 init();
242 startLevel = sl;
243 stopping.systemShutdown = sys;
244 singleUserMode = 0;
245 singleUserApi = 0xFFFFFFFF;
246 }
247
248 inline
setDynamicId(Uint32 dynamic)249 void NodeStatePOD::setDynamicId(Uint32 dynamic){
250 dynamicId = dynamic;
251 }
252
253 inline
setNodeGroup(Uint32 group)254 void NodeStatePOD::setNodeGroup(Uint32 group){
255 nodeGroup = group;
256 }
257
258 inline
setSingleUser(Uint32 s)259 void NodeStatePOD::setSingleUser(Uint32 s) {
260 singleUserMode = s;
261 }
262
263 inline
setSingleUserApi(Uint32 n)264 void NodeStatePOD::setSingleUserApi(Uint32 n) {
265 singleUserApi = n;
266 }
267 inline
getNodeRestartInProgress() const268 bool NodeStatePOD::getNodeRestartInProgress() const {
269 return startLevel == SL_STARTING &&
270 (starting.restartType == ST_NODE_RESTART ||
271 starting.restartType == ST_INITIAL_NODE_RESTART);
272 }
273
274 inline
getSingleUserMode() const275 bool NodeStatePOD::getSingleUserMode() const {
276 return singleUserMode;
277 }
278
279 inline
getSingleUserApi() const280 Uint32 NodeStatePOD::getSingleUserApi() const {
281 return singleUserApi;
282 }
283
284 inline
getSystemRestartInProgress() const285 bool NodeStatePOD::getSystemRestartInProgress() const {
286 return startLevel == SL_STARTING && starting.restartType == ST_SYSTEM_RESTART;
287 }
288
289 inline
290 NdbOut &
operator <<(NdbOut & ndbout,const NodeStatePOD & state)291 operator<<(NdbOut& ndbout, const NodeStatePOD & state){
292 ndbout << "[NodeState: startLevel: ";
293 switch(state.startLevel){
294 case NodeState::SL_NOTHING:
295 ndbout << "<NOTHING> ]";
296 break;
297 case NodeState::SL_CMVMI:
298 ndbout << "<CMVMI> ]";
299 break;
300 case NodeState::SL_STARTING:
301 ndbout << "<STARTING type: ";
302 switch(state.starting.restartType){
303 case NodeState::ST_INITIAL_START:
304 ndbout << " INITIAL START";
305 break;
306 case NodeState::ST_SYSTEM_RESTART:
307 ndbout << " SYSTEM RESTART ";
308 break;
309 case NodeState::ST_NODE_RESTART:
310 ndbout << " NODE RESTART ";
311 break;
312 case NodeState::ST_INITIAL_NODE_RESTART:
313 ndbout << " INITIAL NODE RESTART ";
314 break;
315 case NodeState::ST_ILLEGAL_TYPE:
316 default:
317 ndbout << " UNKNOWN " << state.starting.restartType;
318 }
319 ndbout << " phase: " << state.starting.startPhase << "> ]";
320 break;
321 case NodeState::SL_STARTED:
322 ndbout << "<STARTED> ]";
323 break;
324 case NodeState::SL_STOPPING_1:
325 ndbout << "<STOPPING 1 sys: " << state.stopping.systemShutdown << "> ]";
326 break;
327 case NodeState::SL_STOPPING_2:
328 ndbout << "<STOPPING 2 sys: " << state.stopping.systemShutdown << "> ]";
329 break;
330 case NodeState::SL_STOPPING_3:
331 ndbout << "<STOPPING 3 sys: " << state.stopping.systemShutdown << "> ]";
332 break;
333 case NodeState::SL_STOPPING_4:
334 ndbout << "<STOPPING 4 sys: " << state.stopping.systemShutdown << "> ]";
335 break;
336 default:
337 ndbout << "<UNKNOWN " << state.startLevel << "> ]";
338 }
339 return ndbout;
340 }
341
342 inline
343 NodeState&
operator =(const NodeStatePOD & ns)344 NodeState::operator=(const NodeStatePOD& ns)
345 {
346 startLevel = ns.startLevel;
347 nodeGroup = ns.nodeGroup;
348 dynamicId = ns.dynamicId;
349 // masterNodeId is union with dynamicId
350 starting.startPhase = ns.starting.startPhase;
351 starting.restartType = ns.starting.restartType;
352 // stopping.systemShutdown is union with starting.startPhase
353 // stopping.timeout is union with starting.restartType
354 stopping.alarmTime = ns.stopping.alarmTime;
355 singleUserMode = ns.singleUserMode;
356 singleUserApi = ns.singleUserApi;
357 m_connected_nodes.assign(ns.m_connected_nodes);
358 return * this;
359 }
360
361 #undef JAM_FILE_ID
362
363 #endif
364