浏览了下webscalesql 的代码。目前包含的62个commit分类如下。
目前还没有能够体现”webscale”特征的代码,不过从roadmap上看,fb回头会继续把一些大动作加进来,可以期待。
本文先简要说明一下当前分支中一些有趣的代码。
关于代码洁癖
Steaphan Greene (@fb)同学的代码洁癖从多达二十几个关于testcase和编译参数调整的commit里面可见一斑。这注定webscalesql分支会是一个够干净的分支。从照片上如此粗旷的汉子真是看不出来。
其中如 “去掉cmake中的-DWITH_DEBUG参数”这样的commit确实大块人心,原来那些重复的又可能自相矛盾的编译参数真是令人捉急。
gcc编译warning这种问题,大概很多公司的源码开发人员的原则是“不增加新的warning”,使用者估计都直接无视了。这里也有一些修复。
还有像把yacc.yy中的YYTHD改成thd这样的“脏活累活”,“去掉一些errorlog中引号和内容之间的空”。恩,反正点赞吧。
值得一提的是3a5b1e7跟一个骨灰级(2006年)的bug有关。当时glibc有个bug导致可能会crash,mysqld代码中做了特殊处理,作者特别说明,半年后glibc发了新版本就可以删除这些代码。结果到现在代码还在。我只是好奇他们是怎么想起来这个的-_-
bug修复类
1、7a0d05ce 是为了修复2012年就发现的一个bug。原始作者笔误导致在如下操作序列下,
create database BaR collate ascii_bin;
create database Bar collate utf8_unicode_ci;
use BaR;
create table f(i int);
show create table f;
结果为
CREATE TABLE f
( i
int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
窃以为这个也许是webscalesql出手的一个原因----官方有时候响应略慢,其实有效代码只有三行。
2、从5.5+开始MySQL默认的SQL_MODE计算unsigned时不做类型转换,因此下列操作会报错
create table tb(c int unsigned);
insert into tb values(1);
select c-2 from tb;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(test2.tb.c-2)’
可以通过设置sql_mode=NO_UNSIGNED_SUBTRACTION来实现。但是由于这个判断只对减法有效,因此会看到如下怪怪的结果。
set sql_mode=NO_UNSIGNED_SUBTRACTION;
select c-2 from tb;
select c+(-2) from tb;
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in ‘(test2
.tb
.c
+ -(2))’
7e2d1b 这个提交把这个判断移到减法和加法两个实现类的父类里面,使得一起生效。OO之美。
由于历史原因5.1的在sql_mode为空的时候默认是不作越界判断。这就导致在statement格式下,且主库是5.1,备库是5.6的时候,出现类似 insert … (select c-2 from tb)这样的语句的时候,主备同步停止。这个commit顺便修复了这种情况。
这个commit也说明,先不要管“够不够general”,先把patch亮出来,需者自取。貌似是现在webscalesql的主要思想之一。
feature 类
1、 超级read_only. 顾名思义就是对super权限用户,也限定为read_only,不能DDL或DML。这个只是防止误操作,因为super用户有权限关掉这个全局变量。
2、 innodb_max_dirty_pages_pct 允许设置为小数。这个只能说需者自取。除非真的有必要,否则75%和76%的区别都感觉不出来,大概很少人关心75.03%和75.04%的区别。
3、 新增的 idle_flush_pct 这个参数有点意思。为了提高高峰期的性能,InnoDB会趁着DB空闲的时候多刷点脏。现在flash设备成标配了,随机读写已经不是洪水猛兽,于是兄弟们开始怜香惜玉,“刷太狠狠影响flash设备的寿命,所以要慢慢来”。
4、 5.6以后有单独线程专门做page_cleaner操作。这个操作的判断仍然沿袭传统,会依据“当前系统忙不忙”来决定行为。但由于“忙不忙”这个判断判断的是有没有新请求,真是要多不准有多不准,所以干脆这里无视他。
5、 flush_list 和 lru_list 这两个列表每次遍历都从头或从尾来,这次加了指针,可以从上次完成的位置继续。41445e直接port from Oracle。
6、 94de54 mysqld_safe上增加参数支持numa绑定参数和清OS pagecache。与时俱进。
7、 2b7cb9 允许设置毫秒级别的超时时间。如今都是各种跨机房、异地方案,设置为零点几的需求大概不会强烈。
性能相关类
1、 semi-sync静态编译,恩,其实插件这种方式可能对跨版本移植有点好处,但是对于运维和性能来说,还是静态编译好吧~
2、 327702这个commit略有意思。若一个索引中包含前缀索引,在取值的时候会回表。从大处着眼就是能不能用上covering index?可以的就都不回表,不行就都回表。Steaphan同学觉得,对于每一行都可以再多做一次判断。如果这一行我们需要的信息从索引就能得到,就不需要回表,注意这个是对行级别的判断。
典型场景对于一些长度变化较大,又设置了前缀索引的场景(比如商品描述),那些实际内容较短的行,减少一次回表读操作。
由于每一行都要做这个判断,这个收益就跟场景有关了。
这个patch还能再稍微改进一下。对于每一行,都要按列依次判断,全部满足条件的才能节省回表操作。在对行里面的每一列做判断之前,可以先做个简单的判断,“如果需要取的列数目大于索引的列数目,则说明必须回表”,尤其对于喜闻乐见的”select *”这种写法,能减少cpu消耗。
3、 perfSchema这个插件被认为“turned out to have too much overhead to be worth it”,默认不包含,除非cmake时显式指定 -DWITH_PERFSCHEMA_STORAGE_ENGINE。个人测试出来差别5%。也许增加一个动态开关是一种权衡。
4、 bce9eddc1d这个commit的作用是把一处memcmp改成strncmp,目的仅仅是因为strncmp会在’\0’截断。
总之,期待后续代码吧。
1ba2531 |
非功能修改,把yacc.yy中的YYTHD改成thd |
2b7cb91 |
允许设置毫秒级别的超时时间,三个动作 reads, writes, and connects |
f3f3a69 |
修改自动化测试框架脚本,便于在集成环境上跑 |
94de545 |
mysqld_safe上增加参数支持numa绑定参数和清OS pagecache。在linux 2.6.23以上版本,BP申请时增加OS_MAP_POPULATE参数 |
41445e3 |
在BP上增加两个指针,flush_hp和lru_hp分别遍历flush_list和lru_list。这样每次遍历可以从上次完成的点继续,减少扫描。(port from Oracle)buf_flush_batch返回的值可能是淘汰页数或刷脏页数,修改成用一个std::pair分别存储这两个值。 |
5846095 |
buf_flush_LRU_tail 无视server的activity。主要也是因为这个activety的判断很不准。 |
9788a8c |
增加一个参数 idle_flush_pct 控制空闲期间的刷脏页速度。为了减少刷写的次数,保护flush盘的寿命 |
625a677 |
允许 innodb_max_dirty_pages_pct 设置为小数 |
83029a8 |
超级read_only。就是超级用户也被read_only的意思。但super可以修改这个配置值,因此只是用于防止误操作。 |
3277028 |
性能优化。若索引中包含前缀索引字段,但查询条件中的对应字段传入值短于前缀索引的长度,则使用覆盖索引,不回表。即按行判断是否需要回表。注意长度必须-1 |
233a66a |
改用原子操作更新stat值,保证单个值原子 |
36d4a98 |
静态编译semi-sync |
85b2e40 |
mtr结构体中新增一个trx指针指向当前事务,暂时没有发现在哪里有使用。 |
961b3b0 |
把fil_node_t、fil_space_t 和 fil_system_t 的声明从fil0fil.cc转移到fil0fil.h |
3f0c8ca |
testcase修复。并且默认关掉 perfschema |
26c9c41 |
性能优化。innodb启动时,若recv_needed_recovery为false,则不需要将所有的bp脏页刷到磁盘,能够加快启动速度 |
71ecc91 |
修复测试集 innodb_stress.* |
3228874 |
在net_write_buff开始前判断内容是否为空,以防空包导致crash。 |
7e2d1b2 |
两处改动,1、把fix_length_and_dec从Item_func_minus提到父类Item_func_additive_op中。没有case不好理解,已经补上。2、若从库设置了global.sql_mode=NO_UNSIGNED_SUBTRACTION,则sql_thread继承此模式(历史原因5.1不需要设置NO_UNSIGNED_SUBTRACTION)。第二部分对RBR无影响。 |
3a5b1e7 |
挖坟贴,2006年由于glibc的一个bug,mysqld里面引入了一段geek代码,后来glibc的bug修复了,代码没删,这次删。 |
70cd384 |
修复一个主备同步的bug,打开压缩协议的时候不会覆盖其他flag |
7a0d05c |
修复一个两年前提的老bug(#64347)。其实改动很小,也许webscalesql就是为了处理这些”顽疾“? |
2fed584 |
修改一批perfschema.* 的testcase |
302ba4c |
修改testcse, show processlist相关。 |
bb1a206 |
修改testcase,把两个路径变量从"改成' |
4e4fdff |
修改testcase,使得打开perfschema模式下一些profiling相关的testcase能正常工作 |
bcd252e |
修改testcase,限定innodb.innodb-log-file-size-1只在16k page大小下测试 |
61c1222 |
修改重连时间为5分钟防止debug模式下测试失败 |
e9d5641 |
给test case large_tests.alter_table |
34af910 |
修改一批测试用例 perfschema.* |
055c753 |
修改parts.suite.opt, 初始化这个case的参数 |
9f093b2 |
修改testcase wl6443_deprecation |
32e49b4 |
修改mtr脚本,去掉loose-skip-innodb-use-native-aio硬编码 |
28e7063 |
修改 innodb.innodb这个测试用例 |
762573d |
处理valgrind模式下的warning (sendmmsg) |
1bc3747 |
去掉一些errorlog中引号和内容之间的空格 |
bce9edd |
把一处memcmp改成strncmp |
8a9b8a8 |
设置三个局部变量的初始值 |
094187c |
增加了一些边界判断,不是bug,只是gcc不报warning |
719dae7 |
修改InnoDB中多处没有判断返回值的fwrite,改为在debug模式下增加判断并输出错误信息 |
b13a919 |
增加 DBUG_ONLY定义,去掉编译器 unused warning |
361e3b8 |
调整编译参数 |
c261c31 |
调整编译参数,强制要求编译使用 libreadline |
723078a |
调整编译参数 |
0ccbee0 |
调整编译参数 |
46a8c47 |
去掉cmake中的-DWITH_DEBUG参数 |
50ac89d |
删除不必要的代码 |
68f68ed |
一些便于FB和webscalesql审核和测试的脚本 |
5e76a2f |
Imported mysql-5.6.17 |
06d3640 |
Imported mysql-5.6.16 |
dad2a3c |
Imported mysql-5.6.15 |
7726877 |
Imported mysql-5.6.14 |
8461ad7 |
Imported mysql-5.6.13 |
da1e6d6 |
Imported mysql-5.6.12 |
f81edab |
Imported mysql-5.6.11 |
9516471 |
Imported mysql-5.6.10 |
3c45457 |
Imported mysql-5.6.4-m7 |
d282970 |
Imported mysql-5.6.8-rc |
e49b3ad |
Imported mysql-5.6.7-rc |
64b1ebb |
Imported mysql-5.6.6-m9 |
7d177f2 |
Imported mysql-5.6.5-m8 |
8a0ec69 |
Imported mysql-5.6.4-m7 |