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., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/log0log.ic
23
Created 12/9/1995 Heikki Tuuri
24
*******************************************************/
27
#include "mach0data.h"
30
/******************************************************//**
31
Checks by parsing that the catenated log segment for a single mtr is
37
byte* buf, /*!< in: pointer to the start of
38
the log segment in the
39
log_sys->buf log buffer */
40
ulint len, /*!< in: segment length in bytes */
41
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
43
/************************************************************//**
44
Gets a log block flush bit.
45
@return TRUE if this block was the first to be written in a log flush */
48
log_block_get_flush_bit(
49
/*====================*/
50
const byte* log_block) /*!< in: log block */
52
if (LOG_BLOCK_FLUSH_BIT_MASK
53
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
61
/************************************************************//**
62
Sets the log block flush bit. */
65
log_block_set_flush_bit(
66
/*====================*/
67
byte* log_block, /*!< in/out: log block */
68
ibool val) /*!< in: value to set */
72
field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
75
field = field | LOG_BLOCK_FLUSH_BIT_MASK;
77
field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
80
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
83
/************************************************************//**
84
Gets a log block number stored in the header.
85
@return log block number stored in the block header */
90
const byte* log_block) /*!< in: log block */
92
return(~LOG_BLOCK_FLUSH_BIT_MASK
93
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
96
/************************************************************//**
97
Sets the log block number stored in the header; NOTE that this must be set
98
before the flush bit! */
101
log_block_set_hdr_no(
102
/*=================*/
103
byte* log_block, /*!< in/out: log block */
104
ulint n) /*!< in: log block number: must be > 0 and
105
< LOG_BLOCK_FLUSH_BIT_MASK */
108
ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
110
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
113
/************************************************************//**
114
Gets a log block data length.
115
@return log block data length measured as a byte offset from the block start */
118
log_block_get_data_len(
119
/*===================*/
120
const byte* log_block) /*!< in: log block */
122
return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
125
/************************************************************//**
126
Sets the log block data length. */
129
log_block_set_data_len(
130
/*===================*/
131
byte* log_block, /*!< in/out: log block */
132
ulint len) /*!< in: data length */
134
mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
137
/************************************************************//**
138
Gets a log block first mtr log record group offset.
139
@return first mtr log record group byte offset from the block start, 0
143
log_block_get_first_rec_group(
144
/*==========================*/
145
const byte* log_block) /*!< in: log block */
147
return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
150
/************************************************************//**
151
Sets the log block first mtr log record group offset. */
154
log_block_set_first_rec_group(
155
/*==========================*/
156
byte* log_block, /*!< in/out: log block */
157
ulint offset) /*!< in: offset, 0 if none */
159
mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
162
/************************************************************//**
163
Gets a log block checkpoint number field (4 lowest bytes).
164
@return checkpoint no (4 lowest bytes) */
167
log_block_get_checkpoint_no(
168
/*========================*/
169
const byte* log_block) /*!< in: log block */
171
return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
174
/************************************************************//**
175
Sets a log block checkpoint number field (4 lowest bytes). */
178
log_block_set_checkpoint_no(
179
/*========================*/
180
byte* log_block, /*!< in/out: log block */
181
ib_uint64_t no) /*!< in: checkpoint no */
183
mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
186
/************************************************************//**
187
Converts a lsn to a log block number.
188
@return log block number, it is > 0 and <= 1G */
191
log_block_convert_lsn_to_no(
192
/*========================*/
193
ib_uint64_t lsn) /*!< in: lsn of a byte within the block */
195
return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
198
/************************************************************//**
199
Calculates the checksum for a log block.
203
log_block_calc_checksum(
204
/*====================*/
205
const byte* block) /*!< in: log block */
214
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
215
ulint b = (ulint) block[i];
228
/************************************************************//**
229
Gets a log block checksum field value.
233
log_block_get_checksum(
234
/*===================*/
235
const byte* log_block) /*!< in: log block */
237
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
238
- LOG_BLOCK_CHECKSUM));
241
/************************************************************//**
242
Sets a log block checksum field value. */
245
log_block_set_checksum(
246
/*===================*/
247
byte* log_block, /*!< in/out: log block */
248
ulint checksum) /*!< in: checksum */
250
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
251
- LOG_BLOCK_CHECKSUM,
255
/************************************************************//**
256
Initializes a log block in the log buffer. */
261
byte* log_block, /*!< in: pointer to the log buffer */
262
ib_uint64_t lsn) /*!< in: lsn within the log block */
266
ut_ad(mutex_own(&(log_sys->mutex)));
268
no = log_block_convert_lsn_to_no(lsn);
270
log_block_set_hdr_no(log_block, no);
272
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
273
log_block_set_first_rec_group(log_block, 0);
276
/************************************************************//**
277
Initializes a log block in the log buffer in the old format, where there
278
was no checksum yet. */
281
log_block_init_in_old_format(
282
/*=========================*/
283
byte* log_block, /*!< in: pointer to the log buffer */
284
ib_uint64_t lsn) /*!< in: lsn within the log block */
288
ut_ad(mutex_own(&(log_sys->mutex)));
290
no = log_block_convert_lsn_to_no(lsn);
292
log_block_set_hdr_no(log_block, no);
293
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
294
- LOG_BLOCK_CHECKSUM, no);
295
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
296
log_block_set_first_rec_group(log_block, 0);
299
#ifndef UNIV_HOTBACKUP
300
/************************************************************//**
301
Writes to the log the string given. The log must be released with
303
@return end lsn of the log record, zero if did not succeed */
306
log_reserve_and_write_fast(
307
/*=======================*/
308
byte* str, /*!< in: string */
309
ulint len, /*!< in: string length */
310
ib_uint64_t* start_lsn,/*!< out: start lsn of the log record */
311
ibool* success)/*!< out: TRUE if success */
313
log_t* log = log_sys;
319
mutex_enter(&(log->mutex));
321
data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
323
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
325
/* The string does not fit within the current log block
326
or the log block would become full */
330
mutex_exit(&(log->mutex));
335
*start_lsn = log->lsn;
337
ut_memcpy(log->buf + log->buf_free, str, len);
339
log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
340
OS_FILE_LOG_BLOCK_SIZE),
342
#ifdef UNIV_LOG_DEBUG
343
log->old_buf_free = log->buf_free;
344
log->old_lsn = log->lsn;
346
log->buf_free += len;
348
ut_ad(log->buf_free <= log->buf_size);
350
lsn = log->lsn += len;
352
#ifdef UNIV_LOG_DEBUG
353
log_check_log_recs(log->buf + log->old_buf_free,
354
log->buf_free - log->old_buf_free, log->old_lsn);
359
/***********************************************************************//**
360
Releases the log mutex. */
366
mutex_exit(&(log_sys->mutex));
369
/************************************************************//**
370
Gets the current lsn.
371
@return current lsn */
379
mutex_enter(&(log_sys->mutex));
383
mutex_exit(&(log_sys->mutex));
388
/****************************************************************
389
Gets the log group capacity. It is OK to read the value without
390
holding log_sys->mutex because it is constant.
391
@return log group capacity */
394
log_get_capacity(void)
395
/*==================*/
397
return(log_sys->log_group_capacity);
400
/***********************************************************************//**
401
Checks if there is need for a log buffer flush or a new checkpoint, and does
402
this if yes. Any database operation should call this when it has modified
403
more than about 4 pages. NOTE that this function may only be called when the
404
OS thread owns no synchronization objects except the dictionary mutex. */
410
/* ut_ad(sync_thread_levels_empty()); */
412
if (log_sys->check_flush_or_checkpoint) {
417
#endif /* !UNIV_HOTBACKUP */