函数buf_page_init_for_read
/********************************************************************//**
Function which inits a page for read to the buffer buf_pool. If the page is
(1) already in buf_pool, or
(2) if we specify to read only ibuf pages and the page is not an ibuf page, or
(3) if the space is deleted or being deleted,
then this function does nothing.
Sets the io_fix flag to BUF_IO_READ and sets a non-recursive exclusive lock
on the buffer frame. The io-handler must take care that the flag is cleared
and the lock released later.
@return pointer to the block or NULL */
UNIV_INTERN
buf_page_t*
buf_page_init_for_read(
/*===================*/
ulint* err, /*!< out: DB_SUCCESS or DB_TABLESPACE_DELETED */
ulint mode, /*!< in: BUF_READ_IBUF_PAGES_ONLY, ... */
ulint space, /*!< in: space id */
ulint zip_size,/*!< in: compressed page size, or 0 */
ibool unzip, /*!< in: TRUE=request uncompressed page */
ib_int64_t tablespace_version,
/*!< in: prevents reading from a wrong
version of the tablespace in case we have done
DISCARD + IMPORT */
ulint offset) /*!< in: page number */
{
buf_block_t* block;
buf_page_t* bpage = NULL;
buf_page_t* watch_page;
mtr_t mtr;
ulint fold;
ibool lru = FALSE;
void* data;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
ut_ad(buf_pool);
*err = DB_SUCCESS;
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
/* It is a read-ahead within an ibuf routine */
ut_ad(!ibuf_bitmap_page(zip_size, offset));
ibuf_mtr_start(&mtr);
if (!recv_no_ibuf_operations
&& !ibuf_page(space, zip_size, offset, &mtr)) {
ibuf_mtr_commit(&mtr);
return(NULL);
}
} else {
ut_ad(mode == BUF_READ_ANY_PAGE);
}
if (zip_size && UNIV_LIKELY(!unzip)
&& UNIV_LIKELY(!recv_recovery_is_on())) {
block = NULL;
} else { /** *按理说 会走到这里 zip_size 为0 ,非压缩页 * * */
block = buf_LRU_get_free_block(buf_pool); //获得一块余闲的block free_list->uzip_lru->common_lru顺序 详见
ut_ad(block);
ut_ad(buf_pool_from_block(block) == buf_pool);
}
fold = buf_page_address_fold(space, offset);
buf_pool_mutex_enter(buf_pool);
watch_page = buf_page_hash_get_low(buf_pool, space, offset, fold);
if (watch_page && !buf_pool_watch_is_sentinel(buf_pool, watch_page)) {
/* The page is already in the buffer pool. */
watch_page = NULL;
err_exit:
if (block) {
mutex_enter(&block->mutex);
buf_LRU_block_free_non_file_page(block);
mutex_exit(&block->mutex);
}
bpage = NULL;
goto func_exit;
}
if (fil_tablespace_deleted_or_being_deleted_in_mem(
space, tablespace_version)) {
/* The page belongs to a space which has been
deleted or is being deleted. */
*err = DB_TABLESPACE_DELETED;
goto err_exit;
}
if (block) {
bpage = &block->page;
mutex_enter(&block->mutex);
ut_ad(buf_pool_from_bpage(bpage) == buf_pool);
buf_page_init(buf_pool, space, offset, fold, zip_size, block); //详见 /* The block must be put to the LRU list, to the old blocks */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
/* We set a pass-type x-lock on the frame because then
the same thread which called for the read operation
(and is running now at this point of code) can wait
for the read to complete by waiting for the x-lock on
the frame; if the x-lock were recursive, the same
thread would illegally get the x-lock before the page
read is completed. The x-lock is cleared by the
io-handler thread. */
rw_lock_x_lock_gen(&block->lock, BUF_IO_READ);
buf_page_set_io_fix(bpage, BUF_IO_READ);//设置bpage->io_fix为BUF_IO_READ,表示将从磁盘读取Page
if (UNIV_UNLIKELY(zip_size)) {
/* buf_pool->mutex may be released and
reacquired by buf_buddy_alloc(). Thus, we
must release block->mutex in order not to
break the latching order in the reacquisition
of buf_pool->mutex. We also must defer this
operation until after the block descriptor has
been added to buf_pool->LRU and
buf_pool->page_hash. */
mutex_exit(&block->mutex);
data = buf_buddy_alloc(buf_pool, zip_size, &lru);
mutex_enter(&block->mutex);
block->page.zip.data = data;
/* To maintain the invariant
block->in_unzip_LRU_list
== buf_page_belongs_to_unzip_LRU(&block->page)
we have to add this block to unzip_LRU
after block->page.zip.data is set. */
ut_ad(buf_page_belongs_to_unzip_LRU(&block->page));
buf_unzip_LRU_add_block(block, TRUE);
}
mutex_exit(&block->mutex);
} else {
/* The compressed page must be allocated before the
control block (bpage), in order to avoid the
invocation of buf_buddy_relocate_block() on
uninitialized data. */
data = buf_buddy_alloc(buf_pool, zip_size, &lru);
/* If buf_buddy_alloc() allocated storage from the LRU list,
it released and reacquired buf_pool->mutex. Thus, we must
check the page_hash again, as it may have been modified. */
if (UNIV_UNLIKELY(lru)) {
watch_page = buf_page_hash_get_low(
buf_pool, space, offset, fold);
if (watch_page
&& !buf_pool_watch_is_sentinel(buf_pool,
watch_page)) {
/* The block was added by some other thread. */
watch_page = NULL;
buf_buddy_free(buf_pool, data, zip_size);
bpage = NULL;
goto func_exit;
}
}
bpage = buf_page_alloc_descriptor();
/* Initialize the buf_pool pointer. */
bpage->buf_pool_index = buf_pool_index(buf_pool);
page_zip_des_init(&bpage->zip);
page_zip_set_size(&bpage->zip, zip_size);
bpage->zip.data = data;
mutex_enter(&buf_pool->zip_mutex);
UNIV_MEM_DESC(bpage->zip.data,
page_zip_get_size(&bpage->zip), bpage);
buf_page_init_low(bpage);
bpage->state = BUF_BLOCK_ZIP_PAGE;
bpage->space = space;
bpage->offset = offset;
#ifdef UNIV_DEBUG
bpage->in_page_hash = FALSE;
bpage->in_zip_hash = FALSE;
bpage->in_flush_list = FALSE;
bpage->in_free_list = FALSE;
bpage->in_LRU_list = FALSE;
#endif /* UNIV_DEBUG */
ut_d(bpage->in_page_hash = TRUE);
if (UNIV_LIKELY_NULL(watch_page)) {
/* Preserve the reference count. */
ulint buf_fix_count = watch_page->buf_fix_count;
ut_a(buf_fix_count > );
bpage->buf_fix_count += buf_fix_count;
ut_ad(buf_pool_watch_is_sentinel(buf_pool, watch_page));
buf_pool_watch_remove(buf_pool, fold, watch_page);
}
HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold,
bpage);
/* The block must be put to the LRU list, to the old blocks
The zip_size is already set into the page zip */
buf_LRU_add_block(bpage, TRUE/* to old blocks */);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
buf_LRU_insert_zip_clean(bpage);
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
buf_page_set_io_fix(bpage, BUF_IO_READ);
mutex_exit(&buf_pool->zip_mutex);
}
buf_pool->n_pend_reads++;
func_exit:
buf_pool_mutex_exit(buf_pool);
if (mode == BUF_READ_IBUF_PAGES_ONLY) {
ibuf_mtr_commit(&mtr);
}
ut_ad(!bpage || buf_page_in_file(bpage));
return(bpage);
}
函数buf_page_init_for_read的更多相关文章
- InnoDB源码分析--缓冲池(二)
转载请附原文链接:http://www.cnblogs.com/wingsless/p/5578727.html 上一篇中我简单的分析了一下InnoDB缓冲池LRU算法的相关源码,其实说不上是分析,应 ...
- 服务器IO瓶颈对MySQL性能的影响
[背景] 之前我们碰到一些MySQL的性能问题,比如服务器日志备份时可能会导致慢查询增多,一句简单的select或insert语句可能执行几秒,IO负载较高的服务器更容易出现并发线程数升高,CPU上升 ...
- Python 小而美的函数
python提供了一些有趣且实用的函数,如any all zip,这些函数能够大幅简化我们得代码,可以更优雅的处理可迭代的对象,同时使用的时候也得注意一些情况 any any(iterable) ...
- 探究javascript对象和数组的异同,及函数变量缓存技巧
javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...
- JavaScript权威指南 - 函数
函数本身就是一段JavaScript代码,定义一次但可能被调用任意次.如果函数挂载在一个对象上,作为对象的一个属性,通常这种函数被称作对象的方法.用于初始化一个新创建的对象的函数被称作构造函数. 相对 ...
- C++对C的函数拓展
一,内联函数 1.内联函数的概念 C++中的const常量可以用来代替宏常数的定义,例如:用const int a = 10来替换# define a 10.那么C++中是否有什么解决方案来替代宏代码 ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- javascript中的this与函数讲解
前言 javascript中没有块级作用域(es6以前),javascript中作用域分为函数作用域和全局作用域.并且,大家可以认为全局作用域其实就是Window函数的函数作用域,我们编写的js代码, ...
- 复杂的 Hash 函数组合有意义吗?
很久以前看到一篇文章,讲某个大网站储存用户口令时,会经过十分复杂的处理.怎么个复杂记不得了,大概就是先 Hash,结果加上一些特殊字符再 Hash,结果再加上些字符.再倒序.再怎么怎么的.再 Hash ...
随机推荐
- Java 8 VM GC Tuning Guide Charter3-4
第三章 Generations One strength of the Java SE platform is that it shields the developer from the compl ...
- Java工程转换为Maven工程-b
1. 前言 在开发中经常要建立一个Maven的子工程,对于没有模板的同学来说从Java工程来转换也是一个不错的选择.本文就如何从一个Java工程创建一个Maven工程做了一个介绍,相信对于将一个Jav ...
- app进入后台申请10分钟活跃时间-b
IOS允许长时间在后台运行的情况有7种: audio VoIP GPS 下载新闻 和其它附属硬件进行通讯时 使用蓝牙进行通讯时 使用蓝牙共享数据时 除以上情况,程序退出时可能设置短暂运行10分钟 让程 ...
- 2435: [Noi2011]道路修建 - BZOJ
Description 在 W 星球上有 n 个国家.为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通.但是每个国家的国王都很吝啬,他们只愿意修建恰好 n – 1条双向道路. ...
- 【HDOJ】【3037】Saving Beans
排列组合 啊……这题是要求c(n-1,0)+c(n,1)+c(n+1,2)+......+c(n+m-1,m) 这个玩意……其实就等于c(n+m,m) 好吧然后就是模P……Lucas大法好= = 我S ...
- 剑指offer--面试题16
#include<stack> //思路:遍历链表过程中,将各个指针入栈,再出栈进行反转 ListNode* ReverseList(ListNode* pHead) { if(pHead ...
- [转载]C++ CString与int 互转
1.CString 转 int CString strtemp = "100"; int intResult; intResult= atoi(strtem ...
- grub,mbr的那些事
今天遇到一个问题是:双系统为win10和Ubuntu.启动模式为mbr,当前可以启动win10,但不能启动Ubuntu.先利用easybcd重新添加了一个,想着依旧用win10的启动项,(此处可以参考 ...
- UVA 11424 GCD - Extreme (I) (欧拉函数+筛法)
题目:给出n,求gcd(1,2)+gcd(1,3)+gcd(2,3)+gcd(1,4)+gcd(2,4)+gcd(3,4)+...+gcd(1,n)+gcd(2,n)+...+gcd(n-1,n) 此 ...
- POJ 1060 Modular multiplication of polynomials(多项式的加减乘除,除法转化成减法来求)
题意:给出f(x),g(x),h(x)的 (最高次幂+1)的值,以及它们的各项系数,求f(x)*g(x)/h(x)的余数. 这里多项式的系数只有1或0,因为题目要求:这里多项式的加减法是将系数相加/减 ...