246
246
page_arr = ut_malloc(sizeof(ulint)
247
247
* BUF_LRU_DROP_SEARCH_HASH_SIZE);
248
248
buf_pool_mutex_enter();
252
252
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
254
254
while (bpage != NULL) {
255
mutex_t* block_mutex = buf_page_get_mutex(bpage);
256
255
buf_page_t* prev_bpage;
258
mutex_enter(block_mutex);
259
258
prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
261
260
ut_a(buf_page_in_file(bpage));
263
262
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE
264
263
|| bpage->space != id
265
|| bpage->buf_fix_count > 0
266
264
|| bpage->io_fix != BUF_IO_NONE) {
267
/* We leave the fixed pages as is in this scan.
268
To be dealt with later in the final scan. */
269
mutex_exit(block_mutex);
273
if (((buf_block_t*) bpage)->is_hashed) {
275
/* Store the offset(i.e.: page_no) in the array
276
so that we can drop hash index in a batch
278
page_arr[num_entries] = bpage->offset;
279
mutex_exit(block_mutex);
280
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
283
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
286
/* Array full. We release the buf_pool_mutex to
287
obey the latching order. */
288
buf_pool_mutex_exit();
290
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
293
buf_pool_mutex_enter();
295
mutex_exit(block_mutex);
265
/* Compressed pages are never hashed.
266
Skip blocks of other tablespaces.
267
Skip I/O-fixed blocks (to be dealt with later). */
299
/* Note that we may have released the buf_pool mutex
300
above after reading the prev_bpage during processing
301
of a page_hash_batch (i.e.: when the array was full).
302
This means that prev_bpage can change in LRU list.
303
This is OK because this function is a 'best effort'
304
to drop as many search hash entries as possible and
305
it does not guarantee that ALL such entries will be
273
mutex_enter(&((buf_block_t*) bpage)->mutex);
274
is_fixed = bpage->buf_fix_count > 0
275
|| !((buf_block_t*) bpage)->index;
276
mutex_exit(&((buf_block_t*) bpage)->mutex);
282
/* Store the page number so that we can drop the hash
283
index in a batch later. */
284
page_arr[num_entries] = bpage->offset;
285
ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
288
if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
292
/* Array full. We release the buf_pool_mutex to
293
obey the latching order. */
294
buf_pool_mutex_exit();
295
buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
297
buf_pool_mutex_enter();
300
/* Note that we released the buf_pool mutex above
301
after reading the prev_bpage during processing of a
302
page_hash_batch (i.e.: when the array was full).
303
Because prev_bpage could belong to a compressed-only
304
block, it may have been relocated, and thus the
305
pointer cannot be trusted. Because bpage is of type
306
buf_block_t, it is safe to dereference.
308
bpage can change in the LRU list. This is OK because
309
this function is a 'best effort' to drop as many
310
search hash entries as possible and it does not
311
guarantee that ALL such entries will be dropped. */
309
313
/* If, however, bpage has been removed from LRU list
310
314
to the free list then we should restart the scan.
311
315
bpage->state is protected by buf_pool mutex. */
312
if (bpage && !buf_page_in_file(bpage)) {
313
ut_a(num_entries == 0);
317
&& buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
364
368
if (buf_page_get_space(bpage) != id) {
365
369
/* Skip this block, as it does not belong to
366
370
the space that is being invalidated. */
367
372
} else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
368
373
/* We cannot remove this page during this scan
369
374
yet; maybe the system is currently reading it
370
375
in, or flushing the modifications to the file */
372
377
all_freed = FALSE;
374
mutex_t* block_mutex = buf_page_get_mutex(bpage);
380
block_mutex = buf_page_get_mutex(bpage);
375
381
mutex_enter(block_mutex);
377
383
if (bpage->buf_fix_count > 0) {
385
mutex_exit(block_mutex);
379
386
/* We cannot remove this page during
380
387
this scan yet; maybe the system is
381
388
currently reading it in, or flushing
397
ut_ad(mutex_own(block_mutex));
389
399
#ifdef UNIV_DEBUG
390
if (buf_debug_prints) {
392
"Dropping space %lu page %lu\n",
393
(ulong) buf_page_get_space(bpage),
394
(ulong) buf_page_get_page_no(bpage));
400
if (buf_debug_prints) {
402
"Dropping space %lu page %lu\n",
403
(ulong) buf_page_get_space(bpage),
404
(ulong) buf_page_get_page_no(bpage));
397
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
398
/* This is a compressed-only block
399
descriptor. Ensure that prev_bpage
400
cannot be relocated when bpage is freed. */
401
if (UNIV_LIKELY(prev_bpage != NULL)) {
402
switch (buf_page_get_state(
404
case BUF_BLOCK_FILE_PAGE:
405
/* Descriptors of uncompressed
406
blocks will not be relocated,
407
because we are holding the
410
case BUF_BLOCK_ZIP_PAGE:
411
case BUF_BLOCK_ZIP_DIRTY:
412
/* Descriptors of compressed-
413
only blocks can be relocated,
414
unless they are buffer-fixed.
415
Because both bpage and
416
prev_bpage are protected by
417
buf_pool_zip_mutex, it is
418
not necessary to acquire
420
ut_ad(&buf_pool_zip_mutex
422
ut_ad(mutex_own(block_mutex));
423
prev_bpage_buf_fix = TRUE;
424
prev_bpage->buf_fix_count++;
430
} else if (((buf_block_t*) bpage)->is_hashed) {
434
buf_pool_mutex_exit();
436
zip_size = buf_page_get_zip_size(bpage);
437
page_no = buf_page_get_page_no(bpage);
439
mutex_exit(block_mutex);
441
/* Note that the following call will acquire
442
an S-latch on the page */
444
btr_search_drop_page_hash_when_freed(
445
id, zip_size, page_no);
449
if (bpage->oldest_modification != 0) {
451
buf_flush_remove(bpage);
454
/* Remove from the LRU list. */
456
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
457
!= BUF_BLOCK_ZIP_FREE) {
458
buf_LRU_block_free_hashed_page((buf_block_t*)
461
/* The block_mutex should have been
462
released by buf_LRU_block_remove_hashed_page()
463
when it returns BUF_BLOCK_ZIP_FREE. */
464
ut_ad(block_mutex == &buf_pool_zip_mutex);
465
ut_ad(!mutex_own(block_mutex));
467
if (prev_bpage_buf_fix) {
468
/* We temporarily buffer-fixed
470
buf_buddy_free() could not
471
relocate it, in case it was a
472
compressed-only block
475
mutex_enter(block_mutex);
476
ut_ad(prev_bpage->buf_fix_count > 0);
477
prev_bpage->buf_fix_count--;
478
mutex_exit(block_mutex);
481
goto next_page_no_mutex;
407
if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
408
/* This is a compressed-only block
409
descriptor. Do nothing. */
410
} else if (((buf_block_t*) bpage)->index) {
414
buf_pool_mutex_exit();
416
zip_size = buf_page_get_zip_size(bpage);
417
page_no = buf_page_get_page_no(bpage);
419
mutex_exit(block_mutex);
421
/* Note that the following call will acquire
422
and release an X-latch on the page. */
424
btr_search_drop_page_hash_when_freed(
425
id, zip_size, page_no);
429
if (bpage->oldest_modification != 0) {
431
buf_flush_remove(bpage);
434
/* Remove from the LRU list. */
436
if (buf_LRU_block_remove_hashed_page(bpage, TRUE)
437
!= BUF_BLOCK_ZIP_FREE) {
438
buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
439
mutex_exit(block_mutex);
441
/* The block_mutex should have been released
442
by buf_LRU_block_remove_hashed_page() when it
443
returns BUF_BLOCK_ZIP_FREE. */
444
ut_ad(block_mutex == &buf_pool_zip_mutex);
445
ut_ad(!mutex_own(block_mutex));
484
mutex_exit(block_mutex);
488
448
bpage = prev_bpage;
568
530
UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
569
531
block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
571
enum buf_lru_free_block_status freed;
573
535
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
574
536
ut_ad(block->in_unzip_LRU_list);
575
537
ut_ad(block->page.in_LRU_list);
577
539
mutex_enter(&block->mutex);
578
freed = buf_LRU_free_block(&block->page, FALSE, NULL);
540
freed = buf_LRU_free_block(&block->page, FALSE);
579
541
mutex_exit(&block->mutex);
585
case BUF_LRU_CANNOT_RELOCATE:
586
/* If we failed to relocate, try
587
regular LRU eviction. */
590
case BUF_LRU_NOT_FREED:
591
/* The block was buffer-fixed or I/O-fixed.
596
/* inappropriate return value from
597
buf_LRU_free_block() */
626
573
UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
627
574
bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
629
enum buf_lru_free_block_status freed;
632
= buf_page_get_mutex(bpage);
578
mutex_t* block_mutex = buf_page_get_mutex(bpage);
634
580
ut_ad(buf_page_in_file(bpage));
635
581
ut_ad(bpage->in_LRU_list);
637
583
mutex_enter(block_mutex);
638
584
accessed = buf_page_is_accessed(bpage);
639
freed = buf_LRU_free_block(bpage, TRUE, NULL);
585
freed = buf_LRU_free_block(bpage, TRUE);
640
586
mutex_exit(block_mutex);
644
589
/* Keep track of pages that are evicted without
645
590
ever being accessed. This gives us a measure of
646
591
the effectiveness of readahead */
878
807
/* If there is a block in the free list, take it */
879
808
block = buf_LRU_get_free_only();
809
buf_pool_mutex_exit();
883
block->page.zip.m_start =
884
#endif /* UNIV_DEBUG */
885
block->page.zip.m_end =
886
block->page.zip.m_nonempty =
887
block->page.zip.n_blobs = 0;
889
if (UNIV_UNLIKELY(zip_size)) {
891
page_zip_set_size(&block->page.zip, zip_size);
892
block->page.zip.data = buf_buddy_alloc(zip_size, &lru);
893
UNIV_MEM_DESC(block->page.zip.data, zip_size, block);
895
page_zip_set_size(&block->page.zip, 0);
896
block->page.zip.data = NULL;
899
buf_pool_mutex_exit();
812
memset(&block->page.zip, 0, sizeof block->page.zip);
901
814
if (started_monitor) {
902
815
srv_print_innodb_monitor = mon_value_was;
1364
1275
Try to free a block. If bpage is a descriptor of a compressed-only
1365
1276
page, the descriptor object will be freed as well.
1367
NOTE: If this function returns BUF_LRU_FREED, it will temporarily
1278
NOTE: If this function returns TRUE, it will temporarily
1368
1279
release buf_pool_mutex. Furthermore, the page frame will no longer be
1369
1280
accessible via bpage.
1371
1282
The caller must hold buf_pool_mutex and buf_page_get_mutex(bpage) and
1372
1283
release these two mutexes after the call. No other
1373
1284
buf_page_get_mutex() may be held when calling this function.
1374
@return BUF_LRU_FREED if freed, BUF_LRU_CANNOT_RELOCATE or
1375
BUF_LRU_NOT_FREED otherwise. */
1285
@return TRUE if freed, FALSE otherwise. */
1377
enum buf_lru_free_block_status
1378
1288
buf_LRU_free_block(
1379
1289
/*===============*/
1380
1290
buf_page_t* bpage, /*!< in: block to be freed */
1381
ibool zip, /*!< in: TRUE if should remove also the
1291
ibool zip) /*!< in: TRUE if should remove also the
1382
1292
compressed page of an uncompressed page */
1383
ibool* buf_pool_mutex_released)
1384
/*!< in: pointer to a variable that will
1385
be assigned TRUE if buf_pool_mutex
1386
was temporarily released, or NULL */
1388
1294
buf_page_t* b = NULL;
1389
1295
mutex_t* block_mutex = buf_page_get_mutex(bpage);
1821
1719
ut_a(bpage->zip.data);
1822
1720
ut_a(buf_page_get_zip_size(bpage));
1722
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1824
1723
UT_LIST_REMOVE(list, buf_pool->zip_clean, bpage);
1724
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1826
1726
mutex_exit(&buf_pool_zip_mutex);
1827
1727
buf_pool_mutex_exit_forbid();
1828
1728
buf_buddy_free(bpage->zip.data,
1829
1729
page_zip_get_size(&bpage->zip));
1830
buf_buddy_free(bpage, sizeof(*bpage));
1831
1730
buf_pool_mutex_exit_allow();
1832
UNIV_MEM_UNDESC(bpage);
1731
buf_page_free_descriptor(bpage);
1833
1732
return(BUF_BLOCK_ZIP_FREE);
1835
1734
case BUF_BLOCK_FILE_PAGE:
1955
1855
buf_LRU_stat_arr_ind++;
1956
1856
buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL;
1958
/* Add the current value and subtract the obsolete entry. */
1959
buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io;
1960
buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip;
1858
/* Add the current value and subtract the obsolete entry.
1859
Since buf_LRU_stat_cur is not protected by any mutex,
1860
it can be changing between adding to buf_LRU_stat_sum
1861
and copying to item. Assign it to local variables to make
1862
sure the same value assign to the buf_LRU_stat_sum
1864
cur_stat = buf_LRU_stat_cur;
1866
buf_LRU_stat_sum.io += cur_stat.io - item->io;
1867
buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip;
1962
1869
/* Put current entry in the array. */
1963
memcpy(item, &buf_LRU_stat_cur, sizeof *item);
1870
memcpy(item, &cur_stat, sizeof *item);
1965
1872
buf_pool_mutex_exit();