1
1
/*****************************************************************************
3
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
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
57
#endif /* UNIV_DEBUG */
59
53
object = slot->object;
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);
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
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
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);
107
104
mtr_memo_slot_release(mtr, slot);
111
/*****************************************************************//**
112
Releases the item in the slot given. */
115
mtr_memo_slot_note_modification(
116
/*============================*/
117
mtr_t* mtr, /*!< in: mtr */
118
mtr_memo_slot_t* slot) /*!< in: memo slot */
121
ut_ad(mtr->magic_n == MTR_MAGIC_N);
122
ut_ad(mtr->modifications);
124
if (slot->object != NULL && slot->type == MTR_MEMO_PAGE_X_FIX) {
125
buf_block_t* block = (buf_block_t*) slot->object;
128
ut_ad(log_flush_order_mutex_own());
129
#endif /* UNIV_DEBUG */
130
buf_flush_note_modification(block, mtr);
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. */
143
mtr_memo_note_modifications(
144
/*========================*/
145
mtr_t* mtr) /*!< in: mtr */
151
ut_ad(mtr->magic_n == MTR_MAGIC_N);
152
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
156
offset = dyn_array_get_data_size(memo);
159
mtr_memo_slot_t* slot;
161
offset -= sizeof(mtr_memo_slot_t);
162
slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
164
mtr_memo_slot_note_modification(mtr, slot);
168
108
/************************************************************//**
169
109
Writes the contents of a mini-transaction log, if any, to the database log. */
225
163
mtr->end_lsn = log_close();
228
log_flush_order_mutex_enter();
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. */
235
if (mtr->modifications) {
236
mtr_memo_note_modifications(mtr);
239
log_flush_order_mutex_exit();
241
165
#endif /* !UNIV_HOTBACKUP */
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;
260
if (mtr->modifications && mtr->n_log_recs) {
261
190
mtr_log_reserve_and_write(mtr);
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. */
264
201
mtr_memo_pop_all(mtr);
265
206
#endif /* !UNIV_HOTBACKUP */
267
208
ut_d(mtr->state = MTR_COMMITTED);
297
238
while (offset > savepoint) {
298
239
offset -= sizeof(mtr_memo_slot_t);
300
slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
241
slot = dyn_array_get_element(memo, offset);
302
243
ut_ad(slot->type != MTR_MEMO_MODIFY);
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);
331
268
offset = dyn_array_get_data_size(memo);
333
log_flush_order_mutex_enter();
334
270
while (offset > 0) {
335
271
offset -= sizeof(mtr_memo_slot_t);
337
slot = static_cast<mtr_memo_slot_t *>(dyn_array_get_element(memo, offset));
339
if (object == slot->object && type == slot->type) {
341
/* We cannot release a page that has been written
342
to in the middle of a mini-transaction. */
344
ut_ad(!(mtr->modifications
345
&& slot->type == MTR_MEMO_PAGE_X_FIX));
273
slot = dyn_array_get_element(memo, offset);
275
if ((object == slot->object) && (type == slot->type)) {
347
277
mtr_memo_slot_release(mtr, slot);
352
log_flush_order_mutex_exit();
354
283
#endif /* !UNIV_HOTBACKUP */
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 */
368
297
ut_ad(mtr->state == MTR_ACTIVE);
310
/********************************************************//**
311
Reads 8 bytes from a file page buffered in the buffer pool.
312
@return value read */
317
const byte* ptr, /*!< in: pointer from where to read */
318
mtr_t* mtr __attribute__((unused)))
319
/*!< in: mini-transaction handle */
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));
381
327
#ifdef UNIV_DEBUG
382
328
# ifndef UNIV_HOTBACKUP
383
329
/**********************************************************//**