本文主要对goInception工具做一些简单介绍,并举例说明其主要做什么。
介绍
goInception是一个集审核、执行、备份及生成回滚语句于一身的MySQL运维工具, 通过对执行SQL的语法解析,返回基于自定义规则的审核结果,并提供执行和备份及生成回滚语句的功能。
goInception基于TiDB的语法解析器,和业内有名的inpcetion审核工具重构。
面向读者:该文主要面向于后端开发、DBA或运维小伙伴,通过举例说明goInception大概做了哪些事,关于安装和使用等均可以查看 使用文档 或 github项目首页。另外,除安装以外,现在很多inception相关的资料和文章等,均可查阅,很多都是通用的。
架构图:(摘自inception)
goInception类似于mysql服务,可以连接到服务端口,执行SQL语句。 接下来通过一个示例来说明goInception具体做了哪些操作。
审核示例
在调用goInception时,需要指定要访问的生产库地址,所以需要一种特殊语法形式, goInception延用inception的使用方式,在审核的sql开始前添加注释来指定远端服务器,并在sql的前后添加特殊标识以区分待审核语句,示例如下:
/*--host=127.0.0.1;--port=3306;--user=xxx;--password=xxx;--check=0;*/
inception_magic_start;
use db;
一个或多个sql,支持大多数DDL和DML语法;
inception_magic_commit;
复制代码
各选项说明
参数 | 默认值 | 数据类型 | 说明 |
---|---|---|---|
host | '' | string | 线上数据库IP地址 |
port | 0 | int | 线上数据库端口 |
user | '' | string | 线上数据库用户名 |
password | '' | string | 线上数据库密码 |
check | false | bool | 开启审核功能 |
execute | false | bool | 开启执行功能 |
backup | false | bool | 开启备份功能,仅在执行时生效 |
ignore_warnings | false | bool | 是否忽略警告,仅在执行时生效。该参数控制有警告时是继续执行还是中止 |
要审核的语句:
create table dbtest.table1(
id int unsigned auto_increment primary key,
name varchar(20)
) engine = innodb default character set utf8;
insert into dbtest.table1 values(1,'aaa'),(2,'bbb');
复制代码
那调用时可以变为如下形式:
/*--host=127.0.0.1;--port=3306;--user=xxx;--password=xxx;--execute=1;--backup=1;--ignore_warnings=1;*/
inception_magic_start;
use dbtest;
create table table1(
id int unsigned auto_increment primary key,
name varchar(20)
) engine = innodb default character set utf8;
insert into table1 values(1,'aaa'),(2,'bbb');
inception_magic_commit;
复制代码
其中,
- 为了方便,可以通过use切换数据库,上下文自动保持该数据库
- 为讲述更多涉及的功能,我们开启了执行和备份参数,此时仍会先进行审核,只有在审核通过之后才会真正执行
goInception内部会进行三个阶段的操作,分别是审核阶段,执行阶段和备份阶段,接下来逐一讲解。
审核阶段
- goInception在收到sql语句后,先会解析注释中的远程数据库配置,并建立连接
- 如果开启了备份功能,则会检查binlog日志是否开启(log_bin=ON)
- 判断语法开始位置,必须以
inception_magic_start
语法开始 - 开始逐行解析,并进行语法树解析,失败时返回
- 解析到
use dbtest
,会通过show databases
判断数据库是否存在 - 解析到
create table table1...
,接下来进行建表的校验- 判断库、表是否存在
- 表名、列名长度校验,关键字校验
- 存储引擎校验,表/列的字符集和注释校验
- 列名重复性校验
- 自增列个数校验,自增列列名校验,起始值校验,建议添加unsigned属性
- 外键校验,分区表校验
- 列类型校验,部分类型有设置开关,开启后才能使用,char也会建议改为varchar类型
- 默认值校验,日期格式校验
- not null约束校验
- 索引名校验,前缀校验,长度校验,表索引个数,索引列数,索引列重复性校验
- 上面列出了大部分会进行的逻辑校验,顺序上和实际顺序会有差异,这些审核规则大都有开关设置,详细参数可查看 审核规则
- 解析到
insert into table1 ...
,接下来进行insert的校验- 判断表、列是否存在
- 判断insert列数和值列表是否一致
- 检查不为null的列,是否指定了null
- 检查列是否重复指定
- 如果使用了insert select语法,会审核select语法是否有不存在的表或列
- 解析到
inception_magic_commit
,判断所有的审核是否成功,如果有错误时,直接返回,而有警告时会判断是否开启了忽略警告的参数,以判断是否进行下一步
执行阶段
- 只有在审核成功时(或有警告但启用了忽略),才会进入执行阶段
- 有些语法是不会执行的,其在审核阶段已经执行,比如
desc table1;
语法
接下来继续说明执行阶段:
- 在执行阶段,DDL语句和DML语句走不同的逻辑,其中DML通过binlog解析实现回滚,而DDL语句根据语法树规则直接生成逆向SQL即可
- DML:在开始执行和执行完成时,记录binlog位置
- DDL和DML:开始执行,并在执行失败时记录失败原因并结束执行操作,成功时记录受影响行数
- 执行中可能想要执行KILL以中止执行,可查看 KILL操作说明
备份阶段
备份功能的详细说明请查看 备份功能
- 到达备份阶段有两种情况,可能执行成功也可能部分成功了,此时会进行判断,只备份执行成功的语句
- DDL的备份是保存自动生成的逆向SQL语句
- DML的备份是根据执行前后记录的binlog位置和线程号,模拟从库的形式获取binlog信息,并做事件解析
- 解析binlog日志要求binlog格式必须为ROW模式,该模式也会有备份前检查和自动设置,因此可能需要
SUPER
权限 - 在解析过binlog后,会生成逆向的SQL语句,并异步批量写入备份库
- 在回滚语句写入完成后,所有操作执行完成,并返回结果给客户端。
交流与反馈
欢迎通过Github Issues提交问题报告与建议
QQ群: 499262190
微信: