1. /********************************************************************//**
  2. This is the general function used to get access to a database page.
  3. @return pointer to the block or NULL */
  4. UNIV_INTERN
  5. buf_block_t*
  6. buf_page_get_gen(
  7. /*=============*/
  8. ulint space, /*!< in: space id */
  9. ulint zip_size,/*!< in: compressed page size in bytes
  10. or 0 for uncompressed pages */
  11. ulint offset, /*!< in: page number */
  12. ulint rw_latch,/*!< in: RW_S_LATCH, RW_X_LATCH, RW_NO_LATCH */
  13. buf_block_t* guess, /*!< in: guessed block or NULL */
  14. ulint mode, /*!< in: BUF_GET, BUF_GET_IF_IN_POOL,
  15. BUF_PEEK_IF_IN_POOL, BUF_GET_NO_LATCH, or
  16. BUF_GET_IF_IN_POOL_OR_WATCH */
  17. const char* file, /*!< in: file name */
  18. ulint line, /*!< in: line where called */
  19. mtr_t* mtr) /*!< in: mini-transaction */
  20. {
  21. buf_block_t* block;
  22. ulint fold;
  23. unsigned access_time;
  24. ulint fix_type;
  25. ibool must_read;
  26. ulint retries = ;
  27. buf_pool_t* buf_pool = buf_pool_get(space, offset);
  28.  
  29. ut_ad(mtr);
  30. ut_ad(mtr->state == MTR_ACTIVE);
  31. ut_ad((rw_latch == RW_S_LATCH)
  32. || (rw_latch == RW_X_LATCH)
  33. || (rw_latch == RW_NO_LATCH));
  34.  
  35. ut_ad(zip_size == fil_space_get_zip_size(space));
  36. ut_ad(ut_is_2pow(zip_size));
  37.  
  38. buf_pool->stat.n_page_gets++;
  39. fold = buf_page_address_fold(space, offset);
  40. loop:
  41. block = guess; //guess 为 NULL
  42. buf_pool_mutex_enter(buf_pool);
  43.  
  44. if (block) { //这里不进来,因为block为空
  45. /* If the guess is a compressed page descriptor that
  46. has been allocated by buf_page_alloc_descriptor(),
  47. it may have been freed by buf_relocate(). */
  48.  
  49. if (!buf_block_is_uncompressed(buf_pool, block)
  50. || offset != block->page.offset
  51. || space != block->page.space
  52. || buf_block_get_state(block) != BUF_BLOCK_FILE_PAGE) {
  53.  
  54. block = guess = NULL;
  55. } else {
  56. ut_ad(!block->page.in_zip_hash);
  57. ut_ad(block->page.in_page_hash);
  58. }
  59. }
  60.  
  61. if (block == NULL) { /** *详见 *从buf_pool->page_hash中找到相应page *当找到的page->offset == offset时,返回page * */
  62. block = (buf_block_t*) buf_page_hash_get_low(buf_pool, space, offset, fold);
  63. }
  64.  
  65. if (block && buf_pool_watch_is_sentinel(buf_pool, &block->page)) {
  66. block = NULL;
  67. }
  68.  
  69. if (block == NULL) {
  70. /* Page not in buf_pool: needs to be read from file */
  71. //如果hash表中没有找到block,就读取硬盘文件
  72. if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
  73. block = (buf_block_t*) buf_pool_watch_set(space, offset, fold);
  74.  
  75. if (UNIV_LIKELY_NULL(block)) {
  76.  
  77. goto got_block;
  78. }
  79. }
  80.  
  81. buf_pool_mutex_exit(buf_pool);
  82.  
  83. if (mode == BUF_GET_IF_IN_POOL
  84. || mode == BUF_PEEK_IF_IN_POOL
  85. || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
  86.  
  87. return(NULL);
  88. }
  89.  
  90. if (buf_read_page(space, zip_size, offset)) {//从硬盘中读取数据,并开始预读,详见
  91. buf_read_ahead_random(space, zip_size, offset,ibuf_inside(mtr));
  92.  
  93. retries = ;
  94. } else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
  95. ++retries;
  96. DBUG_EXECUTE_IF(
  97. "innodb_page_corruption_retries",
  98. retries = BUF_PAGE_READ_MAX_RETRIES;
  99. );
  100. } else {
  101. fprintf(stderr, "InnoDB: Error: Unable"
  102. " to read tablespace %lu page no"
  103. " %lu into the buffer pool after"
  104. " %lu attempts\n"
  105. "InnoDB: The most probable cause"
  106. " of this error may be that the"
  107. " table has been corrupted.\n"
  108. "InnoDB: You can try to fix this"
  109. " problem by using"
  110. " innodb_force_recovery.\n"
  111. "InnoDB: Please see reference manual"
  112. " for more details.\n"
  113. "InnoDB: Aborting...\n",
  114. space, offset,
  115. BUF_PAGE_READ_MAX_RETRIES);
  116.  
  117. ut_error;
  118. }
  119.  
  120. #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
  121. ut_a(++buf_dbg_counter % || buf_validate());
  122. #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
  123. goto loop;
  124. }
  125.  
  126. got_block:
  127. ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
  128.  
  129. must_read = buf_block_get_io_fix(block) == BUF_IO_READ;
  130.  
  131. if (must_read && (mode == BUF_GET_IF_IN_POOL
  132. || mode == BUF_PEEK_IF_IN_POOL)) {
  133.  
  134. /* The page is being read to buffer pool,
  135. but we cannot wait around for the read to
  136. complete. */
  137. null_exit:
  138. buf_pool_mutex_exit(buf_pool);
  139.  
  140. return(NULL);
  141. }
  142.  
  143. switch (buf_block_get_state(block)) {
  144. buf_page_t* bpage;
  145. ibool success;
  146.  
  147. case BUF_BLOCK_FILE_PAGE:
  148. break;
  149.  
  150. case BUF_BLOCK_ZIP_PAGE:
  151. case BUF_BLOCK_ZIP_DIRTY:
  152. if (mode == BUF_PEEK_IF_IN_POOL) {
  153. /* This mode is only used for dropping an
  154. adaptive hash index. There cannot be an
  155. adaptive hash index for a compressed-only
  156. page, so do not bother decompressing the page. */
  157. goto null_exit;
  158. }
  159.  
  160. bpage = &block->page;
  161. /* Protect bpage->buf_fix_count. */
  162. mutex_enter(&buf_pool->zip_mutex);
  163.  
  164. if (bpage->buf_fix_count
  165. || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
  166. /* This condition often occurs when the buffer
  167. is not buffer-fixed, but I/O-fixed by
  168. buf_page_init_for_read(). */
  169. mutex_exit(&buf_pool->zip_mutex);
  170. wait_until_unfixed:
  171. /* The block is buffer-fixed or I/O-fixed.
  172. Try again later. */
  173. buf_pool_mutex_exit(buf_pool);
  174. os_thread_sleep(WAIT_FOR_READ);
  175.  
  176. goto loop;
  177. }
  178.  
  179. /* Buffer-fix the block so that it cannot be evicted
  180. or relocated while we are attempting to allocate an
  181. uncompressed page. */
  182. bpage->buf_fix_count++;
  183.  
  184. /* Allocate an uncompressed page. */
  185. buf_pool_mutex_exit(buf_pool);
  186. mutex_exit(&buf_pool->zip_mutex);
  187.  
  188. block = buf_LRU_get_free_block(buf_pool);
  189. ut_a(block);
  190.  
  191. buf_pool_mutex_enter(buf_pool);
  192. mutex_enter(&block->mutex);
  193. mutex_enter(&buf_pool->zip_mutex);
  194. /* Buffer-fixing prevents the page_hash from changing. */
  195. ut_ad(bpage == buf_page_hash_get_low(buf_pool,
  196. space, offset, fold));
  197.  
  198. if (--bpage->buf_fix_count
  199. || buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
  200.  
  201. mutex_exit(&buf_pool->zip_mutex);
  202. /* The block was buffer-fixed or I/O-fixed while
  203. buf_pool->mutex was not held by this thread.
  204. Free the block that was allocated and retry.
  205. This should be extremely unlikely, for example,
  206. if buf_page_get_zip() was invoked. */
  207.  
  208. buf_LRU_block_free_non_file_page(block);
  209. mutex_exit(&block->mutex);
  210.  
  211. goto wait_until_unfixed;
  212. }
  213.  
  214. /* Move the compressed page from bpage to block,
  215. and uncompress it. */
  216.  
  217. buf_relocate(bpage, &block->page);
  218. buf_block_init_low(block);
  219. block->lock_hash_val = lock_rec_hash(space, offset);
  220.  
  221. UNIV_MEM_DESC(&block->page.zip.data,
  222. page_zip_get_size(&block->page.zip), block);
  223.  
  224. if (buf_page_get_state(&block->page)
  225. == BUF_BLOCK_ZIP_PAGE) {
  226. #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
  227. UT_LIST_REMOVE(list, buf_pool->zip_clean,
  228. &block->page);
  229. #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
  230. ut_ad(!block->page.in_flush_list);
  231. } else {
  232. /* Relocate buf_pool->flush_list. */
  233. buf_flush_relocate_on_flush_list(bpage,
  234. &block->page);
  235. }
  236.  
  237. /* Buffer-fix, I/O-fix, and X-latch the block
  238. for the duration of the decompression.
  239. Also add the block to the unzip_LRU list. */
  240. block->page.state = BUF_BLOCK_FILE_PAGE;
  241.  
  242. /* Insert at the front of unzip_LRU list */
  243. buf_unzip_LRU_add_block(block, FALSE);
  244.  
  245. block->page.buf_fix_count = ;
  246. buf_block_set_io_fix(block, BUF_IO_READ);
  247. rw_lock_x_lock_inline(&block->, file, line);
  248.  
  249. UNIV_MEM_INVALID(bpage, sizeof *bpage);
  250.  
  251. buf_pool->n_pend_unzip++;
  252. mutex_exit(&buf_pool->zip_mutex);
  253. buf_pool_mutex_exit(buf_pool);
  254.  
  255. access_time = buf_page_is_accessed(&block->page);
  256. mutex_exit(&block->mutex);
  257.  
  258. buf_page_free_descriptor(bpage);
  259.  
  260. /* Decompress the page while not holding
  261. buf_pool->mutex or block->mutex. */
  262. success = buf_zip_decompress(block, srv_use_checksums);
  263. ut_a(success);
  264.  
  265. if (UNIV_LIKELY(!recv_no_ibuf_operations)) {
  266. if (access_time) {
  267. #ifdef UNIV_IBUF_COUNT_DEBUG
  268. ut_a(ibuf_count_get(space, offset) == );
  269. #endif /* UNIV_IBUF_COUNT_DEBUG */
  270. } else {
  271. ibuf_merge_or_delete_for_page(
  272. block, space, offset, zip_size, TRUE);
  273. }
  274. }
  275.  
  276. /* Unfix and unlatch the block. */
  277. buf_pool_mutex_enter(buf_pool);
  278. mutex_enter(&block->mutex);
  279. block->page.buf_fix_count--;
  280. buf_block_set_io_fix(block, BUF_IO_NONE);
  281. mutex_exit(&block->mutex);
  282. buf_pool->n_pend_unzip--;
  283. rw_lock_x_unlock(&block->lock);
  284.  
  285. break;
  286.  
  287. case BUF_BLOCK_ZIP_FREE:
  288. case BUF_BLOCK_NOT_USED:
  289. case BUF_BLOCK_READY_FOR_USE:
  290. case BUF_BLOCK_MEMORY:
  291. case BUF_BLOCK_REMOVE_HASH:
  292. ut_error;
  293. break;
  294. }
  295.  
  296. ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
  297.  
  298. mutex_enter(&block->mutex);
  299. #if UNIV_WORD_SIZE == 4
  300. /* On 32-bit systems, there is no padding in buf_page_t. On
  301. other systems, Valgrind could complain about uninitialized pad
  302. bytes. */
  303. UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
  304. #endif
  305. #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
  306. if ((mode == BUF_GET_IF_IN_POOL || mode == BUF_GET_IF_IN_POOL_OR_WATCH)
  307. && ibuf_debug) {
  308. /* Try to evict the block from the buffer pool, to use the
  309. insert buffer (change buffer) as much as possible. */
  310.  
  311. if (buf_LRU_free_block(&block->page, TRUE)) {
  312. mutex_exit(&block->mutex);
  313. if (mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
  314. /* Set the watch, as it would have
  315. been set if the page were not in the
  316. buffer pool in the first place. */
  317. block = (buf_block_t*) buf_pool_watch_set(
  318. space, offset, fold);
  319.  
  320. if (UNIV_LIKELY_NULL(block)) {
  321.  
  322. /* The page entered the buffer
  323. pool for some reason. Try to
  324. evict it again. */
  325. goto got_block;
  326. }
  327. }
  328. buf_pool_mutex_exit(buf_pool);
  329. fprintf(stderr,
  330. "innodb_change_buffering_debug evict %u %u\n",
  331. (unsigned) space, (unsigned) offset);
  332. return(NULL);
  333. } else if (buf_flush_page_try(buf_pool, block)) {
  334. fprintf(stderr,
  335. "innodb_change_buffering_debug flush %u %u\n",
  336. (unsigned) space, (unsigned) offset);
  337. guess = block;
  338. goto loop;
  339. }
  340.  
  341. /* Failed to evict the page; change it directly */
  342. }
  343. #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
  344.  
  345. buf_block_buf_fix_inc(block, file, line);
  346. #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
  347. ut_a(mode == BUF_GET_POSSIBLY_FREED
  348. || !block->page.file_page_was_freed);
  349. #endif
  350. buf_pool_mutex_exit(buf_pool);
  351.  
  352. /* Check if this is the first access to the page */
  353. access_time = buf_page_is_accessed(&block->page);
  354.  
  355. buf_page_set_accessed(&block->page);
  356.  
  357. mutex_exit(&block->mutex);
  358.  
  359. if (mode != BUF_PEEK_IF_IN_POOL) {
  360. buf_page_make_young_if_needed(&block->page);
  361. }
  362.  
  363. #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
  364. ut_a(++buf_dbg_counter % || buf_validate());
  365. ut_a(block->page.buf_fix_count > );
  366. ut_a(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
  367. #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
  368.  
  369. switch (rw_latch) {
  370. case RW_NO_LATCH:
  371. if (must_read) {
  372. /* Let us wait until the read operation
  373. completes */
  374.  
  375. for (;;) {
  376. enum buf_io_fix io_fix;
  377.  
  378. mutex_enter(&block->mutex);
  379. io_fix = buf_block_get_io_fix(block);
  380. mutex_exit(&block->mutex);
  381.  
  382. if (io_fix == BUF_IO_READ) {
  383. /* wait by temporaly s-latch */
  384. rw_lock_s_lock(&(block->lock));
  385. rw_lock_s_unlock(&(block->lock));
  386. } else {
  387. break;
  388. }
  389. }
  390. }
  391.  
  392. fix_type = MTR_MEMO_BUF_FIX;
  393. break;
  394.  
  395. case RW_S_LATCH:
  396. rw_lock_s_lock_inline(&(block->, file, line);
  397.  
  398. fix_type = MTR_MEMO_PAGE_S_FIX;
  399. break;
  400.  
  401. default:
  402. ut_ad(rw_latch == RW_X_LATCH);
  403. rw_lock_x_lock_inline(&(block->, file, line);
  404.  
  405. fix_type = MTR_MEMO_PAGE_X_FIX;
  406. break;
  407. }
  408.  
  409. mtr_memo_push(mtr, block, fix_type);
  410.  
  411. if (mode != BUF_PEEK_IF_IN_POOL && !access_time) {
  412. /* In the case of a first access, try to apply linear
  413. read-ahead */
  414.  
  415. buf_read_ahead_linear(space, zip_size, offset,
  416. ibuf_inside(mtr));
  417. }
  418.  
  419. #ifdef UNIV_IBUF_COUNT_DEBUG
  420. ut_a(ibuf_count_get(buf_block_get_space(block),
  421. buf_block_get_page_no(block)) == );
  422. #endif
  423. return(block);
  424. }

函数buf_page_get_gen的更多相关文章

  1. Python 小而美的函数

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

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

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

  3. JavaScript权威指南 - 函数

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

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

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

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

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

  6. javascript中的this与函数讲解

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

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

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

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

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

  9. C++中的时间函数

    C++获取时间函数众多,何时该用什么函数,拿到的是什么时间?该怎么用?很多人都会混淆. 本文是本人经历了几款游戏客户端和服务器开发后,对游戏中时间获取的一点总结. 最早学习游戏客户端时,为了获取最精确 ...

随机推荐

  1. bw R/3端配置 (转)

    先检查一下两边系统的补丁:R3端如下, BW端按照老师的说法至少补丁要打到17,貌似我们是19,通过,这样做起事情来后顾无忧 登陆R3界面,SBIW这个是R3的最常用事务码,有关BW的所有东东都在他的 ...

  2. 本地虚拟机中匿名ftp上传文件失败的问题

    在10.10.50.230中新建了一个匿名的ftp服务器,结果在10.10.50.241中上传文件时提示: local: README.txt remote: /var/ftp/pub/upload ...

  3. css3 怎么实现像书籍装订线的效果

    .test{ width: 150px; height: 150px; margin: 20% auto; background-color: white; background-image: rep ...

  4. 【BZOJ】【2879】【NOI2012】美食节

    网络流/费用流 跟 BZOJ 1070 修车 几乎是一道题,只是这题“要修的车”(即菜)多了很多……几乎是从$n$变成了$n^2$,所以建图的时候就得动态加点…… 也就是说,当一个厨师已经确定了他的后 ...

  5. 新建android项目src和layout文件夹中没有内容的问题

    这个问题好像是最新版ADT(ver:23.0.0)才会出现的问题,解决办法也简单,直接把android SDK和ADT的老版本(ver:22.6.2)覆盖安装一次就好了.至于新版为什么会这么设计,现在 ...

  6. Java多线程——<五>后台线程(daemon)

    一.后台线程(守护线程) 学一个东西,最重要的一点就是,为什么要用它? 后台线程区别于普通线程,普通线程又可以称为用户线程,只完成用户自己想要完成的任务,不提供公共服务.而有时,我们希望编写一段程序, ...

  7. 让32位Eclipse和64位Eclipse同时在64的Windows7上运行

    转自让32位Eclipse和64位Eclipse同时在64的Windows7上运行 参考这篇文章:http://wenku.baidu.com/view/57994c270066f5335a81214 ...

  8. linq中查询列表的使用及iqueryable和list集合之间的转换

    linq中查询列表的使用及iqueryable和list集合之间的转换 比如要查询一个货架集合,但是只需要其id和name即可,可以用以下方法:先写一个model类:CatalogModel(注意该类 ...

  9. 【hadoop2.6.0】MapReduce原理

    看了几篇博文,感觉还是云里雾里的. http://blog.csdn.net/opennaive/article/details/7514146 http://www.aboutyun.com/thr ...

  10. cast——java类型转换

    以下例说之: byte b = 3; //??? 3是一个int常量,但是会自动判断3是不是在byte类型的范围内 b = b + 2; //Type mismatch: cannot convert ...