1
/*****************************************************************************
3
Copyright (C) 1996, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/trx0sys.ic
23
Created 3/26/1996 Heikki Tuuri
24
*******************************************************/
27
#include "data0type.h"
28
#ifndef UNIV_HOTBACKUP
32
/* The typedef for rseg slot in the file copy */
33
typedef byte trx_sysf_rseg_t;
35
/* Rollback segment specification slot offsets */
36
/*-------------------------------------------------------------*/
37
#define TRX_SYS_RSEG_SPACE 0 /* space where the the segment
38
header is placed; starting with
39
MySQL/InnoDB 5.1.7, this is
40
UNIV_UNDEFINED if the slot is unused */
41
#define TRX_SYS_RSEG_PAGE_NO 4 /* page number where the the segment
42
header is placed; this is FIL_NULL
43
if the slot is unused */
44
/*-------------------------------------------------------------*/
45
/* Size of a rollback segment specification slot */
46
#define TRX_SYS_RSEG_SLOT_SIZE 8
48
/*****************************************************************//**
49
Writes the value of max_trx_id to the file based trx system header. */
52
trx_sys_flush_max_trx_id(void);
53
/*==========================*/
55
/***************************************************************//**
56
Checks if a page address is the trx sys header page.
57
@return TRUE if trx sys header page */
62
ulint space, /*!< in: space */
63
ulint page_no)/*!< in: page number */
65
if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
73
/***************************************************************//**
74
Gets the pointer in the nth slot of the rseg array.
75
@return pointer to rseg object, NULL if slot not in use */
80
trx_sys_t* sys, /*!< in: trx system */
81
ulint n) /*!< in: index of slot */
83
ut_ad(mutex_own(&(kernel_mutex)));
84
ut_ad(n < TRX_SYS_N_RSEGS);
86
return(sys->rseg_array[n]);
89
/***************************************************************//**
90
Sets the pointer in the nth slot of the rseg array. */
95
trx_sys_t* sys, /*!< in: trx system */
96
ulint n, /*!< in: index of slot */
97
trx_rseg_t* rseg) /*!< in: pointer to rseg object, NULL if slot
100
ut_ad(n < TRX_SYS_N_RSEGS);
102
sys->rseg_array[n] = rseg;
105
/**********************************************************************//**
106
Gets a pointer to the transaction system header and x-latches its page.
107
@return pointer to system header, page x-latched. */
112
mtr_t* mtr) /*!< in: mtr */
119
block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
121
buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
123
header = TRX_SYS + buf_block_get_frame(block);
128
/*****************************************************************//**
129
Gets the space of the nth rollback segment slot in the trx system
134
trx_sysf_rseg_get_space(
135
/*====================*/
136
trx_sysf_t* sys_header, /*!< in: trx sys header */
137
ulint i, /*!< in: slot index == rseg id */
138
mtr_t* mtr) /*!< in: mtr */
140
ut_ad(mutex_own(&(kernel_mutex)));
142
ut_ad(i < TRX_SYS_N_RSEGS);
144
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
145
+ i * TRX_SYS_RSEG_SLOT_SIZE
146
+ TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
149
/*****************************************************************//**
150
Gets the page number of the nth rollback segment slot in the trx system
152
@return page number, FIL_NULL if slot unused */
155
trx_sysf_rseg_get_page_no(
156
/*======================*/
157
trx_sysf_t* sys_header, /*!< in: trx system header */
158
ulint i, /*!< in: slot index == rseg id */
159
mtr_t* mtr) /*!< in: mtr */
162
ut_ad(mutex_own(&(kernel_mutex)));
163
ut_ad(i < TRX_SYS_N_RSEGS);
165
return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
166
+ i * TRX_SYS_RSEG_SLOT_SIZE
167
+ TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
170
/*****************************************************************//**
171
Sets the space id of the nth rollback segment slot in the trx system
175
trx_sysf_rseg_set_space(
176
/*====================*/
177
trx_sysf_t* sys_header, /*!< in: trx sys file copy */
178
ulint i, /*!< in: slot index == rseg id */
179
ulint space, /*!< in: space id */
180
mtr_t* mtr) /*!< in: mtr */
182
ut_ad(mutex_own(&(kernel_mutex)));
184
ut_ad(i < TRX_SYS_N_RSEGS);
186
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
187
+ i * TRX_SYS_RSEG_SLOT_SIZE
188
+ TRX_SYS_RSEG_SPACE,
193
/*****************************************************************//**
194
Sets the page number of the nth rollback segment slot in the trx system
198
trx_sysf_rseg_set_page_no(
199
/*======================*/
200
trx_sysf_t* sys_header, /*!< in: trx sys header */
201
ulint i, /*!< in: slot index == rseg id */
202
ulint page_no, /*!< in: page number, FIL_NULL if the
203
slot is reset to unused */
204
mtr_t* mtr) /*!< in: mtr */
206
ut_ad(mutex_own(&(kernel_mutex)));
208
ut_ad(i < TRX_SYS_N_RSEGS);
210
mlog_write_ulint(sys_header + TRX_SYS_RSEGS
211
+ i * TRX_SYS_RSEG_SLOT_SIZE
212
+ TRX_SYS_RSEG_PAGE_NO,
216
#endif /* !UNIV_HOTBACKUP */
218
/*****************************************************************//**
219
Writes a trx id to an index page. In case that the id size changes in
220
some future version, this function should be used instead of
226
byte* ptr, /*!< in: pointer to memory where written */
227
trx_id_t id) /*!< in: id */
229
#if DATA_TRX_ID_LEN != 6
230
# error "DATA_TRX_ID_LEN != 6"
232
mach_write_to_6(ptr, id);
235
#ifndef UNIV_HOTBACKUP
236
/*****************************************************************//**
237
Reads a trx id from an index page. In case that the id size changes in
238
some future version, this function should be used instead of
245
const byte* ptr) /*!< in: pointer to memory from where to read */
247
#if DATA_TRX_ID_LEN != 6
248
# error "DATA_TRX_ID_LEN != 6"
250
return(mach_read_from_6(ptr));
253
/****************************************************************//**
254
Looks for the trx handle with the given id in trx_list.
255
@return the trx handle or NULL if not found */
260
trx_id_t trx_id) /*!< in: trx id to search for */
264
ut_ad(mutex_own(&(kernel_mutex)));
266
trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
268
while (trx != NULL) {
269
if (trx_id == trx->id) {
274
trx = UT_LIST_GET_NEXT(trx_list, trx);
280
/****************************************************************//**
281
Returns the minumum trx id in trx list. This is the smallest id for which
282
the trx can possibly be active. (But, you must look at the trx->conc_state to
283
find out if the minimum trx id transaction itself is active, or already
285
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
288
trx_list_get_min_trx_id(void)
289
/*=========================*/
293
ut_ad(mutex_own(&(kernel_mutex)));
295
trx = UT_LIST_GET_LAST(trx_sys->trx_list);
299
return(trx_sys->max_trx_id);
305
/****************************************************************//**
306
Checks if a transaction with the given id is active.
307
@return TRUE if active */
312
trx_id_t trx_id) /*!< in: trx id of the transaction */
316
ut_ad(mutex_own(&(kernel_mutex)));
318
if (trx_id < trx_list_get_min_trx_id()) {
323
if (UNIV_UNLIKELY(trx_id >= trx_sys->max_trx_id)) {
325
/* There must be corruption: we return TRUE because this
326
function is only called by lock_clust_rec_some_has_impl()
327
and row_vers_impl_x_locked_off_kernel() and they have
328
diagnostic prints in this case */
333
trx = trx_get_on_id(trx_id);
334
if (trx && (trx->conc_state == TRX_ACTIVE
335
|| trx->conc_state == TRX_PREPARED)) {
343
/*****************************************************************//**
344
Allocates a new transaction id.
345
@return new, allocated trx id */
348
trx_sys_get_new_trx_id(void)
349
/*========================*/
353
ut_ad(mutex_own(&kernel_mutex));
355
/* VERY important: after the database is started, max_trx_id value is
356
divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
357
will evaluate to TRUE when this function is first time called,
358
and the value for trx id will be written to disk-based header!
359
Thus trx id values will not overlap when the database is
360
repeatedly started! */
362
if ((ulint) trx_sys->max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) {
364
trx_sys_flush_max_trx_id();
367
id = trx_sys->max_trx_id++;
372
/*****************************************************************//**
373
Allocates a new transaction number.
374
@return new, allocated trx number */
377
trx_sys_get_new_trx_no(void)
378
/*========================*/
380
ut_ad(mutex_own(&kernel_mutex));
382
return(trx_sys_get_new_trx_id());
384
#endif /* !UNIV_HOTBACKUP */