1 /*****************************************************************************
3 Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
17 *****************************************************************************/
19 /**************************************************//**
20 @file include/trx0undo.h
23 Created 3/26/1996 Heikki Tuuri
24 *******************************************************/
30 #include "trx0types.h"
33 #include "page0types.h"
36 #ifndef UNIV_HOTBACKUP
37 /***********************************************************************//**
38 Builds a roll pointer.
39 @return roll pointer */
42 trx_undo_build_roll_ptr(
43 /*====================*/
44 ibool is_insert
, /*!< in: TRUE if insert undo log */
45 ulint rseg_id
, /*!< in: rollback segment id */
46 ulint page_no
, /*!< in: page number */
47 ulint offset
); /*!< in: offset of the undo entry within page */
48 /***********************************************************************//**
49 Decodes a roll pointer. */
52 trx_undo_decode_roll_ptr(
53 /*=====================*/
54 roll_ptr_t roll_ptr
, /*!< in: roll pointer */
55 ibool
* is_insert
, /*!< out: TRUE if insert undo log */
56 ulint
* rseg_id
, /*!< out: rollback segment id */
57 ulint
* page_no
, /*!< out: page number */
58 ulint
* offset
); /*!< out: offset of the undo
60 /***********************************************************************//**
61 Returns TRUE if the roll pointer is of the insert type.
62 @return TRUE if insert undo log */
65 trx_undo_roll_ptr_is_insert(
66 /*========================*/
67 roll_ptr_t roll_ptr
); /*!< in: roll pointer */
68 #endif /* !UNIV_HOTBACKUP */
69 /*****************************************************************//**
70 Writes a roll ptr to an index page. In case that the size changes in
71 some future version, this function should be used instead of
77 byte
* ptr
, /*!< in: pointer to memory where
79 roll_ptr_t roll_ptr
); /*!< in: roll ptr */
80 /*****************************************************************//**
81 Reads a roll ptr from an index page. In case that the roll ptr size
82 changes in some future version, this function should be used instead of
89 const byte
* ptr
); /*!< in: pointer to memory from where to read */
90 #ifndef UNIV_HOTBACKUP
91 /******************************************************************//**
92 Gets an undo log page and x-latches it.
93 @return pointer to page x-latched */
98 ulint space
, /*!< in: space where placed */
99 ulint zip_size
, /*!< in: compressed page size in bytes
100 or 0 for uncompressed pages */
101 ulint page_no
, /*!< in: page number */
102 mtr_t
* mtr
); /*!< in: mtr */
103 /******************************************************************//**
104 Gets an undo log page and s-latches it.
105 @return pointer to page s-latched */
108 trx_undo_page_get_s_latched(
109 /*========================*/
110 ulint space
, /*!< in: space where placed */
111 ulint zip_size
, /*!< in: compressed page size in bytes
112 or 0 for uncompressed pages */
113 ulint page_no
, /*!< in: page number */
114 mtr_t
* mtr
); /*!< in: mtr */
115 /******************************************************************//**
116 Returns the previous undo record on the page in the specified log, or
118 @return pointer to record, NULL if none */
121 trx_undo_page_get_prev_rec(
122 /*=======================*/
123 trx_undo_rec_t
* rec
, /*!< in: undo log record */
124 ulint page_no
,/*!< in: undo log header page number */
125 ulint offset
);/*!< in: undo log header offset on page */
126 /******************************************************************//**
127 Returns the next undo log record on the page in the specified log, or
129 @return pointer to record, NULL if none */
132 trx_undo_page_get_next_rec(
133 /*=======================*/
134 trx_undo_rec_t
* rec
, /*!< in: undo log record */
135 ulint page_no
,/*!< in: undo log header page number */
136 ulint offset
);/*!< in: undo log header offset on page */
137 /******************************************************************//**
138 Returns the last undo record on the page in the specified undo log, or
140 @return pointer to record, NULL if none */
143 trx_undo_page_get_last_rec(
144 /*=======================*/
145 page_t
* undo_page
,/*!< in: undo log page */
146 ulint page_no
,/*!< in: undo log header page number */
147 ulint offset
); /*!< in: undo log header offset on page */
148 /******************************************************************//**
149 Returns the first undo record on the page in the specified undo log, or
151 @return pointer to record, NULL if none */
154 trx_undo_page_get_first_rec(
155 /*========================*/
156 page_t
* undo_page
,/*!< in: undo log page */
157 ulint page_no
,/*!< in: undo log header page number */
158 ulint offset
);/*!< in: undo log header offset on page */
159 /***********************************************************************//**
160 Gets the previous record in an undo log.
161 @return undo log record, the page s-latched, NULL if none */
164 trx_undo_get_prev_rec(
165 /*==================*/
166 trx_undo_rec_t
* rec
, /*!< in: undo record */
167 ulint page_no
,/*!< in: undo log header page number */
168 ulint offset
, /*!< in: undo log header offset on page */
169 mtr_t
* mtr
); /*!< in: mtr */
170 /***********************************************************************//**
171 Gets the next record in an undo log.
172 @return undo log record, the page s-latched, NULL if none */
175 trx_undo_get_next_rec(
176 /*==================*/
177 trx_undo_rec_t
* rec
, /*!< in: undo record */
178 ulint page_no
,/*!< in: undo log header page number */
179 ulint offset
, /*!< in: undo log header offset on page */
180 mtr_t
* mtr
); /*!< in: mtr */
181 /***********************************************************************//**
182 Gets the first record in an undo log.
183 @return undo log record, the page latched, NULL if none */
186 trx_undo_get_first_rec(
187 /*===================*/
188 ulint space
, /*!< in: undo log header space */
189 ulint zip_size
,/*!< in: compressed page size in bytes
190 or 0 for uncompressed pages */
191 ulint page_no
,/*!< in: undo log header page number */
192 ulint offset
, /*!< in: undo log header offset on page */
193 ulint mode
, /*!< in: latching mode: RW_S_LATCH or RW_X_LATCH */
194 mtr_t
* mtr
); /*!< in: mtr */
195 /********************************************************************//**
196 Tries to add a page to the undo log segment where the undo log is placed.
197 @return X-latched block if success, else NULL */
202 trx_t
* trx
, /*!< in: transaction */
203 trx_undo_t
* undo
, /*!< in: undo log memory object */
204 mtr_t
* mtr
) /*!< in: mtr which does not have a latch to any
205 undo log page; the caller must have reserved
206 the rollback segment mutex */
207 __attribute__((nonnull
, warn_unused_result
));
208 /********************************************************************//**
209 Frees the last undo log page.
210 The caller must hold the rollback segment mutex. */
213 trx_undo_free_last_page_func(
214 /*==========================*/
216 const trx_t
* trx
, /*!< in: transaction */
217 #endif /* UNIV_DEBUG */
218 trx_undo_t
* undo
, /*!< in/out: undo log memory copy */
219 mtr_t
* mtr
) /*!< in/out: mini-transaction which does not
220 have a latch to any undo log page or which
221 has allocated the undo log page */
222 __attribute__((nonnull
));
224 # define trx_undo_free_last_page(trx,undo,mtr) \
225 trx_undo_free_last_page_func(trx,undo,mtr)
226 #else /* UNIV_DEBUG */
227 # define trx_undo_free_last_page(trx,undo,mtr) \
228 trx_undo_free_last_page_func(undo,mtr)
229 #endif /* UNIV_DEBUG */
231 /***********************************************************************//**
232 Truncates an undo log from the end. This function is used during a rollback
233 to free space from an undo log. */
236 trx_undo_truncate_end_func(
237 /*=======================*/
239 const trx_t
* trx
, /*!< in: transaction whose undo log it is */
240 #endif /* UNIV_DEBUG */
241 trx_undo_t
* undo
, /*!< in/out: undo log */
242 undo_no_t limit
) /*!< in: all undo records with undo number
243 >= this value should be truncated */
244 __attribute__((nonnull
));
246 # define trx_undo_truncate_end(trx,undo,limit) \
247 trx_undo_truncate_end_func(trx,undo,limit)
248 #else /* UNIV_DEBUG */
249 # define trx_undo_truncate_end(trx,undo,limit) \
250 trx_undo_truncate_end_func(undo,limit)
251 #endif /* UNIV_DEBUG */
253 /***********************************************************************//**
254 Truncates an undo log from the start. This function is used during a purge
258 trx_undo_truncate_start(
259 /*====================*/
260 trx_rseg_t
* rseg
, /*!< in: rollback segment */
261 ulint space
, /*!< in: space id of the log */
262 ulint hdr_page_no
, /*!< in: header page number */
263 ulint hdr_offset
, /*!< in: header offset on the page */
264 undo_no_t limit
); /*!< in: all undo pages with
265 undo numbers < this value
266 should be truncated; NOTE that
267 the function only frees whole
268 pages; the header page is not
269 freed, but emptied, if all the
270 records there are < limit */
271 /********************************************************************//**
272 Initializes the undo log lists for a rollback segment memory copy.
273 This function is only called when the database is started or a new
274 rollback segment created.
275 @return the combined size of undo log segments in pages */
280 trx_rseg_t
* rseg
); /*!< in: rollback segment memory object */
281 /**********************************************************************//**
282 Assigns an undo log for a transaction. A new undo log is created or a cached
284 @return DB_SUCCESS if undo log assign successful, possible error codes
285 are: DB_TOO_MANY_CONCURRENT_TRXS DB_OUT_OF_FILE_SPACE
289 trx_undo_assign_undo(
290 /*=================*/
291 trx_t
* trx
, /*!< in: transaction */
292 ulint type
); /*!< in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
293 /******************************************************************//**
294 Sets the state of the undo log segment at a transaction finish.
295 @return undo log segment header page, x-latched */
298 trx_undo_set_state_at_finish(
299 /*=========================*/
300 trx_rseg_t
* rseg
, /*!< in: rollback segment memory object */
301 trx_t
* trx
, /*!< in: transaction */
302 trx_undo_t
* undo
, /*!< in: undo log memory copy */
303 mtr_t
* mtr
); /*!< in: mtr */
304 /******************************************************************//**
305 Sets the state of the undo log segment at a transaction prepare.
306 @return undo log segment header page, x-latched */
309 trx_undo_set_state_at_prepare(
310 /*==========================*/
311 trx_t
* trx
, /*!< in: transaction */
312 trx_undo_t
* undo
, /*!< in: undo log memory copy */
313 mtr_t
* mtr
); /*!< in: mtr */
315 /**********************************************************************//**
316 Adds the update undo log header as the first in the history list, and
317 frees the memory object, or puts it to the list of cached update undo log
321 trx_undo_update_cleanup(
322 /*====================*/
323 trx_t
* trx
, /*!< in: trx owning the update undo log */
324 page_t
* undo_page
, /*!< in: update undo log header page,
326 mtr_t
* mtr
); /*!< in: mtr */
327 /******************************************************************//**
328 Frees or caches an insert undo log after a transaction commit or rollback.
329 Knowledge of inserts is not needed after a commit or rollback, therefore
330 the data can be discarded. */
333 trx_undo_insert_cleanup(
334 /*====================*/
335 trx_t
* trx
); /*!< in: transaction handle */
337 /********************************************************************//**
338 At shutdown, frees the undo logs of a PREPARED transaction. */
341 trx_undo_free_prepared(
342 /*===================*/
343 trx_t
* trx
) /*!< in/out: PREPARED transaction */
344 __attribute__((nonnull
));
345 #endif /* !UNIV_HOTBACKUP */
346 /***********************************************************//**
347 Parses the redo log entry of an undo log page initialization.
348 @return end of log record or NULL */
351 trx_undo_parse_page_init(
352 /*=====================*/
353 byte
* ptr
, /*!< in: buffer */
354 byte
* end_ptr
,/*!< in: buffer end */
355 page_t
* page
, /*!< in: page or NULL */
356 mtr_t
* mtr
); /*!< in: mtr or NULL */
357 /***********************************************************//**
358 Parses the redo log entry of an undo log page header create or reuse.
359 @return end of log record or NULL */
362 trx_undo_parse_page_header(
363 /*=======================*/
364 ulint type
, /*!< in: MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE */
365 byte
* ptr
, /*!< in: buffer */
366 byte
* end_ptr
,/*!< in: buffer end */
367 page_t
* page
, /*!< in: page or NULL */
368 mtr_t
* mtr
); /*!< in: mtr or NULL */
369 /***********************************************************//**
370 Parses the redo log entry of an undo log page header discard.
371 @return end of log record or NULL */
374 trx_undo_parse_discard_latest(
375 /*==========================*/
376 byte
* ptr
, /*!< in: buffer */
377 byte
* end_ptr
,/*!< in: buffer end */
378 page_t
* page
, /*!< in: page or NULL */
379 mtr_t
* mtr
); /*!< in: mtr or NULL */
380 /************************************************************************
381 Frees an undo log memory copy. */
386 trx_undo_t
* undo
); /* in: the undo object to be freed */
388 /* Types of an undo log segment */
389 #define TRX_UNDO_INSERT 1 /* contains undo entries for inserts */
390 #define TRX_UNDO_UPDATE 2 /* contains undo entries for updates
391 and delete markings: in short,
392 modifys (the name 'UPDATE' is a
394 /* States of an undo log segment */
395 #define TRX_UNDO_ACTIVE 1 /* contains an undo log of an active
397 #define TRX_UNDO_CACHED 2 /* cached for quick reuse */
398 #define TRX_UNDO_TO_FREE 3 /* insert undo segment can be freed */
399 #define TRX_UNDO_TO_PURGE 4 /* update undo segment will not be
400 reused: it can be freed in purge when
401 all undo data in it is removed */
402 #define TRX_UNDO_PREPARED 5 /* contains an undo log of an
403 prepared transaction */
405 #ifndef UNIV_HOTBACKUP
406 /** Transaction undo log memory object; this is protected by the undo_mutex
407 in the corresponding transaction object */
409 struct trx_undo_struct
{
410 /*-----------------------------*/
411 ulint id
; /*!< undo log slot number within the
413 ulint type
; /*!< TRX_UNDO_INSERT or
415 ulint state
; /*!< state of the corresponding undo log
417 ibool del_marks
; /*!< relevant only in an update undo log:
418 this is TRUE if the transaction may
419 have delete marked records, because of
420 a delete of a row or an update of an
421 indexed field; purge is then
422 necessary; also TRUE if the transaction
423 has updated an externally stored
425 trx_id_t trx_id
; /*!< id of the trx assigned to the undo
427 XID xid
; /*!< X/Open XA transaction
429 ibool dict_operation
; /*!< TRUE if a dict operation trx */
430 dulint table_id
; /*!< if a dict operation, then the table
432 trx_rseg_t
* rseg
; /*!< rseg where the undo log belongs */
433 /*-----------------------------*/
434 ulint space
; /*!< space id where the undo log
436 ulint zip_size
; /*!< compressed page size of space
437 in bytes, or 0 for uncompressed */
438 ulint hdr_page_no
; /*!< page number of the header page in
440 ulint hdr_offset
; /*!< header offset of the undo log on the
442 ulint last_page_no
; /*!< page number of the last page in the
443 undo log; this may differ from
444 top_page_no during a rollback */
445 ulint size
; /*!< current size in pages */
446 /*-----------------------------*/
447 ulint empty
; /*!< TRUE if the stack of undo log
448 records is currently empty */
449 ulint top_page_no
; /*!< page number where the latest undo
450 log record was catenated; during
451 rollback the page from which the latest
452 undo record was chosen */
453 ulint top_offset
; /*!< offset of the latest undo record,
454 i.e., the topmost element in the undo
455 log if we think of it as a stack */
456 undo_no_t top_undo_no
; /*!< undo number of the latest record */
457 buf_block_t
* guess_block
; /*!< guess for the buffer block where
458 the top page might reside */
459 /*-----------------------------*/
460 UT_LIST_NODE_T(trx_undo_t
) undo_list
;
461 /*!< undo log objects in the rollback
462 segment are chained into lists */
464 #endif /* !UNIV_HOTBACKUP */
466 /** The offset of the undo log page header on pages of the undo log */
467 #define TRX_UNDO_PAGE_HDR FSEG_PAGE_DATA
468 /*-------------------------------------------------------------*/
469 /** Transaction undo log page header offsets */
471 #define TRX_UNDO_PAGE_TYPE 0 /*!< TRX_UNDO_INSERT or
473 #define TRX_UNDO_PAGE_START 2 /*!< Byte offset where the undo log
474 records for the LATEST transaction
475 start on this page (remember that
476 in an update undo log, the first page
477 can contain several undo logs) */
478 #define TRX_UNDO_PAGE_FREE 4 /*!< On each page of the undo log this
479 field contains the byte offset of the
480 first free byte on the page */
481 #define TRX_UNDO_PAGE_NODE 6 /*!< The file list node in the chain
483 /*-------------------------------------------------------------*/
484 #define TRX_UNDO_PAGE_HDR_SIZE (6 + FLST_NODE_SIZE)
485 /*!< Size of the transaction undo
486 log page header, in bytes */
489 /** An update undo segment with just one page can be reused if it has
490 at most this many bytes used; we must leave space at least for one new undo
491 log header on the page */
493 #define TRX_UNDO_PAGE_REUSE_LIMIT (3 * UNIV_PAGE_SIZE / 4)
495 /* An update undo log segment may contain several undo logs on its first page
496 if the undo logs took so little space that the segment could be cached and
497 reused. All the undo log headers are then on the first page, and the last one
498 owns the undo log records on subsequent pages if the segment is bigger than
499 one page. If an undo log is stored in a segment, then on the first page it is
500 allowed to have zero undo records, but if the segment extends to several
501 pages, then all the rest of the pages must contain at least one undo log
504 /** The offset of the undo log segment header on the first page of the undo
507 #define TRX_UNDO_SEG_HDR (TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE)
508 /** Undo log segment header */
510 /*-------------------------------------------------------------*/
511 #define TRX_UNDO_STATE 0 /*!< TRX_UNDO_ACTIVE, ... */
512 #define TRX_UNDO_LAST_LOG 2 /*!< Offset of the last undo log header
513 on the segment header page, 0 if
515 #define TRX_UNDO_FSEG_HEADER 4 /*!< Header for the file segment which
516 the undo log segment occupies */
517 #define TRX_UNDO_PAGE_LIST (4 + FSEG_HEADER_SIZE)
518 /*!< Base node for the list of pages in
519 the undo log segment; defined only on
520 the undo log segment's first page */
521 /*-------------------------------------------------------------*/
522 /** Size of the undo log segment header */
523 #define TRX_UNDO_SEG_HDR_SIZE (4 + FSEG_HEADER_SIZE + FLST_BASE_NODE_SIZE)
527 /** The undo log header. There can be several undo log headers on the first
528 page of an update undo log segment. */
530 /*-------------------------------------------------------------*/
531 #define TRX_UNDO_TRX_ID 0 /*!< Transaction id */
532 #define TRX_UNDO_TRX_NO 8 /*!< Transaction number of the
533 transaction; defined only if the log
534 is in a history list */
535 #define TRX_UNDO_DEL_MARKS 16 /*!< Defined only in an update undo
536 log: TRUE if the transaction may have
537 done delete markings of records, and
538 thus purge is necessary */
539 #define TRX_UNDO_LOG_START 18 /*!< Offset of the first undo log record
540 of this log on the header page; purge
541 may remove undo log record from the
542 log start, and therefore this is not
543 necessarily the same as this log
545 #define TRX_UNDO_XID_EXISTS 20 /*!< TRUE if undo log header includes
546 X/Open XA transaction identification
548 #define TRX_UNDO_DICT_TRANS 21 /*!< TRUE if the transaction is a table
549 create, index create, or drop
550 transaction: in recovery
551 the transaction cannot be rolled back
552 in the usual way: a 'rollback' rather
553 means dropping the created or dropped
554 table, if it still exists */
555 #define TRX_UNDO_TABLE_ID 22 /*!< Id of the table if the preceding
557 #define TRX_UNDO_NEXT_LOG 30 /*!< Offset of the next undo log header
558 on this page, 0 if none */
559 #define TRX_UNDO_PREV_LOG 32 /*!< Offset of the previous undo log
560 header on this page, 0 if none */
561 #define TRX_UNDO_HISTORY_NODE 34 /*!< If the log is put to the history
562 list, the file list node is here */
563 /*-------------------------------------------------------------*/
564 /** Size of the undo log header without XID information */
565 #define TRX_UNDO_LOG_OLD_HDR_SIZE (34 + FLST_NODE_SIZE)
567 /* Note: the writing of the undo log old header is coded by a log record
568 MLOG_UNDO_HDR_CREATE or MLOG_UNDO_HDR_REUSE. The appending of an XID to the
569 header is logged separately. In this sense, the XID is not really a member
570 of the undo log header. TODO: do not append the XID to the log header if XA
571 is not needed by the user. The XID wastes about 150 bytes of space in every
572 undo log. In the history list we may have millions of undo logs, which means
573 quite a large overhead. */
575 /** X/Open XA Transaction Identification (XID) */
577 /** xid_t::formatID */
578 #define TRX_UNDO_XA_FORMAT (TRX_UNDO_LOG_OLD_HDR_SIZE)
579 /** xid_t::gtrid_length */
580 #define TRX_UNDO_XA_TRID_LEN (TRX_UNDO_XA_FORMAT + 4)
581 /** xid_t::bqual_length */
582 #define TRX_UNDO_XA_BQUAL_LEN (TRX_UNDO_XA_TRID_LEN + 4)
583 /** Distributed transaction identifier data */
584 #define TRX_UNDO_XA_XID (TRX_UNDO_XA_BQUAL_LEN + 4)
585 /*--------------------------------------------------------------*/
586 #define TRX_UNDO_LOG_XA_HDR_SIZE (TRX_UNDO_XA_XID + XIDDATASIZE)
587 /*!< Total size of the undo log header
592 #include "trx0undo.ic"