~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Padraig O'Sullivan
  • Date: 2009-03-21 20:26:28 UTC
  • mto: (960.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 961.
  • Revision ID: osullivan.padraig@gmail.com-20090321202628-nh6qsi825m4d4av6
Removing the queues.[h,cc] files from the mysys directory. The only place
where they are needed now is in the MyISAM storage engine. Thus, I moved the
files there and updated the files in the MyISAM storage engine
appropriately.

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., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
 
16
 
 
17
*****************************************************************************/
 
18
 
 
19
/******************************************************
 
20
Mini-transaction buffer
 
21
 
 
22
Created 11/26/1995 Heikki Tuuri
 
23
*******************************************************/
 
24
 
 
25
#include "mtr0mtr.h"
 
26
 
 
27
#ifdef UNIV_NONINL
 
28
#include "mtr0mtr.ic"
 
29
#endif
 
30
 
 
31
#include "buf0buf.h"
 
32
#include "page0types.h"
 
33
#include "mtr0log.h"
 
34
#include "log0log.h"
 
35
 
 
36
/*********************************************************************
 
37
Releases the item in the slot given. */
 
38
UNIV_INLINE
 
39
void
 
40
mtr_memo_slot_release(
 
41
/*==================*/
 
42
        mtr_t*                  mtr,    /* in: mtr */
 
43
        mtr_memo_slot_t*        slot)   /* in: memo slot */
 
44
{
 
45
        void*   object;
 
46
        ulint   type;
 
47
 
 
48
        ut_ad(mtr && slot);
 
49
 
 
50
        object = slot->object;
 
51
        type = slot->type;
 
52
 
 
53
        if (UNIV_LIKELY(object != NULL)) {
 
54
                if (type <= MTR_MEMO_BUF_FIX) {
 
55
                        buf_page_release((buf_block_t*)object, type, mtr);
 
56
                } else if (type == MTR_MEMO_S_LOCK) {
 
57
                        rw_lock_s_unlock((rw_lock_t*)object);
 
58
#ifdef UNIV_DEBUG
 
59
                } else if (type != MTR_MEMO_X_LOCK) {
 
60
                        ut_ad(type == MTR_MEMO_MODIFY);
 
61
                        ut_ad(mtr_memo_contains(mtr, object,
 
62
                                                MTR_MEMO_PAGE_X_FIX));
 
63
#endif /* UNIV_DEBUG */
 
64
                } else {
 
65
                        rw_lock_x_unlock((rw_lock_t*)object);
 
66
                }
 
67
        }
 
68
 
 
69
        slot->object = NULL;
 
70
}
 
71
 
 
72
/**************************************************************
 
73
Releases the mlocks and other objects stored in an mtr memo. They are released
 
74
in the order opposite to which they were pushed to the memo. NOTE! It is
 
75
essential that the x-rw-lock on a modified buffer page is not released before
 
76
buf_page_note_modification is called for that page! Otherwise, some thread
 
77
might race to modify it, and the flush list sort order on lsn would be
 
78
destroyed. */
 
79
UNIV_INLINE
 
80
void
 
81
mtr_memo_pop_all(
 
82
/*=============*/
 
83
        mtr_t*  mtr)    /* in: mtr */
 
84
{
 
85
        mtr_memo_slot_t* slot;
 
86
        dyn_array_t*    memo;
 
87
        ulint           offset;
 
88
 
 
89
        ut_ad(mtr);
 
90
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
 
91
        ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
 
92
                                             commit */
 
93
        memo = &(mtr->memo);
 
94
 
 
95
        offset = dyn_array_get_data_size(memo);
 
96
 
 
97
        while (offset > 0) {
 
98
                offset -= sizeof(mtr_memo_slot_t);
 
99
                slot = dyn_array_get_element(memo, offset);
 
100
 
 
101
                mtr_memo_slot_release(mtr, slot);
 
102
        }
 
103
}
 
104
 
 
105
/****************************************************************
 
106
Writes the contents of a mini-transaction log, if any, to the database log. */
 
107
static
 
108
void
 
109
mtr_log_reserve_and_write(
 
110
/*======================*/
 
111
        mtr_t*  mtr)    /* in: mtr */
 
112
{
 
113
        dyn_array_t*    mlog;
 
114
        dyn_block_t*    block;
 
115
        ulint           data_size;
 
116
        ibool           success;
 
117
        byte*           first_data;
 
118
 
 
119
        ut_ad(mtr);
 
120
 
 
121
        mlog = &(mtr->log);
 
122
 
 
123
        first_data = dyn_block_get_data(mlog);
 
124
 
 
125
        if (mtr->n_log_recs > 1) {
 
126
                mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE);
 
127
        } else {
 
128
                *first_data = (byte)((ulint)*first_data
 
129
                                     | MLOG_SINGLE_REC_FLAG);
 
130
        }
 
131
 
 
132
        if (mlog->heap == NULL) {
 
133
                mtr->end_lsn = log_reserve_and_write_fast(
 
134
                        first_data, dyn_block_get_used(mlog),
 
135
                        &(mtr->start_lsn), &success);
 
136
                if (success) {
 
137
 
 
138
                        return;
 
139
                }
 
140
        }
 
141
 
 
142
        data_size = dyn_array_get_data_size(mlog);
 
143
 
 
144
        /* Open the database log for log_write_low */
 
145
        mtr->start_lsn = log_reserve_and_open(data_size);
 
146
 
 
147
        if (mtr->log_mode == MTR_LOG_ALL) {
 
148
 
 
149
                block = mlog;
 
150
 
 
151
                while (block != NULL) {
 
152
                        log_write_low(dyn_block_get_data(block),
 
153
                                      dyn_block_get_used(block));
 
154
                        block = dyn_array_get_next_block(mlog, block);
 
155
                }
 
156
        } else {
 
157
                ut_ad(mtr->log_mode == MTR_LOG_NONE);
 
158
                /* Do nothing */
 
159
        }
 
160
 
 
161
        mtr->end_lsn = log_close();
 
162
}
 
163
 
 
164
/*******************************************************************
 
165
Commits a mini-transaction. */
 
166
UNIV_INTERN
 
167
void
 
168
mtr_commit(
 
169
/*=======*/
 
170
        mtr_t*  mtr)    /* in: mini-transaction */
 
171
{
 
172
        ibool           write_log;
 
173
 
 
174
        ut_ad(mtr);
 
175
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
 
176
        ut_ad(mtr->state == MTR_ACTIVE);
 
177
        ut_d(mtr->state = MTR_COMMITTING);
 
178
 
 
179
        write_log = mtr->modifications && mtr->n_log_recs;
 
180
 
 
181
        if (write_log) {
 
182
                mtr_log_reserve_and_write(mtr);
 
183
        }
 
184
 
 
185
        /* We first update the modification info to buffer pages, and only
 
186
        after that release the log mutex: this guarantees that when the log
 
187
        mutex is free, all buffer pages contain an up-to-date info of their
 
188
        modifications. This fact is used in making a checkpoint when we look
 
189
        at the oldest modification of any page in the buffer pool. It is also
 
190
        required when we insert modified buffer pages in to the flush list
 
191
        which must be sorted on oldest_modification. */
 
192
 
 
193
        mtr_memo_pop_all(mtr);
 
194
 
 
195
        if (write_log) {
 
196
                log_release();
 
197
        }
 
198
 
 
199
        ut_d(mtr->state = MTR_COMMITTED);
 
200
        dyn_array_free(&(mtr->memo));
 
201
        dyn_array_free(&(mtr->log));
 
202
}
 
203
 
 
204
/**************************************************************
 
205
Releases the latches stored in an mtr memo down to a savepoint.
 
206
NOTE! The mtr must not have made changes to buffer pages after the
 
207
savepoint, as these can be handled only by mtr_commit. */
 
208
UNIV_INTERN
 
209
void
 
210
mtr_rollback_to_savepoint(
 
211
/*======================*/
 
212
        mtr_t*  mtr,            /* in: mtr */
 
213
        ulint   savepoint)      /* in: savepoint */
 
214
{
 
215
        mtr_memo_slot_t* slot;
 
216
        dyn_array_t*    memo;
 
217
        ulint           offset;
 
218
 
 
219
        ut_ad(mtr);
 
220
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
 
221
        ut_ad(mtr->state == MTR_ACTIVE);
 
222
 
 
223
        memo = &(mtr->memo);
 
224
 
 
225
        offset = dyn_array_get_data_size(memo);
 
226
        ut_ad(offset >= savepoint);
 
227
 
 
228
        while (offset > savepoint) {
 
229
                offset -= sizeof(mtr_memo_slot_t);
 
230
 
 
231
                slot = dyn_array_get_element(memo, offset);
 
232
 
 
233
                ut_ad(slot->type != MTR_MEMO_MODIFY);
 
234
                mtr_memo_slot_release(mtr, slot);
 
235
        }
 
236
}
 
237
 
 
238
/*******************************************************
 
239
Releases an object in the memo stack. */
 
240
UNIV_INTERN
 
241
void
 
242
mtr_memo_release(
 
243
/*=============*/
 
244
        mtr_t*  mtr,    /* in: mtr */
 
245
        void*   object, /* in: object */
 
246
        ulint   type)   /* in: object type: MTR_MEMO_S_LOCK, ... */
 
247
{
 
248
        mtr_memo_slot_t* slot;
 
249
        dyn_array_t*    memo;
 
250
        ulint           offset;
 
251
 
 
252
        ut_ad(mtr);
 
253
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
 
254
        ut_ad(mtr->state == MTR_ACTIVE);
 
255
 
 
256
        memo = &(mtr->memo);
 
257
 
 
258
        offset = dyn_array_get_data_size(memo);
 
259
 
 
260
        while (offset > 0) {
 
261
                offset -= sizeof(mtr_memo_slot_t);
 
262
 
 
263
                slot = dyn_array_get_element(memo, offset);
 
264
 
 
265
                if ((object == slot->object) && (type == slot->type)) {
 
266
 
 
267
                        mtr_memo_slot_release(mtr, slot);
 
268
 
 
269
                        break;
 
270
                }
 
271
        }
 
272
}
 
273
 
 
274
/************************************************************
 
275
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
 
276
UNIV_INTERN
 
277
ulint
 
278
mtr_read_ulint(
 
279
/*===========*/
 
280
                                /* out: value read */
 
281
        const byte*     ptr,    /* in: pointer from where to read */
 
282
        ulint           type,   /* in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
 
283
        mtr_t*          mtr __attribute__((unused)))
 
284
                                /* in: mini-transaction handle */
 
285
{
 
286
        ut_ad(mtr->state == MTR_ACTIVE);
 
287
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
 
288
              || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
 
289
        if (type == MLOG_1BYTE) {
 
290
                return(mach_read_from_1(ptr));
 
291
        } else if (type == MLOG_2BYTES) {
 
292
                return(mach_read_from_2(ptr));
 
293
        } else {
 
294
                ut_ad(type == MLOG_4BYTES);
 
295
                return(mach_read_from_4(ptr));
 
296
        }
 
297
}
 
298
 
 
299
/************************************************************
 
300
Reads 8 bytes from a file page buffered in the buffer pool. */
 
301
UNIV_INTERN
 
302
dulint
 
303
mtr_read_dulint(
 
304
/*============*/
 
305
                                /* out: value read */
 
306
        const byte*     ptr,    /* in: pointer from where to read */
 
307
        mtr_t*          mtr __attribute__((unused)))
 
308
                                /* in: mini-transaction handle */
 
309
{
 
310
        ut_ad(mtr->state == MTR_ACTIVE);
 
311
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
 
312
              || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
 
313
        return(mach_read_from_8(ptr));
 
314
}
 
315
 
 
316
#ifdef UNIV_DEBUG
 
317
/**************************************************************
 
318
Checks if memo contains the given page. */
 
319
UNIV_INTERN
 
320
ibool
 
321
mtr_memo_contains_page(
 
322
/*===================*/
 
323
                                /* out: TRUE if contains */
 
324
        mtr_t*          mtr,    /* in: mtr */
 
325
        const byte*     ptr,    /* in: pointer to buffer frame */
 
326
        ulint           type)   /* in: type of object */
 
327
{
 
328
        return(mtr_memo_contains(mtr, buf_block_align(ptr), type));
 
329
}
 
330
 
 
331
/*************************************************************
 
332
Prints info of an mtr handle. */
 
333
UNIV_INTERN
 
334
void
 
335
mtr_print(
 
336
/*======*/
 
337
        mtr_t*  mtr)    /* in: mtr */
 
338
{
 
339
        fprintf(stderr,
 
340
                "Mini-transaction handle: memo size %lu bytes"
 
341
                " log size %lu bytes\n",
 
342
                (ulong) dyn_array_get_data_size(&(mtr->memo)),
 
343
                (ulong) dyn_array_get_data_size(&(mtr->log)));
 
344
}
 
345
#endif /* UNIV_DEBUG */