~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
Transaction system
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 3/26/1996 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#include "srv0srv.h"
 
10
#include "trx0trx.h"
 
11
#include "data0type.h"
 
12
 
 
13
/* The typedef for rseg slot in the file copy */
 
14
typedef byte    trx_sysf_rseg_t;
 
15
 
 
16
/* Rollback segment specification slot offsets */
 
17
/*-------------------------------------------------------------*/
 
18
#define TRX_SYS_RSEG_SPACE      0       /* space where the the segment
 
19
                                        header is placed; starting with
 
20
                                        MySQL/InnoDB 5.1.7, this is
 
21
                                        UNIV_UNDEFINED if the slot is unused */
 
22
#define TRX_SYS_RSEG_PAGE_NO    4       /*  page number where the the segment
 
23
                                        header is placed; this is FIL_NULL
 
24
                                        if the slot is unused */
 
25
/*-------------------------------------------------------------*/
 
26
/* Size of a rollback segment specification slot */
 
27
#define TRX_SYS_RSEG_SLOT_SIZE  8
 
28
 
 
29
/*********************************************************************
 
30
Writes the value of max_trx_id to the file based trx system header. */
 
31
 
 
32
void
 
33
trx_sys_flush_max_trx_id(void);
 
34
/*==========================*/
 
35
 
 
36
/*******************************************************************
 
37
Checks if a page address is the trx sys header page. */
 
38
UNIV_INLINE
 
39
ibool
 
40
trx_sys_hdr_page(
 
41
/*=============*/
 
42
                        /* out: TRUE if trx sys header page */
 
43
        ulint   space,  /* in: space */
 
44
        ulint   page_no)/* in: page number */
 
45
{
 
46
        if ((space == TRX_SYS_SPACE) && (page_no == TRX_SYS_PAGE_NO)) {
 
47
 
 
48
                return(TRUE);
 
49
        }
 
50
 
 
51
        return(FALSE);
 
52
}
 
53
 
 
54
/*******************************************************************
 
55
Gets the pointer in the nth slot of the rseg array. */
 
56
UNIV_INLINE
 
57
trx_rseg_t*
 
58
trx_sys_get_nth_rseg(
 
59
/*=================*/
 
60
                                /* out: pointer to rseg object, NULL if slot
 
61
                                not in use */
 
62
        trx_sys_t*      sys,    /* in: trx system */
 
63
        ulint           n)      /* in: index of slot */
 
64
{
 
65
        ut_ad(mutex_own(&(kernel_mutex)));
 
66
        ut_ad(n < TRX_SYS_N_RSEGS);
 
67
 
 
68
        return(sys->rseg_array[n]);
 
69
}
 
70
 
 
71
/*******************************************************************
 
72
Sets the pointer in the nth slot of the rseg array. */
 
73
UNIV_INLINE
 
74
void
 
75
trx_sys_set_nth_rseg(
 
76
/*=================*/
 
77
        trx_sys_t*      sys,    /* in: trx system */
 
78
        ulint           n,      /* in: index of slot */
 
79
        trx_rseg_t*     rseg)   /* in: pointer to rseg object, NULL if slot
 
80
                                not in use */
 
81
{
 
82
        ut_ad(n < TRX_SYS_N_RSEGS);
 
83
 
 
84
        sys->rseg_array[n] = rseg;
 
85
}
 
86
 
 
87
/**************************************************************************
 
88
Gets a pointer to the transaction system header and x-latches its page. */
 
89
UNIV_INLINE
 
90
trx_sysf_t*
 
91
trx_sysf_get(
 
92
/*=========*/
 
93
                        /* out: pointer to system header, page x-latched. */
 
94
        mtr_t*  mtr)    /* in: mtr */
 
95
{
 
96
        trx_sysf_t*     header;
 
97
 
 
98
        ut_ad(mtr);
 
99
 
 
100
        header = TRX_SYS + buf_page_get(TRX_SYS_SPACE, TRX_SYS_PAGE_NO,
 
101
                                        RW_X_LATCH, mtr);
 
102
 
 
103
#ifdef UNIV_SYNC_DEBUG
 
104
        buf_page_dbg_add_level(header, SYNC_TRX_SYS_HEADER);
 
105
#endif /* UNIV_SYNC_DEBUG */
 
106
 
 
107
        return(header);
 
108
}
 
109
 
 
110
/*********************************************************************
 
111
Gets the space of the nth rollback segment slot in the trx system
 
112
file copy. */
 
113
UNIV_INLINE
 
114
ulint
 
115
trx_sysf_rseg_get_space(
 
116
/*====================*/
 
117
                                        /* out: space id */
 
118
        trx_sysf_t*     sys_header,     /* in: trx sys header */
 
119
        ulint           i,              /* in: slot index == rseg id */
 
120
        mtr_t*          mtr)            /* in: mtr */
 
121
{
 
122
        ut_ad(mutex_own(&(kernel_mutex)));
 
123
        ut_ad(sys_header);
 
124
        ut_ad(i < TRX_SYS_N_RSEGS);
 
125
 
 
126
        return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
 
127
                              + i * TRX_SYS_RSEG_SLOT_SIZE
 
128
                              + TRX_SYS_RSEG_SPACE, MLOG_4BYTES, mtr));
 
129
}
 
130
 
 
131
/*********************************************************************
 
132
Gets the page number of the nth rollback segment slot in the trx system
 
133
header. */
 
134
UNIV_INLINE
 
135
ulint
 
136
trx_sysf_rseg_get_page_no(
 
137
/*======================*/
 
138
                                        /* out: page number, FIL_NULL
 
139
                                        if slot unused */
 
140
        trx_sysf_t*     sys_header,     /* in: trx system header */
 
141
        ulint           i,              /* in: slot index == rseg id */
 
142
        mtr_t*          mtr)            /* in: mtr */
 
143
{
 
144
        ut_ad(sys_header);
 
145
        ut_ad(mutex_own(&(kernel_mutex)));
 
146
        ut_ad(i < TRX_SYS_N_RSEGS);
 
147
 
 
148
        return(mtr_read_ulint(sys_header + TRX_SYS_RSEGS
 
149
                              + i * TRX_SYS_RSEG_SLOT_SIZE
 
150
                              + TRX_SYS_RSEG_PAGE_NO, MLOG_4BYTES, mtr));
 
151
}
 
152
 
 
153
/*********************************************************************
 
154
Sets the space id of the nth rollback segment slot in the trx system
 
155
file copy. */
 
156
UNIV_INLINE
 
157
void
 
158
trx_sysf_rseg_set_space(
 
159
/*====================*/
 
160
        trx_sysf_t*     sys_header,     /* in: trx sys file copy */
 
161
        ulint           i,              /* in: slot index == rseg id */
 
162
        ulint           space,          /* in: space id */
 
163
        mtr_t*          mtr)            /* in: mtr */
 
164
{
 
165
        ut_ad(mutex_own(&(kernel_mutex)));
 
166
        ut_ad(sys_header);
 
167
        ut_ad(i < TRX_SYS_N_RSEGS);
 
168
 
 
169
        mlog_write_ulint(sys_header + TRX_SYS_RSEGS
 
170
                         + i * TRX_SYS_RSEG_SLOT_SIZE
 
171
                         + TRX_SYS_RSEG_SPACE,
 
172
                         space,
 
173
                         MLOG_4BYTES, mtr);
 
174
}
 
175
 
 
176
/*********************************************************************
 
177
Sets the page number of the nth rollback segment slot in the trx system
 
178
header. */
 
179
UNIV_INLINE
 
180
void
 
181
trx_sysf_rseg_set_page_no(
 
182
/*======================*/
 
183
        trx_sysf_t*     sys_header,     /* in: trx sys header */
 
184
        ulint           i,              /* in: slot index == rseg id */
 
185
        ulint           page_no,        /* in: page number, FIL_NULL if the
 
186
                                        slot is reset to unused */
 
187
        mtr_t*          mtr)            /* in: mtr */
 
188
{
 
189
        ut_ad(mutex_own(&(kernel_mutex)));
 
190
        ut_ad(sys_header);
 
191
        ut_ad(i < TRX_SYS_N_RSEGS);
 
192
 
 
193
        mlog_write_ulint(sys_header + TRX_SYS_RSEGS
 
194
                         + i * TRX_SYS_RSEG_SLOT_SIZE
 
195
                         + TRX_SYS_RSEG_PAGE_NO,
 
196
                         page_no,
 
197
                         MLOG_4BYTES, mtr);
 
198
}
 
199
 
 
200
/*********************************************************************
 
201
Writes a trx id to an index page. In case that the id size changes in
 
202
some future version, this function should be used instead of
 
203
mach_write_... */
 
204
UNIV_INLINE
 
205
void
 
206
trx_write_trx_id(
 
207
/*=============*/
 
208
        byte*   ptr,    /* in: pointer to memory where written */
 
209
        dulint  id)     /* in: id */
 
210
{
 
211
        ut_ad(DATA_TRX_ID_LEN == 6);
 
212
 
 
213
        mach_write_to_6(ptr, id);
 
214
}
 
215
 
 
216
/*********************************************************************
 
217
Reads a trx id from an index page. In case that the id size changes in
 
218
some future version, this function should be used instead of
 
219
mach_read_... */
 
220
UNIV_INLINE
 
221
dulint
 
222
trx_read_trx_id(
 
223
/*============*/
 
224
                        /* out: id */
 
225
        byte*   ptr)    /* in: pointer to memory from where to read */
 
226
{
 
227
        ut_ad(DATA_TRX_ID_LEN == 6);
 
228
 
 
229
        return(mach_read_from_6(ptr));
 
230
}
 
231
 
 
232
/********************************************************************
 
233
Looks for the trx handle with the given id in trx_list. */
 
234
UNIV_INLINE
 
235
trx_t*
 
236
trx_get_on_id(
 
237
/*==========*/
 
238
                        /* out: the trx handle or NULL if not found */
 
239
        dulint  trx_id) /* in: trx id to search for */
 
240
{
 
241
        trx_t*  trx;
 
242
 
 
243
        ut_ad(mutex_own(&(kernel_mutex)));
 
244
 
 
245
        trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
 
246
 
 
247
        while (trx != NULL) {
 
248
                if (0 == ut_dulint_cmp(trx_id, trx->id)) {
 
249
 
 
250
                        return(trx);
 
251
                }
 
252
 
 
253
                trx = UT_LIST_GET_NEXT(trx_list, trx);
 
254
        }
 
255
 
 
256
        return(NULL);
 
257
}
 
258
 
 
259
/********************************************************************
 
260
Returns the minumum trx id in trx list. This is the smallest id for which
 
261
the trx can possibly be active. (But, you must look at the trx->conc_state to
 
262
find out if the minimum trx id transaction itself is active, or already
 
263
committed.) */
 
264
UNIV_INLINE
 
265
dulint
 
266
trx_list_get_min_trx_id(void)
 
267
/*=========================*/
 
268
                        /* out: the minimum trx id, or trx_sys->max_trx_id
 
269
                        if the trx list is empty */
 
270
{
 
271
        trx_t*  trx;
 
272
 
 
273
        ut_ad(mutex_own(&(kernel_mutex)));
 
274
 
 
275
        trx = UT_LIST_GET_LAST(trx_sys->trx_list);
 
276
 
 
277
        if (trx == NULL) {
 
278
 
 
279
                return(trx_sys->max_trx_id);
 
280
        }
 
281
 
 
282
        return(trx->id);
 
283
}
 
284
 
 
285
/********************************************************************
 
286
Checks if a transaction with the given id is active. */
 
287
UNIV_INLINE
 
288
ibool
 
289
trx_is_active(
 
290
/*==========*/
 
291
                        /* out: TRUE if active */
 
292
        dulint  trx_id) /* in: trx id of the transaction */
 
293
{
 
294
        trx_t*  trx;
 
295
 
 
296
        ut_ad(mutex_own(&(kernel_mutex)));
 
297
 
 
298
        if (ut_dulint_cmp(trx_id, trx_list_get_min_trx_id()) < 0) {
 
299
 
 
300
                return(FALSE);
 
301
        }
 
302
 
 
303
        if (ut_dulint_cmp(trx_id, trx_sys->max_trx_id) >= 0) {
 
304
 
 
305
                /* There must be corruption: we return TRUE because this
 
306
                function is only called by lock_clust_rec_some_has_impl()
 
307
                and row_vers_impl_x_locked_off_kernel() and they have
 
308
                diagnostic prints in this case */
 
309
 
 
310
                return(TRUE);
 
311
        }
 
312
 
 
313
        trx = trx_get_on_id(trx_id);
 
314
        if (trx && (trx->conc_state == TRX_ACTIVE
 
315
                    || trx->conc_state == TRX_PREPARED)) {
 
316
 
 
317
                return(TRUE);
 
318
        }
 
319
 
 
320
        return(FALSE);
 
321
}
 
322
 
 
323
/*********************************************************************
 
324
Allocates a new transaction id. */
 
325
UNIV_INLINE
 
326
dulint
 
327
trx_sys_get_new_trx_id(void)
 
328
/*========================*/
 
329
                        /* out: new, allocated trx id */
 
330
{
 
331
        dulint  id;
 
332
 
 
333
        ut_ad(mutex_own(&kernel_mutex));
 
334
 
 
335
        /* VERY important: after the database is started, max_trx_id value is
 
336
        divisible by TRX_SYS_TRX_ID_WRITE_MARGIN, and the following if
 
337
        will evaluate to TRUE when this function is first time called,
 
338
        and the value for trx id will be written to disk-based header!
 
339
        Thus trx id values will not overlap when the database is
 
340
        repeatedly started! */
 
341
 
 
342
        if (ut_dulint_get_low(trx_sys->max_trx_id)
 
343
            % TRX_SYS_TRX_ID_WRITE_MARGIN == 0) {
 
344
 
 
345
                trx_sys_flush_max_trx_id();
 
346
        }
 
347
 
 
348
        id = trx_sys->max_trx_id;
 
349
 
 
350
        UT_DULINT_INC(trx_sys->max_trx_id);
 
351
 
 
352
        return(id);
 
353
}
 
354
 
 
355
/*********************************************************************
 
356
Allocates a new transaction number. */
 
357
UNIV_INLINE
 
358
dulint
 
359
trx_sys_get_new_trx_no(void)
 
360
/*========================*/
 
361
                        /* out: new, allocated trx number */
 
362
{
 
363
        ut_ad(mutex_own(&kernel_mutex));
 
364
 
 
365
        return(trx_sys_get_new_trx_id());
 
366
}