~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/mtr/mtr0mtr.c

  • Committer: Lee Bieber
  • Date: 2010-11-07 19:34:48 UTC
  • mfrom: (1910.1.2 build)
  • Revision ID: kalebral@gmail.com-20101107193448-64kdu912qej354sh
Merge Stewart - including adapting and expanding the "differences from mysql" page from the wiki.
Merge Stewart - fix bug 668143: drizzleslap with --commit runs second iteration data load in a transaction

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, 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
30
30
#endif
31
31
 
32
32
#include "buf0buf.h"
33
 
#include "buf0flu.h"
34
33
#include "page0types.h"
35
34
#include "mtr0log.h"
36
35
#include "log0log.h"
39
38
# include "log0recv.h"
40
39
/*****************************************************************//**
41
40
Releases the item in the slot given. */
42
 
static
 
41
UNIV_INLINE
43
42
void
44
43
mtr_memo_slot_release(
45
44
/*==================*/
49
48
        void*   object;
50
49
        ulint   type;
51
50
 
52
 
        ut_ad(mtr);
53
 
        ut_ad(slot);
54
 
 
55
 
#ifndef UNIV_DEBUG
56
 
        UT_NOT_USED(mtr);
57
 
#endif /* UNIV_DEBUG */
 
51
        ut_ad(mtr && slot);
58
52
 
59
53
        object = slot->object;
60
54
        type = slot->type;
61
55
 
62
56
        if (UNIV_LIKELY(object != NULL)) {
63
57
                if (type <= MTR_MEMO_BUF_FIX) {
64
 
                        buf_page_release((buf_block_t*)object, type);
 
58
                        buf_page_release((buf_block_t*)object, type, mtr);
65
59
                } else if (type == MTR_MEMO_S_LOCK) {
66
60
                        rw_lock_s_unlock((rw_lock_t*)object);
67
61
#ifdef UNIV_DEBUG
79
73
}
80
74
 
81
75
/**********************************************************//**
82
 
Releases the mlocks and other objects stored in an mtr memo.
83
 
They are released in the order opposite to which they were pushed
84
 
to the memo. */
85
 
static
 
76
Releases the mlocks and other objects stored in an mtr memo. They are released
 
77
in the order opposite to which they were pushed to the memo. NOTE! It is
 
78
essential that the x-rw-lock on a modified buffer page is not released before
 
79
buf_page_note_modification is called for that page! Otherwise, some thread
 
80
might race to modify it, and the flush list sort order on lsn would be
 
81
destroyed. */
 
82
UNIV_INLINE
86
83
void
87
84
mtr_memo_pop_all(
88
85
/*=============*/
102
99
 
103
100
        while (offset > 0) {
104
101
                offset -= sizeof(mtr_memo_slot_t);
105
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
 
102
                slot = dyn_array_get_element(memo, offset);
106
103
 
107
104
                mtr_memo_slot_release(mtr, slot);
108
105
        }
109
106
}
110
107
 
111
 
/*****************************************************************//**
112
 
Releases the item in the slot given. */
113
 
static
114
 
void
115
 
mtr_memo_slot_note_modification(
116
 
/*============================*/
117
 
        mtr_t*                  mtr,    /*!< in: mtr */
118
 
        mtr_memo_slot_t*        slot)   /*!< in: memo slot */
119
 
{
120
 
        ut_ad(mtr);
121
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
122
 
        ut_ad(mtr->modifications);
123
 
 
124
 
        if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) {
125
 
                buf_block_t*    block = (buf_block_t*) slot->object;
126
 
 
127
 
#ifdef UNIV_DEBUG
128
 
                ut_ad(log_flush_order_mutex_own());
129
 
#endif /* UNIV_DEBUG */
130
 
                buf_flush_note_modification(block, mtr);
131
 
        }
132
 
}
133
 
 
134
 
/**********************************************************//**
135
 
Add the modified pages to the buffer flush list. They are released
136
 
in the order opposite to which they were pushed to the memo. NOTE! It is
137
 
essential that the x-rw-lock on a modified buffer page is not released
138
 
before buf_page_note_modification is called for that page! Otherwise,
139
 
some thread might race to modify it, and the flush list sort order on
140
 
lsn would be destroyed. */
141
 
static
142
 
void
143
 
mtr_memo_note_modifications(
144
 
/*========================*/
145
 
        mtr_t*  mtr)    /*!< in: mtr */
146
 
{
147
 
        dyn_array_t*    memo;
148
 
        ulint           offset;
149
 
 
150
 
        ut_ad(mtr);
151
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
152
 
        ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
153
 
                                             commit */
154
 
        memo = &mtr->memo;
155
 
 
156
 
        offset = dyn_array_get_data_size(memo);
157
 
 
158
 
        while (offset > 0) {
159
 
                mtr_memo_slot_t* slot;
160
 
 
161
 
                offset -= sizeof(mtr_memo_slot_t);
162
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
163
 
 
164
 
                mtr_memo_slot_note_modification(mtr, slot);
165
 
        }
166
 
}
167
 
 
168
108
/************************************************************//**
169
109
Writes the contents of a mini-transaction log, if any, to the database log. */
170
110
static
197
137
                        &mtr->start_lsn);
198
138
                if (mtr->end_lsn) {
199
139
 
200
 
                        /* Success. We have the log mutex.
201
 
                        Add pages to flush list and exit */
202
 
                        goto func_exit;
 
140
                        return;
203
141
                }
204
142
        }
205
143
 
223
161
        }
224
162
 
225
163
        mtr->end_lsn = log_close();
226
 
 
227
 
func_exit:
228
 
        log_flush_order_mutex_enter();
229
 
 
230
 
        /* It is now safe to release the log mutex because the
231
 
        flush_order mutex will ensure that we are the first one
232
 
        to insert into the flush list. */
233
 
        log_release();
234
 
 
235
 
        if (mtr->modifications) {
236
 
                mtr_memo_note_modifications(mtr);
237
 
        }
238
 
 
239
 
        log_flush_order_mutex_exit();
240
164
}
241
165
#endif /* !UNIV_HOTBACKUP */
242
166
 
248
172
/*=======*/
249
173
        mtr_t*  mtr)    /*!< in: mini-transaction */
250
174
{
 
175
#ifndef UNIV_HOTBACKUP
 
176
        ibool           write_log;
 
177
#endif /* !UNIV_HOTBACKUP */
 
178
 
251
179
        ut_ad(mtr);
252
180
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
253
181
        ut_ad(mtr->state == MTR_ACTIVE);
256
184
#ifndef UNIV_HOTBACKUP
257
185
        /* This is a dirty read, for debugging. */
258
186
        ut_ad(!recv_no_log_write);
 
187
        write_log = mtr->modifications && mtr->n_log_recs;
259
188
 
260
 
        if (mtr->modifications && mtr->n_log_recs) {
 
189
        if (write_log) {
261
190
                mtr_log_reserve_and_write(mtr);
262
191
        }
263
192
 
 
193
        /* We first update the modification info to buffer pages, and only
 
194
        after that release the log mutex: this guarantees that when the log
 
195
        mutex is free, all buffer pages contain an up-to-date info of their
 
196
        modifications. This fact is used in making a checkpoint when we look
 
197
        at the oldest modification of any page in the buffer pool. It is also
 
198
        required when we insert modified buffer pages in to the flush list
 
199
        which must be sorted on oldest_modification. */
 
200
 
264
201
        mtr_memo_pop_all(mtr);
 
202
 
 
203
        if (write_log) {
 
204
                log_release();
 
205
        }
265
206
#endif /* !UNIV_HOTBACKUP */
266
207
 
267
208
        ut_d(mtr->state = MTR_COMMITTED);
297
238
        while (offset > savepoint) {
298
239
                offset -= sizeof(mtr_memo_slot_t);
299
240
 
300
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
 
241
                slot = dyn_array_get_element(memo, offset);
301
242
 
302
243
                ut_ad(slot->type != MTR_MEMO_MODIFY);
303
 
 
304
 
                /* We do not call mtr_memo_slot_note_modification()
305
 
                because there MUST be no changes made to the buffer
306
 
                pages after the savepoint */
307
244
                mtr_memo_slot_release(mtr, slot);
308
245
        }
309
246
}
330
267
 
331
268
        offset = dyn_array_get_data_size(memo);
332
269
 
333
 
        log_flush_order_mutex_enter();
334
270
        while (offset > 0) {
335
271
                offset -= sizeof(mtr_memo_slot_t);
336
272
 
337
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
338
 
 
339
 
                if (object == slot->object && type == slot->type) {
340
 
 
341
 
                        /* We cannot release a page that has been written
342
 
                        to in the middle of a mini-transaction. */
343
 
 
344
 
                        ut_ad(!(mtr->modifications
345
 
                                && slot->type == MTR_MEMO_PAGE_X_FIX));
 
273
                slot = dyn_array_get_element(memo, offset);
 
274
 
 
275
                if ((object == slot->object) && (type == slot->type)) {
346
276
 
347
277
                        mtr_memo_slot_release(mtr, slot);
348
278
 
349
279
                        break;
350
280
                }
351
281
        }
352
 
        log_flush_order_mutex_exit();
353
282
}
354
283
#endif /* !UNIV_HOTBACKUP */
355
284
 
362
291
/*===========*/
363
292
        const byte*     ptr,    /*!< in: pointer from where to read */
364
293
        ulint           type,   /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
365
 
        mtr_t*          /*mtr __attribute__((unused))*/)
 
294
        mtr_t*          mtr __attribute__((unused)))
366
295
                                /*!< in: mini-transaction handle */
367
296
{
368
297
        ut_ad(mtr->state == MTR_ACTIVE);
378
307
        }
379
308
}
380
309
 
 
310
/********************************************************//**
 
311
Reads 8 bytes from a file page buffered in the buffer pool.
 
312
@return value read */
 
313
UNIV_INTERN
 
314
dulint
 
315
mtr_read_dulint(
 
316
/*============*/
 
317
        const byte*     ptr,    /*!< in: pointer from where to read */
 
318
        mtr_t*          mtr __attribute__((unused)))
 
319
                                /*!< in: mini-transaction handle */
 
320
{
 
321
        ut_ad(mtr->state == MTR_ACTIVE);
 
322
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
 
323
              || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
 
324
        return(mach_read_from_8(ptr));
 
325
}
 
326
 
381
327
#ifdef UNIV_DEBUG
382
328
# ifndef UNIV_HOTBACKUP
383
329
/**********************************************************//**