inception 自动化sql审核

##概念:

Inception是一款自动化运维的利器,有别与现在各个公司使用的方式,使用Inception,将会给DBA带来最大的便利性,将DBA从繁冗的工作中解放出来,做一些更多的自动化工作,或者从架构方面研究如何更大程度的保证数据库的高可用等等。

inception支持语句审核、语句执行、备份回滚、及对OSC支持——在线执行DDL语句。

Inception是集审核、执行、回滚于一体的一个自动化运维系统,它是根据MySQL代码修改过来的,用它可以很明确的,详细的,准确的审核MySQL的SQL语句,它的工作模式和MySQL完全相同,可以直接使用MySQL客户端来连接,但不需要验证权限,它相对应用程序(上层审核流程系统等)而言,是一个服务器,在连接时需要指定服务器地址及Inception服务器的端口即可,而它相对要审核或执行的语句所对应的线上MySQL服务器来说,是一个客户端,它在内部需要实时的连接数据库服务器来获取所需要的信息,或者直接在在线上执行相应的语句及获取binlog等,Inception就是一个中间性质的服务。图1.1所示为Inception的架构。

Inception提供的功能很丰富,首先,它可以对提交的所有语句的语法分析,如果语法有问题,都会将相应的错误信息返回给审核者。还提供语义分析,当一个表,库,列等信息不正确或者不符合规范的时候报错,或者使用了一个不存在的对象时报错等等。还提供了很多针对SQL规范性约束的功能,这些DBA都是可以通过系统参数来配置的。更高级的功能是,可以辅助DBA分析一条查询语句的性能,如果没有使用索引或者某些原因导致查询很慢,都可以检查。

还提供SQL语句的执行功能,可执行的语句类型包括常用的DML及DDL语句及truncate table等操作。Inception 在执行 DML 时还提供生成回滚语句的功能,对应的操作记录及回滚语句会被存储在备份机器上面,备份机器通过配置Inception参数来指定。

##规划

机器一:192.168.99.108     安装inception服务、安装mysql数据库(充当线上mysql服务器)

机器二:192.168.99.205     安装mysql服务器(用于inception备份数据库,用于数据本分和回滚)

两台机器提前安装好mysqld服务,yum安装就行了。我这里不安装了。

192.168.99.108上的mysql服务建立测试账号 root 密码123456。给inception链接用,这个会在后边的脚本(aa.py)中设置。

192.168.99.205 上的mysql服务也建立个账号root 密码123456。给inception链接备份数据库用。在inception配置文件中有配置。注意改成你的机器和账号。

1>、在机器一 192.168.99.108上安装inception

yum install cmake bison  ncurses-devel gcc gcc-c++  openssl-devel ##依赖环境

mkdir /usr/local/inception  ##安装目录

mkdir /usr/local/src/inception ##源码保存目录

cd /usr/local/src/inception 

wget https://github.com/mysql-inception/inception/archive/master.zip 

unzip master  ##上边下载时间可能有点长,耐心等待

cd inception-master

#cmake .

#cmake -DWITH_DEBUG=OFF -DCMAKE_INSTALL_PREFIX=/usr/local/inception  -DMYSQL_DATADIR=/data/inception -DWITH_SSL=yes -DCMAKE_BUILD_TYPE=RELEASE-DWITH_ZLIB=bundled-DMY_MAINTAINER_CXX_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing  -Wno-unused-parameter -Woverloaded-virtual" -DMY_MAINTAINER_C_WARNINGS="-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Wdeclaration-after-statement"

#make && make install

vim /etc/inc.cnf  ##配置文件创建,绿色部分为配置文件内容和解释。不了解的可以参看上边几个链接。注释内容不用担心,不会影响配置文件。

[inception]
general_log=1 #这个参数就是原生的MySQL的参数,用来记录在Inception服务上执行过哪些语句,用来定位一些问题等
general_log_file=/usr/local/inception/data/inception.log #设置general log写入的文件路径
port=6669   #Inception的服务端口
socket=/usr/local/inception/data/inc.socket #Inception的套接字文件存放位置
character-set-server=utf8 #mysql原生参数

#Inception 审核规则
inception_check_autoincrement_datatype=1 #当建表时自增列的类型不为int或者bigint时报错
inception_check_autoincrement_init_value=1 #当建表时自增列的值指定的不为1,则报错
inception_check_autoincrement_name=1 #建表时,如果指定的自增列的名字不为ID,则报错,说明是有意义的,给提示
inception_check_column_comment=1 #建表时,列没有注释时报错
inception_check_column_default_value=0 #检查在建表、修改列、新增列时,新的列属性是不是要有默认值
inception_check_dml_limit=1 #在DML语句中使用了LIMIT时,是不是要报错
inception_check_dml_orderby=1 #在DML语句中使用了Order By时,是不是要报错
inception_check_dml_where=1 #在DML语句中没有WHERE条件时,是不是要报错
inception_check_identifier=1 #打开与关闭Inception对SQL语句中各种名字的检查,如果设置为ON,则如果发现名字中存在除数字、字母、下划线之外的字符时,会报Identifier "invalidname" is invalid, valid options: [a-z,A-Z,0-9,_].
inception_check_index_prefix=1 #是不是要检查索引名字前缀为"idx_",检查唯一索引前缀是不是"uniq_"
inception_check_insert_field=1  #是不是要检查插入语句中的列链表的存在性
inception_check_primary_key=1 #建表时,如果没有主键,则报错
inception_check_table_comment=1 #建表时,表没有注释时报错
inception_check_timestamp_default=0 #建表时,如果没有为timestamp类型指定默认值,则报错
inception_enable_autoincrement_unsigned=1 #自增列是不是要为无符号型
inception_enable_blob_type=0 #检查是不是支持BLOB字段,包括建表、修改列、新增列操作 默认开启
inception_enable_column_charset=0 #允许列自己设置字符集
inception_enable_enum_set_bit=0 #是不是支持enum,set,bit数据类型
inception_enable_foreign_key=0 #是不是支持外键
inception_enable_identifer_keyword=0 #检查在SQL语句中,是不是有标识符被写成MySQL的关键字,默认值为报警。
inception_enable_not_innodb=0 #建表指定的存储引擎不为Innodb,不报错
inception_enable_nullable=0 #创建或者新增列时如果列为NULL,不报错
inception_enable_orderby_rand=0 #order by rand时是不是报错
inception_enable_partition_table=0 #是不是支持分区表
inception_enable_select_star=0 #Select*时是不是要报错
inception_enable_sql_statistic=1 #设置是不是支持统计Inception执行过的语句中,各种语句分别占多大比例,如果打开这个参数,则每次执行的情况都会在备份数据库实例中的inception库的statistic表中以一条记录存储这次操作的统计情况,每次操作对应一条记录,这条记录中含有的信息是各种类型的语句执行次数情况。
inception_max_char_length=16 #当char类型的长度大于这个值时,就提示将其转换为VARCHAR
inception_max_key_parts=5 #一个索引中,列的最大个数,超过这个数目则报错
inception_max_keys=16 #一个表中,最大的索引数目,超过这个数则报错
inception_max_update_rows=10000 #在一个修改语句中,预计影响的最大行数,超过这个数就报错
inception_merge_alter_table=1 #在多个改同一个表的语句出现是,报错,提示合成一个
 #inception 支持 OSC 参数
inception_osc_bin_dir=/user/bin #用于指定pt-online-schema-change脚本的位置,不可修改,在配置文件中设置
inception_osc_check_interval=5 #对应OSC参数--check-interval,意义是Sleep time between checks for --max-lag.
inception_osc_chunk_size=1000 #对应OSC参数--chunk-size
inception_osc_chunk_size_limit=4 #对应OSC参数--chunk-size-limit
inception_osc_chunk_time=0.1 #对应OSC参数--chunk-time
inception_osc_critical_thread_connected=1000 #对应参数--critical-load中的thread_connected部分
inception_osc_critical_thread_running=80 #对应参数--critical-load中的thread_running部分
inception_osc_drop_new_table=1 #对应参数--[no]drop-new-table
inception_osc_drop_old_table=1 #对应参数--[no]drop-old-table
inception_osc_max_lag=3 #对应参数--max-lag
inception_osc_max_thread_connected=1000 #对应参数--max-load中的thread_connected部分
inception_osc_max_thread_running=80 #对应参数--max-load中的thread_running部分
inception_osc_min_table_size=0 # 这个参数实际上是一个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'"来实现的
inception_osc_on=1 #一个全局的OSC开关,默认是打开的,如果想要关闭则设置为OFF,这样就会直接修改
inception_osc_print_none=1 #用来设置在Inception返回结果集中,对于原来OSC在执行过程的标准输出信息是不是要打印到结果集对应的错误信息列中,如果设置为1,就不打印,如果设置为0,就打印。而如果出现错误了,则都会打印
inception_osc_print_sql=1 #对应参数--print 
 #备份服务器信息,注意改成你的机器
inception_remote_system_password=123456
inception_remote_system_user=root
inception_remote_backup_port=3306
inception_remote_backup_host=192.168.99.205
inception_support_charset=utf8 #表示在建表或者建库时支持的字符集,如果需要多个,则用逗号分隔,影响的范围是建表、设置会话字符集、修改表字符集属性等 


nohup /usr/local/inception/bin/Inception --defaults-file=/etc/inc.cnf  &   ##建议这种启动方式

netstat -tulpn  查看是否有6669端口已经启动

cd /usr/local/inception/bin

./Inception  --defaults-file=/etc/inc.cnf & ##后台启动,去掉&变为前台启动

netstat -tulpn  查看是否有6669端口已经启动

Inception –port=6669  &  ##后台启动,不过配置是默认的配置。没有使用上边的配置文件

nohup /usr/local/inception/bin/Inception --defaults-file=/etc/inc.cnf  &  
netstat -tulpn  查看是否有6669端口已经启动


mysql  -h127.0.0.1 -uroot -P6669  ##链接inception服务

inception get variables; ##显示变量即证明安装inception正常。




##构建python测试脚本,目前只支持python和c、c++编写的程序接口。

====================================================================

vim aa.py  ##在mysql数据库中建立一张表。注意人家的标准和格式。为了方便比较下边给出bb.py脚本。(建议还是看看上边的链接官方文档),给出线上数据库ip、账号、端口。其他的对于表的DML,DDL操作请参看上边链接,都有相应的列子。

#!/usr/bin/python
#-*-coding: utf-8-*-
import MySQLdb
sql='/*--user=root;--password=123456;--host=127.0.0.1;--execute=1;--port=3306;*/
inception_magic_start;
use mysql;
CREATE TABLE `alifeba_user` (

                    `ID` int(11) unsigned NOT NULL auto_increment comment"aaa",
                    `username` varchar(50) NOT NULL Default "" comment"aaa",
                    `realName` varchar(50) NOT NULL Default "" comment"aaa",
                    `age` int(11) NOT NULL Default 0 comment"aaa",
                    PRIMARY KEY (`ID`)
                    ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT="AAAA";

inception_magic_commit;'
try:
    conn=MySQLdb.connect(host='127.0.0.1',user='root',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,e:
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])


=======================================================================

vim bb.py

#!/usr/bin/python
#-*-coding: utf-8-*-
import MySQLdb
sql='/*--user=root;--password=123456;--host=127.0.0.1;--execute=1;--port=3306;*/
inception_magic_start;
use mysql;
INSERT INTO alifeba_user(username,realName,age) VALUES ("Lucy","RealLucy",18);

 

inception_magic_commit;'
try:
    conn=MySQLdb.connect(host='127.0.0.1',user='root',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,e:
     print "Mysql Error %d: %s" % (e.args[0], e.args[1])

========================================================================================

##返回结果

['ID', 'stage', 'errlevel', 'stagestatus', 'errormessage', 'SQL', 'Affected_rows', 'sequence', 'backup_dbname', 'execute_time', 'sqlsha1']
1 | RERUN | 0 | Execute Successfully | None |     ###对应上边use mysql;具体的每个字段的含义参看上边链接中的文档。

2 | EXECUTED | 0 | Execute Successfully Backup successfully | None |  对应上边的另一语句。

##可以链接192.168.99.205数据库,查看相应的备份数据库。

127_0_0_1_3306_mysql 这个数据库就是备份的数据库,命名规则ip+端口+数据库名(每个数据库都单独有一个)

$_$Inception_backup_information$_$  ##这个就是记录的全部对该数据库的操作,内容如下。具体的含义参照官方文档看看就明白了。就是为了记录你的操作和方便你查找回滚的操作。

   opid_time: 1495357758_4_1  ##标识你的一个操作语句,用这个标识到 alifeba_user表中查找此次对应的所有操作(此次可能对应对个操作,1495357758_4_2 ..)
start_binlog_file: 
 start_binlog_pos: 0
  end_binlog_file: 
   end_binlog_pos: 0
    sql_statement: CREATE TABLE `alifeba_user` (
                    `ID` int(11) unsigned NOT NULL auto_increment  comment"aaa",
                    `username` varchar(50) NOT NULL Default "" comment"aaa",
                    `realName` varchar(50) NOT NULL Default "" comment"aaa",
                    `age` int(11) NOT NULL Default 0 comment"aaa",
                    PRIMARY KEY (`ID`)
                    ) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT="AAAA"
             host: 127.0.0.1
           dbname: mysql
        tablename: alifeba_user
             port: 3306
             time: 2017-05-21 17:09:18
             type: CREATETABLE

 alifeba_user        ##对该表的所有操作都在这里边,备份这。可以用来回滚。   通过上边的 opid_time可以找到此次所做的所有操作备份代码。进行回滚     

附加:如果报错,import MySQLdb找不到。可自行google或者直接yum  -y install  MySQL-python 即可。

##因为inception支持OSC功能(在线修改表结构),所以为了功能完善,安装pt-online-schema-change。

原理:

http://seanlook.com/2016/05/27/mysql-pt-online-schema-change/

https://lanjingling.github.io/2016/03/26/mysql-pt-online-schema-change/

安装:http://mrcto.blog.51cto.com/1923168/1319549

wget percona.com/get/percona-toolkit.rpm

yum install percona-toolkit.rpm -y

安装完后测试前参看,之后试着通过在inception中执行DDL语句。我已经测试通过,最好不要在mysql服务器上的那个自带的mysql库中测试。可能会出问题。如遇其它问题请自行google

https://lanjingling.github.io/2016/03/26/mysql-pt-online-schema-change/  ##建议

http://mrcto.blog.51cto.com/1923168/1319549

####网页接口,只是参照。只实现了表结构语法检查功能。

哥们实现的较简单:https://github.com/dbalihui/inception_web  下载zip包

先升级Python2.7

# wget https://www.python.org/ftp/python/2.7.10/Python-2.7.10.tgz --no-check-certificate

# tar -xvf Python-2.7.10.tar

# cd Python-2.7.10

# ./configure && make && make install

# /usr/local/bin/python -V

# mv /usr/bin/python /usr/bin/python2.6.6

# ln -s /usr/local/bin/python /usr/bin/python

# python -V //验证版本

# vim /usr/bin/yum   //修改#!/usr/bin/python 为#!/usr/bin/python2.6.6,因为yum安装依赖的是2.6版本的python

下面安装模块:

首先安装一个pip

# yum -y install python-pip   //这种安装处理是2.6版本的

# wget  https://bootstrap.pypa.io/ez_setup.py  --no-check-certificate  //下载一个ez_setup 安装pip2.7版本的

# python2.7   ez_setup.py

# easy_install-2.7   pip

# pip2.7 install   MySQL-python

# yum install mysql-devel  //如果报错看看是不是缺失mysql-devel包。

# pip2.7 install flask_wtf

# pip2.7  install flask-script

# pip2.7 install flask-debugtoolbar

安装步骤:

# unzip inception_web-master.zip
# cd inception_web-master/app
# vim inception.py //修改配置文件,注意下边的配置的主机和密码。
#coding=utf-8

import MySQLdb

def table_structure(mysql_structure):
    sql1='/*--user=root;--password=123456;--host=127.0.0.1;--execute=1;--port=3306;*/
            inception_magic_start;
            use mysql;'
    sql2='inception_magic_commit;'
    sql = sql1 + mysql_structure + sql2
    try:
        conn=MySQLdb.connect(host='127.0.0.1',user='root',passwd='',db='',port=6669,use_unicode=True, charset="utf8")
        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,e:
        print "Mysql Error %d: %s" % (e.args[0], e.args[1])
    return result[1][4].split(" ")


# ./run.py runserver --host 0.0.0.0  //启动服务。如遇其它问题请自行google解决,本人测试通过。

##web浏览器中输入192.168.99.108:5000   ##可以看到界面。输入下边建表语句测试下是否成功。如遇其它问题qq:1250134974

 CREATE TABLE `alifeba_user2` (
                    `ID` int(11) unsigned NOT NULL auto_increment  comment"aaa",
                    `username` varchar(50) NOT NULL Default "" comment"aaa",
                    `realName` varchar(50) NOT NULL Default "" comment"aaa",
                    `age` int(11) NOT NULL Default 0 comment"aaa",
                    PRIMARY KEY (`ID`)
                    ) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT="AAAA";

总结:可以参考他的网页版本制作出自己的,一套审核系统。他的已经很长时间没更新了。对于回滚操作也可以做到网页系统里边。回滚的操作需要自己来根据相应的记录查找。并导出sql语句,之后再到msyql客户端执行。这样就完全可以恢复由于误操作,比如说删除和更新操作成的问题。不用再去 搞二进制还原了。好麻烦呢。

原文地址:https://www.cnblogs.com/EikiXu/p/10217940.html