~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Stewart Smith
  • Author(s): Marko Mäkelä
  • Date: 2010-12-20 03:21:44 UTC
  • mto: (2021.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2022.
  • Revision ID: stewart@flamingspork.com-20101220032144-7aqh2z403u7d7bdp
Merge Revision revid:marko.makela@oracle.com-20101104131215-pfxnpidlrzd4krg0 from MySQL InnoDB

Original revid:marko.makela@oracle.com-20101104131215-pfxnpidlrzd4krg0

Original Authors: Marko Mäkelä <marko.makela@oracle.com>
Original commit message:
row_ins_index_entry(): Note that only CREATE INDEX sets foreign=FALSE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************
2
 
Mini-transaction buffer
3
 
 
4
 
(c) 1995 Innobase Oy
5
 
 
6
 
Created 11/26/1995 Heikki Tuuri
7
 
*******************************************************/
8
 
 
9
 
#include "mtr0mtr.h"
10
 
 
11
 
#ifdef UNIV_NONINL
12
 
#include "mtr0mtr.ic"
13
 
#endif
14
 
 
15
 
#include "buf0buf.h"
16
 
#include "page0types.h"
17
 
#include "mtr0log.h"
18
 
#include "log0log.h"
19
 
 
20
 
/*********************************************************************
21
 
Releases the item in the slot given. */
22
 
UNIV_INLINE
23
 
void
24
 
mtr_memo_slot_release(
25
 
/*==================*/
26
 
        mtr_t*                  mtr,    /* in: mtr */
27
 
        mtr_memo_slot_t*        slot)   /* in: memo slot */
28
 
{
29
 
        void*   object;
30
 
        ulint   type;
31
 
 
32
 
        ut_ad(mtr && slot);
33
 
 
34
 
        object = slot->object;
35
 
        type = slot->type;
36
 
 
37
 
        if (UNIV_LIKELY(object != NULL)) {
38
 
                if (type <= MTR_MEMO_BUF_FIX) {
39
 
                        buf_page_release((buf_block_t*)object, type, mtr);
40
 
                } else if (type == MTR_MEMO_S_LOCK) {
41
 
                        rw_lock_s_unlock((rw_lock_t*)object);
42
 
#ifdef UNIV_DEBUG
43
 
                } else if (type != MTR_MEMO_X_LOCK) {
44
 
                        ut_ad(type == MTR_MEMO_MODIFY);
45
 
                        ut_ad(mtr_memo_contains(mtr, object,
46
 
                                                MTR_MEMO_PAGE_X_FIX));
47
 
#endif /* UNIV_DEBUG */
48
 
                } else {
49
 
                        rw_lock_x_unlock((rw_lock_t*)object);
50
 
                }
51
 
        }
52
 
 
53
 
        slot->object = NULL;
54
 
}
55
 
 
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
64
 
void
65
 
mtr_memo_pop_all(
66
 
/*=============*/
67
 
        mtr_t*  mtr)    /* in: mtr */
68
 
{
69
 
        mtr_memo_slot_t* slot;
70
 
        dyn_array_t*    memo;
71
 
        ulint           offset;
72
 
 
73
 
        ut_ad(mtr);
74
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
75
 
        ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
76
 
                                             commit */
77
 
        memo = &(mtr->memo);
78
 
 
79
 
        offset = dyn_array_get_data_size(memo);
80
 
 
81
 
        while (offset > 0) {
82
 
                offset -= sizeof(mtr_memo_slot_t);
83
 
                slot = dyn_array_get_element(memo, offset);
84
 
 
85
 
                mtr_memo_slot_release(mtr, slot);
86
 
        }
87
 
}
88
 
 
89
 
/****************************************************************
90
 
Writes the contents of a mini-transaction log, if any, to the database log. */
91
 
static
92
 
void
93
 
mtr_log_reserve_and_write(
94
 
/*======================*/
95
 
        mtr_t*  mtr)    /* in: mtr */
96
 
{
97
 
        dyn_array_t*    mlog;
98
 
        dyn_block_t*    block;
99
 
        ulint           data_size;
100
 
        ibool           success;
101
 
        byte*           first_data;
102
 
 
103
 
        ut_ad(mtr);
104
 
 
105
 
        mlog = &(mtr->log);
106
 
 
107
 
        first_data = dyn_block_get_data(mlog);
108
 
 
109
 
        if (mtr->n_log_recs > 1) {
110
 
                mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE);
111
 
        } else {
112
 
                *first_data = (byte)((ulint)*first_data
113
 
                                     | MLOG_SINGLE_REC_FLAG);
114
 
        }
115
 
 
116
 
        if (mlog->heap == NULL) {
117
 
                mtr->end_lsn = log_reserve_and_write_fast(
118
 
                        first_data, dyn_block_get_used(mlog),
119
 
                        &(mtr->start_lsn), &success);
120
 
                if (success) {
121
 
 
122
 
                        return;
123
 
                }
124
 
        }
125
 
 
126
 
        data_size = dyn_array_get_data_size(mlog);
127
 
 
128
 
        /* Open the database log for log_write_low */
129
 
        mtr->start_lsn = log_reserve_and_open(data_size);
130
 
 
131
 
        if (mtr->log_mode == MTR_LOG_ALL) {
132
 
 
133
 
                block = mlog;
134
 
 
135
 
                while (block != NULL) {
136
 
                        log_write_low(dyn_block_get_data(block),
137
 
                                      dyn_block_get_used(block));
138
 
                        block = dyn_array_get_next_block(mlog, block);
139
 
                }
140
 
        } else {
141
 
                ut_ad(mtr->log_mode == MTR_LOG_NONE);
142
 
                /* Do nothing */
143
 
        }
144
 
 
145
 
        mtr->end_lsn = log_close();
146
 
}
147
 
 
148
 
/*******************************************************************
149
 
Commits a mini-transaction. */
150
 
UNIV_INTERN
151
 
void
152
 
mtr_commit(
153
 
/*=======*/
154
 
        mtr_t*  mtr)    /* in: mini-transaction */
155
 
{
156
 
        ibool           write_log;
157
 
 
158
 
        ut_ad(mtr);
159
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
160
 
        ut_ad(mtr->state == MTR_ACTIVE);
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) {
167
 
                mtr_log_reserve_and_write(mtr);
168
 
        }
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
 
 
178
 
        mtr_memo_pop_all(mtr);
179
 
 
180
 
        if (write_log) {
181
 
                log_release();
182
 
        }
183
 
 
184
 
#ifdef UNIV_DEBUG
185
 
        mtr->state = MTR_COMMITTED;
186
 
#endif
187
 
        dyn_array_free(&(mtr->memo));
188
 
        dyn_array_free(&(mtr->log));
189
 
}
190
 
 
191
 
/**************************************************************
192
 
Releases the latches stored in an mtr memo down to a savepoint.
193
 
NOTE! The mtr must not have made changes to buffer pages after the
194
 
savepoint, as these can be handled only by mtr_commit. */
195
 
UNIV_INTERN
196
 
void
197
 
mtr_rollback_to_savepoint(
198
 
/*======================*/
199
 
        mtr_t*  mtr,            /* in: mtr */
200
 
        ulint   savepoint)      /* in: savepoint */
201
 
{
202
 
        mtr_memo_slot_t* slot;
203
 
        dyn_array_t*    memo;
204
 
        ulint           offset;
205
 
 
206
 
        ut_ad(mtr);
207
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
208
 
        ut_ad(mtr->state == MTR_ACTIVE);
209
 
 
210
 
        memo = &(mtr->memo);
211
 
 
212
 
        offset = dyn_array_get_data_size(memo);
213
 
        ut_ad(offset >= savepoint);
214
 
 
215
 
        while (offset > savepoint) {
216
 
                offset -= sizeof(mtr_memo_slot_t);
217
 
 
218
 
                slot = dyn_array_get_element(memo, offset);
219
 
 
220
 
                ut_ad(slot->type != MTR_MEMO_MODIFY);
221
 
                mtr_memo_slot_release(mtr, slot);
222
 
        }
223
 
}
224
 
 
225
 
/*******************************************************
226
 
Releases an object in the memo stack. */
227
 
UNIV_INTERN
228
 
void
229
 
mtr_memo_release(
230
 
/*=============*/
231
 
        mtr_t*  mtr,    /* in: mtr */
232
 
        void*   object, /* in: object */
233
 
        ulint   type)   /* in: object type: MTR_MEMO_S_LOCK, ... */
234
 
{
235
 
        mtr_memo_slot_t* slot;
236
 
        dyn_array_t*    memo;
237
 
        ulint           offset;
238
 
 
239
 
        ut_ad(mtr);
240
 
        ut_ad(mtr->magic_n == MTR_MAGIC_N);
241
 
        ut_ad(mtr->state == MTR_ACTIVE);
242
 
 
243
 
        memo = &(mtr->memo);
244
 
 
245
 
        offset = dyn_array_get_data_size(memo);
246
 
 
247
 
        while (offset > 0) {
248
 
                offset -= sizeof(mtr_memo_slot_t);
249
 
 
250
 
                slot = dyn_array_get_element(memo, offset);
251
 
 
252
 
                if ((object == slot->object) && (type == slot->type)) {
253
 
 
254
 
                        mtr_memo_slot_release(mtr, slot);
255
 
 
256
 
                        break;
257
 
                }
258
 
        }
259
 
}
260
 
 
261
 
/************************************************************
262
 
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
263
 
UNIV_INTERN
264
 
ulint
265
 
mtr_read_ulint(
266
 
/*===========*/
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 */
272
 
{
273
 
        ut_ad(mtr->state == MTR_ACTIVE);
274
 
        ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_S_FIX)
275
 
              || mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
276
 
        if (type == MLOG_1BYTE) {
277
 
                return(mach_read_from_1(ptr));
278
 
        } else if (type == MLOG_2BYTES) {
279
 
                return(mach_read_from_2(ptr));
280
 
        } else {
281
 
                ut_ad(type == MLOG_4BYTES);
282
 
                return(mach_read_from_4(ptr));
283
 
        }
284
 
}
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
 
 
303
 
#ifdef UNIV_DEBUG
304
 
/**************************************************************
305
 
Checks if memo contains the given page. */
306
 
UNIV_INTERN
307
 
ibool
308
 
mtr_memo_contains_page(
309
 
/*===================*/
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 */
314
 
{
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);
321
 
}
322
 
 
323
 
/*************************************************************
324
 
Prints info of an mtr handle. */
325
 
UNIV_INTERN
326
 
void
327
 
mtr_print(
328
 
/*======*/
329
 
        mtr_t*  mtr)    /* in: mtr */
330
 
{
331
 
        fprintf(stderr,
332
 
                "Mini-transaction handle: memo size %lu bytes"
333
 
                " log size %lu bytes\n",
334
 
                (ulong) dyn_array_get_data_size(&(mtr->memo)),
335
 
                (ulong) dyn_array_get_data_size(&(mtr->log)));
336
 
}
337
 
#endif /* UNIV_DEBUG */