1
/******************************************************
6
Created 12/9/1995 Heikki Tuuri
7
*******************************************************/
10
#include "mach0data.h"
13
/**********************************************************
14
Checks by parsing that the catenated log segment for a single mtr is
20
byte* buf, /* in: pointer to the start of
21
the log segment in the
22
log_sys->buf log buffer */
23
ulint len, /* in: segment length in bytes */
24
ib_uint64_t buf_start_lsn); /* in: buffer start lsn */
26
/****************************************************************
27
Gets a log block flush bit. */
30
log_block_get_flush_bit(
31
/*====================*/
32
/* out: TRUE if this block was the first
33
to be written in a log flush */
34
byte* log_block) /* in: log block */
36
if (LOG_BLOCK_FLUSH_BIT_MASK
37
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
45
/****************************************************************
46
Sets the log block flush bit. */
49
log_block_set_flush_bit(
50
/*====================*/
51
byte* log_block, /* in: log block */
52
ibool val) /* in: value to set */
56
field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
59
field = field | LOG_BLOCK_FLUSH_BIT_MASK;
61
field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
64
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
67
/****************************************************************
68
Gets a log block number stored in the header. */
73
/* out: log block number stored in the block
75
byte* log_block) /* in: log block */
77
return(~LOG_BLOCK_FLUSH_BIT_MASK
78
& mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
81
/****************************************************************
82
Sets the log block number stored in the header; NOTE that this must be set
83
before the flush bit! */
88
byte* log_block, /* in: log block */
89
ulint n) /* in: log block number: must be > 0 and
90
< LOG_BLOCK_FLUSH_BIT_MASK */
93
ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
95
mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
98
/****************************************************************
99
Gets a log block data length. */
102
log_block_get_data_len(
103
/*===================*/
104
/* out: log block data length measured as a
105
byte offset from the block start */
106
byte* log_block) /* in: log block */
108
return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
111
/****************************************************************
112
Sets the log block data length. */
115
log_block_set_data_len(
116
/*===================*/
117
byte* log_block, /* in: log block */
118
ulint len) /* in: data length */
120
mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
123
/****************************************************************
124
Gets a log block first mtr log record group offset. */
127
log_block_get_first_rec_group(
128
/*==========================*/
129
/* out: first mtr log record group byte offset
130
from the block start, 0 if none */
131
byte* log_block) /* in: log block */
133
return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
136
/****************************************************************
137
Sets the log block first mtr log record group offset. */
140
log_block_set_first_rec_group(
141
/*==========================*/
142
byte* log_block, /* in: log block */
143
ulint offset) /* in: offset, 0 if none */
145
mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
148
/****************************************************************
149
Gets a log block checkpoint number field (4 lowest bytes). */
152
log_block_get_checkpoint_no(
153
/*========================*/
154
/* out: checkpoint no (4 lowest bytes) */
155
byte* log_block) /* in: log block */
157
return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
160
/****************************************************************
161
Sets a log block checkpoint number field (4 lowest bytes). */
164
log_block_set_checkpoint_no(
165
/*========================*/
166
byte* log_block, /* in: log block */
167
ib_uint64_t no) /* in: checkpoint no */
169
mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
172
/****************************************************************
173
Converts a lsn to a log block number. */
176
log_block_convert_lsn_to_no(
177
/*========================*/
178
/* out: log block number,
179
it is > 0 and <= 1G */
180
ib_uint64_t lsn) /* in: lsn of a byte within the block */
182
return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
185
/****************************************************************
186
Calculates the checksum for a log block. */
189
log_block_calc_checksum(
190
/*====================*/
192
const byte* block) /* in: log block */
201
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
202
ulint b = (ulint) block[i];
215
/****************************************************************
216
Gets a log block checksum field value. */
219
log_block_get_checksum(
220
/*===================*/
222
const byte* log_block) /* in: log block */
224
return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
225
- LOG_BLOCK_CHECKSUM));
228
/****************************************************************
229
Sets a log block checksum field value. */
232
log_block_set_checksum(
233
/*===================*/
234
byte* log_block, /* in: log block */
235
ulint checksum) /* in: checksum */
237
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
238
- LOG_BLOCK_CHECKSUM,
242
/****************************************************************
243
Initializes a log block in the log buffer. */
248
byte* log_block, /* in: pointer to the log buffer */
249
ib_uint64_t lsn) /* in: lsn within the log block */
253
ut_ad(mutex_own(&(log_sys->mutex)));
255
no = log_block_convert_lsn_to_no(lsn);
257
log_block_set_hdr_no(log_block, no);
259
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
260
log_block_set_first_rec_group(log_block, 0);
263
/****************************************************************
264
Initializes a log block in the log buffer in the old format, where there
265
was no checksum yet. */
268
log_block_init_in_old_format(
269
/*=========================*/
270
byte* log_block, /* in: pointer to the log buffer */
271
ib_uint64_t lsn) /* in: lsn within the log block */
275
ut_ad(mutex_own(&(log_sys->mutex)));
277
no = log_block_convert_lsn_to_no(lsn);
279
log_block_set_hdr_no(log_block, no);
280
mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
281
- LOG_BLOCK_CHECKSUM, no);
282
log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
283
log_block_set_first_rec_group(log_block, 0);
286
/****************************************************************
287
Writes to the log the string given. The log must be released with
291
log_reserve_and_write_fast(
292
/*=======================*/
293
/* out: end lsn of the log record,
294
zero if did not succeed */
295
byte* str, /* in: string */
296
ulint len, /* in: string length */
297
ib_uint64_t* start_lsn,/* out: start lsn of the log record */
298
ibool* success)/* out: TRUE if success */
300
log_t* log = log_sys;
306
mutex_enter(&(log->mutex));
308
data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
310
if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
312
/* The string does not fit within the current log block
313
or the log block would become full */
317
mutex_exit(&(log->mutex));
322
*start_lsn = log->lsn;
324
ut_memcpy(log->buf + log->buf_free, str, len);
326
log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
327
OS_FILE_LOG_BLOCK_SIZE),
329
#ifdef UNIV_LOG_DEBUG
330
log->old_buf_free = log->buf_free;
331
log->old_lsn = log->lsn;
333
log->buf_free += len;
335
ut_ad(log->buf_free <= log->buf_size);
337
lsn = log->lsn += len;
339
#ifdef UNIV_LOG_DEBUG
340
log_check_log_recs(log->buf + log->old_buf_free,
341
log->buf_free - log->old_buf_free, log->old_lsn);
346
/***************************************************************************
347
Releases the log mutex. */
353
mutex_exit(&(log_sys->mutex));
356
/****************************************************************
357
Gets the current lsn. */
362
/* out: current lsn */
366
mutex_enter(&(log_sys->mutex));
370
mutex_exit(&(log_sys->mutex));
375
/***************************************************************************
376
Checks if there is need for a log buffer flush or a new checkpoint, and does
377
this if yes. Any database operation should call this when it has modified
378
more than about 4 pages. NOTE that this function may only be called when the
379
OS thread owns no synchronization objects except the dictionary mutex. */
385
/* ut_ad(sync_thread_levels_empty()); */
387
if (log_sys->check_flush_or_checkpoint) {