~ubuntu-branches/ubuntu/natty/mysql-5.1/natty-proposed

« back to all changes in this revision

Viewing changes to storage/innodb_plugin/buf/buf0lru.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-02-22 08:30:45 UTC
  • mfrom: (1.4.1)
  • Revision ID: package-import@ubuntu.com-20120222083045-2rd53r4bnyx7qus4
Tags: 5.1.61-0ubuntu0.11.04.1
* SECURITY UPDATE: Update to 5.1.61 to fix multiple security issues
  (LP: #937869)
  - http://www.oracle.com/technetwork/topics/security/cpujan2012-366304.html
  - CVE-2011-2262
  - CVE-2012-0075
  - CVE-2012-0112
  - CVE-2012-0113
  - CVE-2012-0114
  - CVE-2012-0115
  - CVE-2012-0116
  - CVE-2012-0117
  - CVE-2012-0118
  - CVE-2012-0119
  - CVE-2012-0120
  - CVE-2012-0484
  - CVE-2012-0485
  - CVE-2012-0486
  - CVE-2012-0487
  - CVE-2012-0488
  - CVE-2012-0489
  - CVE-2012-0490
  - CVE-2012-0491
  - CVE-2012-0492
  - CVE-2012-0493
  - CVE-2012-0494
  - CVE-2012-0495
  - CVE-2012-0496

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
246
246
        page_arr = ut_malloc(sizeof(ulint)
247
247
                             * BUF_LRU_DROP_SEARCH_HASH_SIZE);
248
248
        buf_pool_mutex_enter();
249
 
 
250
 
scan_again:
251
249
        num_entries = 0;
 
250
 
 
251
scan_again:
252
252
        bpage = UT_LIST_GET_LAST(buf_pool->LRU);
253
253
 
254
254
        while (bpage != NULL) {
255
 
                mutex_t*        block_mutex = buf_page_get_mutex(bpage);
256
255
                buf_page_t*     prev_bpage;
 
256
                ibool           is_fixed;
257
257
 
258
 
                mutex_enter(block_mutex);
259
258
                prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
260
259
 
261
260
                ut_a(buf_page_in_file(bpage));
262
261
 
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);
270
 
                        goto next_page;
271
 
                }
272
 
 
273
 
                if (((buf_block_t*) bpage)->is_hashed) {
274
 
 
275
 
                        /* Store the offset(i.e.: page_no) in the array
276
 
                        so that we can drop hash index in a batch
277
 
                        later. */
278
 
                        page_arr[num_entries] = bpage->offset;
279
 
                        mutex_exit(block_mutex);
280
 
                        ut_a(num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE);
281
 
                        ++num_entries;
282
 
 
283
 
                        if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
284
 
                                goto next_page;
285
 
                        }
286
 
                        /* Array full. We release the buf_pool_mutex to
287
 
                        obey the latching order. */
288
 
                        buf_pool_mutex_exit();
289
 
 
290
 
                        buf_LRU_drop_page_hash_batch(id, zip_size, page_arr,
291
 
                                                     num_entries);
292
 
                        num_entries = 0;
293
 
                        buf_pool_mutex_enter();
294
 
                } else {
295
 
                        mutex_exit(block_mutex);
296
 
                }
297
 
 
 
265
                        /* Compressed pages are never hashed.
 
266
                        Skip blocks of other tablespaces.
 
267
                        Skip I/O-fixed blocks (to be dealt with later). */
298
268
next_page:
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
306
 
                dropped. */
307
 
                bpage = prev_bpage;
 
269
                        bpage = prev_bpage;
 
270
                        continue;
 
271
                }
 
272
 
 
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);
 
277
 
 
278
                if (is_fixed) {
 
279
                        goto next_page;
 
280
                }
 
281
 
 
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);
 
286
                ++num_entries;
 
287
 
 
288
                if (num_entries < BUF_LRU_DROP_SEARCH_HASH_SIZE) {
 
289
                        goto next_page;
 
290
                }
 
291
 
 
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,
 
296
                                             num_entries);
 
297
                buf_pool_mutex_enter();
 
298
                num_entries = 0;
 
299
 
 
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.
 
307
 
 
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. */
308
312
 
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);
 
316
                if (bpage
 
317
                    && buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
314
318
                        goto scan_again;
315
319
                }
316
320
        }
351
355
 
352
356
        while (bpage != NULL) {
353
357
                buf_page_t*     prev_bpage;
354
 
                ibool           prev_bpage_buf_fix = FALSE;
 
358
                mutex_t*        block_mutex = NULL;
355
359
 
356
360
                ut_a(buf_page_in_file(bpage));
357
361
 
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. */
 
371
                        goto next_page;
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 */
371
376
 
372
377
                        all_freed = FALSE;
 
378
                        goto next_page;
373
379
                } else {
374
 
                        mutex_t* block_mutex = buf_page_get_mutex(bpage);
 
380
                        block_mutex = buf_page_get_mutex(bpage);
375
381
                        mutex_enter(block_mutex);
376
382
 
377
383
                        if (bpage->buf_fix_count > 0) {
378
384
 
 
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
385
392
 
386
393
                                goto next_page;
387
394
                        }
 
395
                }
 
396
 
 
397
                ut_ad(mutex_own(block_mutex));
388
398
 
389
399
#ifdef UNIV_DEBUG
390
 
                        if (buf_debug_prints) {
391
 
                                fprintf(stderr,
392
 
                                        "Dropping space %lu page %lu\n",
393
 
                                        (ulong) buf_page_get_space(bpage),
394
 
                                        (ulong) buf_page_get_page_no(bpage));
395
 
                        }
 
400
                if (buf_debug_prints) {
 
401
                        fprintf(stderr,
 
402
                                "Dropping space %lu page %lu\n",
 
403
                                (ulong) buf_page_get_space(bpage),
 
404
                                (ulong) buf_page_get_page_no(bpage));
 
405
                }
396
406
#endif
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(
403
 
                                                        prev_bpage)) {
404
 
                                        case BUF_BLOCK_FILE_PAGE:
405
 
                                                /* Descriptors of uncompressed
406
 
                                                blocks will not be relocated,
407
 
                                                because we are holding the
408
 
                                                buf_pool_mutex. */
409
 
                                                break;
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
419
 
                                                further mutexes. */
420
 
                                                ut_ad(&buf_pool_zip_mutex
421
 
                                                      == block_mutex);
422
 
                                                ut_ad(mutex_own(block_mutex));
423
 
                                                prev_bpage_buf_fix = TRUE;
424
 
                                                prev_bpage->buf_fix_count++;
425
 
                                                break;
426
 
                                        default:
427
 
                                                ut_error;
428
 
                                        }
429
 
                                }
430
 
                        } else if (((buf_block_t*) bpage)->is_hashed) {
431
 
                                ulint   page_no;
432
 
                                ulint   zip_size;
433
 
 
434
 
                                buf_pool_mutex_exit();
435
 
 
436
 
                                zip_size = buf_page_get_zip_size(bpage);
437
 
                                page_no = buf_page_get_page_no(bpage);
438
 
 
439
 
                                mutex_exit(block_mutex);
440
 
 
441
 
                                /* Note that the following call will acquire
442
 
                                an S-latch on the page */
443
 
 
444
 
                                btr_search_drop_page_hash_when_freed(
445
 
                                        id, zip_size, page_no);
446
 
                                goto scan_again;
447
 
                        }
448
 
 
449
 
                        if (bpage->oldest_modification != 0) {
450
 
 
451
 
                                buf_flush_remove(bpage);
452
 
                        }
453
 
 
454
 
                        /* Remove from the LRU list. */
455
 
 
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*)
459
 
                                                               bpage);
460
 
                        } else {
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));
466
 
 
467
 
                                if (prev_bpage_buf_fix) {
468
 
                                        /* We temporarily buffer-fixed
469
 
                                        prev_bpage, so that
470
 
                                        buf_buddy_free() could not
471
 
                                        relocate it, in case it was a
472
 
                                        compressed-only block
473
 
                                        descriptor. */
474
 
 
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);
479
 
                                }
480
 
 
481
 
                                goto next_page_no_mutex;
482
 
                        }
 
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) {
 
411
                        ulint   page_no;
 
412
                        ulint   zip_size;
 
413
 
 
414
                        buf_pool_mutex_exit();
 
415
 
 
416
                        zip_size = buf_page_get_zip_size(bpage);
 
417
                        page_no = buf_page_get_page_no(bpage);
 
418
 
 
419
                        mutex_exit(block_mutex);
 
420
 
 
421
                        /* Note that the following call will acquire
 
422
                        and release an X-latch on the page. */
 
423
 
 
424
                        btr_search_drop_page_hash_when_freed(
 
425
                                id, zip_size, page_no);
 
426
                        goto scan_again;
 
427
                }
 
428
 
 
429
                if (bpage->oldest_modification != 0) {
 
430
 
 
431
                        buf_flush_remove(bpage);
 
432
                }
 
433
 
 
434
                /* Remove from the LRU list. */
 
435
 
 
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);
 
440
                } else {
 
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));
 
446
                }
483
447
next_page:
484
 
                        mutex_exit(block_mutex);
485
 
                }
486
 
 
487
 
next_page_no_mutex:
488
448
                bpage = prev_bpage;
489
449
        }
490
450
 
497
457
        }
498
458
}
499
459
 
 
460
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
500
461
/********************************************************************//**
501
462
Insert a compressed block into buf_pool->zip_clean in the LRU order. */
502
463
UNIV_INTERN
528
489
                UT_LIST_ADD_FIRST(list, buf_pool->zip_clean, bpage);
529
490
        }
530
491
}
 
492
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
531
493
 
532
494
/******************************************************************//**
533
495
Try to free an uncompressed page of a compressed block from the unzip
568
530
             UNIV_LIKELY(block != NULL) && UNIV_LIKELY(distance > 0);
569
531
             block = UT_LIST_GET_PREV(unzip_LRU, block), distance--) {
570
532
 
571
 
                enum buf_lru_free_block_status  freed;
 
533
                ibool freed;
572
534
 
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);
576
538
 
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);
580
542
 
581
 
                switch (freed) {
582
 
                case BUF_LRU_FREED:
 
543
                if (freed) {
583
544
                        return(TRUE);
584
 
 
585
 
                case BUF_LRU_CANNOT_RELOCATE:
586
 
                        /* If we failed to relocate, try
587
 
                        regular LRU eviction. */
588
 
                        return(FALSE);
589
 
 
590
 
                case BUF_LRU_NOT_FREED:
591
 
                        /* The block was buffer-fixed or I/O-fixed.
592
 
                        Keep looking. */
593
 
                        continue;
594
545
                }
595
 
 
596
 
                /* inappropriate return value from
597
 
                buf_LRU_free_block() */
598
 
                ut_error;
599
546
        }
600
547
 
601
548
        return(FALSE);
626
573
             UNIV_LIKELY(bpage != NULL) && UNIV_LIKELY(distance > 0);
627
574
             bpage = UT_LIST_GET_PREV(LRU, bpage), distance--) {
628
575
 
629
 
                enum buf_lru_free_block_status  freed;
630
 
                unsigned                        accessed;
631
 
                mutex_t*                        block_mutex
632
 
                        = buf_page_get_mutex(bpage);
 
576
                ibool           freed;
 
577
                unsigned        accessed;
 
578
                mutex_t*        block_mutex = buf_page_get_mutex(bpage);
633
579
 
634
580
                ut_ad(buf_page_in_file(bpage));
635
581
                ut_ad(bpage->in_LRU_list);
636
582
 
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);
641
587
 
642
 
                switch (freed) {
643
 
                case BUF_LRU_FREED:
 
588
                if (freed) {
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 */
648
593
                                ++buf_pool->stat.n_ra_pages_evicted;
649
594
                        }
650
595
                        return(TRUE);
651
 
 
652
 
                case BUF_LRU_NOT_FREED:
653
 
                        /* The block was dirty, buffer-fixed, or I/O-fixed.
654
 
                        Keep looking. */
655
 
                        continue;
656
 
 
657
 
                case BUF_LRU_CANNOT_RELOCATE:
658
 
                        /* This should never occur, because we
659
 
                        want to discard the compressed page too. */
660
 
                        break;
661
596
                }
662
 
 
663
 
                /* inappropriate return value from
664
 
                buf_LRU_free_block() */
665
 
                ut_error;
666
597
        }
667
598
 
668
599
        return(FALSE);
798
729
@return the free control block, in state BUF_BLOCK_READY_FOR_USE */
799
730
UNIV_INTERN
800
731
buf_block_t*
801
 
buf_LRU_get_free_block(
802
 
/*===================*/
803
 
        ulint   zip_size)       /*!< in: compressed page size in bytes,
804
 
                                or 0 if uncompressed tablespace */
 
732
buf_LRU_get_free_block(void)
 
733
/*========================*/
805
734
{
806
735
        buf_block_t*    block           = NULL;
807
736
        ibool           freed;
877
806
 
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();
 
810
 
880
811
        if (block) {
881
 
 
882
 
#ifdef UNIV_DEBUG
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;
888
 
 
889
 
                if (UNIV_UNLIKELY(zip_size)) {
890
 
                        ibool   lru;
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);
894
 
                } else {
895
 
                        page_zip_set_size(&block->page.zip, 0);
896
 
                        block->page.zip.data = NULL;
897
 
                }
898
 
 
899
 
                buf_pool_mutex_exit();
 
812
                memset(&block->page.zip, 0, sizeof block->page.zip);
900
813
 
901
814
                if (started_monitor) {
902
815
                        srv_print_innodb_monitor = mon_value_was;
908
821
        /* If no block was in the free list, search from the end of the LRU
909
822
        list and try to free a block there */
910
823
 
911
 
        buf_pool_mutex_exit();
912
 
 
913
824
        freed = buf_LRU_search_and_free_block(n_iterations);
914
825
 
915
826
        if (freed > 0) {
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.
1366
1277
 
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.
1370
1281
 
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. */
1376
1286
UNIV_INTERN
1377
 
enum buf_lru_free_block_status
 
1287
ibool
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 */
1387
1293
{
1388
1294
        buf_page_t*     b = NULL;
1389
1295
        mutex_t*        block_mutex = buf_page_get_mutex(bpage);
1403
1309
        if (!buf_page_can_relocate(bpage)) {
1404
1310
 
1405
1311
                /* Do not free buffer-fixed or I/O-fixed blocks. */
1406
 
                return(BUF_LRU_NOT_FREED);
 
1312
                return(FALSE);
1407
1313
        }
1408
1314
 
1409
1315
#ifdef UNIV_IBUF_COUNT_DEBUG
1415
1321
                /* Do not completely free dirty blocks. */
1416
1322
 
1417
1323
                if (bpage->oldest_modification) {
1418
 
                        return(BUF_LRU_NOT_FREED);
 
1324
                        return(FALSE);
1419
1325
                }
1420
1326
        } else if (bpage->oldest_modification) {
1421
1327
                /* Do not completely free dirty blocks. */
1423
1329
                if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
1424
1330
                        ut_ad(buf_page_get_state(bpage)
1425
1331
                              == BUF_BLOCK_ZIP_DIRTY);
1426
 
                        return(BUF_LRU_NOT_FREED);
 
1332
                        return(FALSE);
1427
1333
                }
1428
1334
 
1429
1335
                goto alloc;
1432
1338
                If it cannot be allocated (without freeing a block
1433
1339
                from the LRU list), refuse to free bpage. */
1434
1340
alloc:
1435
 
                buf_pool_mutex_exit_forbid();
1436
 
                b = buf_buddy_alloc(sizeof *b, NULL);
1437
 
                buf_pool_mutex_exit_allow();
1438
 
 
1439
 
                if (UNIV_UNLIKELY(!b)) {
1440
 
                        return(BUF_LRU_CANNOT_RELOCATE);
1441
 
                }
1442
 
 
 
1341
                b = buf_page_alloc_descriptor();
 
1342
                ut_a(b);
1443
1343
                memcpy(b, bpage, sizeof *b);
1444
1344
        }
1445
1345
 
1538
1438
                        }
1539
1439
 
1540
1440
                        if (b->state == BUF_BLOCK_ZIP_PAGE) {
 
1441
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
1541
1442
                                buf_LRU_insert_zip_clean(b);
 
1443
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
1542
1444
                        } else {
1543
1445
                                /* Relocate on buf_pool->flush_list. */
1544
1446
                                buf_flush_relocate_on_flush_list(bpage, b);
1554
1456
                        b->io_fix = BUF_IO_READ;
1555
1457
                }
1556
1458
 
1557
 
                if (buf_pool_mutex_released) {
1558
 
                        *buf_pool_mutex_released = TRUE;
1559
 
                }
1560
 
 
1561
1459
                buf_pool_mutex_exit();
1562
1460
                mutex_exit(block_mutex);
1563
1461
 
1609
1507
                mutex_enter(block_mutex);
1610
1508
        }
1611
1509
 
1612
 
        return(BUF_LRU_FREED);
 
1510
        return(TRUE);
1613
1511
}
1614
1512
 
1615
1513
/******************************************************************//**
1821
1719
                ut_a(bpage->zip.data);
1822
1720
                ut_a(buf_page_get_zip_size(bpage));
1823
1721
 
 
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 */
1825
1725
 
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);
1834
1733
 
1835
1734
        case BUF_BLOCK_FILE_PAGE:
1942
1841
/*=====================*/
1943
1842
{
1944
1843
        buf_LRU_stat_t* item;
 
1844
        buf_LRU_stat_t  cur_stat;
1945
1845
 
1946
1846
        /* If we haven't started eviction yet then don't update stats. */
1947
1847
        if (buf_pool->freed_page_clock == 0) {
1955
1855
        buf_LRU_stat_arr_ind++;
1956
1856
        buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL;
1957
1857
 
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
 
1863
        and item */
 
1864
        cur_stat = buf_LRU_stat_cur;
 
1865
 
 
1866
        buf_LRU_stat_sum.io += cur_stat.io - item->io;
 
1867
        buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip;
1961
1868
 
1962
1869
        /* Put current entry in the array. */
1963
 
        memcpy(item, &buf_LRU_stat_cur, sizeof *item);
 
1870
        memcpy(item, &cur_stat, sizeof *item);
1964
1871
 
1965
1872
        buf_pool_mutex_exit();
1966
1873