~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/include/log0log.ic

  • Committer: Brian Aker
  • Date: 2010-09-22 22:25:29 UTC
  • mto: (1791.1.1 drizzle)
  • mto: This revision was merged to the branch mainline in revision 1792.
  • Revision ID: brian@tangent.org-20100922222529-geo4wggmu5ntqa5k
Current boost work (more conversion).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
4
 
 
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.
8
 
 
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.
12
 
 
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
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file include/log0log.ic
21
 
Database log
22
 
 
23
 
Created 12/9/1995 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
#include "os0file.h"
27
 
#include "mach0data.h"
28
 
#include "mtr0mtr.h"
29
 
 
30
 
#ifdef UNIV_LOG_DEBUG
31
 
/******************************************************//**
32
 
Checks by parsing that the catenated log segment for a single mtr is
33
 
consistent. */
34
 
UNIV_INTERN
35
 
ibool
36
 
log_check_log_recs(
37
 
/*===============*/
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 */
44
 
 
45
 
/************************************************************//**
46
 
Gets a log block flush bit.
47
 
@return TRUE if this block was the first to be written in a log flush */
48
 
UNIV_INLINE
49
 
ibool
50
 
log_block_get_flush_bit(
51
 
/*====================*/
52
 
        const byte*     log_block)      /*!< in: log block */
53
 
{
54
 
        if (LOG_BLOCK_FLUSH_BIT_MASK
55
 
            & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
56
 
 
57
 
                return(TRUE);
58
 
        }
59
 
 
60
 
        return(FALSE);
61
 
}
62
 
 
63
 
/************************************************************//**
64
 
Sets the log block flush bit. */
65
 
UNIV_INLINE
66
 
void
67
 
log_block_set_flush_bit(
68
 
/*====================*/
69
 
        byte*   log_block,      /*!< in/out: log block */
70
 
        ibool   val)            /*!< in: value to set */
71
 
{
72
 
        ulint   field;
73
 
 
74
 
        field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
75
 
 
76
 
        if (val) {
77
 
                field = field | LOG_BLOCK_FLUSH_BIT_MASK;
78
 
        } else {
79
 
                field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
80
 
        }
81
 
 
82
 
        mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
83
 
}
84
 
 
85
 
/************************************************************//**
86
 
Gets a log block number stored in the header.
87
 
@return log block number stored in the block header */
88
 
UNIV_INLINE
89
 
ulint
90
 
log_block_get_hdr_no(
91
 
/*=================*/
92
 
        const byte*     log_block)      /*!< in: log block */
93
 
{
94
 
        return(~LOG_BLOCK_FLUSH_BIT_MASK
95
 
               & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
96
 
}
97
 
 
98
 
/************************************************************//**
99
 
Sets the log block number stored in the header; NOTE that this must be set
100
 
before the flush bit! */
101
 
UNIV_INLINE
102
 
void
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 */
108
 
{
109
 
        ut_ad(n > 0);
110
 
        ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
111
 
 
112
 
        mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
113
 
}
114
 
 
115
 
/************************************************************//**
116
 
Gets a log block data length.
117
 
@return log block data length measured as a byte offset from the block start */
118
 
UNIV_INLINE
119
 
ulint
120
 
log_block_get_data_len(
121
 
/*===================*/
122
 
        const byte*     log_block)      /*!< in: log block */
123
 
{
124
 
        return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
125
 
}
126
 
 
127
 
/************************************************************//**
128
 
Sets the log block data length. */
129
 
UNIV_INLINE
130
 
void
131
 
log_block_set_data_len(
132
 
/*===================*/
133
 
        byte*   log_block,      /*!< in/out: log block */
134
 
        ulint   len)            /*!< in: data length */
135
 
{
136
 
        mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
137
 
}
138
 
 
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
142
 
if none */
143
 
UNIV_INLINE
144
 
ulint
145
 
log_block_get_first_rec_group(
146
 
/*==========================*/
147
 
        const byte*     log_block)      /*!< in: log block */
148
 
{
149
 
        return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
150
 
}
151
 
 
152
 
/************************************************************//**
153
 
Sets the log block first mtr log record group offset. */
154
 
UNIV_INLINE
155
 
void
156
 
log_block_set_first_rec_group(
157
 
/*==========================*/
158
 
        byte*   log_block,      /*!< in/out: log block */
159
 
        ulint   offset)         /*!< in: offset, 0 if none */
160
 
{
161
 
        mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
162
 
}
163
 
 
164
 
/************************************************************//**
165
 
Gets a log block checkpoint number field (4 lowest bytes).
166
 
@return checkpoint no (4 lowest bytes) */
167
 
UNIV_INLINE
168
 
ulint
169
 
log_block_get_checkpoint_no(
170
 
/*========================*/
171
 
        const byte*     log_block)      /*!< in: log block */
172
 
{
173
 
        return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
174
 
}
175
 
 
176
 
/************************************************************//**
177
 
Sets a log block checkpoint number field (4 lowest bytes). */
178
 
UNIV_INLINE
179
 
void
180
 
log_block_set_checkpoint_no(
181
 
/*========================*/
182
 
        byte*           log_block,      /*!< in/out: log block */
183
 
        ib_uint64_t     no)             /*!< in: checkpoint no */
184
 
{
185
 
        mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
186
 
}
187
 
 
188
 
/************************************************************//**
189
 
Converts a lsn to a log block number.
190
 
@return log block number, it is > 0 and <= 1G */
191
 
UNIV_INLINE
192
 
ulint
193
 
log_block_convert_lsn_to_no(
194
 
/*========================*/
195
 
        ib_uint64_t     lsn)    /*!< in: lsn of a byte within the block */
196
 
{
197
 
        return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
198
 
}
199
 
 
200
 
/************************************************************//**
201
 
Calculates the checksum for a log block.
202
 
@return checksum */
203
 
UNIV_INLINE
204
 
ulint
205
 
log_block_calc_checksum(
206
 
/*====================*/
207
 
        const byte*     block)  /*!< in: log block */
208
 
{
209
 
        ulint   sum;
210
 
        ulint   sh;
211
 
        ulint   i;
212
 
 
213
 
        sum = 1;
214
 
        sh = 0;
215
 
 
216
 
        for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
217
 
                ulint   b = (ulint) block[i];
218
 
                sum &= 0x7FFFFFFFUL;
219
 
                sum += b;
220
 
                sum += b << sh;
221
 
                sh++;
222
 
                if (sh > 24) {
223
 
                        sh = 0;
224
 
                }
225
 
        }
226
 
 
227
 
        return(sum);
228
 
}
229
 
 
230
 
/************************************************************//**
231
 
Gets a log block checksum field value.
232
 
@return checksum */
233
 
UNIV_INLINE
234
 
ulint
235
 
log_block_get_checksum(
236
 
/*===================*/
237
 
        const byte*     log_block)      /*!< in: log block */
238
 
{
239
 
        return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
240
 
                                - LOG_BLOCK_CHECKSUM));
241
 
}
242
 
 
243
 
/************************************************************//**
244
 
Sets a log block checksum field value. */
245
 
UNIV_INLINE
246
 
void
247
 
log_block_set_checksum(
248
 
/*===================*/
249
 
        byte*   log_block,      /*!< in/out: log block */
250
 
        ulint   checksum)       /*!< in: checksum */
251
 
{
252
 
        mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
253
 
                        - LOG_BLOCK_CHECKSUM,
254
 
                        checksum);
255
 
}
256
 
 
257
 
/************************************************************//**
258
 
Initializes a log block in the log buffer. */
259
 
UNIV_INLINE
260
 
void
261
 
log_block_init(
262
 
/*===========*/
263
 
        byte*           log_block,      /*!< in: pointer to the log buffer */
264
 
        ib_uint64_t     lsn)            /*!< in: lsn within the log block */
265
 
{
266
 
        ulint   no;
267
 
 
268
 
        ut_ad(mutex_own(&(log_sys->mutex)));
269
 
 
270
 
        no = log_block_convert_lsn_to_no(lsn);
271
 
 
272
 
        log_block_set_hdr_no(log_block, no);
273
 
 
274
 
        log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
275
 
        log_block_set_first_rec_group(log_block, 0);
276
 
}
277
 
 
278
 
/************************************************************//**
279
 
Initializes a log block in the log buffer in the old format, where there
280
 
was no checksum yet. */
281
 
UNIV_INLINE
282
 
void
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 */
287
 
{
288
 
        ulint   no;
289
 
 
290
 
        ut_ad(mutex_own(&(log_sys->mutex)));
291
 
 
292
 
        no = log_block_convert_lsn_to_no(lsn);
293
 
 
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);
299
 
}
300
 
 
301
 
#ifndef UNIV_HOTBACKUP
302
 
/************************************************************//**
303
 
Writes to the log the string given. The log must be released with
304
 
log_release.
305
 
@return end lsn of the log record, zero if did not succeed */
306
 
UNIV_INLINE
307
 
ib_uint64_t
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 */
313
 
{
314
 
        ulint           data_len;
315
 
#ifdef UNIV_LOG_LSN_DEBUG
316
 
        /* length of the LSN pseudo-record */
317
 
        ulint           lsn_len;
318
 
#endif /* UNIV_LOG_LSN_DEBUG */
319
 
 
320
 
        mutex_enter(&log_sys->mutex);
321
 
#ifdef UNIV_LOG_LSN_DEBUG
322
 
        lsn_len = 1
323
 
                + mach_get_compressed_size(log_sys->lsn >> 32)
324
 
                + mach_get_compressed_size(log_sys->lsn & 0xFFFFFFFFUL);
325
 
#endif /* UNIV_LOG_LSN_DEBUG */
326
 
 
327
 
        data_len = len
328
 
#ifdef UNIV_LOG_LSN_DEBUG
329
 
                + lsn_len
330
 
#endif /* UNIV_LOG_LSN_DEBUG */
331
 
                + log_sys->buf_free % OS_FILE_LOG_BLOCK_SIZE;
332
 
 
333
 
        if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
334
 
 
335
 
                /* The string does not fit within the current log block
336
 
                or the log block would become full */
337
 
 
338
 
                mutex_exit(&log_sys->mutex);
339
 
 
340
 
                return(0);
341
 
        }
342
 
 
343
 
        *start_lsn = log_sys->lsn;
344
 
 
345
 
#ifdef UNIV_LOG_LSN_DEBUG
346
 
        {
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]);
355
 
 
356
 
                memcpy(b, str, len);
357
 
                len += lsn_len;
358
 
        }
359
 
#else /* UNIV_LOG_LSN_DEBUG */
360
 
        memcpy(log_sys->buf + log_sys->buf_free, str, len);
361
 
#endif /* UNIV_LOG_LSN_DEBUG */
362
 
 
363
 
        log_block_set_data_len((byte*) ut_align_down(log_sys->buf
364
 
                                                     + log_sys->buf_free,
365
 
                                                     OS_FILE_LOG_BLOCK_SIZE),
366
 
                               data_len);
367
 
#ifdef UNIV_LOG_DEBUG
368
 
        log_sys->old_buf_free = log_sys->buf_free;
369
 
        log_sys->old_lsn = log_sys->lsn;
370
 
#endif
371
 
        log_sys->buf_free += len;
372
 
 
373
 
        ut_ad(log_sys->buf_free <= log_sys->buf_size);
374
 
 
375
 
        log_sys->lsn += len;
376
 
 
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,
380
 
                           log_sys->old_lsn);
381
 
#endif
382
 
        return(log_sys->lsn);
383
 
}
384
 
 
385
 
/***********************************************************************//**
386
 
Releases the log mutex. */
387
 
UNIV_INLINE
388
 
void
389
 
log_release(void)
390
 
/*=============*/
391
 
{
392
 
        mutex_exit(&(log_sys->mutex));
393
 
}
394
 
 
395
 
/************************************************************//**
396
 
Gets the current lsn.
397
 
@return current lsn */
398
 
UNIV_INLINE
399
 
ib_uint64_t
400
 
log_get_lsn(void)
401
 
/*=============*/
402
 
{
403
 
        ib_uint64_t     lsn;
404
 
 
405
 
        mutex_enter(&(log_sys->mutex));
406
 
 
407
 
        lsn = log_sys->lsn;
408
 
 
409
 
        mutex_exit(&(log_sys->mutex));
410
 
 
411
 
        return(lsn);
412
 
}
413
 
 
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 */
418
 
UNIV_INLINE
419
 
ulint
420
 
log_get_capacity(void)
421
 
/*==================*/
422
 
{
423
 
        return(log_sys->log_group_capacity);
424
 
}
425
 
 
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. */
431
 
UNIV_INLINE
432
 
void
433
 
log_free_check(void)
434
 
/*================*/
435
 
{
436
 
 
437
 
#ifdef UNIV_SYNC_DEBUG
438
 
        ut_ad(sync_thread_levels_empty_gen(TRUE));
439
 
#endif /* UNIV_SYNC_DEBUG */
440
 
 
441
 
        if (log_sys->check_flush_or_checkpoint) {
442
 
 
443
 
                log_check_margins();
444
 
        }
445
 
}
446
 
#endif /* !UNIV_HOTBACKUP */