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