iDB是如何运转的 一

郑昀 建立于2015/12/2 最后更新于2015/12/4 html

关键词:数据库,MySQL,自动化运维,DDL,DML,SQL审核,备份,回滚,Inception,osc mysql


  每一个大型互联网公司都有一个数据库自动化运维系统,好比 Qunar 有 Inception(已开源),美团也有,赶集网的3个 DBA 开发了一个变动自助发布系统,淘宝和新浪呢都叫 iDB,腾讯互动娱乐团队有个 TMySQL。 git

  你们都作这件事,必定是由于当数据量大到必定程度,数据重要到必定程度时,online schema change 和刷库不容有失,第一解决锁表问题,不能影响线上业务,第二搞定操做回滚问题,第三解救 DBA 于倒悬。咱们的实现请参考《#研发解决方案#iDB-数据库自动化运维平台》。 github

 

0x00,普通DBA和文艺DBA怎么作SQL审核

不管是 DDL 操做,仍是数据订正(也被称为 DML 操做),都涉及 SQL 审核、预执行和数据备份及回滚。 sql

 

1,普通 DBA 青年的作法是: 数据库

  1. Dev 或 CM 给 DBA 发执行脚本,
  2. DBA 肉眼审核,
    • 语法错误/语义错误/不符合规范/……
  3. 驳回,修改,审核,再驳回,……,经过,
  4. DBA 执行前作一次全表备份,
    • 援引 Inception 文档的原话:
    • 备份是必要的,由于语句在没有执行时,都是想不到它影响会有多大,通常是不须要,而须要时,才知道备份是多么的重要,这也正是应了一句谚语:“书到用时方恨少,事非通过不知难。”,但这个工做也很让人为难,应该备份全表呢?仍是把影响的查出来备份呢?DBA在这个时候确定是不肯意这样作的,但万一出问题怎么办?都懂得,不说了。』
  5. 执行,
  6. Dev 或 QA 检查,
  7. 收兵,或许有问题,则备份还原。

 

2,稍微文艺一些的 DBA 青年的作法是: 服务器

  1. Dev 或 CM 登陆自动化运维系统,提交 SQL 脚本,
  2. SQL 审核组件对脚本自动审核,检查语法,检查规范,
  3. DBA 点击预执行,脚本在测试数据库上 explain 或直接执行,得到第一手数据,
    • 影响行数,索引使用状况
    • 预估执行时间
  4. DBA 确认无误后,审核经过,系统按时在生产库上执行,执行前系统将生产库数据备份。

或者援引 Inception 文档里的这张图示意: 架构

Inception的架构

图1 Inception的架构 运维

 

0x01,预执行库如何实操

咱们云纵对 iDB 的设想是,当审核 DDL 操做时,环境中部署一个预执行库。当 iDB 上要作预执行时,iDB 程序调用命令行暂停预执行库的同步,等预执行回滚以后恢复同步,避免由于表结构变化而同步中止。预执行库不须要配置为 blackhole,由于咱们须要真实数据来得到执行耗时,来决定咱们应以什么策略在线上自动执行。 工具

 

下面展现一下预执行时审核详情页上点击”生成执行明细“按钮的效果:

审核详情页

 

咱们能够在这里选一下“执行方式”,共有三种可选:

  • nobinlog:适合咱们的 Cobar 库,合并库和主站库。先执行从库,再执行主库。从库执行以后,会给30分钟时间确认是否执行主库。
  • binlog:非 Cobar 库操做。
  • osc:对应于 MySQL 的在线 schema 修改工具 pt-online-schema-change。它先建立一个 tmp 表做为原表导数据的临时表,而后在原表上创建三个触发器,对应 Insert、Update、Delete 三种操做,再拷贝原表数据到临时表中,Rename 原表为 old 表,再把临时表 Rename 为原表,最后清理以上过程当中再也不使用的数据,如 old 表。它强调的是”在线更改表结构“,适合于大表。咱们看一下 Inception 怎么作的:Inception 有一个设置项 inception_osc_min_table_size,默认为 16MB,表示表空间占用大于 16MB 时自动选择 osc 方式执行。

 

0x02,Inception 对备份/回滚服务器的特殊处理

Inception 在作 DML 操做时,会将全部当前语句修改的行备份下来,存储到一个指定的库中。Qunar 在这里有一些特殊设计,值得借鉴。

下面文字搬运自他们的文档:

备份数据在备份机器的存储,是与线上被修改库一对一的。但由于机器多(线上机器有不少)对一(备份机器只有一台),因此为了防止库名的冲突,备份机器的库名组成是由线上机器的 IP 地址的点换成下划线,再加上端口号,再加上库名三部分,这三部分也是经过下划线链接起来的。例如:

192_168_1_1_3310_inceptiondb

一个备份库,里面的表与对应线上表都是一一对应的,也就是说线上库 inceptiondb 中有什么表,在备份库 192_168_1_1_3310_inceptiondb 中就有什么表,表名也彻底相同,不一样的只是表中的列不一样而已,它是用来存储全部对这个表修改的回滚语句的,对应的表包括的列主要有下面两个:

rollback_statement text:这个列存储的是针对当前这个表的某一行被修改后,生成的这行修改的回滚语句。由于 binlog 是 Row 模式的,因此不论是什么语句,产生的回滚语句都是针对一行的,同时有可能一条语句的修改影响了多行,那么这里就会有多个回滚语句,但对应的是同一个 SQL 语句。对应关于经过下面的列来关联起来。

opid_time varchar(50):这个列存储的是的被执行的 SQL 语句在执行时的一个序列号,这个序列号由三部分组成:timestamp(int 值,是语句被执行的时间点),线上服务器执行时所产生的 thread_id,当前这条语句在全部被执行的语句块中的一个序号。产生结果相似下面的样子:1413347135_136_3,针对同一个语句影响多行的状况,那么所产生的多行数据中,这个列的值都是相同的,这样就能够找到一条语句对应的全部被影响数据的回滚语句。

因而线上库表结果与备份库表结构的对应关系为:

Inception的备份服务器

图2 Inception的备份服务器

 

-未完待续-

参考资源:

1,Inception使用规范及说明文档

2,2014,isadba,pt-online-schema-change工具文艺用法;

3,2014,博客园-王滔,mysql在线修改表结构大数据表的风险与解决办法概括

4,2011,杨挺,OSC 实现原理剖析

5,2015,郑昀,#研发解决方案#iDB-数据库自动化运维平台