二、Archery 架构概览
Archery 的整体架构并不复杂,核心组件如下:
| 组件 | 作用 |
|---|
| Django | Web 后端框架,提供 UI 和 API |
| MySQL | Archery 自身的元数据存储 |
| Redis | 缓存和异步任务队列 |
| Inception / goInception | MySQL SQL 审核引擎 |
| Goinception | 替代原版 Inception,支持更多特性 |
| SQLE / SQLAdvisor | 可选的辅助审核引擎 |
整个流程大致是:
用户提交 SQL
↓
Archery (Django) 接收请求
↓
调用 goInception 进行 SQL 审核
↓
审核通过 → DBA 确认 → 执行 SQL
↓
执行结果记录到 MySQL 后端
对于 Oracle 和 PostgreSQL 的审核,Archery 使用的是内置的规则引擎,不依赖 goInception。
三、Docker Compose 一键部署
3.1 环境准备
推荐配置:
- 操作系统:CentOS 7/8、Ubuntu 20.04+、Debian 11+
- CPU:2 核以上
- 内存:4GB 以上
- Docker:20.10+
- Docker Compose:v2.0+
先确保 Docker 和 Docker Compose 已安装:
1# 安装 Docker(如果还没装的话)
2
3> **本章目标**:掌握本章核心知识点
4> **前置要求**:完成前序章节学习
5> **预计时长**:60 分钟
6
7curl -fsSL https://get.docker.com | sh
8systemctl start docker
9systemctl enable docker
10
11# 确认版本
12docker --version
13docker compose version
3.2 拉取 Archery 项目
1cd /opt
2git clone https://github.com/hhyo/Archery.git
3cd Archery
3.3 Docker Compose 配置文件
Archery 官方已经提供了 docker-compose.yml,但我们可以根据实际情况做一些调整。以下是一份经过优化的配置:
1version: '3'
2
3services:
4 mysql:
5 image: mysql:5.7
6 container_name: archery-mysql
7 restart: always
8 ports:
9 - "3306:3306"
10 environment:
11 MYSQL_ROOT_PASSWORD: archery_root_2026
12 MYSQL_DATABASE: archery
13 MYSQL_USER: archery
14 MYSQL_PASSWORD: archery_pwd_2026
15 volumes:
16 - ./mysql/data:/var/lib/mysql
17 - ./mysql/conf:/etc/mysql/conf.d
18 command:
19 - --character-set-server=utf8mb4
20 - --collation-server=utf8mb4_unicode_ci
21 - --innodb_buffer_pool_size=512M
22 - --max_connections=500
23 networks:
24 - archery-net
25
26 redis:
27 image: redis:7-alpine
28 container_name: archery-redis
29 restart: always
30 ports:
31 - "6379:6379"
32 volumes:
33 - ./redis/data:/data
34 networks:
35 - archery-net
36
37 goinception:
38 image: hanchuanchuan/goinception:latest
39 container_name: archery-goinception
40 restart: always
41 ports:
42 - "4000:4000"
43 volumes:
44 - ./goinception/config.toml:/etc/config.toml
45 networks:
46 - archery-net
47
48 archery:
49 image: hhyo/archery:latest
50 container_name: archery
51 restart: always
52 ports:
53 - "9123:9123"
54 volumes:
55 - ./archery/settings.py:/opt/archery/archery/settings.py
56 - ./archery/soar.yaml:/etc/soar.yaml
57 - ./archery/docs:/opt/archery/docs
58 - ./archery/logs:/opt/archery/logs
59 - ./archery/keys:/opt/archery/keys
60 depends_on:
61 - mysql
62 - redis
63 - goinception
64 environment:
65 NGINX_PORT: 9123
66 command: ["dockerize", "-wait", "tcp://mysql:3306", "-wait", "tcp://redis:6379", "-timeout", "60s", "/opt/archery/src/docker/startup.sh"]
67 networks:
68 - archery-net
69
70networks:
71 archery-net:
72 driver: bridge
3.4 准备 goInception 配置文件
1mkdir -p goinception
2cat > goinception/config.toml << 'EOF'
3[inc]
4backup_host = "archery-mysql"
5backup_port = 3306
6backup_user = "root"
7backup_password = "archery_root_2026"
8
9enable_blob_type = true
10enable_json_type = true
11enable_nullable = true
12check_column_comment = true
13check_table_comment = true
14support_charset = "utf8,utf8mb4"
15lang = "zh-CN"
16
17[osc]
18osc_on = false
19
20[ghost]
21ghost_on = false
22EOF
3.5 启动服务
1# 启动所有服务
2docker compose up -d
3
4# 查看日志,确认启动正常
5docker compose logs -f archery
6
7# 等待看到类似以下输出表示启动成功:
8# [INFO] archery started successfully
启动过程大概需要 1-2 分钟,因为要等 MySQL 初始化完成。
3.6 初始化数据库
首次启动后,需要执行数据库迁移和创建管理员账号:
1# 执行数据库迁移
2docker exec -it archery bash -c "cd /opt/archery && python3 manage.py makemigrations && python3 manage.py migrate"
3
4# 创建超级管理员
5docker exec -it archery bash -c "cd /opt/archery && python3 manage.py createsuperuser"
6# 按提示输入用户名、邮箱、密码
完成后访问 http://your-server-ip:9123,用刚才创建的管理员账号登录。
四、初始配置
4.1 系统配置
登录后,先做一些基本配置。进入 系统管理 → 配置项管理:
| 配置项 | 建议值 | 说明 |
|---|
GO_INCEPTION_HOST | goinception | goInception 的地址 |
GO_INCEPTION_PORT | 4000 | goInception 端口 |
SIGN_UP_ENABLED | true | 是否允许用户自助注册 |
AUTO_REVIEW | true | 是否开启自动审核 |
4.2 添加资源组
资源组是 Archery 中管理权限的核心概念。建议按业务线或环境来划分:
- 生产环境-业务A
- 测试环境-业务A
- 生产环境-业务B
进入 系统管理 → 资源组管理,创建资源组。
4.3 注册数据库实例
进入 实例管理 → 实例列表 → 添加实例,填写目标数据库的连接信息:
实例名称:prod-mysql-01
数据库类型:MySQL
主机:192.168.1.100
端口:3306
用户名:archery_audit
密码:xxxxxxxx
资源组:生产环境-业务A
注意:给 Archery 使用的数据库账号需要有足够权限。对于 MySQL,建议授权如下:
1-- 创建审核专用账号
2CREATE USER 'archery_audit'@'%' IDENTIFIED BY 'YourStrongPassword';
3
4-- 授予必要权限
5GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, ALTER, DROP, INDEX,
6 EXECUTE, REFERENCES, SHOW VIEW, CREATE VIEW,
7 PROCESS, REPLICATION CLIENT, REPLICATION SLAVE,
8 SUPER, RELOAD
9ON *.* TO 'archery_audit'@'%';
10
11FLUSH PRIVILEGES;
五、MySQL SQL 审核实战
这是 Archery 最核心的功能,我们来走一遍完整流程。
5.1 提交 SQL 工单
进入 SQL 审核 → 提交 SQL 上线工单:
- 选择目标实例:
prod-mysql-01
- 选择目标数据库:
myapp_db
- 填写工单说明:"新增用户扩展信息表"
- 输入 SQL:
1-- 新增用户扩展信息表
2CREATE TABLE user_profile (
3 id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
4 user_id BIGINT UNSIGNED NOT NULL COMMENT '用户ID',
5 nickname VARCHAR(64) NOT NULL DEFAULT '' COMMENT '昵称',
6 avatar_url VARCHAR(512) NOT NULL DEFAULT '' COMMENT '头像URL',
7 bio TEXT COMMENT '个人简介',
8 birthday DATE DEFAULT NULL COMMENT '生日',
9 created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
10 updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
11 PRIMARY KEY (id),
12 UNIQUE KEY uk_user_id (user_id),
13 KEY idx_created_at (created_at)
14) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户扩展信息表';
15
16-- 给已有的 orders 表新增索引
17ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
点击 提交 后,Archery 会自动调用 goInception 进行审核。
5.2 自动审核结果
审核结果会显示每条 SQL 的检查状态:
1✅ CREATE TABLE user_profile ...
2 审核结果:通过
3 预计影响行数:0
4
5✅ ALTER TABLE orders ADD INDEX ...
6 审核结果:通过
7 预计影响行数:0
8 备注:建议在业务低峰期执行
如果 SQL 有问题,goInception 会给出具体的错误和建议。比如:
1❌ ALTER TABLE orders DROP COLUMN user_id;
2 审核结果:不通过
3 原因:删除列操作需要确认,该列可能被业务依赖
5.3 DBA 审核
自动审核通过后,工单流转到 DBA 进行人工审核。DBA 可以:
- 通过:确认 SQL 没有问题
- 驳回:说明原因,退回给开发修改
- 追加备注:比如"请在凌晨 2 点执行"
5.4 执行上线
DBA 审核通过后,可以选择:
- 立即执行:马上执行 SQL
- 定时执行:设置执行时间,Archery 会在指定时间自动执行
执行过程中可以看到实时进度和每条 SQL 的执行结果。
5.5 回滚支持
goInception 在执行 DDL/DML 时会自动生成回滚语句。如果发现问题,可以在工单详情中查看并执行回滚 SQL。
六、Oracle SQL 审核配置
6.1 安装 Oracle 客户端依赖
Archery 连接 Oracle 需要 cx_Oracle 库和 Oracle Instant Client。如果使用 Docker 部署,需要在容器中安装:
1# 进入 Archery 容器
2docker exec -it archery bash
3
4# 下载 Oracle Instant Client(以 19c 为例)
5cd /tmp
6wget https://download.oracle.com/otn_software/linux/instantclient/1919000/instantclient-basic-linux.x64-19.19.0.0.0dbru.zip
7unzip instantclient-basic-linux.x64-19.19.0.0.0dbru.zip -d /opt/oracle
8
9# 设置环境变量
10echo 'export LD_LIBRARY_PATH=/opt/oracle/instantclient_19_19:$LD_LIBRARY_PATH' >> /etc/profile
11source /etc/profile
12
13# 安装 Python 依赖
14pip3 install cx_Oracle
也可以将这些步骤写入自定义 Dockerfile:
1FROM hhyo/archery:latest
2
3# 安装 Oracle Instant Client
4COPY instantclient-basic-linux.x64-19.19.0.0.0dbru.zip /tmp/
5RUN cd /tmp && unzip instantclient-basic-linux.x64-19.19.0.0.0dbru.zip -d /opt/oracle \
6 && echo '/opt/oracle/instantclient_19_19' > /etc/ld.so.conf.d/oracle.conf \
7 && ldconfig \
8 && pip3 install cx_Oracle \
9 && rm -f /tmp/*.zip
6.2 注册 Oracle 实例
在 实例管理 中添加 Oracle 实例:
实例名称:prod-oracle-01
数据库类型:Oracle
主机:192.168.1.200
端口:1521
用户名:archery_audit
密码:xxxxxxxx
SID/Service Name:ORCL
资源组:生产环境-业务A
Oracle 审核账号建议权限:
1-- 创建审核用户
2CREATE USER archery_audit IDENTIFIED BY "YourStrongPassword";
3
4-- 授予基本权限
5GRANT CONNECT, RESOURCE TO archery_audit;
6GRANT SELECT ANY TABLE TO archery_audit;
7GRANT SELECT ANY DICTIONARY TO archery_audit;
8GRANT CREATE SESSION TO archery_audit;
9GRANT EXECUTE ANY PROCEDURE TO archery_audit;
10
11-- 如果需要执行 DDL
12GRANT CREATE TABLE TO archery_audit;
13GRANT ALTER ANY TABLE TO archery_audit;
14GRANT DROP ANY TABLE TO archery_audit;
15GRANT CREATE ANY INDEX TO archery_audit;
6.3 Oracle SQL 审核示例
提交一个 Oracle DDL 工单:
1-- 创建客户信息表
2CREATE TABLE customer_info (
3 customer_id NUMBER(12) NOT NULL,
4 customer_name VARCHAR2(100) NOT NULL,
5 email VARCHAR2(200),
6 phone VARCHAR2(20),
7 create_date DATE DEFAULT SYSDATE,
8 status NUMBER(2) DEFAULT 1,
9 CONSTRAINT pk_customer_info PRIMARY KEY (customer_id)
10);
11
12-- 创建索引
13CREATE INDEX idx_customer_email ON customer_info(email);
14
15-- 添加注释
16COMMENT ON TABLE customer_info IS '客户信息表';
17COMMENT ON COLUMN customer_info.customer_id IS '客户ID';
18COMMENT ON COLUMN customer_info.customer_name IS '客户姓名';
Archery 会检查 Oracle SQL 的基本语法和一些常见规则,不过 Oracle 的审核规则没有 MySQL(goInception)那么丰富,建议结合自定义审核规则使用。
七、PostgreSQL SQL 审核配置
7.1 注册 PostgreSQL 实例
在 实例管理 中添加 PostgreSQL 实例:
实例名称:prod-pg-01
数据库类型:PgSQL
主机:192.168.1.300
端口:5432
用户名:archery_audit
密码:xxxxxxxx
数据库名:myapp
资源组:生产环境-业务A
PostgreSQL 审核账号建议权限:
1-- 创建审核用户
2CREATE USER archery_audit WITH PASSWORD 'YourStrongPassword';
3
4-- 授予连接权限
5GRANT CONNECT ON DATABASE myapp TO archery_audit;
6
7-- 授予 schema 使用权限
8GRANT USAGE ON SCHEMA public TO archery_audit;
9
10-- 授予表的读写权限
11GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO archery_audit;
12ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO archery_audit;
13
14-- 如果需要执行 DDL
15GRANT CREATE ON SCHEMA public TO archery_audit;
7.2 PostgreSQL SQL 审核示例
提交一个 PostgreSQL 工单:
1-- 创建商品表
2CREATE TABLE products (
3 id BIGSERIAL PRIMARY KEY,
4 product_name VARCHAR(200) NOT NULL,
5 description TEXT,
6 price NUMERIC(10, 2) NOT NULL DEFAULT 0.00,
7 stock INTEGER NOT NULL DEFAULT 0,
8 category_id INTEGER,
9 is_active BOOLEAN NOT NULL DEFAULT TRUE,
10 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
11 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
12);
13
14-- 创建索引
15CREATE INDEX idx_products_category ON products(category_id);
16CREATE INDEX idx_products_active ON products(is_active) WHERE is_active = TRUE;
17
18-- 添加注释
19COMMENT ON TABLE products IS '商品信息表';
20COMMENT ON COLUMN products.price IS '商品价格';
PostgreSQL 的审核同样使用内置规则引擎。
八、慢日志管理
Archery 内置了慢日志收集和分析功能,这对 DBA 来说非常实用。
8.1 MySQL 慢日志配置
首先确保 MySQL 开启了慢日志:
1-- 检查慢日志状态
2SHOW VARIABLES LIKE 'slow_query%';
3SHOW VARIABLES LIKE 'long_query_time';
4
5-- 开启慢日志(如果还没开)
6SET GLOBAL slow_query_log = ON;
7SET GLOBAL long_query_time = 1; -- 超过1秒的查询记录
8SET GLOBAL log_queries_not_using_indexes = ON;
8.2 配置 Archery 慢日志收集
Archery 支持通过 pt-query-digest 来分析慢日志。在 Archery 容器中确认已安装 Percona Toolkit:
1# 检查是否已安装
2docker exec -it archery which pt-query-digest
3
4# 如果没有安装
5docker exec -it archery bash -c "apt-get update && apt-get install -y percona-toolkit"
然后在 系统管理 → 配置项管理 中配置:
| 配置项 | 值 |
|---|
SLOWQUERY_ON | true |
SQLADVISOR | /usr/bin/sqladvisor |
8.3 慢日志分析
在 慢日志 → 慢日志列表 中,可以看到按实例分组的慢查询汇总:
- 执行次数:该 SQL 模板被执行了多少次
- 平均耗时:平均执行时间
- 最大耗时:最长的一次执行时间
- 扫描行数:平均扫描行数
点击具体的慢查询,可以看到完整的 SQL 文本,还可以直接在平台上进行 SQL 优化建议。
九、集成 LDAP 与消息通知
9.1 LDAP 集成
如果公司使用 LDAP(如 Active Directory)管理用户,可以让 Archery 对接 LDAP,实现统一认证。
编辑 Archery 的 settings.py:
1# LDAP 配置
2ENABLE_LDAP = True
3
4import ldap
5from django_auth_ldap.config import LDAPSearch, GroupOfNamesType
6
7AUTH_LDAP_SERVER_URI = "ldap://ldap.example.com:389"
8AUTH_LDAP_BIND_DN = "cn=admin,dc=example,dc=com"
9AUTH_LDAP_BIND_PASSWORD = "ldap_password"
10
11AUTH_LDAP_USER_SEARCH = LDAPSearch(
12 "ou=people,dc=example,dc=com",
13 ldap.SCOPE_SUBTREE,
14 "(uid=%(user)s)"
15)
16
17AUTH_LDAP_USER_ATTR_MAP = {
18 "first_name": "givenName",
19 "last_name": "sn",
20 "email": "mail",
21}
配置完成后重启 Archery 容器:
1docker compose restart archery
9.2 钉钉通知
Archery 支持通过钉钉机器人发送工单通知。配置步骤:
- 在钉钉群中添加自定义机器人,获取 Webhook URL
- 在 系统管理 → 配置项管理 中配置:
| 配置项 | 值 |
|---|
DING_ENABLED | true |
DING_WEBHOOK | https://oapi.dingtalk.com/robot/send?access_token=xxx |
配置完成后,当有工单提交、审核、执行等状态变更时,钉钉群会自动收到通知,包含工单标题、提交人、SQL 概要等信息。
9.3 企业微信通知
Archery 同样支持企业微信通知:
1WECHAT_ENABLED = true
2WECHAT_CORP_ID = "your_corp_id"
3WECHAT_SECRET = "your_secret"
4WECHAT_AGENT_ID = "your_agent_id"
十、最佳实践与常见坑
10.1 权限管理最佳实践
Archery 的权限体系基于 用户 + 资源组 + 角色,建议这样设计:
10.2 审核规则定制
goInception 支持大量的审核规则配置,以下是一些建议开启的规则:
1# goinception/config.toml 推荐配置
2
3[inc]
4# 强制要求表注释
5check_table_comment = true
6
7# 强制要求列注释
8check_column_comment = true
9
10# 禁止使用 SELECT *
11enable_select_star = false
12
13# 限制 INSERT 语句的批量行数
14max_insert_rows = 10000
15
16# 检查索引前缀
17check_index_prefix = true
18index_prefix = "idx_"
19uniq_index_prefix = "uk_"
20
21# 禁止全表更新/删除
22enable_delete_no_where = false
23enable_update_no_where = false
24
25# 字段默认值检查
26check_column_default_value = true
27
28# 主键检查
29check_primary_key = true
30check_autoincrement = true
31check_autoincrement_init_value = true
10.3 常见问题排查
问题1:Archery 启动后页面打不开
1# 检查容器状态
2docker compose ps
3
4# 查看 Archery 日志
5docker compose logs archery | tail -50
6
7# 常见原因:MySQL 还没初始化完成,重启一下
8docker compose restart archery
问题2:goInception 连接失败
1# 检查 goInception 是否正常运行
2docker compose logs goinception
3
4# 测试连接
5docker exec -it archery bash -c "mysql -h goinception -P 4000 -e 'inception get variables'"
问题3:Oracle 实例连接报错 "cx_Oracle not found"
这是因为容器里没有安装 Oracle 客户端,参考第六节的安装步骤。
问题4:工单执行后无法回滚
确认 goInception 的备份功能已正确配置:
1[inc]
2backup_host = "archery-mysql"
3backup_port = 3306
4backup_user = "root"
5backup_password = "your_password"
并且 Archery 的 MySQL 中有对应的备份库。
10.4 性能优化建议
- MySQL 后端:给 Archery 用的 MySQL 建议使用 SSD 存储,
innodb_buffer_pool_size 设置为物理内存的 50-70%
- Redis:设置
maxmemory 防止内存溢出
- 定期清理:过期的工单和慢日志数据可以定期归档,避免数据量过大影响性能
- 多节点部署:如果并发用户量大,可以部署多个 Archery 实例,前面用 Nginx 做负载均衡
10.5 安全加固
1# 修改默认端口
2# docker-compose.yml 中将 9123 改为其他端口
3
4# 启用 HTTPS(通过 Nginx 反向代理)
5# nginx.conf 示例
1server {
2 listen 443 ssl;
3 server_name archery.example.com;
4
5 ssl_certificate /etc/nginx/ssl/archery.crt;
6 ssl_certificate_key /etc/nginx/ssl/archery.key;
7
8 location / {
9 proxy_pass http://127.0.0.1:9123;
10 proxy_set_header Host $host;
11 proxy_set_header X-Real-IP $remote_addr;
12 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
13 proxy_set_header X-Forwarded-Proto $scheme;
14 }
15}
十一、总结
Archery 作为一个开源的 SQL 审核平台,功能确实很全面。部署起来虽然有些组件需要折腾(尤其是 Oracle 客户端),但整体使用 Docker Compose 还是比较方便的。
回顾一下我们完成的内容:
- 使用 Docker Compose 部署了 Archery 全套环境
- 配置了 MySQL、Oracle、PostgreSQL 三种数据库实例
- 演示了完整的 SQL 审核工作流程
- 配置了慢日志管理
- 集成了 LDAP 和钉钉通知
- 分享了最佳实践和常见问题排查
最后给几点建议:
- 先在测试环境跑起来,熟悉了再推生产
- 审核规则别一开始就太严,循序渐进,否则开发会抵触
- DBA 审核不能完全依赖自动化,自动审核只是辅助,人工 review 仍然重要
- 做好备份,尤其是 Archery 自身的 MySQL 数据库
如果在部署过程中遇到问题,可以参考 Archery 的官方文档和 GitHub Issue,社区还是比较活跃的。
祝大家部署顺利,再也不用在微信群里审核 SQL 了!
本章小结
本章介绍了以下核心内容:
- 前言
- 一、为什么需要 SQL 审核平台
- 二、Archery 架构概览
- 三、Docker Compose 一键部署
- 四、初始配置
- 五、MySQL SQL 审核实战
- 六、Oracle SQL 审核配置
- 七、PostgreSQL SQL 审核配置
- 八、慢日志管理
- 九、集成 LDAP 与消息通知
- 十、最佳实践与常见坑
- 十一、总结