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
Calculates the index of a buffer pool to the buf_pool[] array.
52
@return the position of the buffer pool in buf_pool[] */
57
const buf_pool_t* buf_pool) /*!< in: buffer pool */
59
ulint i = buf_pool - buf_pool_ptr;
60
ut_ad(i < MAX_BUFFER_POOLS);
61
ut_ad(i < srv_buf_pool_instances);
65
/******************************************************************//**
66
Returns the buffer pool instance given a page instance
72
const buf_page_t* bpage) /*!< in: buffer pool page */
75
i = bpage->buf_pool_index;
76
ut_ad(i < srv_buf_pool_instances);
77
return(&buf_pool_ptr[i]);
80
/******************************************************************//**
81
Returns the buffer pool instance given a block instance
87
const buf_block_t* block) /*!< in: block */
89
return(buf_pool_from_bpage(&block->page));
92
/*********************************************************************//**
93
Gets the current size of buffer buf_pool in pages.
94
@return size in pages*/
97
buf_pool_get_n_pages(void)
98
/*======================*/
100
return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
103
/********************************************************************//**
104
Reads the freed_page_clock of a buffer block.
105
@return freed_page_clock */
108
buf_page_get_freed_page_clock(
109
/*==========================*/
110
const buf_page_t* bpage) /*!< in: block */
112
/* This is sometimes read without holding buf_pool->mutex. */
113
return(bpage->freed_page_clock);
116
/********************************************************************//**
117
Reads the freed_page_clock of a buffer block.
118
@return freed_page_clock */
121
buf_block_get_freed_page_clock(
122
/*===========================*/
123
const buf_block_t* block) /*!< in: block */
125
return(buf_page_get_freed_page_clock(&block->page));
128
/********************************************************************//**
129
Recommends a move of a block to the start of the LRU list if there is danger
130
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
132
@return TRUE if should be made younger */
135
buf_page_peek_if_too_old(
136
/*=====================*/
137
const buf_page_t* bpage) /*!< in: block to make younger */
139
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
141
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
142
/* If eviction has not started yet, do not update the
143
statistics or move blocks in the LRU list. This is
144
either the warm-up phase or an in-memory workload. */
146
} else if (buf_LRU_old_threshold_ms && bpage->old) {
147
unsigned access_time = buf_page_is_accessed(bpage);
150
&& ((ib_uint32_t) (ut_time_ms() - access_time))
151
>= buf_LRU_old_threshold_ms) {
155
buf_pool->stat.n_pages_not_made_young++;
158
/* FIXME: bpage->freed_page_clock is 31 bits */
159
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
160
> ((ulint) bpage->freed_page_clock
161
+ (buf_pool->curr_size
162
* (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
163
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
167
/*********************************************************************//**
168
Gets the state of a block.
174
const buf_page_t* bpage) /*!< in: pointer to the control block */
176
enum buf_page_state state = (enum buf_page_state) bpage->state;
180
case BUF_BLOCK_ZIP_FREE:
181
case BUF_BLOCK_ZIP_PAGE:
182
case BUF_BLOCK_ZIP_DIRTY:
183
case BUF_BLOCK_NOT_USED:
184
case BUF_BLOCK_READY_FOR_USE:
185
case BUF_BLOCK_FILE_PAGE:
186
case BUF_BLOCK_MEMORY:
187
case BUF_BLOCK_REMOVE_HASH:
192
#endif /* UNIV_DEBUG */
196
/*********************************************************************//**
197
Gets the state of a block.
203
const buf_block_t* block) /*!< in: pointer to the control block */
205
return(buf_page_get_state(&block->page));
207
/*********************************************************************//**
208
Sets the state of a block. */
213
buf_page_t* bpage, /*!< in/out: pointer to control block */
214
enum buf_page_state state) /*!< in: state */
217
enum buf_page_state old_state = buf_page_get_state(bpage);
220
case BUF_BLOCK_ZIP_FREE:
223
case BUF_BLOCK_ZIP_PAGE:
224
ut_a(state == BUF_BLOCK_ZIP_DIRTY);
226
case BUF_BLOCK_ZIP_DIRTY:
227
ut_a(state == BUF_BLOCK_ZIP_PAGE);
229
case BUF_BLOCK_NOT_USED:
230
ut_a(state == BUF_BLOCK_READY_FOR_USE);
232
case BUF_BLOCK_READY_FOR_USE:
233
ut_a(state == BUF_BLOCK_MEMORY
234
|| state == BUF_BLOCK_FILE_PAGE
235
|| state == BUF_BLOCK_NOT_USED);
237
case BUF_BLOCK_MEMORY:
238
ut_a(state == BUF_BLOCK_NOT_USED);
240
case BUF_BLOCK_FILE_PAGE:
241
ut_a(state == BUF_BLOCK_NOT_USED
242
|| state == BUF_BLOCK_REMOVE_HASH);
244
case BUF_BLOCK_REMOVE_HASH:
245
ut_a(state == BUF_BLOCK_MEMORY);
248
#endif /* UNIV_DEBUG */
249
bpage->state = state;
250
ut_ad(buf_page_get_state(bpage) == state);
253
/*********************************************************************//**
254
Sets the state of a block. */
259
buf_block_t* block, /*!< in/out: pointer to control block */
260
enum buf_page_state state) /*!< in: state */
262
buf_page_set_state(&block->page, state);
265
/*********************************************************************//**
266
Determines if a block is mapped to a tablespace.
267
@return TRUE if mapped */
272
const buf_page_t* bpage) /*!< in: pointer to control block */
274
switch (buf_page_get_state(bpage)) {
275
case BUF_BLOCK_ZIP_FREE:
276
/* This is a free page in buf_pool->zip_free[].
277
Such pages should only be accessed by the buddy allocator. */
280
case BUF_BLOCK_ZIP_PAGE:
281
case BUF_BLOCK_ZIP_DIRTY:
282
case BUF_BLOCK_FILE_PAGE:
284
case BUF_BLOCK_NOT_USED:
285
case BUF_BLOCK_READY_FOR_USE:
286
case BUF_BLOCK_MEMORY:
287
case BUF_BLOCK_REMOVE_HASH:
294
#ifndef UNIV_HOTBACKUP
295
/*********************************************************************//**
296
Determines if a block should be on unzip_LRU list.
297
@return TRUE if block belongs to unzip_LRU */
300
buf_page_belongs_to_unzip_LRU(
301
/*==========================*/
302
const buf_page_t* bpage) /*!< in: pointer to control block */
304
ut_ad(buf_page_in_file(bpage));
306
return(bpage->zip.data
307
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
310
/*********************************************************************//**
311
Gets the mutex of a block.
312
@return pointer to mutex protecting bpage */
317
const buf_page_t* bpage) /*!< in: pointer to control block */
319
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
321
switch (buf_page_get_state(bpage)) {
322
case BUF_BLOCK_ZIP_FREE:
325
case BUF_BLOCK_ZIP_PAGE:
326
case BUF_BLOCK_ZIP_DIRTY:
327
return(&buf_pool->zip_mutex);
329
return(&((buf_block_t*) bpage)->mutex);
333
/*********************************************************************//**
334
Get the flush type of a page.
335
@return flush type */
338
buf_page_get_flush_type(
339
/*====================*/
340
const buf_page_t* bpage) /*!< in: buffer page */
342
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
345
switch (flush_type) {
347
case BUF_FLUSH_SINGLE_PAGE:
350
case BUF_FLUSH_N_TYPES:
354
#endif /* UNIV_DEBUG */
357
/*********************************************************************//**
358
Set the flush type of a page. */
361
buf_page_set_flush_type(
362
/*====================*/
363
buf_page_t* bpage, /*!< in: buffer page */
364
enum buf_flush flush_type) /*!< in: flush type */
366
bpage->flush_type = flush_type;
367
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
370
/*********************************************************************//**
371
Map a block to a file page. */
374
buf_block_set_file_page(
375
/*====================*/
376
buf_block_t* block, /*!< in/out: pointer to control block */
377
ulint space, /*!< in: tablespace id */
378
ulint page_no)/*!< in: page number */
380
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
381
block->page.space = space;
382
block->page.offset = page_no;
385
/*********************************************************************//**
386
Gets the io_fix state of a block.
387
@return io_fix state */
392
const buf_page_t* bpage) /*!< in: pointer to the control block */
394
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
403
#endif /* UNIV_DEBUG */
407
/*********************************************************************//**
408
Gets the io_fix state of a block.
409
@return io_fix state */
412
buf_block_get_io_fix(
413
/*=================*/
414
const buf_block_t* block) /*!< in: pointer to the control block */
416
return(buf_page_get_io_fix(&block->page));
419
/*********************************************************************//**
420
Sets the io_fix state of a block. */
425
buf_page_t* bpage, /*!< in/out: control block */
426
enum buf_io_fix io_fix) /*!< in: io_fix state */
429
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
430
ut_ad(buf_pool_mutex_own(buf_pool));
432
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
434
bpage->io_fix = io_fix;
435
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
438
/*********************************************************************//**
439
Sets the io_fix state of a block. */
442
buf_block_set_io_fix(
443
/*=================*/
444
buf_block_t* block, /*!< in/out: control block */
445
enum buf_io_fix io_fix) /*!< in: io_fix state */
447
buf_page_set_io_fix(&block->page, io_fix);
450
/********************************************************************//**
451
Determine if a buffer block can be relocated in memory. The block
452
can be dirty, but it must not be I/O-fixed or bufferfixed. */
455
buf_page_can_relocate(
456
/*==================*/
457
const buf_page_t* bpage) /*!< control block being relocated */
460
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
461
ut_ad(buf_pool_mutex_own(buf_pool));
463
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
464
ut_ad(buf_page_in_file(bpage));
465
ut_ad(bpage->in_LRU_list);
467
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
468
&& bpage->buf_fix_count == 0);
471
/*********************************************************************//**
472
Determine if a block has been flagged old.
473
@return TRUE if old */
478
const buf_page_t* bpage) /*!< in: control block */
481
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
482
ut_ad(buf_pool_mutex_own(buf_pool));
484
ut_ad(buf_page_in_file(bpage));
489
/*********************************************************************//**
495
buf_page_t* bpage, /*!< in/out: control block */
496
ibool old) /*!< in: old */
499
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
500
#endif /* UNIV_DEBUG */
501
ut_a(buf_page_in_file(bpage));
502
ut_ad(buf_pool_mutex_own(buf_pool));
503
ut_ad(bpage->in_LRU_list);
505
#ifdef UNIV_LRU_DEBUG
506
ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
507
/* If a block is flagged "old", the LRU_old list must exist. */
508
ut_a(!old || buf_pool->LRU_old);
510
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
511
const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
512
const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
513
if (prev->old == next->old) {
514
ut_a(prev->old == old);
517
ut_a(buf_pool->LRU_old == (old ? bpage : next));
520
#endif /* UNIV_LRU_DEBUG */
525
/*********************************************************************//**
526
Determine the time of first access of a block in the buffer pool.
527
@return ut_time_ms() at the time of first access, 0 if not accessed */
530
buf_page_is_accessed(
531
/*=================*/
532
const buf_page_t* bpage) /*!< in: control block */
534
ut_ad(buf_page_in_file(bpage));
536
return(bpage->access_time);
539
/*********************************************************************//**
540
Flag a block accessed. */
543
buf_page_set_accessed(
544
/*==================*/
545
buf_page_t* bpage, /*!< in/out: control block */
546
ulint time_ms) /*!< in: ut_time_ms() */
549
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
550
ut_ad(buf_pool_mutex_own(buf_pool));
552
ut_a(buf_page_in_file(bpage));
554
if (!bpage->access_time) {
555
/* Make this the time of the first access. */
556
bpage->access_time = time_ms;
560
/*********************************************************************//**
561
Gets the buf_block_t handle of a buffered file block if an uncompressed
562
page frame exists, or NULL.
563
@return control block, or NULL */
568
buf_page_t* bpage) /*!< in: control block, or NULL */
570
if (UNIV_LIKELY(bpage != NULL)) {
571
ut_ad(buf_page_in_file(bpage));
573
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
574
return((buf_block_t*) bpage);
580
#endif /* !UNIV_HOTBACKUP */
583
/*********************************************************************//**
584
Gets a pointer to the memory frame of a block.
585
@return pointer to the frame */
590
const buf_block_t* block) /*!< in: pointer to the control block */
594
switch (buf_block_get_state(block)) {
595
case BUF_BLOCK_ZIP_FREE:
596
case BUF_BLOCK_ZIP_PAGE:
597
case BUF_BLOCK_ZIP_DIRTY:
598
case BUF_BLOCK_NOT_USED:
601
case BUF_BLOCK_FILE_PAGE:
602
# ifndef UNIV_HOTBACKUP
603
ut_a(block->page.buf_fix_count > 0);
604
# endif /* !UNIV_HOTBACKUP */
606
case BUF_BLOCK_READY_FOR_USE:
607
case BUF_BLOCK_MEMORY:
608
case BUF_BLOCK_REMOVE_HASH:
613
return((buf_frame_t*) block->frame);
615
#endif /* UNIV_DEBUG */
617
/*********************************************************************//**
618
Gets the space id of a block.
624
const buf_page_t* bpage) /*!< in: pointer to the control block */
627
ut_a(buf_page_in_file(bpage));
629
return(bpage->space);
632
/*********************************************************************//**
633
Gets the space id of a block.
639
const buf_block_t* block) /*!< in: pointer to the control block */
642
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
644
return(block->page.space);
647
/*********************************************************************//**
648
Gets the page number of a block.
649
@return page number */
652
buf_page_get_page_no(
653
/*=================*/
654
const buf_page_t* bpage) /*!< in: pointer to the control block */
657
ut_a(buf_page_in_file(bpage));
659
return(bpage->offset);
662
/*********************************************************************//**
663
Gets the page number of a block.
664
@return page number */
667
buf_block_get_page_no(
668
/*==================*/
669
const buf_block_t* block) /*!< in: pointer to the control block */
672
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
674
return(block->page.offset);
677
/*********************************************************************//**
678
Gets the compressed page size of a block.
679
@return compressed page size, or 0 */
682
buf_page_get_zip_size(
683
/*==================*/
684
const buf_page_t* bpage) /*!< in: pointer to the control block */
686
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
689
/*********************************************************************//**
690
Gets the compressed page size of a block.
691
@return compressed page size, or 0 */
694
buf_block_get_zip_size(
695
/*===================*/
696
const buf_block_t* block) /*!< in: pointer to the control block */
698
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
701
#ifndef UNIV_HOTBACKUP
702
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
703
/*********************************************************************//**
704
Gets the compressed page descriptor corresponding to an uncompressed page
706
@return compressed page descriptor, or NULL */
708
const page_zip_des_t*
709
buf_frame_get_page_zip(
710
/*===================*/
711
const byte* ptr) /*!< in: pointer to the page */
713
return(buf_block_get_page_zip(buf_block_align(ptr)));
715
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
716
#endif /* !UNIV_HOTBACKUP */
718
/**********************************************************************//**
719
Gets the space id, page offset, and byte offset within page of a
720
pointer pointing to a buffer frame containing a file page. */
723
buf_ptr_get_fsp_addr(
724
/*=================*/
725
const void* ptr, /*!< in: pointer to a buffer frame */
726
ulint* space, /*!< out: space id */
727
fil_addr_t* addr) /*!< out: page offset and byte offset */
729
const page_t* page = (const page_t*) ut_align_down(ptr,
732
*space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
733
addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
734
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
737
#ifndef UNIV_HOTBACKUP
738
/**********************************************************************//**
739
Gets the hash value of the page the pointer is pointing to. This can be used
740
in searches in the lock hash table.
741
@return lock hash value */
744
buf_block_get_lock_hash_val(
745
/*========================*/
746
const buf_block_t* block) /*!< in: block */
749
ut_ad(buf_page_in_file(&block->page));
750
#ifdef UNIV_SYNC_DEBUG
751
ut_ad(rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_EXCLUSIVE)
752
|| rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_SHARED));
753
#endif /* UNIV_SYNC_DEBUG */
754
return(block->lock_hash_val);
757
/********************************************************************//**
758
Frees a buffer block which does not contain a file page. */
763
buf_block_t* block) /*!< in, own: block to be freed */
765
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
767
buf_pool_mutex_enter(buf_pool);
769
mutex_enter(&block->mutex);
771
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
773
buf_LRU_block_free_non_file_page(block);
775
mutex_exit(&block->mutex);
777
buf_pool_mutex_exit(buf_pool);
779
#endif /* !UNIV_HOTBACKUP */
781
/*********************************************************************//**
782
Copies contents of a buffer frame to a given buffer.
788
byte* buf, /*!< in: buffer to copy to */
789
const buf_frame_t* frame) /*!< in: buffer frame */
793
ut_memcpy(buf, frame, UNIV_PAGE_SIZE);
798
#ifndef UNIV_HOTBACKUP
799
/********************************************************************//**
800
Calculates a folded value of a file page address to use in the page hash
802
@return the folded value */
805
buf_page_address_fold(
806
/*==================*/
807
ulint space, /*!< in: space id */
808
ulint offset) /*!< in: offset of the page within space */
810
return((space << 20) + space + offset);
813
/********************************************************************//**
814
Gets the youngest modification log sequence number for a frame.
815
Returns zero if not file page or no modification occurred yet.
816
@return newest modification to page */
819
buf_page_get_newest_modification(
820
/*=============================*/
821
const buf_page_t* bpage) /*!< in: block containing the
825
mutex_t* block_mutex = buf_page_get_mutex(bpage);
827
mutex_enter(block_mutex);
829
if (buf_page_in_file(bpage)) {
830
lsn = bpage->newest_modification;
835
mutex_exit(block_mutex);
840
/********************************************************************//**
841
Increments the modify clock of a frame by 1. The caller must (1) own the
842
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
846
buf_block_modify_clock_inc(
847
/*=======================*/
848
buf_block_t* block) /*!< in: block */
850
#ifdef UNIV_SYNC_DEBUG
851
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
853
ut_ad((buf_pool_mutex_own(buf_pool)
854
&& (block->page.buf_fix_count == 0))
855
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
856
#endif /* UNIV_SYNC_DEBUG */
858
block->modify_clock++;
861
/********************************************************************//**
862
Returns the value of the modify clock. The caller must have an s-lock
863
or x-lock on the block.
867
buf_block_get_modify_clock(
868
/*=======================*/
869
buf_block_t* block) /*!< in: block */
871
#ifdef UNIV_SYNC_DEBUG
872
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
873
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
874
#endif /* UNIV_SYNC_DEBUG */
876
return(block->modify_clock);
879
/*******************************************************************//**
880
Increments the bufferfix count. */
883
buf_block_buf_fix_inc_func(
884
/*=======================*/
885
#ifdef UNIV_SYNC_DEBUG
886
const char* file, /*!< in: file name */
887
ulint line, /*!< in: line */
888
#endif /* UNIV_SYNC_DEBUG */
889
buf_block_t* block) /*!< in/out: block to bufferfix */
891
#ifdef UNIV_SYNC_DEBUG
894
ret = rw_lock_s_lock_nowait(&(block->debug_latch), file, line);
896
#endif /* UNIV_SYNC_DEBUG */
897
ut_ad(mutex_own(&block->mutex));
899
block->page.buf_fix_count++;
901
#ifdef UNIV_SYNC_DEBUG
902
/** Increments the bufferfix count.
903
@param b in/out: block to bufferfix
904
@param f in: file name where requested
905
@param l in: line number where requested */
906
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
907
#else /* UNIV_SYNC_DEBUG */
908
/** Increments the bufferfix count.
909
@param b in/out: block to bufferfix
910
@param f in: file name where requested
911
@param l in: line number where requested */
912
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
913
#endif /* UNIV_SYNC_DEBUG */
915
/*******************************************************************//**
916
Decrements the bufferfix count. */
919
buf_block_buf_fix_dec(
920
/*==================*/
921
buf_block_t* block) /*!< in/out: block to bufferunfix */
923
ut_ad(mutex_own(&block->mutex));
925
block->page.buf_fix_count--;
926
#ifdef UNIV_SYNC_DEBUG
927
rw_lock_s_unlock(&block->debug_latch);
931
/******************************************************************//**
932
Returns the buffer pool instance given space and offset of page
933
@return buffer pool */
938
ulint space, /*!< in: space id */
939
ulint offset) /*!< in: offset of the page within space */
943
ulint ignored_offset;
945
ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/
946
fold = buf_page_address_fold(space, ignored_offset);
947
index = fold % srv_buf_pool_instances;
948
return(&buf_pool_ptr[index]);
951
/******************************************************************//**
952
Returns the buffer pool instance given its array index
953
@return buffer pool */
958
ulint index) /*!< in: array index to get
959
buffer pool instance from */
961
ut_ad(index < MAX_BUFFER_POOLS);
962
ut_ad(index < srv_buf_pool_instances);
963
return(&buf_pool_ptr[index]);
966
/******************************************************************//**
967
Returns the control block of a file page, NULL if not found.
968
@return block, NULL if not found */
971
buf_page_hash_get_low(
972
/*==================*/
973
buf_pool_t* buf_pool, /*!< buffer pool instance */
974
ulint space, /*!< in: space id */
975
ulint offset, /*!< in: offset of the page
977
ulint fold) /*!< in: buf_page_address_fold(
983
ut_ad(buf_pool_mutex_own(buf_pool));
984
ut_ad(fold == buf_page_address_fold(space, offset));
986
/* Look for the page in the hash table */
988
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
989
ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
990
&& buf_page_in_file(bpage)),
991
bpage->space == space && bpage->offset == offset);
993
ut_a(buf_page_in_file(bpage));
994
ut_ad(bpage->in_page_hash);
995
ut_ad(!bpage->in_zip_hash);
996
#if UNIV_WORD_SIZE == 4
997
/* On 32-bit systems, there is no padding in
998
buf_page_t. On other systems, Valgrind could complain
999
about uninitialized pad bytes. */
1000
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
1007
/******************************************************************//**
1008
Returns the control block of a file page, NULL if not found.
1009
@return block, NULL if not found or not a real control block */
1014
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1015
ulint space, /*!< in: space id */
1016
ulint offset) /*!< in: offset of the page
1020
ulint fold = buf_page_address_fold(space, offset);
1022
bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
1024
if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
1031
/******************************************************************//**
1032
Returns the control block of a file page, NULL if not found
1033
or an uncompressed page frame does not exist.
1034
@return block, NULL if not found */
1039
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1040
ulint space, /*!< in: space id */
1041
ulint offset) /*!< in: offset of the page
1046
block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
1051
/********************************************************************//**
1052
Returns TRUE if the page can be found in the buffer pool hash table.
1054
NOTE that it is possible that the page is not yet read from disk,
1057
@return TRUE if found in the page hash table */
1062
ulint space, /*!< in: space id */
1063
ulint offset) /*!< in: page number */
1065
const buf_page_t* bpage;
1066
buf_pool_t* buf_pool = buf_pool_get(space, offset);
1068
buf_pool_mutex_enter(buf_pool);
1070
bpage = buf_page_hash_get(buf_pool, space, offset);
1072
buf_pool_mutex_exit(buf_pool);
1074
return(bpage != NULL);
1077
/********************************************************************//**
1078
Releases a compressed-only page acquired with buf_page_get_zip(). */
1081
buf_page_release_zip(
1082
/*=================*/
1083
buf_page_t* bpage) /*!< in: buffer block */
1086
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1089
ut_a(bpage->buf_fix_count > 0);
1091
switch (buf_page_get_state(bpage)) {
1092
case BUF_BLOCK_ZIP_PAGE:
1093
case BUF_BLOCK_ZIP_DIRTY:
1094
mutex_enter(&buf_pool->zip_mutex);
1095
bpage->buf_fix_count--;
1096
mutex_exit(&buf_pool->zip_mutex);
1098
case BUF_BLOCK_FILE_PAGE:
1099
block = (buf_block_t*) bpage;
1100
mutex_enter(&block->mutex);
1101
#ifdef UNIV_SYNC_DEBUG
1102
rw_lock_s_unlock(&block->debug_latch);
1104
bpage->buf_fix_count--;
1105
mutex_exit(&block->mutex);
1107
case BUF_BLOCK_ZIP_FREE:
1108
case BUF_BLOCK_NOT_USED:
1109
case BUF_BLOCK_READY_FOR_USE:
1110
case BUF_BLOCK_MEMORY:
1111
case BUF_BLOCK_REMOVE_HASH:
1119
/********************************************************************//**
1120
Decrements the bufferfix count of a buffer control block and releases
1121
a latch, if specified. */
1126
buf_block_t* block, /*!< in: buffer block */
1127
ulint rw_latch) /*!< in: RW_S_LATCH, RW_X_LATCH,
1132
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1133
ut_a(block->page.buf_fix_count > 0);
1135
mutex_enter(&block->mutex);
1137
#ifdef UNIV_SYNC_DEBUG
1138
rw_lock_s_unlock(&(block->debug_latch));
1140
block->page.buf_fix_count--;
1142
mutex_exit(&block->mutex);
1144
if (rw_latch == RW_S_LATCH) {
1145
rw_lock_s_unlock(&(block->lock));
1146
} else if (rw_latch == RW_X_LATCH) {
1147
rw_lock_x_unlock(&(block->lock));
1151
#ifdef UNIV_SYNC_DEBUG
1152
/*********************************************************************//**
1153
Adds latch level info for the rw-lock protecting the buffer frame. This
1154
should be called in the debug version after a successful latching of a
1155
page if we know the latching order level of the acquired latch. */
1158
buf_block_dbg_add_level(
1159
/*====================*/
1160
buf_block_t* block, /*!< in: buffer page
1161
where we have acquired latch */
1162
ulint level) /*!< in: latching order level */
1164
sync_thread_add_level(&block->lock, level);
1166
#endif /* UNIV_SYNC_DEBUG */
1167
/********************************************************************//**
1168
Acquire mutex on all buffer pool instances. */
1171
buf_pool_mutex_enter_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_enter(buf_pool);
1184
/********************************************************************//**
1185
Release mutex on all buffer pool instances. */
1188
buf_pool_mutex_exit_all(void)
1189
/*=========================*/
1193
for (i = 0; i < srv_buf_pool_instances; i++) {
1194
buf_pool_t* buf_pool;
1196
buf_pool = buf_pool_from_array(i);
1197
buf_pool_mutex_exit(buf_pool);
1200
#endif /* !UNIV_HOTBACKUP */