57
58
#define BUF_LRU_OLD_TOLERANCE 20
59
/* The whole LRU list length is divided by this number to determine an
60
/** The whole LRU list length is divided by this number to determine an
60
61
initial segment in buf_LRU_get_recent_limit */
62
63
#define BUF_LRU_INITIAL_RATIO 8
64
/* When dropping the search hash index entries before deleting an ibd
65
/** When dropping the search hash index entries before deleting an ibd
65
66
file, we build a local array of pages belonging to that tablespace
66
67
in the buffer pool. Following is the size of that array. */
67
68
#define BUF_LRU_DROP_SEARCH_HASH_SIZE 1024
69
/* If we switch on the InnoDB monitor because there are too few available
70
/** If we switch on the InnoDB monitor because there are too few available
70
71
frames in the buffer pool, we set this to TRUE */
71
UNIV_INTERN ibool buf_lru_switched_on_innodb_mon = FALSE;
72
static ibool buf_lru_switched_on_innodb_mon = FALSE;
73
/**********************************************************************
74
/******************************************************************//**
74
75
These statistics are not 'of' LRU but 'for' LRU. We keep count of I/O
75
76
and page_zip_decompress() operations. Based on the statistics,
76
77
buf_LRU_evict_from_unzip_LRU() decides if we want to evict from
79
80
the regular LRU, we will evict the entire block (i.e.: both the
80
81
uncompressed and compressed data), which must be clean. */
82
/* Number of intervals for which we keep the history of these stats.
85
/** Number of intervals for which we keep the history of these stats.
83
86
Each interval is 1 second, defined by the rate at which
84
87
srv_error_monitor_thread() calls buf_LRU_stat_update(). */
85
88
#define BUF_LRU_STAT_N_INTERVAL 50
87
/* Co-efficient with which we multiply I/O operations to equate them
90
/** Co-efficient with which we multiply I/O operations to equate them
88
91
with page_zip_decompress() operations. */
89
92
#define BUF_LRU_IO_TO_UNZIP_FACTOR 50
91
/* Sampled values buf_LRU_stat_cur.
94
/** Sampled values buf_LRU_stat_cur.
92
95
Protected by buf_pool_mutex. Updated by buf_LRU_stat_update(). */
93
96
static buf_LRU_stat_t buf_LRU_stat_arr[BUF_LRU_STAT_N_INTERVAL];
94
/* Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
97
/** Cursor to buf_LRU_stat_arr[] that is updated in a round-robin fashion. */
95
98
static ulint buf_LRU_stat_arr_ind;
97
/* Current operation counters. Not protected by any mutex. Cleared
100
/** Current operation counters. Not protected by any mutex. Cleared
98
101
by buf_LRU_stat_update(). */
99
102
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_cur;
101
/* Running sum of past values of buf_LRU_stat_cur.
104
/** Running sum of past values of buf_LRU_stat_cur.
102
105
Updated by buf_LRU_stat_update(). Protected by buf_pool_mutex. */
103
106
UNIV_INTERN buf_LRU_stat_t buf_LRU_stat_sum;
105
/**********************************************************************
110
/******************************************************************//**
106
111
Takes a block out of the LRU list and page hash table.
107
112
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
108
113
the object will be freed and buf_pool_zip_mutex will be released.
110
115
If a compressed page or a compressed-only block descriptor is freed,
111
116
other compressed pages or compressed-only block descriptors may be
118
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
119
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
114
121
enum buf_page_state
115
122
buf_LRU_block_remove_hashed_page(
116
123
/*=============================*/
117
/* out: the new state of the block
118
(BUF_BLOCK_ZIP_FREE if the state was
119
BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
121
buf_page_t* bpage, /* in: block, must contain a file page and
124
buf_page_t* bpage, /*!< in: block, must contain a file page and
122
125
be in a state where it can be freed; there
123
126
may or may not be a hash index to the page */
124
ibool zip); /* in: TRUE if should remove also the
127
ibool zip); /*!< in: TRUE if should remove also the
125
128
compressed page of an uncompressed page */
126
/**********************************************************************
129
/******************************************************************//**
127
130
Puts a file page whose has no hash index to the free list. */
130
133
buf_LRU_block_free_hashed_page(
131
134
/*===========================*/
132
buf_block_t* block); /* in: block, must contain a file page and
135
buf_block_t* block); /*!< in: block, must contain a file page and
133
136
be in a state where it can be freed */
135
/**********************************************************************
138
/******************************************************************//**
136
139
Determines if the unzip_LRU list should be used for evicting a victim
137
instead of the general LRU list. */
140
instead of the general LRU list.
141
@return TRUE if should use unzip_LRU */
140
144
buf_LRU_evict_from_unzip_LRU(void)
141
145
/*==============================*/
142
/* out: TRUE if should use unzip_LRU */
179
182
return(unzip_avg <= io_avg * BUF_LRU_IO_TO_UNZIP_FACTOR);
182
/**********************************************************************
185
/******************************************************************//**
183
186
Attempts to drop page hash index on a batch of pages belonging to a
184
187
particular space id. */
187
190
buf_LRU_drop_page_hash_batch(
188
191
/*=========================*/
189
ulint space_id, /* in: space id */
190
ulint zip_size, /* in: compressed page size in bytes
192
ulint space_id, /*!< in: space id */
193
ulint zip_size, /*!< in: compressed page size in bytes
191
194
or 0 for uncompressed pages */
192
const ulint* arr, /* in: array of page_no */
193
ulint count) /* in: number of entries in array */
195
const ulint* arr, /*!< in: array of page_no */
196
ulint count) /*!< in: number of entries in array */
428
/**********************************************************************
431
/******************************************************************//**
429
432
Gets the minimum LRU_position field for the blocks in an initial segment
430
433
(determined by BUF_LRU_INITIAL_RATIO) of the LRU list. The limit is not
431
guaranteed to be precise, because the ulint_clock may wrap around. */
434
guaranteed to be precise, because the ulint_clock may wrap around.
435
@return the limit; zero if could not determine it */
434
438
buf_LRU_get_recent_limit(void)
435
439
/*==========================*/
436
/* out: the limit; zero if could not determine it */
438
441
const buf_page_t* bpage;
454
457
bpage = UT_LIST_GET_FIRST(buf_pool->LRU);
456
limit = buf_page_get_LRU_position(bpage) - len / BUF_LRU_INITIAL_RATIO;
459
limit = buf_page_get_LRU_position(bpage);
460
len /= BUF_LRU_INITIAL_RATIO;
458
462
buf_pool_mutex_exit();
464
return(limit > len ? (limit - len) : 0);
463
/************************************************************************
467
/********************************************************************//**
464
468
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
467
471
buf_LRU_insert_zip_clean(
468
472
/*=====================*/
469
buf_page_t* bpage) /* in: pointer to the block in question */
473
buf_page_t* bpage) /*!< in: pointer to the block in question */
495
/**********************************************************************
499
/******************************************************************//**
496
500
Try to free an uncompressed page of a compressed block from the unzip
497
LRU list. The compressed page is preserved, and it need not be clean. */
501
LRU list. The compressed page is preserved, and it need not be clean.
502
@return TRUE if freed */
500
505
buf_LRU_free_from_unzip_LRU_list(
501
506
/*=============================*/
502
/* out: TRUE if freed */
503
ulint n_iterations) /* in: how many times this has been called
507
ulint n_iterations) /*!< in: how many times this has been called
504
508
repeatedly without result: a high value means
505
509
that we should search farther; we will search
506
510
n_iterations / 5 of the unzip_LRU list,
567
/**********************************************************************
568
Try to free a clean page from the common LRU list. */
571
/******************************************************************//**
572
Try to free a clean page from the common LRU list.
573
@return TRUE if freed */
571
576
buf_LRU_free_from_common_LRU_list(
572
577
/*==============================*/
573
/* out: TRUE if freed */
574
ulint n_iterations) /* in: how many times this has been called
578
ulint n_iterations) /*!< in: how many times this has been called
575
579
repeatedly without result: a high value means
576
580
that we should search farther; if
577
581
n_iterations < 10, then we search
626
/**********************************************************************
627
Try to free a replaceable block. */
630
/******************************************************************//**
631
Try to free a replaceable block.
632
@return TRUE if found and freed */
630
635
buf_LRU_search_and_free_block(
631
636
/*==========================*/
632
/* out: TRUE if found and freed */
633
ulint n_iterations) /* in: how many times this has been called
637
ulint n_iterations) /*!< in: how many times this has been called
634
638
repeatedly without result: a high value means
635
639
that we should search farther; if
636
640
n_iterations < 10, then we search
716
/**********************************************************************
719
/******************************************************************//**
717
720
Returns a free block from the buf_pool. The block is taken off the
718
free list. If it is empty, returns NULL. */
721
free list. If it is empty, returns NULL.
722
@return a free control block, or NULL if the buf_block->free list is empty */
721
725
buf_LRU_get_free_only(void)
722
726
/*=======================*/
723
/* out: a free control block, or NULL
724
if the buf_block->free list is empty */
726
728
buf_block_t* block;
751
/**********************************************************************
753
/******************************************************************//**
752
754
Returns a free block from the buf_pool. The block is taken off the
753
755
free list. If it is empty, blocks are moved from the end of the
754
LRU list to the free list. */
756
LRU list to the free list.
757
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
757
760
buf_LRU_get_free_block(
758
761
/*===================*/
759
/* out: the free control block,
760
in state BUF_BLOCK_READY_FOR_USE */
761
ulint zip_size) /* in: compressed page size in bytes,
762
ulint zip_size) /*!< in: compressed page size in bytes,
762
763
or 0 if uncompressed tablespace */
764
765
buf_block_t* block = NULL;
1201
/**********************************************************************
1202
/******************************************************************//**
1202
1203
Adds a block to the LRU list. */
1205
1206
buf_LRU_add_block_low(
1206
1207
/*==================*/
1207
buf_page_t* bpage, /* in: control block */
1208
ibool old) /* in: TRUE if should be put to the old blocks
1208
buf_page_t* bpage, /*!< in: control block */
1209
ibool old) /*!< in: TRUE if should be put to the old blocks
1209
1210
in the LRU list, else put to the start; if the
1210
1211
LRU list is very short, the block is added to
1211
1212
the start, regardless of this parameter */
1273
/**********************************************************************
1274
/******************************************************************//**
1274
1275
Adds a block to the LRU list. */
1277
1278
buf_LRU_add_block(
1278
1279
/*==============*/
1279
buf_page_t* bpage, /* in: control block */
1280
ibool old) /* in: TRUE if should be put to the old
1280
buf_page_t* bpage, /*!< in: control block */
1281
ibool old) /*!< in: TRUE if should be put to the old
1281
1282
blocks in the LRU list, else put to the start;
1282
1283
if the LRU list is very short, the block is
1283
1284
added to the start, regardless of this
1286
1287
buf_LRU_add_block_low(bpage, old);
1289
/**********************************************************************
1290
/******************************************************************//**
1290
1291
Moves a block to the start of the LRU list. */
1293
1294
buf_LRU_make_block_young(
1294
1295
/*=====================*/
1295
buf_page_t* bpage) /* in: control block */
1296
buf_page_t* bpage) /*!< in: control block */
1297
1298
buf_LRU_remove_block(bpage);
1298
1299
buf_LRU_add_block_low(bpage, FALSE);
1301
/**********************************************************************
1302
/******************************************************************//**
1302
1303
Moves a block to the end of the LRU list. */
1305
1306
buf_LRU_make_block_old(
1306
1307
/*===================*/
1307
buf_page_t* bpage) /* in: control block */
1308
buf_page_t* bpage) /*!< in: control block */
1309
1310
buf_LRU_remove_block(bpage);
1310
1311
buf_LRU_add_block_to_end_low(bpage);
1313
/**********************************************************************
1314
/******************************************************************//**
1314
1315
Try to free a block. If bpage is a descriptor of a compressed-only
1315
1316
page, the descriptor object will be freed as well.
1321
1322
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
1322
1323
release these two mutexes after the call. No other
1323
buf_page_get_mutex() may be held when calling this function. */
1324
buf_page_get_mutex() may be held when calling this function.
1325
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
1326
BUF_LRU_NOT_FREED otherwise. */
1325
1328
enum buf_lru_free_block_status
1326
1329
buf_LRU_free_block(
1327
1330
/*===============*/
1328
/* out: BUF_LRU_FREED if freed,
1329
BUF_LRU_CANNOT_RELOCATE or
1330
BUF_LRU_NOT_FREED otherwise. */
1331
buf_page_t* bpage, /* in: block to be freed */
1332
ibool zip, /* in: TRUE if should remove also the
1331
buf_page_t* bpage, /*!< in: block to be freed */
1332
ibool zip, /*!< in: TRUE if should remove also the
1333
1333
compressed page of an uncompressed page */
1334
1334
ibool* buf_pool_mutex_released)
1335
/* in: pointer to a variable that will
1335
/*!< in: pointer to a variable that will
1336
1336
be assigned TRUE if buf_pool_mutex
1337
1337
was temporarily released, or NULL */
1633
1633
UNIV_MEM_ASSERT_AND_FREE(block->frame, UNIV_PAGE_SIZE);
1636
/**********************************************************************
1636
/******************************************************************//**
1637
1637
Takes a block out of the LRU list and page hash table.
1638
1638
If the block is compressed-only (BUF_BLOCK_ZIP_PAGE),
1639
1639
the object will be freed and buf_pool_zip_mutex will be released.
1641
1641
If a compressed page or a compressed-only block descriptor is freed,
1642
1642
other compressed pages or compressed-only block descriptors may be
1644
@return the new state of the block (BUF_BLOCK_ZIP_FREE if the state
1645
was BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH otherwise) */
1645
1647
enum buf_page_state
1646
1648
buf_LRU_block_remove_hashed_page(
1647
1649
/*=============================*/
1648
/* out: the new state of the block
1649
(BUF_BLOCK_ZIP_FREE if the state was
1650
BUF_BLOCK_ZIP_PAGE, or BUF_BLOCK_REMOVE_HASH
1652
buf_page_t* bpage, /* in: block, must contain a file page and
1650
buf_page_t* bpage, /*!< in: block, must contain a file page and
1653
1651
be in a state where it can be freed; there
1654
1652
may or may not be a hash index to the page */
1655
ibool zip) /* in: TRUE if should remove also the
1653
ibool zip) /*!< in: TRUE if should remove also the
1656
1654
compressed page of an uncompressed page */
1658
1656
const buf_page_t* hashed_bpage;