Inception安装测试文档

一、Inception介绍

  • Inception是由去哪儿团队开发的一个集审核、执行、备份及生成回滚语句于一身的MySQL自动化运维工具
  • MySQL语句的审核,在业界都已经基本被认同了,实际上也是对MySQL语句写法的统一化,标准化,而之前的人工审核,针对标准这个问题其实是很吃力的,标准越多,DBA越累,开发也越累。那么,在这个都追求自动化运维的时代,审核也必须要跟上步伐,因此Inception诞生了。而Inception可以做的工作远不止是一个自动化审核工具,同时还具备执行,生成对影响数据的回滚语句(类似闪回的功能),这样一条龙服务的工具,将会给DBA的工作带来翻天覆地的变化,DBA从此就从繁重的审核、登上去执行,出错了很难回滚(如果提前没有备份的话)的被动局面解放了出来,突然发现,做DBA原来可以这么轻松,工作可以不饱和了,那就有更多的自由时间学习、进一步向自动化运维平台的实现等更智能化的方向去发展,是具有里程碑意义的。


二、Inception安装

安装环境

  • CentOS release 6.5 (Final) 64位
  • 4核
  • 2G内存
  • 安装了MySQL5.7.17

安装前准备

准备好 安装包依赖包
1
$ wget https://github.com/mysql-inception/inception
1
$ yum install gcc gcc-c++ cmake bison openssl-devel ncurses-devel

安装步骤

1、解压到安装目录
1
$ unzip -d /usr/local/ inception-master.zip 
2、进入安装目录,执行安装脚本
1
$ cd /usr/local/inception-master/
2
$ sh inception_build.sh  debug [linux]
或手动编译安装:
1
$ cmake .
2
$ make && make install
3、编辑配置文件
1
$ vim /etc/inc.cnf
2
3
[inception]
4
general_log=1
5
general_log_file=inc.log  //该文件在解压文件目录下
6
port=6669
7
socket=/tmp/inc.socket 
8
character-set-client-handshake=0
9
character-set-server=utf8 
10
inception_remote_system_password=123456
11
inception_remote_system_user=root
12
inception_remote_backup_port=3306
13
inception_remote_backup_host=127.0.0.1
14
inception_support_charset=utf8
15
inception_enable_nullable=0
16
inception_check_primary_key=1
17
inception_check_column_comment=1
18
inception_check_table_comment=1
19
inception_osc_min_table_size=1
20
inception_osc_bin_dir=/usr/bin
21
inception_osc_chunk_time=0.1
22
inception_ddl_support=1
23
inception_enable_blob_type=1
24
inception_check_column_default_value=1
4、启动服务
1
$ ./debug/mysql/bin/Inception --defaults-file=/etc/inc.cnf &
5、登录inception测试
1
$ mysql -uroot -h127.0.0.1 -P6669
2
mysql> inception get variables;
输出变量则表明安装成功

常见报错

报错1
1
$ sh inception_build.sh debug [linux]
2
make: *** no rule to make target install'. stop.
解决办法
1
$ make -j6 && make install
或手动编译安装


三、Inception测试

测试前准备

创建测试用户inc
1
mysql> grant all privileges on *.* to 'inc'@'192.168.127.%';
2
Query OK, 0 rows affected, 1 warning (0.00 sec)
创建测试库inception_test
1
mysql> create database inception_test;

Inception SQL审核测试

1、建表语句
建表语句检查项
  • 表属性的检查项
    • 这个表不存在
    • 对于create table like,会检查like的老表是不是存在。
    • 对于create table db.table,会检查db这个数据库是不是存在
    • 表名、列名、索引名的长度不大于64个字节
    • 如果建立的是临时表,则必须要以tmp为前缀
    • 必须要指定建立innodb的存储引擎(可配置)
    • 必须要指定utf8的字符集(字符串可配置,指定支持哪些字符集)
    • 表必须要有注释(可配置)
    • 表不能建立为分区表(可配置)
    • 只能有一个自增列
    • 索引名字不能是Primay
    • 不支持Foreign key(可配置)
    • 建表时,如果指定auto_increment的值不为1,报错(可配置)
    • 如果自增列的名字不为id,说明有可能是有意义的,MySQL这样使用比较危险,所以报警(可配置)
  • 列属性的检查项
    • 不能设置列的字符集(可配置)
    • 列的类型不能使用集合、枚举、位图类型。(可配置)
    • 列必须要有注释(可配置)
    • char长度大于20的时候需要改为varchar(长度可配置)
    • 列的类型不能是BLOB/TEXT。(可配置)
    • 每个列都使用not null(可配置)
    • 如果列为BLOB/TEXT类型的,则这个列不能设置为NOT NULL。
    • 如何是自增列,则使用无符号类型(可配置)
    • 如果自增列,则长度必须要大于等于4个字节(可配置)
    • 如果是timestamp类型的,则要必须指定默认值。
    • 对于MySQL5.5版本(包含)以下的数据库,不能同时有两个TIMESTAMP类型的列,如果是DATETIME类型,则不能定义成DATETIME DEFAULT CURRENT_TIMESTAMP及ON UPDATE CURRENT_TIMESTAMP等语句。
    • 每个列都需要定义默认值,除了自增列、主键列及大字段列之外(可配置)
    • 不能有重复的列名
  • 索引属性检查项
    • 索引必须要有名字
    • 不能有外键(可配置)
    • Unique索引必须要以uniq_为前缀(可配置)
    • 普通索引必须要以idx_为前缀(可配置)
    • 索引的列数不能超过5个(数目可以配置)
    • 表必须要有一个主键(可配置)
    • 最多有5个索引(数目可配置)
    • 建索引时,指定的列必须存在。
    • 索引中的列,不能重复
    • BLOB列不能建做KEY
    • 索引长度不能超过766
    • 不能有重复的索引,名字及内容
  • 默认值检查项
    • BLOB/TEXT类型的列,不能有非NULL的默认值
    • MySQL5.5以下(含)的版本,对于DATETIME类型的列,不能有函数NOW()的默认值。
    • 如果设置默认值为函数,则只能是NOW()。
    • 如果默认值为NULL,但列类型为NOT NULL,或者是主键列,或者定义为自增列,则报错。
    • 自增列不能设置默认值。
建表语句审核测试
Python脚本 testa.py
1
#/usr/bin/python
2
#-\*-coding: utf-8-\*-
3
import MySQLdb
4
sql='/*--user=inc;--password=;--host=192.168.127.128;--execute=1;--port=3306;*/\
5
inception_magic_start;\
6
use inception_test;\
7
create table `test1`(id int);\
8
inception_magic_commit;'
9
try:
10
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
11
    cur=conn.cursor()
12
    ret=cur.execute(sql)
13
    result=cur.fetchall()
14
    num_fields = len(cur.description)
15
    field_names = [i[0] for i in cur.description]
16
    print field_names
17
    for row in result:
18
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
19
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
20
    cur.close()
21
    conn.close()
22
except MySQLdb.Error,e:
23
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

审核未通过
1
$ python testa.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | CHECKED | 0 | Audit completed | None | 2 | CHECKED | 1 | Audit completed | Set engine to innodb for table 'test1'.
4
Set charset to one of 'utf8mb4' for table 'test1'.
5
Set comments for table 'test1'.
6
Column 'id' in table 'test1' have no comments.
7
Column 'id' in table 'test1' is not allowed to been nullable.
8
Set Default value for column 'id' in table 'test1'
9
Set a primary key for table 'test1'. |

审核通过
1
$ python testa.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | RERUN | 0 | Execute Successfully | None | 2 | EXECUTED | 2 | Execute Successfully
4
Backup failed | Backup: Access denied for user 'wzf1'@'localhost' (using password: YES)
5
Backup: Access denied for user 'wzf1'@'localhost' (using password: YES) |


2、插入语句
插入语句检查项
  • 表是否存在
  • 必须指定插入列表,也就是要对哪几个列指定插入值,如insert into t (id,id2) values(...),(可配置)
  • 必须指定值列表,与上面对应的列,插入的值是什么,必须要指定。
  • 插入列列表与值列表个数相同,上面二者的个数需要相同,如果没有指定列列表(因为可配置),则值列表长度要与表列数相同。
  • 不为null的列,如果插入的值是null,报错(可配置)
  • 插入指定的列名对应的列必须是存在的。
  • 插入指定的列列表中,同一个列不能出现多次。
  • 插入值列表中的简单表达式会做检查,但具体包括什么不一一指定

插入语句审核测试
Python脚本 testb.py
1
#/usr/bin/python
2
#-\*-coding: utf-8-\*-
3
import MySQLdb
4
sql='/*--user=inc;--password=;--host=192.168.127.128;--execute=1;--port=3306;*/\
5
inception_magic_start;\
6
use inception_test;\
7
insert into test2 values(1);\
8
inception_magic_commit;'
9
try:
10
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
11
    cur=conn.cursor()
12
    ret=cur.execute(sql)
13
    result=cur.fetchall()
14
    num_fields = len(cur.description)
15
    field_names = [i[0] for i in cur.description]
16
    print field_names
17
    for row in result:
18
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
19
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
20
    cur.close()
21
    conn.close()
22
except MySQLdb.Error,e:
23
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

审核未通过
1
$ python testb.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | CHECKED | 0 | Audit completed | None | 2 | CHECKED | 2 | Audit completed | Set the field list for insert statements.
4
Column count doesn't match value count at row 1. |

审核通过
1
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
2
1 | RERUN | 0 | Execute Successfully | None | 2 | EXECUTED | 2 | Execute Successfully
3
Backup failed | Backup: Access denied for user 'wzf1'@'localhost' (using password: YES)
4
Backup: Access denied for user 'wzf1'@'localhost' (using password: YES) |

3、更新、删除语句
更新、删除语句检查项
  • 表是否存在
  • 必须有where条件(可配置)
  • delete语句不能有limit条件(可配置)
  • 不能有order by语句(可配置)
  • 影响行数大于10000条,则报警(数目可配置)
  • 对WHERE条件这个表达式做简单检查,具体包括什么不一一指定
  • 对更新列的值列表表达式做简单检查,具体不一一指定
  • 对更新列对象做简单检查,主要检查列是不是存在等
  • 多表更新、删除时,每个表必须要存在

更新语句审核测试
Python脚本 testc.py
1
#/usr/bin/python
2
#-\*-coding: utf-8-\*-
3
import MySQLdb
4
sql='/*--user=inc;--password=;--host=192.168.127.128;--execute=1;--port=3306;*/\
5
inception_magic_start;\
6
use inception_test;\
7
update test2 set realname="chenlehan"  where username="b";\
8
inception_magic_commit;'
9
try:
10
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
11
    cur=conn.cursor()
12
    ret=cur.execute(sql)
13
    result=cur.fetchall()
14
    num_fields = len(cur.description)
15
    field_names = [i[0] for i in cur.description]
16
    print field_names
17
    for row in result:
18
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
19
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
20
    cur.close()
21
    conn.close()
22
except MySQLdb.Error,e:
23
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

审核通过
1
$ python testc.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | RERUN | 0 | Execute Successfully | None | 2 | EXECUTED | 2 | Execute Successfully
4
Backup failed | Backup: Access denied for user 'wzf1'@'localhost' (using password: YES)
5
Backup: Access denied for user 'wzf1'@'localhost' (using password: YES) |

删除语句审核测试
Python脚本 testd.py
1
#/usr/bin/python
2
#-\*-coding: utf-8-\*-
3
import MySQLdb
4
sql='/*--user=inc;--password=;--host=192.168.127.128;--execute=1;--port=3306;*/\
5
inception_magic_start;\
6
use inception_test;\
7
delete from test2 where username="b";\
8
inception_magic_commit;'
9
try:
10
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
11
    cur=conn.cursor()
12
    ret=cur.execute(sql)
13
    result=cur.fetchall()
14
    num_fields = len(cur.description)
15
    field_names = [i[0] for i in cur.description]
16
    print field_names
17
    for row in result:
18
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
19
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
20
    cur.close()
21
    conn.close()
22
except MySQLdb.Error,e:
23
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

审核通过
1
$ python testd.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | RERUN | 0 | Execute Successfully | None | 2 | EXECUTED | 2 | Execute Successfully
4
Backup failed | Backup: Access denied for user 'wzf1'@'localhost' (using password: YES)
5
Backup: Access denied for user 'wzf1'@'localhost' (using password: YES) |


4、查询语句
不支持大部分查询语句的优化,不能使用select *语句

查询语句审核测试
Python脚本 teste.py
1
#/usr/bin/python
2
#-\*-coding: utf-8-\*-
3
import MySQLdb
4
sql='/*--user=inc;--password=;--host=192.168.127.128;--execute=1;--port=3306;*/\
5
inception_magic_start;\
6
use inception_test;\
7
select * from test2 where username="b";\
8
inception_magic_commit;'
9
try:
10
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
11
    cur=conn.cursor()
12
    ret=cur.execute(sql)
13
    result=cur.fetchall()
14
    num_fields = len(cur.description) 
15
    field_names = [i[0] for i in cur.description]
16
    print field_names
17
    for row in result:
18
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
19
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
20
    cur.close()
21
    conn.close()
22
except MySQLdb.Error,e:
23
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

审核未通过
1
$ python teste.py 
2
['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
3
1 | CHECKED | 0 | Audit completed | None | 2 | CHECKED | 1 | Audit completed | Select only star is not allowed. |



测试中遇到的问题
执行脚本时报错:
1
ImportError: libmysqlclient.so.20: cannot open shared object file: No such file or directory
解决方法:
找到libmysqlclient.so.20的绝对路径,链接到/usr/lib64目录下(如果是32位的链接到/usr/lib目录下)
1
$ find / -name libmysqlclient.so.20
2
/opt/mysql-5.7.16-install/mysql-5.7.16/libmysql/libmysqlclient.so.20
3
/usr/local/mysql/lib/libmysqlclient.so.20
4
$ ln -s /usr/local/mysql/lib/libmysqlclient.so.20 /usr/lib64/libmysqlclient.so.20

注意
配置脚本时,注意如下部分,try中的port为inception客户端的端口号
1
try:
2
    conn=MySQLdb.connect(host='192.168.127.129',user='test',passwd='123456',db='mysql',port=6669)
3
    cur=conn.cursor()
4
    ret=cur.execute(sql)
5
    result=cur.fetchall()
6
    num_fields = len(cur.description)
7
    field_names = [i[0] for i in cur.description]
8
    print field_names
9
    for row in result:
10
        print row[0], "|",row[1],"|",row[2],"|",row[3],"|",row[4],"|",
11
        row[5],"|",row[6],"|",row[7],"|",row[8],"|",row[9],"|",row[10]
12
    cur.close()
13
    conn.close()
14
except MySQLdb.Error,e:
15
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值