1/*****************************************************************************
2
3Copyright (c) 1996, 2009, Oracle and/or its affiliates. All Rights Reserved.
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/******************************************************************//**
39Gets a rollback segment header.
40@return	rollback segment header, page x-latched */
41UNIV_INLINE
42trx_rsegf_t*
43trx_rsegf_get(
44/*==========*/
45	ulint	space,		/*!< in: space where placed */
46	ulint	zip_size,	/*!< in: compressed page size in bytes
47				or 0 for uncompressed pages */
48	ulint	page_no,	/*!< in: page number of the header */
49	mtr_t*	mtr)		/*!< in: mtr */
50{
51	buf_block_t*	block;
52	trx_rsegf_t*	header;
53
54	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
55	buf_block_dbg_add_level(block, SYNC_RSEG_HEADER);
56
57	header = TRX_RSEG + buf_block_get_frame(block);
58
59	return(header);
60}
61
62/******************************************************************//**
63Gets a newly created rollback segment header.
64@return	rollback segment header, page x-latched */
65UNIV_INLINE
66trx_rsegf_t*
67trx_rsegf_get_new(
68/*==============*/
69	ulint	space,		/*!< in: space where placed */
70	ulint	zip_size,	/*!< in: compressed page size in bytes
71				or 0 for uncompressed pages */
72	ulint	page_no,	/*!< in: page number of the header */
73	mtr_t*	mtr)		/*!< in: mtr */
74{
75	buf_block_t*	block;
76	trx_rsegf_t*	header;
77
78	block = buf_page_get(space, zip_size, page_no, RW_X_LATCH, mtr);
79	buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
80
81	header = TRX_RSEG + buf_block_get_frame(block);
82
83	return(header);
84}
85
86/***************************************************************//**
87Gets the file page number of the nth undo log slot.
88@return	page number of the undo log segment */
89UNIV_INLINE
90ulint
91trx_rsegf_get_nth_undo(
92/*===================*/
93	trx_rsegf_t*	rsegf,	/*!< in: rollback segment header */
94	ulint		n,	/*!< in: index of slot */
95	mtr_t*		mtr)	/*!< in: mtr */
96{
97	if (n >= TRX_RSEG_N_SLOTS) {
98		fprintf(stderr,
99			"InnoDB: Error: trying to get slot %lu of rseg\n",
100			(ulong) n);
101		ut_error;
102	}
103
104	return(mtr_read_ulint(rsegf + TRX_RSEG_UNDO_SLOTS
105			      + n * TRX_RSEG_SLOT_SIZE, MLOG_4BYTES, mtr));
106}
107
108/***************************************************************//**
109Sets the file page number of the nth undo log slot. */
110UNIV_INLINE
111void
112trx_rsegf_set_nth_undo(
113/*===================*/
114	trx_rsegf_t*	rsegf,	/*!< in: rollback segment header */
115	ulint		n,	/*!< in: index of slot */
116	ulint		page_no,/*!< in: page number of the undo log segment */
117	mtr_t*		mtr)	/*!< in: mtr */
118{
119	if (n >= TRX_RSEG_N_SLOTS) {
120		fprintf(stderr,
121			"InnoDB: Error: trying to set slot %lu of rseg\n",
122			(ulong) n);
123		ut_error;
124	}
125
126	mlog_write_ulint(rsegf + TRX_RSEG_UNDO_SLOTS + n * TRX_RSEG_SLOT_SIZE,
127			 page_no, MLOG_4BYTES, mtr);
128}
129
130/****************************************************************//**
131Looks for a free slot for an undo log segment.
132@return	slot index or ULINT_UNDEFINED if not found */
133UNIV_INLINE
134ulint
135trx_rsegf_undo_find_free(
136/*=====================*/
137	trx_rsegf_t*	rsegf,	/*!< in: rollback segment header */
138	mtr_t*		mtr)	/*!< in: mtr */
139{
140	ulint		i;
141	ulint		page_no;
142
143	for (i = 0;
144#ifndef UNIV_DEBUG
145	     i < TRX_RSEG_N_SLOTS;
146#else
147	     i < (trx_rseg_n_slots_debug ? trx_rseg_n_slots_debug : TRX_RSEG_N_SLOTS);
148#endif
149	     i++) {
150
151		page_no = trx_rsegf_get_nth_undo(rsegf, i, mtr);
152
153		if (page_no == FIL_NULL) {
154
155			return(i);
156		}
157	}
158
159	return(ULINT_UNDEFINED);
160}
161
162/******************************************************************//**
163Looks for a rollback segment, based on the rollback segment id.
164@return	rollback segment */
165UNIV_INLINE
166trx_rseg_t*
167trx_rseg_get_on_id(
168/*===============*/
169	ulint	id)	/*!< in: rollback segment id */
170{
171	ut_a(id < TRX_SYS_N_RSEGS);
172
173	return(trx_sys->rseg_array[id]);
174}
175
176