MySQL 5.6

MySQL: 对超长blob列的redo log限制

我们知道,Innodb使用固定长度的N个iblog文件来存储redo log,文件空间可以被复用。这些被复用的空间redo需要保证已经做了checkpoint。 假定我们的iblog大小为1G,如果我们更新一个非常大的字段,就有可能覆盖掉未checkpoint的redo log,因为Innodb并没有根据其可能产生的log长度来判断redo log空间是否够用。而只是保证会预留一定比例的redo log空间。详细见bug链接:http://bugs.mysql.com/bug.php?id=69477 原创文章,转载请注明: 转载自Simple Life 本文链接地址: MySQL: 对超长blob列的redo log限制 Post Footer automatically generated by wp-posturl plugin for wordpress.


Facebook MySQL: 索引在线碎片整理特性

背景 我们知道Innodb使用BTREE来进行数据组织存储,当发生INSERT/UPDATE/DELETE时,有可能会产生数据s碎片,不能有效的利用page空间。而这些空洞在未来甚至有可能不再被使用到。即使是顺序的Insert,也可能产生空间浪费:为了保证以后对相同page的更新不会产生page分裂,Innodb总是为其保留一部分的剩余空间。 原创文章,转载请注明: 转载自Simple Life 本文链接地址: Facebook MySQL: 索引在线碎片整理特性 Post Footer automatically generated by wp-posturl plugin for wordpress.


MySQL table cache的分区方式

今天在跑高压力高并发下只读查询时,发现个比较有意思的小问题 先来看看performance schema root@performance_schema 03:13:45>SELECT COUNT_STAR, SUM_TIMER_WAIT, AVG_TIMER_WAIT, EVENT_NAME FROM events_waits_summary_global_by_event_name where COUNT_STAR > 0 and EVENT_NAME like ‘wait/synch/%’ order by SUM_TIMER_WAIT desc limit 20; +————-+——————+—————-+—————————————————+ | COUNT_STAR | SUM_TIMER_WAIT | AVG_TIMER_WAIT | EVENT_NAME | +————-+——————+—————-+—————————————————+ | 794349716 | 9217250429384944 | 11603268 | wait/synch/mutex/sql/LOCK_table_cache | | 395819330 | 8052052171747844 | 20342452 | wait/synch/rwlock/sql/LOCK_grant | | […]


(bugfix in 5.6.21) DUPLICATES IN UNIQUE SECONDARY INDEX BECAUSE OF FIX OF BUG#68021

(bugfix in 5.6.21) DUPLICATES IN UNIQUE SECONDARY INDEX BECAUSE OF FIX OF BUG#68021 在MySQL5.6.21版本里,fix了这样一个有趣(坑爹)的bug,影响5.6.12之后及5.6.21之间的版本 InnoDB: With a transaction isolation level less than or equal to READ COMMITTED, gap locks were not taken when scanning a unique secondary index to check for duplicates. As a result, duplicate check logic failed allowing duplicate key values in the […]


DML对innodb page空间的影响

前言 我们知道Innodb使用BTREE来进行数据组织存储,当发生INSERT/UPDATE/DELETE时,有可能会产生数据空洞,不能有效的利用page的空间。而这些空洞在未来甚至有可能不再被使用到。本文主要记录了相关的代码,现有的处理方式,最后介绍了facebook mysql对page碎片的处理方式.   DML对page空间影响 以下简述下三种操作类型对页面空间的影响 原创文章,转载请注明: 转载自Simple Life 本文链接地址: DML对innodb page空间的影响 Post Footer automatically generated by wp-posturl plugin for wordpress.


[MySQL5.6] 最近对group commit的小优化

最近花了一些时间在做MySQL Group Commit的优化,关于Group commit的原理,这里不再赘述,有兴趣的可以翻阅我之前的博客http://mysqllover.com/?p=581,这里简单描述下两点优化,主要基于MySQL5.6.16 1.优化binlog_order_commits=0并且sync_binlog>0时的性能  我们知道当binlog_order_commits关闭时,表示我们能接受binlog commit和innodb commit的顺序不同(这不会带来数据不一致,但可能会影响到热备份),关闭该选项可以带来一定程度的性能提升。 本优化也是基于该前提,假定sync_binlog =1000, 那么在第1000组事务进入sync stage时,需要去做binlog sync,我们知道fsync操作是非常慢且耗时的操作,而第1001组事务,显然无需去做sync,如果我们允许innodb/binlog commit失序,就可以让第1001组事务跳过sync stage,直接进入innodb commit detail见http://bugs.mysql.com/bug.php?id=73018,附加补丁 2.延迟写redo直到group commit时来提升性能 我们知道MySQL使用Binlog,Innodb XA的方式来进行crash recovery,所有记录在binlog中的事务我们都期望能够commit掉; 这意味着,在写binlog之前,需要确保事务的prepare状态被写到redo中,这样才能从crash中恢复. 原生的逻辑中,各个事务各自做innodb prepare, 并写redo log; 只有到了commit阶段,进入ordered_commit,才进入组提交; 我们主要集中在group commit的第一阶段:flush stage。 在该阶段,leader线程从队列中pop 线程加入queue,并依次flush thread cache到binlog文件. 修改后的流程: 1. 在Innodb prepare阶段不再write/sync redo log,而是直接返回 2.在group commit的flush stage阶段,修改成如下逻辑 a) 收集组提交队列 b) 调用ha_flush_logs 做一次redo write/sync c) 将队列中thd的所有binlog cache写到binlog文件中 detail见http://bugs.mysql.com/bug.php?id=73202, 附加补丁 […]


MySQL select now()的性能问题

问题描述 localtime函数会去调用/etc/localtime文件,对于大量并发的select now(),可以观察到明显的瓶颈(下面红色标注的函数) 26 __lll_lock_wait_private(libc.so.6),_L_lock_2164(libc.so.6),__tz_convert(libc.so.6),Time_zone_system::gmt_sec_to_TIME(tztime.cc:1079),gmt_sec_to_TIME(tztime.h:60),set_datetime(tztime.h:60),Item_func_now::fix_length_and_dec(tztime.h:60),Item_func::fix_fields(item_func.cc:231),setup_fields(sql_base.cc:8229),JOIN::prepare(sql_resolver.cc:168),mysql_prepare_select(sql_select.cc:1054),mysql_select(sql_select.cc:1054),handle_select(sql_select.cc:110),execute_sqlcom_select(sql_parse.cc:5544),mysql_execute_command(sql_parse.cc:3033),mysql_parse(sql_parse.cc:6729),dispatch_command(sql_parse.cc:1634),do_handle_one_connection(sql_connect.cc:982),handle_one_connection(sql_connect.cc:898),pfs_spawn_thread(pfs.cc:1858),start_thread(libpthread.so.0),clone(libc.so.6) localtime调用会去访问本地文件,引起底层库级别的锁冲突(类似bug#72701),对于高性能服务器,应该尽量避免调用localtime函数。之前FB的Domas也写了篇文章来描述这个问题 Workaround 导入时区信息: mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -uroot -S /u01/my3306/run/mysql.sock mysql 查看本机时区配置: $cat /etc/sysconfig/clock ZONE=”Asia/Shanghai” 然后以以下任意一种方式设置: 1). mysql> set global time_zone=’Asia/Shanghai’; Query OK, 0 rows affected (0.00 sec) 2).在不导入时区配置的情况下(不调用mysql_tzinfo_to_sql ),直接设置时区: mysql> set global time_zone = ‘+8:00′; Query OK, 0 rows affected (0.00 sec) 3).在配置文件里添加: default-time-zone=’Asia/Shanghai’ 测试 主要测试SELECT NOW()的效率 mysqlslap –no-defaults […]


zlib库优化性能测试(port from facebook and intel)

背景 facebook基于zlib 1.2.5 做了些改进,并port了intel的一些相关补丁。本文主要目的是验证其压缩效果 主要有两个补丁: https://github.com/facebook/mysql-5.6/commit/8ac9e7d219c8679b75da26e64d702b5517d05ea8 (Optimize zlib for a non-sliding window.) https://github.com/facebook/mysql-5.6/commit/ed46ec9b4ef367f3335a531999f39cb1d9d40341 (port from intel) intel补丁的主要修改: 1) By default, use CRC32 as the hash, computed using SSE4.2 2) Also provide a better fallback hash in case of no SSE 3) By default use double-byte comparisons by enabling UNALIGNED_OK 4) Use best_len_minus_1 instead of best_len in longest_match() […]


[MySQL5.6] MySQL 5.6.17新特性:online optimize table (以及其他主要bugfix)

在刚刚放出来的MySQL5.6.17版本中,最引人注意的功能当属于能够在线的进行opimitze table操作,这可以帮助减小表的大小而无需阻塞并发负载,另外以下几类操作也开始支持online ddl: OPTIMIZE TABLE ALTER TABLE … FORCE ALTER TABLE … ENGINE=INNODB (when run on an InnoDB table) 上述操作将触发表的rebuild,代码的改动量非常小 修改见 【Rev:5820】 这几个选项从sql_mode中移除了:ERROR_FOR_DIVISION_BY_ZERO, NO_ZERO_DATE, and NO_ZERO_IN_DATE;而是在严格模式中默认开启(【Rev:5829】) ALTER  IGNORE TABLE 也被弃用(目前只是打印warning,未来版本可能移除掉),根据描述,该类操作可能导致对unique key的ddl操作及外键操作以及复制问题  (搞不定一些问题就把他干掉。。。。呵呵)(修改见【Rev:5745】) 其他一些比较有意思的bugfix 【Rev:5800】 开始支持分区表的flush table for export,但依然不支持分区表的ALTER TABLE DISACARD/IMPORT TABLESPACE (不知道会否进一步开发) 【Rev:5846】 修复一个压缩表性能退化的bug(bug#71436) 调整了zip_mutex的顺序(buf_page_get_gen),当读入一个压缩页,实际上在递增计数器buf_pool->n_pend_unzip后,就可以直接释放buf_pool->zip_mutex 【Rev:5753】 purge协调线程和innodb monitor线程在shutdown时可能产生race condition(bug#70430) 因为purge线程退出时,还有可能进入到函数lock_print_info_summary中 , 之前的ut_error被移除掉了 另外一个和shutdown相关的bug, shutdown可能hang住(【Rev:5752】),也和purge线程的状态相关; 【Rev:5758】 在打开innodb_stats_persistent时,CREATE TABLE时需要向mysql.innodb_index_stats表中插入多条记录,每次插入都会commit一次,现在改成只commit一次(buf#70063) 见函数dict_stats_save_index_stat/dict_stats_save […]


[MySQL 5.6] Percona Server 5.6.16的主要改进

Percona刚刚放出了其最新的基于MySQL5.6.16的分支,在该版本中,Percona增加了几个比较有趣的特性,这里只列出我比较关心的,其他的自行参考官方Release Note (例如Percona对tokudb的支持应该是很多人关注的) Backup Locks 首先要提的是新特性 Backup Locks ,看起来是用来代替备份时臭名昭著的flush table with read lock 。主要增加了三个新的语法: LOCK TABLES FOR BACKUP //使用一种新的MDL锁来阻塞对非事务表的DML以及对所有表的DDL,但不阻塞SELECT查询 LOCK BINLOG FOR BACKUP //阻止对binlog位点的更新,也就是说对于DML/DDL操作会一直进行直到需要写入binlog的阶段被阻塞 UNLOCK BINLOG  // 解除LOCK BINLOG FOR BACKUP Percona的博客上专门写了篇博客来介绍关于备份加锁的历史发展以及对该特性的介绍,有兴趣的可以看看,另外也提到了Mariadb对备份的改进(将被include到下一个版本的Percona Server中) 另外Facebook很早就写了个补丁来绕过ftwrl,具体做法就是增加了新的语法,能够开启一个read view的同时返回当前与read view一致的binlog位点,但只适用于所有的表都是Innodb引擎; 具体的更改可以参考文档 及代码 LRU manager thread 使用新的独立后台线程来刷buffer pool的LRU链表,将这部分工作负担从page cleaner线程剥离。实际上就是直接转移刷LRU的代码到独立线程了, 实际从之前Percona的版本来看,都是在不断的强化后台线程,让用户线程少参与到刷脏/checkpoint这类耗时操作中 具体阅读Percona blueprint 及代码 page cleaner线程对server acitve的判断 在bug#71988中,描述了一种场景,即使每秒有activity,也会去做furous flush; Percona做的修改是,只有1秒钟内innodb没有任何active,才认为实例处于inactive状态,会去做100% IO Capacticy的刷脏操作(furious flush) 题外话:当前官方版本的Innodb,定义实例是否avtive的逻辑非常简单,做一个简单的DML,都会认为实例处于活跃状态,曾经观察到负载停止,而innodb 刷脏页的数据流量呈现出非常巨大的波动状态,结果发现是监控程序每秒做一次DML导致的(具体可以看我之前report的bug#69174) 修复5.6.16的一个性能退化bug […]