1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2020, 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/trx0undo.h
28  Transaction undo log
29 
30  Created 3/26/1996 Heikki Tuuri
31  *******************************************************/
32 
33 #ifndef trx0undo_h
34 #define trx0undo_h
35 
36 #include "mtr0mtr.h"
37 #include "page0types.h"
38 #include "sql/xa.h"
39 #include "trx0sys.h"
40 #include "trx0types.h"
41 #include "trx0xa.h"
42 #include "univ.i"
43 
44 #ifndef UNIV_HOTBACKUP
45 /** Returns TRUE if the roll pointer is of the insert type.
46  @return true if insert undo log */
47 UNIV_INLINE
48 ibool trx_undo_roll_ptr_is_insert(roll_ptr_t roll_ptr); /*!< in: roll pointer */
49 /** Returns true if the record is of the insert type.
50  @return true if the record was freshly inserted (not updated). */
51 UNIV_INLINE
52 bool trx_undo_trx_id_is_insert(
53     const byte *trx_id) /*!< in: DB_TRX_ID, followed by DB_ROLL_PTR */
54     MY_ATTRIBUTE((warn_unused_result));
55 #endif /* !UNIV_HOTBACKUP */
56 
57 /** Writes a roll ptr to an index page. In case that the size changes in
58 some future version, this function should be used instead of
59 mach_write_...
60 @param[in]	ptr		pointer to memory where written
61 @param[in]	roll_ptr	roll ptr */
62 UNIV_INLINE
63 void trx_write_roll_ptr(byte *ptr, roll_ptr_t roll_ptr);
64 
65 /** Reads a roll ptr from an index page. In case that the roll ptr size
66  changes in some future version, this function should be used instead of
67  mach_read_...
68  @return roll ptr */
69 UNIV_INLINE
70 roll_ptr_t trx_read_roll_ptr(
71     const byte *ptr); /*!< in: pointer to memory from where to read */
72 #ifndef UNIV_HOTBACKUP
73 
74 /** Gets an undo log page and x-latches it.
75 @param[in]	page_id		page id
76 @param[in]	page_size	page size
77 @param[in,out]	mtr		mini-transaction
78 @return pointer to page x-latched */
79 UNIV_INLINE
80 page_t *trx_undo_page_get(const page_id_t &page_id,
81                           const page_size_t &page_size, mtr_t *mtr);
82 
83 /** Gets an undo log page and s-latches it.
84 @param[in]	page_id		page id
85 @param[in]	page_size	page size
86 @param[in,out]	mtr		mini-transaction
87 @return pointer to page s-latched */
88 UNIV_INLINE
89 page_t *trx_undo_page_get_s_latched(const page_id_t &page_id,
90                                     const page_size_t &page_size, mtr_t *mtr);
91 
92 /** Returns the previous undo record on the page in the specified log, or
93 NULL if none exists.
94 @param[in]	rec		undo log record
95 @param[in]	page_no		undo log header page number
96 @param[in]	offset		undo log header offset on page
97 @return pointer to record, NULL if none */
98 UNIV_INLINE
99 trx_undo_rec_t *trx_undo_page_get_prev_rec(trx_undo_rec_t *rec,
100                                            page_no_t page_no, ulint offset);
101 
102 /** Returns the next undo log record on the page in the specified log, or
103 NULL if none exists.
104 @param[in]	rec		undo log record
105 @param[in]	page_no		undo log header page number
106 @param[in]	offset		undo log header offset on page
107 @return pointer to record, NULL if none */
108 UNIV_INLINE
109 trx_undo_rec_t *trx_undo_page_get_next_rec(trx_undo_rec_t *rec,
110                                            page_no_t page_no, ulint offset);
111 
112 /** Returns the last undo record on the page in the specified undo log, or
113 NULL if none exists.
114 @param[in]	undo_page	undo log page
115 @param[in]	page_no		undo log header page number
116 @param[in]	offset		undo log header offset on page
117 @return pointer to record, NULL if none */
118 UNIV_INLINE
119 trx_undo_rec_t *trx_undo_page_get_last_rec(page_t *undo_page, page_no_t page_no,
120                                            ulint offset);
121 
122 /** Returns the first undo record on the page in the specified undo log, or
123 NULL if none exists.
124 @param[in]	undo_page	undo log page
125 @param[in]	page_no		undo log header page number
126 @param[in]	offset		undo log header offset on page
127 @return pointer to record, NULL if none */
128 UNIV_INLINE
129 trx_undo_rec_t *trx_undo_page_get_first_rec(page_t *undo_page,
130                                             page_no_t page_no, ulint offset);
131 
132 /** Gets the previous record in an undo log.
133  @return undo log record, the page s-latched, NULL if none */
134 trx_undo_rec_t *trx_undo_get_prev_rec(
135     trx_undo_rec_t *rec, /*!< in: undo record */
136     page_no_t page_no,   /*!< in: undo log header page number */
137     ulint offset,        /*!< in: undo log header offset on page */
138     bool shared,         /*!< in: true=S-latch, false=X-latch */
139     mtr_t *mtr);         /*!< in: mtr */
140 /** Gets the next record in an undo log.
141  @return undo log record, the page s-latched, NULL if none */
142 trx_undo_rec_t *trx_undo_get_next_rec(
143     trx_undo_rec_t *rec, /*!< in: undo record */
144     page_no_t page_no,   /*!< in: undo log header page number */
145     ulint offset,        /*!< in: undo log header offset on page */
146     mtr_t *mtr);         /*!< in: mtr */
147 
148 /** Gets the first record in an undo log.
149 @param[out]	modifier_trx_id	the modifier trx identifier.
150 @param[in]	space		undo log header space
151 @param[in]	page_size	page size
152 @param[in]	page_no		undo log header page number
153 @param[in]	offset		undo log header offset on page
154 @param[in]	mode		latching mode: RW_S_LATCH or RW_X_LATCH
155 @param[in,out]	mtr		mini-transaction
156 @return undo log record, the page latched, NULL if none */
157 trx_undo_rec_t *trx_undo_get_first_rec(trx_id_t *modifier_trx_id,
158                                        space_id_t space,
159                                        const page_size_t &page_size,
160                                        page_no_t page_no, ulint offset,
161                                        ulint mode, mtr_t *mtr);
162 
163 /** Tries to add a page to the undo log segment where the undo log is placed.
164  @return X-latched block if success, else NULL */
165 buf_block_t *trx_undo_add_page(
166     trx_t *trx,               /*!< in: transaction */
167     trx_undo_t *undo,         /*!< in: undo log memory object */
168     trx_undo_ptr_t *undo_ptr, /*!< in: assign undo log from
169                               referred rollback segment. */
170     mtr_t *mtr)               /*!< in: mtr which does not have
171                               a latch to any undo log page;
172                               the caller must have reserved
173                               the rollback segment mutex */
174     MY_ATTRIBUTE((warn_unused_result));
175 /** Frees the last undo log page.
176  The caller must hold the rollback segment mutex. */
177 void trx_undo_free_last_page_func(
178 #ifdef UNIV_DEBUG
179     const trx_t *trx, /*!< in: transaction */
180 #endif                /* UNIV_DEBUG */
181     trx_undo_t *undo, /*!< in/out: undo log memory copy */
182     mtr_t *mtr);      /*!< in/out: mini-transaction which does not
183                       have a latch to any undo log page or which
184                       has allocated the undo log page */
185 #ifdef UNIV_DEBUG
186 #define trx_undo_free_last_page(trx, undo, mtr) \
187   trx_undo_free_last_page_func(trx, undo, mtr)
188 #else /* UNIV_DEBUG */
189 #define trx_undo_free_last_page(trx, undo, mtr) \
190   trx_undo_free_last_page_func(undo, mtr)
191 #endif /* UNIV_DEBUG */
192 
193 /** Truncates an undo log from the end. This function is used during
194 a rollback to free space from an undo log. */
195 #ifdef UNIV_DEBUG
196 /**
197 @param[in]  trx    transaction for this undo log */
198 #endif /* UNIV_DEBUG */
199 /**
200 @param[in]  undo   undo log
201 @param[in]  limit  all undo records with undo number;
202                    This value should be truncated. */
203 void trx_undo_truncate_end_func(
204 #ifdef UNIV_DEBUG
205     const trx_t *trx,
206 #endif /* UNIV_DEBUG */
207     trx_undo_t *undo, undo_no_t limit);
208 
209 #ifdef UNIV_DEBUG
210 #define trx_undo_truncate_end(trx, undo, limit) \
211   trx_undo_truncate_end_func(trx, undo, limit)
212 #else /* UNIV_DEBUG */
213 #define trx_undo_truncate_end(trx, undo, limit) \
214   trx_undo_truncate_end_func(undo, limit)
215 #endif /* UNIV_DEBUG */
216 
217 /** Truncate the head of an undo log.
218 NOTE that only whole pages are freed; the header page is not
219 freed, but emptied, if all the records there are below the limit.
220 @param[in,out]	rseg		rollback segment
221 @param[in]	hdr_page_no	header page number
222 @param[in]	hdr_offset	header offset on the page
223 @param[in]	limit		first undo number to preserve
224 (everything below the limit will be truncated) */
225 void trx_undo_truncate_start(trx_rseg_t *rseg, page_no_t hdr_page_no,
226                              ulint hdr_offset, undo_no_t limit);
227 /** Initializes the undo log lists for a rollback segment memory copy.
228  This function is only called when the database is started or a new
229  rollback segment created.
230  @return the combined size of undo log segments in pages */
231 ulint trx_undo_lists_init(
232     trx_rseg_t *rseg); /*!< in: rollback segment memory object */
233 /** Assigns an undo log for a transaction. A new undo log is created or a cached
234  undo log reused.
235  @return DB_SUCCESS if undo log assign successful, possible error codes
236  are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE DB_READ_ONLY
237  DB_OUT_OF_MEMORY */
238 dberr_t trx_undo_assign_undo(
239     trx_t *trx,               /*!< in: transaction */
240     trx_undo_ptr_t *undo_ptr, /*!< in: assign undo log from
241                               referred rollback segment. */
242     ulint type)               /*!< in: TRX_UNDO_INSERT or
243                               TRX_UNDO_UPDATE */
244     MY_ATTRIBUTE((warn_unused_result));
245 /** Sets the state of the undo log segment at a transaction finish.
246  @return undo log segment header page, x-latched */
247 page_t *trx_undo_set_state_at_finish(
248     trx_undo_t *undo, /*!< in: undo log memory copy */
249     mtr_t *mtr);      /*!< in: mtr */
250 
251 /** Set the state of the undo log segment at a XA PREPARE or XA ROLLBACK.
252 @param[in,out]	trx		transaction
253 @param[in,out]	undo		insert_undo or update_undo log
254 @param[in]	rollback	false=XA PREPARE, true=XA ROLLBACK
255 @param[in,out]	mtr		mini-transaction
256 @return undo log segment header page, x-latched */
257 page_t *trx_undo_set_state_at_prepare(trx_t *trx, trx_undo_t *undo,
258                                       bool rollback, mtr_t *mtr);
259 
260 /** Adds the update undo log header as the first in the history list, and
261  frees the memory object, or puts it to the list of cached update undo log
262  segments. */
263 void trx_undo_update_cleanup(
264     trx_t *trx,               /*!< in: trx owning the update
265                               undo log */
266     trx_undo_ptr_t *undo_ptr, /*!< in: update undo log. */
267     page_t *undo_page,        /*!< in: update undo log header page,
268                               x-latched */
269     bool update_rseg_history_len,
270     /*!< in: if true: update rseg history
271     len else skip updating it. */
272     ulint n_added_logs, /*!< in: number of logs added */
273     mtr_t *mtr);        /*!< in: mtr */
274 
275 /** Frees an insert undo log after a transaction commit or rollback.
276 Knowledge of inserts is not needed after a commit or rollback, therefore
277 the data can be discarded.
278 @param[in,out]	undo_ptr	undo log to clean up
279 @param[in]	noredo		whether the undo tablespace is redo logged */
280 void trx_undo_insert_cleanup(trx_undo_ptr_t *undo_ptr, bool noredo);
281 
282 /** At shutdown, frees the undo logs of a transaction which was either
283 PREPARED or (ACTIVE and recovered).
284 @param[in]  trx                   transation which undo logs are freed
285 @param[in]  expected_undo_state   expected state of undo logs */
286 void trx_undo_free_trx_with_prepared_or_active_logs(
287     trx_t *trx, ulint expected_undo_state) UNIV_COLD;
288 
289 /* Forward declaration. */
290 namespace undo {
291 struct Tablespace;
292 class Truncate;
293 }  // namespace undo
294 
295 /** Truncate UNDO tablespace, reinitialize header and rseg.
296 @param[in]  marked_space  UNDO tablespace to truncate
297 @return true if success else false. */
298 bool trx_undo_truncate_tablespace(undo::Tablespace *marked_space);
299 
300 #endif /* !UNIV_HOTBACKUP */
301 /** Parses the redo log entry of an undo log page initialization.
302  @return end of log record or NULL */
303 byte *trx_undo_parse_page_init(const byte *ptr,     /*!< in: buffer */
304                                const byte *end_ptr, /*!< in: buffer end */
305                                page_t *page,        /*!< in: page or NULL */
306                                mtr_t *mtr);         /*!< in: mtr or NULL */
307 /** Parse the redo log entry of an undo log page header create or reuse.
308 @param[in]	type	MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE
309 @param[in]	ptr	redo log record
310 @param[in]	end_ptr	end of log buffer
311 @param[in,out]	page	page frame or NULL
312 @param[in,out]	mtr	mini-transaction or NULL
313 @return end of log record or NULL */
314 byte *trx_undo_parse_page_header(mlog_id_t type, const byte *ptr,
315                                  const byte *end_ptr, page_t *page, mtr_t *mtr);
316 /************************************************************************
317 Frees an undo log memory copy. */
318 void trx_undo_mem_free(trx_undo_t *undo); /* in: the undo object to be freed */
319 
320 /* Types of an undo log segment */
321 #define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
322 #define TRX_UNDO_UPDATE                  \
323   2 /* contains undo entries for updates \
324     and delete markings: in short,       \
325     modifys (the name 'UPDATE' is a      \
326     historical relic) */
327 /* States of an undo log segment */
328 #define TRX_UNDO_ACTIVE                                         \
329   1                        /* contains an undo log of an active \
330                            transaction */
331 #define TRX_UNDO_CACHED 2  /* cached for quick reuse */
332 #define TRX_UNDO_TO_FREE 3 /* insert undo segment can be freed */
333 #define TRX_UNDO_TO_PURGE                 \
334   4 /* update undo segment will not be    \
335     reused: it can be freed in purge when \
336     all undo data in it is removed */
337 #define TRX_UNDO_PREPARED         \
338   5 /* contains an undo log of an \
339     prepared transaction */
340 
341 #ifndef UNIV_HOTBACKUP
342 /** Transaction undo log memory object; this is protected by the undo_mutex
343 in the corresponding transaction object */
344 
345 struct trx_undo_t {
346   /* Set undo segment to prepared state and set XID
347   @param[in]	in_xid	transaction XID. */
348   void set_prepared(const XID *in_xid);
349 
350   /*-----------------------------*/
351   ulint id;        /*!< undo log slot number within the
352                    rollback segment */
353   ulint type;      /*!< TRX_UNDO_INSERT or
354                    TRX_UNDO_UPDATE */
355   ulint state;     /*!< state of the corresponding undo log
356                    segment */
357   ibool del_marks; /*!< relevant only in an update undo
358                    log: this is TRUE if the transaction may
359                    have delete marked records, because of
360                    a delete of a row or an update of an
361                    indexed field; purge is then
362                    necessary; also TRUE if the transaction
363                    has updated an externally stored
364                    field */
365   trx_id_t trx_id; /*!< id of the trx assigned to the undo
366                    log */
367   XID xid;         /*!< X/Open XA transaction
368                    identification */
369   ulint flag;      /*!< flag for current transaction XID and GTID.
370                    Persisted in TRX_UNDO_FLAGS flag of undo header. */
371 
372   /** Set if space for GTID is allocated. */
373   bool gtid_allocated;
374 
375   ibool dict_operation; /*!< TRUE if a dict operation trx */
376   trx_rseg_t *rseg;     /*!< rseg where the undo log belongs */
377   /*-----------------------------*/
378   space_id_t space; /*!< space id where the undo log
379                     placed */
380   page_size_t page_size;
381   page_no_t hdr_page_no;  /*!< page number of the header page in
382                           the undo log */
383   ulint hdr_offset;       /*!< header offset of the undo log on
384                           the page */
385   page_no_t last_page_no; /*!< page number of the last page in the
386                           undo log; this may differ from
387                           top_page_no during a rollback */
388   ulint size;             /*!< current size in pages */
389   /*-----------------------------*/
390   ulint empty;              /*!< TRUE if the stack of undo log
391                             records is currently empty */
392   page_no_t top_page_no;    /*!< page number where the latest undo
393                             log record was catenated; during
394                             rollback the page from which the latest
395                             undo record was chosen */
396   ulint top_offset;         /*!< offset of the latest undo record,
397                             i.e., the topmost element in the undo
398                             log if we think of it as a stack */
399   undo_no_t top_undo_no;    /*!< undo number of the latest record */
400   buf_block_t *guess_block; /*!< guess for the buffer block where
401                             the top page might reside */
402   ulint withdraw_clock;     /*!< the withdraw clock value of the
403                             buffer pool when guess_block was stored */
404   /*-----------------------------*/
405   UT_LIST_NODE_T(trx_undo_t) undo_list;
406   /*!< undo log objects in the rollback
407   segment are chained into lists */
408 };
409 
410 /** Write any previous GTIDs to disk. Used for external XA
411 Commit and Rollback to write XA prepare GTID to disk table
412 before updating undo log GTID with commit/rollback GTID.
413 @param[in]	trx	transaction
414 */
415 void trx_undo_gtid_flush_prepare(trx_t *trx);
416 
417 /** For saving GTID add update undo slot, if required.
418 @param[in]	trx		transaction
419 @param[in]	prepare		operation is prepare
420 @param[in]	rollback	operation is rollback
421 @return innodb error code. */
422 dberr_t trx_undo_gtid_add_update_undo(trx_t *trx, bool prepare, bool rollback);
423 
424 /** Set GTID flag in undo if transaction has GTID/
425 @param[in,out]	trx		transaction
426 @param[in,out]	undo		undo log memory object */
427 void trx_undo_gtid_set(trx_t *trx, trx_undo_t *undo);
428 
429 /** Read and persist GTID from undo header during recovery.
430 @param[in]	undo_log	undo log header */
431 void trx_undo_gtid_read_and_persist(trx_ulogf_t *undo_log);
432 
433 /** Write GTID information to undo log header.
434 @param[in,out]	trx		transaction
435 @param[in,out]	undo_header	undo log header
436 @param[in,out]	undo		undo log memory object
437 @param[in,out]	mtr		minit transaction for write */
438 void trx_undo_gtid_write(trx_t *trx, trx_ulogf_t *undo_header, trx_undo_t *undo,
439                          mtr_t *mtr);
440 
441 #endif /* !UNIV_HOTBACKUP */
442 
443 /** The offset of the undo log page header on pages of the undo log */
444 #define TRX_UNDO_PAGE_HDR FSEG_PAGE_DATA
445 /*-------------------------------------------------------------*/
446 /** Transaction undo log page header offsets */
447 /* @{ */
448 #define TRX_UNDO_PAGE_TYPE  \
449   0 /*!< TRX_UNDO_INSERT or \
450     TRX_UNDO_UPDATE */
451 #define TRX_UNDO_PAGE_START               \
452   2 /*!< Byte offset where the undo log   \
453     records for the LATEST transaction    \
454     start on this page (remember that     \
455     in an update undo log, the first page \
456     can contain several undo logs) */
457 #define TRX_UNDO_PAGE_FREE                 \
458   4 /*!< On each page of the undo log this \
459     field contains the byte offset of the  \
460     first free byte on the page */
461 #define TRX_UNDO_PAGE_NODE               \
462   6 /*!< The file list node in the chain \
463     of undo log pages */
464 /*-------------------------------------------------------------*/
465 #define TRX_UNDO_PAGE_HDR_SIZE (6 + FLST_NODE_SIZE)
466 /*!< Size of the transaction undo
467 log page header, in bytes */
468 /* @} */
469 
470 /** An update undo segment with just one page can be reused if it has
471 at most this many bytes used; we must leave space at least for one new undo
472 log header on the page */
473 
474 #define TRX_UNDO_PAGE_REUSE_LIMIT (3 * UNIV_PAGE_SIZE / 4)
475 
476 /* An update undo log segment may contain several undo logs on its first page
477 if the undo logs took so little space that the segment could be cached and
478 reused. All the undo log headers are then on the first page, and the last one
479 owns the undo log records on subsequent pages if the segment is bigger than
480 one page. If an undo log is stored in a segment, then on the first page it is
481 allowed to have zero undo records, but if the segment extends to several
482 pages, then all the rest of the pages must contain at least one undo log
483 record. */
484 
485 /** The offset of the undo log segment header on the first page of the undo
486 log segment */
487 
488 #define TRX_UNDO_SEG_HDR (TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE)
489 /** Undo log segment header */
490 /* @{ */
491 /*-------------------------------------------------------------*/
492 #define TRX_UNDO_STATE 0 /*!< TRX_UNDO_ACTIVE, ... */
493 
494 #define TRX_UNDO_LAST_LOG                   \
495   2 /*!< Offset of the last undo log header \
496     on the segment header page, 0 if        \
497     none */
498 #define TRX_UNDO_FSEG_HEADER               \
499   4 /*!< Header for the file segment which \
500     the undo log segment occupies */
501 #define TRX_UNDO_PAGE_LIST (4 + FSEG_HEADER_SIZE)
502 /*!< Base node for the list of pages in
503 the undo log segment; defined only on
504 the undo log segment's first page */
505 /*-------------------------------------------------------------*/
506 /** Size of the undo log segment header */
507 #define TRX_UNDO_SEG_HDR_SIZE (4 + FSEG_HEADER_SIZE + FLST_BASE_NODE_SIZE)
508 /* @} */
509 
510 /** The undo log header. There can be several undo log headers on the first
511 page of an update undo log segment. */
512 /* @{ */
513 /*-------------------------------------------------------------*/
514 #define TRX_UNDO_TRX_ID 0 /*!< Transaction id */
515 #define TRX_UNDO_TRX_NO                  \
516   8 /*!< Transaction number of the       \
517     transaction; defined only if the log \
518     is in a history list */
519 #define TRX_UNDO_DEL_MARKS                 \
520   16 /*!< Defined only in an update undo   \
521      log: TRUE if the transaction may have \
522      done delete markings of records, and  \
523      thus purge is necessary */
524 #define TRX_UNDO_LOG_START                    \
525   18 /*!< Offset of the first undo log record \
526      of this log on the header page; purge    \
527      may remove undo log record from the      \
528      log start, and therefore this is not     \
529      necessarily the same as this log         \
530      header end offset */
531 #define TRX_UNDO_FLAGS                               \
532   20 /*! Transaction UNDO flags in one byte. This is \
533      backward compatible as earlier we were storing  \
534      either 1 or 0 for TRX_UNDO_XID_EXISTS. */
535 #define TRX_UNDO_FLAG_XID                    \
536   0x01 /*!< TRUE if undo log header includes \
537        X/Open XA transaction identification  \
538        XID */
539 #define TRX_UNDO_FLAG_GTID                   \
540   0x02 /*!< TRUE if undo log header includes \
541        GTID information from replication */
542 #define TRX_UNDO_DICT_TRANS                  \
543   21 /*!< TRUE if the transaction is a table \
544      create, index create, or drop           \
545      transaction: in recovery                \
546      the transaction cannot be rolled back   \
547      in the usual way: a 'rollback' rather   \
548      means dropping the created or dropped   \
549      table, if it still exists */
550 #define TRX_UNDO_TABLE_ID                  \
551   22 /*!< Id of the table if the preceding \
552      field is TRUE. Note: deprecated */
553 #define TRX_UNDO_NEXT_LOG                    \
554   30 /*!< Offset of the next undo log header \
555      on this page, 0 if none */
556 #define TRX_UNDO_PREV_LOG                 \
557   32 /*!< Offset of the previous undo log \
558      header on this page, 0 if none */
559 #define TRX_UNDO_HISTORY_NODE              \
560   34 /*!< If the log is put to the history \
561      list, the file list node is here */
562 /*-------------------------------------------------------------*/
563 /** Size of the undo log header without XID information */
564 #define TRX_UNDO_LOG_OLD_HDR_SIZE (34 + FLST_NODE_SIZE)
565 
566 /* Note: the writing of the undo log old header is coded by a log record
567 MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE. The appending of an XID to the
568 header is logged separately. In this sense, the XID is not really a member
569 of the undo log header. TODO: do not append the XID to the log header if XA
570 is not needed by the user. The XID wastes about 150 bytes of space in every
571 undo log. In the history list we may have millions of undo logs, which means
572 quite a large overhead. */
573 
574 /** X/Open XA Transaction Identification (XID) */
575 /* @{ */
576 /** xid_t::formatID */
577 #define TRX_UNDO_XA_FORMAT (TRX_UNDO_LOG_OLD_HDR_SIZE)
578 /** xid_t::gtrid_length */
579 #define TRX_UNDO_XA_TRID_LEN (TRX_UNDO_XA_FORMAT + 4)
580 /** xid_t::bqual_length */
581 #define TRX_UNDO_XA_BQUAL_LEN (TRX_UNDO_XA_TRID_LEN + 4)
582 /** Distributed transaction identifier data */
583 #define TRX_UNDO_XA_XID (TRX_UNDO_XA_BQUAL_LEN + 4)
584 /*--------------------------------------------------------------*/
585 #define TRX_UNDO_LOG_XA_HDR_SIZE (TRX_UNDO_XA_XID + XIDDATASIZE)
586 /*!< Total size of the undo log header
587 with the XA XID */
588 /* @} */
589 
590 /* GTID is generated by replication when binlog and GTID mode is on. We
591 persist GTID with undo record till it is written to gtid_exeuted table.
592 GTID information is present when TRX_UNDO_FLAG_GTID set. It follows XID
593 information */
594 
595 /** GTID version offset */
596 #define TRX_UNDO_LOG_GTID_VERSION (TRX_UNDO_LOG_XA_HDR_SIZE)
597 
598 /** GTID offset */
599 #define TRX_UNDO_LOG_GTID (TRX_UNDO_LOG_XA_HDR_SIZE + 1)
600 
601 /** Total length of GTID */
602 #define TRX_UNDO_LOG_GTID_LEN 64
603 
604 /** Total size of GTID information. */
605 #define TRX_UNDO_LOG_HDR_SIZE (TRX_UNDO_LOG_GTID + TRX_UNDO_LOG_GTID_LEN)
606 
607 #include "trx0undo.ic"
608 #endif
609