~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2008-11-24 05:39:31 UTC
  • mto: This revision was merged to the branch mainline in revision 610.
  • Revision ID: mordred@solanthus.local-20081124053931-tzlxsgkdvs3b7n8n
Reverted libuuid check code. 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
Database log
 
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
 
6
Created 12/9/1995 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#include "os0file.h"
 
10
#include "mach0data.h"
 
11
#include "mtr0mtr.h"
 
12
 
 
13
/**********************************************************
 
14
Checks by parsing that the catenated log segment for a single mtr is
 
15
consistent. */
 
16
UNIV_INTERN
 
17
ibool
 
18
log_check_log_recs(
 
19
/*===============*/
 
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 */
 
25
 
 
26
/****************************************************************
 
27
Gets a log block flush bit. */
 
28
UNIV_INLINE
 
29
ibool
 
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 */
 
35
{
 
36
        if (LOG_BLOCK_FLUSH_BIT_MASK
 
37
            & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO)) {
 
38
 
 
39
                return(TRUE);
 
40
        }
 
41
 
 
42
        return(FALSE);
 
43
}
 
44
 
 
45
/****************************************************************
 
46
Sets the log block flush bit. */
 
47
UNIV_INLINE
 
48
void
 
49
log_block_set_flush_bit(
 
50
/*====================*/
 
51
        byte*   log_block,      /* in: log block */
 
52
        ibool   val)            /* in: value to set */
 
53
{
 
54
        ulint   field;
 
55
 
 
56
        field = mach_read_from_4(log_block + LOG_BLOCK_HDR_NO);
 
57
 
 
58
        if (val) {
 
59
                field = field | LOG_BLOCK_FLUSH_BIT_MASK;
 
60
        } else {
 
61
                field = field & ~LOG_BLOCK_FLUSH_BIT_MASK;
 
62
        }
 
63
 
 
64
        mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, field);
 
65
}
 
66
 
 
67
/****************************************************************
 
68
Gets a log block number stored in the header. */
 
69
UNIV_INLINE
 
70
ulint
 
71
log_block_get_hdr_no(
 
72
/*=================*/
 
73
                                /* out: log block number stored in the block
 
74
                                header */
 
75
        byte*   log_block)      /* in: log block */
 
76
{
 
77
        return(~LOG_BLOCK_FLUSH_BIT_MASK
 
78
               & mach_read_from_4(log_block + LOG_BLOCK_HDR_NO));
 
79
}
 
80
 
 
81
/****************************************************************
 
82
Sets the log block number stored in the header; NOTE that this must be set
 
83
before the flush bit! */
 
84
UNIV_INLINE
 
85
void
 
86
log_block_set_hdr_no(
 
87
/*=================*/
 
88
        byte*   log_block,      /* in: log block */
 
89
        ulint   n)              /* in: log block number: must be > 0 and
 
90
                                < LOG_BLOCK_FLUSH_BIT_MASK */
 
91
{
 
92
        ut_ad(n > 0);
 
93
        ut_ad(n < LOG_BLOCK_FLUSH_BIT_MASK);
 
94
 
 
95
        mach_write_to_4(log_block + LOG_BLOCK_HDR_NO, n);
 
96
}
 
97
 
 
98
/****************************************************************
 
99
Gets a log block data length. */
 
100
UNIV_INLINE
 
101
ulint
 
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 */
 
107
{
 
108
        return(mach_read_from_2(log_block + LOG_BLOCK_HDR_DATA_LEN));
 
109
}
 
110
 
 
111
/****************************************************************
 
112
Sets the log block data length. */
 
113
UNIV_INLINE
 
114
void
 
115
log_block_set_data_len(
 
116
/*===================*/
 
117
        byte*   log_block,      /* in: log block */
 
118
        ulint   len)            /* in: data length */
 
119
{
 
120
        mach_write_to_2(log_block + LOG_BLOCK_HDR_DATA_LEN, len);
 
121
}
 
122
 
 
123
/****************************************************************
 
124
Gets a log block first mtr log record group offset. */
 
125
UNIV_INLINE
 
126
ulint
 
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 */
 
132
{
 
133
        return(mach_read_from_2(log_block + LOG_BLOCK_FIRST_REC_GROUP));
 
134
}
 
135
 
 
136
/****************************************************************
 
137
Sets the log block first mtr log record group offset. */
 
138
UNIV_INLINE
 
139
void
 
140
log_block_set_first_rec_group(
 
141
/*==========================*/
 
142
        byte*   log_block,      /* in: log block */
 
143
        ulint   offset)         /* in: offset, 0 if none */
 
144
{
 
145
        mach_write_to_2(log_block + LOG_BLOCK_FIRST_REC_GROUP, offset);
 
146
}
 
147
 
 
148
/****************************************************************
 
149
Gets a log block checkpoint number field (4 lowest bytes). */
 
150
UNIV_INLINE
 
151
ulint
 
152
log_block_get_checkpoint_no(
 
153
/*========================*/
 
154
                                /* out: checkpoint no (4 lowest bytes) */
 
155
        byte*   log_block)      /* in: log block */
 
156
{
 
157
        return(mach_read_from_4(log_block + LOG_BLOCK_CHECKPOINT_NO));
 
158
}
 
159
 
 
160
/****************************************************************
 
161
Sets a log block checkpoint number field (4 lowest bytes). */
 
162
UNIV_INLINE
 
163
void
 
164
log_block_set_checkpoint_no(
 
165
/*========================*/
 
166
        byte*           log_block,      /* in: log block */
 
167
        ib_uint64_t     no)             /* in: checkpoint no */
 
168
{
 
169
        mach_write_to_4(log_block + LOG_BLOCK_CHECKPOINT_NO, (ulint) no);
 
170
}
 
171
 
 
172
/****************************************************************
 
173
Converts a lsn to a log block number. */
 
174
UNIV_INLINE
 
175
ulint
 
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 */
 
181
{
 
182
        return(((ulint) (lsn / OS_FILE_LOG_BLOCK_SIZE) & 0x3FFFFFFFUL) + 1);
 
183
}
 
184
 
 
185
/****************************************************************
 
186
Calculates the checksum for a log block. */
 
187
UNIV_INLINE
 
188
ulint
 
189
log_block_calc_checksum(
 
190
/*====================*/
 
191
                                /* out: checksum */
 
192
        const byte*     block)  /* in: log block */
 
193
{
 
194
        ulint   sum;
 
195
        ulint   sh;
 
196
        ulint   i;
 
197
 
 
198
        sum = 1;
 
199
        sh = 0;
 
200
 
 
201
        for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE; i++) {
 
202
                ulint   b = (ulint) block[i];
 
203
                sum &= 0x7FFFFFFFUL;
 
204
                sum += b;
 
205
                sum += b << sh;
 
206
                sh++;
 
207
                if (sh > 24) {
 
208
                        sh = 0;
 
209
                }
 
210
        }
 
211
 
 
212
        return(sum);
 
213
}
 
214
 
 
215
/****************************************************************
 
216
Gets a log block checksum field value. */
 
217
UNIV_INLINE
 
218
ulint
 
219
log_block_get_checksum(
 
220
/*===================*/
 
221
                                        /* out: checksum */
 
222
        const byte*     log_block)      /* in: log block */
 
223
{
 
224
        return(mach_read_from_4(log_block + OS_FILE_LOG_BLOCK_SIZE
 
225
                                - LOG_BLOCK_CHECKSUM));
 
226
}
 
227
 
 
228
/****************************************************************
 
229
Sets a log block checksum field value. */
 
230
UNIV_INLINE
 
231
void
 
232
log_block_set_checksum(
 
233
/*===================*/
 
234
        byte*   log_block,      /* in: log block */
 
235
        ulint   checksum)       /* in: checksum */
 
236
{
 
237
        mach_write_to_4(log_block + OS_FILE_LOG_BLOCK_SIZE
 
238
                        - LOG_BLOCK_CHECKSUM,
 
239
                        checksum);
 
240
}
 
241
 
 
242
/****************************************************************
 
243
Initializes a log block in the log buffer. */
 
244
UNIV_INLINE
 
245
void
 
246
log_block_init(
 
247
/*===========*/
 
248
        byte*           log_block,      /* in: pointer to the log buffer */
 
249
        ib_uint64_t     lsn)            /* in: lsn within the log block */
 
250
{
 
251
        ulint   no;
 
252
 
 
253
        ut_ad(mutex_own(&(log_sys->mutex)));
 
254
 
 
255
        no = log_block_convert_lsn_to_no(lsn);
 
256
 
 
257
        log_block_set_hdr_no(log_block, no);
 
258
 
 
259
        log_block_set_data_len(log_block, LOG_BLOCK_HDR_SIZE);
 
260
        log_block_set_first_rec_group(log_block, 0);
 
261
}
 
262
 
 
263
/****************************************************************
 
264
Initializes a log block in the log buffer in the old format, where there
 
265
was no checksum yet. */
 
266
UNIV_INLINE
 
267
void
 
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 */
 
272
{
 
273
        ulint   no;
 
274
 
 
275
        ut_ad(mutex_own(&(log_sys->mutex)));
 
276
 
 
277
        no = log_block_convert_lsn_to_no(lsn);
 
278
 
 
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);
 
284
}
 
285
 
 
286
/****************************************************************
 
287
Writes to the log the string given. The log must be released with
 
288
log_release. */
 
289
UNIV_INLINE
 
290
ib_uint64_t
 
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 */
 
299
{
 
300
        log_t*          log     = log_sys;
 
301
        ulint           data_len;
 
302
        ib_uint64_t     lsn;
 
303
 
 
304
        *success = TRUE;
 
305
 
 
306
        mutex_enter(&(log->mutex));
 
307
 
 
308
        data_len = len + log->buf_free % OS_FILE_LOG_BLOCK_SIZE;
 
309
 
 
310
        if (data_len >= OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_TRL_SIZE) {
 
311
 
 
312
                /* The string does not fit within the current log block
 
313
                or the log block would become full */
 
314
 
 
315
                *success = FALSE;
 
316
 
 
317
                mutex_exit(&(log->mutex));
 
318
 
 
319
                return(0);
 
320
        }
 
321
 
 
322
        *start_lsn = log->lsn;
 
323
 
 
324
        ut_memcpy(log->buf + log->buf_free, str, len);
 
325
 
 
326
        log_block_set_data_len((byte*) ut_align_down(log->buf + log->buf_free,
 
327
                                                     OS_FILE_LOG_BLOCK_SIZE),
 
328
                               data_len);
 
329
#ifdef UNIV_LOG_DEBUG
 
330
        log->old_buf_free = log->buf_free;
 
331
        log->old_lsn = log->lsn;
 
332
#endif
 
333
        log->buf_free += len;
 
334
 
 
335
        ut_ad(log->buf_free <= log->buf_size);
 
336
 
 
337
        lsn = log->lsn += len;
 
338
 
 
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);
 
342
#endif
 
343
        return(lsn);
 
344
}
 
345
 
 
346
/***************************************************************************
 
347
Releases the log mutex. */
 
348
UNIV_INLINE
 
349
void
 
350
log_release(void)
 
351
/*=============*/
 
352
{
 
353
        mutex_exit(&(log_sys->mutex));
 
354
}
 
355
 
 
356
/****************************************************************
 
357
Gets the current lsn. */
 
358
UNIV_INLINE
 
359
ib_uint64_t
 
360
log_get_lsn(void)
 
361
/*=============*/
 
362
                        /* out: current lsn */
 
363
{
 
364
        ib_uint64_t     lsn;
 
365
 
 
366
        mutex_enter(&(log_sys->mutex));
 
367
 
 
368
        lsn = log_sys->lsn;
 
369
 
 
370
        mutex_exit(&(log_sys->mutex));
 
371
 
 
372
        return(lsn);
 
373
}
 
374
 
 
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. */
 
380
UNIV_INLINE
 
381
void
 
382
log_free_check(void)
 
383
/*================*/
 
384
{
 
385
        /* ut_ad(sync_thread_levels_empty()); */
 
386
 
 
387
        if (log_sys->check_flush_or_checkpoint) {
 
388
 
 
389
                log_check_margins();
 
390
        }
 
391
}