1
/*****************************************************************************
3
Copyright (C) 1995, 2010, 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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/log0log.ic
23
Created 12/9/1995 Heikki Tuuri
24
*******************************************************/
27
#include "mach0data.h"
31
/******************************************************//**
32
Checks by parsing that the catenated log segment for a single mtr is
38
const byte* buf, /*!< in: pointer to the start of
39
the log segment in the
40
log_sys->buf log buffer */
41
ulint len, /*!< in: segment length in bytes */
42
ib_uint64_t buf_start_lsn); /*!< in: buffer start lsn */
43
#endif /* UNIV_LOG_DEBUG */
45
/************************************************************//**
46
Gets a log block flush bit.
47
@return TRUE if this block was the first to be written in a log flush */
50
log_block_get_flush_bit(
51
/*====================*/
52
const byte* log_block) /*!< in: log block */
54
if (LOG_BLOCK_FLUSH_BIT_MASK
55
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
63
/************************************************************//**
64
Sets the log block flush bit. */
67
log_block_set_flush_bit(
68
/*====================*/
69
byte* log_block, /*!< in/out: log block */
70
ibool val) /*!< in: value to set */
74
field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
77
field = field | LOG_BLOCK_FLUSH_BIT_MASK;
79
field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
82
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
85
/************************************************************//**
86
Gets a log block number stored in the header.
87
@return log block number stored in the block header */
92
const byte* log_block) /*!< in: log block */
94
return(~LOG_BLOCK_FLUSH_BIT_MASK
95
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
98
/************************************************************//**
99
Sets the log block number stored in the header; NOTE that this must be set
100
before the flush bit! */
103
log_block_set_hdr_no(
104
/*=================*/
105
byte* log_block, /*!< in/out: log block */
106
ulint n) /*!< in: log block number: must be > 0 and
107
< LOG_BLOCK_FLUSH_BIT_MASK */
110
ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
112
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
115
/************************************************************//**
116
Gets a log block data length.
117
@return log block data length measured as a byte offset from the block start */
120
log_block_get_data_len(
121
/*===================*/
122
const byte* log_block) /*!< in: log block */
124
return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
127
/************************************************************//**
128
Sets the log block data length. */
131
log_block_set_data_len(
132
/*===================*/
133
byte* log_block, /*!< in/out: log block */
134
ulint len) /*!< in: data length */
136
mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
139
/************************************************************//**
140
Gets a log block first mtr log record group offset.
141
@return first mtr log record group byte offset from the block start, 0
145
log_block_get_first_rec_group(
146
/*==========================*/
147
const byte* log_block) /*!< in: log block */
149
return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
152
/************************************************************//**
153
Sets the log block first mtr log record group offset. */
156
log_block_set_first_rec_group(
157
/*==========================*/
158
byte* log_block, /*!< in/out: log block */
159
ulint offset) /*!< in: offset, 0 if none */
161
mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
164
/************************************************************//**
165
Gets a log block checkpoint number field (4 lowest bytes).
166
@return checkpoint no (4 lowest bytes) */
169
log_block_get_checkpoint_no(
170
/*========================*/
171
const byte* log_block) /*!< in: log block */
173
return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
176
/************************************************************//**
177
Sets a log block checkpoint number field (4 lowest bytes). */
180
log_block_set_checkpoint_no(
181
/*========================*/
182
byte* log_block, /*!< in/out: log block */
183
ib_uint64_t no) /*!< in: checkpoint no */
185
mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
188
/************************************************************//**
189
Converts a lsn to a log block number.
190
@return log block number, it is > 0 and <= 1G */
193
log_block_convert_lsn_to_no(
194
/*========================*/
195
ib_uint64_t lsn) /*!< in: lsn of a byte within the block */
197
return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
200
/************************************************************//**
201
Calculates the checksum for a log block.
205
log_block_calc_checksum(
206
/*====================*/
207
const byte* block) /*!< in: log block */
216
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
217
ulint b = (ulint) block[i];
230
/************************************************************//**
231
Gets a log block checksum field value.
235
log_block_get_checksum(
236
/*===================*/
237
const byte* log_block) /*!< in: log block */
239
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
240
- LOG_BLOCK_CHECKSUM));
243
/************************************************************//**
244
Sets a log block checksum field value. */
247
log_block_set_checksum(
248
/*===================*/
249
byte* log_block, /*!< in/out: log block */
250
ulint checksum) /*!< in: checksum */
252
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
253
- LOG_BLOCK_CHECKSUM,
257
/************************************************************//**
258
Initializes a log block in the log buffer. */
263
byte* log_block, /*!< in: pointer to the log buffer */
264
ib_uint64_t lsn) /*!< in: lsn within the log block */
268
ut_ad(mutex_own(&(log_sys->mutex)));
270
no = log_block_convert_lsn_to_no(lsn);
272
log_block_set_hdr_no(log_block, no);
274
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
275
log_block_set_first_rec_group(log_block, 0);
278
/************************************************************//**
279
Initializes a log block in the log buffer in the old format, where there
280
was no checksum yet. */
283
log_block_init_in_old_format(
284
/*=========================*/
285
byte* log_block, /*!< in: pointer to the log buffer */
286
ib_uint64_t lsn) /*!< in: lsn within the log block */
290
ut_ad(mutex_own(&(log_sys->mutex)));
292
no = log_block_convert_lsn_to_no(lsn);
294
log_block_set_hdr_no(log_block, no);
295
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
296
- LOG_BLOCK_CHECKSUM, no);
297
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
298
log_block_set_first_rec_group(log_block, 0);
301
#ifndef UNIV_HOTBACKUP
302
/************************************************************//**
303
Writes to the log the string given. The log must be released with
305
@return end lsn of the log record, zero if did not succeed */
308
log_reserve_and_write_fast(
309
/*=======================*/
310
const void* str, /*!< in: string */
311
ulint len, /*!< in: string length */
312
ib_uint64_t* start_lsn)/*!< out: start lsn of the log record */
315
#ifdef UNIV_LOG_LSN_DEBUG
316
/* length of the LSN pseudo-record */
318
#endif /* UNIV_LOG_LSN_DEBUG */
320
mutex_enter(&log_sys->mutex);
321
#ifdef UNIV_LOG_LSN_DEBUG
323
+ mach_get_compressed_size(log_sys->lsn >> 32)
324
+ mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
325
#endif /* UNIV_LOG_LSN_DEBUG */
328
#ifdef UNIV_LOG_LSN_DEBUG
330
#endif /* UNIV_LOG_LSN_DEBUG */
331
+ log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
333
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
335
/* The string does not fit within the current log block
336
or the log block would become full */
338
mutex_exit(&log_sys->mutex);
343
*start_lsn = log_sys->lsn;
345
#ifdef UNIV_LOG_LSN_DEBUG
347
/* Write the LSN pseudo-record. */
348
byte* b = &log_sys->buf[log_sys->buf_free];
349
*b++ = MLOG_LSN | (MLOG_SINGLE_REC_FLAG & *(const byte*) str);
350
/* Write the LSN in two parts,
351
as a pseudo page number and space id. */
352
b += mach_write_compressed(b, log_sys->lsn >> 32);
353
b += mach_write_compressed(b, log_sys->lsn & 0xFFFFFFFFUL);
354
ut_a(b - lsn_len == &log_sys->buf[log_sys->buf_free]);
359
#else /* UNIV_LOG_LSN_DEBUG */
360
memcpy(log_sys->buf + log_sys->buf_free, str, len);
361
#endif /* UNIV_LOG_LSN_DEBUG */
363
log_block_set_data_len((byte*) ut_align_down(log_sys->buf
365
OS_FILE_LOG_BLOCK_SIZE),
367
#ifdef UNIV_LOG_DEBUG
368
log_sys->old_buf_free = log_sys->buf_free;
369
log_sys->old_lsn = log_sys->lsn;
371
log_sys->buf_free += len;
373
ut_ad(log_sys->buf_free <= log_sys->buf_size);
377
#ifdef UNIV_LOG_DEBUG
378
log_check_log_recs(log_sys->buf + log_sys->old_buf_free,
379
log_sys->buf_free - log_sys->old_buf_free,
382
return(log_sys->lsn);
385
/***********************************************************************//**
386
Releases the log mutex. */
392
mutex_exit(&(log_sys->mutex));
395
/************************************************************//**
396
Gets the current lsn.
397
@return current lsn */
405
mutex_enter(&(log_sys->mutex));
409
mutex_exit(&(log_sys->mutex));
414
/****************************************************************
415
Gets the log group capacity. It is OK to read the value without
416
holding log_sys->mutex because it is constant.
417
@return log group capacity */
420
log_get_capacity(void)
421
/*==================*/
423
return(log_sys->log_group_capacity);
426
/***********************************************************************//**
427
Checks if there is need for a log buffer flush or a new checkpoint, and does
428
this if yes. Any database operation should call this when it has modified
429
more than about 4 pages. NOTE that this function may only be called when the
430
OS thread owns no synchronization objects except the dictionary mutex. */
437
#ifdef UNIV_SYNC_DEBUG
438
ut_ad(sync_thread_levels_empty_gen(TRUE));
439
#endif /* UNIV_SYNC_DEBUG */
441
if (log_sys->check_flush_or_checkpoint) {
446
#endif /* !UNIV_HOTBACKUP */