1
/******************************************************
2
Mini-transaction buffer
6
Created 11/26/1995 Heikki Tuuri
7
*******************************************************/
16
#include "page0types.h"
20
/*******************************************************************
21
Starts a mini-transaction and creates a mini-transaction handle
22
and buffer in the memory buffer given by the caller. */
27
/* out: mtr buffer which also acts as
29
mtr_t* mtr) /* in: memory buffer for the mtr buffer */
31
return(mtr_start(mtr));
34
/*********************************************************************
35
Releases the item in the slot given. */
38
mtr_memo_slot_release(
39
/*==================*/
40
mtr_t* mtr, /* in: mtr */
41
mtr_memo_slot_t* slot) /* in: memo slot */
48
object = slot->object;
51
if (UNIV_LIKELY(object != NULL)) {
52
if (type <= MTR_MEMO_BUF_FIX) {
53
buf_page_release((buf_block_t*)object, type, mtr);
54
} else if (type == MTR_MEMO_S_LOCK) {
55
rw_lock_s_unlock((rw_lock_t*)object);
57
} else if (type == MTR_MEMO_X_LOCK) {
58
rw_lock_x_unlock((rw_lock_t*)object);
60
ut_ad(type == MTR_MEMO_MODIFY);
61
ut_ad(mtr_memo_contains(mtr, object,
62
MTR_MEMO_PAGE_X_FIX));
65
rw_lock_x_unlock((rw_lock_t*)object);
73
/**************************************************************
74
Releases the mlocks and other objects stored in an mtr memo. They are released
75
in the order opposite to which they were pushed to the memo. NOTE! It is
76
essential that the x-rw-lock on a modified buffer page is not released before
77
buf_page_note_modification is called for that page! Otherwise, some thread
78
might race to modify it, and the flush list sort order on lsn would be
84
mtr_t* mtr) /* in: mtr */
86
mtr_memo_slot_t* slot;
91
ut_ad(mtr->magic_n == MTR_MAGIC_N);
92
ut_ad(mtr->state == MTR_COMMITTING); /* Currently only used in
96
offset = dyn_array_get_data_size(memo);
99
offset -= sizeof(mtr_memo_slot_t);
100
slot = dyn_array_get_element(memo, offset);
102
mtr_memo_slot_release(mtr, slot);
106
/****************************************************************
107
Writes the contents of a mini-transaction log, if any, to the database log. */
110
mtr_log_reserve_and_write(
111
/*======================*/
112
mtr_t* mtr) /* in: mtr */
124
first_data = dyn_block_get_data(mlog);
126
if (mtr->n_log_recs > 1) {
127
mlog_catenate_ulint(mtr, MLOG_MULTI_REC_END, MLOG_1BYTE);
129
*first_data = (byte)((ulint)*first_data
130
| MLOG_SINGLE_REC_FLAG);
133
if (mlog->heap == NULL) {
134
mtr->end_lsn = log_reserve_and_write_fast(
135
first_data, dyn_block_get_used(mlog),
136
&(mtr->start_lsn), &success);
143
data_size = dyn_array_get_data_size(mlog);
145
/* Open the database log for log_write_low */
146
mtr->start_lsn = log_reserve_and_open(data_size);
148
if (mtr->log_mode == MTR_LOG_ALL) {
152
while (block != NULL) {
153
log_write_low(dyn_block_get_data(block),
154
dyn_block_get_used(block));
155
block = dyn_array_get_next_block(mlog, block);
158
ut_ad(mtr->log_mode == MTR_LOG_NONE);
162
mtr->end_lsn = log_close();
165
/*******************************************************************
166
Commits a mini-transaction. */
171
mtr_t* mtr) /* in: mini-transaction */
174
ut_ad(mtr->magic_n == MTR_MAGIC_N);
175
ut_ad(mtr->state == MTR_ACTIVE);
177
mtr->state = MTR_COMMITTING;
179
if (mtr->modifications) {
180
mtr_log_reserve_and_write(mtr);
183
/* We first update the modification info to buffer pages, and only
184
after that release the log mutex: this guarantees that when the log
185
mutex is free, all buffer pages contain an up-to-date info of their
186
modifications. This fact is used in making a checkpoint when we look
187
at the oldest modification of any page in the buffer pool. It is also
188
required when we insert modified buffer pages in to the flush list
189
which must be sorted on oldest_modification. */
191
mtr_memo_pop_all(mtr);
193
if (mtr->modifications) {
198
mtr->state = MTR_COMMITTED;
200
dyn_array_free(&(mtr->memo));
201
dyn_array_free(&(mtr->log));
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. */
210
mtr_rollback_to_savepoint(
211
/*======================*/
212
mtr_t* mtr, /* in: mtr */
213
ulint savepoint) /* in: savepoint */
215
mtr_memo_slot_t* slot;
220
ut_ad(mtr->magic_n == MTR_MAGIC_N);
221
ut_ad(mtr->state == MTR_ACTIVE);
225
offset = dyn_array_get_data_size(memo);
226
ut_ad(offset >= savepoint);
228
while (offset > savepoint) {
229
offset -= sizeof(mtr_memo_slot_t);
231
slot = dyn_array_get_element(memo, offset);
233
ut_ad(slot->type != MTR_MEMO_MODIFY);
234
mtr_memo_slot_release(mtr, slot);
238
/*******************************************************
239
Releases an object in the memo stack. */
244
mtr_t* mtr, /* in: mtr */
245
void* object, /* in: object */
246
ulint type) /* in: object type: MTR_MEMO_S_LOCK, ... */
248
mtr_memo_slot_t* slot;
253
ut_ad(mtr->magic_n == MTR_MAGIC_N);
254
ut_ad(mtr->state == MTR_ACTIVE);
258
offset = dyn_array_get_data_size(memo);
261
offset -= sizeof(mtr_memo_slot_t);
263
slot = dyn_array_get_element(memo, offset);
265
if ((object == slot->object) && (type == slot->type)) {
267
mtr_memo_slot_release(mtr, slot);
274
/************************************************************
275
Reads 1 - 4 bytes from a file page buffered in the buffer pool. */
280
/* out: value read */
281
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 */
286
ut_ad(mtr->state == MTR_ACTIVE);
287
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
289
|| mtr_memo_contains(mtr, buf_block_align(ptr),
290
MTR_MEMO_PAGE_X_FIX));
291
if (type == MLOG_1BYTE) {
292
return(mach_read_from_1(ptr));
293
} else if (type == MLOG_2BYTES) {
294
return(mach_read_from_2(ptr));
296
ut_ad(type == MLOG_4BYTES);
297
return(mach_read_from_4(ptr));
301
/************************************************************
302
Reads 8 bytes from a file page buffered in the buffer pool. */
307
/* out: value read */
308
byte* ptr, /* in: pointer from where to read */
309
mtr_t* mtr __attribute__((unused)))
310
/* in: mini-transaction handle */
312
ut_ad(mtr->state == MTR_ACTIVE);
314
ut_ad(mtr_memo_contains(mtr, buf_block_align(ptr),
316
|| mtr_memo_contains(mtr, buf_block_align(ptr),
317
MTR_MEMO_PAGE_X_FIX));
318
return(mach_read_from_8(ptr));
322
/*************************************************************
323
Prints info of an mtr handle. */
328
mtr_t* mtr) /* in: mtr */
331
"Mini-transaction handle: memo size %lu bytes"
332
" log size %lu bytes\n",
333
(ulong) dyn_array_get_data_size(&(mtr->memo)),
334
(ulong) dyn_array_get_data_size(&(mtr->log)));
336
#endif /* UNIV_DEBUG */