~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/trx/trx0rseg.cc

  • Committer: Olaf van der Spek
  • Date: 2011-02-12 18:24:24 UTC
  • mto: (2167.1.2 build) (2172.1.4 build)
  • mto: This revision was merged to the branch mainline in revision 2168.
  • Revision ID: olafvdspek@gmail.com-20110212182424-kgnm9osi7qo97at2
casts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (C) 1996, 2010, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
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
 
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 
15
St, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
34
34
#include "srv0srv.h"
35
35
#include "trx0purge.h"
36
36
 
 
37
#ifdef UNIV_PFS_MUTEX
 
38
/* Key to register rseg_mutex_key with performance schema */
 
39
UNIV_INTERN mysql_pfs_key_t     rseg_mutex_key;
 
40
#endif /* UNIV_PFS_MUTEX */
 
41
 
37
42
/******************************************************************//**
38
43
Looks for a rollback segment, based on the rollback segment id.
39
44
@return rollback segment */
46
51
        trx_rseg_t*     rseg;
47
52
 
48
53
        rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list);
49
 
        ut_ad(rseg);
50
54
 
51
 
        while (rseg->id != id) {
 
55
        while (rseg && rseg->id != id) {
52
56
                rseg = UT_LIST_GET_NEXT(rseg_list, rseg);
53
 
                ut_ad(rseg);
54
57
        }
55
58
 
56
59
        return(rseg);
68
71
        ulint   zip_size,       /*!< in: compressed page size in bytes
69
72
                                or 0 for uncompressed pages */
70
73
        ulint   max_size,       /*!< in: max size in pages */
71
 
        ulint*  slot_no,        /*!< out: rseg id == slot number in trx sys */
 
74
        ulint   rseg_slot_no,   /*!< in: rseg id == slot number in trx sys */
72
75
        mtr_t*  mtr)            /*!< in: mtr */
73
76
{
74
77
        ulint           page_no;
81
84
        ut_ad(mutex_own(&kernel_mutex));
82
85
        ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space, NULL),
83
86
                                MTR_MEMO_X_LOCK));
84
 
        sys_header = trx_sysf_get(mtr);
85
 
 
86
 
        *slot_no = trx_sysf_rseg_find_free(mtr);
87
 
 
88
 
        if (*slot_no == ULINT_UNDEFINED) {
89
 
 
90
 
                return(FIL_NULL);
91
 
        }
92
87
 
93
88
        /* Allocate a new file segment for the rollback segment */
94
89
        block = fseg_create(space, 0,
122
117
                trx_rsegf_set_nth_undo(rsegf, i, FIL_NULL, mtr);
123
118
        }
124
119
 
125
 
        /* Add the rollback segment info to the free slot in the trx system
126
 
        header */
127
 
 
128
 
        trx_sysf_rseg_set_space(sys_header, *slot_no, space, mtr);
129
 
        trx_sysf_rseg_set_page_no(sys_header, *slot_no, page_no, mtr);
 
120
        /* Add the rollback segment info to the free slot in
 
121
        the trx system header */
 
122
 
 
123
        sys_header = trx_sysf_get(mtr);
 
124
 
 
125
        trx_sysf_rseg_set_space(sys_header, rseg_slot_no, space, mtr);
 
126
        trx_sysf_rseg_set_page_no(sys_header, rseg_slot_no, page_no, mtr);
130
127
 
131
128
        return(page_no);
132
129
}
133
130
 
134
131
/***********************************************************************//**
 
132
Free's an instance of the rollback segment in memory. */
 
133
UNIV_INTERN
 
134
void
 
135
trx_rseg_mem_free(
 
136
/*==============*/
 
137
        trx_rseg_t*     rseg)   /* in, own: instance to free */
 
138
{
 
139
        trx_undo_t*     undo;
 
140
 
 
141
        mutex_free(&rseg->mutex);
 
142
 
 
143
        /* There can't be any active transactions. */
 
144
        ut_a(UT_LIST_GET_LEN(rseg->update_undo_list) == 0);
 
145
        ut_a(UT_LIST_GET_LEN(rseg->insert_undo_list) == 0);
 
146
 
 
147
        undo = UT_LIST_GET_FIRST(rseg->update_undo_cached);
 
148
 
 
149
        while (undo != NULL) {
 
150
                trx_undo_t*     prev_undo = undo;
 
151
 
 
152
                undo = UT_LIST_GET_NEXT(undo_list, undo);
 
153
                UT_LIST_REMOVE(undo_list, rseg->update_undo_cached, prev_undo);
 
154
 
 
155
                trx_undo_mem_free(prev_undo);
 
156
        }
 
157
 
 
158
        undo = UT_LIST_GET_FIRST(rseg->insert_undo_cached);
 
159
 
 
160
        while (undo != NULL) {
 
161
                trx_undo_t*     prev_undo = undo;
 
162
 
 
163
                undo = UT_LIST_GET_NEXT(undo_list, undo);
 
164
                UT_LIST_REMOVE(undo_list, rseg->insert_undo_cached, prev_undo);
 
165
 
 
166
                trx_undo_mem_free(prev_undo);
 
167
        }
 
168
 
 
169
        trx_sys_set_nth_rseg(trx_sys, rseg->id, NULL);
 
170
 
 
171
        mem_free(rseg);
 
172
}
 
173
 
 
174
/***************************************************************************
135
175
Creates and initializes a rollback segment object. The values for the
136
176
fields are read from the header. The object is inserted to the rseg
137
177
list of the trx system object and a pointer is inserted in the rseg
148
188
        ulint   page_no,        /*!< in: page number of the segment header */
149
189
        mtr_t*  mtr)            /*!< in: mtr */
150
190
{
 
191
        ulint           len;
 
192
        trx_rseg_t*     rseg;
 
193
        fil_addr_t      node_addr;
151
194
        trx_rsegf_t*    rseg_header;
152
 
        trx_rseg_t*     rseg;
153
195
        trx_ulogf_t*    undo_log_hdr;
154
 
        fil_addr_t      node_addr;
155
196
        ulint           sum_of_undo_sizes;
156
 
        ulint           len;
157
197
 
158
198
        ut_ad(mutex_own(&kernel_mutex));
159
199
 
160
 
        rseg = mem_alloc(sizeof(trx_rseg_t));
 
200
        void *rseg_buf= mem_zalloc(sizeof(trx_rseg_t));
 
201
        rseg = static_cast<trx_rseg_t *>(rseg_buf);
161
202
 
162
203
        rseg->id = id;
163
204
        rseg->space = space;
164
205
        rseg->zip_size = zip_size;
165
206
        rseg->page_no = page_no;
166
207
 
167
 
        mutex_create(&rseg->mutex, SYNC_RSEG);
 
208
        mutex_create(rseg_mutex_key, &rseg->mutex, SYNC_RSEG);
168
209
 
169
210
        UT_LIST_ADD_LAST(rseg_list, trx_sys->rseg_list, rseg);
170
211
 
196
237
                                                 node_addr.page,
197
238
                                                 mtr) + node_addr.boffset;
198
239
 
199
 
                rseg->last_trx_no = mtr_read_dulint(
200
 
                        undo_log_hdr + TRX_UNDO_TRX_NO, mtr);
 
240
                rseg->last_trx_no = mach_read_from_8(
 
241
                        undo_log_hdr + TRX_UNDO_TRX_NO);
201
242
                rseg->last_del_marks = mtr_read_ulint(
202
243
                        undo_log_hdr + TRX_UNDO_DEL_MARKS, MLOG_2BYTES, mtr);
203
244
        } else {
207
248
        return(rseg);
208
249
}
209
250
 
210
 
/*********************************************************************//**
211
 
Creates the memory copies for rollback segments and initializes the
 
251
/********************************************************************
 
252
Creates the memory copies for the rollback segments and initializes the
212
253
rseg list and array in trx_sys at a database startup. */
213
 
UNIV_INTERN
 
254
static
214
255
void
215
 
trx_rseg_list_and_array_init(
216
 
/*=========================*/
 
256
trx_rseg_create_instance(
 
257
/*=====================*/
217
258
        trx_sysf_t*     sys_header,     /*!< in: trx system header */
218
259
        mtr_t*          mtr)            /*!< in: mtr */
219
260
{
220
 
        ulint   i;
221
 
        ulint   page_no;
222
 
        ulint   space;
223
 
 
224
 
        UT_LIST_INIT(trx_sys->rseg_list);
225
 
 
226
 
        trx_sys->rseg_history_len = 0;
 
261
        ulint           i;
227
262
 
228
263
        for (i = 0; i < TRX_SYS_N_RSEGS; i++) {
 
264
                ulint   page_no;
229
265
 
230
266
                page_no = trx_sysf_rseg_get_page_no(sys_header, i, mtr);
231
267
 
232
268
                if (page_no == FIL_NULL) {
233
 
 
234
269
                        trx_sys_set_nth_rseg(trx_sys, i, NULL);
235
270
                } else {
236
 
                        ulint   zip_size;
 
271
                        ulint           space;
 
272
                        ulint           zip_size;
 
273
                        trx_rseg_t*     rseg = NULL;
 
274
 
 
275
                        ut_a(!trx_rseg_get_on_id(i));
237
276
 
238
277
                        space = trx_sysf_rseg_get_space(sys_header, i, mtr);
239
278
 
240
279
                        zip_size = space ? fil_space_get_zip_size(space) : 0;
241
280
 
242
 
                        trx_rseg_mem_create(i, space, zip_size, page_no, mtr);
 
281
                        rseg = trx_rseg_mem_create(
 
282
                                i, space, zip_size, page_no, mtr);
 
283
 
 
284
                        ut_a(rseg->id == i);
243
285
                }
244
286
        }
245
287
}
246
288
 
247
 
/****************************************************************//**
248
 
Creates a new rollback segment to the database.
249
 
@return the created segment object, NULL if fail */
 
289
/*********************************************************************
 
290
Creates a rollback segment.
 
291
@return pointer to new rollback segment if create successful */
250
292
UNIV_INTERN
251
293
trx_rseg_t*
252
 
trx_rseg_create(
253
 
/*============*/
254
 
        ulint   space,          /*!< in: space id */
255
 
        ulint   max_size,       /*!< in: max size in pages */
256
 
        ulint*  id,             /*!< out: rseg id */
257
 
        mtr_t*  mtr)            /*!< in: mtr */
 
294
trx_rseg_create(void)
 
295
/*=================*/
258
296
{
259
 
        ulint           flags;
260
 
        ulint           zip_size;
261
 
        ulint           page_no;
262
 
        trx_rseg_t*     rseg;
263
 
 
264
 
        mtr_x_lock(fil_space_get_latch(space, &flags), mtr);
265
 
        zip_size = dict_table_flags_to_zip_size(flags);
 
297
        mtr_t           mtr;
 
298
        ulint           slot_no;
 
299
        trx_rseg_t*     rseg = NULL;
 
300
 
 
301
        mtr_start(&mtr);
 
302
 
 
303
        /* To obey the latching order, acquire the file space
 
304
        x-latch before the kernel mutex. */
 
305
        mtr_x_lock(fil_space_get_latch(TRX_SYS_SPACE, NULL), &mtr);
 
306
 
266
307
        mutex_enter(&kernel_mutex);
267
308
 
268
 
        page_no = trx_rseg_header_create(space, zip_size, max_size, id, mtr);
269
 
 
270
 
        if (page_no == FIL_NULL) {
271
 
 
272
 
                mutex_exit(&kernel_mutex);
273
 
                return(NULL);
 
309
        slot_no = trx_sysf_rseg_find_free(&mtr);
 
310
 
 
311
        if (slot_no != ULINT_UNDEFINED) {
 
312
                ulint           space;
 
313
                ulint           page_no;
 
314
                ulint           zip_size;
 
315
                trx_sysf_t*     sys_header;
 
316
 
 
317
                page_no = trx_rseg_header_create(
 
318
                        TRX_SYS_SPACE, 0, ULINT_MAX, slot_no, &mtr);
 
319
 
 
320
                ut_a(page_no != FIL_NULL);
 
321
 
 
322
                ut_ad(!trx_rseg_get_on_id(slot_no));
 
323
 
 
324
                sys_header = trx_sysf_get(&mtr);
 
325
 
 
326
                space = trx_sysf_rseg_get_space(sys_header, slot_no, &mtr);
 
327
 
 
328
                zip_size = space ? fil_space_get_zip_size(space) : 0;
 
329
 
 
330
                rseg = trx_rseg_mem_create(
 
331
                        slot_no, space, zip_size, page_no, &mtr);
274
332
        }
275
333
 
276
 
        rseg = trx_rseg_mem_create(*id, space, zip_size, page_no, mtr);
277
 
 
278
334
        mutex_exit(&kernel_mutex);
 
335
        mtr_commit(&mtr);
279
336
 
280
337
        return(rseg);
281
338
}
 
339
 
 
340
/********************************************************************
 
341
Initialize the rollback instance list. */
 
342
UNIV_INTERN
 
343
void
 
344
trx_rseg_list_and_array_init(
 
345
/*=========================*/
 
346
        trx_sysf_t*     sys_header,     /* in: trx system header */
 
347
        mtr_t*          mtr)            /* in: mtr */
 
348
{
 
349
        UT_LIST_INIT(trx_sys->rseg_list);
 
350
 
 
351
        trx_sys->rseg_history_len = 0;
 
352
 
 
353
        trx_rseg_create_instance(sys_header, mtr);
 
354
}
 
355