1 | /***************************************************************************** |
2 | |
3 | Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. |
4 | Copyright (c) 2017, 2018, MariaDB Corporation. |
5 | |
6 | This program is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free Software |
8 | Foundation; version 2 of the License. |
9 | |
10 | This program is distributed in the hope that it will be useful, but WITHOUT |
11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
12 | FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License along with |
15 | this program; if not, write to the Free Software Foundation, Inc., |
16 | 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA |
17 | |
18 | *****************************************************************************/ |
19 | |
20 | /**************************************************//** |
21 | @file include/trx0rseg.ic |
22 | Rollback segment |
23 | |
24 | Created 3/26/1996 Heikki Tuuri |
25 | *******************************************************/ |
26 | |
27 | #include "srv0srv.h" |
28 | #include "mtr0log.h" |
29 | |
30 | /** Gets a rollback segment header. |
31 | @param[in] space space where placed |
32 | @param[in] page_no page number of the header |
33 | @param[in,out] mtr mini-transaction |
34 | @return rollback segment header, page x-latched */ |
35 | UNIV_INLINE |
36 | trx_rsegf_t* |
37 | trx_rsegf_get(fil_space_t* space, ulint page_no, mtr_t* mtr) |
38 | { |
39 | ut_ad(space == fil_system.sys_space || space == fil_system.temp_space |
40 | || srv_is_undo_tablespace(space->id) |
41 | || !srv_was_started); |
42 | |
43 | buf_block_t* block = buf_page_get(page_id_t(space->id, page_no), |
44 | univ_page_size, RW_X_LATCH, mtr); |
45 | |
46 | buf_block_dbg_add_level(block, SYNC_RSEG_HEADER); |
47 | |
48 | return TRX_RSEG + block->frame; |
49 | } |
50 | |
51 | /** Gets a newly created rollback segment header. |
52 | @param[in] space space where placed |
53 | @param[in] page_no page number of the header |
54 | @param[in,out] mtr mini-transaction |
55 | @return rollback segment header, page x-latched */ |
56 | UNIV_INLINE |
57 | trx_rsegf_t* |
58 | trx_rsegf_get_new( |
59 | ulint space, |
60 | ulint page_no, |
61 | mtr_t* mtr) |
62 | { |
63 | buf_block_t* block; |
64 | trx_rsegf_t* ; |
65 | |
66 | ut_ad(space <= srv_undo_tablespaces_active || space == SRV_TMP_SPACE_ID |
67 | || !srv_was_started); |
68 | ut_ad(space <= TRX_SYS_MAX_UNDO_SPACES || space == SRV_TMP_SPACE_ID); |
69 | |
70 | block = buf_page_get( |
71 | page_id_t(space, page_no), univ_page_size, RW_X_LATCH, mtr); |
72 | |
73 | buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW); |
74 | |
75 | header = TRX_RSEG + buf_block_get_frame(block); |
76 | |
77 | return(header); |
78 | } |
79 | |
80 | /***************************************************************//** |
81 | Sets the file page number of the nth undo log slot. */ |
82 | UNIV_INLINE |
83 | void |
84 | trx_rsegf_set_nth_undo( |
85 | /*===================*/ |
86 | trx_rsegf_t* rsegf, /*!< in: rollback segment header */ |
87 | ulint n, /*!< in: index of slot */ |
88 | ulint page_no,/*!< in: page number of the undo log segment */ |
89 | mtr_t* mtr) /*!< in: mtr */ |
90 | { |
91 | ut_a(n < TRX_RSEG_N_SLOTS); |
92 | |
93 | mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE, |
94 | page_no, MLOG_4BYTES, mtr); |
95 | } |
96 | |
97 | /****************************************************************//** |
98 | Looks for a free slot for an undo log segment. |
99 | @return slot index or ULINT_UNDEFINED if not found */ |
100 | UNIV_INLINE |
101 | ulint |
102 | trx_rsegf_undo_find_free(const trx_rsegf_t* rsegf) |
103 | { |
104 | ulint i; |
105 | ulint page_no; |
106 | ulint max_slots = TRX_RSEG_N_SLOTS; |
107 | |
108 | #ifdef UNIV_DEBUG |
109 | if (trx_rseg_n_slots_debug) { |
110 | max_slots = ut_min(static_cast<ulint>(trx_rseg_n_slots_debug), |
111 | static_cast<ulint>(TRX_RSEG_N_SLOTS)); |
112 | } |
113 | #endif |
114 | |
115 | for (i = 0; i < max_slots; i++) { |
116 | page_no = trx_rsegf_get_nth_undo(rsegf, i); |
117 | |
118 | if (page_no == FIL_NULL) { |
119 | return(i); |
120 | } |
121 | } |
122 | |
123 | return(ULINT_UNDEFINED); |
124 | } |
125 | |