1
1
/*****************************************************************************
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (C) 2008, Google Inc.
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
31
31
*******************************************************/
33
33
#include "mtr0mtr.h"
34
#ifndef UNIV_HOTBACKUP
35
34
#include "buf0flu.h"
36
35
#include "buf0lru.h"
37
36
#include "buf0rea.h"
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);
39
103
/********************************************************************//**
40
104
Reads the freed_page_clock of a buffer block.
45
109
/*==========================*/
46
110
const buf_page_t* bpage) /*!< in: block */
48
/* This is sometimes read without holding buf_pool_mutex. */
112
/* This is sometimes read without holding buf_pool->mutex. */
49
113
return(bpage->freed_page_clock);
72
136
/*=====================*/
73
137
const buf_page_t* bpage) /*!< in: block to make younger */
139
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
75
141
if (UNIV_UNLIKELY(buf_pool->freed_page_clock == 0)) {
76
142
/* If eviction has not started yet, do not update the
77
143
statistics or move blocks in the LRU list. This is
93
159
return((buf_pool->freed_page_clock & ((1UL << 31) - 1))
94
160
> ((ulint) bpage->freed_page_clock
95
161
+ (buf_pool->curr_size
96
* (BUF_LRU_OLD_RATIO_DIV - buf_LRU_old_ratio)
162
* (BUF_LRU_OLD_RATIO_DIV - buf_pool->LRU_old_ratio)
97
163
/ (BUF_LRU_OLD_RATIO_DIV * 4))));
101
167
/*********************************************************************//**
102
Gets the current size of buffer buf_pool in bytes.
103
@return size in bytes */
106
buf_pool_get_curr_size(void)
107
/*========================*/
109
return(buf_pool->curr_size * UNIV_PAGE_SIZE);
112
/********************************************************************//**
113
Gets the smallest oldest_modification lsn for any page in the pool. Returns
114
zero if all modified pages have been flushed to disk.
115
@return oldest modification in pool, zero if none */
118
buf_pool_get_oldest_modification(void)
119
/*==================================*/
124
buf_pool_mutex_enter();
126
bpage = UT_LIST_GET_LAST(buf_pool->flush_list);
131
ut_ad(bpage->in_flush_list);
132
lsn = bpage->oldest_modification;
135
buf_pool_mutex_exit();
137
/* The returned answer may be out of date: the flush_list can
138
change after the mutex has been released. */
142
#endif /* !UNIV_HOTBACKUP */
144
/*********************************************************************//**
145
168
Gets the state of a block.
293
316
/*===============*/
294
317
const buf_page_t* bpage) /*!< in: pointer to control block */
319
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
296
321
switch (buf_page_get_state(bpage)) {
297
322
case BUF_BLOCK_ZIP_FREE:
300
325
case BUF_BLOCK_ZIP_PAGE:
301
326
case BUF_BLOCK_ZIP_DIRTY:
302
return(&buf_pool_zip_mutex);
327
return(&buf_pool->zip_mutex);
304
329
return(&((buf_block_t*) bpage)->mutex);
400
425
buf_page_t* bpage, /*!< in/out: control block */
401
426
enum buf_io_fix io_fix) /*!< in: io_fix state */
403
ut_ad(buf_pool_mutex_own());
429
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
430
ut_ad(buf_pool_mutex_own(buf_pool));
404
432
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
406
434
bpage->io_fix = io_fix;
428
456
/*==================*/
429
457
const buf_page_t* bpage) /*!< control block being relocated */
431
ut_ad(buf_pool_mutex_own());
460
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
461
ut_ad(buf_pool_mutex_own(buf_pool));
432
463
ut_ad(mutex_own(buf_page_get_mutex(bpage)));
433
464
ut_ad(buf_page_in_file(bpage));
434
465
ut_ad(bpage->in_LRU_list);
447
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));
449
484
ut_ad(buf_page_in_file(bpage));
450
ut_ad(buf_pool_mutex_own());
452
486
return(bpage->old);
461
495
buf_page_t* bpage, /*!< in/out: control block */
462
496
ibool old) /*!< in: old */
499
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
500
#endif /* UNIV_DEBUG */
464
501
ut_a(buf_page_in_file(bpage));
465
ut_ad(buf_pool_mutex_own());
502
ut_ad(buf_pool_mutex_own(buf_pool));
466
503
ut_ad(bpage->in_LRU_list);
468
505
#ifdef UNIV_LRU_DEBUG
508
545
buf_page_t* bpage, /*!< in/out: control block */
509
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));
511
552
ut_a(buf_page_in_file(bpage));
512
ut_ad(buf_pool_mutex_own());
514
554
if (!bpage->access_time) {
515
555
/* Make this the time of the first access. */
717
757
/********************************************************************//**
718
Allocates a buffer block.
719
@return own: the allocated block, in state BUF_BLOCK_MEMORY */
724
ulint zip_size) /*!< in: compressed page size in bytes,
725
or 0 if uncompressed tablespace */
729
block = buf_LRU_get_free_block(zip_size);
731
buf_block_set_state(block, BUF_BLOCK_MEMORY);
736
/********************************************************************//**
737
758
Frees a buffer block which does not contain a file page. */
825
848
buf_block_t* block) /*!< in: block */
827
850
#ifdef UNIV_SYNC_DEBUG
828
ut_ad((buf_pool_mutex_own()
851
buf_pool_t* buf_pool = buf_pool_from_bpage((buf_page_t*)block);
853
ut_ad((buf_pool_mutex_own(buf_pool)
829
854
&& (block->page.buf_fix_count == 0))
830
855
|| rw_lock_own(&(block->lock), RW_LOCK_EXCLUSIVE));
831
856
#endif /* UNIV_SYNC_DEBUG */
906
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
/******************************************************************//**
907
967
Returns the control block of a file page, NULL if not found.
908
968
@return block, NULL if not found */
913
ulint space, /*!< in: space id */
914
ulint offset) /*!< in: offset of the page within space */
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(
916
980
buf_page_t* bpage;
920
ut_ad(buf_pool_mutex_own());
983
ut_ad(buf_pool_mutex_own(buf_pool));
984
ut_ad(fold == buf_page_address_fold(space, offset));
922
986
/* Look for the page in the hash table */
924
fold = buf_page_address_fold(space, offset);
926
988
HASH_SEARCH(hash, buf_pool->page_hash, fold, buf_page_t*, bpage,
927
989
ut_ad(bpage->in_page_hash && !bpage->in_zip_hash
928
990
&& buf_page_in_file(bpage)),
945
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
/******************************************************************//**
946
1032
Returns the control block of a file page, NULL if not found
947
1033
or an uncompressed page frame does not exist.
948
1034
@return block, NULL if not found */
951
1037
buf_block_hash_get(
952
1038
/*===============*/
953
ulint space, /*!< in: space id */
954
ulint offset) /*!< in: offset of the page within space */
1039
buf_pool_t* buf_pool, /*!< in: buffer pool instance */
1040
ulint space, /*!< in: space id */
1041
ulint offset) /*!< in: offset of the page
956
return(buf_page_get_block(buf_page_hash_get(space, offset)));
1046
block = buf_page_get_block(buf_page_hash_get(buf_pool, space, offset));
959
1051
/********************************************************************//**
971
1063
ulint offset) /*!< in: page number */
973
1065
const buf_page_t* bpage;
975
buf_pool_mutex_enter();
977
bpage = buf_page_hash_get(space, offset);
979
buf_pool_mutex_exit();
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);
981
1074
return(bpage != NULL);
997
1091
switch (buf_page_get_state(bpage)) {
998
1092
case BUF_BLOCK_ZIP_PAGE:
999
1093
case BUF_BLOCK_ZIP_DIRTY:
1000
mutex_enter(&buf_pool_zip_mutex);
1094
mutex_enter(&buf_pool->zip_mutex);
1001
1095
bpage->buf_fix_count--;
1002
mutex_exit(&buf_pool_zip_mutex);
1096
mutex_exit(&buf_pool->zip_mutex);
1004
1098
case BUF_BLOCK_FILE_PAGE:
1005
1099
block = (buf_block_t*) bpage;
1029
1124
buf_page_release(
1030
1125
/*=============*/
1031
1126
buf_block_t* block, /*!< in: buffer block */
1032
ulint rw_latch, /*!< in: RW_S_LATCH, RW_X_LATCH,
1127
ulint rw_latch) /*!< in: RW_S_LATCH, RW_X_LATCH,
1034
mtr_t* mtr) /*!< in: mtr */
1038
1132
ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
1039
1133
ut_a(block->page.buf_fix_count > 0);
1041
if (rw_latch == RW_X_LATCH && mtr->modifications) {
1042
buf_pool_mutex_enter();
1043
buf_flush_note_modification(block, mtr);
1044
buf_pool_mutex_exit();
1047
1135
mutex_enter(&block->mutex);
1049
1137
#ifdef UNIV_SYNC_DEBUG
1076
1164
sync_thread_add_level(&block->lock, level);
1078
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);
1079
1200
#endif /* !UNIV_HOTBACKUP */