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