October 2012

MySQL buffer pool初始化内存分配

之前一直理解的是buffer pool在启动时候就被分配好,今天有同事问到这个问题,跟着代码看了下。 buf_pool_init |–>buf_pool_init_instance |–>buf_chunk_init |–>os_mem_alloc_large ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, -1, 0); 调用mmap之前TOP出来的VIRT虚拟内存为135M,调用之后VIRT值为2714M,而实际的物理内存RES才不到100M 也就是说mmap并没有分配物理内存。 实际上这里使用mmap时限了匿名的存储区域映射,那么mmap和直接malloc有什么区别呢? 做个简单的实验 1. #include <stdio.h> #include <malloc.h> #include <fcntl.h> #include <sys/mman.h> int main(int argc, char *argv[]) { printf(“alloc=====\n”); char *ptr = malloc(2693120000); //2.5G sleep(60); free(ptr); printf(“=====finish\n”); return 0; } 2. 将内存分配修改为: void* ptr= mmap(0, 2693120000, […]

[MySQL 新特性] MySQL5.6 RC的压缩表自适应padding实现

以下是对facebook的adaptive padding实现简述,实际上,这是个很小的补丁,并且对OLTP的性能提升效果非常显著(但会影响压缩的效果)。 在5.6.7中引入了facebook对压缩表的改进,其中重要的特性之一就是adaptive padding。 我们知道,在buffer pool中,对一个压缩表的page,同时存在压缩页和非压缩页 –对Page的更改被记录到压缩page的mlog中 –当一个压缩页满时,会进行重压缩 –当重压缩失败时,会分裂压缩页 分裂压缩页的开销很大,需要对原先的压缩page拆分成两个Page,并重新进行压缩,并且会有额外的锁(index rw-lock)开销。 adaptive padding的目的是对一个buffer pool中一个16k的非压缩page”少放一些数据“,来降低压缩失败导致分裂的概率,例如之前会对一个装满16K数据的Page进行压缩,如果pad值为2K,那么会对14K的数据压缩,这会降低压缩失败的概率。 具体实现在函数dict_index_zip_pad_update中,每次压缩成功或失败,都会调用到这个函数。每采样ZIP_PAD_ROUND_LEN(128次)次会进行如下判断: —当失败率高于innodb_compression_failure_threshold_pct时,pad+=ZIP_PAD_INCR —当失败率连续ZIP_PAD_SUCCESSFUL_ROUND_LIMIT(5)次低于innodb_compression_failure_threshold_pct且pad>0时,pad-= ZIP_PAD_INCR 其中ZIP_PAD_INCR值默认为128 这样就对pad的值实现了动态调整。 函数dict_index_zip_success和dict_index_zip_failure在函数page_zip_compress中对应压缩成功和失败的逻辑被调用。 dict_index_zip_pad_optimal_page_size函数返回减去pad后的page大小,但不得小于(UNIV_PAGE_SIZE * (100 – zip_pad_max)) / 100,在如下函数被调用到: 1.btr_compress   //page merge,当page的size小于BTR_CUR_PAGE_COMPRESS_LIMIT时会尝试合并page,purge线程调用btr_cur_pessimistic_delete->btr_cur_compress_if_useful->btr_compress,另外在做btr_cur_pessimistic_update时也可能调用到 2.btr_cur_optimistic_insert     //insert操作 3.btr_cur_update_alloc_zip    //update操作 通过判断加上新记录后,是否超过optimal page size,如果超过了,则对16k page进行分裂或不进行合并。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: [MySQL 新特性] MySQL5.6 RC的压缩表自适应padding实现 Post Footer automatically generated by […]

[MySQL 特性] MySQL5.6.7 对压缩表的改进

5.6.7已经RC,其中关于压缩表部分,引进了大多数Facebook的改进 1.可配置的zlib压缩级别 innodb_compression_level 用于动态调整zlib的压缩级别,从1-9,默认为6,越小压缩效果越差,但压缩速度越快;值越大,压缩效果越好,可能会减小压缩失败及page split, 但速度越慢,有更多的CPU开销。 2. innodb_log_compressed_pages 控制压缩page是否被记录到redo中,这会减少redo产生的数据量,可能会提升throughput 3.增加adaptive padding功能,通过在page中留下空白来防止减少page分裂,Facebook的实现是在启动mysqld后,对压缩表中的压缩失败的page进行采样,以计算出合适的留白数。 增加了两个参数: innodb_compression_failure_threshold_pct  当压缩失败rate大于这个值时,会增加padding来减小失败率,为0表示禁止该padding.(官方文档貌似有误,已report)  innodb_compression_pad_pct_max 一个page中最大允许留白的百分比 4.新的关于压缩表的i_s表:  innodb_cmp_per_index innodb_cmp_per_index_reset 由于这些表里记载了每个索引的压缩信息,因此会产生一些额外的开销,通过选项 innodb_cmp_per_index_enabled 来控制开关 例如: mysql> select * from  innodb_cmp_per_index\G *************************** 1. row ***************************   database_name: cmp2k8      table_name: com1@@@      index_name: PRIMARY    compress_ops: 34999 compress_ops_ok: 34150   compress_time: 13  uncompress_ops: 424 uncompress_time: 0 1 row in set (0.00 sec) […]

[MySQL 工具] 备库预热工具relayfetch及错误处理工具seh

今年上半年,由于线上许多实例存在主备延迟,并且经常有备库复制中断导致DBA同学需要半夜起来处理,出于这样的需求,所以写了这两个工具,不过严格来讲,seh算是relayfetch的衍生品。 两个工具都可以从如下地址checkout: http://code.google.com/p/relay-fetch/ Relayfetch 由于在备库上(尤其是没有读写负载的备库)SQL线程是单线程的,比较悲观的情况是,需要从磁盘读取数据,然后再做DML。当数据量远大于buffer pool的大小时,这种磁盘IO开销尤为明显。 通常的作法是将binlog中的事件转换成select操作,目前社区也有很多类似的工具,不过都是只支持STATEMENT模式,如果你是基于STATEMENT模式复制的话,可以在主备产生延迟时,挑一个用。 为了不重复发明轮子,relayfetch主要用于支持row模式(只支持简单的statement模式,没做充分测试),通过解析binlog中的DELETE_ROWS_EVENT/UPDATE_ROWS_EVENT/WRITE_ROWS_EVENT,获取其中的primary key和unique key,然后转换成select语句,使用多线程执行select,默认5个线程,能够控制预热不会“走的太快”。 当然备库预热并不总是有效果的,也有一些限制: 1、如果buffer pool足够大到容纳大部分数据/热点数据的话,可能没什么效果(瓶颈不在磁盘IO) 2、需要有主键或者唯一键 3、对insert操作产生的延迟预热效果不明显,尤其是连续插入(但对存在多个唯一键(包括主键)会有不错的效果,因为按照主键顺序插入时,唯一键上的INSERT可能是随机的IO) 4、目前主要针对ROW模式预热,基于STATEMENT模式的同学请自行谷歌目前社区的预热工具   Seh备库错误处理工具 写这个工具的初衷是由于各种原因(复制bug,人为失误,主备切换导致数据丢失等等。。。)备库经常会出现复制中断,DUPLICATE KEY和KEY NOT FOUND错误应该是比较常见的(对应的错误码为1062和1032) 通常的处理办法是设置sql_slave_skip_counter来跳过错误,但这样明显的会产生主备数据不一致。seh不是跳过错误,而是将导致错误的数据补上。 seh通过解析binlog,找到发生错误的事件,对于找不到键的错误,将相应的记录补上。代码里面还实现了处理重复键的代码,不过没有开启(删除记录太暴力。。。。),对于重复键错误,如果是插入操作导致的,可以通过将slave_exec_mode设置为IDEMPOTENT来解决。 同样seh需要表上有主键存在,并且无法处理同时存在主键错误和唯一键冲突的情况,例如丢失的记录上如果有唯一键并且和已有记录冲突时,就会补数据失败。 有兴趣的同学可以玩一下这两个工具,有问题的话可以在google code上提交issue,或邮件我.     原创文章,转载请注明: 转载自Simple Life 本文链接地址: [MySQL 工具] 备库预热工具relayfetch及错误处理工具seh Post Footer automatically generated by wp-posturl plugin for wordpress.