1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License, version 2.0, as published by the
7 Free Software Foundation.
8 
9 This program is also distributed with certain software (including but not
10 limited to OpenSSL) that is licensed under separate terms, as designated in a
11 particular file or component or in included license documentation. The authors
12 of MySQL hereby grant you an additional permission to link the program and
13 your derivative works with the separately licensed software that they have
14 included with MySQL.
15 
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19 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 St, Fifth Floor, Boston, MA 02110-1301  USA
24 
25 *****************************************************************************/
26 
27 /** @file include/trx0rseg.h
28  Rollback segment
29 
30  Created 3/26/1996 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef trx0rseg_h
34 #define trx0rseg_h
35 
36 #include <vector>
37 #include "fut0lst.h"
38 #include "trx0sys.h"
39 #include "trx0types.h"
40 #include "univ.i"
41 
42 /** Gets a rollback segment header.
43 @param[in]	space		space where placed
44 @param[in]	page_no		page number of the header
45 @param[in]	page_size	page size
46 @param[in,out]	mtr		mini-transaction
47 @return rollback segment header, page x-latched */
48 UNIV_INLINE
49 trx_rsegf_t *trx_rsegf_get(space_id_t space, page_no_t page_no,
50                            const page_size_t &page_size, mtr_t *mtr);
51 
52 /** Gets a newly created rollback segment header.
53 @param[in]	space		space where placed
54 @param[in]	page_no		page number of the header
55 @param[in]	page_size	page size
56 @param[in,out]	mtr		mini-transaction
57 @return rollback segment header, page x-latched */
58 UNIV_INLINE
59 trx_rsegf_t *trx_rsegf_get_new(space_id_t space, page_no_t page_no,
60                                const page_size_t &page_size, mtr_t *mtr);
61 
62 /** Gets the file page number of the nth undo log slot.
63 @param[in]	rsegf	rollback segment header
64 @param[in]	n	index of slot
65 @param[in]	mtr	mtr
66 @return page number of the undo log segment */
67 UNIV_INLINE
68 page_no_t trx_rsegf_get_nth_undo(trx_rsegf_t *rsegf, ulint n, mtr_t *mtr);
69 
70 /** Sets the file page number of the nth undo log slot.
71 @param[in]	rsegf	rollback segment header
72 @param[in]	n	index of slot
73 @param[in]	page_no	page number of the undo log segment
74 @param[in]	mtr	mtr */
75 UNIV_INLINE
76 void trx_rsegf_set_nth_undo(trx_rsegf_t *rsegf, ulint n, page_no_t page_no,
77                             mtr_t *mtr);
78 
79 /** Looks for a free slot for an undo log segment.
80 @param[in]	rsegf	rollback segment header
81 @param[in]	mtr	mtr
82 @return slot index or ULINT_UNDEFINED if not found */
83 UNIV_INLINE
84 ulint trx_rsegf_undo_find_free(trx_rsegf_t *rsegf, mtr_t *mtr);
85 
86 /** Creates a rollback segment header.
87 This function is called only when a new rollback segment is created in
88 the database.
89 @param[in]	space_id		space id
90 @param[in]	page_size	page size
91 @param[in]	max_size	max size in pages
92 @param[in]	rseg_slot	rseg id == slot number in trx sys
93 @param[in,out]	mtr		mini-transaction
94 @return page number of the created segment, FIL_NULL if fail */
95 page_no_t trx_rseg_header_create(space_id_t space_id,
96                                  const page_size_t &page_size,
97                                  page_no_t max_size, ulint rseg_slot,
98                                  mtr_t *mtr);
99 
100 /** Add more rsegs to the rseg list in each tablespace until there are
101 srv_rollback_segments of them.  Use any rollback segment that already
102 exists so that the purge_queue can be filled and processed with any
103 existing undo log. If the rollback segments do not exist in this
104 tablespace and we need them according to target_rollback_segments,
105 then build them in the tablespace.
106 @param[in]	target_rollback_segments	new number of rollback
107                                                 segments per space
108 @return true if all necessary rollback segments and trx_rseg_t objects
109 were created. */
110 bool trx_rseg_adjust_rollback_segments(ulong target_rollback_segments);
111 
112 /** Create the requested number of Rollback Segments in a newly created undo
113 tablespace and add them to the Rsegs object.
114 @param[in]  space_id                  undo tablespace ID
115 @param[in]  target_rollback_segments  number of rollback segments per space
116 @return true if all necessary rollback segments and trx_rseg_t objects
117 were created. */
118 bool trx_rseg_init_rollback_segments(space_id_t space_id,
119                                      ulong target_rollback_segments);
120 
121 /** Create the memory copies for rollback segments and initialize the
122 rseg array in trx_sys at a database startup.
123 @param[in]	purge_queue	queue of rsegs to purge */
124 void trx_rsegs_init(purge_pq_t *purge_queue);
125 
126 /** Create and initialize a rollback segment object.  Some of
127 the values for the fields are read from the segment header page.
128 The caller must insert it into the correct list.
129 @param[in]	id		rollback segment id
130 @param[in]	space_id	space where the segment is placed
131 @param[in]	page_no		page number of the segment header
132 @param[in]	page_size	page size
133 @param[in]      gtid_trx_no     trx number up to which GTID is persisted
134 @param[in,out]	purge_queue	rseg queue
135 @param[in,out]	mtr		mini-transaction
136 @return own: rollback segment object */
137 trx_rseg_t *trx_rseg_mem_create(ulint id, space_id_t space_id,
138                                 page_no_t page_no, const page_size_t &page_size,
139                                 trx_id_t gtid_trx_no, purge_pq_t *purge_queue,
140                                 mtr_t *mtr);
141 
142 /** Create a rollback segment in the given tablespace. This could be either
143 the system tablespace, the temporary tablespace, or an undo tablespace.
144 @param[in]	space_id	tablespace to get the rollback segment
145 @param[in]	rseg_id		slot number of the rseg within this tablespace
146 @return page number of the rollback segment header page created */
147 page_no_t trx_rseg_create(space_id_t space_id, ulint rseg_id);
148 
149 /** Build a list of unique undo tablespaces found in the TRX_SYS page.
150 Do not count the system tablespace. The vector will be sorted on space id.
151 @param[in,out]	spaces_to_open		list of undo tablespaces found. */
152 void trx_rseg_get_n_undo_tablespaces(Space_Ids *spaces_to_open);
153 
154 /** Upgrade the TRX_SYS page so that it no longer tracks rsegs in undo
155 tablespaces other than the system tablespace.  Add these tablespaces to
156 undo::spaces and put FIL_NULL in the slots in TRX_SYS.*/
157 void trx_rseg_upgrade_undo_tablespaces();
158 
159 /** Create the file page for the rollback segment directory in an undo
160 tablespace. This function is called just after an undo tablespace is
161 created so the next page created here should by FSP_FSEG_DIR_PAGE_NUM.
162 @param[in]	space_id	Undo Tablespace ID
163 @param[in]	mtr		mtr */
164 void trx_rseg_array_create(space_id_t space_id, mtr_t *mtr);
165 
166 /** Sets the page number of the nth rollback segment slot in the
167 independent undo tablespace.
168 @param[in]	rsegs_header	rollback segment array page header
169 @param[in]	slot		slot number on page  == rseg id
170 @param[in]	page_no		rollback regment header page number
171 @param[in]	mtr		mtr */
172 UNIV_INLINE
173 void trx_rsegsf_set_page_no(trx_rsegsf_t *rsegs_header, ulint slot,
174                             page_no_t page_no, mtr_t *mtr);
175 
176 /* Number of undo log slots in a rollback segment file copy */
177 #define TRX_RSEG_N_SLOTS (UNIV_PAGE_SIZE / 16)
178 
179 /* Maximum number of transactions supported by a single rollback segment */
180 #define TRX_RSEG_MAX_N_TRXS (TRX_RSEG_N_SLOTS / 2)
181 
182 /* Undo log segment slot in a rollback segment header */
183 /*-------------------------------------------------------------*/
184 #define TRX_RSEG_SLOT_PAGE_NO            \
185   0 /* Page number of the header page of \
186     an undo log segment */
187 /*-------------------------------------------------------------*/
188 /* Slot size */
189 #define TRX_RSEG_SLOT_SIZE 4
190 
191 /* The offset of the rollback segment header on its page */
192 #define TRX_RSEG FSEG_PAGE_DATA
193 
194 /* Transaction rollback segment header */
195 /*-------------------------------------------------------------*/
196 #define TRX_RSEG_MAX_SIZE                \
197   0 /* Maximum allowed size for rollback \
198     segment in pages */
199 #define TRX_RSEG_HISTORY_SIZE        \
200   4 /* Number of file pages occupied \
201     by the logs in the history list */
202 #define TRX_RSEG_HISTORY                  \
203   8 /* The update undo logs for committed \
204     transactions */
205 /* Header for the file segment where
206 this page is placed */
207 #define TRX_RSEG_FSEG_HEADER (8 + FLST_BASE_NODE_SIZE)
208 /* Undo log segment slots */
209 #define TRX_RSEG_UNDO_SLOTS (8 + FLST_BASE_NODE_SIZE + FSEG_HEADER_SIZE)
210 
211 /* End of undo slots in rollback segment page. */
212 #define TRX_RSEG_SLOT_END \
213   (TRX_RSEG_UNDO_SLOTS + (TRX_RSEG_SLOT_SIZE * TRX_RSEG_N_SLOTS))
214 
215 /* Maximum transaction number ever added to this rollback segment history
216 list. It is always increasing number over lifetime starting from zero.
217 The size is 8 bytes. */
218 #define TRX_RSEG_MAX_TRX_NO TRX_RSEG_SLOT_END
219 
220 /*-------------------------------------------------------------*/
221 
222 /** The offset of the Rollback Segment Directory header on an RSEG_ARRAY page */
223 #define RSEG_ARRAY_HEADER FSEG_PAGE_DATA
224 
225 /** Rollback Segment Array Header */
226 /*------------------------------------------------------------- */
227 /** The RSEG ARRAY base version is a number derived from the string
228 'RSEG' [0x 52 53 45 47] for extra validation. Each new version
229 increments the base version by 1. */
230 #define RSEG_ARRAY_VERSION 0x52534547 + 1
231 
232 /** The RSEG ARRAY version offset in the header. */
233 #define RSEG_ARRAY_VERSION_OFFSET 0
234 
235 /** The current number of rollback segments being tracked in this array */
236 #define RSEG_ARRAY_SIZE_OFFSET 4
237 
238 /** This is the pointer to the file segment inode that tracks this
239 rseg array page. */
240 #define RSEG_ARRAY_FSEG_HEADER_OFFSET 8
241 
242 /** The start of the array of rollback segment header page numbers for this
243 undo tablespace. The potential size of this array is limited only by the
244 page size minus overhead. The actual size of the array is limited by
245 srv_rollback_segments. */
246 #define RSEG_ARRAY_PAGES_OFFSET (8 + FSEG_HEADER_SIZE)
247 
248 /** Reserved space at the end of an RSEG_ARRAY page reserved for future use. */
249 #define RSEG_ARRAY_RESERVED_BYTES 200
250 
251 /* Slot size of the array of rollback segment header page numbers */
252 #define RSEG_ARRAY_SLOT_SIZE 4
253 /*------------------------------------------------------------- */
254 
255 #include "trx0rseg.ic"
256 
257 #endif
258