简要记录一下压缩表在buffer pool中的相关结构体:

////////////////////////////////////////////////////////////

struct buf_pool_struct{

mutex_t     zip_mutex;   //用于保护压缩page(buf_page_t)

mutex_t     zip_free_mutex;

mutex_t     zip_hash_mutex;   //保护zip_hash

hash_table_t*   zip_hash;  //hash table of buf_block_t blocks whose frames are allocated to the zip buddy system, indexed by block->frame

ulint       n_pend_unzip;  //number of pending decompressions

UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;   //base node of the unzip_LRU list

UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX]; //存储buddy allocator的空闲block

}

Innodb采用Binary buddy allocator算法来为compress page(block->page.zip.data)分配内存块(buf/buf0buddy.c)

buf_buddy_alloc_low是分配block的函数,需要持有LRU_list_mutex,不可以持有zip_mutex

buf_buddy_free_low是释放block的函数,需要持有zip_free_mutex,不可以持有zip_mutex

innodb_cmpmem表显示每个bp instance的不同page size的内存分配情况,因此在调用i_s_cmpmem_fill_low时需要持有zip_free_mutex锁

zip_mutex用于保护压缩页在buffer pool中的操作,在如下函数中被调用到:

1.buf/buf0lru.c

buf_LRU_free_block:

buf_LRU_block_remove_hashed_page:该函数会释放zip_mutex

2.buf/buf0buf.c

buf_page_init

buf_page_init_for_read

buf_page_get_gen

buf_get_latched_pages_number_instance

buf_pool_watch_set/buf_pool_watch_unset

buf_pool_validate_instance

buf_get_latched_pages_number_instance

3.include/buf0buf.ic

buf_page_release_zip

zip_hash_mutex用于保护buf_pool->zip_hash,在如下函数中调用

buf/buf0buddy.c:

buf_buddy_block_free

buf_buddy_block_register

——————————————————

buf_block_struct{

UT_LIST_NODE_T(buf_block_t) unzip_LRU;   在解压page LRU  list上的节点,当该block的page.state == BUF_BLOCK_FILE_PAGE并且page.zip.data != NULL时会在unzip_lru list上

buf_page_t  page;

}

——————————————————-

struct buf_page_struct{

page_zip_des_t  zip;   //包含压缩页信息

UT_LIST_NODE_T(buf_page_t) zip_list;    //zip_clean or zip_free[]

}

从代码来看,zip_list应该是buffer_pool->zip_free链表的节点

——————————————————–

struct page_zip_des_struct{

page_zip_t* data;    //压缩Page数据

m_start   //debug编译,mlog开始的偏移量

m_end    //mlog的结尾偏移量

m_nonempty  //为true时表示mlog不为空

n_blobs   //该Page上外部存储的列的个数,在一个16kb的page上最大为744

ssize  //为0表示非压缩Page,否则压缩page大小为PAGE_ZIP_MIN_SIZE << (ssize – 1)

}

时间: 2024-10-30 23:30:19

简要记录一下压缩表在buffer pool中的相关结构体:的相关文章

[MySQL 源码] 从buffer pool中获取空闲block流程

当我们将一个page读入内存时,需要先为其分配一个block,从buffer pool中获取.入口函数为buf_LRU_get_free_block 之前在http://mysqllover.com/?p=303有简要介绍,这里详细看看,当然,跟最近博客的主题一样,我们还是主要针对压缩表来分析. 以下分析基于Percona Server 5.5.18 buf_LRU_get_free_block loop: 1.block = buf_LRU_get_free_only(buf_pool) 首先

MySQL · 引擎特性 · InnoDB Buffer Pool

前言 用户对数据库的最基本要求就是能高效的读取和存储数据,但是读写数据都涉及到与低速的设备交互,为了弥补两者之间的速度差异,所有数据库都有缓存池,用来管理相应的数据页,提高数据库的效率,当然也因为引入了这一中间层,数据库对内存的管理变得相对比较复杂.本文主要分析MySQL Buffer Pool的相关技术以及实现原理,源码基于阿里云RDS MySQL 5.6分支,其中部分特性已经开源到AliSQL.Buffer Pool相关的源代码在buf目录下,主要包括LRU List,Flu List,Do

[MySQL学习] 一个压缩Page从磁盘读入buffer pool的过程

以下是边看代码边记录的,从磁盘读取一个压缩Page到buffer pool的的全过程,以函数buf_page_get_gen作为入口 buf_page_get_gen 1.根据space和offset来计算请求的page是否已经读到了buffer pool中 fold = buf_page_address_fold(space, offset); block = (buf_block_t*) buf_page_hash_get_low(                           buf

[MySQL 源码] MySQL drop table(压缩表)效率与流程分析

 之前发生过一起连续drop压缩表,最后长时间等待信号量crash,线上alert log里的报错是: OS WAIT ARRAY INFO: reservation count 36647199, signal count 34050225 --Thread 1331538240 has waited at row0purge.c line 680 for 950.00 seconds the semaphore: S-lock on RW-latch at 0xe60b60 '&dict_o

[MySQL学习]Innodb压缩表之内存分配/回收

最近看到Yoshinori Matsunobu在官方buglist上提交的一个Bug#68077,大意是说,当使用压缩表时,在bp吃紧时,存在过度碎片合并的情况.Innodb压缩表由于存在不同的Page Size,因此使用buddy allocator的方式进行内存分配,他的内存块来自于buffer pool中. 如bug#68077所提到的,如果我们使用的全部是4kb的内存块,那么把他们合并成8k的又有什么意义呢?并且在碎片整理的过程中,函数buf_buddy_free 的效率是很低的.在之前

[MySQL学习] MySQL压缩表

以下是在阅读官方文档时的笔记 官方文档: http://dev.mysql.com/doc/refman/5.6/en/innodb-compression.html#innodb-compression-tuning //////////////////////////////////////////////////////////////////////// 关于压缩表,可以调整的参数看起来只有key_block_size,在建表时指定,意味着innodb会将page压缩到指定的大小,例如,

MySQL内核月报 2015.02-MySQL · 性能优化· InnoDB buffer pool flush策略漫谈

背景 我们知道InnoDB使用buffer pool来缓存从磁盘读取到内存的数据页.buffer pool通常由数个内存块加上一组控制结构体对象组成.内存块的个数取决于buffer pool instance的个数,不过在5.7版本中开始默认以128M(可配置)的chunk单位分配内存块,这样做的目的是为了支持buffer pool的在线动态调整大小. Buffer pool的每个内存块通过mmap的方式分配内存,因此你会发现,在实例启动时虚存很高,而物理内存很低.这些大片的内存块又按照16KB

谁占用了我的Buffer Pool

场景带入 双十一后,老鸟接二连三的狂轰滥炸着菜鸟:"你读过一本叫<谁动了我的奶酪>的书吗?正好,你研究下谁动了SQL Server的Buffer Pool吧?". 菜鸟又是满脸懵逼茫然状:"这谁跟谁啊?有半毛钱关系吗?".没办法,老鸟交代的任务,菜鸟还是要一丝不苟的竭尽全力. 哪些数据库占用了Buffer Pool 于是,菜鸟从大处着眼:"哪些数据库占用了SQL Server的Buffer Pool?每个库占用了多少Buffer Pool的空间

MySQL 5.7.5: Buffer Pool 转储、恢复 以及存在的问题

MySQL提供了一个比较有用的功能,能够把buffer pool LRU上的block对应的page id 和space id 存储到文件中.在重启时,会自动读取这个转储文件,然后把对应的<space id, page id>读入到buffer pool中,快速预热内存,以尽快提供服务. 参数 使用该特性比较简单,通过多个参数控制. 简单说下几个参数 转储到文件: innodb_buffer_pool_dump_now  : 立刻做一次buffer pool  LRU dump innodb_