1/***************************************************************************** 2 3Copyright (c) 1996, 2021, Oracle and/or its affiliates. 4 5This program is free software; you can redistribute it and/or modify 6it under the terms of the GNU General Public License, version 2.0, 7as published by the Free Software Foundation. 8 9This program is also distributed with certain software (including 10but not limited to OpenSSL) that is licensed under separate terms, 11as designated in a particular file or component or in included license 12documentation. The authors of MySQL hereby grant you an additional 13permission to link the program and your derivative works with the 14separately licensed software that they have included with MySQL. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License, version 2.0, for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25*****************************************************************************/ 26 27/**************************************************//** 28@file include/trx0rseg.ic 29Rollback segment 30 31Created 3/26/1996 Heikki Tuuri 32*******************************************************/ 33 34#include "srv0srv.h" 35#include "mtr0log.h" 36#include "trx0sys.h" 37 38/** Gets a rollback segment header. 39@param[in] space space where placed 40@param[in] page_no page number of the header 41@param[in] page_size page size 42@param[in,out] mtr mini-transaction 43@return rollback segment header, page x-latched */ 44UNIV_INLINE 45trx_rsegf_t* 46trx_rsegf_get( 47 ulint space, 48 ulint page_no, 49 const page_size_t& page_size, 50 mtr_t* mtr) 51{ 52 buf_block_t* block; 53 trx_rsegf_t* header; 54 55 block = buf_page_get( 56 page_id_t(space, page_no), page_size, RW_X_LATCH, mtr); 57 58 buf_block_dbg_add_level(block, SYNC_RSEG_HEADER); 59 60 header = TRX_RSEG + buf_block_get_frame(block); 61 62 return(header); 63} 64 65/** Gets a newly created rollback segment header. 66@param[in] space space where placed 67@param[in] page_no page number of the header 68@param[in] page_size page size 69@param[in,out] mtr mini-transaction 70@return rollback segment header, page x-latched */ 71UNIV_INLINE 72trx_rsegf_t* 73trx_rsegf_get_new( 74 ulint space, 75 ulint page_no, 76 const page_size_t& page_size, 77 mtr_t* mtr) 78{ 79 buf_block_t* block; 80 trx_rsegf_t* header; 81 82 block = buf_page_get( 83 page_id_t(space, page_no), page_size, RW_X_LATCH, mtr); 84 85 buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW); 86 87 header = TRX_RSEG + buf_block_get_frame(block); 88 89 return(header); 90} 91 92/***************************************************************//** 93Gets the file page number of the nth undo log slot. 94@return page number of the undo log segment */ 95UNIV_INLINE 96ulint 97trx_rsegf_get_nth_undo( 98/*===================*/ 99 trx_rsegf_t* rsegf, /*!< in: rollback segment header */ 100 ulint n, /*!< in: index of slot */ 101 mtr_t* mtr) /*!< in: mtr */ 102{ 103 ut_a(n < TRX_RSEG_N_SLOTS); 104 105 return(mtr_read_ulint(rsegf + TRX_RSEG_UNDO_SLOTS 106 + n * TRX_RSEG_SLOT_SIZE, MLOG_4BYTES, mtr)); 107} 108 109/***************************************************************//** 110Sets the file page number of the nth undo log slot. */ 111UNIV_INLINE 112void 113trx_rsegf_set_nth_undo( 114/*===================*/ 115 trx_rsegf_t* rsegf, /*!< in: rollback segment header */ 116 ulint n, /*!< in: index of slot */ 117 ulint page_no,/*!< in: page number of the undo log segment */ 118 mtr_t* mtr) /*!< in: mtr */ 119{ 120 ut_a(n < TRX_RSEG_N_SLOTS); 121 122 mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE, 123 page_no, MLOG_4BYTES, mtr); 124} 125 126/****************************************************************//** 127Looks for a free slot for an undo log segment. 128@return slot index or ULINT_UNDEFINED if not found */ 129UNIV_INLINE 130ulint 131trx_rsegf_undo_find_free( 132/*=====================*/ 133 trx_rsegf_t* rsegf, /*!< in: rollback segment header */ 134 mtr_t* mtr) /*!< in: mtr */ 135{ 136 ulint i; 137 ulint page_no; 138 ulint max_slots = TRX_RSEG_N_SLOTS; 139 140#ifdef UNIV_DEBUG 141 if (trx_rseg_n_slots_debug) { 142 max_slots = ut_min(static_cast<ulint>(trx_rseg_n_slots_debug), 143 static_cast<ulint>(TRX_RSEG_N_SLOTS)); 144 } 145#endif 146 147 for (i = 0; i < max_slots; i++) { 148 page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr); 149 150 if (page_no == FIL_NULL) { 151 return(i); 152 } 153 } 154 155 return(ULINT_UNDEFINED); 156} 157 158/******************************************************************//** 159Looks for a rollback segment, based on the rollback segment id. 160@return rollback segment */ 161UNIV_INLINE 162trx_rseg_t* 163trx_rseg_get_on_id( 164/*===============*/ 165 ulint id, /*!< in: rollback segment id */ 166 bool is_redo_rseg) /*!< in: true if redo rseg else false. */ 167{ 168 ut_a(id < TRX_SYS_N_RSEGS); 169 170 /* If redo rseg is being requested and id falls in range of 171 non-redo rseg that is from slot-1....slot-srv_tmp_undo_logs then 172 server is being upgraded from pre-5.7.2. In such case return 173 rseg from pending_purge_rseg_array array. */ 174 if (is_redo_rseg && trx_sys_is_noredo_rseg_slot(id)) { 175 ut_ad(trx_sys->pending_purge_rseg_array[id] != NULL); 176 return(trx_sys->pending_purge_rseg_array[id]); 177 } 178 179 return(trx_sys->rseg_array[id]); 180} 181 182