innodb之change buffer被动merge

被动merge情景一,二级索引页空间不足:ibuf0ibuf.cc:: ibuf_insert_low

1、当尝试缓存插入操作时,如果预估二级索引page的空间不足,可能导致索引分裂,则定位到尝试缓存的page no在ibuf tree中的位置,最多merge 8个page,merge方式为异步,即发起异步读取索引页请求。

说明:

Buffered:当前二级索引页已经缓存的记录

entry_size:待插入的二级索引记录大小

page_dir_calc_reserved_space(1):待插入记录的slot大小

ibuf_index_page_calc_free_from_bits(zip_size,bits)):待插入二级索引页面剩余空间大小

/* Find out the volume of already bufferedinserts for the same index page */

min_n_recs= 0;

buffered= ibuf_get_volume_buffered(&pcur, space, page_no,

op == IBUF_OP_DELETE

? &min_n_recs

: NULL, &mtr);

……

do_merge = FALSE;

……

//打开待插入ibuf记录在ibuf tree中的前一个记录位置

btr_pcur_open(ibuf->index, ibuf_entry,PAGE_CUR_LE, mode, &pcur, &mtr);

……

if (op == IBUF_OP_INSERT){

ulint bits = ibuf_bitmap_page_get_bits(

bitmap_page,page_no, zip_size, IBUF_BITMAP_FREE,&bitmap_mtr);

if(buffered + entry_size + page_dir_calc_reserved_space(1)

>ibuf_index_page_calc_free_from_bits(zip_size, bits)) {

do_merge= TRUE;

ibuf_get_merge_page_nos(FALSE,

btr_pcur_get_rec(&pcur),&mtr,

space_ids,space_versions,

page_nos,&n_stored);

……

}

}

……

if(do_merge) {

buf_read_ibuf_merge_pages(false, space_ids,space_versions,

page_nos, n_stored);

}

问题:

1、buffered指什么?page_dir_calc_reserved_space(1)是什么?

指二级索引页插入二级索引时,已经缓存的记录的个数。当插入二级索引时,如果二级索引页发生分裂,ibuf树种记录的页面信息就会部分时效。因此每次插入时需要对bitmap进行判断。

2、如何判读merge了8页?

IBUF_MAX_N_PAGES_MERGED值是8.

Merge页的个数是8和当前buffer pool大小的1/4最小值

Ibuf0ibuf.cc::ibuf_get_merge_page_nos_func

limit = ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool_get_curr_size() / 4);

while (*n_stored < limit) {

……

page_nos[*n_stored] = prev_page_no;

……

}

3、merge的哪8个页?

递增的8个页。。。,这8个页指的是索引页,还是ibuftree的页?

首先定位到待插入记录的前一个记录的位置,根据前一个记录依次向前推8个记录。这8个记录里的space id和page no就是需要被merge的二级索引页的标记。

1、buf0rea.cc::buf_read_ibuf_merge_pages

输入参数:

Bool Sync:true if the caller wantsthis function to wait for the highest address page to get read in, before this functionreturns

const ulint* space_ids:space id数组

const ib_int64_t* space_versions:the spaces musthave this version number (timestamp), otherwise we discard the read; we usethis to cancel reads if DISCARD + IMPORT may have changed the tablespace size

const ulint*      page_nos:读入的页号数组

ulint          n_stored:页号数组元素个数

说明:

将数组页读入内存,merge相关页

Issues read requests for pages which theibuf module wants to read in, in order to contract the insert buffer tree.Technically, this function is like a read-ahead function

for (i = 0; i < n_stored; i++) {

……

buf_read_page_low(&err, sync && (i + 1 == n_stored),

BUF_READ_ANY_PAGE, space_ids[i],

zip_size, TRUE,space_versions[i],

page_nos[i]);

if (sync) {

/* The i/o is already completed when wearrive from     fil_read */

if (!buf_page_io_complete(bpage)) {

return(0);

}

}

……

}

Buf0buf.cc::buf_page_io_complete:异步读

if (io_type ==BUF_IO_READ){

if (uncompressed&& !recv_no_ibuf_operations) {

ibuf_merge_or_delete_for_page(

(buf_block_t*)bpage, bpage->space,

bpage->offset,buf_page_get_zip_size(bpage),

TRUE);

}

}

……

2、ibuf0ibuf.cc:: ibuf_merge_or_delete_for_page

输入参数:

block: 如果page已经从磁盘读取,指向pagex-latched

space:index page的space id

page_no:index page的页号

zip_size:compressed page大小

update_ibuf_bitmap:通常情况下设true。如果已经或者正在删除tablespace,设false

说明:

当一个二级索引页从磁盘读到buffer pool时,应用这个函数,将该页对应的所有操作merge,删除insert buffer中的entries。如果这个页没有读,但在buffer pool中创建,那么删除他缓存的操作记录。

被动merge情景二,insert buffer过大:ibuf0ibuf.cc:: ibuf_insert_low

如果insert buffer大小过大,contract insert buffer,并且放弃本次缓存。

1、  ibuf->size大于ibuf->max_size+10(单位页)执行一次同步ibuf merge(ibuf_contract),merge的page no是随机定位的记录的page no,最多一次merge 8页,同时放弃本次缓存

2、  其中ibuf_max_size=25%*bufferpool size,百分比由innodb_change_buffer_max_size控制,可动态调整。

if (ibuf->size >= ibuf->max_size +IBUF_CONTRACT_DO_NOT_INSERT) {

/*Insert buffer is now too big, contract it but do not try to insert */

/* Use synchronous contract (== TRUE) */

ibuf_contract(TRUE);

return(ibuf_merge(0, &n_pages, sync));

return(ibuf_merge_pages(n_pages,sync));

return(DB_STRONG_FAIL);

}

被动merge情景三,insert 操作可能产生ibuf btree分裂:ibuf0ibuf.cc:: ibuf_insert_low

说明:

1、  当ibuf->size<ibuf->max_size时(IBUF_CONTRACT_ON_INSERT_NON_SYNC=0)不做任何操作

2、  当ibuf->size>= ibuf->max_size+5时,ibuf_contract(true),同步一次ibuf merge,位置随机

3、  当ibuf->max_size< ibuf->size <= ibuf->max_size+5时,ibuf_contract(false),异步merge,位置随机。

4、  Merge至少8页,ut_min(IBUF_MAX_N_PAGES_MERGED, buf_pool_get_curr_size() / 4);

……

if (err == DB_SUCCESS && mode ==BTR_MODIFY_TREE) {

ibuf_contract_after_insert(entry_size);

if (size < max_size +IBUF_CONTRACT_ON_INSERT_NON_SYNC) {

return;

}

sync = (size >= max_size +IBUF_CONTRACT_ON_INSERT_SYNC);

size = ibuf_contract(sync);

return(ibuf_merge(0,&n_pages, sync));

return(ibuf_merge_pages(n_pages,sync));

}

……

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-29 19:07:35

innodb之change buffer被动merge的相关文章

innodb之change buffer主动merge

一.srv0srv.cc:: srv_master_thread 说明: 1.  主线程有3种状态:ACTIVE.IDLE.SHUTDOWN状态 2.  ACTIVE:srv_master_do_active_tasks() 3. IDLE:srv_master_do_idle_tasks() 4.  SHUTDOWN:srv_master_do_shutdown_tasks 1.srv_master_thread - while (srv_shutdown_state ==SRV_SHUTDO

InnoDB关键特性之change buffer

一.关于IOT:索引组织表 表在存储的时候按照主键排序进行存储,同时在主键上建立一棵树,这样就形成了一个索引组织表,一个表的存储方式以索引的方式来组织存储的. 所以,MySQL表一定要加上主键,通过主键来访问MySQL表的性能是最好: 1.显式定义主键:primary key 2.隐式定义主键:如果没有指定主键,MySQL自己会默认建立一个主键(rowid隐藏主键) 1.特点 1.表按照主键排好序,数据按照主键顺序存放(核心原因) 2.主键上有一棵树,叶子节点就是数据节点 3.表本身就是索引,表

insert buffer/change buffer double write buffer,双写 adaptive hash index(AHI) innodb的crash recovery innodb重要参数 innodb监控

https://yq.aliyun.com/articles/41000 http://blog.itpub.net/22664653/viewspace-1163838/ http://www.cnblogs.com/MYSQLZOUQI/p/5602206.html https://yq.aliyun.com/articles/222 主从不一致性的3种可能原因1.binlog format是不是row2.session级关闭binlog3.人工在slave修改数据 set sql_log_

mysql-5.7 innodb change buffer 详解

一.innodb change buffer 介绍: 1.innodb change buffer 是针对oltp场景下磁盘IO的一种优化(我也感觉这个不太像人话,但是它又非常的准确的说明 innodb change buffer 的功能) 二.innodb change buffer 原理: 对于insert ,update ,delete 操作一来要更新数据,二来要更新索引:如果要更新的索引页还没有在内存中,那么innodb 不会急于把索引页调入内存,更新,再写回磁盘:它会先把对索引的更新这

Change Buffer与innodb_force_recovery=4

一.关于innodb_force_recovery 熟悉mysql的人一定熟悉innodb_force_recovery这个参数,如果数据库crash,再次启动的时候innodb会对innodb表进行恢复,恢复成功,数据库正常启动,如果恢复失败,数据库将无法启动.根据经验,innodb_force_recovery=4这个参数相当管用,最近用于恢复了一个数据库,步骤网上都有: 1.在/etc/my.cnf中增加: [mysqld]innodb_force_recovery = 42.重启MySQ

MySql 缓冲池(buffer pool) 和 写缓存(change buffer) 转

应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库. 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问. MySQL作为一个存储系统,同样具有缓冲池(buffer pool)机制,以避免每次查询数据都进行磁盘IO. 今天,和大家聊一聊InnoDB的缓冲池. InnoDB的缓冲池缓存什么?有什么用? 缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用. 速度快,

普通索引和唯一索引如何选择(谈谈change buffer)

假设有一张市民表(本篇只需要用其中的name和id_card字段,有兴趣的可以翻看“索引”篇,里面有建表语句) 每个人都有一个唯一的身份证号,且业务代码已经保证不会重复. 由于业务需求,市民需要按身份证查找对应姓名,即执行如下sql select name from CUser where id_card = 'xxxxxxxyyyyyyzzzzz'; 我们自然会想在id_card上建索引.因为该字段较大,一般不建议直接作为主键. 于是我们面临选择:是建普通索引还是唯一索引——结合前面的背景说明

MySQL 5.7 Reference Manual】15.4.2 Change Buffer(变更缓冲)

15.4.2 Change Buffer(变更缓冲) The change buffer is a special data structure that caches changes to secondary index pages when affected pages are not in the buffer pool. The buffered changes, which may result from INSERT, UPDATE, or DELETE operations (DM

Mysql InnDB 内存存储结构 -- Change Buffer

在InnoDB中,当对应的数据不存在与Buffer Pool中时,为了避免大量的随机磁盘I/O可能带来的性能瓶颈,InnoDB 在Buffer Pool 中划分出一部分内存,称为Change Buffer,由其负责缓存由DML操作引起的二级索引相关数据的变化.当对应的数据下次被读入Buffer Pool 中时,Change Buffer 中记录的变化信息会被合并到数据中.其结构如下图所示.简要的,使用Change Buffer有三个要点:a. DML操作, b. 涉及二级索引,c. 对应page