1
/******************************************************
2
Mini-transaction buffer
6
Created 11/26/1995 Heikki Tuuri
7
*******************************************************/
16
#include "page0types.h"
20
/*********************************************************************
21
Releases the item in the slot given. */
24
mtr_memo_slot_release(
25
/*==================*/
26
mtr_t* mtr, /* in: mtr */
27
mtr_memo_slot_t* slot) /* in: memo slot */
34
object = slot->object;
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);
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 */
49
rw_lock_x_unlock((rw_lock_t*)object);
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
67
mtr_t* mtr) /* in: mtr */
69
mtr_memo_slot_t* slot;
74
ut_ad(mtr->magic_n == MTR_MAGIC_N);
75
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
79
offset = dyn_array_get_data_size(memo);
82
offset -= sizeof(mtr_memo_slot_t);
83
slot = dyn_array_get_element(memo, offset);
85
mtr_memo_slot_release(mtr, slot);
89
/****************************************************************
90
Writes the contents of a mini-transaction log, if any, to the database log. */
93
mtr_log_reserve_and_write(
94
/*======================*/
95
mtr_t* mtr) /* in: mtr */
107
first_data = dyn_block_get_data(mlog);
109
if (mtr->n_log_recs > 1) {
110
mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE);
112
*first_data = (byte)((ulint)*first_data
113
| MLOG_SINGLE_REC_FLAG);
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);
126
data_size = dyn_array_get_data_size(mlog);
128
/* Open the database log for log_write_low */
129
mtr->start_lsn = log_reserve_and_open(data_size);
131
if (mtr->log_mode == MTR_LOG_ALL) {
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);
141
ut_ad(mtr->log_mode == MTR_LOG_NONE);
145
mtr->end_lsn = log_close();
148
/*******************************************************************
149
Commits a mini-transaction. */
154
mtr_t* mtr) /* in: mini-transaction */
159
ut_ad(mtr->magic_n == MTR_MAGIC_N);
160
ut_ad(mtr->state == MTR_ACTIVE);
162
mtr->state = MTR_COMMITTING;
164
write_log = mtr->modifications && mtr->n_log_recs;
167
mtr_log_reserve_and_write(mtr);
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. */
178
mtr_memo_pop_all(mtr);
185
mtr->state = MTR_COMMITTED;
187
dyn_array_free(&(mtr->memo));
188
dyn_array_free(&(mtr->log));
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. */
197
mtr_rollback_to_savepoint(
198
/*======================*/
199
mtr_t* mtr, /* in: mtr */
200
ulint savepoint) /* in: savepoint */
202
mtr_memo_slot_t* slot;
207
ut_ad(mtr->magic_n == MTR_MAGIC_N);
208
ut_ad(mtr->state == MTR_ACTIVE);
212
offset = dyn_array_get_data_size(memo);
213
ut_ad(offset >= savepoint);
215
while (offset > savepoint) {
216
offset -= sizeof(mtr_memo_slot_t);
218
slot = dyn_array_get_element(memo, offset);
220
ut_ad(slot->type != MTR_MEMO_MODIFY);
221
mtr_memo_slot_release(mtr, slot);
225
/*******************************************************
226
Releases an object in the memo stack. */
231
mtr_t* mtr, /* in: mtr */
232
void* object, /* in: object */
233
ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
235
mtr_memo_slot_t* slot;
240
ut_ad(mtr->magic_n == MTR_MAGIC_N);
241
ut_ad(mtr->state == MTR_ACTIVE);
245
offset = dyn_array_get_data_size(memo);
248
offset -= sizeof(mtr_memo_slot_t);
250
slot = dyn_array_get_element(memo, offset);
252
if ((object == slot->object) && (type == slot->type)) {
254
mtr_memo_slot_release(mtr, slot);
261
/************************************************************
262
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
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 */
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));
281
ut_ad(type == MLOG_4BYTES);
282
return(mach_read_from_4(ptr));
286
/************************************************************
287
Reads 8 bytes from a file page buffered in the buffer pool. */
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 */
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));
304
/**************************************************************
305
Checks if memo contains the given page. */
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 */
317
buf_pool_mutex_enter();
318
ret = mtr_memo_contains(mtr, buf_block_align(ptr), type);
319
buf_pool_mutex_exit();
323
/*************************************************************
324
Prints info of an mtr handle. */
329
mtr_t* mtr) /* in: mtr */
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)));
337
#endif /* UNIV_DEBUG */