MySQL 新特性

[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源码] Facebook对压缩表的改进

由于公司最近很多地方需要开始有使用压缩表的需求,但根据测试结果,压缩表对OLTP的性能相当不理想,在最近的一次测试中,UPDATE的性能最大可以下降到1/12,几乎不可接受。   Facebook从2011年开始对压缩表进行改进,花了两个星期从facebook的博客、facebook成员在官方list上提交的bug以及Mark在lauchpad上提交的patch着手调研,以下内容基本涵盖了Facebook对压缩表的改进,以及对应的Rev 接下来,需要做的就是研究这些Patch,如何为我所用。   注:除了以下内容,在查看facebook的bzr log时,还发现很多比较小的优化点(例如对innodb层线程调度的改进),但未公布出来,有兴趣的可以看看。   1.提供更多的信息来监控/诊断压缩表性能 MySQL本身(包括Percona版本)提供的压缩表内部信息非常少,很难通过这些信息来进行优化,Facebook增加了大量的信息用以显示。 从mysql@facebook的代码来看,为table_statistics增加了大量的统计数据,包括IO、索引、压缩表相关信息,我们关注如下几个跟压缩表相关的信息: COMPRESSED_PAGE_SIZE COMPRESS_PADDING PADDING_SAVINGS COMPRESS_OPS  COMPRESS_OPS_OK COMPRESS_PRIMARY_OPS COMPRESS_PRIMARY_OPS_OK  COMPRESS_USECS COMPRESS_OK_USECS COMPRESS_PRIMARY_USECS  COMPRESS_PRIMARY_OK_USECS UNCOMPRESS_OPS UNCOMPRESS_USECS 另外在update_global_table_stats函数中,facebook做了一些优化,通过原子操作代替锁操作,避免长期持有全局锁 LOCK_global_table_stats 相关:r3668, r3670,r3678 扩展innodb_cmp表的信息 r3679 更多的global status信息 r3672,r3671   2.从redo log中移除压缩Page,并为压缩表增加了一种新的日志记录 –r3641   3.增加adpative padding功能,减少每个page上的数据来降低压缩失败率 类似于在page上填写空白,当压缩失败率升高到某个层次时,加大pad值。当失败率维持在很低的水平时,则减小pad值。 动态padding实现 r3754, r3759, r3764, r3768 线性算法计算自适应padding值 r3820 4.减少分配的空白页,以降低文件的大小 相关bug: bug#64673 r3814   5.减少压缩Page的malloc/free次数 避免每次page 压缩/解压时频繁malloc/free 内存 r3808   6.更高效的压缩page checksum 对压缩page使用快速checksum r3824 related bug#49852 通过只在需要的时候计算压缩page/非压缩page的checksum来降低cpu占用 r3816 , r3817 related bug#64170   7.移除对adler32的调用 r3818   8.允许设置zlib的压缩级别 增加了新的参数innodb_compression_level来控制zlib的压缩级别 r3766   9. fix  bug#61341 r3675   10.其他 增加innochecksum工具对压缩表的支持 r3813 Fix bug#64258 可动态调整WAIT_FOR_READ r3792 跟压缩表相关,未具说明的bugfix r3779, r3780 (maybe […]


[MySQL 调试] 初试breakpad

breakpad是google开源的一个崩溃报告工具,按照其声称,生成的core file相当小,近日开始调研将其集成到我们线上MySQL的可行性,以下是初步的安装尝试 1. checkout 代码 svn co http://google-breakpad.googlecode.com/svn/trunk  breakpad 2. configure && make && make install 3.暴力cp src/client/linux/libbreakpad_client.a 4.测试程序 #include “client/linux/handler/exception_handler.h” #include <cstdio> static bool dumpCallback(const google_breakpad::MinidumpDescriptor &md, void* context, bool succeeded) { printf(“Dump path: %s\n”, md.path()); return succeeded; } void crash() { volatile int* a = (int*)(NULL); *a = 1; } int main() { google_breakpad::MinidumpDescriptor […]


[MySQL5.6 新特性] 全局事务标示符(GTID)

GTID的全称为 global transaction identifier  , 可以翻译为全局事务标示符,GTID在原始master上的事务提交时被创建。GTID需要在全局的主-备拓扑结构中保持唯一性,GTID由两部分组成: GTID = source_id:transaction_id source_id用于标示源服务器,用server_uuid来表示,这个值在第一次启动时生成,并写入到配置文件data/auto.cnf中 transaction_id则是根据在源服务器上第几个提交的事务来确定。 一个GTID的生命周期包括: 1.事务在主库上执行并提交 给事务分配一个gtid(由主库的uuid和该服务器上未使用的最小事务序列号),该GTID被写入到binlog中。 2.备库读取relaylog中的gtid,并设置session级别的gtid_next的值,以告诉备库下一个事务必须使用这个值 3.备库检查该gtid是否已经被其使用并记录到他自己的binlog中。slave需要担保之前的事务没有使用这个gtid,也要担保此时已分读取gtid,但未提交的事务也不恩呢过使用这个gtid. 4.由于gtid_next非空,slave不会去生成一个新的gtid,而是使用从主库获得的gtid。这可以保证在一个复制拓扑中的同一个事务gtid不变。 由于GTID在全局的唯一性,通过GTID,我们可以在自动切换时对一些复杂的复制拓扑很方便的提升新主库及新备库,例如通过指向特定的GTID来确定新备库复制坐标。 当然,使用GTID也有一些限制: 1.事务中的更新包含非事务性存储引擎,这可能导致多个GTID分配给同一个事务。 2. create table…select语句不被支持,因为该语句会被拆分成create table 和insert两个事务,并且这个两个事务被分配了同一个GTID,这会导致insert被备库忽略掉。 3.不支持CREATE/DROP临时表操作 可以看到,支持GTID的复制对一些语句都有一些限制,MySQL也提供了一个选项disable-gtid-unsafe-statements以禁止这些语句的执行。 参考: http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-restrictions.html http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html 原创文章,转载请注明: 转载自Simple Life 本文链接地址: [MySQL5.6 新特性] 全局事务标示符(GTID) Post Footer automatically generated by wp-posturl plugin for wordpress.


[MySQL5.6 新特性] 并行复制代码结构(1)

相关文件: rpl_slave.cc  rpl_slave.h rpl_rli_pdb.cc rpl_rli_pdb.h 1.启动slave. init_slave    |—>start_slave_threads                          |—>handle_slave_io(IO thread) 启动IO线程                        |—>handle_slave_sql(SQL thread) 启动SQL线程(作为协调者)                                  |—>slave_start_workers(Worker thread)   […]