前言
日常项目开发中,都会涉及对表结构的修改、数据修改,一般通过 sql 脚本来执行,保存执行记录。
目前我经历过的项目使用的是 flyway 工具来管理数据库脚本版本,保证各个环境的数据库的一致性。使用 flyway 过程中,其优点是:
- 实行版本管理,方便脚本统一管理;
- 各环境同步数据库更改方便;
缺点是:
-
需要优先审核语句是否能成功执行通过(开发提前在开发环境试执行通过、DBA或者TM循环审核),防止正式运行失败; -
需要规范版本管理,约定脚本命名,要求团队高协同; -
线上环境运行失败时,处理麻烦,尤其生产部署失败频繁造成发版延误; -
回滚麻烦,不能提供回滚语句的生成,需要手动处理;
通过调研考虑使用 Inception 审核工具替换或者结合 flyway 使用,Inception 作为 SQL 脚本审核工具,flyway 继续作为版本管理工具。
一、Inception 介绍
????
相信对于那些公司还为接入自动化数据库审核工具的DBA来说,耗费大部分时间审核 sql 语句,是繁荣而枯燥的。
Inception 是集审核、执行、回滚于一体的一个自动化运营工具,这个工具本身就是根据 MySQL 代码修改过来的,跟 MySQL 执行语句一样能准确、详细地审核 SQL 语句。使用时,可以直接使用 MySQL 客户端连接 Inception。
如图所示,相对待审核、执行的 SQL 可视化界面,Inception 是一个服务器,对于线上的 MySQL 的服务器,Inception 是一个客户端,额外一个备份的数据库服务器用来保存自动生成的回滚语句。
二、相关开源工具介绍
1. MySQL Inception 介绍
目前已闭源,如要了解,这里就不介绍了。
2. Yearning 介绍?
官网及文档
配置
新建数据库
create database if not exists database_name default character set utf8 default collate utf8_general_ci;
create user 'user_name'@'%' identified by 'password';
grant all on database_name.* to 'user_name'@'%' with grant option;
flush privileges;
下载
https://github.com/cookieY/Yearning/releases
进入文件夹修改 conf.toml 文件,填入上面创建的数据库信息
[Mysql]
Db = "数据库相关信息"
Host = ""
Port = ""
Password = ""
User = ""
[General]
SecretKey = "32位字符串"
Hours = 4
修改 Dockerfile 文件
FROM alpine:3.12
LABEL maintainer="HenryYee-2020/11/16"
EXPOSE 8000
COPY Yearning /opt/Yearning
COPY conf.toml /opt/conf.toml
RUN echo "http://mirrors.ustc.edu.cn/alpine/v3.12/main/" > /etc/apk/repositories && \
apk add --no-cache tzdata libc6-compat && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "Asia/Shanghai" >> /etc/timezone && \
echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf
WORKDIR /opt
RUN chmod 777 /opt
RUN chmod 777 /opt/Yearning
CMD /opt/Yearning install && /opt/Yearning run
编译镜像
docker build -t yearning .
运行
docker run -d -it -p 8000:8000 yearning
展示
3. GoInception 介绍
官网
文档
配置
下载、解压
wget https://github.com/hanchuanchuan/goInception/releases/download/v1.2.5/goInception-linux-v1.2.5-19-gce34ba8.tar.gz
tar -xvf xxx
修改配置文件部分配置
# GoIncepiton Configuration.
# IP地址
host = "0.0.0.0"
# 端口
port = 4001
...
# 日志文件
[log.file]
# 日志文件名
filename = "/dnn/goInception/logs/goinception.log"
# 日志文件的最大上限(MB)
max-size = 300
# Max日志文件的保存天数,默认值 `0`,即不清理
max-days = 7
# 要保留的最大旧日志文件数,默认值 `0`,即不清理
max-backups = 7
# 日志轮询,默认值 `true`,即开启
log-rotate = true
[inc]
# 备份数据库地址、用户(需要高级权限)
backup_host = "ip"
backup_port = 3306
backup_user = "root"
backup_password = "xxx"
...
运行
./goInception -config=config/config.toml
测试
Python 脚本
import pymysql
import prettytable as pt
tb = pt.PrettyTable()
// 审核连接的数据库用户信息,需要高级权限,可以直接使用 root 测试
sql = '''/*--user=root;--password=xxx;--host=ip;--port=3306;--execute=1;--backup=1;*/
inception_magic_start;
use database_name;
insert into t_app(id,name) values(3,'name');
inception_magic_commit;'''
// 备份数据库地址
conn = pymysql.connect(host='ip', user='', passwd='',
db='', port=4001, charset="utf8mb4")
cur = conn.cursor()
ret = cur.execute(sql)
result = cur.fetchall()
cur.close()
conn.close()
tb.field_names = [i[0] for i in cur.description]
for row in result:
tb.add_row(row)
print(tb)
Java 脚本
public static void main(String[] args) {
// 备份数据库信息
String url = "jdbc:mysql://ip:4001/?characterEncoding=utf-8";
Connection connection = null;
PreparedStatement statement = null;
ResultSet result = null;
// 审核的数据库信息
String sql = "/*--user=root;--password=xxx;--host=ip;--port=3306;--execute=1;--backup=1;*/\n" +
" inception_magic_start;\n" +
" use wool_user;\n" +
" insert into t_app(id,name) values(3,'name');\n" +
" inception_magic_commit";
try {
// 加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
connection = DriverManager.getConnection(url);
// 执行
statement = connection.prepareStatement(sql);
// 结果
result = statement.executeQuery();
while (result.next()) {
log.info(result.getString(5));
}
} catch (Exception e) {
log.info(e.getMessage());
} finally {
if (connection != null) {
try {
connection.close();
statement.close();
result.close();
} catch (Exception e) {
log.info(e.getMessage());
}
}
if (statement != null) {
try {
statement.close();
} catch (Exception e) {
log.info(e.getMessage());
}
}
if (result != null) {
try {
result.close();
} catch (Exception e) {
log.info(e.getMessage());
}
}
}
}
总结
因为 MySQL Inception 闭源,目前好用的是 Yearning 自带可视化系统,但目前不支持数据库定义语言 DDL 的回滚语句生成,而且不太使用多环境同步,GoInception 没有找到可用的可视化系统。
|