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., 59 Temple
22
Place, Suite 330, Boston, MA 02111-1307 USA
24
*****************************************************************************/
26
/**************************************************//**
27
@file include/buf0buf.ic
28
The database buffer buf_pool
30
Created 11/5/1995 Heikki Tuuri
31
*******************************************************/
38
/*********************************************************************//**
39
Gets the current size of buffer buf_pool in bytes.
40
@return size in bytes */
43
buf_pool_get_curr_size(void)
44
/*========================*/
46
return(srv_buf_pool_curr_size);
49
/********************************************************************//**
50
Calculates the index of a buffer pool to the buf_pool[] array.
51
@return the position of the buffer pool in buf_pool[] */
56
const buf_pool_t* buf_pool) /*!< in: buffer pool */
58
ulint i = buf_pool - buf_pool_ptr;
59
ut_ad(i < MAX_BUFFER_POOLS);
60
ut_ad(i < srv_buf_pool_instances);
64
/******************************************************************//**
65
Returns the buffer pool instance given a page instance
71
const buf_page_t* bpage) /*!< in: buffer pool page */
74
i = bpage->buf_pool_index;
75
ut_ad(i < srv_buf_pool_instances);
76
return(&buf_pool_ptr[i]);
79
/******************************************************************//**
80
Returns the buffer pool instance given a block instance
86
const buf_block_t* block) /*!< in: block */
88
return(buf_pool_from_bpage(&block->page));
91
/*********************************************************************//**
92
Gets the current size of buffer buf_pool in pages.
93
@return size in pages*/
96
buf_pool_get_n_pages(void)
97
/*======================*/
99
return(buf_pool_get_curr_size() / UNIV_PAGE_SIZE);
102
/********************************************************************//**
103
Reads the freed_page_clock of a buffer block.
104
@return freed_page_clock */
107
buf_page_get_freed_page_clock(
108
/*==========================*/
109
const buf_page_t* bpage) /*!< in: block */
111
/* This is sometimes read without holding buf_pool->mutex. */
112
return(bpage->freed_page_clock);
115
/********************************************************************//**
116
Reads the freed_page_clock of a buffer block.
117
@return freed_page_clock */
120
buf_block_get_freed_page_clock(
121
/*===========================*/
122
const buf_block_t* block) /*!< in: block */
124
return(buf_page_get_freed_page_clock(&block->page));
127
/********************************************************************//**
128
Tells if a block is still close enough to the MRU end of the LRU list
129
meaning that it is not in danger of getting evicted and also implying
130
that it has been accessed recently.
131
Note that this is for heuristics only and does not reserve buffer pool
133
@return TRUE if block is close to MRU end of LRU */
136
buf_page_peek_if_young(
137
/*===================*/
138
const buf_page_t* bpage) /*!< in: block */
140
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
142
/* FIXME: bpage->freed_page_clock is 31 bits */
143
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
144
< ((ulint) bpage->freed_page_clock
145
+ (buf_pool->curr_size
146
* (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
147
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
150
/********************************************************************//**
151
Recommends a move of a block to the start of the LRU list if there is danger
152
of dropping from the buffer pool. NOTE: does not reserve the buffer pool
154
@return TRUE if should be made younger */
157
buf_page_peek_if_too_old(
158
/*=====================*/
159
const buf_page_t* bpage) /*!< in: block to make younger */
161
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
163
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
164
/* If eviction has not started yet, do not update the
165
statistics or move blocks in the LRU list. This is
166
either the warm-up phase or an in-memory workload. */
168
} else if (buf_LRU_old_threshold_ms && bpage->old) {
169
unsigned access_time = buf_page_is_accessed(bpage);
172
&& ((ib_uint32_t) (ut_time_ms() - access_time))
173
>= buf_LRU_old_threshold_ms) {
177
buf_pool->stat.n_pages_not_made_young++;
180
return(!buf_page_peek_if_young(bpage));
184
/*********************************************************************//**
185
Gets the state of a block.
191
const buf_page_t* bpage) /*!< in: pointer to the control block */
193
enum buf_page_state state = (enum buf_page_state) bpage->state;
197
case BUF_BLOCK_ZIP_FREE:
198
case BUF_BLOCK_ZIP_PAGE:
199
case BUF_BLOCK_ZIP_DIRTY:
200
case BUF_BLOCK_NOT_USED:
201
case BUF_BLOCK_READY_FOR_USE:
202
case BUF_BLOCK_FILE_PAGE:
203
case BUF_BLOCK_MEMORY:
204
case BUF_BLOCK_REMOVE_HASH:
209
#endif /* UNIV_DEBUG */
213
/*********************************************************************//**
214
Gets the state of a block.
220
const buf_block_t* block) /*!< in: pointer to the control block */
222
return(buf_page_get_state(&block->page));
224
/*********************************************************************//**
225
Sets the state of a block. */
230
buf_page_t* bpage, /*!< in/out: pointer to control block */
231
enum buf_page_state state) /*!< in: state */
234
enum buf_page_state old_state = buf_page_get_state(bpage);
237
case BUF_BLOCK_ZIP_FREE:
240
case BUF_BLOCK_ZIP_PAGE:
241
ut_a(state == BUF_BLOCK_ZIP_DIRTY);
243
case BUF_BLOCK_ZIP_DIRTY:
244
ut_a(state == BUF_BLOCK_ZIP_PAGE);
246
case BUF_BLOCK_NOT_USED:
247
ut_a(state == BUF_BLOCK_READY_FOR_USE);
249
case BUF_BLOCK_READY_FOR_USE:
250
ut_a(state == BUF_BLOCK_MEMORY
251
|| state == BUF_BLOCK_FILE_PAGE
252
|| state == BUF_BLOCK_NOT_USED);
254
case BUF_BLOCK_MEMORY:
255
ut_a(state == BUF_BLOCK_NOT_USED);
257
case BUF_BLOCK_FILE_PAGE:
258
ut_a(state == BUF_BLOCK_NOT_USED
259
|| state == BUF_BLOCK_REMOVE_HASH);
261
case BUF_BLOCK_REMOVE_HASH:
262
ut_a(state == BUF_BLOCK_MEMORY);
265
#endif /* UNIV_DEBUG */
266
bpage->state = state;
267
ut_ad(buf_page_get_state(bpage) == state);
270
/*********************************************************************//**
271
Sets the state of a block. */
276
buf_block_t* block, /*!< in/out: pointer to control block */
277
enum buf_page_state state) /*!< in: state */
279
buf_page_set_state(&block->page, state);
282
/*********************************************************************//**
283
Determines if a block is mapped to a tablespace.
284
@return TRUE if mapped */
289
const buf_page_t* bpage) /*!< in: pointer to control block */
291
switch (buf_page_get_state(bpage)) {
292
case BUF_BLOCK_ZIP_FREE:
293
/* This is a free page in buf_pool->zip_free[].
294
Such pages should only be accessed by the buddy allocator. */
297
case BUF_BLOCK_ZIP_PAGE:
298
case BUF_BLOCK_ZIP_DIRTY:
299
case BUF_BLOCK_FILE_PAGE:
301
case BUF_BLOCK_NOT_USED:
302
case BUF_BLOCK_READY_FOR_USE:
303
case BUF_BLOCK_MEMORY:
304
case BUF_BLOCK_REMOVE_HASH:
311
#ifndef UNIV_HOTBACKUP
312
/*********************************************************************//**
313
Determines if a block should be on unzip_LRU list.
314
@return TRUE if block belongs to unzip_LRU */
317
buf_page_belongs_to_unzip_LRU(
318
/*==========================*/
319
const buf_page_t* bpage) /*!< in: pointer to control block */
321
ut_ad(buf_page_in_file(bpage));
323
return(bpage->zip.data
324
&& buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
327
/*********************************************************************//**
328
Gets the mutex of a block.
329
@return pointer to mutex protecting bpage */
334
const buf_page_t* bpage) /*!< in: pointer to control block */
336
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
338
switch (buf_page_get_state(bpage)) {
339
case BUF_BLOCK_ZIP_FREE:
342
case BUF_BLOCK_ZIP_PAGE:
343
case BUF_BLOCK_ZIP_DIRTY:
344
return(&buf_pool->zip_mutex);
346
return(&((buf_block_t*) bpage)->mutex);
350
/*********************************************************************//**
351
Get the flush type of a page.
352
@return flush type */
355
buf_page_get_flush_type(
356
/*====================*/
357
const buf_page_t* bpage) /*!< in: buffer page */
359
enum buf_flush flush_type = (enum buf_flush) bpage->flush_type;
362
switch (flush_type) {
364
case BUF_FLUSH_SINGLE_PAGE:
367
case BUF_FLUSH_N_TYPES:
371
#endif /* UNIV_DEBUG */
374
/*********************************************************************//**
375
Set the flush type of a page. */
378
buf_page_set_flush_type(
379
/*====================*/
380
buf_page_t* bpage, /*!< in: buffer page */
381
enum buf_flush flush_type) /*!< in: flush type */
383
bpage->flush_type = flush_type;
384
ut_ad(buf_page_get_flush_type(bpage) == flush_type);
387
/*********************************************************************//**
388
Map a block to a file page. */
391
buf_block_set_file_page(
392
/*====================*/
393
buf_block_t* block, /*!< in/out: pointer to control block */
394
ulint space, /*!< in: tablespace id */
395
ulint page_no)/*!< in: page number */
397
buf_block_set_state(block, BUF_BLOCK_FILE_PAGE);
398
block->page.space = space;
399
block->page.offset = page_no;
402
/*********************************************************************//**
403
Gets the io_fix state of a block.
404
@return io_fix state */
409
const buf_page_t* bpage) /*!< in: pointer to the control block */
411
enum buf_io_fix io_fix = (enum buf_io_fix) bpage->io_fix;
420
#endif /* UNIV_DEBUG */
424
/*********************************************************************//**
425
Gets the io_fix state of a block.
426
@return io_fix state */
429
buf_block_get_io_fix(
430
/*=================*/
431
const buf_block_t* block) /*!< in: pointer to the control block */
433
return(buf_page_get_io_fix(&block->page));
436
/*********************************************************************//**
437
Sets the io_fix state of a block. */
442
buf_page_t* bpage, /*!< in/out: control block */
443
enum buf_io_fix io_fix) /*!< in: io_fix state */
446
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
447
ut_ad(buf_pool_mutex_own(buf_pool));
449
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
451
bpage->io_fix = io_fix;
452
ut_ad(buf_page_get_io_fix(bpage) == io_fix);
455
/*********************************************************************//**
456
Sets the io_fix state of a block. */
459
buf_block_set_io_fix(
460
/*=================*/
461
buf_block_t* block, /*!< in/out: control block */
462
enum buf_io_fix io_fix) /*!< in: io_fix state */
464
buf_page_set_io_fix(&block->page, io_fix);
467
/********************************************************************//**
468
Determine if a buffer block can be relocated in memory. The block
469
can be dirty, but it must not be I/O-fixed or bufferfixed. */
472
buf_page_can_relocate(
473
/*==================*/
474
const buf_page_t* bpage) /*!< control block being relocated */
477
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
478
ut_ad(buf_pool_mutex_own(buf_pool));
480
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
481
ut_ad(buf_page_in_file(bpage));
482
ut_ad(bpage->in_LRU_list);
484
return(buf_page_get_io_fix(bpage) == BUF_IO_NONE
485
&& bpage->buf_fix_count == 0);
488
/*********************************************************************//**
489
Determine if a block has been flagged old.
490
@return TRUE if old */
495
const buf_page_t* bpage) /*!< in: control block */
498
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
499
ut_ad(buf_pool_mutex_own(buf_pool));
501
ut_ad(buf_page_in_file(bpage));
506
/*********************************************************************//**
512
buf_page_t* bpage, /*!< in/out: control block */
513
ibool old) /*!< in: old */
516
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
517
#endif /* UNIV_DEBUG */
518
ut_a(buf_page_in_file(bpage));
519
ut_ad(buf_pool_mutex_own(buf_pool));
520
ut_ad(bpage->in_LRU_list);
522
#ifdef UNIV_LRU_DEBUG
523
ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL));
524
/* If a block is flagged "old", the LRU_old list must exist. */
525
ut_a(!old || buf_pool->LRU_old);
527
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) {
528
const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage);
529
const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage);
530
if (prev->old == next->old) {
531
ut_a(prev->old == old);
534
ut_a(buf_pool->LRU_old == (old ? bpage : next));
537
#endif /* UNIV_LRU_DEBUG */
542
/*********************************************************************//**
543
Determine the time of first access of a block in the buffer pool.
544
@return ut_time_ms() at the time of first access, 0 if not accessed */
547
buf_page_is_accessed(
548
/*=================*/
549
const buf_page_t* bpage) /*!< in: control block */
551
ut_ad(buf_page_in_file(bpage));
553
return(bpage->access_time);
556
/*********************************************************************//**
557
Flag a block accessed. */
560
buf_page_set_accessed(
561
/*==================*/
562
buf_page_t* bpage, /*!< in/out: control block */
563
ulint time_ms) /*!< in: ut_time_ms() */
566
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
567
ut_ad(buf_pool_mutex_own(buf_pool));
569
ut_a(buf_page_in_file(bpage));
571
if (!bpage->access_time) {
572
/* Make this the time of the first access. */
573
bpage->access_time = time_ms;
577
/*********************************************************************//**
578
Gets the buf_block_t handle of a buffered file block if an uncompressed
579
page frame exists, or NULL.
580
@return control block, or NULL */
585
buf_page_t* bpage) /*!< in: control block, or NULL */
587
if (UNIV_LIKELY(bpage != NULL)) {
588
ut_ad(buf_page_in_file(bpage));
590
if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
591
return((buf_block_t*) bpage);
597
#endif /* !UNIV_HOTBACKUP */
600
/*********************************************************************//**
601
Gets a pointer to the memory frame of a block.
602
@return pointer to the frame */
607
const buf_block_t* block) /*!< in: pointer to the control block */
611
switch (buf_block_get_state(block)) {
612
case BUF_BLOCK_ZIP_FREE:
613
case BUF_BLOCK_ZIP_PAGE:
614
case BUF_BLOCK_ZIP_DIRTY:
615
case BUF_BLOCK_NOT_USED:
618
case BUF_BLOCK_FILE_PAGE:
619
# ifndef UNIV_HOTBACKUP
620
ut_a(block->page.buf_fix_count > 0);
621
# endif /* !UNIV_HOTBACKUP */
623
case BUF_BLOCK_READY_FOR_USE:
624
case BUF_BLOCK_MEMORY:
625
case BUF_BLOCK_REMOVE_HASH:
630
return((buf_frame_t*) block->frame);
632
#endif /* UNIV_DEBUG */
634
/*********************************************************************//**
635
Gets the space id of a block.
641
const buf_page_t* bpage) /*!< in: pointer to the control block */
644
ut_a(buf_page_in_file(bpage));
646
return(bpage->space);
649
/*********************************************************************//**
650
Gets the space id of a block.
656
const buf_block_t* block) /*!< in: pointer to the control block */
659
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
661
return(block->page.space);
664
/*********************************************************************//**
665
Gets the page number of a block.
666
@return page number */
669
buf_page_get_page_no(
670
/*=================*/
671
const buf_page_t* bpage) /*!< in: pointer to the control block */
674
ut_a(buf_page_in_file(bpage));
676
return(bpage->offset);
679
/*********************************************************************//**
680
Gets the page number of a block.
681
@return page number */
684
buf_block_get_page_no(
685
/*==================*/
686
const buf_block_t* block) /*!< in: pointer to the control block */
689
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
691
return(block->page.offset);
694
/*********************************************************************//**
695
Gets the compressed page size of a block.
696
@return compressed page size, or 0 */
699
buf_page_get_zip_size(
700
/*==================*/
701
const buf_page_t* bpage) /*!< in: pointer to the control block */
703
return(bpage->zip.ssize ? 512 << bpage->zip.ssize : 0);
706
/*********************************************************************//**
707
Gets the compressed page size of a block.
708
@return compressed page size, or 0 */
711
buf_block_get_zip_size(
712
/*===================*/
713
const buf_block_t* block) /*!< in: pointer to the control block */
715
return(block->page.zip.ssize ? 512 << block->page.zip.ssize : 0);
718
#ifndef UNIV_HOTBACKUP
719
#if defined UNIV_DEBUG || defined UNIV_ZIP_DEBUG
720
/*********************************************************************//**
721
Gets the compressed page descriptor corresponding to an uncompressed page
723
@return compressed page descriptor, or NULL */
725
const page_zip_des_t*
726
buf_frame_get_page_zip(
727
/*===================*/
728
const byte* ptr) /*!< in: pointer to the page */
730
return(buf_block_get_page_zip(buf_block_align(ptr)));
732
#endif /* UNIV_DEBUG || UNIV_ZIP_DEBUG */
733
#endif /* !UNIV_HOTBACKUP */
735
/**********************************************************************//**
736
Gets the space id, page offset, and byte offset within page of a
737
pointer pointing to a buffer frame containing a file page. */
740
buf_ptr_get_fsp_addr(
741
/*=================*/
742
const void* ptr, /*!< in: pointer to a buffer frame */
743
ulint* space, /*!< out: space id */
744
fil_addr_t* addr) /*!< out: page offset and byte offset */
746
const page_t* page = (const page_t*) ut_align_down(ptr,
749
*space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
750
addr->page = mach_read_from_4(page + FIL_PAGE_OFFSET);
751
addr->boffset = ut_align_offset(ptr, UNIV_PAGE_SIZE);
754
#ifndef UNIV_HOTBACKUP
755
/**********************************************************************//**
756
Gets the hash value of the page the pointer is pointing to. This can be used
757
in searches in the lock hash table.
758
@return lock hash value */
761
buf_block_get_lock_hash_val(
762
/*========================*/
763
const buf_block_t* block) /*!< in: block */
766
ut_ad(buf_page_in_file(&block->page));
767
#ifdef UNIV_SYNC_DEBUG
768
ut_ad(rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_EXCLUSIVE)
769
|| rw_lock_own(&(((buf_block_t*) block)->lock), RW_LOCK_SHARED));
770
#endif /* UNIV_SYNC_DEBUG */
771
return(block->lock_hash_val);
774
/********************************************************************//**
775
Allocates a buf_page_t descriptor. This function must succeed. In case
776
of failure we assert in this function.
777
@return: the allocated descriptor. */
780
buf_page_alloc_descriptor(void)
781
/*===========================*/
785
bpage = (buf_page_t*) ut_malloc(sizeof *bpage);
786
ut_d(memset(bpage, 0, sizeof *bpage));
787
UNIV_MEM_ALLOC(bpage, sizeof *bpage);
792
/********************************************************************//**
793
Free a buf_page_t descriptor. */
796
buf_page_free_descriptor(
797
/*=====================*/
798
buf_page_t* bpage) /*!< in: bpage descriptor to free. */
803
/********************************************************************//**
804
Frees a buffer block which does not contain a file page. */
809
buf_block_t* block) /*!< in, own: block to be freed */
811
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
813
buf_pool_mutex_enter(buf_pool);
815
mutex_enter(&block->mutex);
817
ut_a(buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE);
819
buf_LRU_block_free_non_file_page(block);
821
mutex_exit(&block->mutex);
823
buf_pool_mutex_exit(buf_pool);
825
#endif /* !UNIV_HOTBACKUP */
827
/*********************************************************************//**
828
Copies contents of a buffer frame to a given buffer.
834
byte* buf, /*!< in: buffer to copy to */
835
const buf_frame_t* frame) /*!< in: buffer frame */
839
ut_memcpy(buf, frame, UNIV_PAGE_SIZE);
844
#ifndef UNIV_HOTBACKUP
845
/********************************************************************//**
846
Calculates a folded value of a file page address to use in the page hash
848
@return the folded value */
851
buf_page_address_fold(
852
/*==================*/
853
ulint space, /*!< in: space id */
854
ulint offset) /*!< in: offset of the page within space */
856
return((space << 20) + space + offset);
859
/********************************************************************//**
860
Gets the youngest modification log sequence number for a frame.
861
Returns zero if not file page or no modification occurred yet.
862
@return newest modification to page */
865
buf_page_get_newest_modification(
866
/*=============================*/
867
const buf_page_t* bpage) /*!< in: block containing the
871
mutex_t* block_mutex = buf_page_get_mutex(bpage);
873
mutex_enter(block_mutex);
875
if (buf_page_in_file(bpage)) {
876
lsn = bpage->newest_modification;
881
mutex_exit(block_mutex);
886
/********************************************************************//**
887
Increments the modify clock of a frame by 1. The caller must (1) own the
888
buf_pool mutex and block bufferfix count has to be zero, (2) or own an x-lock
892
buf_block_modify_clock_inc(
893
/*=======================*/
894
buf_block_t* block) /*!< in: block */
896
#ifdef UNIV_SYNC_DEBUG
897
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
899
ut_ad((buf_pool_mutex_own(buf_pool)
900
&& (block->page.buf_fix_count == 0))
901
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
902
#endif /* UNIV_SYNC_DEBUG */
904
block->modify_clock++;
907
/********************************************************************//**
908
Returns the value of the modify clock. The caller must have an s-lock
909
or x-lock on the block.
913
buf_block_get_modify_clock(
914
/*=======================*/
915
buf_block_t* block) /*!< in: block */
917
#ifdef UNIV_SYNC_DEBUG
918
ut_ad(rw_lock_own(&(block->lock), RW_LOCK_SHARED)
919
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
920
#endif /* UNIV_SYNC_DEBUG */
922
return(block->modify_clock);
925
/*******************************************************************//**
926
Increments the bufferfix count. */
929
buf_block_buf_fix_inc_func(
930
/*=======================*/
931
#ifdef UNIV_SYNC_DEBUG
932
const char* file, /*!< in: file name */
933
ulint line, /*!< in: line */
934
#endif /* UNIV_SYNC_DEBUG */
935
buf_block_t* block) /*!< in/out: block to bufferfix */
937
#ifdef UNIV_SYNC_DEBUG
940
ret = rw_lock_s_lock_nowait(&(block->debug_latch), file, line);
942
#endif /* UNIV_SYNC_DEBUG */
943
ut_ad(mutex_own(&block->mutex));
945
block->page.buf_fix_count++;
947
#ifdef UNIV_SYNC_DEBUG
948
/** Increments the bufferfix count.
949
@param b in/out: block to bufferfix
950
@param f in: file name where requested
951
@param l in: line number where requested */
952
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b)
953
#else /* UNIV_SYNC_DEBUG */
954
/** Increments the bufferfix count.
955
@param b in/out: block to bufferfix
956
@param f in: file name where requested
957
@param l in: line number where requested */
958
# define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b)
959
#endif /* UNIV_SYNC_DEBUG */
961
/*******************************************************************//**
962
Decrements the bufferfix count. */
965
buf_block_buf_fix_dec(
966
/*==================*/
967
buf_block_t* block) /*!< in/out: block to bufferunfix */
969
ut_ad(mutex_own(&block->mutex));
971
block->page.buf_fix_count--;
972
#ifdef UNIV_SYNC_DEBUG
973
rw_lock_s_unlock(&block->debug_latch);
977
/******************************************************************//**
978
Returns the buffer pool instance given space and offset of page
979
@return buffer pool */
984
ulint space, /*!< in: space id */
985
ulint offset) /*!< in: offset of the page within space */
989
ulint ignored_offset;
991
ignored_offset = offset >> 6; /* 2log of BUF_READ_AHEAD_AREA (64)*/
992
fold = buf_page_address_fold(space, ignored_offset);
993
index = fold % srv_buf_pool_instances;
994
return(&buf_pool_ptr[index]);
997
/******************************************************************//**
998
Returns the buffer pool instance given its array index
999
@return buffer pool */
1002
buf_pool_from_array(
1003
/*================*/
1004
ulint index) /*!< in: array index to get
1005
buffer pool instance from */
1007
ut_ad(index < MAX_BUFFER_POOLS);
1008
ut_ad(index < srv_buf_pool_instances);
1009
return(&buf_pool_ptr[index]);
1012
/******************************************************************//**
1013
Returns the control block of a file page, NULL if not found.
1014
@return block, NULL if not found */
1017
buf_page_hash_get_low(
1018
/*==================*/
1019
buf_pool_t* buf_pool, /*!< buffer pool instance */
1020
ulint space, /*!< in: space id */
1021
ulint offset, /*!< in: offset of the page
1023
ulint fold) /*!< in: buf_page_address_fold(
1029
ut_ad(buf_pool_mutex_own(buf_pool));
1030
ut_ad(fold == buf_page_address_fold(space, offset));
1032
/* Look for the page in the hash table */
1034
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
1035
ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
1036
&& buf_page_in_file(bpage)),
1037
bpage->space == space && bpage->offset == offset);
1039
ut_a(buf_page_in_file(bpage));
1040
ut_ad(bpage->in_page_hash);
1041
ut_ad(!bpage->in_zip_hash);
1042
#if UNIV_WORD_SIZE == 4
1043
/* On 32-bit systems, there is no padding in
1044
buf_page_t. On other systems, Valgrind could complain
1045
about uninitialized pad bytes. */
1046
UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
1053
/******************************************************************//**
1054
Returns the control block of a file page, NULL if not found.
1055
@return block, NULL if not found or not a real control block */
1060
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1061
ulint space, /*!< in: space id */
1062
ulint offset) /*!< in: offset of the page
1066
ulint fold = buf_page_address_fold(space, offset);
1068
bpage = buf_page_hash_get_low(buf_pool, space, offset, fold);
1070
if (bpage && buf_pool_watch_is_sentinel(buf_pool, bpage)) {
1077
/******************************************************************//**
1078
Returns the control block of a file page, NULL if not found
1079
or an uncompressed page frame does not exist.
1080
@return block, NULL if not found */
1085
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1086
ulint space, /*!< in: space id */
1087
ulint offset) /*!< in: offset of the page
1092
block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
1097
/********************************************************************//**
1098
Returns TRUE if the page can be found in the buffer pool hash table.
1100
NOTE that it is possible that the page is not yet read from disk,
1103
@return TRUE if found in the page hash table */
1108
ulint space, /*!< in: space id */
1109
ulint offset) /*!< in: page number */
1111
const buf_page_t* bpage;
1112
buf_pool_t* buf_pool = buf_pool_get(space, offset);
1114
buf_pool_mutex_enter(buf_pool);
1116
bpage = buf_page_hash_get(buf_pool, space, offset);
1118
buf_pool_mutex_exit(buf_pool);
1120
return(bpage != NULL);
1123
/********************************************************************//**
1124
Releases a compressed-only page acquired with buf_page_get_zip(). */
1127
buf_page_release_zip(
1128
/*=================*/
1129
buf_page_t* bpage) /*!< in: buffer block */
1132
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
1135
ut_a(bpage->buf_fix_count > 0);
1137
switch (buf_page_get_state(bpage)) {
1138
case BUF_BLOCK_ZIP_PAGE:
1139
case BUF_BLOCK_ZIP_DIRTY:
1140
mutex_enter(&buf_pool->zip_mutex);
1141
bpage->buf_fix_count--;
1142
mutex_exit(&buf_pool->zip_mutex);
1144
case BUF_BLOCK_FILE_PAGE:
1145
block = (buf_block_t*) bpage;
1146
mutex_enter(&block->mutex);
1147
#ifdef UNIV_SYNC_DEBUG
1148
rw_lock_s_unlock(&block->debug_latch);
1150
bpage->buf_fix_count--;
1151
mutex_exit(&block->mutex);
1153
case BUF_BLOCK_ZIP_FREE:
1154
case BUF_BLOCK_NOT_USED:
1155
case BUF_BLOCK_READY_FOR_USE:
1156
case BUF_BLOCK_MEMORY:
1157
case BUF_BLOCK_REMOVE_HASH:
1165
/********************************************************************//**
1166
Decrements the bufferfix count of a buffer control block and releases
1167
a latch, if specified. */
1172
buf_block_t* block, /*!< in: buffer block */
1173
ulint rw_latch) /*!< in: RW_S_LATCH, RW_X_LATCH,
1178
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1179
ut_a(block->page.buf_fix_count > 0);
1181
mutex_enter(&block->mutex);
1183
#ifdef UNIV_SYNC_DEBUG
1184
rw_lock_s_unlock(&(block->debug_latch));
1186
block->page.buf_fix_count--;
1188
mutex_exit(&block->mutex);
1190
if (rw_latch == RW_S_LATCH) {
1191
rw_lock_s_unlock(&(block->lock));
1192
} else if (rw_latch == RW_X_LATCH) {
1193
rw_lock_x_unlock(&(block->lock));
1197
#ifdef UNIV_SYNC_DEBUG
1198
/*********************************************************************//**
1199
Adds latch level info for the rw-lock protecting the buffer frame. This
1200
should be called in the debug version after a successful latching of a
1201
page if we know the latching order level of the acquired latch. */
1204
buf_block_dbg_add_level(
1205
/*====================*/
1206
buf_block_t* block, /*!< in: buffer page
1207
where we have acquired latch */
1208
ulint level) /*!< in: latching order level */
1210
sync_thread_add_level(&block->lock, level);
1212
#endif /* UNIV_SYNC_DEBUG */
1213
/********************************************************************//**
1214
Acquire mutex on all buffer pool instances. */
1217
buf_pool_mutex_enter_all(void)
1218
/*==========================*/
1222
for (i = 0; i < srv_buf_pool_instances; i++) {
1223
buf_pool_t* buf_pool;
1225
buf_pool = buf_pool_from_array(i);
1226
buf_pool_mutex_enter(buf_pool);
1230
/********************************************************************//**
1231
Release mutex on all buffer pool instances. */
1234
buf_pool_mutex_exit_all(void)
1235
/*=========================*/
1239
for (i = 0; i < srv_buf_pool_instances; i++) {
1240
buf_pool_t* buf_pool;
1242
buf_pool = buf_pool_from_array(i);
1243
buf_pool_mutex_exit(buf_pool);
1246
#endif /* !UNIV_HOTBACKUP */