~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2009-01-07 09:27:07 UTC
  • Revision ID: brian@tangent.org-20090107092707-bn67qpdllfcyh3j9
Removing dead field translator code.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1995, 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., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file mtr/mtr0mtr.c
 
1
/******************************************************
21
2
Mini-transaction buffer
22
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
23
6
Created 11/26/1995 Heikki Tuuri
24
7
*******************************************************/
25
8
 
30
13
#endif
31
14
 
32
15
#include "buf0buf.h"
33
 
#include "buf0flu.h"
34
16
#include "page0types.h"
35
17
#include "mtr0log.h"
36
18
#include "log0log.h"
37
19
 
38
 
#ifndef UNIV_HOTBACKUP
39
 
# include "log0recv.h"
40
 
/*****************************************************************//**
 
20
/*********************************************************************
41
21
Releases the item in the slot given. */
42
 
static
 
22
UNIV_INLINE
43
23
void
44
24
mtr_memo_slot_release(
45
25
/*==================*/
46
 
        mtr_t*                  mtr,    /*!< in: mtr */
47
 
        mtr_memo_slot_t*        slot)   /*!< in: memo slot */
 
26
        mtr_t*                  mtr,    /* in: mtr */
 
27
        mtr_memo_slot_t*        slot)   /* in: memo slot */
48
28
{
49
29
        void*   object;
50
30
        ulint   type;
51
31
 
52
 
        ut_ad(mtr);
53
 
        ut_ad(slot);
54
 
 
55
 
#ifndef UNIV_DEBUG
56
 
        UT_NOT_USED(mtr);
57
 
#endif /* UNIV_DEBUG */
 
32
        ut_ad(mtr && slot);
58
33
 
59
34
        object = slot->object;
60
35
        type = slot->type;
61
36
 
62
37
        if (UNIV_LIKELY(object != NULL)) {
63
38
                if (type <= MTR_MEMO_BUF_FIX) {
64
 
                        buf_page_release((buf_block_t*)object, type);
 
39
                        buf_page_release((buf_block_t*)object, type, mtr);
65
40
                } else if (type == MTR_MEMO_S_LOCK) {
66
41
                        rw_lock_s_unlock((rw_lock_t*)object);
67
42
#ifdef UNIV_DEBUG
78
53
        slot->object = NULL;
79
54
}
80
55
 
81
 
/**********************************************************//**
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
 
56
/**************************************************************
 
57
Releases the mlocks and other objects stored in an mtr memo. They are released
 
58
in the order opposite to which they were pushed to the memo. NOTE! It is
 
59
essential that the x-rw-lock on a modified buffer page is not released before
 
60
buf_page_note_modification is called for that page! Otherwise, some thread
 
61
might race to modify it, and the flush list sort order on lsn would be
 
62
destroyed. */
 
63
UNIV_INLINE
86
64
void
87
65
mtr_memo_pop_all(
88
66
/*=============*/
89
 
        mtr_t*  mtr)    /*!< in: mtr */
 
67
        mtr_t*  mtr)    /* in: mtr */
90
68
{
91
69
        mtr_memo_slot_t* slot;
92
70
        dyn_array_t*    memo;
102
80
 
103
81
        while (offset > 0) {
104
82
                offset -= sizeof(mtr_memo_slot_t);
105
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
 
83
                slot = dyn_array_get_element(memo, offset);
106
84
 
107
85
                mtr_memo_slot_release(mtr, slot);
108
86
        }
109
87
}
110
88
 
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
 
/************************************************************//**
 
89
/****************************************************************
169
90
Writes the contents of a mini-transaction log, if any, to the database log. */
170
91
static
171
92
void
172
93
mtr_log_reserve_and_write(
173
94
/*======================*/
174
 
        mtr_t*  mtr)    /*!< in: mtr */
 
95
        mtr_t*  mtr)    /* in: mtr */
175
96
{
176
97
        dyn_array_t*    mlog;
177
98
        dyn_block_t*    block;
178
99
        ulint           data_size;
 
100
        ibool           success;
179
101
        byte*           first_data;
180
102
 
181
103
        ut_ad(mtr);
194
116
        if (mlog->heap == NULL) {
195
117
                mtr->end_lsn = log_reserve_and_write_fast(
196
118
                        first_data, dyn_block_get_used(mlog),
197
 
                        &mtr->start_lsn);
198
 
                if (mtr->end_lsn) {
 
119
                        &(mtr->start_lsn), &success);
 
120
                if (success) {
199
121
 
200
 
                        /* Success. We have the log mutex.
201
 
                        Add pages to flush list and exit */
202
 
                        goto func_exit;
 
122
                        return;
203
123
                }
204
124
        }
205
125
 
223
143
        }
224
144
 
225
145
        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
146
}
241
 
#endif /* !UNIV_HOTBACKUP */
242
147
 
243
 
/***************************************************************//**
 
148
/*******************************************************************
244
149
Commits a mini-transaction. */
245
150
UNIV_INTERN
246
151
void
247
152
mtr_commit(
248
153
/*=======*/
249
 
        mtr_t*  mtr)    /*!< in: mini-transaction */
 
154
        mtr_t*  mtr)    /* in: mini-transaction */
250
155
{
 
156
        ibool           write_log;
 
157
 
251
158
        ut_ad(mtr);
252
159
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
253
160
        ut_ad(mtr->state == MTR_ACTIVE);
254
 
        ut_d(mtr->state = MTR_COMMITTING);
255
 
 
256
 
#ifndef UNIV_HOTBACKUP
257
 
        /* This is a dirty read, for debugging. */
258
 
        ut_ad(!recv_no_log_write);
259
 
 
260
 
        if (mtr->modifications && mtr->n_log_recs) {
 
161
#ifdef UNIV_DEBUG
 
162
        mtr->state = MTR_COMMITTING;
 
163
#endif
 
164
        write_log = mtr->modifications && mtr->n_log_recs;
 
165
 
 
166
        if (write_log) {
261
167
                mtr_log_reserve_and_write(mtr);
262
168
        }
263
169
 
 
170
        /* We first update the modification info to buffer pages, and only
 
171
        after that release the log mutex: this guarantees that when the log
 
172
        mutex is free, all buffer pages contain an up-to-date info of their
 
173
        modifications. This fact is used in making a checkpoint when we look
 
174
        at the oldest modification of any page in the buffer pool. It is also
 
175
        required when we insert modified buffer pages in to the flush list
 
176
        which must be sorted on oldest_modification. */
 
177
 
264
178
        mtr_memo_pop_all(mtr);
265
 
#endif /* !UNIV_HOTBACKUP */
266
 
 
267
 
        ut_d(mtr->state = MTR_COMMITTED);
 
179
 
 
180
        if (write_log) {
 
181
                log_release();
 
182
        }
 
183
 
 
184
#ifdef UNIV_DEBUG
 
185
        mtr->state = MTR_COMMITTED;
 
186
#endif
268
187
        dyn_array_free(&(mtr->memo));
269
188
        dyn_array_free(&(mtr->log));
270
189
}
271
190
 
272
 
#ifndef UNIV_HOTBACKUP
273
 
/**********************************************************//**
 
191
/**************************************************************
274
192
Releases the latches stored in an mtr memo down to a savepoint.
275
193
NOTE! The mtr must not have made changes to buffer pages after the
276
194
savepoint, as these can be handled only by mtr_commit. */
278
196
void
279
197
mtr_rollback_to_savepoint(
280
198
/*======================*/
281
 
        mtr_t*  mtr,            /*!< in: mtr */
282
 
        ulint   savepoint)      /*!< in: savepoint */
 
199
        mtr_t*  mtr,            /* in: mtr */
 
200
        ulint   savepoint)      /* in: savepoint */
283
201
{
284
202
        mtr_memo_slot_t* slot;
285
203
        dyn_array_t*    memo;
297
215
        while (offset > savepoint) {
298
216
                offset -= sizeof(mtr_memo_slot_t);
299
217
 
300
 
                slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
 
218
                slot = dyn_array_get_element(memo, offset);
301
219
 
302
220
                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
221
                mtr_memo_slot_release(mtr, slot);
308
222
        }
309
223
}
310
224
 
311
 
/***************************************************//**
 
225
/*******************************************************
312
226
Releases an object in the memo stack. */
313
227
UNIV_INTERN
314
228
void
315
229
mtr_memo_release(
316
230
/*=============*/
317
 
        mtr_t*  mtr,    /*!< in: mtr */
318
 
        void*   object, /*!< in: object */
319
 
        ulint   type)   /*!< in: object type: MTR_MEMO_S_LOCK, ... */
 
231
        mtr_t*  mtr,    /* in: mtr */
 
232
        void*   object, /* in: object */
 
233
        ulint   type)   /* in: object type: MTR_MEMO_S_LOCK, ... */
320
234
{
321
235
        mtr_memo_slot_t* slot;
322
236
        dyn_array_t*    memo;
330
244
 
331
245
        offset = dyn_array_get_data_size(memo);
332
246
 
333
 
        log_flush_order_mutex_enter();
334
247
        while (offset > 0) {
335
248
                offset -= sizeof(mtr_memo_slot_t);
336
249
 
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));
 
250
                slot = dyn_array_get_element(memo, offset);
 
251
 
 
252
                if ((object == slot->object) && (type == slot->type)) {
346
253
 
347
254
                        mtr_memo_slot_release(mtr, slot);
348
255
 
349
256
                        break;
350
257
                }
351
258
        }
352
 
        log_flush_order_mutex_exit();
353
259
}
354
 
#endif /* !UNIV_HOTBACKUP */
355
260
 
356
 
/********************************************************//**
357
 
Reads 1 - 4 bytes from a file page buffered in the buffer pool.
358
 
@return value read */
 
261
/************************************************************
 
262
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
359
263
UNIV_INTERN
360
264
ulint
361
265
mtr_read_ulint(
362
266
/*===========*/
363
 
        const byte*     ptr,    /*!< in: pointer from where to read */
364
 
        ulint           type,   /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
365
 
        mtr_t*          /*mtr __attribute__((unused))*/)
366
 
                                /*!< in: mini-transaction handle */
 
267
                                /* out: value read */
 
268
        const byte*     ptr,    /* in: pointer from where to read */
 
269
        ulint           type,   /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
 
270
        mtr_t*          mtr __attribute__((unused)))
 
271
                                /* in: mini-transaction handle */
367
272
{
368
273
        ut_ad(mtr->state == MTR_ACTIVE);
369
274
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
378
283
        }
379
284
}
380
285
 
 
286
/************************************************************
 
287
Reads 8 bytes from a file page buffered in the buffer pool. */
 
288
UNIV_INTERN
 
289
dulint
 
290
mtr_read_dulint(
 
291
/*============*/
 
292
                                /* out: value read */
 
293
        const byte*     ptr,    /* in: pointer from where to read */
 
294
        mtr_t*          mtr __attribute__((unused)))
 
295
                                /* in: mini-transaction handle */
 
296
{
 
297
        ut_ad(mtr->state == MTR_ACTIVE);
 
298
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
 
299
              || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
 
300
        return(mach_read_from_8(ptr));
 
301
}
 
302
 
381
303
#ifdef UNIV_DEBUG
382
 
# ifndef UNIV_HOTBACKUP
383
 
/**********************************************************//**
384
 
Checks if memo contains the given page.
385
 
@return TRUE if contains */
 
304
/**************************************************************
 
305
Checks if memo contains the given page. */
386
306
UNIV_INTERN
387
307
ibool
388
308
mtr_memo_contains_page(
389
309
/*===================*/
390
 
        mtr_t*          mtr,    /*!< in: mtr */
391
 
        const byte*     ptr,    /*!< in: pointer to buffer frame */
392
 
        ulint           type)   /*!< in: type of object */
 
310
                                /* out: TRUE if contains */
 
311
        mtr_t*          mtr,    /* in: mtr */
 
312
        const byte*     ptr,    /* in: pointer to buffer frame */
 
313
        ulint           type)   /* in: type of object */
393
314
{
394
 
        return(mtr_memo_contains(mtr, buf_block_align(ptr), type));
 
315
        ibool   ret;
 
316
 
 
317
        buf_pool_mutex_enter();
 
318
        ret = mtr_memo_contains(mtr, buf_block_align(ptr), type);
 
319
        buf_pool_mutex_exit();
 
320
        return(ret);
395
321
}
396
322
 
397
 
/*********************************************************//**
 
323
/*************************************************************
398
324
Prints info of an mtr handle. */
399
325
UNIV_INTERN
400
326
void
401
327
mtr_print(
402
328
/*======*/
403
 
        mtr_t*  mtr)    /*!< in: mtr */
 
329
        mtr_t*  mtr)    /* in: mtr */
404
330
{
405
331
        fprintf(stderr,
406
332
                "Mini-transaction handle: memo size %lu bytes"
408
334
                (ulong) dyn_array_get_data_size(&(mtr->memo)),
409
335
                (ulong) dyn_array_get_data_size(&(mtr->log)));
410
336
}
411
 
# endif /* !UNIV_HOTBACKUP */
412
337
#endif /* UNIV_DEBUG */