1
/*****************************************************************************
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
6
Portions of this file contain modifications contributed and copyrighted by
7
Google, Inc. Those modifications are gratefully acknowledged and are described
8
briefly in the InnoDB documentation. The contributions by Google are
9
incorporated with their permission, and subject to the conditions contained in
10
the file COPYING.Google.
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
St, Fifth Floor, Boston, MA 02110-1301 USA
24
*****************************************************************************/
26
/**************************************************//**
27
@file include/buf0buf.ic
28
The database buffer buf_pool
30
Created 11/5/1995 Heikki Tuuri
31
*******************************************************/
39
/*********************************************************************//**
40
Gets the current size of buffer buf_pool in bytes.
41
@return size in bytes */
44
buf_pool_get_curr_size(void)
45
/*========================*/
47
return(srv_buf_pool_curr_size);
50
/*********************************************************************//**
51
Gets the current size of buffer buf_pool in pages.
52
@return size in pages*/
55
buf_pool_get_n_pages(void)
56
/*======================*/
58
return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
61
/********************************************************************//**
62
Reads the freed_page_clock of a buffer block.
63
@return freed_page_clock */
66
buf_page_get_freed_page_clock(
67
/*==========================*/
68
const buf_page_t* bpage) /*!< in: block */
70
/* This is sometimes read without holding buf_pool->mutex. */
71
return(bpage->freed_page_clock);
74
/********************************************************************//**
75
Reads the freed_page_clock of a buffer block.
76
@return freed_page_clock */
79
buf_block_get_freed_page_clock(
80
/*===========================*/
81
const buf_block_t* block) /*!< in: block */
83
return(buf_page_get_freed_page_clock(&block->page));
86
/********************************************************************//**
87
Recommends a move of a block to the start of the LRU list if there is danger
88
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
90
@return TRUE if should be made younger */
93
buf_page_peek_if_too_old(
94
/*=====================*/
95
const buf_page_t* bpage) /*!< in: block to make younger */
97
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
99
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
100
/* If eviction has not started yet, do not update the
101
statistics or move blocks in the LRU list. This is
102
either the warm-up phase or an in-memory workload. */
104
} else if (buf_LRU_old_threshold_ms && bpage->old) {
105
unsigned access_time = buf_page_is_accessed(bpage);
108
&& ((ib_uint32_t) (ut_time_ms() - access_time))
109
>= buf_LRU_old_threshold_ms) {
113
buf_pool->stat.n_pages_not_made_young++;
116
/* FIXME: bpage->freed_page_clock is 31 bits */
117
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
118
> ((ulint) bpage->freed_page_clock
119
+ (buf_pool->curr_size
120
* (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
121
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
125
/*********************************************************************//**
126
Gets the state of a block.
132
const buf_page_t* bpage) /*!< in: pointer to the control block */
134
enum buf_page_state state = (enum buf_page_state) bpage->state;
138
case BUF_BLOCK_ZIP_FREE:
139
case BUF_BLOCK_ZIP_PAGE:
140
case BUF_BLOCK_ZIP_DIRTY:
141
case BUF_BLOCK_NOT_USED:
142
case BUF_BLOCK_READY_FOR_USE:
143
case BUF_BLOCK_FILE_PAGE:
144
case BUF_BLOCK_MEMORY:
145
case BUF_BLOCK_REMOVE_HASH:
150
#endif /* UNIV_DEBUG */
154
/*********************************************************************//**
155
Gets the state of a block.
161
const buf_block_t* block) /*!< in: pointer to the control block */
163
return(buf_page_get_state(&block->page));
165
/*********************************************************************//**
166
Sets the state of a block. */
171
buf_page_t* bpage, /*!< in/out: pointer to control block */
172
enum buf_page_state state) /*!< in: state */
175
enum buf_page_state old_state = buf_page_get_state(bpage);
178
case BUF_BLOCK_ZIP_FREE:
181
case BUF_BLOCK_ZIP_PAGE:
182
ut_a(state == BUF_BLOCK_ZIP_DIRTY);
184
case BUF_BLOCK_ZIP_DIRTY:
185
ut_a(state == BUF_BLOCK_ZIP_PAGE);
187
case BUF_BLOCK_NOT_USED:
188
ut_a(state == BUF_BLOCK_READY_FOR_USE);
190
case BUF_BLOCK_READY_FOR_USE:
191
ut_a(state == BUF_BLOCK_MEMORY
192
|| state == BUF_BLOCK_FILE_PAGE
193
|| state == BUF_BLOCK_NOT_USED);
195
case BUF_BLOCK_MEMORY:
196
ut_a(state == BUF_BLOCK_NOT_USED);
198
case BUF_BLOCK_FILE_PAGE:
199
ut_a(state == BUF_BLOCK_NOT_USED
200
|| state == BUF_BLOCK_REMOVE_HASH);
202
case BUF_BLOCK_REMOVE_HASH:
203
ut_a(state == BUF_BLOCK_MEMORY);
206
#endif /* UNIV_DEBUG */
207
bpage->state = state;
208
ut_ad(buf_page_get_state(bpage) == state);
211
/*********************************************************************//**
212
Sets the state of a block. */
217
buf_block_t* block, /*!< in/out: pointer to control block */
218
enum buf_page_state state) /*!< in: state */
220
buf_page_set_state(&block->page, state);
223
/*********************************************************************//**
224
Determines if a block is mapped to a tablespace.
225
@return TRUE if mapped */
230
const buf_page_t* bpage) /*!< in: pointer to control block */
232
switch (buf_page_get_state(bpage)) {
233
case BUF_BLOCK_ZIP_FREE:
234
/* This is a free page in buf_pool->zip_free[].
235
Such pages should only be accessed by the buddy allocator. */
238
case BUF_BLOCK_ZIP_PAGE:
239
case BUF_BLOCK_ZIP_DIRTY:
240
case BUF_BLOCK_FILE_PAGE:
242
case BUF_BLOCK_NOT_USED:
243
case BUF_BLOCK_READY_FOR_USE:
244
case BUF_BLOCK_MEMORY:
245
case BUF_BLOCK_REMOVE_HASH:
252
#ifndef UNIV_HOTBACKUP
253
/*********************************************************************//**
254
Determines if a block should be on unzip_LRU list.
255
@return TRUE if block belongs to unzip_LRU */
258
buf_page_belongs_to_unzip_LRU(
259
/*==========================*/
260
const buf_page_t* bpage) /*!< in: pointer to control block */
262
ut_ad(buf_page_in_file(bpage));
264
return(bpage->zip.data
265
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
268
/*********************************************************************//**
269
Gets the mutex of a block.
270
@return pointer to mutex protecting bpage */
275
const buf_page_t* bpage) /*!< in: pointer to control block */
277
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
279
switch (buf_page_get_state(bpage)) {
280
case BUF_BLOCK_ZIP_FREE:
283
case BUF_BLOCK_ZIP_PAGE:
284
case BUF_BLOCK_ZIP_DIRTY:
285
return(&buf_pool->zip_mutex);
287
return(&((buf_block_t*) bpage)->mutex);
291
/*********************************************************************//**
292
Get the flush type of a page.
293
@return flush type */
296
buf_page_get_flush_type(
297
/*====================*/
298
const buf_page_t* bpage) /*!< in: buffer page */
300
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
303
switch (flush_type) {
305
case BUF_FLUSH_SINGLE_PAGE:
308
case BUF_FLUSH_N_TYPES:
312
#endif /* UNIV_DEBUG */
315
/*********************************************************************//**
316
Set the flush type of a page. */
319
buf_page_set_flush_type(
320
/*====================*/
321
buf_page_t* bpage, /*!< in: buffer page */
322
enum buf_flush flush_type) /*!< in: flush type */
324
bpage->flush_type = flush_type;
325
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
328
/*********************************************************************//**
329
Map a block to a file page. */
332
buf_block_set_file_page(
333
/*====================*/
334
buf_block_t* block, /*!< in/out: pointer to control block */
335
ulint space, /*!< in: tablespace id */
336
ulint page_no)/*!< in: page number */
338
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
339
block->page.space = space;
340
block->page.offset = page_no;
343
/*********************************************************************//**
344
Gets the io_fix state of a block.
345
@return io_fix state */
350
const buf_page_t* bpage) /*!< in: pointer to the control block */
352
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
361
#endif /* UNIV_DEBUG */
365
/*********************************************************************//**
366
Gets the io_fix state of a block.
367
@return io_fix state */
370
buf_block_get_io_fix(
371
/*=================*/
372
const buf_block_t* block) /*!< in: pointer to the control block */
374
return(buf_page_get_io_fix(&block->page));
377
/*********************************************************************//**
378
Sets the io_fix state of a block. */
383
buf_page_t* bpage, /*!< in/out: control block */
384
enum buf_io_fix io_fix) /*!< in: io_fix state */
387
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
388
ut_ad(buf_pool_mutex_own(buf_pool));
390
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
392
bpage->io_fix = io_fix;
393
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
396
/*********************************************************************//**
397
Sets the io_fix state of a block. */
400
buf_block_set_io_fix(
401
/*=================*/
402
buf_block_t* block, /*!< in/out: control block */
403
enum buf_io_fix io_fix) /*!< in: io_fix state */
405
buf_page_set_io_fix(&block->page, io_fix);
408
/********************************************************************//**
409
Determine if a buffer block can be relocated in memory. The block
410
can be dirty, but it must not be I/O-fixed or bufferfixed. */
413
buf_page_can_relocate(
414
/*==================*/
415
const buf_page_t* bpage) /*!< control block being relocated */
418
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
419
ut_ad(buf_pool_mutex_own(buf_pool));
421
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
422
ut_ad(buf_page_in_file(bpage));
423
ut_ad(bpage->in_LRU_list);
425
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
426
&& bpage->buf_fix_count == 0);
429
/*********************************************************************//**
430
Determine if a block has been flagged old.
431
@return TRUE if old */
436
const buf_page_t* bpage) /*!< in: control block */
439
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
440
ut_ad(buf_pool_mutex_own(buf_pool));
442
ut_ad(buf_page_in_file(bpage));
447
/*********************************************************************//**
453
buf_page_t* bpage, /*!< in/out: control block */
454
ibool old) /*!< in: old */
457
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
458
#endif /* UNIV_DEBUG */
459
ut_a(buf_page_in_file(bpage));
460
ut_ad(buf_pool_mutex_own(buf_pool));
461
ut_ad(bpage->in_LRU_list);
463
#ifdef UNIV_LRU_DEBUG
464
ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
465
/* If a block is flagged "old", the LRU_old list must exist. */
466
ut_a(!old || buf_pool->LRU_old);
468
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
469
const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
470
const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
471
if (prev->old == next->old) {
472
ut_a(prev->old == old);
475
ut_a(buf_pool->LRU_old == (old ? bpage : next));
478
#endif /* UNIV_LRU_DEBUG */
483
/*********************************************************************//**
484
Determine the time of first access of a block in the buffer pool.
485
@return ut_time_ms() at the time of first access, 0 if not accessed */
488
buf_page_is_accessed(
489
/*=================*/
490
const buf_page_t* bpage) /*!< in: control block */
492
ut_ad(buf_page_in_file(bpage));
494
return(bpage->access_time);
497
/*********************************************************************//**
498
Flag a block accessed. */
501
buf_page_set_accessed(
502
/*==================*/
503
buf_page_t* bpage, /*!< in/out: control block */
504
ulint time_ms) /*!< in: ut_time_ms() */
507
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
508
ut_ad(buf_pool_mutex_own(buf_pool));
510
ut_a(buf_page_in_file(bpage));
512
if (!bpage->access_time) {
513
/* Make this the time of the first access. */
514
bpage->access_time = time_ms;
518
/*********************************************************************//**
519
Gets the buf_block_t handle of a buffered file block if an uncompressed
520
page frame exists, or NULL.
521
@return control block, or NULL */
526
buf_page_t* bpage) /*!< in: control block, or NULL */
528
if (UNIV_LIKELY(bpage != NULL)) {
529
ut_ad(buf_page_in_file(bpage));
531
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
532
return((buf_block_t*) bpage);
538
#endif /* !UNIV_HOTBACKUP */
541
/*********************************************************************//**
542
Gets a pointer to the memory frame of a block.
543
@return pointer to the frame */
548
const buf_block_t* block) /*!< in: pointer to the control block */
552
switch (buf_block_get_state(block)) {
553
case BUF_BLOCK_ZIP_FREE:
554
case BUF_BLOCK_ZIP_PAGE:
555
case BUF_BLOCK_ZIP_DIRTY:
556
case BUF_BLOCK_NOT_USED:
559
case BUF_BLOCK_FILE_PAGE:
560
# ifndef UNIV_HOTBACKUP
561
ut_a(block->page.buf_fix_count > 0);
562
# endif /* !UNIV_HOTBACKUP */
564
case BUF_BLOCK_READY_FOR_USE:
565
case BUF_BLOCK_MEMORY:
566
case BUF_BLOCK_REMOVE_HASH:
571
return((buf_frame_t*) block->frame);
573
#endif /* UNIV_DEBUG */
575
/*********************************************************************//**
576
Gets the space id of a block.
582
const buf_page_t* bpage) /*!< in: pointer to the control block */
585
ut_a(buf_page_in_file(bpage));
587
return(bpage->space);
590
/*********************************************************************//**
591
Gets the space id of a block.
597
const buf_block_t* block) /*!< in: pointer to the control block */
600
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
602
return(block->page.space);
605
/*********************************************************************//**
606
Gets the page number of a block.
607
@return page number */
610
buf_page_get_page_no(
611
/*=================*/
612
const buf_page_t* bpage) /*!< in: pointer to the control block */
615
ut_a(buf_page_in_file(bpage));
617
return(bpage->offset);
620
/*********************************************************************//**
621
Gets the page number of a block.
622
@return page number */
625
buf_block_get_page_no(
626
/*==================*/
627
const buf_block_t* block) /*!< in: pointer to the control block */
630
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
632
return(block->page.offset);
635
/*********************************************************************//**
636
Gets the compressed page size of a block.
637
@return compressed page size, or 0 */
640
buf_page_get_zip_size(
641
/*==================*/
642
const buf_page_t* bpage) /*!< in: pointer to the control block */
644
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
647
/*********************************************************************//**
648
Gets the compressed page size of a block.
649
@return compressed page size, or 0 */
652
buf_block_get_zip_size(
653
/*===================*/
654
const buf_block_t* block) /*!< in: pointer to the control block */
656
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
659
#ifndef UNIV_HOTBACKUP
660
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
661
/*********************************************************************//**
662
Gets the compressed page descriptor corresponding to an uncompressed page
664
@return compressed page descriptor, or NULL */
666
const page_zip_des_t*
667
buf_frame_get_page_zip(
668
/*===================*/
669
const byte* ptr) /*!< in: pointer to the page */
671
return(buf_block_get_page_zip(buf_block_align(ptr)));
673
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
674
#endif /* !UNIV_HOTBACKUP */
676
/**********************************************************************//**
677
Gets the space id, page offset, and byte offset within page of a
678
pointer pointing to a buffer frame containing a file page. */
681
buf_ptr_get_fsp_addr(
682
/*=================*/
683
const void* ptr, /*!< in: pointer to a buffer frame */
684
ulint* space, /*!< out: space id */
685
fil_addr_t* addr) /*!< out: page offset and byte offset */
687
const page_t* page = (const page_t*) ut_align_down(ptr,
690
*space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
691
addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
692
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
695
#ifndef UNIV_HOTBACKUP
696
/**********************************************************************//**
697
Gets the hash value of the page the pointer is pointing to. This can be used
698
in searches in the lock hash table.
699
@return lock hash value */
702
buf_block_get_lock_hash_val(
703
/*========================*/
704
const buf_block_t* block) /*!< in: block */
707
ut_ad(buf_page_in_file(&block->page));
708
#ifdef UNIV_SYNC_DEBUG
709
ut_ad(rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_EXCLUSIVE)
710
|| rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_SHARED));
711
#endif /* UNIV_SYNC_DEBUG */
712
return(block->lock_hash_val);
715
/********************************************************************//**
716
Frees a buffer block which does not contain a file page. */
721
buf_block_t* block) /*!< in, own: block to be freed */
723
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
725
buf_pool_mutex_enter(buf_pool);
727
mutex_enter(&block->mutex);
729
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
731
buf_LRU_block_free_non_file_page(block);
733
mutex_exit(&block->mutex);
735
buf_pool_mutex_exit(buf_pool);
737
#endif /* !UNIV_HOTBACKUP */
739
/*********************************************************************//**
740
Copies contents of a buffer frame to a given buffer.
746
byte* buf, /*!< in: buffer to copy to */
747
const buf_frame_t* frame) /*!< in: buffer frame */
751
ut_memcpy(buf, frame, UNIV_PAGE_SIZE);
756
#ifndef UNIV_HOTBACKUP
757
/********************************************************************//**
758
Calculates a folded value of a file page address to use in the page hash
760
@return the folded value */
763
buf_page_address_fold(
764
/*==================*/
765
ulint space, /*!< in: space id */
766
ulint offset) /*!< in: offset of the page within space */
768
return((space << 20) + space + offset);
771
/********************************************************************//**
772
Gets the youngest modification log sequence number for a frame.
773
Returns zero if not file page or no modification occurred yet.
774
@return newest modification to page */
777
buf_page_get_newest_modification(
778
/*=============================*/
779
const buf_page_t* bpage) /*!< in: block containing the
783
mutex_t* block_mutex = buf_page_get_mutex(bpage);
785
mutex_enter(block_mutex);
787
if (buf_page_in_file(bpage)) {
788
lsn = bpage->newest_modification;
793
mutex_exit(block_mutex);
798
/********************************************************************//**
799
Increments the modify clock of a frame by 1. The caller must (1) own the
800
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
804
buf_block_modify_clock_inc(
805
/*=======================*/
806
buf_block_t* block) /*!< in: block */
808
#ifdef UNIV_SYNC_DEBUG
809
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
811
ut_ad((buf_pool_mutex_own(buf_pool)
812
&& (block->page.buf_fix_count == 0))
813
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
814
#endif /* UNIV_SYNC_DEBUG */
816
block->modify_clock++;
819
/********************************************************************//**
820
Returns the value of the modify clock. The caller must have an s-lock
821
or x-lock on the block.
825
buf_block_get_modify_clock(
826
/*=======================*/
827
buf_block_t* block) /*!< in: block */
829
#ifdef UNIV_SYNC_DEBUG
830
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
831
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
832
#endif /* UNIV_SYNC_DEBUG */
834
return(block->modify_clock);
837
/*******************************************************************//**
838
Increments the bufferfix count. */
841
buf_block_buf_fix_inc_func(
842
/*=======================*/
843
#ifdef UNIV_SYNC_DEBUG
844
const char* file, /*!< in: file name */
845
ulint line, /*!< in: line */
846
#endif /* UNIV_SYNC_DEBUG */
847
buf_block_t* block) /*!< in/out: block to bufferfix */
849
#ifdef UNIV_SYNC_DEBUG
852
ret = rw_lock_s_lock_nowait(&(block->debug_latch), file, line);
854
#endif /* UNIV_SYNC_DEBUG */
855
ut_ad(mutex_own(&block->mutex));
857
block->page.buf_fix_count++;
859
#ifdef UNIV_SYNC_DEBUG
860
/** Increments the bufferfix count.
861
@param b in/out: block to bufferfix
862
@param f in: file name where requested
863
@param l in: line number where requested */
864
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
865
#else /* UNIV_SYNC_DEBUG */
866
/** Increments the bufferfix count.
867
@param b in/out: block to bufferfix
868
@param f in: file name where requested
869
@param l in: line number where requested */
870
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
871
#endif /* UNIV_SYNC_DEBUG */
873
/*******************************************************************//**
874
Decrements the bufferfix count. */
877
buf_block_buf_fix_dec(
878
/*==================*/
879
buf_block_t* block) /*!< in/out: block to bufferunfix */
881
ut_ad(mutex_own(&block->mutex));
883
block->page.buf_fix_count--;
884
#ifdef UNIV_SYNC_DEBUG
885
rw_lock_s_unlock(&block->debug_latch);
889
/******************************************************************//**
890
Returns the buffer pool instance given a page instance
896
const buf_page_t* bpage) /*!< in: buffer pool page */
898
/* Every page must be in some buffer pool. */
899
ut_ad(bpage->buf_pool != NULL);
901
return(bpage->buf_pool);
904
/******************************************************************//**
905
Returns the buffer pool instance given a block instance
911
const buf_block_t* block) /*!< in: block */
913
return(buf_pool_from_bpage(&block->page));
916
/******************************************************************//**
917
Returns the buffer pool instance given space and offset of page
918
@return buffer pool */
923
ulint space, /*!< in: space id */
924
ulint offset) /*!< in: offset of the page within space */
928
ulint ignored_offset;
930
ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/
931
fold = buf_page_address_fold(space, ignored_offset);
932
index = fold % srv_buf_pool_instances;
933
return buf_pool_ptr[index];
936
/******************************************************************//**
937
Returns the buffer pool instance given its array index
938
@return buffer pool */
943
ulint index) /*!< in: array index to get
944
buffer pool instance from */
946
return buf_pool_ptr[index];
949
/******************************************************************//**
950
Returns the control block of a file page, NULL if not found.
951
@return block, NULL if not found */
954
buf_page_hash_get_low(
955
/*==================*/
956
buf_pool_t* buf_pool, /*!< buffer pool instance */
957
ulint space, /*!< in: space id */
958
ulint offset, /*!< in: offset of the page
960
ulint fold) /*!< in: buf_page_address_fold(
966
ut_ad(buf_pool_mutex_own(buf_pool));
967
ut_ad(fold == buf_page_address_fold(space, offset));
969
/* Look for the page in the hash table */
971
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
972
ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
973
&& buf_page_in_file(bpage)),
974
bpage->space == space && bpage->offset == offset);
976
ut_a(buf_page_in_file(bpage));
977
ut_ad(bpage->in_page_hash);
978
ut_ad(!bpage->in_zip_hash);
979
#if UNIV_WORD_SIZE == 4
980
/* On 32-bit systems, there is no padding in
981
buf_page_t. On other systems, Valgrind could complain
982
about uninitialized pad bytes. */
983
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
990
/******************************************************************//**
991
Returns the control block of a file page, NULL if not found.
992
@return block, NULL if not found or not a real control block */
997
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
998
ulint space, /*!< in: space id */
999
ulint offset) /*!< in: offset of the page
1003
ulint fold = buf_page_address_fold(space, offset);
1005
bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
1007
if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
1014
/******************************************************************//**
1015
Returns the control block of a file page, NULL if not found
1016
or an uncompressed page frame does not exist.
1017
@return block, NULL if not found */
1022
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1023
ulint space, /*!< in: space id */
1024
ulint offset) /*!< in: offset of the page
1029
block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
1034
/********************************************************************//**
1035
Returns TRUE if the page can be found in the buffer pool hash table.
1037
NOTE that it is possible that the page is not yet read from disk,
1040
@return TRUE if found in the page hash table */
1045
ulint space, /*!< in: space id */
1046
ulint offset) /*!< in: page number */
1048
const buf_page_t* bpage;
1049
buf_pool_t* buf_pool = buf_pool_get(space, offset);
1051
buf_pool_mutex_enter(buf_pool);
1053
bpage = buf_page_hash_get(buf_pool, space, offset);
1055
buf_pool_mutex_exit(buf_pool);
1057
return(bpage != NULL);
1060
/********************************************************************//**
1061
Releases a compressed-only page acquired with buf_page_get_zip(). */
1064
buf_page_release_zip(
1065
/*=================*/
1066
buf_page_t* bpage) /*!< in: buffer block */
1069
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1072
ut_a(bpage->buf_fix_count > 0);
1074
switch (buf_page_get_state(bpage)) {
1075
case BUF_BLOCK_ZIP_PAGE:
1076
case BUF_BLOCK_ZIP_DIRTY:
1077
mutex_enter(&buf_pool->zip_mutex);
1078
bpage->buf_fix_count--;
1079
mutex_exit(&buf_pool->zip_mutex);
1081
case BUF_BLOCK_FILE_PAGE:
1082
block = (buf_block_t*) bpage;
1083
mutex_enter(&block->mutex);
1084
#ifdef UNIV_SYNC_DEBUG
1085
rw_lock_s_unlock(&block->debug_latch);
1087
bpage->buf_fix_count--;
1088
mutex_exit(&block->mutex);
1090
case BUF_BLOCK_ZIP_FREE:
1091
case BUF_BLOCK_NOT_USED:
1092
case BUF_BLOCK_READY_FOR_USE:
1093
case BUF_BLOCK_MEMORY:
1094
case BUF_BLOCK_REMOVE_HASH:
1102
/********************************************************************//**
1103
Decrements the bufferfix count of a buffer control block and releases
1104
a latch, if specified. */
1109
buf_block_t* block, /*!< in: buffer block */
1110
ulint rw_latch) /*!< in: RW_S_LATCH, RW_X_LATCH,
1115
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1116
ut_a(block->page.buf_fix_count > 0);
1118
mutex_enter(&block->mutex);
1120
#ifdef UNIV_SYNC_DEBUG
1121
rw_lock_s_unlock(&(block->debug_latch));
1123
block->page.buf_fix_count--;
1125
mutex_exit(&block->mutex);
1127
if (rw_latch == RW_S_LATCH) {
1128
rw_lock_s_unlock(&(block->lock));
1129
} else if (rw_latch == RW_X_LATCH) {
1130
rw_lock_x_unlock(&(block->lock));
1134
#ifdef UNIV_SYNC_DEBUG
1135
/*********************************************************************//**
1136
Adds latch level info for the rw-lock protecting the buffer frame. This
1137
should be called in the debug version after a successful latching of a
1138
page if we know the latching order level of the acquired latch. */
1141
buf_block_dbg_add_level(
1142
/*====================*/
1143
buf_block_t* block, /*!< in: buffer page
1144
where we have acquired latch */
1145
ulint level) /*!< in: latching order level */
1147
sync_thread_add_level(&block->lock, level);
1149
#endif /* UNIV_SYNC_DEBUG */
1150
/********************************************************************//**
1151
Acquire mutex on all buffer pool instances. */
1154
buf_pool_mutex_enter_all(void)
1155
/*==========================*/
1159
for (i = 0; i < srv_buf_pool_instances; i++) {
1160
buf_pool_t* buf_pool;
1162
buf_pool = buf_pool_from_array(i);
1163
buf_pool_mutex_enter(buf_pool);
1167
/********************************************************************//**
1168
Release mutex on all buffer pool instances. */
1171
buf_pool_mutex_exit_all(void)
1172
/*=========================*/
1176
for (i = 0; i < srv_buf_pool_instances; i++) {
1177
buf_pool_t* buf_pool;
1179
buf_pool = buf_pool_from_array(i);
1180
buf_pool_mutex_exit(buf_pool);
1183
#endif /* !UNIV_HOTBACKUP */