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/trx0rec.h
29 Transaction undo log record
30 
31 Created 3/26/1996 Heikki Tuuri
32 *******************************************************/
33 
34 #ifndef trx0rec_h
35 #define trx0rec_h
36 
37 #include "univ.i"
38 #include "trx0types.h"
39 #include "row0types.h"
40 #include "mtr0mtr.h"
41 #include "dict0types.h"
42 #include "data0data.h"
43 #include "rem0types.h"
44 #include "page0types.h"
45 #include "row0log.h"
46 
47 #ifndef UNIV_HOTBACKUP
48 # include "que0types.h"
49 
50 /** Copies the undo record to the heap.
51 @param[in]	undo_page	Undo Page
52 @param[in]	undo_offset     Offset of the undo record in the page
53 @param[in]	heap		Heap where undo record is copied
54 @return copy of undo log record */
55 UNIV_INLINE
56 trx_undo_rec_t*
57 trx_undo_rec_copy(
58 	const page_t*		undo_page,
59 	ulint			undo_offset,
60 	mem_heap_t*		heap);
61 
62 /**********************************************************************//**
63 Reads the undo log record type.
64 @return record type */
65 UNIV_INLINE
66 ulint
67 trx_undo_rec_get_type(
68 /*==================*/
69 	const trx_undo_rec_t*	undo_rec);	/*!< in: undo log record */
70 /**********************************************************************//**
71 Reads from an undo log record the record compiler info.
72 @return compiler info */
73 UNIV_INLINE
74 ulint
75 trx_undo_rec_get_cmpl_info(
76 /*=======================*/
77 	const trx_undo_rec_t*	undo_rec);	/*!< in: undo log record */
78 /**********************************************************************//**
79 Returns TRUE if an undo log record contains an extern storage field.
80 @return TRUE if extern */
81 UNIV_INLINE
82 ibool
83 trx_undo_rec_get_extern_storage(
84 /*============================*/
85 	const trx_undo_rec_t*	undo_rec);	/*!< in: undo log record */
86 /**********************************************************************//**
87 Reads the undo log record number.
88 @return undo no */
89 UNIV_INLINE
90 undo_no_t
91 trx_undo_rec_get_undo_no(
92 /*=====================*/
93 	const trx_undo_rec_t*	undo_rec);	/*!< in: undo log record */
94 
95 /**********************************************************************//**
96 Returns the start of the undo record data area. */
97 #define trx_undo_rec_get_ptr(undo_rec, undo_no)		\
98 	((undo_rec) + trx_undo_rec_get_offset(undo_no))
99 
100 /**********************************************************************//**
101 Reads from an undo log record the general parameters.
102 @return remaining part of undo log record after reading these values */
103 byte*
104 trx_undo_rec_get_pars(
105 /*==================*/
106 	trx_undo_rec_t*	undo_rec,	/*!< in: undo log record */
107 	ulint*		type,		/*!< out: undo record type:
108 					TRX_UNDO_INSERT_REC, ... */
109 	ulint*		cmpl_info,	/*!< out: compiler info, relevant only
110 					for update type records */
111 	bool*		updated_extern,	/*!< out: true if we updated an
112 					externally stored fild */
113 	undo_no_t*	undo_no,	/*!< out: undo log record number */
114 	table_id_t*	table_id);	/*!< out: table id */
115 
116 /** Reads from an undo log record the table ID
117 @param[in]	undo_rec	Undo log record
118 @return the table ID */
119 table_id_t
120 trx_undo_rec_get_table_id(const trx_undo_rec_t* undo_rec)
121 	MY_ATTRIBUTE((warn_unused_result));
122 
123 /*******************************************************************//**
124 Builds a row reference from an undo log record.
125 @return pointer to remaining part of undo record */
126 byte*
127 trx_undo_rec_get_row_ref(
128 /*=====================*/
129 	byte*		ptr,	/*!< in: remaining part of a copy of an undo log
130 				record, at the start of the row reference;
131 				NOTE that this copy of the undo log record must
132 				be preserved as long as the row reference is
133 				used, as we do NOT copy the data in the
134 				record! */
135 	dict_index_t*	index,	/*!< in: clustered index */
136 	dtuple_t**	ref,	/*!< out, own: row reference */
137 	mem_heap_t*	heap);	/*!< in: memory heap from which the memory
138 				needed is allocated */
139 /*******************************************************************//**
140 Skips a row reference from an undo log record.
141 @return pointer to remaining part of undo record */
142 byte*
143 trx_undo_rec_skip_row_ref(
144 /*======================*/
145 	byte*		ptr,	/*!< in: remaining part in update undo log
146 				record, at the start of the row reference */
147 	dict_index_t*	index);	/*!< in: clustered index */
148 /**********************************************************************//**
149 Reads from an undo log update record the system field values of the old
150 version.
151 @return remaining part of undo log record after reading these values */
152 byte*
153 trx_undo_update_rec_get_sys_cols(
154 /*=============================*/
155 	const byte*	ptr,		/*!< in: remaining part of undo
156 					log record after reading
157 					general parameters */
158 	trx_id_t*	trx_id,		/*!< out: trx id */
159 	roll_ptr_t*	roll_ptr,	/*!< out: roll ptr */
160 	ulint*		info_bits);	/*!< out: info bits state */
161 /*******************************************************************//**
162 Builds an update vector based on a remaining part of an undo log record.
163 @return remaining part of the record, NULL if an error detected, which
164 means that the record is corrupted */
165 byte*
166 trx_undo_update_rec_get_update(
167 /*===========================*/
168 	const byte*	ptr,	/*!< in: remaining part in update undo log
169 				record, after reading the row reference
170 				NOTE that this copy of the undo log record must
171 				be preserved as long as the update vector is
172 				used, as we do NOT copy the data in the
173 				record! */
174 	dict_index_t*	index,	/*!< in: clustered index */
175 	ulint		type,	/*!< in: TRX_UNDO_UPD_EXIST_REC,
176 				TRX_UNDO_UPD_DEL_REC, or
177 				TRX_UNDO_DEL_MARK_REC; in the last case,
178 				only trx id and roll ptr fields are added to
179 				the update vector */
180 	trx_id_t	trx_id,	/*!< in: transaction id from this undorecord */
181 	roll_ptr_t	roll_ptr,/*!< in: roll pointer from this undo record */
182 	ulint		info_bits,/*!< in: info bits from this undo record */
183 	trx_t*		trx,	/*!< in: transaction */
184 	mem_heap_t*	heap,	/*!< in: memory heap from which the memory
185 				needed is allocated */
186 	upd_t**		upd);	/*!< out, own: update vector */
187 /*******************************************************************//**
188 Builds a partial row from an update undo log record, for purge.
189 It contains the columns which occur as ordering in any index of the table.
190 Any missing columns are indicated by col->mtype == DATA_MISSING.
191 @return pointer to remaining part of undo record */
192 byte*
193 trx_undo_rec_get_partial_row(
194 /*=========================*/
195 	const byte*	ptr,	/*!< in: remaining part in update undo log
196 				record of a suitable type, at the start of
197 				the stored index columns;
198 				NOTE that this copy of the undo log record must
199 				be preserved as long as the partial row is
200 				used, as we do NOT copy the data in the
201 				record! */
202 	dict_index_t*	index,	/*!< in: clustered index */
203 	dtuple_t**	row,	/*!< out, own: partial row */
204 	ibool		ignore_prefix, /*!< in: flag to indicate if we
205 				expect blob prefixes in undo. Used
206 				only in the assertion. */
207 	mem_heap_t*	heap)	/*!< in: memory heap from which the memory
208 				needed is allocated */
209 	MY_ATTRIBUTE((warn_unused_result));
210 /***********************************************************************//**
211 Writes information to an undo log about an insert, update, or a delete marking
212 of a clustered index record. This information is used in a rollback of the
213 transaction and in consistent reads that must look to the history of this
214 transaction.
215 @return DB_SUCCESS or error code */
216 dberr_t
217 trx_undo_report_row_operation(
218 /*==========================*/
219 	ulint		flags,		/*!< in: if BTR_NO_UNDO_LOG_FLAG bit is
220 					set, does nothing */
221 	ulint		op_type,	/*!< in: TRX_UNDO_INSERT_OP or
222 					TRX_UNDO_MODIFY_OP */
223 	que_thr_t*	thr,		/*!< in: query thread */
224 	dict_index_t*	index,		/*!< in: clustered index */
225 	const dtuple_t*	clust_entry,	/*!< in: in the case of an insert,
226 					index entry to insert into the
227 					clustered index, otherwise NULL */
228 	const upd_t*	update,		/*!< in: in the case of an update,
229 					the update vector, otherwise NULL */
230 	ulint		cmpl_info,	/*!< in: compiler info on secondary
231 					index updates */
232 	const rec_t*	rec,		/*!< in: case of an update or delete
233 					marking, the record in the clustered
234 					index, otherwise NULL */
235 	const ulint*	offsets,	/*!< in: rec_get_offsets(rec) */
236 	roll_ptr_t*	roll_ptr)	/*!< out: rollback pointer to the
237 					inserted undo log record,
238 					0 if BTR_NO_UNDO_LOG
239 					flag was specified */
240 	MY_ATTRIBUTE((nonnull(4,10), warn_unused_result));
241 /******************************************************************//**
242 Copies an undo record to heap. This function can be called if we know that
243 the undo log record exists.
244 @return own: copy of the record */
245 trx_undo_rec_t*
246 trx_undo_get_undo_rec_low(
247 /*======================*/
248 	roll_ptr_t	roll_ptr,	/*!< in: roll pointer to record */
249 	mem_heap_t*	heap,		/*!< in: memory heap where copied */
250 	bool		is_redo_rseg)	/*!< in: true if redo rseg. */
251 	MY_ATTRIBUTE((warn_unused_result));
252 
253 /** status bit used for trx_undo_prev_version_build() */
254 
255 /** TRX_UNDO_PREV_IN_PURGE tells trx_undo_prev_version_build() that it
256 is being called purge view and we would like to get the purge record
257 even it is in the purge view (in normal case, it will return without
258 fetching the purge record */
259 #define		TRX_UNDO_PREV_IN_PURGE		0x1
260 
261 /** This tells trx_undo_prev_version_build() to fetch the old value in
262 the undo log (which is the after image for an update) */
263 #define		TRX_UNDO_GET_OLD_V_VALUE	0x2
264 
265 /*******************************************************************//**
266 Build a previous version of a clustered index record. The caller must
267 hold a latch on the index page of the clustered index record.
268 @retval true if previous version was built, or if it was an insert
269 or the table has been rebuilt
270 @retval false if the previous version is earlier than purge_view,
271 which means that it may have been removed */
272 bool
273 trx_undo_prev_version_build(
274 /*========================*/
275 	const rec_t*	index_rec,/*!< in: clustered index record in the
276 				index tree */
277 	mtr_t*		index_mtr,/*!< in: mtr which contains the latch to
278 				index_rec page and purge_view */
279 	const rec_t*	rec,	/*!< in: version of a clustered index record */
280 	dict_index_t*	index,	/*!< in: clustered index */
281 	ulint*		offsets,/*!< in/out: rec_get_offsets(rec, index) */
282 	mem_heap_t*	heap,	/*!< in: memory heap from which the memory
283 				needed is allocated */
284 	rec_t**		old_vers,/*!< out, own: previous version, or NULL if
285 				rec is the first inserted version, or if
286 				history data has been deleted */
287 	mem_heap_t*	v_heap,	/* !< in: memory heap used to create vrow
288 				dtuple if it is not yet created. This heap
289 				diffs from "heap" above in that it could be
290 				prebuilt->old_vers_heap for selection */
291 	const dtuple_t**vrow,	/*!< out: virtual column info, if any */
292 	ulint		v_status);
293 				/*!< in: status determine if it is going
294 				into this function by purge thread or not.
295 				And if we read "after image" of undo log */
296 
297 #endif /* !UNIV_HOTBACKUP */
298 /***********************************************************//**
299 Parses a redo log record of adding an undo log record.
300 @return end of log record or NULL */
301 byte*
302 trx_undo_parse_add_undo_rec(
303 /*========================*/
304 	byte*	ptr,	/*!< in: buffer */
305 	byte*	end_ptr,/*!< in: buffer end */
306 	page_t*	page);	/*!< in: page or NULL */
307 /***********************************************************//**
308 Parses a redo log record of erasing of an undo page end.
309 @return end of log record or NULL */
310 byte*
311 trx_undo_parse_erase_page_end(
312 /*==========================*/
313 	byte*	ptr,	/*!< in: buffer */
314 	byte*	end_ptr,/*!< in: buffer end */
315 	page_t*	page,	/*!< in: page or NULL */
316 	mtr_t*	mtr);	/*!< in: mtr or NULL */
317 
318 /** Read from an undo log record a non-virtual column value.
319 @param[in,out]	ptr		pointer to remaining part of the undo record
320 @param[in,out]	field		stored field
321 @param[in,out]	len		length of the field, or UNIV_SQL_NULL
322 @param[in,out]	orig_len	original length of the locally stored part
323 of an externally stored column, or 0
324 @return remaining part of undo log record after reading these values */
325 byte*
326 trx_undo_rec_get_col_val(
327         const byte*     ptr,
328         const byte**    field,
329         ulint*          len,
330         ulint*          orig_len);
331 
332 /** Read virtual column value from undo log
333 @param[in]	table		the table
334 @param[in]	ptr		undo log pointer
335 @param[in,out]	row		the dtuple to fill
336 @param[in]	in_purge        called by purge thread
337 @param[in]	col_map		online rebuild column map */
338 void
339 trx_undo_read_v_cols(
340 	const dict_table_t*	table,
341 	const byte*		ptr,
342 	const dtuple_t*		row,
343 	bool			in_purge,
344 	const ulint*		col_map);
345 
346 /** Read virtual column index from undo log if the undo log contains such
347 info, and verify the column is still indexed, and output its position
348 @param[in]	table		the table
349 @param[in]	ptr		undo log pointer
350 @param[in]	first_v_col	if this is the first virtual column, which
351 				has the version marker
352 @param[in,out]	is_undo_log	his function is used to parse both undo log,
353 				and online log for virtual columns. So
354 				check to see if this is undo log
355 @param[out]	field_no	the column number
356 @return remaining part of undo log record after reading these values */
357 const byte*
358 trx_undo_read_v_idx(
359 	const dict_table_t*	table,
360 	const byte*		ptr,
361 	bool			first_v_col,
362 	bool*			is_undo_log,
363 	ulint*			field_no);
364 
365 #ifndef UNIV_HOTBACKUP
366 
367 /* Types of an undo log record: these have to be smaller than 16, as the
368 compilation info multiplied by 16 is ORed to this value in an undo log
369 record */
370 
371 #define	TRX_UNDO_INSERT_REC	11	/* fresh insert into clustered index */
372 #define	TRX_UNDO_UPD_EXIST_REC	12	/* update of a non-delete-marked
373 					record */
374 #define	TRX_UNDO_UPD_DEL_REC	13	/* update of a delete marked record to
375 					a not delete marked record; also the
376 					fields of the record can change */
377 #define	TRX_UNDO_DEL_MARK_REC	14	/* delete marking of a record; fields
378 					do not change */
379 #define	TRX_UNDO_CMPL_INFO_MULT	16	/* compilation info is multiplied by
380 					this and ORed to the type above */
381 #define	TRX_UNDO_UPD_EXTERN	128	/* This bit can be ORed to type_cmpl
382 					to denote that we updated external
383 					storage fields: used by purge to
384 					free the external storage */
385 
386 /* Operation type flags used in trx_undo_report_row_operation */
387 #define	TRX_UNDO_INSERT_OP		1
388 #define	TRX_UNDO_MODIFY_OP		2
389 
390 #ifndef UNIV_NONINL
391 #include "trx0rec.ic"
392 #endif
393 
394 #endif /* !UNIV_HOTBACKUP */
395 
396 #endif /* trx0rec_h */
397