| 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 | |