/******************************************************************//**
Try to free a block.  If bpage is a descriptor of a compressed-only
page, the descriptor object will be freed as well.

NOTE: If this function returns TRUE, it will temporarily
release buf_pool->mutex.  Furthermore, the page frame will no longer be
accessible via bpage.

The caller must hold buf_pool->mutex and buf_page_get_mutex(bpage) and
release these two mutexes after the call.  No other
buf_page_get_mutex() may be held when calling this function.
@return TRUE if freed, FALSE otherwise. */
UNIV_INTERN
ibool
buf_LRU_free_block(
/*===============*/
    buf_page_t*    bpage,    /*!< in: block to be freed */
    ibool        zip)    /*!< in: TRUE if should remove also the
                compressed page of an uncompressed page */
{
    buf_page_t*    b = NULL;
    buf_pool_t*    buf_pool = buf_pool_from_bpage(bpage);
    mutex_t*    block_mutex = buf_page_get_mutex(bpage);

    ut_ad(buf_pool_mutex_own(buf_pool));
    ut_ad(mutex_own(block_mutex));
    ut_ad(buf_page_in_file(bpage));
    ut_ad(bpage->in_LRU_list);
    ut_ad(!bpage->in_flush_list == !bpage->oldest_modification);
#if UNIV_WORD_SIZE == 4
    /* On 32-bit systems, there is no padding in buf_page_t.  On
    other systems, Valgrind could complain about uninitialized pad
    bytes. */
    UNIV_MEM_ASSERT_RW(bpage, sizeof *bpage);
#endif

    if (!buf_page_can_relocate(bpage)) {

        /* Do not free buffer-fixed or I/O-fixed blocks. */
        return(FALSE);
    }

#ifdef UNIV_IBUF_COUNT_DEBUG
    ut_a(ibuf_count_get(bpage->space, bpage->offset) == );
#endif /* UNIV_IBUF_COUNT_DEBUG */

    if (zip || !bpage->zip.data) {
        /* This would completely free the block. */
        /* Do not completely free dirty blocks. */

        if (bpage->oldest_modification) {
            return(FALSE);
        }
    } else if (bpage->oldest_modification) {
        /* Do not completely free dirty blocks. */

        if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
            ut_ad(buf_page_get_state(bpage)
                  == BUF_BLOCK_ZIP_DIRTY);
            return(FALSE);
        }

        goto alloc;
    } else if (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE) {
        /* Allocate the control block for the compressed page.
        If it cannot be allocated (without freeing a block
        from the LRU list), refuse to free bpage. */
alloc:
        b = buf_page_alloc_descriptor();
        ut_a(b);
        memcpy(b, bpage, sizeof *b);
    }

#ifdef UNIV_DEBUG
    if (buf_debug_prints) {
        fprintf(stderr, "Putting space %lu page %lu to free list\n",
            (ulong) buf_page_get_space(bpage),
            (ulong) buf_page_get_page_no(bpage));
    }
#endif /* UNIV_DEBUG */

    if (buf_LRU_block_remove_hashed_page(bpage, zip)!= BUF_BLOCK_ZIP_FREE) {  //这里
        ut_a(bpage->buf_fix_count == );

        if (b) {
            buf_page_t*    hash_b;
            buf_page_t*    prev_b    = UT_LIST_GET_PREV(LRU, b);

            const ulint    fold = buf_page_address_fold(
                bpage->space, bpage->offset);

            hash_b    = buf_page_hash_get_low(
                buf_pool, bpage->space, bpage->offset, fold);

            ut_a(!hash_b);

            b->state = b->oldest_modification
                ? BUF_BLOCK_ZIP_DIRTY
                : BUF_BLOCK_ZIP_PAGE;
            UNIV_MEM_DESC(b->zip.data,
                      page_zip_get_size(&b->zip), b);

            /* The fields in_page_hash and in_LRU_list of
            the to-be-freed block descriptor should have
            been cleared in
            buf_LRU_block_remove_hashed_page(), which
            invokes buf_LRU_remove_block(). */
            ut_ad(!bpage->in_page_hash);
            ut_ad(!bpage->in_LRU_list);
            /* bpage->state was BUF_BLOCK_FILE_PAGE because
            b != NULL. The type cast below is thus valid. */
            ut_ad(!((buf_block_t*) bpage)->in_unzip_LRU_list);

            /* The fields of bpage were copied to b before
            buf_LRU_block_remove_hashed_page() was invoked. */
            ut_ad(!b->in_zip_hash);
            ut_ad(b->in_page_hash);
            ut_ad(b->in_LRU_list);

            HASH_INSERT(buf_page_t, hash,
                    buf_pool->page_hash, fold, b);

            /* Insert b where bpage was in the LRU list. */
            if (UNIV_LIKELY(prev_b != NULL)) {
                ulint    lru_len;

                ut_ad(prev_b->in_LRU_list);
                ut_ad(buf_page_in_file(prev_b));
#if UNIV_WORD_SIZE == 4
                /* On 32-bit systems, there is no
                padding in buf_page_t.  On other
                systems, Valgrind could complain about
                uninitialized pad bytes. */
                UNIV_MEM_ASSERT_RW(prev_b, sizeof *prev_b);
#endif
                UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU,
                             prev_b, b);

                incr_LRU_size_in_bytes(b, buf_pool);

                if (buf_page_is_old(b)) {
                    buf_pool->LRU_old_len++;
                    if (UNIV_UNLIKELY
                        (buf_pool->LRU_old
                         == UT_LIST_GET_NEXT(LRU, b))) {

                        buf_pool->LRU_old = b;
                    }
                }

                lru_len = UT_LIST_GET_LEN(buf_pool->LRU);

                if (lru_len > BUF_LRU_OLD_MIN_LEN) {
                    ut_ad(buf_pool->LRU_old);
                    /* Adjust the length of the
                    old block list if necessary */
                    buf_LRU_old_adjust_len(buf_pool);
                } else if (lru_len == BUF_LRU_OLD_MIN_LEN) {
                    /* The LRU list is now long
                    enough for LRU_old to become
                    defined: init it */
                    buf_LRU_old_init(buf_pool);
                }
#ifdef UNIV_LRU_DEBUG
                /* Check that the "old" flag is consistent
                in the block and its neighbours. */
                buf_page_set_old(b, buf_page_is_old(b));
#endif /* UNIV_LRU_DEBUG */
            } else {
                ut_d(b->in_LRU_list = FALSE);
                buf_LRU_add_block_low(b, buf_page_is_old(b));
            }

            if (b->state == BUF_BLOCK_ZIP_PAGE) {
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
                buf_LRU_insert_zip_clean(b);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
            } else {
                /* Relocate on buf_pool->flush_list. */
                buf_flush_relocate_on_flush_list(bpage, b);
            }

            bpage->zip.data = NULL;
            page_zip_set_size(&bpage->zip, );

            /* Prevent buf_page_get_gen() from
            decompressing the block while we release
            buf_pool->mutex and block_mutex. */
            mutex_enter(&buf_pool->zip_mutex);
            buf_page_set_sticky(b);
            mutex_exit(&buf_pool->zip_mutex);
        }

        buf_pool_mutex_exit(buf_pool);
        mutex_exit(block_mutex);

        /* Remove possible adaptive hash index on the page.
        The page was declared uninitialized by
        buf_LRU_block_remove_hashed_page().  We need to flag
        the contents of the page valid (which it still is) in
        order to avoid bogus Valgrind warnings.*/

        UNIV_MEM_VALID(((buf_block_t*) bpage)->frame,
                   UNIV_PAGE_SIZE);
        btr_search_drop_page_hash_index((buf_block_t*) bpage);
        UNIV_MEM_INVALID(((buf_block_t*) bpage)->frame,
                 UNIV_PAGE_SIZE);

        if (b) {
            /* Compute and stamp the compressed page
            checksum while not holding any mutex.  The
            block is already half-freed
            (BUF_BLOCK_REMOVE_HASH) and removed from
            buf_pool->page_hash, thus inaccessible by any
            other thread. */

            mach_write_to_4(
                b->zip.data + FIL_PAGE_SPACE_OR_CHKSUM,
                UNIV_LIKELY(srv_use_checksums)
                ? page_zip_calc_checksum(
                    b->zip.data,
                    page_zip_get_size(&b->zip))
                : BUF_NO_CHECKSUM_MAGIC);
        }

        buf_pool_mutex_enter(buf_pool);
        mutex_enter(block_mutex);

        if (b) {
            mutex_enter(&buf_pool->zip_mutex);
            buf_page_unset_sticky(b);
            mutex_exit(&buf_pool->zip_mutex);
        }

        buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
    } else {
        /* The block_mutex should have been released by
        buf_LRU_block_remove_hashed_page() when it returns
        BUF_BLOCK_ZIP_FREE. */
        ut_ad(block_mutex == &buf_pool->zip_mutex);
        mutex_enter(block_mutex);
    }

    return(TRUE);
}

函数buf_LRU_free_block的更多相关文章

  1. innoDB源码分析--缓冲池

    最开始学Oracle的时候,有个概念叫SGA和PGA,是非常重要的概念,其实就是内存中的缓冲池.InnoDB的设计类似于Oracle,也会在内存中开辟一片缓冲池.众所周知,CPU的速度和磁盘的IO速度 ...

  2. Python 小而美的函数

    python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况   any any(iterable) ...

  3. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  4. JavaScript权威指南 - 函数

    函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...

  5. C++对C的函数拓展

    一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...

  6. 菜鸟Python学习笔记第一天:关于一些函数库的使用

    2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...

  7. javascript中的this与函数讲解

    前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...

  8. 复杂的 Hash 函数组合有意义吗?

    很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...

  9. JS核心系列:浅谈函数的作用域

    一.作用域(scope) 所谓作用域就是:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的. function scope(){ var foo = "global&quo ...

随机推荐

  1. SQL Server 2008 安装或卸载时提示“重启计算机失败"的解决办法(转)

    安装或卸载SQL Server 遇到错误提示:以前的某个程序安装已在安装计算机上创建挂起的文件操作.运行安装程序之前必须重新启动计算机.如下图: 解决办法: 1.在开始->运行中输入regedi ...

  2. MySQL基础学习之函数

    数学函数 绝对值      abs() 圆周率      PI() 平方根 sqrt() 模除取余   mod(被除数,除数) 随机数      rand() 四舍五入    round(数字) 次方 ...

  3. VB.Net 文件处理类

    1.编写日志 2.本地文件的读取和写入 3.Base64与图片的互相转换 Imports System.IO Imports System.Text Public Class Cls_File #Re ...

  4. Head of a Gang (map+邻接表+DFS)

    One way that the police finds the head of a gang is to check people's phone calls. If there is a pho ...

  5. 九、mysql触发器的概念

    .所谓触发器,就是指设置好某个表的某个操作(insert ,update ,delete)时候,同时触发的一个操作: 一般用来,比如说删除文章主栏目,那么可以利用触发器删除这个文章栏目下的所有文章 . ...

  6. gridview 一个列勾选框选中,同时选中同一行的另一列勾选框

    <asp:TemplateColumn > <HeaderTemplate> 是否显示 <asp:CheckBox ID="chk_Show" sty ...

  7. 因程序问题引起的服务器CPU负荷一直保持在90%以上

    昨天早上刚到办公室,就接到客户的电话说其某台小型机的CPU负荷一直保持在90以上,告警短信发个不停,一直没有间断过.该服务器是一台IBM的小型机,性能应该还是不错的,出现这样的情况确实不太正常.登陆上 ...

  8. You have new mail in /var/spool/mail/root 烦不烦你?

    http://blog.csdn.net/yx_l128125/article/details/7425182

  9. 我的PHP之旅--XML初步

    什么是XML? XML是可拓展标记语言,它和XHTML很像.但它和XHTML的目的性不一样,XHTML负责展示数据,而XML负责保存或交换传输数据. 而且XML可拓展,它没有固定的标签.它的标签可以自 ...

  10. DataGrid表格控件

    代码Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--& ...