DEVOPS 运维开发系列三:在MySQL DML自助服务中集成使用Inception提供SQL的语法检查和错误信息提示

本文是在CentOS7系统中进行的部署。
Inception是去哪网DBA团队开源的一个很好的工具。主要提供MySQL的语法审查、远程执行以及备份回滚服务。

一、Inception安装

1、下载和安装bison

版本使用2.5.1,http://ftp.gnu.org/gnu/bison/bison-2.5.1.tar.gz,最新的可能会有问题,下载之后,需要编译源码来安装。
方法为:
./configure && make && make install
如果有报错信息,可能是缺少个别依赖包。

2、安装依赖包

安装cmake,ncurses,ncurses-dev,openssl,g++  
# yum install cmake ncurses ncurses-dev openssl g++

3、编译安装inception

从github下载源码: https://github.com/mysql-inception/inception.git   
# pwd
/data/inception

官方提供的安装方法:
./inception_build.sh debug

如果遇上报错,可以试试下面的手动安装办法。因为Inception实际上是在mysql的基础上定制开发得到的,安装Inception的过程、步骤,和编译安装一个mysql一样。
# cmake -DWITH_DEBUG=OFF -DCMAKE_INSTALL_PREFIX=./mysql  -DMYSQL_DATADIR=./mysql/data     -DWITH_SSL=bundled -DCMAKE_BUILD_TYPE=RELEASE -DWITH_ZLIB=bundled    -DMY_MAINTAINER_CXX_WARNINGS="-Wall -Wextra -Wunused -Wno-dev -Wwrite-strings -Wno-strict-aliasing  -Wno-unused-parameter -Woverloaded-virtual"     -DMY_MAINTAINER_C_WARNINGS="-Wall -Wextra -Wno-dev -Wunused -Wwrite-strings -Wno-strict-aliasing -Wdeclaration-after-statement"

# make
# make install

4、配置和启动Inception服务

下面是一个比较通用的Inception配置文件。
$ cat /etc/inc.cnf
[inception]
general_log=1
general_log_file=inception.log
port=6669
socket=/data/inception/inception-master/inc.socket
character-set-client-handshake=0
character-set-server=utf8
inception_support_charset=utf8mb4
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_enable_blob_type=1
inception_check_column_default_value=1
  • --enable-check     # 告诉Inception当前要做什么操作,是审核还是执行,这个参数与下面的--enable-execute只能指定一个。
  • --enable-remote-backup  # 指定在执行时是不是要备份,这个参数默认是打开的,如果不想备份,则指定参数--disable-remote-backup,这个选项所支持的备份,实际上是对当前所执行的操作的备份及被修改数据的回滚语句的存储。Inception 是默认开备份功能的。
  • --disable-remote-backup     # 禁用备份功能

手动启动方法:
./Inception --defaults-file=/etc/inc.cnf
或者:
./Inception --port=6669

启动成功之后,可以简单试一下看,通过MySQL客户端
mysql -uroot -h127.0.0.1 -P6669
登录上去之后,再执行一个命令:
inception get variables;
输出了所有的变量,恭喜你,已经启动成功了

将Inception配置为CentOS7的自动启动服务:
# pwd
/usr/lib/systemd/system
# cat Inception.service
[Unit]
Description=Inception server
After=network.target

[Service]
Type=simple
User=root
Group=root

ExecStart= /data/inception/inception-master/mysql/bin/Inception --defaults-file=/etc/inc.cnf

# Give a reasonable amount of time for the server to start up/shut down
TimeoutSec=300

# Place temp files in a secure directory, not /tmp
PrivateTmp=true

[Install]
WantedBy=multi-user.target

# systemctl daemon-reload
# systemctl enable Inception
Created symlink from /etc/systemd/system/multi-user.target.wants/Inception.service to /usr/lib/systemd/system/Inception.service.
# systemctl start Inception
# systemctl status Inception
● Inception.service - Inception server
   Loaded: loaded (/usr/lib/systemd/system/Inception.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2018-07-02 16:33:12 CST; 7s ago
Main PID: 11260 (Inception)
   CGroup: /system.slice/Inception.service
           └─11260 /data/inception/inception/mysql/bin/Inception --defaults-file=/etc/inc.cnf

Jul 02 16:33:12 host01 systemd[1]: Started Inception server.
Jul 02 16:33:12 host01 systemd[1]: Starting Inception server...
Jul 02 16:33:12 host01 Inception[11260]: 2018-07-02 16:33:12 0 [Note] Welcome to use Inception2.1.50
Jul 02 16:33:12 host01 Inception[11260]: 2018-07-02 16:33:12 11260 [Note] Server hostname (bind-address): '*'; port: 6669
Jul 02 16:33:12 host01 Inception[11260]: 2018-07-02 16:33:12 11260 [Note] IPv6 is available.
Jul 02 16:33:12 host01 Inception[11260]: 2018-07-02 16:33:12 11260 [Note]   - '::' resolves to '::';
Jul 02 16:33:12 host01 Inception[11260]: 2018-07-02 16:33:12 11260 [Note] Server socket created on IP: '::'.
注:不足之处是因为这个程序问题,使用命令根本无法正常关停,如果一定要停掉它,需要使用kill -9才行。

二、调用Inception服务API接口进行sql语法检查

1、关于Inception功能的说明

首先,需要说明的一点是Inception目前支持至少以下几个主要功能:
  • 检查sql语法错误并予以提示;
  • 远程执行sql命令;
  • 对变更的数据进行备份,提供回退支持;
其次,我们这里只使用了它的sql语法检查功能。至少目前看,sql语法检查是我们最大的痛点。
如果要使用Inception,必须要使Inception服务能直接访问到目标mysql数据库。如果这个库是在其他机房的,可能需要有vpn并提供必要的访问授权。从这一点来看,不是很安全,必竟要能执行sql dml命令的账号,权限自然也不会小。因此,我们先行仅使用了它的语法检查功能,这样只需要为其提供一个远程只读访问目标数据库的管理账号即可。

2、Inception语法格式

通过Inception对语句进行审核时,必须要告诉Inception这些语句对应的目标数据库地址、数据库端口以及Inception连接数据库时使用的用户名、密码等信息,而不能简单的只是执行一条sql语句,所以必须要通过某种方式将这些信息传达给Inception。
语法格式为:
/*--user=username;--password=xxxx;--host=127.0.0.1;--port=3306;*/

语法格式要求:
  •  Inception要做的是一个语句块的审核,需要引入一个规则,将要执行的语句包围起来,Inception规定,在语句的最开始位置,要加上inception_magic_start;语句,在执行语句块的最后加上inception_magic_commit;语句,这2个语句在 Inception 中都是合法的、具有标记性质的可被正确解析的 SQL 语句。
  • 被包围起来的所有需要审核或者执行的语句都必须要在每条之后加上分号,其实就是批量执行SQL语句。(包括 use database语句之后也要加分号,这点与 MySQL 客户端不同),不然存在语法错误。
  • 在具体执行时,在没有解析到inception_magic_start之前如果发现要执行其它的语句,则直接报错,因为规则中inception_magic_start是强制的。
  • 而如果在执行的语句块最后没有出现inception_magic_commit,则直接报错,不会做任何操作。 
  • 在前面注释部分,需要指定一些操作的选项,包括线上用户名、密码、数据库地址、检查/执行等
下面是一个简单的例子:
/*--user=xxxxxxx;--password=xxxxxxxxxxx;--host=xxxxxxxxxx;
--enable-check;--port=3306;*/  
inception_magic_start;  
use mysql;  
CREATE TABLE adaptive_office(id int);  
inception_magic_commit;
那么上面这一段就是一批正常可以执行的SQL语句,目前执行只支持通过C/C++接口、Python接口来对Inception访问,这一段必须是一次性的通过执行接口提交给Inception,那么在处理完成之后,Inception会返回一个结果集,来告诉我们这些语句中存在什么错误,或者是完全正常等等。

3、程序接口调用方法的示例

下面是一段执行上面语句的Python程序的例子:
\ #!/usr/bin/python
\ #-\*-coding: utf-8-\*- import MySQLdb
sql= '/*--user=username;--password=password;--host=192.168.10.10;--check=1; --disable-remote-backup; --port=3306;*/\
inception_magic_start;\
use mysql;\
CREATE TABLE adaptive_office(id int);\
inception_magic_commit;'
try :
conn=MySQLdb.connect(host= '127.0.0.1' ,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,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 | CHECKED | 0 | Audit completed | None | use mysql | 0 | '0_0_0' | None | 0 |
2 | CHECKED | 1 | Audit completed | Set engine to innodb for table 'adaptive_office' .
Set charset to one of 'utf8mb4' for table 'adaptive_office' .
Set comments for table 'adaptive_office' .
Column 'id' in table 'adaptive_office' have no comments.
Column 'id' in table 'adaptive_office' is not allowed to been nullable.
Set Default value for column 'id' in table 'adaptive_office'
Set a primary key for table 'adaptive_office' . | CREATE TABLE adaptive_office(id int )
| 0 | '0_0_1' | 127 _0_0_1_3306_mysql | 0 |

4、WEB页面功能实现效果展示

上一章节主要演示的是代码实现,以下演示的是在WEB管理平台中的效果。
下面是一个用于测试的表格,表结构如下图所示。
需要一个能够填写sql语句信息的表单页面:
比方说,我们向person表中插入一条数据,故意把数据的值写错,多了一个值。
提交表单后,会首先调用Inception服务对sql语法做审查。因为我们提供的是一个错误的sql,所以执行失败并返回了以下错误提示信息。
总结:在运维工作中,总会有各种各样的原因,需要直接到数据库表中执行sql,对数据进行变更管理。自助服务,是解放运维人员精力的最好办法。但面对开发部门同事的各类低级sql语法错误,也常是不胜其扰,因此第一时间找来了Inception这个很不错的国产开源小工具。该工具的远程执行功能和备份回退功能,有更高的使用要求,比如要能直接访问和管理数据库,数据库需要配置了生成binlog日志等。

猜你喜欢

转载自blog.csdn.net/watermelonbig/article/details/80892493