TMySQL核心技术内幕


TMySQL核心技术内幕 vinchen(陈福荣), Tencent 2013.10.26 自我介绍 • 陈福荣(vinchen),TMySQL核心开发及项目主要负责人 • Email:vinchen13@vip.qq.com • QQ:350519744 • 微博:t.qq.com/keanusneo • weibo.com/keanusneo • 博客:vinchen.cnblogs.com • 工作经历: – 2010.1~2011.11:上海达梦数据库,DM7内核 – 2011.12至今:腾讯,DB高可用、TMySQL 目录 • TMySQL介绍 • TMySQL版本历史 • 在线加字段 • BLOB列压缩 • 总结与展望 TMySQL介绍 • 背景 –MySQL海量数据运营 – 越来越多的挑战(DDL、数据恢复、存储空间利用率) – 团队对MySQL把控越来越强 • TMySQL是为了适应互娱事业群业务发展需求,由互娱 DBA团队定制的一个MySQL分支版本 – Based MySQL 5.5.24 – 首创的新特性 – 学习与借鉴各类优秀patch – 反馈开源社区 TMySQL版本历史 2012.09 A TMySQL 1.0 首个Release版本,支持 InnoDB的在线加字段操作 2013.02 C TMySQL 1.2 集成Google tcmalloc组件,降低 MySQL大量分区表内存碎片过多 的问题 2013.10 E TMySQL 1.4 InnoDB BLOB字段压缩,Binlog 并行恢复,诊断视图加强 B TMySQL 1.1 支持分区表的在线加字 段,TMySQL的安装量 大幅增加 2012.12 2013.06 D TMySQL 1.3 MySQL 5.0原地升级,覆盖 更多核心业务DB 在线加字段 • 背景 – 相对频繁的版本变更 – 游戏角色属性增加 – 公告-停服 alter table auction_main add column socket1 int(10) unsigned NOT NULL default ‘0’; 3小时! 在线加字段 • MySQL的加字段过程 – 1. 目标表T1上字典锁(SHARED_NO_WRITE),阻塞所有写操作 – 2. 创建跟目标表T1同构的临时表S1(含新增字段, frm+ibd) – 3. 拷贝数据:拷贝目标表数据到临时表中,新增字段内容要么为NULL, 要么为默认值(此过程可能是漫长的过程,跟表数据量有关) – 4. 目标表T1的字典锁升级为排它锁,所有关于T1表的所有读写操作被阻塞 – 5. 目标表T1重命名为临时表S2 – 6. 临时表S1重命名为临时表T1 – 7. 删除表S2 – 8. 释放表T1的字典锁 在线加字段 • 解决思路: – 取消拷贝数据的过程(最优) – 拷贝数据过程不锁表 • 业界解决方案 Fackbook OSC 5.6 OSC Oracle 实现原理 触发器+change log 内部记录change log 存储格式支持 实现效果 不锁表 不需拷贝数据 优点 通用,支持多种DDL在线操作 快速,副作用少 缺点 性能有一定损失,加字段时间长 (CPU/IO负载增加20%, 4.8G+400insert/s) 不够通用 一定技术风险(存 储格式支持) 在线加字段 数据存取 数据缓存 索引 事务特性(故 障恢复) SQL解析 查询优化 查询执行 数据库对象 • InnoDB数据组织 – B+树 • 页内数据是按索引键排序的 • 页面从左到右有序存储 – 叶子节点存数据 – 非叶子节点仅存索引键 在线加字段 ... ... 在线加字段 • GCS存储格式 – TMySQL为在线加字段功能新增的行格式GCS – 默认行格式 – 原理:扩展原Compact格式,增加1~2字节控制信息 Barracuda File Format Antelope File Format Compact Redundant Dynamic Compressed GCS 在线加字段 • Compact格式(聚集索引) – 记录体:字段内容 – 记录头 • Record Extra Bytes:是固定的5字节,表示记录的额外信息。 • Nullable Bitmap:记录可空位图,使用1个bit来表示一个可空字段 是否为NULL。 • non-NULL Variable-Length Array:非空变长字段数组,表示非空 变长字段(如varchar、varbinary)在该行的长度。 主键 事务ID (6字节)记录头 记录指针 Roll Ptr (7字节) 主键外的其他非空字段 Nullable Bitmapnon-NULL Variable-Length Array Record Extra Bytes • Compact格式的特点: – 定义顺序与存储顺序一致(除主键) – NULL字段不占用存储空间 • 加字段记录改变: – 允许为NULL并不指定默认值 • Alter table t1 add column d1 int; – 不允许为NULL并指定默认值 • Alter table t1 add column d2 varchar(20) not null default ‘abc’; 在线加字段 增加1个bit 增加一项,视乎所加字段是否变长字段 在线加字段 • GCS格式改造 – 记录体:与Compact一致 – 记录头:增加Field Count标记 • 表示插入该行时表的字段个数,占用1~2个字节(如果字段数超过 127,就是用2字节) Nullable Bitmapnon-NULL Variable-Length Array Record Extra BytesField Count 主键 事务ID (6字节)记录头 记录指针 Roll Ptr (7字节) 主键外的其他非空字段 在线加字段 • GCS记录解析 – 假设某GCS记录的Field Count记录为x,表当前字段数为y,那么 x <= y总是成立的。 – GCS记录解析过程: • 如果x==y,按原来的方式解析 • 如果x < y,那么记录必定是在最后一次快速加字段前就生成,那么 最后y - x个字段必为NULL或默认值。 – 如果该字段是允许为NULL,则为NULL。 – 如果该字段不允许为NULL,则为默认值。 在线加字段 • GCS存储格式-约束 – 如果所加字段是允许为NULL,并指定默认值,会与上述判断冲突, 因此不支持该类型在线加字段 • 如 Alter table add column int default 0; • Oracle 11g有同样的约束 – 在线加字段不支持指定before/after • GCS存储格式-一个优化 – GCS行格式新增的Field Count是为了表示记录的字段数,如果表 不执行加字段操作,该部分其实是不起作用的。 – GCS表第一次在线加字段之后插入的记录才使用Field Count记录 当前字段数。 • 存储效率更高 • 实现Compact->GCS的快速转换(Online操作) – Alter table tbl_compact row_format=GCS; • 迁移成本大大降低 在线加字段 在第一次加字段前,Field Count总等于表的字段数 第一次加字段前的Field Count保存在数据字典中 在线加字段 • 其他关键改造 – 元数据 • 新增默认值系统表sys_added_cols_default – redo • redo是所有页面操作的物理重做日志,为了防止系统异常是脏页未 刷盘的数据丢失,用于故障恢复。 • 记录操作redo格式一般为:数据字典+记录内容 • 修改GCS表redo记录的数据字典部分 – undo • undo是记录事务中未提交记录的原值,用于事务回滚和故障恢复 • 扩展undo支持表示默认值 • 扩展回滚操作可能生成行外字段的逻辑 create table sys_added_col_default( tableid bigint, pos int, def_val binary(65535), def_val_len int, primary key (tableid, pos) ); • DML操作对GCS格式支持 – 更新 • 更新GCS新增字段 • 更新变长字段(长度发生变化) 在线加字段 已删除记录Rec8 New Rec8 在线加字段 • MySQL加字段逻辑控制 – 1. 目标表T1上字典锁(SHARED_NO_WRITE),阻塞所有 写操作 – 2. 判断是否符合在线加字段的条件,如符合,执行步骤3, 否则按照官方拷贝数据的方式来新增字段。 – 3. 创建跟目标表T1同构的临时表frm文件S1.frm(含新增字 段) – 4. 目标表T1的字典锁升级为排它锁,所有关于T1表的所有 读写操作被阻塞 – 5. 修改T1表InnoDB内部数据字典信息,增加新字段。 – 6. 将S1.frm重命名为T1.frm – 7. 释放表T1的字典锁 • 取消拷贝数据,并且无临时表生成 在线加字段 • 现网效果 业务 DB版本 表数 分区总数 数据总量 变更耗时 业务A TMySQL 1.1 16 6896 46G 27秒 业务A MySQL 5.1.47 16 6905 43G 7664秒 业务B TMySQL 1.2 1 466 361G 30秒 业务B MySQL 5.1.47 1 466 365G 37376秒? BLOB列压缩 • 背景 – 结构体序列化存储 – 较多C/C++ NULL占位符 – 过大的BLOB会导致行外存储 • 性能会有所折扣(读取一条记录需要多次逻辑/物理读) • 存储效率降低(行外存储无法充分利用行外页面空间) – InnoDB没有针对字段提供列级压缩存储方案 • row_format=compressed是页级压缩 BLOB列压缩 • 新增压缩属性 – 建表 – 修改表 – 某业务数据,压缩前51G,压缩后7.3G,压缩率达14.3% Create table t1 ( C1 int primary key, C2 blob compressed, C3 text character set gbk compressed, C4 blob ) engine = innodb row_format=GCS Alter table t1 change c4 c4 blob compressed. BLOB列压缩 • 压缩格式 – 适配GCS行格式 – 字段内容变为 • 是否压缩:首字节最高bit,若为1表示已压缩;若为0表示不压缩, 同时解压后长度为空。 • 多种压缩算法:首字节5~6 bit用于可表示4种不同压缩算法,目前只 支持zlib(0) • 其他特性扩充预留 – 支持行外存储 BLOB列压缩 • 元数据 – frm – InnoDB系统表SYS_COLUMNS • 压缩/解压操作 – handler接口 – MySQL/InnoDB数据交换接口 • row_mysql_store_col_in_innobase_format • row_sel_store_mysql_rec • innobase_rec_to_mysql BLOB列压缩 • 导入/导出优化 – 问题 • mysqldump导出默认解压 • 导入默认压缩 – SQL_COMPRESSED标记 – 导入/导出性能提高3~4倍,IO/CPU负载明显降低 Select SQL_COMPRESSED * FROM t1; Insert SQL_COMPRESSED INTO T1 VALUES(…); BLOB列压缩 • 对比测试 原始数据 row_format= compressed BLOB列压缩 数据量 51G 24G 7.1G QPS 1174 1524 3994 IO 100% 100% 30% CPU 15% 45% 50% 总结与展望 • TMySQL目前已在3000+实例上稳定运营 – 加字段变更:76小时 vs 32小时 • 新功能规划 – DB云化方案(海量数据处理,数据水平扩展) – Percona/MariaDB/5.6新特性学习 • 开源 – Binary公布 ( https://github.com/TencentDBA/TMySQL-Binary) – 源码开放(https://github.com/TencentDBA/TMySQL) – 贡献社区 • Feature • Bug Fixed and reported(6个) 谢谢大家! Questions? QQ: 350519744 Email: vinchen13@vip.qq.com 团队Github: github.com/TencentDBA
还剩29页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

mulonghao

贡献于2016-07-30

下载需要 10 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf