数据库 | 查询 | 审核 | 执行 | 备份 | 数据字典 | 慢日志 | 会话管理 | 账号管理 | 参数管理 | 数据归档 |
---|---|---|---|---|---|---|---|---|---|---|
MySQL | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
MsSQL | √ | × | √ | × | √ | × | × | × | × | × |
Redis | √ | × | √ | × | × | × | × | × | × | × |
PgSQL | √ | × | √ | × | × | × | × | × | × | × |
Oracle | √ | √ | √ | √ | √ | × | × | × | × | × |
MongoDB | √ | √ | √ | × | × | × | × | × | × | × |
Phoenix | √ | × | √ | × | × | × | × | × | × | × |
ODPS | √ | × | × | × | × | × | × | × | × | × |
ClickHouse | √ | √ | √ | × | × | × | × | × | × | × |
基于Inception/goInception实现,集成审核、执行、备份
支持提交和执行工单,依托工作流实现流程化管理
审批和执行可以分配给不同的用户进行操作
在工单详情可快速提交相同SQL内容到其他实例,可适用于test>beta>ga等多套环境维护的需求
工单审核通过后可以选择定时执行或者立即执行
基于PT收集慢日志,需要单独部署
基于SQLAdvisor|SOAR|SQLTuning的全方位优化建议
管理实例数据库,支持添加
管理实例账号,支持增加、授权、删除
可修改实例动态参数并记录修改历史
支持使用pt-archiver归档MySQL数据,支持直接添加配置和由用户申请归档
将Binlog2SQL模块可视化,从MySQL binlog解析出你要的SQL
My2SQL可视化,更高效地解析MySQL binlog,快速回滚
对比不同数据库的Schema信息,输出修改语句和回滚语句,SchemaSync不仅限于表结构,它可以处理的对象还有:视图、事件、存储过程、函数、触发器、外键
支持自定义资源(项目)组,管理资源组和关联对象,资源组成员之间审批流程、实例配置、消息通知等资源隔离
权限可以分配给用户,也可以分配给权限组,支持对大多数操作进行限制,独立控制用户的审核、执行等操作权限
工作流审批流程支持多层级多用户,并且隔离资源组,不同资源组不同的工单类型可以配置不同的审批层级
系统配置项、工作流审批流程可在前端页面动态修改,无需重启服务实时生效
支持钉钉、企业微信、邮件通知,及时知晓工单状态变化
使用pyecharts实现工单、查询维度的可视化统计
服务器信息
系统:centos7.9
内网ip:192.168.0.213
公网ip:121.37.17.85
# wget https://download.docker.com/linux/centos/docker-ce.repo #下载docker的yum源
# mv docker-ce.repo /etc/yum.repos.d
# yum -y install docker-ce-18.09.9
# docker -v
Docker version 20.10.6, build 370c289
# systemctl start docker
# systemctl enable docker
# 修改docker的日志规则
# vim /etc/docker/daemon.json #docker18版本之后无效
{
"log-driver":"json-file",
"log-opts":{ "max-size" :"500m","max-file":"30"} #最大日志500m 最大保留个数30,一定删除注释
},
{
"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}
#修改docker的数据存储路径
# vim /usr/lib/systemd/system/docker.service
在ExecStart=/usr/bin/dockerd-current \ 下添加
--graph /opt/docker \ #docker存储路径
--registry-mirror=http://hub-mirror.c.163.com \ #加速地址
--registry-mirror=https://docker.mirrors.ustc.edu.cn \
--registry-mirror=https://p31wiatp.mirror.aliyuncs.com \
-H tcp://0.0.0.0:6935 -H unix://var/run/docker.sock #portainer可以检测到
# systemctl daemon-reload
# systemctl restart docker
# docker info |grep Root #查看docker数据存储位置
Docker Root Dir: /opt/docker
# ss -ltnp |grep 6935
#安装docker-compose
# curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# docker-compose --version
docker-compose version 1.29.2, build 5becea4c
创建目录
# mkdir -p /opt/mysql_8_0_31/mysql/data
# mkdir -p /opt/mysql_8_0_31/mysql/sql
# cd /opt/mysql_8_0_31/
准备初始化sql
# vim /opt/mysql_8_0_31/mysql/sql/archery.sql
CREATE DATABASE `archery` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci';
create user 'archery'@'%' identified by 'Archeryweb%123' ;
GRANT ALL on archery.* TO 'archery'@'%';
GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process,Create,Update,Insert,Drop,DELETE ON *.*
TO 'archery'@'%';
# 特别注意Drop,DELETE权限,生产不允许授这个权限,但是没有Drop,DELETE权限不能执行一些回滚sql,请联系管理员手动执行回滚sql
flush privileges;
编写docker-compose文件
# pwd
/opt/mysql_8_0_31/
# vim docker-compose-mysql.yaml
version: '3.7'
services:
mysql8_0_31:
image: docker.io/mysql:8.0.31
ports:
- 3366:3306
container_name: mysql8_0_31
environment:
- MYSQL_ROOT_PASSWORD=Archeryweb%123
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/sql/archery.sql:/docker-entrypoint-initdb.d/archery.sql
restart: always
docker-compose启动mysql
# pwd
/opt/mysql_8_0_31/
# docker-compose -f docker-compose-mysql.yaml create #根据docker-compose文件创建容器及网络或存储卷
# docker-compose -f docker-compose-mysql.yaml up -d # 后台启动容器
上传archery.tar.gz包
# pwd
/opt
# ls
Archery.tar.gz containerd docker
# 解压tar包
# tar xzvf Archery.tar.gz
# ls
Archery Archery.tar.gz containerd docker
# 查看目录结构
# tree ./Archery #如果提示没有tree命令,请执行yum -y install tree
Archery
├── archery
│ ├── docs.md
│ ├── downloads
│ │ ├── archiver
│ │ ├── binlog2sql
│ │ └── schemasync
│ ├── keys
│ ├── logs
│ │ ├── archery.log
│ │ ├── qcluster.log
│ │ └── supervisord.log
│ ├── notify.py
│ ├── notify.py.bak
│ ├── settings.py
│ ├── soar_path
│ │ ├── soar_path
│ │ └── sqladvisor_path
│ ├── soar.yaml
│ └── sql
│ └── migrations
│ ├── 0001_initial.py
│ ├── __init__.py
│ └── __pycache__
│ ├── 0001_initial.cpython-39.pyc
│ └── __init__.cpython-39.pyc
├── docker-compose.yml
├── inception
│ └── config.toml
└── mysql
└── my.cnf
修改mysql连接为外置
修改docker-compose
# cd Archery
# pwd
/opt/Archery
# vim docker-compose.yml
version: '3'
services:
redis:
image: redis:5
container_name: redis
restart: always
command: redis-server --requirepass 123456
expose:
- "6379"
#将mysql的注释掉
# mysql:
# image: mysql:5.7
# container_name: mysql
# restart: always
# ports:
# - "3306:3306"
# volumes:
# - "./mysql/my.cnf:/etc/mysql/my.cnf"
# - "./mysql/datadir:/var/lib/mysql"
# environment:
# MYSQL_DATABASE: archery
# MYSQL_ROOT_PASSWORD: 123456
goinception:
image: hanchuanchuan/goinception
container_name: goinception
restart: always
ports:
- "4000:4000"
volumes:
- "./inception/config.toml:/etc/config.toml"
archery:
image: hhyo/archery:v1.9.1
container_name: archery
restart: always
ports:
- "9123:9123"
volumes:
- "./archery/settings.py:/opt/archery/local_settings.py"
- "./archery/soar.yaml:/etc/soar.yaml"
- "./archery/docs.md:/opt/archery/docs/docs.md"
- "./archery/notify.py:/opt/archery/sql/notify.py"
- "./archery/downloads:/opt/archery/downloads"
- "./archery/soar_path/sqladvisor_path:/opt/archery/soar_path/sqladvisor_path"
- "./archery/soar_path/soar_path:/opt/archery/soar_path/soar_path"
- "./archery/sql/migrations:/opt/archery/sql/migrations"
- "./archery/logs:/opt/archery/logs"
- "./archery/keys:/opt/archery/keys"
entrypoint: "dockerize -wait tcp://192.168.0.213:3366 -wait tcp://redis:6379 -timeout 60s /opt/archery/src/docker/startup.sh"
env_file:
- .env
==========================================================================
# 注意
entrypoint: "dockerize -wait tcp://192.168.0.213:3366 -wait tcp://redis:6379 -timeout 60s /opt/archery/src/docker/startup.sh" 这里的mysql地址一定要修改
修改.env文件
# pwd
/opt/Archery
# ls -a
. .. archery docker-compose.yml .env inception mysql
# vim .env
NGINX_PORT=9123
# https://django-environ.readthedocs.io/en/latest/quickstart.html#usage
# https://docs.djangoproject.com/zh-hans/4.1/ref/settings/
DEBUG=false
#修改mysql配置信息
DATABASE_URL=mysql://archery:Archeryweb%[email protected]:3366/archery
CACHE_URL=redis://redis:6379/0?PASSWORD=123456
# https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins
CSRF_TRUSTED_ORIGINS=http://127.0.0.1:9123
# https://django-auth-ldap.readthedocs.io/en/latest/
ENABLE_LDAP=false
AUTH_LDAP_ALWAYS_UPDATE_USER=true
AUTH_LDAP_USER_ATTR_MAP=username=cn,display=displayname,email=email
# https://django-q.readthedocs.io/en/latest/configure.html#
Q_CLUISTER_WORKERS=4
Q_CLUISTER_TIMEOUT=60
Q_CLUISTER_SYNC=false
修改setting.py
# cd /opt/Archery/archery
# vim settings.py
# 修改SECRET_KEY
# 关闭debug模式
DEBUG = False
# 设置ALLOWED_HOSTS,建议限制内网访问
ALLOWED_HOSTS = [
'.example.com', # Allow domain and subdomains
'.example.com.', # Also allow FQDN and subdomains
]
# 请求大小限制,如果提交SQL语句过大可以修改该值
DATA_UPLOAD_MAX_MEMORY_SIZE = 15728640
# 密码校验,用户注册和添加密码校验规则
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {
'min_length': 9,
}
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
#mysql配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'archery', # 数据库名称
'USER': 'archery', # 数据库用户
'PASSWORD': 'Archeryweb%123', # 数据库密码
'HOST': '192.168.0.213', # 数据库HOST,如果是docker启动并且关联,可以使用容器名连接
'PORT': '3366', # 数据库端口
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", # SQL_MODE,为了兼容select * group by,可以按需调整
'charset': 'utf8mb4'
},
'TEST': {
'NAME': 'test_archery',
'CHARSET': 'utf8mb4',
},
}
}
# Django-Q配置
Q_CLUSTER = {
'name': 'archery',
'workers': 4,
'recycle': 500,
'timeout': 60,
'compress': True,
'cpu_affinity': 1,
'save_limit': 0,
'queue_limit': 50,
'label': 'Django Q',
'django_redis': 'default',
'sync': False # 本地调试可以修改为True,使用同步模式
}
# 缓存配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://redis:6379/0", # redis://host:port/db
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"PASSWORD": "123456"
}
}
}
docker-compose启动Archery
# pwd
/opt/Archery
# docker-compose create #根据docker-compose文件创建容器及网络或存储卷
# docker-compose up -d # 后台启动容器
# 表结构初始化
docker exec -ti archery /bin/bash
cd /opt/archery
source /opt/venv4archery/bin/activate
python3 manage.py makemigrations sql
python3 manage.py migrate
# 数据初始化
python3 manage.py dbshell<sql/fixtures/auth_group.sql
python3 manage.py dbshell<src/init_sql/mysql_slow_query_review.sql
# 创建管理用户
python3 manage.py createsuperuser
#账户:admin 邮箱:[email protected] 密码:Fysladmin
exit
# 重启
docker restart archery
# 日志查看和问题排查
docker logs archery -f --tail=50
访问http://{ip}:9123
账户:admin 密码:Fysladmin
GO_INCEPTION_HOST 192.168.0.213
GO_INCEPTION_PORT 4000
**BACKUP_HOST ** 192.168.0.213
BACKUP_PORT 3366
BACKUP_USER root
BACKUP_PASSWORD Archeryweb%123
SQLADVISOR_PATH /opt/archery/soar_path/sqladvisor_path
SOAR_PATH /opt/archery/soar_path/soar_path
飞书机器人webhook地址:https://open.larksuite.com/open-apis/bot/v2/hook/xxxxxx
注意:数据库账户权限需具有以下权限
关于账户授权的sql语句示例如下:
create user 'archery'@'%' identified by 'Archeryweb%123' ;
GRANT ALL on archery.* TO 'archery'@'%';
GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process ON *.*
TO 'archery'@'%';
flush privileges;
测试新用户注册
账户:test001
密码:fysltest001
登录
可以看到之前配置的飞书机器人webhook已经发出通知了
登录DBA的账户,对申请进行批复
到这新用户注册的权限组测试完毕,新注册的用户仅能申请SQL查询权限
PM权限用户:
账户:PM-test001
密码:Fysltest03
DBA权限用户:
账户:DBA-test001
密码:Fysltest02
RD权限用户:
账户:RD-test004
密码:Fysltest03
创建测试表
create table test(
id int unsigned not null auto_increment primary key comment 'id',
t2_name varchar(10) not null default 'a' comment 'a:有效,x:无效',
cun varchar(10) not null default 'y' comment 'y:可用,n:不可用',
email varchar(254) NOT NULL default ' ' comment '账户邮箱'
) comment 'table';
提交后根据审批流程,依次登录相关的测试账户审批
测试提交回滚SQL,这里省略(回滚步骤跟SQL上线步骤是一样的)
略
略
归档是将数据归档成sql文件或者csv文件,本步骤详情操作省略
创建上线SQL,插入测试数据
INSERT INTO
test(id, t2_name, cun, email)
VALUES
(1, 'a', 'y', '[email protected]');
INSERT INTO
test(id, t2_name, cun, email)
VALUES
(2, 'a', 'y', '[email protected]');
INSERT INTO
test(id, t2_name, cun, email)
VALUES
(3, 'a', 'y', '[email protected]');
配置数据脱敏字段
测试数据脱敏效果
升级分为两步, 数据库变更和服务更新, 以 Release v1.3.8 升级为 Release v1.5.0 为例
脚本文件地址: init_sql
需要执行当前版本至目标版本之间的所有数据库变更脚本
v1.3.8_v1.4.0.sql
v1.4.2_v1.4.3.sql
v1.4.3_v1.4.5.sql
v1.4.5_v1.5.0.sql
1.使用 docker-compose -f docker-compose.yml down
停止旧版本服务, 删除旧版本服务使用的所有 docker 镜像
2.下载对应 Release 版本的压缩包: Releases
3.对比 src/docker-compose
文件夹, 按照最新配置进行调整, 注意务必更新 settings.py
文件, 否则可能无法启动, 确认配置没问题后使用 docker-compose -f docker-compose.yml up -d
启动新版本服务
4.执行数据库升级脚本, 跨多版本升级时需要执行当前版本至目标版本之间的所有数据库变更脚本(实际升级时注意替换文件名)
docker exec -it archery /bin/bash
source /opt/venv4archery/bin/activate
python manage.py dbshell < src/init_sql/v1.3.8_v1.4.0.sql
python manage.py dbshell < src/init_sql/v1.4.2_v1.4.3.sql
python manage.py dbshell < src/init_sql/v1.4.3_v1.4.5.sql
python manage.py dbshell < src/init_sql/v1.4.5_v1.5.0.sql
5.应用数据库变更 python manage.py migrate
6.使用 docker-compose -f docker-compose.yml restart
重新启动服务
登录服务器查看容器 goinception日志
# docker logs -f goinception
################################################
Warning: The following parameters will be deprecated and replaced with disable_types:
enable_blob_type
enable_json_type
enable_enum_set_bit
enable_timestamp_type
https://github.com/hanchuanchuan/goInception/pull/418
################################################
time="2023/01/15 10:36:34.468" level=error msg="con:14 解析失败! line 5 column 2 near \") comment 'table'\" " file=session_inception.go func=executeInc line=220
time="2023/01/15 10:36:34.469" level=error msg=" create table test(\n id int unsigned not null auto_increment primary key comment 'id',\n t2_name varchar(10) not null default 'a' comment 'a:有效,x:无效',\n cun varchar(10) not null default 'y' comment 'y:可用,n:不可用',\n) comment 'table'" file=session_inception.go func=executeInc line=221
time="2023/01/15 10:38:53.933" level=error msg="con:17 con:17 dial tcp: lookup mysql on 127.0.0.11:53: no such host" file=session_inception.go func=parseOptions line=2134
可以看到goinception的备份数据库地址不正确,还是默认的127.0.0.1
解决方案:
修改goinception配置文件,将备份数据库信息修改
# pwd
/opt/Archery/inception
# ls
config.toml
# vim config.toml
...
##修改备份数据库信息
backup_host = "192.168.0.213"
backup_port = 3366
backup_user = "root"
backup_password = "Archeryweb%123"
# cd ../
# pwd
/opt/Archery
# docker-compose down
# docker-compose up -d
再次提交SQL上线
可以看到执行正常结束
查看回滚SQL
执行上线SQL报错 lookup mysql on 127.0.0.11:53: no such host问题解决
登录服务器查看容器 goinception日志
# docker logs -f goinception
is operation" file=session_inception.go func=mysqlFetchMasterBinlogPosition line=1570
time="2020/09/03 15:50:48.804" level=error msg="con:8 Error 1227: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation" file=conn.go func=raw line=68
time="2020/09/03 15:50:48.804" level=error msg="con:8 Error 1227: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation" file=session_inception.go func=mysqlFetchMasterBinlogPosition line=1570
解决方案:
去连接每个实例的账户需要同时授予Replication Client、Replication Slave、Process和Select权限,缺一不可
GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process,Create,Update,Insert,Drop,DELETE ON *.*
TO 'archery'@'%';
# 特别注意Drop,DELETE权限,生产不允许授这个权限,但是没有Drop,DELETE权限不能执行一些回滚sql,请联系管理员手动执行回滚sql
flush privileges;
关于这个权限,官方文档并没有说明,此处需注意。