1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2021, Oracle and/or its affiliates.
4 
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License, version 2.0,
7 as published by the Free Software Foundation.
8 
9 This program is also distributed with certain software (including
10 but not limited to OpenSSL) that is licensed under separate terms,
11 as designated in a particular file or component or in included license
12 documentation.  The authors of MySQL hereby grant you an additional
13 permission to link the program and your derivative works with the
14 separately licensed software that they have included with MySQL.
15 
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 GNU General Public License, version 2.0, for more details.
20 
21 You should have received a copy of the GNU General Public License along with
22 this program; if not, write to the Free Software Foundation, Inc.,
23 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
24 
25 *****************************************************************************/
26 
27 /**************************************************//**
28 @file include/trx0types.h
29 Transaction system global type definitions
30 
31 Created 3/26/1996 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef trx0types_h
35 #define trx0types_h
36 
37 #include "ut0byte.h"
38 #include "ut0mutex.h"
39 #include "ut0new.h"
40 
41 #include <set>
42 #include <queue>
43 #include <vector>
44 
45 //#include <unordered_set>
46 
47 /** printf(3) format used for printing DB_TRX_ID and other system fields */
48 #define TRX_ID_FMT		IB_ID_FMT
49 
50 /** maximum length that a formatted trx_t::id could take, not including
51 the terminating NUL character. */
52 static const ulint TRX_ID_MAX_LEN = 17;
53 
54 /** Space id of the transaction system page (the system tablespace) */
55 static const ulint TRX_SYS_SPACE = 0;
56 
57 /** Page number of the transaction system page */
58 #define TRX_SYS_PAGE_NO		FSP_TRX_SYS_PAGE_NO
59 
60 /** Random value to check for corruption of trx_t */
61 static const ulint TRX_MAGIC_N = 91118598;
62 
63 /** If this flag is set then the transaction cannot be rolled back
64 asynchronously. */
65 static const ib_uint32_t TRX_FORCE_ROLLBACK_DISABLE = 1 << 29;
66 
67 /** Was the transaction rolled back asynchronously or by the
68 owning thread. This flag is relevant only if TRX_FORCE_ROLLBACK
69 is set.  */
70 static const ib_uint32_t TRX_FORCE_ROLLBACK_ASYNC = 1 << 30;
71 
72 /** Mark the transaction for forced rollback */
73 static const ib_uint32_t TRX_FORCE_ROLLBACK = 1 << 31;
74 
75 /** For masking out the above four flags */
76 static const ib_uint32_t TRX_FORCE_ROLLBACK_MASK = 0x1FFFFFFF;
77 
78 /** Transaction execution states when trx->state == TRX_STATE_ACTIVE */
79 enum trx_que_t {
80 	TRX_QUE_RUNNING,		/*!< transaction is running */
81 	TRX_QUE_LOCK_WAIT,		/*!< transaction is waiting for
82 					a lock */
83 	TRX_QUE_ROLLING_BACK,		/*!< transaction is rolling back */
84 	TRX_QUE_COMMITTING		/*!< transaction is committing */
85 };
86 
87 /** Transaction states (trx_t::state) */
88 enum trx_state_t {
89 
90 	TRX_STATE_NOT_STARTED,
91 
92 	/** Same as not started but with additional semantics that it
93 	was rolled back asynchronously the last time it was active. */
94 	TRX_STATE_FORCED_ROLLBACK,
95 
96 	TRX_STATE_ACTIVE,
97 
98 	/** Support for 2PC/XA */
99 	TRX_STATE_PREPARED,
100 
101 	TRX_STATE_COMMITTED_IN_MEMORY
102 };
103 
104 /** Type of data dictionary operation */
105 enum trx_dict_op_t {
106 	/** The transaction is not modifying the data dictionary. */
107 	TRX_DICT_OP_NONE = 0,
108 	/** The transaction is creating a table or an index, or
109 	dropping a table.  The table must be dropped in crash
110 	recovery.  This and TRX_DICT_OP_NONE are the only possible
111 	operation modes in crash recovery. */
112 	TRX_DICT_OP_TABLE = 1,
113 	/** The transaction is creating or dropping an index in an
114 	existing table.  In crash recovery, the data dictionary
115 	must be locked, but the table must not be dropped. */
116 	TRX_DICT_OP_INDEX = 2
117 };
118 
119 /** Memory objects */
120 /* @{ */
121 /** Transaction */
122 struct trx_t;
123 /** The locks and state of an active transaction */
124 struct trx_lock_t;
125 /** Transaction system */
126 struct trx_sys_t;
127 /** Signal */
128 struct trx_sig_t;
129 /** Rollback segment */
130 struct trx_rseg_t;
131 /** Transaction undo log */
132 struct trx_undo_t;
133 /** The control structure used in the purge operation */
134 struct trx_purge_t;
135 /** Rollback command node in a query graph */
136 struct roll_node_t;
137 /** Commit command node in a query graph */
138 struct commit_node_t;
139 /** SAVEPOINT command node in a query graph */
140 struct trx_named_savept_t;
141 /* @} */
142 
143 /** Row identifier (DB_ROW_ID, DATA_ROW_ID) */
144 typedef ib_id_t	row_id_t;
145 /** Transaction identifier (DB_TRX_ID, DATA_TRX_ID) */
146 typedef ib_id_t	trx_id_t;
147 /** Rollback pointer (DB_ROLL_PTR, DATA_ROLL_PTR) */
148 typedef ib_id_t	roll_ptr_t;
149 /** Undo number */
150 typedef ib_id_t	undo_no_t;
151 
152 /** Maximum transaction identifier */
153 #define TRX_ID_MAX	IB_ID_MAX
154 
155 /** Transaction savepoint */
156 struct trx_savept_t{
157 	undo_no_t	least_undo_no;	/*!< least undo number to undo */
158 };
159 
160 /** File objects */
161 /* @{ */
162 /** Transaction system header */
163 typedef byte	trx_sysf_t;
164 /** Rollback segment header */
165 typedef byte	trx_rsegf_t;
166 /** Undo segment header */
167 typedef byte	trx_usegf_t;
168 /** Undo log header */
169 typedef byte	trx_ulogf_t;
170 /** Undo log page header */
171 typedef byte	trx_upagef_t;
172 
173 /** Undo log record */
174 typedef	byte	trx_undo_rec_t;
175 
176 /* @} */
177 
178 typedef ib_mutex_t RsegMutex;
179 typedef ib_mutex_t TrxMutex;
180 typedef ib_mutex_t UndoMutex;
181 typedef ib_mutex_t PQMutex;
182 typedef ib_mutex_t TrxSysMutex;
183 
184 /** Rollback segements from a given transaction with trx-no
185 scheduled for purge. */
186 class TrxUndoRsegs {
187 private:
188 	typedef std::vector<trx_rseg_t*, ut_allocator<trx_rseg_t*> >
189 		trx_rsegs_t;
190 public:
191 	typedef trx_rsegs_t::iterator iterator;
192 
193 	/** Default constructor */
TrxUndoRsegs()194 	TrxUndoRsegs() : m_trx_no() { }
195 
TrxUndoRsegs(trx_id_t trx_no)196 	explicit TrxUndoRsegs(trx_id_t trx_no)
197 		:
198 		m_trx_no(trx_no)
199 	{
200 		// Do nothing
201 	}
202 
203 	/** Get transaction number
204 	@return trx_id_t - get transaction number. */
get_trx_no()205 	trx_id_t get_trx_no() const
206 	{
207 		return(m_trx_no);
208 	}
209 
210 	/** Add rollback segment.
211 	@param rseg rollback segment to add. */
push_back(trx_rseg_t * rseg)212 	void push_back(trx_rseg_t* rseg)
213 	{
214 		m_rsegs.push_back(rseg);
215 	}
216 
217 	/** Erase the element pointed by given iterator.
218 	@param[in]	iterator	iterator */
erase(iterator & it)219 	void erase(iterator& it)
220 	{
221 		m_rsegs.erase(it);
222 	}
223 
224 	/** Number of registered rsegs.
225 	@return size of rseg list. */
size()226 	ulint size() const
227 	{
228 		return(m_rsegs.size());
229 	}
230 
231 	/**
232 	@return an iterator to the first element */
begin()233 	iterator begin()
234 	{
235 		return(m_rsegs.begin());
236 	}
237 
238 	/**
239 	@return an iterator to the end */
end()240 	iterator end()
241 	{
242 		return(m_rsegs.end());
243 	}
244 
245 	/** Append rollback segments from referred instance to current
246 	instance. */
append(const TrxUndoRsegs & append_from)247 	void append(const TrxUndoRsegs& append_from)
248 	{
249 		ut_ad(get_trx_no() == append_from.get_trx_no());
250 
251 		m_rsegs.insert(m_rsegs.end(),
252 			       append_from.m_rsegs.begin(),
253 			       append_from.m_rsegs.end());
254 	}
255 
256 	/** Compare two TrxUndoRsegs based on trx_no.
257 	@param elem1 first element to compare
258 	@param elem2 second element to compare
259 	@return true if elem1 > elem2 else false.*/
operator()260 	bool operator()(const TrxUndoRsegs& lhs, const TrxUndoRsegs& rhs)
261 	{
262 		return(lhs.m_trx_no > rhs.m_trx_no);
263 	}
264 
265 	/** Compiler defined copy-constructor/assignment operator
266 	should be fine given that there is no reference to a memory
267 	object outside scope of class object.*/
268 
269 private:
270 	/** The rollback segments transaction number. */
271 	trx_id_t		m_trx_no;
272 
273 	/** Rollback segments of a transaction, scheduled for purge. */
274 	trx_rsegs_t		m_rsegs;
275 };
276 
277 typedef std::priority_queue<
278 	TrxUndoRsegs,
279 	std::vector<TrxUndoRsegs, ut_allocator<TrxUndoRsegs> >,
280 	TrxUndoRsegs>	purge_pq_t;
281 
282 typedef std::vector<trx_id_t, ut_allocator<trx_id_t> >	trx_ids_t;
283 
284 /** Mapping read-write transactions from id to transaction instance, for
285 creating read views and during trx id lookup for MVCC and locking. */
286 struct TrxTrack {
287 	explicit TrxTrack(trx_id_t id, trx_t* trx = NULL)
288 		:
m_idTrxTrack289 		m_id(id),
290 		m_trx(trx)
291 	{
292 		// Do nothing
293 	}
294 
295 	trx_id_t	m_id;
296 	trx_t*		m_trx;
297 };
298 
299 struct TrxTrackHash {
operatorTrxTrackHash300 	size_t operator()(const TrxTrack& key) const
301 	{
302 		return(size_t(key.m_id));
303 	}
304 };
305 
306 /**
307 Comparator for TrxMap */
308 struct TrxTrackHashCmp {
309 
operatorTrxTrackHashCmp310 	bool operator() (const TrxTrack& lhs, const TrxTrack& rhs) const
311 	{
312 		return(lhs.m_id == rhs.m_id);
313 	}
314 };
315 
316 /**
317 Comparator for TrxMap */
318 struct TrxTrackCmp {
319 
operatorTrxTrackCmp320 	bool operator() (const TrxTrack& lhs, const TrxTrack& rhs) const
321 	{
322 		return(lhs.m_id < rhs.m_id);
323 	}
324 };
325 
326 //typedef std::unordered_set<TrxTrack, TrxTrackHash, TrxTrackHashCmp> TrxIdSet;
327 typedef std::set<TrxTrack, TrxTrackCmp, ut_allocator<TrxTrack> >
328 	TrxIdSet;
329 
330 #endif /* trx0types_h */
331