~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Renamed strings to mystrings, for include/lib naming consistency.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
#include "buf0rea.h"
12
12
#include "mtr0mtr.h"
13
13
 
14
 
/************************************************************************
15
 
Reads the freed_page_clock of a buffer block. */
16
 
UNIV_INLINE
17
 
ulint
18
 
buf_page_get_freed_page_clock(
19
 
/*==========================*/
20
 
                                        /* out: freed_page_clock */
21
 
        const buf_page_t*       bpage)  /* in: block */
22
 
{
23
 
        return(bpage->freed_page_clock);
24
 
}
25
 
 
26
 
/************************************************************************
27
 
Reads the freed_page_clock of a buffer block. */
28
 
UNIV_INLINE
29
 
ulint
30
 
buf_block_get_freed_page_clock(
31
 
/*===========================*/
32
 
                                        /* out: freed_page_clock */
33
 
        const buf_block_t*      block)  /* in: block */
34
 
{
35
 
        return(buf_page_get_freed_page_clock(&block->page));
36
 
}
37
 
 
 
14
#ifdef UNIV_DEBUG
 
15
extern ulint            buf_dbg_counter; /* This is used to insert validation
 
16
                                        operations in execution in the
 
17
                                        debug version */
 
18
#endif /* UNIV_DEBUG */
38
19
/************************************************************************
39
20
Recommends a move of a block to the start of the LRU list if there is danger
40
21
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
41
22
mutex. */
42
23
UNIV_INLINE
43
24
ibool
44
 
buf_page_peek_if_too_old(
45
 
/*=====================*/
46
 
                                        /* out: TRUE if should be made
47
 
                                        younger */
48
 
        const buf_page_t*       bpage)  /* in: block to make younger */
 
25
buf_block_peek_if_too_old(
 
26
/*======================*/
 
27
                                /* out: TRUE if should be made younger */
 
28
        buf_block_t*    block)  /* in: block to make younger */
49
29
{
50
 
        return(buf_pool->freed_page_clock
51
 
               >= buf_page_get_freed_page_clock(bpage)
 
30
        return(buf_pool->freed_page_clock >= block->freed_page_clock
52
31
               + 1 + (buf_pool->curr_size / 4));
53
32
}
54
33
 
55
34
/*************************************************************************
56
 
Gets the current size of buffer buf_pool in bytes. */
 
35
Gets the current size of buffer buf_pool in bytes. In the case of AWE, the
 
36
size of AWE window (= the frames). */
57
37
UNIV_INLINE
58
38
ulint
59
39
buf_pool_get_curr_size(void)
60
40
/*========================*/
61
41
                        /* out: size in bytes */
62
42
{
63
 
        return(buf_pool->curr_size * UNIV_PAGE_SIZE);
 
43
        return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
 
44
}
 
45
 
 
46
/*************************************************************************
 
47
Gets the maximum size of buffer buf_pool in bytes. In the case of AWE, the
 
48
size of AWE window (= the frames). */
 
49
UNIV_INLINE
 
50
ulint
 
51
buf_pool_get_max_size(void)
 
52
/*=======================*/
 
53
                        /* out: size in bytes */
 
54
{
 
55
        return((buf_pool->n_frames) * UNIV_PAGE_SIZE);
 
56
}
 
57
 
 
58
/***********************************************************************
 
59
Accessor function for block array. */
 
60
UNIV_INLINE
 
61
buf_block_t*
 
62
buf_pool_get_nth_block(
 
63
/*===================*/
 
64
                                /* out: pointer to block */
 
65
        buf_pool_t*     buf_pool,/* in: buf_pool */
 
66
        ulint           i)      /* in: index of the block */
 
67
{
 
68
        ut_ad(buf_pool);
 
69
        ut_ad(i < buf_pool->max_size);
 
70
 
 
71
        return(i + buf_pool->blocks);
 
72
}
 
73
 
 
74
/***********************************************************************
 
75
Checks if a pointer points to the block array of the buffer pool (blocks, not
 
76
the frames). */
 
77
UNIV_INLINE
 
78
ibool
 
79
buf_pool_is_block(
 
80
/*==============*/
 
81
                        /* out: TRUE if pointer to block */
 
82
        void*   ptr)    /* in: pointer to memory */
 
83
{
 
84
        if ((buf_pool->blocks <= (buf_block_t*)ptr)
 
85
            && ((buf_block_t*)ptr < buf_pool->blocks
 
86
                + buf_pool->max_size)) {
 
87
 
 
88
                return(TRUE);
 
89
        }
 
90
 
 
91
        return(FALSE);
64
92
}
65
93
 
66
94
/************************************************************************
67
95
Gets the smallest oldest_modification lsn for any page in the pool. Returns
68
 
zero if all modified pages have been flushed to disk. */
 
96
ut_dulint_zero if all modified pages have been flushed to disk. */
69
97
UNIV_INLINE
70
 
ib_uint64_t
 
98
dulint
71
99
buf_pool_get_oldest_modification(void)
72
100
/*==================================*/
73
101
                                /* out: oldest modification in pool,
74
 
                                zero if none */
 
102
                                ut_dulint_zero if none */
75
103
{
76
 
        buf_page_t*     bpage;
77
 
        ib_uint64_t     lsn;
78
 
 
79
 
        buf_pool_mutex_enter();
80
 
 
81
 
        bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
82
 
 
83
 
        if (bpage == NULL) {
84
 
                lsn = 0;
 
104
        buf_block_t*    block;
 
105
        dulint          lsn;
 
106
 
 
107
        mutex_enter(&(buf_pool->mutex));
 
108
 
 
109
        block = UT_LIST_GET_LAST(buf_pool->flush_list);
 
110
 
 
111
        if (block == NULL) {
 
112
                lsn = ut_dulint_zero;
85
113
        } else {
86
 
                ut_ad(bpage->in_flush_list);
87
 
                lsn = bpage->oldest_modification;
 
114
                lsn = block->oldest_modification;
88
115
        }
89
116
 
90
 
        buf_pool_mutex_exit();
 
117
        mutex_exit(&(buf_pool->mutex));
91
118
 
92
119
        return(lsn);
93
120
}
101
128
/*====================*/
102
129
                        /* out: new clock value */
103
130
{
104
 
        ut_ad(buf_pool_mutex_own());
 
131
        ut_ad(mutex_own(&(buf_pool->mutex)));
105
132
 
106
133
        buf_pool->ulint_clock++;
107
134
 
109
136
}
110
137
 
111
138
/*************************************************************************
112
 
Gets the state of a block. */
113
 
UNIV_INLINE
114
 
enum buf_page_state
115
 
buf_page_get_state(
116
 
/*===============*/
117
 
                                        /* out: state */
118
 
        const buf_page_t*       bpage)  /* in: pointer to the control block */
119
 
{
120
 
        enum buf_page_state     state = (enum buf_page_state) bpage->state;
121
 
 
122
 
#ifdef UNIV_DEBUG
123
 
        switch (state) {
124
 
        case BUF_BLOCK_ZIP_FREE:
125
 
        case BUF_BLOCK_ZIP_PAGE:
126
 
        case BUF_BLOCK_ZIP_DIRTY:
127
 
        case BUF_BLOCK_NOT_USED:
128
 
        case BUF_BLOCK_READY_FOR_USE:
129
 
        case BUF_BLOCK_FILE_PAGE:
130
 
        case BUF_BLOCK_MEMORY:
131
 
        case BUF_BLOCK_REMOVE_HASH:
132
 
                break;
133
 
        default:
134
 
                ut_error;
135
 
        }
136
 
#endif /* UNIV_DEBUG */
137
 
 
138
 
        return(state);
139
 
}
140
 
/*************************************************************************
141
 
Gets the state of a block. */
142
 
UNIV_INLINE
143
 
enum buf_page_state
144
 
buf_block_get_state(
145
 
/*================*/
146
 
                                        /* out: state */
147
 
        const buf_block_t*      block)  /* in: pointer to the control block */
148
 
{
149
 
        return(buf_page_get_state(&block->page));
150
 
}
151
 
/*************************************************************************
152
 
Sets the state of a block. */
153
 
UNIV_INLINE
154
 
void
155
 
buf_page_set_state(
156
 
/*===============*/
157
 
        buf_page_t*             bpage,  /* in/out: pointer to control block */
158
 
        enum buf_page_state     state)  /* in: state */
159
 
{
160
 
#ifdef UNIV_DEBUG
161
 
        enum buf_page_state     old_state       = buf_page_get_state(bpage);
162
 
 
163
 
        switch (old_state) {
164
 
        case BUF_BLOCK_ZIP_FREE:
165
 
                ut_error;
166
 
                break;
167
 
        case BUF_BLOCK_ZIP_PAGE:
168
 
                ut_a(state == BUF_BLOCK_ZIP_DIRTY);
169
 
                break;
170
 
        case BUF_BLOCK_ZIP_DIRTY:
171
 
                ut_a(state == BUF_BLOCK_ZIP_PAGE);
172
 
                break;
173
 
        case BUF_BLOCK_NOT_USED:
174
 
                ut_a(state == BUF_BLOCK_READY_FOR_USE);
175
 
                break;
176
 
        case BUF_BLOCK_READY_FOR_USE:
177
 
                ut_a(state == BUF_BLOCK_MEMORY
178
 
                     || state == BUF_BLOCK_FILE_PAGE
179
 
                     || state == BUF_BLOCK_NOT_USED);
180
 
                break;
181
 
        case BUF_BLOCK_MEMORY:
182
 
                ut_a(state == BUF_BLOCK_NOT_USED);
183
 
                break;
184
 
        case BUF_BLOCK_FILE_PAGE:
185
 
                ut_a(state == BUF_BLOCK_NOT_USED
186
 
                     || state == BUF_BLOCK_REMOVE_HASH);
187
 
                break;
188
 
        case BUF_BLOCK_REMOVE_HASH:
189
 
                ut_a(state == BUF_BLOCK_MEMORY);
190
 
                break;
191
 
        }
192
 
#endif /* UNIV_DEBUG */
193
 
        bpage->state = state;
194
 
        ut_ad(buf_page_get_state(bpage) == state);
195
 
}
196
 
 
197
 
/*************************************************************************
198
 
Sets the state of a block. */
199
 
UNIV_INLINE
200
 
void
201
 
buf_block_set_state(
202
 
/*================*/
203
 
        buf_block_t*            block,  /* in/out: pointer to control block */
204
 
        enum buf_page_state     state)  /* in: state */
205
 
{
206
 
        buf_page_set_state(&block->page, state);
207
 
}
208
 
 
209
 
/*************************************************************************
210
 
Determines if a block is mapped to a tablespace. */
211
 
UNIV_INLINE
212
 
ibool
213
 
buf_page_in_file(
214
 
/*=============*/
215
 
                                        /* out: TRUE if mapped */
216
 
        const buf_page_t*       bpage)  /* in: pointer to control block */
217
 
{
218
 
        switch (buf_page_get_state(bpage)) {
219
 
        case BUF_BLOCK_ZIP_FREE:
220
 
                /* This is a free page in buf_pool->zip_free[].
221
 
                Such pages should only be accessed by the buddy allocator. */
222
 
                ut_error;
223
 
                break;
224
 
        case BUF_BLOCK_ZIP_PAGE:
225
 
        case BUF_BLOCK_ZIP_DIRTY:
226
 
        case BUF_BLOCK_FILE_PAGE:
227
 
                return(TRUE);
228
 
        case BUF_BLOCK_NOT_USED:
229
 
        case BUF_BLOCK_READY_FOR_USE:
230
 
        case BUF_BLOCK_MEMORY:
231
 
        case BUF_BLOCK_REMOVE_HASH:
232
 
                break;
233
 
        }
234
 
 
235
 
        return(FALSE);
236
 
}
237
 
 
238
 
/*************************************************************************
239
 
Determines if a block should be on unzip_LRU list. */
240
 
UNIV_INLINE
241
 
ibool
242
 
buf_page_belongs_to_unzip_LRU(
243
 
/*==========================*/
244
 
                                        /* out: TRUE if block belongs
245
 
                                        to unzip_LRU */
246
 
        const buf_page_t*       bpage)  /* in: pointer to control block */
247
 
{
248
 
        ut_ad(buf_page_in_file(bpage));
249
 
 
250
 
        return(bpage->zip.data
251
 
               && buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
252
 
}
253
 
 
254
 
/*************************************************************************
255
 
Determine the approximate LRU list position of a block. */
256
 
UNIV_INLINE
257
 
ulint
258
 
buf_page_get_LRU_position(
259
 
/*======================*/
260
 
                                        /* out: LRU list position */
261
 
        const buf_page_t*       bpage)  /* in: control block */
262
 
{
263
 
        ut_ad(buf_page_in_file(bpage));
264
 
 
265
 
        return(bpage->LRU_position);
266
 
}
267
 
 
268
 
/*************************************************************************
269
 
Gets the mutex of a block. */
270
 
UNIV_INLINE
271
 
mutex_t*
272
 
buf_page_get_mutex(
273
 
/*===============*/
274
 
                                        /* out: pointer to mutex
275
 
                                        protecting bpage */
276
 
        const buf_page_t*       bpage)  /* in: pointer to control block */
277
 
{
278
 
        switch (buf_page_get_state(bpage)) {
279
 
        case BUF_BLOCK_ZIP_FREE:
280
 
                ut_error;
281
 
                return(NULL);
282
 
        case BUF_BLOCK_ZIP_PAGE:
283
 
        case BUF_BLOCK_ZIP_DIRTY:
284
 
                return(&buf_pool_zip_mutex);
285
 
        default:
286
 
                return(&((buf_block_t*) bpage)->mutex);
287
 
        }
288
 
}
289
 
 
290
 
/*************************************************************************
291
 
Get the flush type of a page. */
292
 
UNIV_INLINE
293
 
enum buf_flush
294
 
buf_page_get_flush_type(
295
 
/*====================*/
296
 
                                        /* out: flush type */
297
 
        const buf_page_t*       bpage)  /* in: buffer page */
298
 
{
299
 
        enum buf_flush  flush_type = (enum buf_flush) bpage->flush_type;
300
 
 
301
 
#ifdef UNIV_DEBUG
302
 
        switch (flush_type) {
303
 
        case BUF_FLUSH_LRU:
304
 
        case BUF_FLUSH_SINGLE_PAGE:
305
 
        case BUF_FLUSH_LIST:
306
 
                return(flush_type);
307
 
        case BUF_FLUSH_N_TYPES:
308
 
                break;
309
 
        }
310
 
        ut_error;
311
 
#endif /* UNIV_DEBUG */
312
 
        return(flush_type);
313
 
}
314
 
/*************************************************************************
315
 
Set the flush type of a page. */
316
 
UNIV_INLINE
317
 
void
318
 
buf_page_set_flush_type(
319
 
/*====================*/
320
 
        buf_page_t*     bpage,          /* in: buffer page */
321
 
        enum buf_flush  flush_type)     /* in: flush type */
322
 
{
323
 
        bpage->flush_type = flush_type;
324
 
        ut_ad(buf_page_get_flush_type(bpage) == flush_type);
325
 
}
326
 
 
327
 
/*************************************************************************
328
 
Map a block to a file page. */
329
 
UNIV_INLINE
330
 
void
331
 
buf_block_set_file_page(
332
 
/*====================*/
333
 
        buf_block_t*            block,  /* in/out: pointer to control block */
334
 
        ulint                   space,  /* in: tablespace id */
335
 
        ulint                   page_no)/* in: page number */
336
 
{
337
 
        buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
338
 
        block->page.space = space;
339
 
        block->page.offset = page_no;
340
 
}
341
 
 
342
 
/*************************************************************************
343
 
Gets the io_fix state of a block. */
344
 
UNIV_INLINE
345
 
enum buf_io_fix
346
 
buf_page_get_io_fix(
347
 
/*================*/
348
 
                                        /* out: io_fix state */
349
 
        const buf_page_t*       bpage)  /* in: pointer to the control block */
350
 
{
351
 
        enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
352
 
#ifdef UNIV_DEBUG
353
 
        switch (io_fix) {
354
 
        case BUF_IO_NONE:
355
 
        case BUF_IO_READ:
356
 
        case BUF_IO_WRITE:
357
 
                return(io_fix);
358
 
        }
359
 
        ut_error;
360
 
#endif /* UNIV_DEBUG */
361
 
        return(io_fix);
362
 
}
363
 
 
364
 
/*************************************************************************
365
 
Gets the io_fix state of a block. */
366
 
UNIV_INLINE
367
 
enum buf_io_fix
368
 
buf_block_get_io_fix(
369
 
/*================*/
370
 
                                        /* out: io_fix state */
371
 
        const buf_block_t*      block)  /* in: pointer to the control block */
372
 
{
373
 
        return(buf_page_get_io_fix(&block->page));
374
 
}
375
 
 
376
 
/*************************************************************************
377
 
Sets the io_fix state of a block. */
378
 
UNIV_INLINE
379
 
void
380
 
buf_page_set_io_fix(
381
 
/*================*/
382
 
        buf_page_t*     bpage,  /* in/out: control block */
383
 
        enum buf_io_fix io_fix) /* in: io_fix state */
384
 
{
385
 
        ut_ad(buf_pool_mutex_own());
386
 
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
387
 
 
388
 
        bpage->io_fix = io_fix;
389
 
        ut_ad(buf_page_get_io_fix(bpage) == io_fix);
390
 
}
391
 
 
392
 
/*************************************************************************
393
 
Sets the io_fix state of a block. */
394
 
UNIV_INLINE
395
 
void
396
 
buf_block_set_io_fix(
397
 
/*=================*/
398
 
        buf_block_t*    block,  /* in/out: control block */
399
 
        enum buf_io_fix io_fix) /* in: io_fix state */
400
 
{
401
 
        buf_page_set_io_fix(&block->page, io_fix);
402
 
}
403
 
 
404
 
/************************************************************************
405
 
Determine if a buffer block can be relocated in memory.  The block
406
 
can be dirty, but it must not be I/O-fixed or bufferfixed. */
407
 
UNIV_INLINE
408
 
ibool
409
 
buf_page_can_relocate(
410
 
/*==================*/
411
 
        const buf_page_t*       bpage)  /* control block being relocated */
412
 
{
413
 
        ut_ad(buf_pool_mutex_own());
414
 
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
415
 
        ut_ad(buf_page_in_file(bpage));
416
 
        ut_ad(bpage->in_LRU_list);
417
 
 
418
 
        return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
419
 
               && bpage->buf_fix_count == 0);
420
 
}
421
 
 
422
 
/*************************************************************************
423
 
Determine if a block has been flagged old. */
424
 
UNIV_INLINE
425
 
ibool
426
 
buf_page_is_old(
427
 
/*============*/
428
 
                                        /* out: TRUE if old */
429
 
        const buf_page_t*       bpage)  /* in: control block */
430
 
{
431
 
        ut_ad(buf_page_in_file(bpage));
432
 
 
433
 
        return(bpage->old);
434
 
}
435
 
 
436
 
/*************************************************************************
437
 
Flag a block old. */
438
 
UNIV_INLINE
439
 
void
440
 
buf_page_set_old(
441
 
/*=============*/
442
 
        buf_page_t*     bpage,  /* in/out: control block */
443
 
        ibool           old)    /* in: old */
444
 
{
445
 
        ut_a(buf_page_in_file(bpage));
446
 
        ut_ad(buf_pool_mutex_own());
447
 
 
448
 
        bpage->old = old;
449
 
}
450
 
 
451
 
/*************************************************************************
452
 
Determine if a block has been accessed in the buffer pool. */
453
 
UNIV_INLINE
454
 
ibool
455
 
buf_page_is_accessed(
456
 
/*=================*/
457
 
                                        /* out: TRUE if accessed */
458
 
        const buf_page_t*       bpage)  /* in: control block */
459
 
{
460
 
        ut_ad(buf_page_in_file(bpage));
461
 
 
462
 
        return(bpage->accessed);
463
 
}
464
 
 
465
 
/*************************************************************************
466
 
Flag a block accessed. */
467
 
UNIV_INLINE
468
 
void
469
 
buf_page_set_accessed(
470
 
/*==================*/
471
 
        buf_page_t*     bpage,          /* in/out: control block */
472
 
        ibool           accessed)       /* in: accessed */
473
 
{
474
 
        ut_a(buf_page_in_file(bpage));
475
 
        ut_ad(mutex_own(buf_page_get_mutex(bpage)));
476
 
 
477
 
        bpage->accessed = accessed;
478
 
}
479
 
 
480
 
/*************************************************************************
481
 
Gets the buf_block_t handle of a buffered file block if an uncompressed
482
 
page frame exists, or NULL. */
483
 
UNIV_INLINE
484
 
buf_block_t*
485
 
buf_page_get_block(
486
 
/*===============*/
487
 
                                /* out: control block, or NULL */
488
 
        buf_page_t*     bpage)  /* in: control block, or NULL */
489
 
{
490
 
        if (UNIV_LIKELY(bpage != NULL)) {
491
 
                ut_ad(buf_page_in_file(bpage));
492
 
 
493
 
                if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
494
 
                        return((buf_block_t*) bpage);
495
 
                }
496
 
        }
497
 
 
498
 
        return(NULL);
499
 
}
500
 
 
501
 
#ifdef UNIV_DEBUG
502
 
/*************************************************************************
503
139
Gets a pointer to the memory frame of a block. */
504
140
UNIV_INLINE
505
141
buf_frame_t*
506
142
buf_block_get_frame(
507
143
/*================*/
508
 
                                        /* out: pointer to the frame */
509
 
        const buf_block_t*      block)  /* in: pointer to the control block */
 
144
                                /* out: pointer to the frame */
 
145
        buf_block_t*    block)  /* in: pointer to the control block */
510
146
{
511
147
        ut_ad(block);
512
 
 
513
 
        switch (buf_block_get_state(block)) {
514
 
        case BUF_BLOCK_ZIP_FREE:
515
 
        case BUF_BLOCK_ZIP_PAGE:
516
 
        case BUF_BLOCK_ZIP_DIRTY:
517
 
        case BUF_BLOCK_NOT_USED:
518
 
                ut_error;
519
 
                break;
520
 
        case BUF_BLOCK_FILE_PAGE:
521
 
                ut_a(block->page.buf_fix_count > 0);
522
 
                /* fall through */
523
 
        case BUF_BLOCK_READY_FOR_USE:
524
 
        case BUF_BLOCK_MEMORY:
525
 
        case BUF_BLOCK_REMOVE_HASH:
526
 
                goto ok;
527
 
        }
528
 
        ut_error;
529
 
ok:
530
 
        return((buf_frame_t*) block->frame);
531
 
}
532
 
#endif /* UNIV_DEBUG */
533
 
 
534
 
/*************************************************************************
535
 
Gets the space id of a block. */
536
 
UNIV_INLINE
537
 
ulint
538
 
buf_page_get_space(
539
 
/*===============*/
540
 
                                        /* out: space id */
541
 
        const buf_page_t*       bpage)  /* in: pointer to the control block */
542
 
{
543
 
        ut_ad(bpage);
544
 
        ut_a(buf_page_in_file(bpage));
545
 
 
546
 
        return(bpage->space);
 
148
        ut_ad(block >= buf_pool->blocks);
 
149
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
 
150
        ut_ad(block->state != BUF_BLOCK_NOT_USED);
 
151
        ut_ad((block->state != BUF_BLOCK_FILE_PAGE)
 
152
              || (block->buf_fix_count > 0));
 
153
 
 
154
        return(block->frame);
547
155
}
548
156
 
549
157
/*************************************************************************
552
160
ulint
553
161
buf_block_get_space(
554
162
/*================*/
555
 
                                        /* out: space id */
556
 
        const buf_block_t*      block)  /* in: pointer to the control block */
 
163
                                /* out: space id */
 
164
        buf_block_t*    block)  /* in: pointer to the control block */
557
165
{
558
166
        ut_ad(block);
559
 
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
560
 
 
561
 
        return(block->page.space);
562
 
}
563
 
 
564
 
/*************************************************************************
565
 
Gets the page number of a block. */
566
 
UNIV_INLINE
567
 
ulint
568
 
buf_page_get_page_no(
569
 
/*=================*/
570
 
                                        /* out: page number */
571
 
        const buf_page_t*       bpage)  /* in: pointer to the control block */
572
 
{
573
 
        ut_ad(bpage);
574
 
        ut_a(buf_page_in_file(bpage));
575
 
 
576
 
        return(bpage->offset);
 
167
        ut_ad(block >= buf_pool->blocks);
 
168
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
 
169
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
170
        ut_ad(block->buf_fix_count > 0);
 
171
 
 
172
        return(block->space);
577
173
}
578
174
 
579
175
/*************************************************************************
582
178
ulint
583
179
buf_block_get_page_no(
584
180
/*==================*/
585
 
                                        /* out: page number */
586
 
        const buf_block_t*      block)  /* in: pointer to the control block */
 
181
                                /* out: page number */
 
182
        buf_block_t*    block)  /* in: pointer to the control block */
587
183
{
588
184
        ut_ad(block);
589
 
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
590
 
 
591
 
        return(block->page.offset);
592
 
}
593
 
 
594
 
/*************************************************************************
595
 
Gets the compressed page size of a block. */
596
 
UNIV_INLINE
597
 
ulint
598
 
buf_page_get_zip_size(
599
 
/*==================*/
600
 
                                        /* out: compressed page size, or 0 */
601
 
        const buf_page_t*       bpage)  /* in: pointer to the control block */
602
 
{
603
 
        return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
604
 
}
605
 
 
606
 
/*************************************************************************
607
 
Gets the compressed page size of a block. */
608
 
UNIV_INLINE
609
 
ulint
610
 
buf_block_get_zip_size(
611
 
/*===================*/
612
 
                                        /* out: compressed page size, or 0 */
613
 
        const buf_block_t*      block)  /* in: pointer to the control block */
614
 
{
615
 
        return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
616
 
}
617
 
 
618
 
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
 
185
        ut_ad(block >= buf_pool->blocks);
 
186
        ut_ad(block < buf_pool->blocks + buf_pool->max_size);
 
187
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
188
        ut_ad(block->buf_fix_count > 0);
 
189
 
 
190
        return(block->offset);
 
191
}
 
192
 
619
193
/***********************************************************************
620
194
Gets the block to whose frame the pointer is pointing to. */
621
195
UNIV_INLINE
622
 
const buf_block_t*
 
196
buf_block_t*
623
197
buf_block_align(
624
198
/*============*/
625
 
                                /* out: pointer to block */
626
 
        const byte*     ptr)    /* in: pointer to a frame */
 
199
                        /* out: pointer to block */
 
200
        byte*   ptr)    /* in: pointer to a frame */
627
201
{
628
 
        const buf_block_t*      block;
629
 
        ulint                   space_id, page_no;
630
 
 
631
 
        ptr = (const byte*) ut_align_down(ptr, UNIV_PAGE_SIZE);
632
 
        page_no = mach_read_from_4(ptr + FIL_PAGE_OFFSET);
633
 
        space_id = mach_read_from_4(ptr + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
634
 
 
635
 
        block = (const buf_block_t*) buf_page_hash_get(space_id, page_no);
636
 
        ut_ad(block);
637
 
        ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
638
 
        ut_ad(block->frame == ptr);
 
202
        buf_block_t*    block;
 
203
        buf_frame_t*    frame_zero;
 
204
 
 
205
        ut_ad(ptr);
 
206
 
 
207
        frame_zero = buf_pool->frame_zero;
 
208
 
 
209
        if (UNIV_UNLIKELY((ulint)ptr < (ulint)frame_zero)
 
210
            || UNIV_UNLIKELY((ulint)ptr > (ulint)(buf_pool->high_end))) {
 
211
 
 
212
                ut_print_timestamp(stderr);
 
213
                fprintf(stderr,
 
214
                        "InnoDB: Error: trying to access a stray pointer %p\n"
 
215
                        "InnoDB: buf pool start is at %p, end at %p\n"
 
216
                        "InnoDB: Probable reason is database corruption"
 
217
                        " or memory\n"
 
218
                        "InnoDB: corruption. If this happens in an"
 
219
                        " InnoDB database recovery, see\n"
 
220
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
221
                        "forcing-recovery.html\n"
 
222
                        "InnoDB: how to force recovery.\n",
 
223
                        ptr, frame_zero,
 
224
                        buf_pool->high_end);
 
225
                ut_error;
 
226
        }
 
227
 
 
228
        block = *(buf_pool->blocks_of_frames + (((ulint)(ptr - frame_zero))
 
229
                                                >> UNIV_PAGE_SIZE_SHIFT));
639
230
        return(block);
640
231
}
641
232
 
642
 
/*************************************************************************
643
 
Gets the compressed page descriptor corresponding to an uncompressed page
644
 
if applicable. */
645
 
UNIV_INLINE
646
 
const page_zip_des_t*
647
 
buf_frame_get_page_zip(
 
233
/***********************************************************************
 
234
Gets the frame the pointer is pointing to. */
 
235
UNIV_INLINE
 
236
buf_frame_t*
 
237
buf_frame_align(
 
238
/*============*/
 
239
                        /* out: pointer to frame */
 
240
        byte*   ptr)    /* in: pointer to a frame */
 
241
{
 
242
        buf_frame_t*    frame;
 
243
 
 
244
        ut_ad(ptr);
 
245
 
 
246
        frame = ut_align_down(ptr, UNIV_PAGE_SIZE);
 
247
 
 
248
        if (UNIV_UNLIKELY((ulint)frame < (ulint)(buf_pool->frame_zero))
 
249
            || UNIV_UNLIKELY((ulint)frame >= (ulint)(buf_pool->high_end))) {
 
250
 
 
251
                ut_print_timestamp(stderr);
 
252
                fprintf(stderr,
 
253
                        "InnoDB: Error: trying to access a stray pointer %p\n"
 
254
                        "InnoDB: buf pool start is at %p, end at %p\n"
 
255
                        "InnoDB: Probable reason is database corruption"
 
256
                        " or memory\n"
 
257
                        "InnoDB: corruption. If this happens in an"
 
258
                        " InnoDB database recovery, see\n"
 
259
                        "InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
 
260
                        "forcing-recovery.html\n"
 
261
                        "InnoDB: how to force recovery.\n",
 
262
                        ptr, buf_pool->frame_zero,
 
263
                        buf_pool->high_end);
 
264
                ut_error;
 
265
        }
 
266
 
 
267
        return(frame);
 
268
}
 
269
 
 
270
/**************************************************************************
 
271
Gets the page number of a pointer pointing within a buffer frame containing
 
272
a file page. */
 
273
UNIV_INLINE
 
274
ulint
 
275
buf_frame_get_page_no(
 
276
/*==================*/
 
277
                        /* out: page number */
 
278
        byte*   ptr)    /* in: pointer to within a buffer frame */
 
279
{
 
280
        return(buf_block_get_page_no(buf_block_align(ptr)));
 
281
}
 
282
 
 
283
/**************************************************************************
 
284
Gets the space id of a pointer pointing within a buffer frame containing a
 
285
file page. */
 
286
UNIV_INLINE
 
287
ulint
 
288
buf_frame_get_space_id(
648
289
/*===================*/
649
 
                                /* out: compressed page descriptor, or NULL */
650
 
        const byte*     ptr)    /* in: pointer to the page */
 
290
                        /* out: space id */
 
291
        byte*   ptr)    /* in: pointer to within a buffer frame */
651
292
{
652
 
        const page_zip_des_t*   page_zip;
653
 
        buf_pool_mutex_enter();
654
 
        page_zip = buf_block_get_page_zip(buf_block_align(ptr));
655
 
        buf_pool_mutex_exit();
656
 
        return(page_zip);
 
293
        return(buf_block_get_space(buf_block_align(ptr)));
657
294
}
658
 
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
659
295
 
660
296
/**************************************************************************
661
297
Gets the space id, page offset, and byte offset within page of a
664
300
void
665
301
buf_ptr_get_fsp_addr(
666
302
/*=================*/
667
 
        const void*     ptr,    /* in: pointer to a buffer frame */
 
303
        byte*           ptr,    /* in: pointer to a buffer frame */
668
304
        ulint*          space,  /* out: space id */
669
305
        fil_addr_t*     addr)   /* out: page offset and byte offset */
670
306
{
671
 
        const page_t*   page = (const page_t*) ut_align_down(ptr,
672
 
                                                             UNIV_PAGE_SIZE);
673
 
 
674
 
        *space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
675
 
        addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
676
 
        addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
 
307
        buf_block_t*    block;
 
308
 
 
309
        block = buf_block_align(ptr);
 
310
 
 
311
        *space = buf_block_get_space(block);
 
312
        addr->page = buf_block_get_page_no(block);
 
313
        addr->boffset = ptr - buf_frame_align(ptr);
677
314
}
678
315
 
679
316
/**************************************************************************
681
318
in searches in the lock hash table. */
682
319
UNIV_INLINE
683
320
ulint
684
 
buf_block_get_lock_hash_val(
 
321
buf_frame_get_lock_hash_val(
685
322
/*========================*/
686
 
                                        /* out: lock hash value */
687
 
        const buf_block_t*      block)  /* in: block */
 
323
                        /* out: lock hash value */
 
324
        byte*   ptr)    /* in: pointer to within a buffer frame */
688
325
{
 
326
        buf_block_t*    block;
 
327
 
 
328
        block = buf_block_align(ptr);
 
329
 
689
330
        return(block->lock_hash_val);
690
331
}
691
332
 
692
 
/************************************************************************
693
 
Allocates a buffer block. */
 
333
/**************************************************************************
 
334
Gets the mutex number protecting the page record lock hash chain in the lock
 
335
table. */
694
336
UNIV_INLINE
695
 
buf_block_t*
696
 
buf_block_alloc(
697
 
/*============*/
698
 
                                /* out, own: the allocated block,
699
 
                                in state BUF_BLOCK_MEMORY */
700
 
        ulint   zip_size)       /* in: compressed page size in bytes,
701
 
                                or 0 if uncompressed tablespace */
 
337
mutex_t*
 
338
buf_frame_get_mutex(
 
339
/*================*/
 
340
                        /* out: mutex */
 
341
        byte*   ptr)    /* in: pointer to within a buffer frame */
702
342
{
703
343
        buf_block_t*    block;
704
344
 
705
 
        block = buf_LRU_get_free_block(zip_size);
706
 
 
707
 
        buf_block_set_state(block, BUF_BLOCK_MEMORY);
708
 
 
709
 
        return(block);
710
 
}
711
 
 
712
 
/************************************************************************
713
 
Frees a buffer block which does not contain a file page. */
714
 
UNIV_INLINE
715
 
void
716
 
buf_block_free(
717
 
/*===========*/
718
 
        buf_block_t*    block)  /* in, own: block to be freed */
719
 
{
720
 
        buf_pool_mutex_enter();
721
 
 
722
 
        mutex_enter(&block->mutex);
723
 
 
724
 
        ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
725
 
 
726
 
        buf_LRU_block_free_non_file_page(block);
727
 
 
728
 
        mutex_exit(&block->mutex);
729
 
 
730
 
        buf_pool_mutex_exit();
 
345
        block = buf_block_align(ptr);
 
346
 
 
347
        return(&block->mutex);
731
348
}
732
349
 
733
350
/*************************************************************************
736
353
byte*
737
354
buf_frame_copy(
738
355
/*===========*/
739
 
                                        /* out: buf */
740
 
        byte*                   buf,    /* in: buffer to copy to */
741
 
        const buf_frame_t*      frame)  /* in: buffer frame */
 
356
                                /* out: buf */
 
357
        byte*           buf,    /* in: buffer to copy to */
 
358
        buf_frame_t*    frame)  /* in: buffer frame */
742
359
{
743
360
        ut_ad(buf && frame);
744
361
 
769
386
buf_page_io_query(
770
387
/*==============*/
771
388
                                /* out: TRUE if io going on */
772
 
        buf_page_t*     bpage)  /* in: buf_pool block, must be bufferfixed */
 
389
        buf_block_t*    block)  /* in: buf_pool block, must be bufferfixed */
773
390
{
774
 
        ibool   io_fixed;
775
 
 
776
 
        buf_pool_mutex_enter();
777
 
 
778
 
        ut_ad(buf_page_in_file(bpage));
779
 
        ut_ad(bpage->buf_fix_count > 0);
780
 
 
781
 
        io_fixed = buf_page_get_io_fix(bpage) != BUF_IO_NONE;
782
 
        buf_pool_mutex_exit();
783
 
 
784
 
        return(io_fixed);
 
391
        mutex_enter(&(buf_pool->mutex));
 
392
 
 
393
        ut_ad(block->state == BUF_BLOCK_FILE_PAGE);
 
394
        ut_ad(block->buf_fix_count > 0);
 
395
 
 
396
        if (block->io_fix != 0) {
 
397
                mutex_exit(&(buf_pool->mutex));
 
398
 
 
399
                return(TRUE);
 
400
        }
 
401
 
 
402
        mutex_exit(&(buf_pool->mutex));
 
403
 
 
404
        return(FALSE);
785
405
}
786
406
 
787
407
/************************************************************************
788
 
Gets the youngest modification log sequence number for a frame.
789
 
Returns zero if not file page or no modification occurred yet. */
 
408
Gets the youngest modification log sequence number for a frame. Returns zero
 
409
if not a file page or no modification occurred yet. */
790
410
UNIV_INLINE
791
 
ib_uint64_t
792
 
buf_page_get_newest_modification(
793
 
/*=============================*/
794
 
                                        /* out: newest modification to page */
795
 
        const buf_page_t*       bpage)  /* in: block containing the
796
 
                                        page frame */
 
411
dulint
 
412
buf_frame_get_newest_modification(
 
413
/*==============================*/
 
414
                                /* out: newest modification to the page */
 
415
        buf_frame_t*    frame)  /* in: pointer to a frame */
797
416
{
798
 
        ib_uint64_t     lsn;
799
 
 
800
 
        buf_pool_mutex_enter();
801
 
 
802
 
        if (buf_page_in_file(bpage)) {
803
 
                lsn = bpage->newest_modification;
 
417
        buf_block_t*    block;
 
418
        dulint          lsn;
 
419
 
 
420
        ut_ad(frame);
 
421
 
 
422
        block = buf_block_align(frame);
 
423
 
 
424
        mutex_enter(&(buf_pool->mutex));
 
425
 
 
426
        if (block->state == BUF_BLOCK_FILE_PAGE) {
 
427
                lsn = block->newest_modification;
804
428
        } else {
805
 
                lsn = 0;
 
429
                lsn = ut_dulint_zero;
806
430
        }
807
431
 
808
 
        buf_pool_mutex_exit();
 
432
        mutex_exit(&(buf_pool->mutex));
809
433
 
810
434
        return(lsn);
811
435
}
815
439
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
816
440
on the block. */
817
441
UNIV_INLINE
818
 
void
 
442
dulint
 
443
buf_frame_modify_clock_inc(
 
444
/*=======================*/
 
445
                                /* out: new value */
 
446
        buf_frame_t*    frame)  /* in: pointer to a frame */
 
447
{
 
448
        buf_block_t*    block;
 
449
 
 
450
        ut_ad(frame);
 
451
 
 
452
        block = buf_block_align(frame);
 
453
 
 
454
#ifdef UNIV_SYNC_DEBUG
 
455
        ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
 
456
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
 
457
#endif /* UNIV_SYNC_DEBUG */
 
458
 
 
459
        UT_DULINT_INC(block->modify_clock);
 
460
 
 
461
        return(block->modify_clock);
 
462
}
 
463
 
 
464
/************************************************************************
 
465
Increments the modify clock of a frame by 1. The caller must (1) own the
 
466
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
 
467
on the block. */
 
468
UNIV_INLINE
 
469
dulint
819
470
buf_block_modify_clock_inc(
820
471
/*=======================*/
 
472
                                /* out: new value */
821
473
        buf_block_t*    block)  /* in: block */
822
474
{
823
475
#ifdef UNIV_SYNC_DEBUG
824
 
        ut_ad((buf_pool_mutex_own()
825
 
               && (block->page.buf_fix_count == 0))
 
476
        ut_ad((mutex_own(&(buf_pool->mutex)) && (block->buf_fix_count == 0))
826
477
              || rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
827
478
#endif /* UNIV_SYNC_DEBUG */
828
479
 
829
 
        block->modify_clock++;
 
480
        UT_DULINT_INC(block->modify_clock);
 
481
 
 
482
        return(block->modify_clock);
830
483
}
831
484
 
832
485
/************************************************************************
833
486
Returns the value of the modify clock. The caller must have an s-lock
834
487
or x-lock on the block. */
835
488
UNIV_INLINE
836
 
ib_uint64_t
 
489
dulint
837
490
buf_block_get_modify_clock(
838
491
/*=======================*/
839
492
                                /* out: value */
847
500
        return(block->modify_clock);
848
501
}
849
502
 
 
503
#ifdef UNIV_SYNC_DEBUG
850
504
/***********************************************************************
851
505
Increments the bufferfix count. */
852
506
UNIV_INLINE
853
507
void
854
 
buf_block_buf_fix_inc_func(
855
 
/*=======================*/
856
 
#ifdef UNIV_SYNC_DEBUG
857
 
        const char*     file,   /* in: file name */
858
 
        ulint           line,   /* in: line */
859
 
#endif /* UNIV_SYNC_DEBUG */
860
 
        buf_block_t*    block)  /* in: block to bufferfix */
 
508
buf_block_buf_fix_inc_debug(
 
509
/*========================*/
 
510
        buf_block_t*    block,  /* in: block to bufferfix */
 
511
        const char*     file __attribute__ ((unused)),  /* in: file name */
 
512
        ulint           line __attribute__ ((unused)))  /* in: line */
861
513
{
862
 
#ifdef UNIV_SYNC_DEBUG
863
514
        ibool   ret;
864
515
 
865
516
        ret = rw_lock_s_lock_func_nowait(&(block->debug_latch), file, line);
866
 
        ut_a(ret);
867
 
#endif /* UNIV_SYNC_DEBUG */
 
517
 
 
518
        ut_ad(ret == TRUE);
868
519
        ut_ad(mutex_own(&block->mutex));
869
 
 
870
 
        block->page.buf_fix_count++;
 
520
        block->buf_fix_count++;
871
521
}
872
 
#ifdef UNIV_SYNC_DEBUG
873
 
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
874
522
#else /* UNIV_SYNC_DEBUG */
875
 
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
876
 
#endif /* UNIV_SYNC_DEBUG */
877
 
 
878
523
/***********************************************************************
879
 
Decrements the bufferfix count. */
 
524
Increments the bufferfix count. */
880
525
UNIV_INLINE
881
526
void
882
 
buf_block_buf_fix_dec(
 
527
buf_block_buf_fix_inc(
883
528
/*==================*/
884
 
        buf_block_t*    block)  /* in: block to bufferunfix */
 
529
        buf_block_t*    block)  /* in: block to bufferfix */
885
530
{
886
531
        ut_ad(mutex_own(&block->mutex));
887
532
 
888
 
        block->page.buf_fix_count--;
889
 
#ifdef UNIV_SYNC_DEBUG
890
 
        rw_lock_s_unlock(&block->debug_latch);
891
 
#endif
 
533
        block->buf_fix_count++;
892
534
}
893
 
 
 
535
#endif /* UNIV_SYNC_DEBUG */
894
536
/**********************************************************************
895
537
Returns the control block of a file page, NULL if not found. */
896
538
UNIV_INLINE
897
 
buf_page_t*
 
539
buf_block_t*
898
540
buf_page_hash_get(
899
541
/*==============*/
900
542
                        /* out: block, NULL if not found */
901
543
        ulint   space,  /* in: space id */
902
544
        ulint   offset) /* in: offset of the page within space */
903
545
{
904
 
        buf_page_t*     bpage;
 
546
        buf_block_t*    block;
905
547
        ulint           fold;
906
548
 
907
549
        ut_ad(buf_pool);
908
 
        ut_ad(buf_pool_mutex_own());
 
550
        ut_ad(mutex_own(&(buf_pool->mutex)));
909
551
 
910
552
        /* Look for the page in the hash table */
911
553
 
912
554
        fold = buf_page_address_fold(space, offset);
913
555
 
914
 
        HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
915
 
                    bpage->space == space && bpage->offset == offset);
916
 
        if (bpage) {
917
 
                ut_a(buf_page_in_file(bpage));
918
 
                ut_ad(bpage->in_page_hash);
919
 
                ut_ad(!bpage->in_zip_hash);
920
 
                UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
921
 
        }
922
 
 
923
 
        return(bpage);
924
 
}
925
 
 
926
 
/**********************************************************************
927
 
Returns the control block of a file page, NULL if not found
928
 
or an uncompressed page frame does not exist. */
929
 
UNIV_INLINE
930
 
buf_block_t*
931
 
buf_block_hash_get(
932
 
/*===============*/
933
 
                        /* out: block, NULL if not found */
934
 
        ulint   space,  /* in: space id */
935
 
        ulint   offset) /* in: offset of the page within space */
936
 
{
937
 
        return(buf_page_get_block(buf_page_hash_get(space, offset)));
938
 
}
939
 
 
940
 
/************************************************************************
941
 
Returns TRUE if the page can be found in the buffer pool hash table. NOTE
942
 
that it is possible that the page is not yet read from disk, though. */
943
 
UNIV_INLINE
944
 
ibool
945
 
buf_page_peek(
946
 
/*==========*/
947
 
                        /* out: TRUE if found from page hash table,
948
 
                        NOTE that the page is not necessarily yet read
949
 
                        from disk! */
950
 
        ulint   space,  /* in: space id */
951
 
        ulint   offset) /* in: page number */
952
 
{
953
 
        const buf_page_t*       bpage;
954
 
 
955
 
        buf_pool_mutex_enter();
956
 
 
957
 
        bpage = buf_page_hash_get(space, offset);
958
 
 
959
 
        buf_pool_mutex_exit();
960
 
 
961
 
        return(bpage != NULL);
962
 
}
963
 
 
964
 
/************************************************************************
965
 
Releases a compressed-only page acquired with buf_page_get_zip(). */
966
 
UNIV_INLINE
967
 
void
968
 
buf_page_release_zip(
969
 
/*=================*/
970
 
        buf_page_t*     bpage)          /* in: buffer block */
971
 
{
972
 
        buf_block_t*    block;
973
 
 
974
 
        ut_ad(bpage);
975
 
        ut_a(bpage->buf_fix_count > 0);
976
 
 
977
 
        switch (buf_page_get_state(bpage)) {
978
 
        case BUF_BLOCK_ZIP_PAGE:
979
 
        case BUF_BLOCK_ZIP_DIRTY:
980
 
                mutex_enter(&buf_pool_zip_mutex);
981
 
                bpage->buf_fix_count--;
982
 
                mutex_exit(&buf_pool_zip_mutex);
983
 
                return;
984
 
        case BUF_BLOCK_FILE_PAGE:
985
 
                block = (buf_block_t*) bpage;
986
 
                mutex_enter(&block->mutex);
987
 
#ifdef UNIV_SYNC_DEBUG
988
 
                rw_lock_s_unlock(&block->debug_latch);
989
 
#endif
990
 
                bpage->buf_fix_count--;
991
 
                mutex_exit(&block->mutex);
992
 
                return;
993
 
        case BUF_BLOCK_ZIP_FREE:
994
 
        case BUF_BLOCK_NOT_USED:
995
 
        case BUF_BLOCK_READY_FOR_USE:
996
 
        case BUF_BLOCK_MEMORY:
997
 
        case BUF_BLOCK_REMOVE_HASH:
998
 
                break;
999
 
        }
1000
 
 
1001
 
        ut_error;
 
556
        HASH_SEARCH(hash, buf_pool->page_hash, fold, block,
 
557
                    (block->space == space) && (block->offset == offset));
 
558
        ut_a(block == NULL || block->state == BUF_BLOCK_FILE_PAGE);
 
559
 
 
560
        return(block);
 
561
}
 
562
 
 
563
/************************************************************************
 
564
Tries to get the page, but if file io is required, releases all latches
 
565
in mtr down to the given savepoint. If io is required, this function
 
566
retrieves the page to buffer buf_pool, but does not bufferfix it or latch
 
567
it. */
 
568
UNIV_INLINE
 
569
buf_frame_t*
 
570
buf_page_get_release_on_io(
 
571
/*=======================*/
 
572
                                /* out: pointer to the frame, or NULL
 
573
                                if not in buffer buf_pool */
 
574
        ulint   space,          /* in: space id */
 
575
        ulint   offset,         /* in: offset of the page within space
 
576
                                in units of a page */
 
577
        buf_frame_t* guess,     /* in: guessed frame or NULL */
 
578
        ulint   rw_latch,       /* in: RW_X_LATCH, RW_S_LATCH,
 
579
                                or RW_NO_LATCH */
 
580
        ulint   savepoint,      /* in: mtr savepoint */
 
581
        mtr_t*  mtr)            /* in: mtr */
 
582
{
 
583
        buf_frame_t*    frame;
 
584
 
 
585
        frame = buf_page_get_gen(space, offset, rw_latch, guess,
 
586
                                 BUF_GET_IF_IN_POOL,
 
587
                                 __FILE__, __LINE__,
 
588
                                 mtr);
 
589
        if (frame != NULL) {
 
590
 
 
591
                return(frame);
 
592
        }
 
593
 
 
594
        /* The page was not in the buffer buf_pool: release the latches
 
595
        down to the savepoint */
 
596
 
 
597
        mtr_rollback_to_savepoint(mtr, savepoint);
 
598
 
 
599
        buf_page_get(space, offset, RW_S_LATCH, mtr);
 
600
 
 
601
        /* When we get here, the page is in buffer, but we release
 
602
        the latches again down to the savepoint, before returning */
 
603
 
 
604
        mtr_rollback_to_savepoint(mtr, savepoint);
 
605
 
 
606
        return(NULL);
1002
607
}
1003
608
 
1004
609
/************************************************************************
1015
620
{
1016
621
        ut_ad(block);
1017
622
 
1018
 
        ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1019
 
        ut_a(block->page.buf_fix_count > 0);
 
623
        ut_a(block->state == BUF_BLOCK_FILE_PAGE);
 
624
        ut_a(block->buf_fix_count > 0);
1020
625
 
1021
626
        if (rw_latch == RW_X_LATCH && mtr->modifications) {
1022
 
                buf_pool_mutex_enter();
 
627
                mutex_enter(&buf_pool->mutex);
1023
628
                buf_flush_note_modification(block, mtr);
1024
 
                buf_pool_mutex_exit();
 
629
                mutex_exit(&buf_pool->mutex);
1025
630
        }
1026
631
 
1027
632
        mutex_enter(&block->mutex);
1029
634
#ifdef UNIV_SYNC_DEBUG
1030
635
        rw_lock_s_unlock(&(block->debug_latch));
1031
636
#endif
1032
 
        block->page.buf_fix_count--;
 
637
        block->buf_fix_count--;
1033
638
 
1034
639
        mutex_exit(&block->mutex);
1035
640
 
1044
649
/*************************************************************************
1045
650
Adds latch level info for the rw-lock protecting the buffer frame. This
1046
651
should be called in the debug version after a successful latching of a
1047
 
page if we know the latching order level of the acquired latch. */
 
652
page if we know the latching order level of the acquired latch. If
 
653
UNIV_SYNC_DEBUG is not defined, compiles to an empty function. */
1048
654
UNIV_INLINE
1049
655
void
1050
 
buf_block_dbg_add_level(
1051
 
/*====================*/
1052
 
        buf_block_t*    block,  /* in: buffer page
 
656
buf_page_dbg_add_level(
 
657
/*===================*/
 
658
        buf_frame_t*    frame __attribute__((unused)), /* in: buffer page
1053
659
                                where we have acquired latch */
1054
 
        ulint           level)  /* in: latching order level */
 
660
        ulint           level __attribute__((unused))) /* in: latching order
 
661
                                level */
1055
662
{
1056
 
        sync_thread_add_level(&block->lock, level);
 
663
        sync_thread_add_level(&(buf_block_align(frame)->lock), level);
1057
664
}
1058
665
#endif /* UNIV_SYNC_DEBUG */