MySQL语句的审核,在业界都已经基本被认同了,实际上也是对MySQL语句写法的统一化,标准化,而以前的人工审核,针对标准这个问题实际上是很吃力的,标准越多,DBA越累,开发也越累。 那么在这个都追求自动化运维的时代,审核也必需要跟上步伐,所以Inception诞生了。而Inception能够作的工做远不止是一个自动化审核工具,同时还具有执行,生成对影响数据的回滚语句(相似闪回的功能),这样一条龙服务的工具,将会给DBA的工做带来翻天覆地的变化,DBA今后就从繁重的审核、登上去执行,出错了很难回滚(若是提早没有备份的话)的被动局面解放了出来,忽然发现,作DBA原来能够这么轻松,工做能够不饱和了,那就有更多的自由时间学习、进一步向自动化运维平台的实现等更智能化的方向去发展,是具备里程碑意义的。 python
Inception是集审核、执行、回滚于一体的一个自动化运维系统。它是根据MySQL代码修改过来的。mysql
相对于应用程序(上层审核流程系统等)而言,它是一个服务器,在链接时须要指定linux
安装依赖项c++
yum install cmake ncurses-devel gcc gcc-c++ openssl-devel
移除bison较新的版本git
yum remove bison –y
从http://ftp.gnu.org/gnu/bison/ 路径,下载 bison-2.6.1.tar.gz 指定版本。下载后,上传至服务器。github
解压并安装bisonsql
tar zxvf bison-2.6.1.tar.gz cd bison-2.6.1 ./configure && make && make install
下载数据库
wget https://github.com/qunarcorp/inception/archive/master.zip
解压服务器
unzip master.zip
cd inception-master
./inception_build.sh debug [Xcode]
指定路径下建立inc.cnf网络
touch /data/Inception/inc.cnf
初始化
/data/Inception/inception-master/debug/mysql/bin/Inception --defaults-file=/data/Inception/inc.cnf &
(##Inception 最佳启动方式是经过nohup后台启动
nohup /data/Inception/inception-master/debug/mysql/bin/Inception --defaults-file=/data/Inception/inc.cnf &
)
找到初始化后的Inception
关闭Inception
kill -9 7927
[inception] general_log=1 general_log_file=inc.log port=6669 socket=/tmp/inc.socket character-set-client-handshake=0 character-set-server=utf8 inception_remote_system_password=备份库密码 inception_remote_system_user=备份库帐号 inception_remote_backup_port=备份库实例端口 inception_remote_backup_host=备份库IP inception_support_charset=utf8mb4,utf8,latin1 inception_enable_nullable=0 inception_check_primary_key=1 inception_check_column_comment=1 inception_check_table_comment=1 inception_osc_min_table_size=1 inception_osc_bin_dir=/data/temp inception_osc_chunk_time=0.1 inception_ddl_support=1 inception_enable_blob_type=1 inception_check_column_default_value=1
(若是执行 ./inception_build.sh debug [Xcode] 命令报错,可将inception-master目录删除,从新解压,而后用
./inception_build.sh build linux 替代。固然,此时的可执行文件 在 /data/Inception/inception-master/build/mysql/bin/Inception
更多的安装知识,可参阅 https://qunarcorp.github.io/inception/install/)
经过mysql 客户端链接
执行 代码验证
inception get variables;
参数名 | 是否须要参数 | 是否可选 | 功能描述 |
--host | 是 | 否 | 须要操做的这部分语句块对应的数据库地址。指定方式能够是IP地址、机器名或DNS域名等,只能惟一解析到这个机器便可。 |
--port | 是 | 否 | 与上面的--host选项对应,指定机器名,必然要再指定一个MySQL实例的端口。 |
--user | 是 | 否 | 经过--user指定的用户名来链接须要操做SQL语句的MySQL实例。 |
--password | 是 | 否 | 与上面的--user选项对应。 |
--sleep | 是 | 是 | 这个参数用来指定在执行完每一条语句后,暂停多少毫秒,这样能够适当控制对线上数据库的冲击,特别是针对大量的写入操做, 单位是毫秒,最小值为0,也就是不暂停,最大值为100秒,也就是100000毫秒。若是设置的值超过了100000毫秒, Inception会自动将其设置为100000毫秒。这个参数能够和其余参数一块儿设置,可是只有在--enable-execute为1的状况下,才起做用。 |
--enable-check | 否 | 否 | 告诉Inception当前要作什么操做,是审核仍是执行,这个参数与下面的--enable-execute智能指定一个。enable-check就是要告诉Inception, 当前的请求是要作审核操做,审核完成后就返回结果集。 |
--enable-execute | 否 | 否 | 若是执行的选项是--enable-execute,则Inception在执行前还会作一次实时的审核,这个审核和前面指定的--enable-check时的 审核是基本相同的,这是此次在审核完成后,还会继续进行。由于相同的语句在不一样的时间审核可能会产生不一样的审核结果(环境有可能变了), 因此有必要再作一次审核。若是审核发现了错误(而不是警告),就不会被执行,此时会提早返回告知错误;若是审核发现的是警告, 而且没有指定--enable-ignore-warnings,则有警告也不会执行。 |
--enable-ignore-warnings | 否 | 是 | Inception采起严格的分阶段处理方式,先对全部的语句进行审核,审核完成以后,会执行全部的语句,以后再会执行全部语句的备份操做。 在三个阶段的过渡过程当中,若是审核有问题则不会继续进行,此时若是人为肯定想要跳过这些警告,则能够选择这个参数, 告诉Inception跳过这个警告的检查,继续执行。 |
--enable-force | 否 | 是 | 批量导入时,有可能会报主键冲突的问题,而DBA能够肯定的是,出现主键冲突不是问题,能够继续执行,那么此时能够经过选项 --enable-force告诉Inception,在执行过程当中碰到一个错误时,能够先保存错误信息并继续下一条语句。此参数需谨慎使用。 |
--enable-remote-back | 否 | 是 | Inception支持备份并生成对应的回滚语句,这是默认的,但当有些影响行数不少且明确不须要回滚的时候,为了提升执行效率, 能够指定在执行时不作备份,指定方式是经过disable来禁用它,即disable-remote-backup。 |
--enable-split | 否 | 是 | 这个参数用来拆分要执行的语句块。若是在语句块中存在对同一个表的DDL操做和DML操做,那么在分析Binlog来生成回滚语句时, 因为表结构已经发生改变,会致使Inception没有办法处理,因此使用这个参数将这些语句分红多批,而后再分别执行。这是在执行前 必需要作的一个操做,否则可能会产生不可预知的错误。固然在执行前的最后一次审核中,若是检查到这样的混用状况, 则会返回报错,而不是警告。 |
--enable-query-print | 否 | 是 | 这个参数用来打印SQL语句在被Inception分析以后的执行树结构,已JSON的形式提供,目的是为了能够在Inception的基础上, 对已经结构化的(JSON)语句再次分析,能够对Inception内置支持的规则进行扩展,作个性化定制,好比使用到哪些列、 哪些语句类型等信息。 |
返回列 | 详细描述 |
ID | 用来表示结果集中记录序号的,也就是被审核的语句在语句块中的序号,按位置排序,计数从1开始。 |
stage | 显示当前语句已经进行到哪一步了,包括四个值:CHECKED、EXECUTED、RERUN和NONE。CHECKED表示这个语句只作审核,而没有再进行下一步操做;EXECUTED表示已经执行过, 若是执行失败,也是用这个状态表示,RERUN表示的是,对于影响上下文的语句,已经执行成功了,可是为了与EXECUTED区分,用RERUN表示,主要是由于在执行过程当中,若是某一条语句 执行失败了,则上层可能须要将没有执行的语句提取出来,再次执行,那么影响上下文的语句就是须要加上的,因此用RERUN来表示。Inception目前支持两种影响上下文的语句,分别是 set names charset 语句和use database语句。NONE表示没有作过任何处理,有可能前面有语法错误直接提早返回。 |
errlevel | 总共有三个值,分别是0、一、2。若是为0,则说明当前语句审核没有任何问题;若是为1,则说明当前语句审核时发现有些写法不符合Inception定义的内置规则,属于警告;若是值为2,则说明 当前语句审核时,发现了严重错误,不管如何都不能经过的。 |
stagestatus | 该列用来描述当前语句的阶段结果,与列stage对应。若是是审核阶段,而且完成,则返回Audit completed。若是是执行阶段,而且执行成功则返回Execute Successfully,不然返回Execute failed。若是是备份阶段,而且备份成功,则在执行描述信息后面追加Backup successfully,不然追加Backup failed。 |
errormessage | 用来表示出错的错误信息,这里包括一条语句中的全部错误信息,用换行符分隔,但有时候若是某一个错误致使不能继续分析了,好比表不存在等问题,在这种状况下,若是语句还有其余错误, 就不能被审核出来了。若是当前语句没有任何错误,则这个列值为NONE。对于执行及备份操做,由于对于一条语句,这样的错误只会有一次,那么执行错误会在执行后面追加:“execute:具体 的执行错误缘由”,若是是备份出错,则在后面追加“backup:具体的错误缘由”。在执行时,有时候还会出现Warning。 |
SQL | 用来表示当前检查的是那条SQL语句,这一列存储的值就是这条SQL语句的文本内容。 |
affected_rows | 审核时,用来表示当前语句预计影响的行数,这个行数通常是经过EXPLAIN来获取的。在执行时,该列输出的是执行时真实影响的行数。 |
sequence | 该列与Inception备份功能有关,其实就是与$_$Inception_backup_information$_$表中的列opid_time一一对应,这就为自动化运维平台针对某一条语句作回滚操做找到了入口。 |
backup_dbname | 该列表示的是当前语句产生的备份信息,存储在备份服务器的那个数据库中。若是是不须要备份的语句,则返回字符串NONE。 |
excute_time | 该列表示当前语句的执行时间,单位是秒,精确到小数点后两位。列类型是字符串。若是只是审核而不执行,则该列返回的值为0. |
SQLSHA1 | 这一列用来存储当前这条语句的一个HASH值,用来标识这个语句是否会使用OSC功能,若是返回信息中有值,则表示这条语句在执行时会使用OSC。 |
Inception在作DML操做时,具备备份功能。它会将全部当前语句修改的行对应生成回滚语句并备份下来,同时也会将全部操做的任务备份下来,一块儿存储到一个指定的库中。
参数 | 说明 |
inception_remote_backup_host | 指定远程备份MySQL实例的地址。 |
inception_remote_backup_port | 指定远程备份MySQL实例的端口。 |
inception_remote_system_user | 备份时,链接备份MySQL实例时所需的用户名,这个用户须要有相应的权限,通常包括Create、Insert和Select权限。 |
inception_remote_system_password | 备份时,链接备份库时所须要的用户对于的密码。 |
由于线上机器有不少,而备份机器只有一台,因此为了防止在备份数据库实例中存在库名冲突的问题,备份机器的库名是将线上机器IP地址的点换成下划线,再加上端口号及库名。
例如:
169_169_167_167_3306_testDB.
主要有两类,一种针对线上每个表生产一个备份表,即与线上的表是一一对应的,表名相同,可是表结构不同。备份表主要用来存储全部对表修改的回滚语句。
主要有如下3列:
列名 | 说明 |
id | 标识列 |
rollback_statement | 当某一行被修改后,生成的对应的回滚语句。由于Binlog必须为Row模式,因此,不论是什么语句,产生的回滚语句都是针对被修改的行记录的。 若是一条语句的执行,影响了多行,那么这里就会有多条回滚语句。 |
opid_time |
执行SQL语句时获取的一个序列号。序列号由三部分组成:timestamp(int值,是语句执行的时间点)、线上服务器执行时所产生的thread_id及 当前这条语句在全部被执行语句块中的一个序号。序列号在指定的备库中是惟一的。针对同一条语句影响多行的状况、在产生的多行回滚语句中, 该列的值是相同的。 |
还有一类表,其实这个表每一个库中只有一个,$_$Inception_backup_information$_$。该表主要用来记录全部对当前库的操做,它是为该库中全部表服务的,对线上这个库的全部的表的操做,都会被存储在这里面。
参数 | 说明 |
opid_time | 该列与上面备份表中的列opid_time是一一对应的,由于这个表中的每一行对应的是在线上执行的实际的一条SQL语句。 opid_time从各个备份表中查找这条语句对应的回滚语句,是一对多的关系。 |
start_binlog_file | 表示执行这条语句前Binlog所在的位置的文件名。这个值是经过 show master status 获取的,在数据库并发比较高的状况下, 这个值不必定准确。这个值只能是这条语句产生Binlog前面的某个位置。同理。下面三个位置信息也是同样。 |
start_binlog_pos | 该列与上面的列对应,表示的是上面指定文件的位置信息。 |
end_binlog_file | 该列表示的是执行当前语句以后,Binlog所在的文件名。 |
end_binlog_pos | 该列与上面的列对应,表示执行完成后,Binlog在文件end_binlog_file中的偏移位置。 |
sql_statement | 该列存储的是当前这个被执行的SQL语句。 |
host | 表示在线上的哪一个数据库实例上执行了该语句。 |
dbname | 表示执行当前语句时所处的环境变量,指的是数据库名。 |
tablename | 表示当前语句影响的表的表名,经过这个名字对应到备份表名。 |
port | 与host对应,表示执行时数据库的端口号。 |
time | 表示当前语句的执行时间 |
type | 表示操做类型,如今只支持INSERT、UPDATE、DDELETE、CREATEDB、CREATETABLE、ALTERTABLE、DROPTABLE等类型。 |
测试环境
类别 | ServerIP | Port |
线上数据库 | XXX.XXX.XXX.9 | 3306 |
Inception | XXX.XXX.XXX.8 | 6669 |
备份数据库 | XXX.XXX.XXX.9 | 3307 |
测试python脚本
#!/usr/bin/python #-*- coding:utf-8 -*- import MySQLdb sql='''/*--user=数据库帐号;--password=相应密码;--host=XXX.XXX.XXX.9;--execute=1;--port=3306;*/\ inception_magic_start;\ use dbtest;\ CREATE TABLE table_test(id int comment 'test' primary key) engine=innodb DEFAULT CHARSET=utf8mb4 comment '测试';\ inception_magic_commit;''' try: conn=MySQLdb.connect(host='XXX.XXX.XXX.8',user='',passwd='',db='',port=6669) cur=conn.cursor() ret=cur.execute(sql) result=cur.fetchall() num_fields = len(cur.description) field_names = [i[0] for i in cur.description] print field_names for row in result: print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10] cur.close() conn.close() except MySQLdb.Error as e: print "Mysql Error %d: %s" % (e.args[0], e.args[1])
执行结果以下:
去备份库上查看,备份状况以下:
若是在测试的过程当中,发现没有实现备份,能够从如下几个方面去检查
(1)线上服务器必需要打开Binlog,在启动时须要设置参数log_bin、log_bin_index等关于Binlog的参数。否则不会备份及生成回滚语句,由于Inception的生成回滚语句是经过解析Binlog来作的。
(2)参数必须binlog_format必须设置为mixed或者row模式。若是是statement模式,则不作备份及回滚语句的生成。可经过语句set global binlog_format=ROW来设置。
(3)将binlog_row_image设置为full ,该配置项默认为 full ,可是若是为了减小binlog的size改为minimal的话,则Inception没法生成回滚语句。
(4)参数server_id必须设置为非0非1,经过语句set global server_id=server_id;来设置,否则在备份时报错。由于在获取Binlog时,须要经过server_id在主库上注册Inception。
(5)被修改表须要有主键:执行时,被影响的表若是没有主键的话,就不会作备份了。这样更简单而且备份时间及数据都会少一点,否则回滚语句的where条件就会将全部列写进去,这样会影响性能且没有太大意义,因此在where条件中,只须要主键便可。
(6)备份相关的四个参数须要设置好,而且对应的用户在备份数据库实例中有足够的权限。
1执行 Python验证,报错信息。
ImportError: No module named MySQLdb
解决方案:
yum install MySQL-python
2.有时候执行Python脚本报错:invalid source infomation。
这时候须要去检查Inception链接数据库的参数配置。
其数据存储在备份实例上的inception数据库上statistic表中,此库自动生成。
主要字段的说明以下:
列名 | 字段描述 |
deleting | 包括普通的删除操做及多表删除操做。 |
inserting | 包括单行插入、多行插入及查询插入。 |
updating | 包括普通单表更新及多表的更新。 |
renaming | 指的是ALTER table语句中的rename操做。 |
createindex | 指的是ALTER table语句中的add index操做。 |
dropindex | 指的是ALTER table语句中的drop index操做。 |
alteroption | 指的是ALTER table语句中的修改表属性的操做,好比存储引擎、自增值及字符集中操做。 |
alterconvert | 指的是ALTER table语句中修改表字符集的操做。 |
-----主要内容参考梳理于网络知识和《MySQL运维内参》,此短文仅为学习笔记,在此原创做者感谢!