~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to plugin/innobase/include/trx0sys.ic

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-03-18 12:12:31 UTC
  • Revision ID: james.westby@ubuntu.com-20100318121231-k6g1xe6cshbwa0f8
Tags: upstream-2010.03.1347
ImportĀ upstreamĀ versionĀ 2010.03.1347

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 
 
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
 
4
 
 
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.
 
8
 
 
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.
 
12
 
 
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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/**************************************************//**
 
20
@file include/trx0sys.ic
 
21
Transaction system
 
22
 
 
23
Created 3/26/1996 Heikki Tuuri
 
24
*******************************************************/
 
25
 
 
26
#include "trx0trx.h"
 
27
#include "data0type.h"
 
28
#ifndef UNIV_HOTBACKUP
 
29
# include "srv0srv.h"
 
30
# include "mtr0log.h"
 
31
 
 
32
/* The typedef for rseg slot in the file copy */
 
33
typedef byte    trx_sysf_rseg_t;
 
34
 
 
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
 
47
 
 
48
/*****************************************************************//**
 
49
Writes the value of max_trx_id to the file based trx system header. */
 
50
UNIV_INTERN
 
51
void
 
52
trx_sys_flush_max_trx_id(void);
 
53
/*==========================*/
 
54
 
 
55
/***************************************************************//**
 
56
Checks if a page address is the trx sys header page.
 
57
@return TRUE if trx sys header page */
 
58
UNIV_INLINE
 
59
ibool
 
60
trx_sys_hdr_page(
 
61
/*=============*/
 
62
        ulint   space,  /*!< in: space */
 
63
        ulint   page_no)/*!< in: page number */
 
64
{
 
65
        if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
 
66
 
 
67
                return(TRUE);
 
68
        }
 
69
 
 
70
        return(FALSE);
 
71
}
 
72
 
 
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 */
 
76
UNIV_INLINE
 
77
trx_rseg_t*
 
78
trx_sys_get_nth_rseg(
 
79
/*=================*/
 
80
        trx_sys_t*      sys,    /*!< in: trx system */
 
81
        ulint           n)      /*!< in: index of slot */
 
82
{
 
83
        ut_ad(mutex_own(&(kernel_mutex)));
 
84
        ut_ad(n < TRX_SYS_N_RSEGS);
 
85
 
 
86
        return(sys->rseg_array[n]);
 
87
}
 
88
 
 
89
/***************************************************************//**
 
90
Sets the pointer in the nth slot of the rseg array. */
 
91
UNIV_INLINE
 
92
void
 
93
trx_sys_set_nth_rseg(
 
94
/*=================*/
 
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
 
98
                                not in use */
 
99
{
 
100
        ut_ad(n < TRX_SYS_N_RSEGS);
 
101
 
 
102
        sys->rseg_array[n] = rseg;
 
103
}
 
104
 
 
105
/**********************************************************************//**
 
106
Gets a pointer to the transaction system header and x-latches its page.
 
107
@return pointer to system header, page x-latched. */
 
108
UNIV_INLINE
 
109
trx_sysf_t*
 
110
trx_sysf_get(
 
111
/*=========*/
 
112
        mtr_t*  mtr)    /*!< in: mtr */
 
113
{
 
114
        buf_block_t*    block;
 
115
        trx_sysf_t*     header;
 
116
 
 
117
        ut_ad(mtr);
 
118
 
 
119
        block = buf_page_get(TRX_SYS_SPACE, 0, TRX_SYS_PAGE_NO,
 
120
                             RW_X_LATCH, mtr);
 
121
        buf_block_dbg_add_level(block, SYNC_TRX_SYS_HEADER);
 
122
 
 
123
        header = TRX_SYS + buf_block_get_frame(block);
 
124
 
 
125
        return(header);
 
126
}
 
127
 
 
128
/*****************************************************************//**
 
129
Gets the space of the nth rollback segment slot in the trx system
 
130
file copy.
 
131
@return space id */
 
132
UNIV_INLINE
 
133
ulint
 
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 */
 
139
{
 
140
        ut_ad(mutex_own(&(kernel_mutex)));
 
141
        ut_ad(sys_header);
 
142
        ut_ad(i < TRX_SYS_N_RSEGS);
 
143
 
 
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));
 
147
}
 
148
 
 
149
/*****************************************************************//**
 
150
Gets the page number of the nth rollback segment slot in the trx system
 
151
header.
 
152
@return page number, FIL_NULL if slot unused */
 
153
UNIV_INLINE
 
154
ulint
 
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 */
 
160
{
 
161
        ut_ad(sys_header);
 
162
        ut_ad(mutex_own(&(kernel_mutex)));
 
163
        ut_ad(i < TRX_SYS_N_RSEGS);
 
164
 
 
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));
 
168
}
 
169
 
 
170
/*****************************************************************//**
 
171
Sets the space id of the nth rollback segment slot in the trx system
 
172
file copy. */
 
173
UNIV_INLINE
 
174
void
 
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 */
 
181
{
 
182
        ut_ad(mutex_own(&(kernel_mutex)));
 
183
        ut_ad(sys_header);
 
184
        ut_ad(i < TRX_SYS_N_RSEGS);
 
185
 
 
186
        mlog_write_ulint(sys_header + TRX_SYS_RSEGS
 
187
                         + i * TRX_SYS_RSEG_SLOT_SIZE
 
188
                         + TRX_SYS_RSEG_SPACE,
 
189
                         space,
 
190
                         MLOG_4BYTES, mtr);
 
191
}
 
192
 
 
193
/*****************************************************************//**
 
194
Sets the page number of the nth rollback segment slot in the trx system
 
195
header. */
 
196
UNIV_INLINE
 
197
void
 
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 */
 
205
{
 
206
        ut_ad(mutex_own(&(kernel_mutex)));
 
207
        ut_ad(sys_header);
 
208
        ut_ad(i < TRX_SYS_N_RSEGS);
 
209
 
 
210
        mlog_write_ulint(sys_header + TRX_SYS_RSEGS
 
211
                         + i * TRX_SYS_RSEG_SLOT_SIZE
 
212
                         + TRX_SYS_RSEG_PAGE_NO,
 
213
                         page_no,
 
214
                         MLOG_4BYTES, mtr);
 
215
}
 
216
#endif /* !UNIV_HOTBACKUP */
 
217
 
 
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
 
221
mach_write_... */
 
222
UNIV_INLINE
 
223
void
 
224
trx_write_trx_id(
 
225
/*=============*/
 
226
        byte*           ptr,    /*!< in: pointer to memory where written */
 
227
        trx_id_t        id)     /*!< in: id */
 
228
{
 
229
#if DATA_TRX_ID_LEN != 6
 
230
# error "DATA_TRX_ID_LEN != 6"
 
231
#endif
 
232
        mach_write_to_6(ptr, id);
 
233
}
 
234
 
 
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
 
239
mach_read_...
 
240
@return id */
 
241
UNIV_INLINE
 
242
trx_id_t
 
243
trx_read_trx_id(
 
244
/*============*/
 
245
        const byte*     ptr)    /*!< in: pointer to memory from where to read */
 
246
{
 
247
#if DATA_TRX_ID_LEN != 6
 
248
# error "DATA_TRX_ID_LEN != 6"
 
249
#endif
 
250
        return(mach_read_from_6(ptr));
 
251
}
 
252
 
 
253
/****************************************************************//**
 
254
Looks for the trx handle with the given id in trx_list.
 
255
@return the trx handle or NULL if not found */
 
256
UNIV_INLINE
 
257
trx_t*
 
258
trx_get_on_id(
 
259
/*==========*/
 
260
        trx_id_t        trx_id) /*!< in: trx id to search for */
 
261
{
 
262
        trx_t*  trx;
 
263
 
 
264
        ut_ad(mutex_own(&(kernel_mutex)));
 
265
 
 
266
        trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
 
267
 
 
268
        while (trx != NULL) {
 
269
                if (0 == ut_dulint_cmp(trx_id, trx->id)) {
 
270
 
 
271
                        return(trx);
 
272
                }
 
273
 
 
274
                trx = UT_LIST_GET_NEXT(trx_list, trx);
 
275
        }
 
276
 
 
277
        return(NULL);
 
278
}
 
279
 
 
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
 
284
committed.)
 
285
@return the minimum trx id, or trx_sys->max_trx_id if the trx list is empty */
 
286
UNIV_INLINE
 
287
trx_id_t
 
288
trx_list_get_min_trx_id(void)
 
289
/*=========================*/
 
290
{
 
291
        trx_t*  trx;
 
292
 
 
293
        ut_ad(mutex_own(&(kernel_mutex)));
 
294
 
 
295
        trx = UT_LIST_GET_LAST(trx_sys->trx_list);
 
296
 
 
297
        if (trx == NULL) {
 
298
 
 
299
                return(trx_sys->max_trx_id);
 
300
        }
 
301
 
 
302
        return(trx->id);
 
303
}
 
304
 
 
305
/****************************************************************//**
 
306
Checks if a transaction with the given id is active.
 
307
@return TRUE if active */
 
308
UNIV_INLINE
 
309
ibool
 
310
trx_is_active(
 
311
/*==========*/
 
312
        trx_id_t        trx_id) /*!< in: trx id of the transaction */
 
313
{
 
314
        trx_t*  trx;
 
315
 
 
316
        ut_ad(mutex_own(&(kernel_mutex)));
 
317
 
 
318
        if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) {
 
319
 
 
320
                return(FALSE);
 
321
        }
 
322
 
 
323
        if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
 
324
 
 
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 */
 
329
 
 
330
                return(TRUE);
 
331
        }
 
332
 
 
333
        trx = trx_get_on_id(trx_id);
 
334
        if (trx && (trx->conc_state == TRX_ACTIVE
 
335
                    || trx->conc_state == TRX_PREPARED)) {
 
336
 
 
337
                return(TRUE);
 
338
        }
 
339
 
 
340
        return(FALSE);
 
341
}
 
342
 
 
343
/*****************************************************************//**
 
344
Allocates a new transaction id.
 
345
@return new, allocated trx id */
 
346
UNIV_INLINE
 
347
trx_id_t
 
348
trx_sys_get_new_trx_id(void)
 
349
/*========================*/
 
350
{
 
351
        trx_id_t        id;
 
352
 
 
353
        ut_ad(mutex_own(&kernel_mutex));
 
354
 
 
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! */
 
361
 
 
362
        if (ut_dulint_get_low(trx_sys->max_trx_id)
 
363
            % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) {
 
364
 
 
365
                trx_sys_flush_max_trx_id();
 
366
        }
 
367
 
 
368
        id = trx_sys->max_trx_id;
 
369
 
 
370
        UT_DULINT_INC(trx_sys->max_trx_id);
 
371
 
 
372
        return(id);
 
373
}
 
374
 
 
375
/*****************************************************************//**
 
376
Allocates a new transaction number.
 
377
@return new, allocated trx number */
 
378
UNIV_INLINE
 
379
trx_id_t
 
380
trx_sys_get_new_trx_no(void)
 
381
/*========================*/
 
382
{
 
383
        ut_ad(mutex_own(&kernel_mutex));
 
384
 
 
385
        return(trx_sys_get_new_trx_id());
 
386
}
 
387
#endif /* !UNIV_HOTBACKUP */