├── README.md ├── docs ├── backup.md ├── bugs.md ├── chapter1.md ├── chapter2.md ├── command.md ├── extras.md ├── inception.md ├── inception_images │ ├── architecture.png │ ├── backup.png │ ├── backup2.png │ ├── noauto.png │ ├── onevar.png │ ├── osc.png │ ├── osccomplete.png │ ├── oscset.png │ ├── processlist.png │ ├── queryprint.png │ ├── queryprintresult.png │ ├── semiauto.png │ ├── showerr.png │ ├── statistic.png │ ├── users.png │ └── variables.png ├── index.md ├── install.md ├── option.md ├── osc.md ├── queryprint.md ├── release.md ├── requires.md ├── results.md ├── rules.md ├── source.md ├── statistic.md ├── usage.md ├── users.md └── variables.md └── mkdocs.yml /README.md: -------------------------------------------------------------------------------- 1 | # Inception简介 2 | **Inception** 是一个集审核、执行、备份及生成回滚语句于一身的MySQL自动化运维工具。由[去哪儿网 http://www.qunar.com](http://www.qunar.com)共享、开源而来。 3 | 4 | 本项目是 **Inception** 的手册部分。 5 | 6 | 项目地址:[Inception](https://github.com/mysql-inception/inception) 7 | 8 | ## 在线文档 9 | 10 | [Inception使用规范及说明文档](http://mysql-inception.github.io/inception-document/) 11 | 12 | ## 目录 13 | 14 | - [Inception使用规范及说明文档](./docs/index.md) 15 | - [Inception序](./docs/chapter1.md) 16 | - [1. Inception 是如何诞生的](./docs/source.md) 17 | - [2. Inception 总述及体系结构](./docs/inception.md) 18 | - [3. Inception 安装说明](./docs/install.md) 19 | - [4. Inception 使用方法](./docs/usage.md) 20 | - [5. Inception 支持选项及意义](./docs/option.md) 21 | - [6. Inception 备份功能说明](./docs/backup.md) 22 | - [7. Inception 审核规范及原则](./docs/rules.md) 23 | - [8. Inception所支持的参数变量](./docs/variables.md) 24 | - [9. Inception结果集](./docs/results.md) 25 | - [10. Inception命令集](./docs/command.md) 26 | - [11. Inception 对线上配置需求](./docs/requires.md) 27 | - [12. Inception 额外功能说明](./docs/extras.md) 28 | - [13. Inception 对OSC的支持](./docs/osc.md) 29 | - [14. Inception 的统计功能](./docs/statistic.md) 30 | - [15. Inception 语法树打印](./docs/queryprint.md) 31 | - [16. Inception 发布日志](./docs/release.md) 32 | -------------------------------------------------------------------------------- /docs/backup.md: -------------------------------------------------------------------------------- 1 | #Inception 备份功能说明 2 | 上面已经提到,Inception在做DML操作时,具有备份功能,它会将所有当前语句修改的行备份下来,存储到一个指定的库中,这些库的指定需要通过几个参数,它们分别是: 3 | 4 | * `inception_remote_backup_host //远程备份库的host` 5 | * `inception_remote_backup_port //远程备份库的port` 6 | * `inception_remote_system_user //远程备份库的一个用户` 7 | * `inception_remote_system_password //上面用户的密码` 8 | 9 | 这些参数可以直接在命令行中指定,也可以用**--defaults-file**指定一个**my.cnf**文件,一经指定,再不能更改,除非将服务器关闭,修改之后再次启动。文件中指定这几个参数的值,用法与mysql是相同的。 10 | 另外:Inception 是默认开备份功能的,为了使备份成为一个可选功能,增加一个是不是备份的参数**--disable-remote-backup**(在前面<<**Inception支持选项及意义**>>一章中已经介绍过),如果开启则不做备份操作,都是直接执行,另外还有一点,执行时被影响的表如果没有主键的话,就不会做备份了,这样更简单并且备份时间及数据都会少一点,不然回滚语句的WHERE条件就会将所有列写进去,这样会影响性能且没有太大意义,所以在WHERE条件中,只需要主键即可。 11 | 12 | 通过上面参数设置的Inception备份用户必须要具备下面的权限才能成功备份的,包括:CREATE、INSERT。CREATE权限用于创建表或者库的,INSERT权限用于插入备份数据的,其它的权限不需要(也许是暂时的)。 13 | 14 | 备份数据在备份机器的存储,是与线上被修改库一对一的。但因为机器的多(线上机器有很多)对一(备份机器只有一台),所以为了防止库名的冲突,备份机器的库名组成是由线上机器的 IP 地址的点换成下划线,再加上端口号,再加上库名三部分,这三部分也是通过下划线连接起来的。例如:`192_168_1_1_3310_inceptiondb`,下面用 inceptiondb 举例为线上库名。 15 | 16 | 针对一个备份库,里面的表与对应线上表都是一一对应的,也就是说线上库inceptiondb中有什么表,在备份库`192_168_1_1_3310_inceptiondb`中就有什么表,表名也完全相同,不同的只是表中的列不同而已,它是用来存储所有对这个表修改的回滚语句的, 对应的表包括的列主要有下面两个: 17 | **`rollback_statement text`**:这个列存储的是针对当前这个表的某一行被修改后,生成的这行修改的回滚语句。因为 binlog 是 ROW 模式的,所以不管是什么语句,产生的回滚语句都是针对一行的,同时有可能一条语句的修改影响了多行,那么这里就会有多个回滚语句,但对应的是同一个 SQL 语句。对应关于通过下面的列来关联起来。 18 | **`opid_time varchar(50)`**:这个列存储的是的被执行的 SQL 语句在执行时的一个序列号,这个序列号由三部分组成:timestamp(int 值,是语句被执行的时间点),线上服务器执行时所产生的 thread_id,当前这条语句在所有被执行的语句块中的一个序号。产生结果类似下面的样子:**1413347135_136_3**,针对同一个语句影响多行的情况,那么所产生的多行数据中,这个列的值都是相同的,这样就可以找到一条语句对应的所有被影响数据的回滚语句。 19 | 20 | 除了与原库中的表一一对应之外,每个备份库中还有另外一个表:**$\_$Inception_backup_information$\_$**,这就是表名,非常难看,主要是为了防止与原线上库中的表名发生冲突。这个表是用来存储所有对当前库操作的操作记录的,它是公用的,对线上这个库的所有表操作记录都存储在这里面,这个表的结构如下: 21 | ![](inception_images/backup.png) 22 | 23 | 而线上库表结果与备份库表结构的对应关系是: 24 | ![](inception_images/backup2.png) 25 | 26 | #各个列的解释: 27 | 28 | --------------- 29 | **opid_time**:这个列其实与上面备份表中的列 `opid_time` 是对应的,这里面存储的每一条记录对应语句块中被执行的一条 SQL 语句,opid_time 就是根据这条语句所生成的,那么一条语句有可能产生多行的影响,那么上面回滚语句表中的多行或者一行对应这个公共表的一行,这样就对上了。 30 | **start_binlog_file**:这个列从名字就可以看出,表示的是执行这条语句前 binlog 所在位置的文件名,当然这个值不一定准确,因为这是在执行语句前通过**show master status;**语句来获取的,那么在数据库并发比较高的话,这个值一般都不是准确的当前语句的Binlog开始位置,这个位置只能是这个语句产生的Binlog前面某个位置,同理下面三个位置信息也是一样。 31 | **start_binlog_pos**:这个列与上面的列对应,表示的是上面指定文件的位置信息。 32 | **end_binlog_file**:这个列表示的是执行当前语句之后,binlog 所在的文件名。 33 | **end_binlog_pos**:这个列与上面的列对应,它表示执行完成之后,binlog 在文件end_binlog_file中的偏移位置。 34 | **sql_statement**:这个列存储的是当前这个被执行的SQL 语句。 35 | **host**:表示在什么地址执行了这条语句。 36 | **dbname**:在哪个库中执行了这个语句。 37 | **tablename**:表示当前语句影响的表的表名。可以通过这个名字来对应到备份表名。 38 | **port**:与 host 对应,表示执行时数据库的端口是什么。 39 | **time**:表示当前语句的执行时间。 40 | **type**:表示操作类型,现在只支持INSERT、UPDATE、DELETE、CREATEDB、CREATETABLE、ALTERTABLE、DROPTABLE等类型。 41 | 42 | ------- 43 | 针对现在备份及回滚的实现方案,如果已经知道一个语句的执行序列,想拿到这个语句的回滚语句,要执行的 SQL 语句为: 44 | ```` 45 | select rollback_statement from 192_168_1_1_3310_inceptiondb.inception_test 46 | where opid_time =‘1413347135_136_3’; 47 | ```` 48 | 上面语句查出来的只是针对一个语句块中某一条语句的回滚语句,但是如果想要得到整个语句块的回滚语句,还需要在这基础上做二次开发,针对每条语句的回滚(包括多条回滚语句)语句的前后,加上事务,保证这个回滚是原子的,并且按照执行结果的最后一个列的倒序将回滚语句排序,这样查出来的就是完整的回滚语句。 49 | 50 | 关于 DDL 的回滚,其实是很难做得完美,因为涉及到数据的大批量更改,并且 binlog 也是语句模式的,所以很难处理,但在 Inception 中采取的策略是只处理定义,不处理数据。现在 DDL 操作的回滚只包括 CREATE TABLE 、ALTER TABLE、DROP TABLE,其它类型的操作不支持,并且也没有太大意义,在实际使用中如果有需求再考虑如何实现。 51 | 52 | 每条 DDL 语句算是一个操作,同样的,这个操作也会存储在表**$\_$Inception_backup_information$\_$**中,关于 binlog 的一些列没有实际意义,对应的 opid_time 与 DML 是相同的,而同时在被操作表中,存储了回滚语句,其中的列 opid_time与上面表中的这个列关联。一个 DDL 操作(不管其中做了多少事),对应的回滚语句也是一条语句,例如: 53 | 原来的表是这样的: 54 | ```` 55 | CREATE TABLE myinfo ( 56 | id int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', 57 | name varchar(10) NOT NULL DEFAULT 'baabb' COMMENT 'agedddd', 58 | age2 int(11) NOT NULL COMMENT 'agddd', 59 | age int(11) NOT NULL COMMENT 'age', 60 | PRIMARY KEY (id), 61 | KEY idx_name (id,name) 62 | ) ENGINE=InnoDB AUTO_INCREMENT=2150 DEFAULT CHARSET=utf8 COMMENT=’t’; 63 | ```` 64 | 65 | 要执行的 alter 表语句为: 66 | ```` 67 | alter table myinfo 68 | rename to myinfo1, 69 | add column age3 int not null comment 'age', 70 | add index idx_age2(age2), 71 | drop column age; 72 | ```` 73 | 那么产生的回滚语句为: 74 | ```` 75 | ALTER TABLE inception.myinfo1 76 | DROP COLUMN age3, 77 | DROP INDEX idx_age2, 78 | ADD COLUMN age int(11) NOT NULL COMMENT 'age', 79 | RENAME TO inception.myinfo; 80 | ```` 81 | -------------------------------------------------------------------------------- /docs/bugs.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/bugs.md -------------------------------------------------------------------------------- /docs/chapter1.md: -------------------------------------------------------------------------------- 1 | #Inception序 2 | Inception是一款自动化运维的利器,有别与现在各个公司使用的方式,使用Inception,将会给DBA带来最大的便利性,将DBA从繁冗的工作中解放出来,做一些更多的自动化工作,或者从架构方面研究如何更大程度的保证数据库的高可用等等。 3 | 本文我们主要从Inception的各个方面说明我们如何使用它,包括总体架构、安装方法、支持的参数、执行选项、结果集的说明及意义、审核规则说明、备份回滚功能及Inception对OSC的支持及Incepiton的统计功能。 4 | 本次Inception是首次亮相,其实是一个试用版本,主要是为了发现更多的问题,或者找到一些不友好的地方,以保证Inception最终尽可能的稳定,以保持最好的颜值和广大的业内朋友相见。 5 | 所以如果在使用的过程中发现任何问题,都可以通过QQ群来讨论,并且提出,我们会尽可能的为大家处理并解决。 6 | QQ群号码:185803996 7 | -------------------------------------------------------------------------------- /docs/chapter2.md: -------------------------------------------------------------------------------- 1 | #Inception实现篇 2 | 经过前面对Inception使用方面的介绍,想必现在对Inception的实现方式、工作原理等已经有了比较清楚的认识了,然而对于一些喜欢 动手的同学而言,可能他自己有比较多的想法,打算试着增加或者修改一些功能,那么此时还需要更深入的、更多的了解Inception的实现细节,那么本篇就是想讲一些Inception在实现方面的一些设计理念及想法。 3 | -------------------------------------------------------------------------------- /docs/command.md: -------------------------------------------------------------------------------- 1 | #Inception命令集语句 2 | Inception命令是一个Inception所支持的一系列命令集,为了与原MySQL的命令区分,在命令前面使用Inception这个新的关键字。 3 | 4 | 这个命令集包括的功能有:打印线上服务器的一些信息,支持所有show命令,只要在原来show命令前面加上inception即可,返回的结果集放在上面所述结果集的SQL列中,前面是当前执行的inception命令,以冒号分隔,后面接着是执行show命令得到的结果集,每行以换行符分隔,一行中的不同列的数据,以竖线“|”分隔。此外还包括上面设置或查看相关参数的三个命令,这三个命令只能通过MySQL客户端或者编程直接执行,而不需要加上数据源、标记语句等信息。因为它是对Inception本身进行操作的。 5 | 6 | 下面列举一下共包括哪几类: 7 | ###显示远程变量 8 | 这种情况,语法为`inception {MySQL支持的原生的show命令};`,比如 9 | ```` 10 | inception show tables; 11 | inception show variables like "%read_only%"; 12 | ```` 13 | 其实这个命令就是用来方便得通过Inception工具来查看线上的某些状态或者变量等信息的,返回的结果会放在后面将要介绍的<<**Inception结果集**>>中所说的结果集的SQL列中的。具体输出格式是,最前面还是输出执行的inception命令,然后以冒号分隔,冒号后面接着是执行show命令得到的结果集,每行以换行符分隔,一行中的不同列的数据,以竖线“|”分隔。 14 | 比如对于命令 15 | ```` 16 | /*--user=zhufeng;--password=xxxxxxxxxxx;--host=xxxxxxxxxx; 17 | --enable-check;--port=3456;*/ 18 | inception_magic_start; 19 | use mysql; 20 | inception show variables like "read%"; 21 | inception_magic_commit; 22 | ```` 23 | 返回结果如下: 24 | ```` 25 | qunar show variables like "read%":
 26 | read_buffer_size | 33554432
 27 | read_only | OFF
 28 | read_rnd_buffer_size | 262144 29 | ```` 30 | **注意**:因为查看远程变量,是需要连到远程数据库服务器的,所以执行时还是必须要加上前面的数据源信息的,不然在MySQL客户只支持这个语句会报错。 31 | ![](inception_images/showerr.png) 32 | 这个就是在提醒,必须要放在`inception_magic_start`及`inception_magic_commit`语句中才能执行。 33 | 34 | ###显示本地全部变量 35 | 显示本地全部变量,就是查看Inception本身所有参数的值,语法非常简单: 36 | ```` 37 | inception get variables; 38 | ```` 39 | 输出就是所有的变量,下图所示为部分变量: 40 | ![](inception_images/variables.png) 41 | **注意**,这个命令只显示Inception本身的一些参数变量的值,那么是不需要数据源信息的,所以它是可以直接在MySQL客户端执行的。 42 | ###显示本地某个变量 43 | 显示本地某个变量,和上面唯一的区别是,这只显示一个变量的值,而上面是显示全部,语法: 44 | ```` 45 | inception get variables 'variable_name'; 46 | ```` 47 | 下面是图例: 48 | ![](inception_images/onevar.png) 49 | 50 | **注意**,这个命令只显示Inception本身的一些参数变量的值,那么是不需要数据源信息的,所以它是可以直接在MySQL客户端执行的,而如果放在数据源信息中执行的话,这样的语句会被忽略,不会做任何处理。 51 | ###设置本地变量 52 | Inception不仅可以查看它的参数值,还可以通过语句动态设置某个参数的值,因为Inception的参数(除部分OSC参数,具体参见<<**Inception所支持的参数变量**>>)是全局的,并且不是会话级别的,所以它是设置之后马上生效的,而有些OSC的参数是会话的,则只影响当前执行的连接。语法为: 53 | ```` 54 | inception set [session] variables_name=value; 55 | ```` 56 | **注意**,这个命令只显示Inception本身的一些参数变量的值,那么是不需要数据源信息的,所以它是可以直接在MySQL客户端执行的,而如果放在数据源信息中执行的话,这样的语句会被忽略,不会做任何处理。 57 | 下面是图例: 58 | ![](inception_images/oscset.png) 59 | ###显示OSC执行进度 60 | 这个语句的作用是,当某一个ALTER TABLE语句正在通过Inception使用OSC执行时,可以通过这个语句来查询执行的进度度信息,语法: 61 | ```` 62 | inception get osc_percent '当前执行的SQL语句以及一些基本信息生成的SHA1哈希值'; 63 | ```` 64 | 具体的细节会在后面专门的一章<<**Inception 对OSC的支持**>>中讲述,这里只看一下图例: 65 | ![](inception_images/osc.png) 66 | 67 | 上面是正在做的,而如果语句块中有多个修改表的操作,则前面的会看到执行完成的进度信息: 68 | ![](inception_images/osccomplete.png) 69 | 70 | 71 | ###查看当前processlist 72 | inception还可以查看当前正在执行的所有线程信息,语法为: 73 | ```` 74 | inception get processlist; 75 | ```` 76 | ![](inception_images/processlist.png) 77 | 当前命令执行之后,返回的结果信息如上图所示,每一个列介绍如下: 78 | 79 | 1. id:一个简单的计数。 80 | 2. dest_user:表示当前执行语句访问数据库时所用的用户名。 81 | 3. dest_host:表示当前执行语句要访问的数据库地址。 82 | 4. dest_port:表示当前执行语句要访问的数据库的端口。 83 | 5. from_host:表示当前执行语句是从机器上发起的。 84 | 6. command:表示当前执行的是什么操作,包括CHECK(简单审核),EXECUTE(执行),SPLIT(拆分),PRINT(打印计划树),LOCAL(本地命令)。 85 | 7. state:表示在当前命令下,执行的状态是什么,状态包括INIT(初始阶段),CHECKING(正在审核),EXECUTING(正在执行),DEINIT(退出),BACKUP(正在备份)。 86 | 8. time:表示当前语句执行所用时间。 87 | 9. info:显示当前正在执行的语句。 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /docs/extras.md: -------------------------------------------------------------------------------- 1 | #Inception 额外功能说明 2 | Inception支持将一段SQL语句按照语句之间相互不影响的原则拿得DDL及DML语句分开,也就是让相同表的DDL及DML语句不能在同一个语句块中执行,这个功能的用法是通过指定另一个新的选项来实现的,这个选项为`--enable-split`,在指定这个选项之后,所有的其它选项(除指定线上地址的4个选项之外)都不起作用,只处理split选项。 3 | 而这个拆分原因是,如果在同一个块中执行,那么Inception对表的缓存结构在变化之后(因为表的修改导致),导致不能正确解析修改之前的binlog记录,这样导致备份会出问题,所以Inception采取一个简单折中的办法来处理这个问题。 4 | 这个功能的输出也是一个结果集,只是这个结果集只有3个列,分别为: 5 | 6 | * **ID**: 第一个列是序号表示当前行被分成第几个语句块,这个值是从1开始的 7 | * **sql_statement**: 第二个列表示的就是可以在一起的所有SQL语句, 都合在一起并且都以分号分开 8 | * **ddlflag**: 第三个列表示的是当前被拆之后,可以一起执行的语句中,有没有`alter/drop table`语句,如果有则输出1,否则输出0,这主要是为了防止在Inception执行这两种语句时有可能带来危险,这样输出之后,可以为上层提供更友好的选择,可以做为一个提醒。 9 | 10 | **注意**:如果第一个列返回的序号为0,那么此次结果集只会有一行,并且第二列中返回的值是出错信息,也就是说这此操作中是有错误的,具体错误可以直接看到,那么是不是有错误发生,只需要看序号值是不是为0就可以了。 11 | -------------------------------------------------------------------------------- /docs/inception.md: -------------------------------------------------------------------------------- 1 | #总述 2 | Inception是集审核、执行、回滚于一体的一个自动化运维系统,它是根据MySQL代码修改过来的,用它可以很明确的,详细的,准确的审核MySQL的SQL语句,它的工作模式和MySQL完全相同,可以直接使用MySQL客户端来连接,但不需要验证权限,它相对应用程序(上层审核流程系统等)而言,是一个服务器,在连接时需要指定服务器地址及Inception服务器的端口即可,而它相对要审核或执行的语句所对应的线上MySQL服务器来说,是一个客户端,它在内部需要实时的连接数据库服务器来获取所需要的信息,或者直接在在线上执行相应的语句及获取binlog等,Inception就是一个中间性质的服务。图1.1所示为Inception的架构。 3 | 4 | ![](inception_images/architecture.png) 5 | 6 | Inception提供的功能很丰富,首先,它可以对提交的所有语句的语法分析,如果语法有问题,都会将相应的错误信息返回给审核者。 7 | 还提供语义分析,当一个表,库,列等信息不正确或者不符合规范的时候报错,或者使用了一个不存在的对象时报错等等。 8 | 还提供了很多针对SQL规范性约束的功能,这些DBA都是可以通过系统参数来配置的。 9 | 更高级的功能是,可以辅助DBA分析一条查询语句的性能,如果没有使用索引或者某些原因导致查询很慢,都可以检查。 10 | 11 | 还提供SQL语句的执行功能,可执行的语句类型包括常用的DML及DDL语句及truncate table等操作。 12 | Inception 在执行 DML 时还提供生成回滚语句的功能,对应的操作记录及回滚语句会被存储在备份机器上面,备份机器通过配置Inception参数来指定。 13 | 14 | -------------------------------------------------------------------------------- /docs/inception_images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/architecture.png -------------------------------------------------------------------------------- /docs/inception_images/backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/backup.png -------------------------------------------------------------------------------- /docs/inception_images/backup2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/backup2.png -------------------------------------------------------------------------------- /docs/inception_images/noauto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/noauto.png -------------------------------------------------------------------------------- /docs/inception_images/onevar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/onevar.png -------------------------------------------------------------------------------- /docs/inception_images/osc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/osc.png -------------------------------------------------------------------------------- /docs/inception_images/osccomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/osccomplete.png -------------------------------------------------------------------------------- /docs/inception_images/oscset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/oscset.png -------------------------------------------------------------------------------- /docs/inception_images/processlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/processlist.png -------------------------------------------------------------------------------- /docs/inception_images/queryprint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/queryprint.png -------------------------------------------------------------------------------- /docs/inception_images/queryprintresult.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/queryprintresult.png -------------------------------------------------------------------------------- /docs/inception_images/semiauto.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/semiauto.png -------------------------------------------------------------------------------- /docs/inception_images/showerr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/showerr.png -------------------------------------------------------------------------------- /docs/inception_images/statistic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/statistic.png -------------------------------------------------------------------------------- /docs/inception_images/users.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/users.png -------------------------------------------------------------------------------- /docs/inception_images/variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cookieY/inception-document/b99ca02e4035be384afa909a2db6706075769853/docs/inception_images/variables.png -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | #关于Inception 2 | MySQL语句的审核,在业界都已经基本被认同了,实际上也是对MySQL语句写法的统一化,标准化,而之前的人工审核,针对标准这个问题其实是很吃力的,标准越多,DBA越累,开发也越累。 3 | 那么在这个都追求自动化运维的时代,审核也必须要跟上步伐,因此Inception诞生了。而Inception可以做的工作远不止是一个自动化审核工具,同时还具备执行,生成对影响数据的回滚语句(类似闪回的功能),这样一条龙服务的工具,将会给DBA的工作带来翻天覆地的变化,DBA从此就从繁重的审核、登上去执行,出错了很难回滚(如果提前没有备份的话)的被动局面解放了出来,突然发现,做DBA原来可以这么轻松,工作可以不饱和了,那就有更多的自由时间学习、进一步向自动化运维平台的实现等更智能化的方向去发展,是具有里程碑意义的。 4 | 5 | #声明 6 | Inception是一个开源系统,每个人或者每个公司都可以自由使用,由于MySQL代码的复杂性,在审核过程中不可能入戏太深,主要是将最重要的审核完成即可,面对很多复杂的子查询、表达式等是不容易检查到的,所以有些就直接忽略了,那么大家在使用过程中,有任何疑问或者发现任何BUG,都直接提出来,我们大家一起将Inception维护得更好。 7 | 8 | 同时还有另一个很重要的原因,不同公司对SQL语句的使用习惯不同,也许针对去哪儿网[http://www.qunar.com](http://www.qunar.com)来说,现在已经正常在线上服务很长时间,也没什么大的问题,而到其它公司了,则可能会遇到比较多问题,这是可以原谅的,也许是水土不服吧!!那么针对这些问题,还是请大家尽管提出来,我们大家一起将Inception维护得更好。 9 | 10 | 平时工作压力比较大,这个工具首先是为了解决问题的,可能还会存在一些没有测试过的代码,有些地方可能也是值得推敲的,还有待优化,本人会不遗余力的维护好,不断的改进,争取成为一个功能更加完善,使用更加友好的系统,同时正在酝酿一些新的更高大上的功能,敬请期待。 11 | 12 | Inception开源GitHub地址: 13 | [https://github.com/mysql-inception/inception.git](https://github.com/mysql-inception/inception.git) 14 | 15 | #联系方式 16 | 王竹峰 17 | **邮箱**:doathink@gmail.com 18 | Inception讨论QQ群:185803996 19 | -------------------------------------------------------------------------------- /docs/install.md: -------------------------------------------------------------------------------- 1 | #Inception安装说明 2 | 看到这个手册,想必已经得到了源码,恭喜你。 3 | 4 | 首先就是编译,在源码根目录下面有一个文件inception_build.sh,执行命令`sh inception_build.sh`,会输出使用方法。 5 | 实际上只需要执行`inception_build.sh debug [Xcode]`即可,后面的平台是可选的,如果不指定就是linux平台,而如果要指定是Xcode,就后面指定Xcode,而debug是编译的目录,编译之后,所有的生成文件都在这个目录下面,包括可执行文件Inception。可执行文件在`debug/sql/Debug/`目录下面(不同平台有可能不相同)。 6 | 7 | 介于在发布之后,很多人使用的是Ubuntu操作系统,这个与其它的有点不同,这里单独说一下在这个下面的编译步骤(其实需要安装的都是编译时所依赖的包,有则略之,无则装之,其它系统仿照这个应该可以轻松搞定): 8 | 9 | 1. 下载bison:[http://ftp.gnu.org/gnu/bison/](http://ftp.gnu.org/gnu/bison/),版本最好是2.6之前的,最新的可能会有问题,下载之后,需要自己编译源码来安装,具体安装方法,可以参数网上的一些说明。 10 | 2. cmake安装:apt-get install cmake 11 | 3. ncurses安装:apt-get install libncurses5-dev 12 | 4. 安装openssl:apt-get install libssl-dev 13 | 5. 安装g++:sudo apt-get install g++ 14 | 15 | 安装完成这些,应该是没什么问题了,那么需要注意的是,每次如果出错之后,需要把编译目录删除掉,重新执行,不然会执行出错。 16 | 17 | 顺便强调说一下,实际上编译Inception,和编译MySQL源码是一样的,如果有不太了解的同学,可以先在网上看看关于MySQL源码的编译,我想遇到的问题都可以解决。 18 | 19 | 编译完成之后,就是使用了,那么需要一个配置文件(inc.cnf): 20 | ```` 21 | [inception] 22 | general_log=1 23 | general_log_file=inception.log 24 | port=6669 25 | socket=/自己目录,请自行修改/inc.socket 26 | character-set-client-handshake=0 27 | character-set-server=utf8 28 | inception_remote_system_password=root 29 | inception_remote_system_user=wzf1 30 | inception_remote_backup_port=3306 31 | inception_remote_backup_host=127.0.0.1 32 | inception_support_charset=utf8mb4 33 | inception_enable_nullable=0 34 | inception_check_primary_key=1 35 | inception_check_column_comment=1 36 | inception_check_table_comment=1 37 | inception_osc_min_table_size=1 38 | inception_osc_bin_dir=/data/temp 39 | inception_osc_chunk_time=0.1 40 | inception_enable_blob_type=1 41 | inception_check_column_default_value=1 42 | ```` 43 | 上面这些参数的配置都是本人随便举例而已。具体每个参数的意义,请参照后面章节<<**Inception所支持的参数变量**>> 44 | 45 | 现在就到启动时间了,那么启动有两种方式,和MySQL是一样的,Inception可执行文件可以在编译目录下面通过find命令找到,编译目录就是在执行inception_build.sh脚本时指定的目录。 46 | 1. 所在目录/Inception --defaults-file=inc.cnf 47 | 2. 所在目录/Inception --port=6669 48 | 49 | 第二种方法就是只指定一个端口,其它参数都是默认值,而第一种方法就是在配置文件中可以指定很多参数,按照自己喜欢的规则来配置。 50 | 51 | **注意**: 52 | 因为Inception支持OSC执行的功能,是通过调用pt-online-schema-change工具来做的,但如果Inception后台启动(&)的话,可能会导致pt-online-schema-change在执行完成之后,长时间不返回,进而导致Inception卡死的问题,这个问题后面会解决,但现阶段请尽量不要使用后台启动的方式,或者可以使用`nohup Inception启动命令 &`的方式来启动。 53 | 54 | 启动如果不报错的话,说明已经启动成功了,实际上很难让它报错,因为非常轻量级 55 | 56 | 启动成功之后,可以简单试一下看,通过MySQL客户端 57 | `mysql -uroot -h127.0.0.1 -P6669` 58 | 登录上去之后,再执行一个命令: 59 | `inception get variables;` 60 | 输出了所有的变量,恭喜你,已经启动成功了,都说了非常简单。 61 | 具体的使用的命令等在后面相应章节都会讲到,继续往后看吧!!! 62 | -------------------------------------------------------------------------------- /docs/option.md: -------------------------------------------------------------------------------- 1 | #Inception支持选项及意义 2 | 在前面<<**Inception使用方法**>>一章的例子中已经看到部分选项了。我们的选项是通过在SQL语句块前面以注释的方式一起传达给Inception的,它支持的选项还算丰富,这里将详细介绍现在所支持的每个选项的使用方法及意义。 3 | 4 | ------------------------------------------- 5 | |参数名字 |是否需要参数 |参数是否可选 |功能描述 | 6 | |:--------------|:-----------:|:------------------------:|:::----------------| 7 | |--host |是 |否|指定将要执行/审核这部分语句块的数据库地址。| 8 | |--port |是 |否|指定将要执行这部分语句块的数据库端口。| 9 | |--password |是 |否|指定Inception连接数据库的密码。| 10 | |--user |是 |否|指定Inception连接数据库的用户名。| 11 | |--sleep|是|是|这个参数用来指定在执行完每一条语句之后,暂停多少毫秒,这样可以适当控制对线上数据库的冲击,特别是针对大量写入的操作,单位为毫秒,最小值为0,也就是不暂停,最大值为100秒,也就是100000毫秒。如果设置得超过100000毫秒,Inception会自动将其设置为100000毫秒。这个参数可以和其它参数一起设置,但是只有在--enable-execute为1的情况下,才起作用。|否 12 | |--enable-check |否 |否|告诉Inception当前要做什么操作,是审核还是执行,这个参数与下面的--enable-execute只能指定一个。| 13 | |--enable-execute| 否 |否 |告诉Inception当前要做什么操作,是审核还是执行,这个参数与上面的--enable-check只能指定一个, 如果指定的是这个参数,则Inception在执行前还会做一次实时的审核,那么这个审核和前面指定--enable-check时的审核基本是相同的,因为相同的语句在不同的时间审核产生不同的结果是有可能的(环境有可能变了),所以再做一次审核是有必要的,如果审核发现错误(而不是警告)就不会被执行,当然如果没有指定--enable-ignore-warnings的话,有警告也是不会执行的,但有错误的话,肯定是不会被执行。| 14 | |--enable-force |否 |是 |告诉Inception,当在执行过程中碰到一个错误时,是中止执行还是保存错误信息继续执行下一个语句,这个参数要谨慎使用。| 15 | |--enable-ignore-warnings |否| 是 |Inception采取严格的分阶段处理,如果审核有问题则不能执行,那么针对一些特殊问题并且审核有警告不通过,但人工审核没问题确定可以执行时,可以选择这个参数,告诉Inception跳过这个警告的检查,继续执行。| 16 | |--enable-remote-backup | 否 | 是 | 指定在执行时是不是要备份,这个参数默认是打开的,如果不想备份,则指定参数--disable-remote-backup,这个选项所支持的备份,实际上是对当前所执行的操作的备份及被修改数据的回滚语句的存储,关于备份的具体内容,在后面章节中专门介绍。| 17 | |--enable-split | 否 | 是 | 这个参数是用来拆分要执行的语句块的,如果在语句块中存在对同一个表的DDL操作及DML操作,那么在备份及生成回滚语句分析binlog时,由于表结构已经发生改变,会导致inception没法处理,所以使用这个参数将这些语句分成多批,然后再分别执行,这是在执行前必须要做的一个操作,不然可能产生不可预知的错误,当然在执行前的最后一次审核中,如果检查到有这样的混用情况,会报错返回,而不是警告。这个参数指定之后,除了前面四个参数之外,其它参数都被忽略,也可以不指定。| 18 | |--enable-query-print|否|是|这个参数用来打印提供SQL语句在被MySQL分析之后的执行树结构,以Json的形式提供,目的是为了可以在Inception的基础上,对已经结构化的(Json)被分析之后的语句做再次分析,比如使用到哪些列、语句类型等信息,目前支持的语句类型有:插入、删除、更新及查询,具体详情请参考<<**Inception语法树打印**>>一节。| 19 | 20 | ------------------------------------------- 21 | 22 | 现在所支持的选项就上面已经给出的这些,下面是一些特殊说明。 23 | 可以看到,上面所说的参数名字除了前面四个连接选项之外,都在前面加了enable,而实际上,这些参数的写法与MySQL配置参数的写法是相同的,比如--enable-check,这个参数的名字只是简单的check,可以写成--check=1,也可以写成--disable-check, 都是比较灵活的,其它的也都是一样的道理。 24 | 25 | 关于`use database`,如果没有使用use语句,则必须要在使用表的同时指定库名,即`databasename.tablename`,否则Inception直接报错,但是如果通过 use 语句指定过一次数据库,当前语句块中,后面可以不再指定,除非想修改当前库的名称,而如果通过`databasename.tablename`方式指定具体库下面的表,则后面的操作不会受到前面的影响,也就是后面还需要明确指定库名。 26 | 27 | -------------------------------------------------------------------------------- /docs/osc.md: -------------------------------------------------------------------------------- 1 | #Inception 对OSC的支持 2 | Inception已经支持Percon ToolKit工具**`pt-online-schema-change`**,这样对表大表的修改操作,就不需要跳过Inception而手动去执行了,给线上操作又带来了非常大的方便性。 3 | ##可选的OSC参数 4 | 为了更友好的实现对OSC的集成,增加了下面的一些参数: 5 | 6 | -------- 7 | |参数名称 | 作用域 |默认值 |说明 8 | |:-----------------------------------------------|:---------|:-------------------|:-------| 9 | |inception_osc_bin_dir | GLOBAL |无 |用于指定pt-online-schema-change脚本的位置,不可修改,在配置文件中设置| 10 | |inception_osc_check_interval | SESSION |5秒 |对应参数--check-interval,意义是Sleep time between checks for --max-lag.| 11 | |inception_osc_chunk_size | SESSION |1000 |对应参数--chunk-size| 12 | |inception_osc_chunk_size_limit | SESSION |4 |对应参数--chunk-size-limit| 13 | |inception_osc_chunk_time | SESSION |1 |对应参数--chunk-time| 14 | |inception_osc_critical_thread_connected | SESSION |1000 |对应参数--critical-load中的thread_connected部分| 15 | |inception_osc_critical_thread_running | SESSION |80 |对应参数--critical-load中的thread_running部分| 16 | |inception_osc_drop_new_table | SESSION |1 |对应参数--[no]drop-new-table| 17 | |inception_osc_drop_old_table | SESSION |1 |对应参数--[no]drop-old-table| 18 | |inception_osc_check_replication_filters | SESSION |1 |对应参数--[no]check-replication-filters| 19 | |inception_osc_check_alter | SESSION |1 |对应参数--[no]check-alter| 20 | |inception_osc_max_lag | SESSION |3 |对应参数--max-lag| 21 | |inception_osc_max_thread_connected | SESSION |1000 |对应参数--max-load中的thread_connected部分| 22 | |inception_osc_max_thread_running | SESSION |80 |对应参数--max-load中的thread_running部分| 23 | |inception_osc_recursion_method| SESSION|processlist |对应OSC参数recursion_method,具体意义可以参考OSC官方手册| 24 | |inception_osc_alter_foreign_keys_method| SESSION|none|对应OSC参数alter-foreign-keys-method,具体意义可以参考OSC官方手册| 25 | |inception_osc_min_table_size | SESSION |16 |这个参数实际上是一个OSC的开关,如果设置为0,则全部ALTER语句都走OSC,如果设置为非0,则当这个表占用空间大小大于这个值时才使用OSC方式。单位为M,这个表大小的计算方式是通过语句: **"select (DATA_LENGTH + INDEX_LENGTH)/1024/1024 from information_schema.tables where table_schema = 'dbname' and table_name = 'tablename'"**来实现的。| 26 | |inception_osc_on | GLOBAL |1 |一个全局的OSC开关,默认是打开的,如果想要关闭则设置为OFF,这样就会直接修改| 27 | |inception_osc_print_sql | GLOBAL |1 |对应参数--print| 28 | |inception_osc_print_none | GLOBAL |1 |用来设置在Inception返回结果集中,对于原来OSC在执行过程的标准输出信息是不是要打印到结果集对应的错误信息列中,如果设置为1,就不打印,如果设置为0,就打印。而如果出现错误了,则都会打印| 29 | | 30 | ---------- 31 | 32 | 33 | 参数名称、作用域、默认值及意义上面都已经列出来了,针对全局的参数,比如inception_osc_on,都是用来控制所有的OSC行为的,这些参数的修改及查看都是通过上面第六节中所介绍的一样,当修改之后,立即生效。 34 | 35 | 而针对会话级的参数,因为这些参数是只能影响当前要执行的语句的行为,所以不能设置全局的值,必须要在执行前设置当前线程的值,Inception可以通过语句:inception set session session_variable_name=value来修改,这样就只会影响当前语句的执行。因为Inception只是一个服务器,那么在具体页面实现时,可能还需要在页面上加入对这些参数修改并且设置的窗口,针对每一个设置,在内部拼写对应的inception set session语句来设置,然后再开始ALTER TABLE。 36 | ##查看OSC执行进度 37 | 对于ALTER比较大的表时,因为所用时间比较长,在修改时可能需要关注一下进度,因为OSC工具本身在执行时是打印进度信息的,所以Inception完全 可以提供这方面的信息,出于更友好的实现方式,Inception新加入一个语句,可以查询当前执行的语句的进度,语句语法为: 38 | ```` 39 | inception get osc_percent '当前执行的SQL语句以及一些基本信息生成的SHA1哈希值' 40 | ```` 41 | 42 | 通过这个语句,可以查看进度信息,这个返回的结果集包括下面5个列: 43 | 44 | * **TABLENAME**:当前被修改的表名; 45 | * **DBNAME**:当前被修改表所在的库名; 46 | * **SQLSHA1**:当前要查询的语句的SHA1字符串; 47 | * **PERCENT**:当前修改已经完成的百分比,这个值是0到100的值。 48 | * **REMAINTIME**:当前修改语句还需要多久才能完成,如03:55表示还需要三分55秒,01:33:44表示还需要1小时33分44秒。 49 | * **INFOMATION**:显示当前OSC执行时的状态信息,内容为OSC当前所有的输出信息,不包括百分比信息,百分比还是由上面的列来显示,这个方便在使用时随时查看执行到哪一步了,可以更加清楚的了解到执行进度。 50 | 51 | 下图是在ALTER的时候,查到的正在做的信息: 52 | ![](inception_images/osc.png) 53 | 54 | 上面是正在做的,而如果语句块中有多个修改表的操作,则前面的会看到执行完成的进度信息: 55 | ![](inception_images/osccomplete.png) 56 | 57 | 具体在上层应用使用时,可以选择性的使用所需要的列。 58 | 59 | 至于上面提到的SHA1值是如何获得的,因为在应用提交语句时,都会审核通过才能提交到流程管理数据库中,那么这个语句就不会被修改了,而此时在审核通过的时候,返回的结果集新增一个列sqlsha1,而只有当Inception判断到当前语句满足使用OSC方式执行时,这个列才会有值,就会根据当前语句信息生成一个哈希值,这个值存储起来以方便后面执行时使用。 60 | 61 | 下面来看看ALTER语句在满足使用OSC的情况下,审核时返回的结果集信息: 62 | ```` 63 | ['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1'] 64 | 1 | CHECKED | 0 | Audit completed | None | use sbtest | 0 | '0_0_0' | None | 0 | 65 | 2 | CHECKED | 0 | Audit completed | None | alter table sbtest1 add c2 int not null default 'a' comment 'for test' | 449234 | '0_0_1' | 127_0_0_1_3306_sbtest | 0 | *F270A6902BB3A0E2DE042A60D79F55418C8D1C00 66 | ```` 67 | 其中"***98A11AC683C0D121568A51CA33A3A94674326630**"就是上面ALTER语句对应的SQLSHA1值。 68 | 69 | 当进入执行阶段之后,在执行当前语句时,OSC会向inception返回进度信息,Inception在收到之后,会根据当前语句的SHA1值更新对应的进度信息,OSC会每百分之一返回一次进度信息,那Inception都会更新当前语句对应的进度信息,OSC不会返回100%,最大99%,而Inception做了处理,当检查到有successfully altered的信息之后,就将进度信息改为100%,剩余时间为00:00,而99%到100%之间做的事情包括清除环境的操作,所以时间可能比之前的1%的时间要长。 70 | 71 | 进度信息缓存有生命周期的,在整个语句块执行完成在退出前,相应的缓存信息就会被清除出去,之后再查询进度就查不到了。查不到的话,当前线程的阻塞也就返回了,说明已经完成。 72 | 73 | ##中止OSC的执行 74 | 在执行OSC的过程中,有可能遇到的问题是,执行一部分了,突然发现对线上造成了MDL等待的现象,这种影响对一些业务是不可接受的,因为很多语句此时就不能执行当前表上面的任何操作了,必须要等OSC的一些辅助操作(建立/删除触发器)完成之后才可以,而OSC的这些操作又是在等待线上的一些慢查询语句执行完成才能继续执行下去,这种情况下,我们一般的处理方式是,先退出OSC执行,等在压力小的时候,或者可以多试几次,才可以继续执行下去,那么此时最需要DBA操作的就是取消当前这个OSC的执行,所以考虑实现一个取消(中止)OSC执行的功能。 75 | 76 | 取消方式与查询执行进度是一样的,还是通过一个新的Inception命令来实现,新的命令如下: 77 | ```` 78 | inception stop alter '当前执行的SQL语句以及一些基本信息生成的SHA1哈希值' 79 | ```` 80 | 这里用到的还是那个SQLSHA1,当OSC开始执行时,这个SQLSHA1对应的缓存对象会被加入到OSC缓存中,此时就可以查到执行进度了(当然一开始还是0%),同时,这个时候也就可以取消这个语句的执行了,但取消的前提是,OSC执行的进程已经创建,同时,执行进度不到100%才可以取消,否则就会报错误`"Can not find OSC executing task"`(2624),如果可以KILL的话,Inception就会主动KILL用来执行OSC的进程,这样轻而易举的就取消掉了OSC的执行了。 81 | 82 | 但是在取消之后,还是有几点需要注意的: 83 | 1. 在多个ALTER语句一起执行的情况下,如果取消某一个,那么整个执行过程都中止,同时被取消的语句返回是未执行状态。所以在前端实现执行错误再次执行时,这个可以归为未执行的语句 84 | 2. 在取消语句的错误描述信息中,报错为`"Execute has been abort in percent: 已执行比例, remain time: 剩余时间"` 85 | 3. 在取消之后,当前语句之后的所有语句不会执行,当然状态为未执行。 86 | 4. 被取消语句,在取消之后,结果集stagestatus列的信息会设置为`"Execute Aborted"`。 87 | ##查看所有OSC执行信息 88 | 语句如下: 89 | ```` 90 | inception get osc processlist; 91 | ```` 92 | 这个语句的功能是打印所有当前正在使用OSC执行的操作,如果在同一个inception请求中有多个ALTER语句,那么显示出来的有可能存在执行进度为100%的语句,通过这个语句,可以轻松查看当前每一个OSC执行进度,如果是卡住了(比如存在从库复制延迟),在这里可以看到具体信息。 93 | 94 | 实际上看到的信息和上面`inception get osc_percent '当前执行的SQL语句以及一些基本信息生成的SHA1哈希值'`返回的结果是一样的,只是这个返回了所有信息。 95 | 96 | ##后记 97 | **需要注意的是**,OSC全局参数最好别频繁修改,因为针对某一个语句的SHA1是分阶段的,生成是在审核阶段的,如果在审核时候没有打开,或者设置的表大小没有满足OSC方式,则不会生成SHA1,那么在执行时候,这个进度就不能被查询了,这个语句的执行情况就不能获取到,影响执行过程的体验。当然这个影响也不大,因为在执行完成之后,如果执行成功了,并且参数`inception_osc_print_none`为OFF,则会看到打印信息,里面包括成功或者失败的所有信息,而如果为ON,则如果结果集中有信息,则说明是执行错误了,如果没有则说明成功。 98 | -------------------------------------------------------------------------------- /docs/queryprint.md: -------------------------------------------------------------------------------- 1 | #Inception 语法树打印 2 | 目前,Inception已经支持大部分MySQL语句了,但是有一点不足之处是,规则都是固定的,虽然可以通过设置参数来修改是不是可以跳过这些检查,但除了检查语法错误之外,其它可配置的检查始终是一个固定在一个范围内的,如果想要新增一些检查项,过程可能比较慢长,所以想到在Inception内部,再集成一个格式化、结构化SQL语句的功能,这样的好处是,上层根据Inception返回的结构化的SQL语句,定义一些自己的规则,这样就可以满足更多人的需求了。 3 | 4 | 如果这是你的需求,请继续往下看。 5 | 6 | ##结果集信息 7 | 8 | 前面在介绍<<**Inception支持选项及意义**>>中已经讲过了,可以通过设置选项--enable-query-print来启用打印语法树的功能,同样的,它与其它enable开头的选项是互斥的,不能同时设置,开启之后,再连接Inception,执行返回的结果集是一个与拆分、审核及执行都不同的结果集,所包括的列如下: 9 | 10 | 1. ID:这个用来表示当前语句的一个序列值。 11 | 1. STATEMENT:这个列用来存储当前被分析的SQL语句。 12 | 1. ERRLEVEL:这个列用来存储当打印遇到问题时,错误的级别,与审核结果集中的ERRLEVEL意义相同。 13 | 1. QUERY_TREE:这个列就是对当前语句的分析结果,格式为JSON字符串。 14 | 1. ERRMSG:这个列与上面的ERRLEVEL对应,当出错时,这里存储分析过程中所有的错误信息,与审核结果集中的同名列意义相同。 15 | 16 | ##举例说明 17 | 18 | 举例说明才是最有说服力的: 针对SQL语句: 19 | ```` 20 | insert into t (sno,name) 21 | select sno, name from t alias_t 22 | where sno=( 23 | select sno+1 from my 24 | where 25 | name like "%zhufeng%" and 26 | sno > '10010' and 27 | name=alias_t.name 28 | ) 29 | order by name 30 | limit 100, 10; 31 | ```` 32 | 33 | 执行时提交给Inception的语句如下: 34 | 35 | ![](inception_images/queryprint.png) 36 | 执行结果如下: 37 | ![](inception_images/queryprintresult.png) 38 | 39 | 注:使用到的print.py其实和之前<<**Inception使用方法**>>中介绍的脚本没什么两样,只是显示的结果集不同而已。 40 | 41 | 对应的Json可视化的query_tree如下: 42 | 43 | ```` 44 | { 45 | "command": "insert", 46 | "table_object": { 47 | "db": "ver", 48 | "table": "t" 49 | }, 50 | "fields": [ 51 | { 52 | "type": "FIELD_ITEM", 53 | "db": "ver", 54 | "table": "t", 55 | "field": "sno" 56 | }, 57 | { 58 | "type": "FIELD_ITEM", 59 | "db": "ver", 60 | "table": "t", 61 | "field": "name" 62 | } 63 | ], 64 | "select_insert_values": { 65 | "select_list": [ 66 | { 67 | "type": "FIELD_ITEM", 68 | "db": "ver", 69 | "table": "t", 70 | "field": "sno" 71 | }, 72 | { 73 | "type": "FIELD_ITEM", 74 | "db": "ver", 75 | "table": "t", 76 | "field": "name" 77 | } 78 | ], 79 | "table_ref": [ 80 | { 81 | "db": "ver", 82 | "table": "t" 83 | } 84 | ], 85 | "where": [ 86 | { 87 | "type": "FUNC_ITEM", 88 | "func": "=", 89 | "args": [ 90 | { 91 | "type": "FIELD_ITEM", 92 | "db": "ver", 93 | "table": "t", 94 | "field": "sno" 95 | }, 96 | { 97 | "type": "SUBSELECT_ITEM", 98 | "engine": "single_select", 99 | "subselect": { 100 | "select_list": [ 101 | { 102 | "type": "FUNC_ITEM", 103 | "func": "OTHERS", 104 | "name": "+", 105 | "args": [ 106 | { 107 | "type": "FIELD_ITEM", 108 | "db": "ver", 109 | "table": "my", 110 | "field": "sno" 111 | }, 112 | { 113 | "type": "INT_ITEM", 114 | "value": "1" 115 | } 116 | ] 117 | } 118 | ], 119 | "table_ref": [ 120 | { 121 | "db": "ver", 122 | "table": "my" 123 | } 124 | ], 125 | "where": [ 126 | { 127 | "type": "COND_ITEM", 128 | "func": "AND", 129 | "args": [ 130 | { 131 | "type": "FUNC_ITEM", 132 | "func": "LIKE", 133 | "args": [ 134 | { 135 | "type": "FIELD_ITEM", 136 | "db": "ver", 137 | "table": "my", 138 | "field": "name" 139 | }, 140 | { 141 | "type": "STRING_ITEM", 142 | "value": "%zhufeng%" 143 | } 144 | ] 145 | }, 146 | { 147 | "type": "FUNC_ITEM", 148 | "func": ">", 149 | "args": [ 150 | { 151 | "type": "FIELD_ITEM", 152 | "db": "ver", 153 | "table": "my", 154 | "field": "sno" 155 | }, 156 | { 157 | "type": "STRING_ITEM", 158 | "value": "10010" 159 | } 160 | ] 161 | }, 162 | { 163 | "type": "FUNC_ITEM", 164 | "func": "=", 165 | "args": [ 166 | { 167 | "type": "FIELD_ITEM", 168 | "db": "ver", 169 | "table": "my", 170 | "field": "name" 171 | }, 172 | { 173 | "type": "FIELD_ITEM", 174 | "db": "ver", 175 | "table": "t", 176 | "field": "name" 177 | } 178 | ] 179 | } 180 | ] 181 | } 182 | ] 183 | } 184 | } 185 | ] 186 | } 187 | ], 188 | "OrderBy": [ 189 | { 190 | "type": "FIELD_ITEM", 191 | "db": "ver", 192 | "table": "t", 193 | "field": "name" 194 | } 195 | ], 196 | "limit": { 197 | "limit": [ 198 | { 199 | "type": "INT_ITEM", 200 | "value": "10" 201 | } 202 | ], 203 | "limit_offset": [ 204 | { 205 | "type": "INT_ITEM", 206 | "value": "100" 207 | } 208 | ] 209 | } 210 | } 211 | } 212 | ```` 213 | 214 | 上面的SQL语句实际上没有任何意义,这里只是为了尽可能好的将每一类型的表达式打印出来而胡乱构造的。 215 | 216 | 可以看到,这个Json串很长,不过结构化之后,整个语句就非常清楚了,是什么语句类型,用到什么表,什么列,有没有ORDER BY等,都非常明确,分析语句再也不是难事儿了,使用程序对这个结构化的语句做分析,应该是很容易了,并且是非常准确的。 217 | 218 | ##标签定义 219 | 不过这里还是要简单讲一下语法树Json串中的一些标签: 220 | 221 | 1. command: 每个语句都是以command开头的,这个表示是什么语句类型,现在支持的有insert, update, delete, select这四种类型。 222 | 1. table_object: 表示当前语句对哪个表做的操作,这个只针对插入、删除操作的,比如是插入哪个表,删除哪个表。而更新操作在语法树中不太好确认哪些表被改了,所以这里没有明确拿出来,而是可以通过从更新列的信息中取到表信息,这也就是被更新的表。这是一个字典,里面包括的是一个,或者多个表信息,并且已经对应到其对应的数据库。 223 | 1. fields: 表示插入时语句中指定的要插入的列列表,如果没有指定,则没有这个信息。它是一个数组,包括了语句中所指定的所有列信息,每一个列是一个对列表达式的表示,包括数据库、表及列名,因为这是一个表达式,所以其表达式类型为FIELD_ITEM,后面会专门列出所有支持的表达式信息。 224 | 1. select_insert_values: 这个表示的是查询插入的查询部分,它是一个字典,里面包括了这个查询语句的所有元素,包括查询列、查询涉及的表、WHERE及ORDER BY等信息。 225 | 1. select_list: 表示当前查询语句(或者子查询)要查询的表达式信息,这里可以是列,也可以是其它计算出来的值,例子中就有select sno+1...这样的查询。 226 | 1. table_ref: 表示当前语句上下文中使用到的表信息,是一个数组,包括了所有的表,这里所谓的上下文,可以简单理解为,在一个子查询的可见范围内的所有表达式,都是属于同一个层次的,而如果比如一个列在当前上下文中找不到,可能就需要去父亲的上下文中找,那如果找到了,这种就算做是相关子查询,那么这种一个语句中有不同层级的查询存在时,就存在不同的上下文。在例子中也有相关反映。 227 | 1. where: 表示的就是查询表达式(包括查询、删除、更新及查询等)的语法树,因为WHERE语句其实就是一个表达式,只是有可能是多个表达式的逻辑运算而已。 228 | 1. OrderBy: 表示查询时使用到的排序列,是一个数组。 229 | 1. limit: 表示在查询时使用到的LIMIT信息,因为LIMIT是一个复合信息,包括了限制行数及开始位置等,所以会有limit及limit_offset,而limit_offset有可能没有,只有限制行数。 230 | 1. GroupBy: 表示查询时使用到的分组列,是一个数组。 231 | 1. Having: 表示查询时,使用到的Having表达式。 232 | 1. subselect: 如果使用到子查询时,则这个就用来表示这个子查询。它是一个字典。 233 | 1. many_values: 在查询语句中,如果插入的是值,而不是查询结果,则用这个来表示它的值列表,因为在MySQL中可以同时插入多个值,则这里有可能是多个。 234 | 1. values: 如果插入的是值时,这个用来表示一行的插入内容,这是一个数组,每个元素是一个列的表达式。这是many_values数组的一个元素。而如果是一个更新语句时,这表示的是被更新的值表达式列表。 235 | 1. set_fields: 用于表示更新语句的更新列的信息的,这是一个数组,里面每个元素对应被更新的一个列表达式。 236 | 237 | 上面就是目前支持的语句中出现的标签说明,但是还有很大一部分是表达式的处理,在打印表达式时,每一个对象都有一个公共的KEY,名为type,而针对不同的type,其它的KEY就不一定相同了,而具体的不同,这里就不多叙述了,这里只给出支持哪些表达式,除type之外的其它信息,可以在使用过程中一试便知。 238 | 239 | ##支持表达式类型 240 | 下面是目前支持的所有表达式的列表,下面仅列出type的不同的值: 241 | 242 | 1. STRING_ITEM: 字符串,有其它KEY用来存储其具体值信息。 243 | 1. FIELD_ITEM: 列信息,有其它KEY用来存储具体对应的库、表及列名等。 244 | 1. FUNC_ITEM,COND_ITEM: 逻辑运算信息,包括比较运算符、AND、OR、ISNULL、ISNOTNULL、LIKE、BETWEEN、IN、NOT、NOW及其它自定义或者内置函数等运算操作。 245 | 1. INT_ITEM: 整数值表达式。 246 | 1. REAL_ITEM: 符点数值表达式。 247 | 1. NULL_ITEM: NULL值表达式。 248 | 1. SUBSELECT_ITEM: 子查询表达式。 249 | 1. SUM_FUNC_ITEM: 集函数表达式。 250 | 1. ROW_ITEM: 行表达式,比如select * from t where (sno,name) = (select sno,name from t1),这里where条件的左值就是这个表达式类型。 251 | 1. DECIMAL_ITEM: DECIMAL表达式类型。 252 | 253 | 上面就是目前所支持的表达式类型,已经基本覆盖所有的常用的表达式。 254 | 255 | 最后要说明的是,这里打印出来的信息,已经不完全只是语法分析结束之后的信息,而是经过Inception加工过的,比如在查询语句中用到了子查询,存在不同的上下文时,同时还使用了别名,或者在使用列时,没有指定其表名,这几种情况,Inception都打印了每一个列对应的库名表名,这样打印出来的信息中,已经不存在没有定位(找到其库名表名)的列名了,使用中更加友好,准确。比如上面例子中,就有这样的情况(名为alisa_t的t表的别名)。 256 | 257 | ##后记 258 | 这个功能是新开发实现的,没有经过太多的验证(但也不存在太大问题),所以还需要后期的不断完善及更新,请各位有兴趣的同学,有任何意见、建议,都可以加群或者联系本人QQ讨论解决。 259 | 260 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | #发布日志 2 | ###2016年3月23日Inception2.1.23发布 3 | 1. [**新增**]增加参数inception_osc_alter_foreign_keys_method,为了解决pt工具改表时 在没有外键的情况下,还是查information schema,导致在库表很多的情况下 非常慢的问题,加上这个参数,默认为none,就不会去查了,速度非常快,并且 可以减少内存的暴涨 4 | 2. [**新增**]新增一种选项,--sleep,用来在执行每条语句之后,都可以在inception内部暂停指定ms数,单位为毫秒。这样可以缓解对线上数据库的冲击,详情请参照<<**Inception支持选项及意义**>> 5 | 6 | ###2015年10月26日Inception2.1.17发布 7 | 1. [**新增**]新增inception get osc processlist的功能,这个语句可以查看所有当前正在执行的OSC线程。 8 | 2. [**新增**]新增inception get processlist的功能,这个语句可以查看所有当前正在执行的线程。 9 | 3. [**新增**]新增参数inception_osc_recursion_method,可以配置在执行OSC时,因为从库有延迟,或者复制停止导致不能正常执行OSC时,可以设置这个参数为NONE跳过slave的检查。 10 | 4. 修改在timestamp类型的列设置默认值为合法的日期,但不在其合法范围内没有报错的问题。 11 | 5. 修改回滚语句拼写错误的问题(多了一个AND) 12 | 6. 修改在只读模式下、不是执行模式的情况下,没有填备份信息还报非法备份的问题 13 | 7. 修改time类型的列建表指定默认值时,报非法默认值的问题 14 | 8. 修改在不同数据库下,执行相同的ALTER表时,生成的sha1是一样的,导致在获取进度时不准确的问题 15 | 9. 修改在生成drop index回滚语句时,ADD INDEX后面的列存在语法错误的问题 16 | 10. 修改在生成回滚语句时,注释太长导致栈溢出的问题 17 | 18 | ###2015年9月18日Inception2.1.9发布 19 | 1. [**新增**]新增参数inception_check_identifier 20 | 2. [**新增**]加入打印执行计划的功能 21 | 3. 修改在打印及审核表达式时字符串溢出导致内存覆盖的问题 22 | 4. 修改在多个加列并且有AFTER的时候,代码变量没有重置导致检查失败的问题 23 | 5. 对增删改查语句中的表达式检查的重构,不会漏掉一个表达式,检查更彻底,在Inception中一个比较遗憾的工作终于搞定了。 24 | 6. 修改Inception在启动的时候,错误的加载了非Inception配置文件组导致启动不成功的问题 25 | 7. 修改对时间类型默认值的检查,不考虑线上sql_mode值,只要是非法的时间值,都报警,时间类型包括所有的DATE、DATETIME、TIMESTAMP,默认值包括INT,STRING及DECIMAL等 26 | 8. 修改在处理sqlmode时代码错误导致系统崩溃的问题 27 | 9. 修改在回滚语句很长时,回滚表对应的字段为TEXT,导致语句被截断的问题,已经修改为Medium类型的TEXT。 28 | 10. 修改在生成回滚语句时,当主键不在第一个列时导致生成的语句存在语法错误的问题。 29 | 11. 废弃参数inception_ddl_support,请更新之后,不要再使用,已经不起作用了(之前手册也没有出现过,可以忽略) 30 | 31 | ###2015年8月28日Inception2.0.18-beta发布 32 | 1. 修改在binlogformat已经是ROW的情况下,还去设置,导致有些没有super权限时出错的问题 33 | 2. 修改在创建索引时,索引列为前缀索引时,没有考虑前缀长度,导致报大于767的问题 34 | 3. 加入对非法时间值在创建表及更改表时,没有报错的问题 35 | 4. 修改oSC执行时结果集名字错误的问题 36 | 5. 修改在截取alter table 真正修改的内容时,如果有注释内容,会出错的问题 37 | 38 | ###2015年8月3日Inception2.0.13-beta发布 39 | 1. 新增使用event对象的检查 40 | 2. 修改多表更新时,审核通过,执行失败的问题 41 | 3. 在表列定义为int(2)类似的情况下,会导致在设置Binlog解析记录长度时错误导致内存correption的问题 42 | 4. 在解析binlog出错之后,没有再去dump导致直接读取网络引起一直阻塞的问题 43 | 5. 修改对线上数据库操作时,数据库名字没有加"\`"导致报错的问题 44 | 6. 修改设置BLOB/TEXT为NOT NULL时报错级别为警告 45 | 7. 禁止在语句中直接使用@uservar类型的表达式 46 | 8. 修复Inception备份时Binlog解析错乱的问题 47 | 9. 增加对创建索引及新建表中,索引长度超过767的检查 48 | 10. 修改在生成ALTER回滚语句出错的问题 49 | 50 | ###2015年6月1日Inception2.0.3-beta发布 51 | 新增: 52 | 1. 实现OSC执行的取消功能 53 | 2. 在审核前获取一些线上参数来辅助审核,比如参数:explicit_defaults_for_timestamp 54 | 修复: 55 | 1. 在Inception没有dump binlog权限的情况下,备份时Inception会陷入死循环的问题 56 | 57 | ###2015年5月22日Inception2.0.0-beta发布 58 | -------------------------------------------------------------------------------- /docs/requires.md: -------------------------------------------------------------------------------- 1 | #Inception 对线上配置需求 2 | 1. 线上服务器必须要打开 binlog,在启动时需要设置参数log_bin、log_bin_index等关于 binlog 的参数。不然不会备份及生成回滚语句。 3 | 2. 参数binlog_format必须要设置为 mixed 或者 row 模式,通过语句: set global binlog_format=mixed/row 来设置,如果是 statement 模式,则不做备份及回滚语句的生成。 4 | 3. 参数 server_id 必须要设置为非0及非1,通过语句:set global server_id=server_id;来设置,不然在备份时会报错。 5 | 4. 线上服务器一定要有指定用户名的权限,这个是在语句前面的注释中指定的,做什么操作就要有什么权限,否则还是会报错,如果需要执行的功能,则要有线上执行语句的权限,比如DDL及DML,同时如果要执行inception show 等远程命令的话,有些语句是需要特殊权限的,这些权限也是需要授予的,关于权限这个问题,因为一般Inception是运行在一台固定机器上面的,那么在选项中指定的用户名密码,实际上是Inception机器对线上数据库访问的权限,所以建议在使用过程中,使用专门固定的帐号来让Inception使用,最好是一个只读一个可写的即可,这样在执行时用可写,审核或者查看线上状态或者表库结果时用只读即可,这样更安全。 6 | 7 | #需要额外注意的点 8 | 1. 在执行时,不能将 DML 语句及 DDL 语句放在一起执行,否则会因为备份解析binlog时由于表结构的变化出现不可预知的错误,如果要有同时执行 DML 及 DDL,则请分开多个语句块儿来执行,如果真的这样做了,Inception 会报错,不会去执行。 9 | -------------------------------------------------------------------------------- /docs/results.md: -------------------------------------------------------------------------------- 1 | #Inception结果集 2 | 3 | Inception给用户返回的信息有两种,一种是提交给Inception的基础信息存在错误,比如源信息不全,或者源信息有错误等,这种情况下,直接报异常,包括错误码及错误信息,与MySQL服务器的异常是一样的,在外面正常处理即可。 4 | 如果没有上面的问题,都会以结果集的方式将检查结果告诉客户端。这种方式非常友好,在它的基础上用现有的成熟的接口处理起来非常方便。返回的结果集中,每一个行数据,就是一条提交的SQL语句,Inception内部将所有提交的语句块一条条的拆开,以结果集的方式返回,针对每一条语句,有什么问题或者状态,在结果集中是一目了然。 5 | 6 | **需要注意的是**,如果在语句中出现语法错误,则不能继续了,因为Inception已经不能将剩下的语句分开了,那么此时前面已经正常检查的多行为多个结果集的行返回,后面出错的语句为一行返回,当然这个的错误信息是语法错误。 7 | Inception返回结果集的结构如下: 8 | 9 | 1. **ID**:用来表示检查的sql序号的,每次检查都是从1开始。 10 | 2. **stage**:这个列显示当前语句已经进行到哪一步了,包括CHECKED、EXECUTED、RERUN、NONE,NONE表示没有做过任何处理,有可能前面有语法错误直接就提前返回了, CHECKED表示这个语句只做过审核,而没有再进行下一步操作,EXECUTED表示已经执行过,如果执行失败,也是用这个状态表示,RERUN表示的是,对于影响上下文的语句,已经执行成功,但为了与EXECUTED区分,用RERUN表示,主要是因为在执行过程中,如果某一条语句执行失败了,则上层可能需要将没有执行的语句提取出来,再次执行,那么影响上下文的语句是需要加上的,所以用RERUN来表示。影响上下文的语句一般包括set names和use db这两种,而当前Inception支持的只有这两种。 11 | 3. **errlevel**:返回值为非0的情况下,说明是有错的。1表示警告,不影响执行,2表示严重错误,必须修改。 12 | 4. **stagestatus**:用来表示检查及执行的过程是成功还是失败,如果审核成功,则返回 Audit completed。如果执行成功则返回Execute Successfully,否则返回Execute failed,如果备份成功,则在后面追加Backup successfully,否则追加Backup failed,这个列的返回信息是为了将结果集直接输出而设置的,如果在具体使用过程中,为了更友好的显示,可以在这基础上再做加工处理。 13 | 5. **errormessage**:用来表示出错错误信息,这里包括一条语句中所有的错误信息,用换行符分隔,但有时候如果某一个错误导致不能继续分析了,则后面的错误就不能显示出来。如果没有出错,则用显示为None。而对于执行及备份错误,因为对于一条语句,这样的错误只会有一次,那么执行错误会在后面追加“execute:具体的执行错误原因”,如果是备份出错,则在后面追加“backup:具体的备份错误原因”,而在执行时,有时候会出现Warnings,比如插入数据时字符串被截断啥的,此时会输出这些warnings:`#1 Execute(Warning, Code errno):warning message`,#号后面的数字表示第几个警告,因为有时候执行一个语句会产生多个警告。 14 | 6. **SQL**:用来表示当前检查的是哪条sql语句。如果某一条sql语句在检查时有语法错误,则这里面会包括从出错语句开始到后面所有的语句,因为语法出错后实在是真的不能再继续分析了,也就不能将后面的每条语句分开了,这个列还会有一个特别的地方,如果当前语句是`inception show xxxx`命令集中的第一种情况(<<**Inception命令集**>>中会做具体介绍)。 15 | 7. **affected_rows**:用来表示当前语句执行时预计影响的行数,在执行时显示的是真实影响行数。 16 | 8. **sequence**:这个列与上面说的备份功能有关系,其实就是对应**$_$Inception_backup_information$_$**表中的 opid_time 这个列,一一对应,这就为前端应用在针对某一操作回滚找到了入口,每次执行都会产生一个序号,如果要回滚,则就使用这个值从备份表中找到对应的回滚语句执行即可。 17 | 9. **backup_dbname**:这个列表示的是当前语句产生的备份信息,存储在备份服务器的哪个数据库中,这是一个字符串类型的值,只针对需要备份的语句,数据库名由IP地址、端口、源数据库名组成,由下划线连接,而如果是不需要备份的语句,则返回字符串None。 18 | 10. **execute_time**:这个列表示当前语句执行时间,单位为秒,精确到小数点后两位。列类型为字符串,使用时可能需要转换成DOUBLE类型的值,如果只是审核而不执行,则这个列返回的值为0。 19 | 11. **SQLSHA1**:这个列用来存储当前这个语句的一个HASH值,这是用来标识这个语句是不是会使用OSC功能,如果返回信息中有值,则表示这个语句在执行的时候会使用OSC,因为在执行前,会有一次单独的审核操作,此时上层已经可以拿到这个值,审核通过之后,语句是不会改变的,当然这个值也不会改变,那么在执行时就可以使用这个值来查看OSC执行的进度等信息,这个值一般长的样子如下:***D0210DFF35F0BC0A7C95CD98F5BCD4D9B0CA8154**,具体其它信息,请参考<<**Inception 对OSC的支持**>>一章。 20 | 21 | #友情提示 22 | 上面的列,是为了尽可能的丰富的,更灵活的让上层使用,所以列比较多,而如果在具体使用中,如果哪些列觉得没什么意义或者用处不大,可以不关心,特别是只做一个审核页面的话,那么很多列都是不需要关心的,只需要关心ID、errlevel、errormessage、SQL及affected_rows即可。总之一句话,灵活应用即可。当然有任何问题或者疑问都可以随时联系本人(见首页)。 23 | 24 | -------------------------------------------------------------------------------- /docs/rules.md: -------------------------------------------------------------------------------- 1 | #Inception 审核规范及原则 2 | ##写在前面的话 3 | 4 | MySQL语句的审核,在业界都已经基本被认同了,实际上也是对MySQL语句写法的统一化,标准化,而之前的人工审核,针对标准这个问题其实是很吃力的,标准越多,DBA越累,开发也越累。那么Inception出现之后,它是不怕标准多的,只要DBA定义了为了更好的管理数据库的规则时,Inception就可以很好的执行,并且返回审核结果,那么这一章主要介绍当前Inception在审核时,是使用什么样的规则来做的,并且哪些规则是可以配置的,哪些规则是不可以配置的,这样针对不同的部门或者公司,可以定制不同的规则,而配置参数将在<<**Inception所支持的参数变量**>>中详细介绍。 5 | 6 | 下面就是有关审核规范的具体信息,但一些人为的或者逻辑的东西机器没办法搞定的,需要我们DBA自己定义,所有制定的规则,都是以语法正确为前提的,当然首先审核的就是语法问题,如果语法不通过,则整个语句块中,语法出问题的位置前面的语句审核完成,后面则不能将各个语句分开,报错时后面就被认为是一个语句。 7 | 8 | **重要声明**:下面所列出来的规则,不一定能覆盖所有Inception当前已经实现的功能,具体包括什么规则,还需要在使用过程中总结,发现,同时可以结合配置参数来详细了解这些规则。 9 | 10 | ##支持的语句类型 11 | * use db:此时会检查这个库是不是存在,需要连接到线上服务器来判断。 12 | * set option:现在只需要支持set names charset,设置其它变量时都报错不支持。 13 | * 创建数据库语句 14 | * 插入语句(包括多值插入) 15 | * 查询插入语句 16 | * 删除语句(包括多表删除) 17 | * 更新语句(包括多表更新) 18 | * 创建表语句 19 | * 删除表语句 20 | * 修改表语句 21 | * Truncate表语句 22 | * inception命令集语句(包括管理命令) 23 | 24 | ##插入语句检查项 25 | * 表是否存在 26 | * 必须指定插入列表,也就是要对哪几个列指定插入值,如insert into t (id,id2) values(...),(可配置) 27 | * 必须指定值列表,与上面对应的列,插入的值是什么,必须要指定。 28 | * 插入列列表与值列表个数相同,上面二者的个数需要相同,如果没有指定列列表(因为可配置),则值列表长度要与表列数相同。 29 | * 不为null的列,如果插入的值是null,报错(可配置) 30 | * 插入指定的列名对应的列必须是存在的。 31 | * 插入指定的列列表中,同一个列不能出现多次。 32 | * 插入值列表中的简单表达式会做检查,但具体包括什么不一一指定 33 | 34 | ##更新、删除语句检查项 35 | * 表是否存在 36 | * 必须有where条件(可配置) 37 | * delete语句不能有limit条件(可配置) 38 | * 不能有order by语句(可配置) 39 | * 影响行数大于10000条,则报警(数目可配置) 40 | * 对WHERE条件这个表达式做简单检查,具体包括什么不一一指定 41 | * 对更新列的值列表表达式做简单检查,具体不一一指定 42 | * 对更新列对象做简单检查,主要检查列是不是存在等 43 | * 多表更新、删除时,每个表必须要存在 44 | 45 | ##建表语句检查项 46 | ###表属性的检查项 47 | * 这个表不存在 48 | * 对于create table like,会检查like的老表是不是存在。 49 | * 对于create table db.table,会检查db这个数据库是不是存在 50 | * 表名、列名、索引名的长度不大于64个字节 51 | * 如果建立的是临时表,则必须要以tmp为前缀 52 | * 必须要指定建立innodb的存储引擎(可配置) 53 | * 必须要指定utf8的字符集(字符串可配置,指定支持哪些字符集) 54 | * 表必须要有注释(可配置) 55 | * 表不能建立为分区表(可配置) 56 | * 只能有一个自增列 57 | * 索引名字不能是Primay 58 | * 不支持Foreign key(可配置) 59 | * 建表时,如果指定auto_increment的值不为1,报错(可配置) 60 | * 如果自增列的名字不为id,说明有可能是有意义的,MySQL这样使用比较危险,所以报警(可配置) 61 | ###列属性的检查项 62 | * 不能设置列的字符集(可配置) 63 | * 列的类型不能使用集合、枚举、位图类型。(可配置) 64 | * 列必须要有注释(可配置) 65 | * char长度大于20的时候需要改为varchar(长度可配置) 66 | * 列的类型不能是BLOB/TEXT。(可配置) 67 | * 每个列都使用not null(可配置) 68 | * 如果列为BLOB/TEXT类型的,则这个列不能设置为NOT NULL。 69 | * 如何是自增列,则使用无符号类型(可配置) 70 | * 如果自增列,则长度必须要大于等于4个字节(可配置) 71 | * 如果是timestamp类型的,则要必须指定默认值。 72 | * 对于MySQL5.5版本(包含)以下的数据库,不能同时有两个TIMESTAMP类型的列,如果是DATETIME类型,则不能定义成DATETIME DEFAULT CURRENT_TIMESTAMP及ON UPDATE CURRENT_TIMESTAMP等语句。 73 | * 每个列都需要定义默认值,除了自增列、主键列及大字段列之外(可配置) 74 | * 不能有重复的列名 75 | ###索引属性检查项 76 | * 索引必须要有名字 77 | * 不能有外键(可配置) 78 | * Unique索引必须要以uniq_为前缀(可配置) 79 | * 普通索引必须要以idx_为前缀(可配置) 80 | * 索引的列数不能超过5个(数目可以配置) 81 | * 表必须要有一个主键(可配置) 82 | * 最多有5个索引(数目可配置) 83 | * 建索引时,指定的列必须存在。 84 | * 索引中的列,不能重复 85 | * BLOB列不能建做KEY 86 | * 索引长度不能超过766 87 | * 不能有重复的索引,名字及内容 88 | ###默认值检查项 89 | * BLOB/TEXT类型的列,不能有非NULL的默认值 90 | * MySQL5.5以下(含)的版本,对于DATETIME类型的列,不能有函数NOW()的默认值。 91 | * 如果设置默认值为函数,则只能是NOW()。 92 | * 如果默认值为NULL,但列类型为NOT NULL,或者是主键列,或者定义为自增列,则报错。 93 | * 自增列不能设置默认值。 94 | 95 | ##修改表语句检查项 96 | * 表是不是存在 97 | ###创建索引检查项 98 | * 同上面创建表中的索引检查项 99 | ###加列检查项 100 | * 同上面创建表中的列检查项 101 | ###修改表检查项 102 | * 表是不是存在 103 | * 如果语句块中存在多条对同一个表的修改语句,则建议合并成一个ALTER语句 104 | * 列是否存在 105 | * 剩下的同上面创建表,创建索引,创建列,默认值等检查项一样 106 | ###删除索引检查项 107 | * 表是不是存在 108 | * 检查索引是不是存在 109 | ###修改列的默认值检查项 110 | * 同默认值检查项 111 | ###修改表属性 112 | * 表属性只支持对存储引擎、表注释、自增值及默认字符集的修改操作。 113 | * 修改存储引擎时检查是不是Innodb(可配置)。 114 | * 字符集修改检查是不是属于设置参数的值(支持字符集可配置)。 115 | ###转换表字符集 116 | * 字符集修改检查是不是属于设置参数的值(支持字符集可配置)。 117 | 118 | #声明 119 | * 针对线上MySQL服务器是不是5.6以上(包含)版本,有不同的处理策略,比如在预估影响行数时,5.6可以直接对任何DML语句做EXPLAIN操作,而在5.5版本中,只支持对SELECT语句执行EXPLAIN操作,而在5.5版本中,有些DML语句是不容易直接转换为SELECT语句去做EXPLAIN,这样导致预估行数为0。 120 | * 还是针对5.6以上版本与5.5版本的不同,DATETIME、TIMESTAMP系列类型在执行时,5.5的限制比较多,而5.6基本通用,所以这上面的处理可能在5.6及5.5版本上,相同语句返回的结果集是不同的(规则是在5.5中以在执行时报的错误信息为准),这与线上版本有关系。 121 | -------------------------------------------------------------------------------- /docs/source.md: -------------------------------------------------------------------------------- 1 | #Inception是如何诞生的 2 | ##当前审核方式对比 3 | MySQL语句需要审核,这一点每个DBA及开发人员都懂,但介于语句及环境的复杂性,大部分人都是望而却步,对其都是采取妥协的态度,从而每个公司都有自己的方法。下面介绍两种当前能用的审核方法: 4 | ###半自动化方法 5 | 在Inception出现之前,很多公司也已经进入了审核自动化阶段,但这种自动化实际上还只能算是半自动化,因为在各个方面,其使用的友好性,审核的准确性,工作效率方面,都还是比较差强人意的,不过这已经是有了很大进步了,正所谓:It's better than nothing. 6 | 那么半自动化方法是如何工作、实现的呢?下面先看图: 7 | ![](inception_images/semiauto.png) 8 | 这种半自动化方法,一般包括四部分,分别是: 9 | 10 | * 一个很强大的审核程序 11 | * 线上待执行数据库服务器 12 | * 与线上数据库对应的Beta数据库服务器(定时与线上同步数据) 13 | * 执行前用来备份数据的备份服务器 14 | 15 | 对于第一部分的审核程序,一般需要或已包括以下功能: 16 | 17 | * 具有简单的语法、语义检查功能,但一般情况下,都是做一些简单的匹配功能,而不是像MySQL一样,对SQL语句进行词法语法分析,做出精确的语法匹配及分析,所以这种情况下,实际上是很难做到精确审核,最简单的情况下,只是提取出SQL语句涉及到的数据库名、表名、列名及语句类型等,更深入复杂的分析很难做到。 18 | * 具有在提取到上面库表列等对象信息之后,还能简单通过与线上或者Beta环境对应信息的比对的功能,这样可以提前判断一些很明显的错误,这方面要尽可能的多做工作,以提高审核效率。 19 | * 具有提前分析过滤出一些高危的SQL语句,提高审核效率的功能。比如可以提前通过在线上或者Beta数据库上执行EXPLAIN命令等方式,一方面可以检验语法及语义的正确性,另一方面,可以根据影响行数、索引使用等返回信息提前过滤出可能对数据库影响比较大,或者语法语义错误的语句,从而提高审核效率。 20 | 21 | 可以具有的功能非常多,就不一一列举了,正所谓:只有你想不到的,没有你做不到的。 22 | 但是做再多,总是感觉走了弯路,总是力不从心,总是在不断的补洞,总是有补不完的洞,或者有些洞根本就补不上。 23 | 实际上,从一开始,这种方式就有问题,造成程序的可维护性差,效率低下,准确性不高等等的一系列问题。 24 | 25 | 对于第二部分的线上数据库服务器,由于第一部分的审核程序有可能存在没有审核到的漏洞,一些本身存在问题的语句被认为没有问题而审核通过,这无疑给线上数据库带来了很大的风险,所以审核的准确性一定不能忽视。 26 | 27 | 对于第三部分,因为审核程序首先要在Beta环境中执行一次,如果发现没问题后,才会去线上执行,那么这个Beta就需要时刻与线上环境保持同步,数据需要一样,数据库及表的元数据必须要保证相同,这样在Beta执行才具有参照性,不然有可能在Beta不存在问题,而在线上执行就出问题了,那么这里关键的问题是如何能保持时刻同步的问题,比如一个修改比较频繁的数据库实例上面,执行过的操作发现有问题,最终没有在线上执行,那这个再有新的审核时,无效操作如何回滚,保证不影响后面的执行?在数据量很大的情况下,不管是执行或者回滚,都是问题,在数据被频繁使用过之后,有可能Beta环境需要不定时的重新做镜像,那么做一个镜像是不是还需要晚上在低峰的时候做?在高峰的时候是不是会影响线上?如此种种,实际上都是很难解决的问题,如果走了这条路,恐怕这将是DBA的又一个噩梦。 28 | 29 | 对于最后一部分,为了防止上面第三部分中执行之后(不管是线上还是Beta数据库),数据不能回滚或恢复的问题,那么最好是在执行前将要影响的数据做个备份,这样万一出问题之后,还可以及时的回滚,以尽量减少对业务的影响时间。但是这个备份说起来简单,但真正去做的时候,发现真的是没法下手,在这里可能有下面几种选择: 30 | 31 | * 通过审核程序想办法先查出来SQL语句将要影响的数据,生成反向的回滚语句 32 | * 备份整个表,修改失败或者需要回滚的时候,直接使用这个备份表即可 33 | * 利用Binlog,通过类似闪回的功能实现数据回滚 34 | 35 | 但上面的方法中,都有不同程度的复杂及不可行性,先说第一种,这种方法,审核程序需要做更多的工作,在执行前取出SQL语句将要影响的全量数据,导出来备份,然后再去修改,但这种方法存在的问题很多,首先不是所有的增删改语句都能简单的转换为一个查询语句,然后通过这个查询语句将数据导出来,其次就是准确性问题,因为数据是一直在变的,数据量大的话,花长时间导出之后,再去执行,实际上执行影响的数据已经与备份的数据不相同了,所以备份已经没有太大意义了,最后就是审核程序自己是不知道当前SQL语句具体修改了哪些数据,或者是哪些列,当数据需要恢复时,它不知道该如何恢复。 36 | 再说第二种,很明显,这种方法对于数据量比较小的表,是可行的,因为它是某一个时刻,一个完整的备份副本。但如果数据量大一点,备份这个表的工作量是非常大的。 37 | 而对于第三种,很明显这种方法是最好的,并且也是最准确的,而一个前提是审核程序去执行的时候生成的Binlog是Row模式的。但这种方法实现起来,门槛非常高,需要全面兼容MySQL Binlog的格式,从文件中分析出数据的修改内容,同时还要在审核程序执行时,保证其执行时的thread_id及Binlog位置等信息,最后根据内容生成回滚语句。听上去非常完美,但很少人为了一个备份会去做这么复杂的工作,所以这种方式在半自动化审核中一直是没有用起来。 38 | 39 | 而在半自动化审核中,备份基本上是一个空白,因为无论对于哪种方法,都是很难实现得完美,可用。 40 | 综上所述,可以看出半自动化方法,实际上存在很多难解的问题,不易推广,每个公司都各自为战,所以导致业界没有一个可以公用的、统一的被大家认可的审核工具。 41 | 42 | ###人肉法 43 | 在MySQL审核方法中,有一种方法是最传统,门槛最低,同时也是与半自动化方法共存的一种方法,那就是人肉法,所谓“人肉法”,就是所有的审核工作都是由人工来完成,下面先看看一般的人工审核的工作方式图: 44 | ![](inception_images/noauto.png) 45 | 这种方法的交流方式一般是邮件,需要执行变更时,DEV/QA写邮件向DBA发起变更,在DBA收到之后,用“火眼金睛”目测他们写的SQL是不是有问题,这里的问题要包括下面几个方面: 46 | 47 | * 语法错误:这些错误其实真是难为我们DBA了,即使我们都是“火眼金睛”,那还是看不出来,终究不是机器人啊,比如经常有开发没有经过测试就发给DBA,会丢失分号,或者“\`”写为“'”,这可真看不出来,只有真正到线上实践后,才会发现错误。 48 | * 语义错误:这种错误,需要DBA时刻要到线上把表结构、数据量等拿出来,然后再与SQL语句中用到的对象比对,看看SQL语句中用到的列、表、库等是不是正确,那么此时也是需要DBA的高超的目测能力(也就是我们熟知的找茬能力)的,想想在一个列名中多一个字母或者少一个字母或者空格,这能看得出来么?我想未必。 49 | * 规则错误:我们对MySQL的SQL语句进行审核的目的就是想让SQL语句尽可能的统一,尽可能的减少错误,尽可能的优化SQL性能,尽可能的提高DBA运维效率,实际上,DBA定义了越多的规则,DBA越累,因为对所有的SQL语句,都要与我们的规则比对,找到不符合规则的语句及问题,那么这有点类似一个成语叫“作茧自缚”。DBA在每次拿到SQL语句后,心中都要遍历好多遍的“规则宝典”,在审核一个大项目之后,DBA长时间的高Load运算导致精疲力尽,同时又花了大半天的时间,也就是说DBA的大部分时间都花在了审核上面,这效率太低了,DBA的产出也太低了(但这些问题又不能不做啊)。 50 | * 循环审核:DBA在辛辛苦苦的找到力所能找到的错误之后,发邮件给DEV,总算能休息一会儿了,同时希望这是倒数第二次审核(因为DEV再回邮件之后,一审核,哇,都改了并且没有新问题,这多好啊,所以谓之倒数第二次审核),但经常是事与愿违,这么好的DEV能有几个啊,叮咚,邮件回过来了,说一句能改的都改好了(哎,我能知道哪些是不能改的么?),DBA需要带着之前审核出来的结果,看这些有没有改好,一个个比对(不管改好没改好,都要看一遍,因为DBA也不知道他改了哪些),实际上做的是又一次完全审核,因为这存在两方面工作,一方面是审核之前提出来的问题有没有改好,第二方面是在改的过程中,有没有引入新的问题。从上面的过程可以知道,DBA在这方面的工作量是非常大的,工作时间也基本都花在这上面,效率低下。 51 | * 主观性:对于已经定义的规则,虽然明明白白写在那里,但不同的DBA对同一条规则的理解其实是不同的,所以存在宽松不均的问题,同一个开发,面对不同DBA时,有时很轻松的通过,但有时又是铁律,搞得DEV/QA摸不着头脑,最终导致规则不成规则,很难推行下去。 52 | * 执行前检查:在上面久经折腾之后,好不容易审核通过了,可以执行了,那现在DBA需要做的事情是先对线上环境做一次检查,比如DEV写得IP是读库的虚IP还是写库的,执行语句时对线上的影响多大,对于DML语句,如果影响行数太多,可能还需要拆开再去执行,而如果是DDL,可能需要考虑晚上再去执行,或者用OSC(pt-online-schema-change)工具来执行等等。这些问题确定之后,再考虑开始执行。 53 | * 执行前备份:备份是必要的,因为语句在没有执行时,都是想不到他有影响会有多大,一般是不需要,而需要时,才知道备份是多么的重要,这也正是应了一句谚语:“书到用时方恨少;事非经过不知难。”,但这个工作也很是让人为难,应该备份全表呢?还是把影响的查出来备份呢?DBA在这个时候肯定是很不愿意这样做,但万一出问题怎么办?都懂得,不说了。 54 | * 执行出错:终于到执行阶段了,可是万万没想到,执行出错了,比较多的是语法/语义错误,此时可能要与DEV沟通,为什么发起时没有测试,通常他们会告诉你,测试过了,但贴到邮件时贴错了,此时DBA可能需要手动一个一个把出现错误的地方修改过来再执行,而需要注意的是,出现之前的那些语句已经执行完了,需要把那些语句去掉,而如果这样的问题在一次执行中出现多次的话,执行过程也会耗费掉不少时间。 55 | * 执行后检查:这个工作一般就是DEV/QA的事情了,DBA在执行完后,通知执行完成,并做检查,之后DBA的事情是等待(类似信号等待),或者可以切换到其它线程去处理其它数据变更请求。当DEV/QA告诉你检查没事儿了,这个事儿才算结束。 56 | 57 | 一个DBA一天的时间往往都被这些不想做而必须要去做的事情困扰着,同时DB组还发现人力根本不够,还需要招人(难道招人来了还是去干这些事情么?),DBA难道就是只干这些事情的人么?不是!!! 58 | 59 | DBA苦审核久矣! 60 | 61 | ##做DBA不久后的思考 62 | 在做一段时间DBA之后,发现DBA的工作根本苦水堪言,基本所有时间都被这些繁冗的事情困扰着,根本没有多余时间去做一些更高大上的工作,比如读读源码等。 63 | 64 | 后来听说一些大公司,都有一些自动化审核工具,此时我如拨云雾而见青天,心想现在不正是自动化运维所兴起的时代么,这种工作完全可以由自动化工具所代替,想到这里不由得感到一种兴奋。 65 | 66 | 后来就开始调研他们的审核工具的实现方式,但后来发现,基本都是上面提到的半自动化实现方法,感觉总是不怎么理想,DBA的负担还是非常重,想着如何能优化,或者有一种更好的方案。 67 | 68 | 忽然有一天,我正在审核一堆的建表语句,因为要有一个大项目上线,我已经心力交瘁了,突然一个念头,MySQL可以执行任何提交给他的MySQL SQL语句,并且如果存在任何问题,都会提前报出来,为什么?不就是因为它支持么(好像是废话),但关键问题就是在这里,MySQL可以执行那些SQL语句,那么是不是可以搞一个和MySQL完全兼容的东西,去审核这些SQL语句呢?或者说,我如果把MySQL切隔改造,让它不去执行,而是分析之后,找出存在问题的地方,这样不就解决了审核准确的第一难题了么?想到这里,一股暖流流过心头,那时,好像在远方的某个地方,看到了希望之火——哦,那是太阳! 69 | 70 | 现在,终于,Inception从此诞生了,它是关于DBA的一个美好的故事。 71 | 72 | -------------------------------------------------------------------------------- /docs/statistic.md: -------------------------------------------------------------------------------- 1 | #Inception 的统计功能 2 | 在使用了Inception之后,数据变更已经全面进入全自动化模式,有了这个利器之后,一些以往想做而做不成的事情,现在可以做了,比如对SQL执行情况的统计,修改表的语句究竟占多大的比例,或者数据变更占多大比例,那么使用Inception,这个事情就轻而易举了,并且非常准确。 3 | 4 | SQL统计功能涉及到的参数为: **inception_enable_sql_statistic**, 这个参数在前面的<<**Inception所支持的参数变量**>>一章中已经介绍过,那么这里主要说一下它的使用方法。 5 | 6 | 除了上面的参数之外,使用这个功能还需要开启操作备份功能,因为这些统计数据需要存储到备份数据库中,存储的数据库名为**inception**中,这个数据库主要是用来存储Inception的一些统计信息的,现在只有一个表**statistic**,这个表存储的就是SQL执行数目的统计数据,而以后有可能还会做一些扩展而新生成一些表。 7 | 8 | **statistic**表的结构如下: 9 | ![](inception_images/statistic.png) 10 | 11 | 从每一个列的名字就可以看到,其值对应的操作是什么,每一个列就是一个自增列,第二个列optime是操作时间,这个主要是用来统计在某一段时间内的某一个操作占多少比例。 12 | 13 | 下面解释一下有些不太明确的列的意义: 14 | **deleting**:包括普通的删除操作及多表删除操作。 15 | **inserting**:包括单行插入、多行插入及查询插入。 16 | **updating**:包括普通单表更新及多表的更新。 17 | **renaming**:指的是ALTER table语句中的rename操作。 18 | **createindex**:指的是ALTER table语句中的add index操作。 19 | **dropindex**:指的是ALTER table语句中的drop index操作。 20 | **alteroption**:指的是ALTER table语句中的修改表属性的操作,比如存储引擎、自增值及字符集中操作。 21 | **alterconvert**:指的是ALTER table语句中修改表字符集的操作。 22 | 23 | 对于ALTER TABLE操作,因为这个操作包含很多的子操作,比如rename、drop index、engine innodb等操作,所以对于列altertable,它的值是renaming, createindex, dropindex, addcolumn, dropcolumn, changecolumn, alteroption, alterconvert的和, 而后面的是对ALTER TABLE语句的细分操作统计。 24 | 25 | 那么如果现在想要统计某一个操作,比如修改表占所有操作的百分比,则使用如下语句即可完成: 26 | ```` 27 | select sum(a.oprate)/count(1) updaterate from 28 | (select (updating)/(usedb+deleting+inserting+updating+selecting+altertable+ 29 | createtable+droptable+createdb+truncating) oprate from 30 | inception.statistic) a; 31 | ```` 32 | 33 | #需要注意的问题 34 | 因为Inception的审核、执行及备份是分阶段的,只有前面的阶段执行成功之后,才能进入下一个步骤,那么针对一块语句的操作统计,只有在开始备份时才会将统计信息存储起来,那么当前面执行、审核有问题导致提前返回时,统计是不是会被更新的,只有成功执行了,才会被记录下来。而如果是后面备份时出错导致提前返回,那么统计信息是被成功存储的。 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /docs/usage.md: -------------------------------------------------------------------------------- 1 | #Inception使用方法 2 | Inception实际上是一个服务程序,那么它应该有自己的一套友好的使用方式,必须要具备简单、高效、易用等特性。那么为了让Inception具有这些特点,在设计之初,就规定了它的使用方式,如下所述。 3 | 4 | 通过Inception对语句进行审核时,必须要告诉Inception这些语句对应的数据库地址、数据库端口以及Inception连接数据库时使用的用户名、密码等信息,而不能简单的只是执行一条sql语句,所以必须要通过某种方式将这些信息传达给Inception。而我们选择的方式是,为了不影响语句的意义,将这些必要信息都以注释的方式放在语句最前面,也就是说所有这些信息都是被 5 | /\*\*/括起来的,每一个参数都是通过分号来分隔,类似的方式为: 6 | `/*--user=username;--password=xxxx;--host=127.0.0.1;--port=3306;*/` 7 | 当然支持的参数不止是这几个,后面还会介绍一些其它的参数。 8 | Inception要做的是一个语句块的审核,需要引入一个规则,将要执行的语句包围起来,Inception规定,在语句的最开始位置,要加上`inception_magic_start;`语句,在执行语句块的最后加上`inception_magic_commit;`语句,这2个语句在 Inception 中都是合法的、具有标记性质的可被正确解析的 SQL 语句。被包围起来的所有需要审核或者执行的语句都必须要在每条之后加上分号,其实就是批量执行SQL语句。(包括 `use database`语句之后也要加分号,这点与 MySQL 客户端不同),不然存在语法错误。 9 | 10 | 在具体执行时,在没有解析到**inception_magic_start**之前如果发现要执行其它的语句,则直接报错,因为规则中**inception_magic_start**是强制的。而如果在执行的语句块最后没有出现**inception_magic_commit**,则直接报错,不会做任何操作。 11 | 在前面注释部分,需要指定一些操作的选项,包括线上用户名、密码、数据库地址、检查/执行等,下面是一个简单的例子: 12 | ```` 13 | /*--user=zhufeng;--password=xxxxxxxxxxx;--host=xxxxxxxxxx; 14 | --enable-check;--port=3456;*/ 15 | inception_magic_start; 16 | use mysql; 17 | CREATE TABLE adaptive_office(id int); 18 | inception_magic_commit; 19 | ```` 20 | ------------------ 21 | **注意:下面说明非常重要,请认真看** 22 | 那么上面这一段就是一批正常可以执行的SQL语句,目前执行**只支持通过C/C++接口、Python接口来对Inception访问**,这一段必须是**一次性**的通过执行接口提交给Inception,那么在处理完成之后,Inception会返回一个结果集,来告诉我们这些语句中存在什么错误,或者是完全正常等等。 23 | 24 | 请不要将下面的SQL语句块,放到MySQL客户端中执行,因为这是一个自动化运维工具,如果使用交互式的命令行来使用的话没有意义,只能是通过写程序来访问Inception服务器。 25 | 26 | 而可以通过MySQL客户端来执行的,只有是Inception命令,请参考<<**inception命令集语句**>>一节。 27 | 28 | 下面是一段执行上面语句的Python程序的例子: 29 | 30 | ----------------- 31 | ````python 32 | \#!/usr/bin/python 33 | \#-\*-coding: utf-8-\*- 34 | import MySQLdb 35 | sql='/*--user=username;--password=password;--host=127.0.0.1;--execute=1;--port=3306;*/\ 36 | inception_magic_start;\ 37 | use mysql;\ 38 | CREATE TABLE adaptive_office(id int);\ 39 | inception_magic_commit;' 40 | try: 41 | conn=MySQLdb.connect(host='127.0.0.1',user='',passwd='',db='',port=9998) 42 | cur=conn.cursor() 43 | ret=cur.execute(sql) 44 | result=cur.fetchall() 45 | num_fields = len(cur.description) 46 | field_names = [i[0] for i in cur.description] 47 | print field_names 48 | for row in result: 49 | print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|", 50 | row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10] 51 | cur.close() 52 | conn.close() 53 | except MySQLdb.Error,e: 54 | print "Mysql Error %d: %s" % (e.args[0], e.args[1]) 55 | ```` 56 | 57 | 执行这段程序之后,返回的结果如下: 58 | ```` 59 | ['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 60 | 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1'] 61 | 1 | CHECKED | 0 | Audit completed | None | use mysql | 0 | '0_0_0' | None | 0 | 62 | 2 | CHECKED | 1 | Audit completed | Set engine to innodb for table 'adaptive_office'. 63 | Set charset to one of 'utf8mb4' for table 'adaptive_office'. 64 | Set comments for table 'adaptive_office'. 65 | Column 'id' in table 'adaptive_office' have no comments. 66 | Column 'id' in table 'adaptive_office' is not allowed to been nullable. 67 | Set Default value for column 'id' in table 'adaptive_office' 68 | Set a primary key for table 'adaptive_office'. | CREATE TABLE adaptive_office(id int) 69 | | 0 | '0_0_1' | 127_0_0_1_3306_mysql | 0| 70 | ```` 71 | 72 | 从返回结果可以看到,每一行语句的审核及执行信息,最前面打印的是field_names,表示Inception的返回结果集的列名信息,总共包括十个列,下面是每个列对应的结果,因为只有两个语句,则只有两行,从结果集第一个列看到只有序号为1和2的两行,而对于每一个列的具体含义,这会在<<**Inception结果集**>>这一章中讲到,这里只看清楚是什么内容即可。 73 | 74 | **注意**:最后一个“|”后面其实是存储列sqlsha1的,但这里没有改表语句,所以都是空,关于这个信息,请看<<**Inception结果集**>>一章及<<**Inception 对OSC的支持**>>一章中相关说明。 75 | 76 | 77 | ------------- 78 | 79 | **需要注意的是**,在注释中指定的数据库服务器,必须要有Inception访问它的权限,不然Inception会返回没有访问权限的错误。 80 | 81 | -------------------------------------------------------------------------------- /docs/users.md: -------------------------------------------------------------------------------- 1 | #Inception使用企业 2 | ![](inception_images/users.png) 3 | 4 | -------------------------------------------------------------------------------- /docs/variables.md: -------------------------------------------------------------------------------- 1 | #Inception所支持的参数变量 2 | 考虑到不同用户的规范会有所不同,Inception支持很多可配置的参数,这些配置参数都是全局参数,因为对于同一个服务的规则,不应该经常变化,或者说不应该出现一些业务是这样的规则,而另一些业务是那样的规则,所以这些变量一经设置,就影响所有的审核。如果确实一个公司有多个规则,则建议配置多套Inception服务,在各自的配置文件中指定相应的参数的值。 3 | 4 | 设置或者打印这些变量的值,可以通过MySQL客户端连接到Inception服务器,通过新的语法命令来实现。连接Inception的时候,只需要指定Inception的地址及端口即可,其它用户名密码可以不指定,因为Inception没有权限验证的过程。 5 | 6 | Inception打印变量时,不支持像原来的MySQL服务器一样可以**`show variables like ‘%name%’`**这样实现模糊匹配,只能是精确匹配,如果找不到则返回空结果集,或者可以打印所有变量。语法如下: 7 | 8 | ---- 9 | |支持语句 | 意义 | 10 | |:----------|:--------------------| 11 | |inception get variables ‘variable_name’; |通过variable_name指定变量名称,只显示指定的变量名的值| 12 | |inception get variables; |显示Inception所有变量的值| 13 | |inception set variable_name=value; |设置变量名为variable_name的变量的值| 14 | 15 | ----- 16 | Inception目前所支持的变量参数如下表所示: 17 | 18 | ----------------- 19 | |参数名字 |可选参数 |默认值 |功能说明| 20 | |:-------------------------------------------------|:-----------------------|:---------------:|:-----------| 21 | |inception_check_insert_field |ON/OFF |ON |是不是要检查插入语句中的列链表的存在性| 22 | |inception_check_dml_where |ON/OFF |ON |在DML语句中没有WHERE条件时,是不是要报错| 23 | |inception_check_dml_limit |ON/OFF |ON |在DML语句中使用了LIMIT时,是不是要报错| 24 | |inception_check_dml_orderby |ON/OFF |ON |在DML语句中使用了Order By时,是不是要报错| 25 | |inception_enable_select_star |ON/OFF |ON |Select*时是不是要报错| 26 | |inception_enable_orderby_rand |ON/OFF |ON |order by rand时是不是报错| 27 | |inception_enable_nullable |ON/OFF |ON |创建或者新增列时如果列为NULL,是不是报错| 28 | |inception_enable_foreign_key |ON/OFF |ON |是不是支持外键| 29 | |inception_max_key_parts |1-64 |5 |一个索引中,列的最大个数,超过这个数目则报错| 30 | |inception_max_update_rows |1-MAX |10000 |在一个修改语句中,预计影响的最大行数,超过这个数就报错| 31 | |inception_max_keys |1-1024 |16 |一个表中,最大的索引数目,超过这个数则报错| 32 | |inception_enable_not_innodb |ON/OFF |OFF |建表指定的存储引擎不为Innodb,不报错| 33 | |inception_support_charset |MySQL支持字符集 |"utf8mb4" |表示在建表或者建库时支持的字符集,如果需要多个,则用逗号分隔,影响的范围是建表、设置会话字符集、修改表字符集属性等| 34 | |inception_check_table_comment |ON/OFF |ON |建表时,表没有注释时报错| 35 | |inception_check_column_comment |ON/OFF |ON |建表时,列没有注释时报错| 36 | |inception_check_primary_key |ON/OFF |On |建表时,如果没有主键,则报错| 37 | |inception_enable_partition_table |ON/OFF |OFF |是不是支持分区表| 38 | |inception_enable_enum_set_bit |ON/OFF |OFF |是不是支持enum,set,bit数据类型| 39 | |inception_check_index_prefix |ON/OFF |ON |是不是要检查索引名字前缀为"idx_",检查唯一索引前缀是不是"uniq_"| 40 | |inception_enable_autoincrement_unsigned |ON/OFF |ON |自增列是不是要为无符号型| 41 | |inception_max_char_length |1-MAX |16 |当char类型的长度大于这个值时,就提示将其转换为VARCHAR| 42 | |inception_check_autoincrement_init_value |ON/OFF |ON |当建表时自增列的值指定的不为1,则报错| 43 | |inception_check_autoincrement_datatype |ON/OFF |ON |当建表时自增列的类型不为int或者bigint时报错| 44 | |inception_check_timestamp_default |ON/OFF |ON |建表时,如果没有为timestamp类型指定默认值,则报错| 45 | |inception_enable_column_charset |ON/OFF |OFF |允许列自己设置字符集| 46 | |inception_check_autoincrement_name |ON/OFF |ON |建表时,如果指定的自增列的名字不为ID,则报错,说明是有意义的,给提示| 47 | |inception_merge_alter_table |ON/OFF |ON |在多个改同一个表的语句出现是,报错,提示合成一个| 48 | |inception_check_column_default_value |ON/OFF |ON |检查在建表、修改列、新增列时,新的列属性是不是要有默认值| 49 | |inception_enable_blob_type |ON/OFF |ON |检查是不是支持BLOB字段,包括建表、修改列、新增列操作| 50 | |inception_enable_identifer_keyword |ON/OFF |OFF |检查在SQL语句中,是不是有标识符被写成MySQL的关键字,默认值为报警。| 51 | |auto_commit|ON/OFF|OFF|这个参数的作用是为了匹配Python客户端每次自动设置auto_commit=0的,如果取消则会报错,针对Inception本身没有实际意义| 52 | |bind_address|string|*|这个参数实际上就是MySQL数据库原来的参数,因为Incpetion没有权限验证过程,那么为了实现更安全的访问,可以给Inception服务器的这个参数设置某台机器(Inception上层的应用程序)不地址,这样其它非法程序是不可访问的,那么再加上Inception执行的选项中的用户名密码,对MySQL就更加安全| 53 | |general_log|ON/OFF|ON|这个参数就是原生的MySQL的参数,用来记录在Inception服务上执行过哪些语句,用来定位一些问题等| 54 | |general_log_file|string|inception.log|设置general log写入的文件路径| 55 | |inception_user|string|empty|这个用户名在配置之后,在连接Inception的选项中可以不指定user,这样线上数据库的用户名及密码就可以不暴露了,可以做为临时使用的一种方式,但这个用户现在只能是用来审核,也就是说,即使在选项中指定--enable-execute,也不能执行,这个是只能用来审核的帐号。| 56 | |inception_password|string|empty|与上面的参数是一对,这个参数对应的是选项中的password,设置这个参数之后,可以在选项中不指定password| 57 | |inception_enable_sql_statistic|ON/OFF|ON|设置是不是支持统计Inception执行过的语句中,各种语句分别占多大比例,如果打开这个参数,则每次执行的情况都会在备份数据库实例中的inception库的statistic表中以一条记录存储这次操作的统计情况,每次操作对应一条记录,这条记录中含有的信息是各种类型的语句执行次数情况,具体的信息需要参考后面一章<<**Inception 的统计功能**>>| 58 | |inception_read_only|ON/OFF|OFF|设置当前Inception服务器是不是只读的,这是为了防止一些人具有修改权限的帐号时,通过Inception误修改一些数据,如果inception_read_only设置为ON,则即使开了enable-execute,同时又有执行权限,也不会去执行,审核完成即返回| 59 | |inception_check_identifier|ON/OFF|ON|打开与关闭Inception对SQL语句中各种名字的检查,如果设置为ON,则如果发现名字中存在除数字、字母、下划线之外的字符时,会报Identifier "invalidname" is invalid, valid options: [a-z,A-Z,0-9,_].| 60 | 61 | ------- 62 | 63 | #注意事项 64 | 上面已经说了,可以用MySQL客户端通过命令`inception get variables;`查看Inception支持的所有参数变量,所有以inception开头的参数,都是专门为Inception加的,而其它的则大都是MySQL原生的,大部分没有任何作用的都已经去除了,有些则没有,这个在使用过程中可着情处理。 65 | 而以inception开头的参数中,还有一部分是以inception_osc开头的,这十几个参数主要是用来控制Inception使用OSC工具来执行ALTER表操作时使用的,这部分会在后面一章<<**Inception 对OSC的支持**>>中详细叙述。 66 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Inception使用规范及说明文档 2 | theme: readthedocs 3 | pages: 4 | - [index.md, 'Inception使用规范及说明文档'] 5 | - [chapter1.md, 'Inception序'] 6 | - [source.md, '1. Inception 是如何诞生的'] 7 | - [inception.md, '2. Inception 总述及体系结构'] 8 | - [install.md, '3. Inception 安装说明'] 9 | - [usage.md, '4. Inception 使用方法'] 10 | - [option.md, '5. Inception 支持选项及意义'] 11 | - [backup.md, '6. Inception 备份功能说明'] 12 | - [rules.md, '7. Inception 审核规范及原则'] 13 | - [variables.md, '8. Inception所支持的参数变量'] 14 | - [results.md, '9. Inception结果集'] 15 | - [command.md, '10. Inception命令集'] 16 | - [requires.md, '11. Inception 对线上配置需求'] 17 | - [extras.md, '12. Inception 额外功能说明'] 18 | - [osc.md, '13. Inception 对OSC的支持'] 19 | - [statistic.md, '14. Inception 的统计功能'] 20 | - [queryprint.md, '15. Inception 语法树打印'] 21 | - [release.md, '16. Inception 发布日志'] 22 | - [users.md, '17. Inception 使用企业'] 23 | --------------------------------------------------------------------------------