1 /*****************************************************************************
3 Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
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.
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.
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.,
15 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *****************************************************************************/
19 /**************************************************//**
20 @file include/mtr0log.ic
21 Mini-transaction logging routines
23 Created 12/7/1995 Heikki Tuuri
24 *******************************************************/
26 #include "mach0data.h"
29 #include "fsp0types.h"
32 /********************************************************//**
33 Opens a buffer to mlog. It must be closed with mlog_close.
34 @return buffer, NULL if log mode MTR_LOG_NONE */
39 mtr_t* mtr, /*!< in: mtr */
40 ulint size) /*!< in: buffer size in bytes; MUST be
41 smaller than DYN_ARRAY_DATA_SIZE! */
45 mtr->modifications = TRUE;
47 if (mtr_get_log_mode(mtr) == MTR_LOG_NONE) {
54 return(dyn_array_open(mlog, size));
57 /********************************************************//**
58 Closes a buffer opened to mlog. */
63 mtr_t* mtr, /*!< in: mtr */
64 byte* ptr) /*!< in: buffer space from ptr up was not used */
68 ut_ad(mtr_get_log_mode(mtr) != MTR_LOG_NONE);
72 dyn_array_close(mlog, ptr);
75 #ifndef UNIV_HOTBACKUP
76 /********************************************************//**
77 Catenates 1 - 4 bytes to the mtr log. The value is not compressed. */
82 mtr_t* mtr, /*!< in: mtr */
83 ulint val, /*!< in: value to write */
84 ulint type) /*!< in: MLOG_1BYTE, MLOG_2BYTES, MLOG_4BYTES */
89 if (mtr_get_log_mode(mtr) == MTR_LOG_NONE) {
97 # error "MLOG_1BYTE != 1"
100 # error "MLOG_2BYTES != 2"
103 # error "MLOG_4BYTES != 4"
106 # error "MLOG_8BYTES != 8"
108 ptr = (byte*) dyn_array_push(mlog, type);
110 if (type == MLOG_4BYTES) {
111 mach_write_to_4(ptr, val);
112 } else if (type == MLOG_2BYTES) {
113 mach_write_to_2(ptr, val);
115 ut_ad(type == MLOG_1BYTE);
116 mach_write_to_1(ptr, val);
120 /********************************************************//**
121 Catenates a compressed ulint to mlog. */
124 mlog_catenate_ulint_compressed(
125 /*===========================*/
126 mtr_t* mtr, /*!< in: mtr */
127 ulint val) /*!< in: value to write */
131 log_ptr = mlog_open(mtr, 10);
133 /* If no logging is requested, we may return now */
134 if (log_ptr == NULL) {
139 log_ptr += mach_write_compressed(log_ptr, val);
141 mlog_close(mtr, log_ptr);
144 /********************************************************//**
145 Catenates a compressed dulint to mlog. */
148 mlog_catenate_dulint_compressed(
149 /*============================*/
150 mtr_t* mtr, /*!< in: mtr */
151 dulint val) /*!< in: value to write */
155 log_ptr = mlog_open(mtr, 15);
157 /* If no logging is requested, we may return now */
158 if (log_ptr == NULL) {
163 log_ptr += mach_dulint_write_compressed(log_ptr, val);
165 mlog_close(mtr, log_ptr);
168 /********************************************************//**
169 Writes the initial part of a log record (3..11 bytes).
170 If the implementation of this function is changed, all
171 size parameters to mlog_open() should be adjusted accordingly!
172 @return new value of log_ptr */
175 mlog_write_initial_log_record_fast(
176 /*===============================*/
177 const byte* ptr, /*!< in: pointer to (inside) a buffer
178 frame holding the file page where
179 modification is made */
180 byte type, /*!< in: log item type: MLOG_1BYTE, ... */
181 byte* log_ptr,/*!< in: pointer to mtr log which has
183 mtr_t* mtr) /*!< in: mtr */
192 ut_ad(mtr_memo_contains_page(mtr, ptr, MTR_MEMO_PAGE_X_FIX));
193 ut_ad(type <= MLOG_BIGGEST_TYPE);
194 ut_ad(ptr && log_ptr);
196 page = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
197 space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
198 offset = mach_read_from_4(page + FIL_PAGE_OFFSET);
200 /* check whether the page is in the doublewrite buffer;
201 the doublewrite buffer is located in pages
202 FSP_EXTENT_SIZE, ..., 3 * FSP_EXTENT_SIZE - 1 in the
204 if (space == TRX_SYS_SPACE
205 && offset >= FSP_EXTENT_SIZE && offset < 3 * FSP_EXTENT_SIZE) {
206 if (trx_doublewrite_buf_is_being_created) {
207 /* Do nothing: we only come to this branch in an
208 InnoDB database creation. We do not redo log
209 anything for the doublewrite buffer pages. */
213 "Error: trying to redo log a record of type "
214 "%d on page %lu of space %lu in the "
215 "doublewrite buffer, continuing anyway.\n"
216 "Please post a bug report to "
218 type, offset, space);
222 mach_write_to_1(log_ptr, type);
224 log_ptr += mach_write_compressed(log_ptr, space);
225 log_ptr += mach_write_compressed(log_ptr, offset);
229 #ifdef UNIV_LOG_DEBUG
231 "Adding to mtr log record type %lu space %lu page no %lu\n",
232 (ulong) type, space, offset);
236 /* We now assume that all x-latched pages have been modified! */
237 block = (buf_block_t*) buf_block_align(ptr);
239 if (!mtr_memo_contains(mtr, block, MTR_MEMO_MODIFY)) {
241 mtr_memo_push(mtr, block, MTR_MEMO_MODIFY);
247 /********************************************************//**
248 Writes a log record about an .ibd file create/delete/rename.
249 @return new value of log_ptr */
252 mlog_write_initial_log_record_for_file_op(
253 /*======================================*/
254 ulint type, /*!< in: MLOG_FILE_CREATE, MLOG_FILE_DELETE, or
256 ulint space_id,/*!< in: space id, if applicable */
257 ulint page_no,/*!< in: page number (not relevant currently) */
258 byte* log_ptr,/*!< in: pointer to mtr log which has been opened */
259 mtr_t* mtr) /*!< in: mtr */
263 mach_write_to_1(log_ptr, type);
266 /* We write dummy space id and page number */
267 log_ptr += mach_write_compressed(log_ptr, space_id);
268 log_ptr += mach_write_compressed(log_ptr, page_no);
274 #endif /* !UNIV_HOTBACKUP */