# 数据中心 MySQL 与接口中心部署说明 ## 已确定的系统边界 - PostgreSQL:继续保存账号、权限、图谱项目与 Schema 等系统元数据。 - FalkorDB:继续保存已发布知识图谱节点和关系。 - MySQL:只负责“数据中心”的关系型业务数据。 - 接口中心当前页面只管理 DBeaver 管理接入:选择数据库、签发个人密钥与账号、查看状态和撤销权限。 - DBeaver:仅供受信任的数据管理员通过专用 SSH 隧道管理 MySQL,使用独立 MySQL 用户和 `GRANT` 权限;不复用接口密钥,也不公开 MySQL 端口。 - SQL 控制台:生产默认只读;写入通过数据表页面执行,以保留记录级变更历史,物理删除始终禁止。 每个数据中心数据库都是真实 MySQL Database:中文名称只用于页面显示,英文数据库编码直接作为物理 MySQL 数据库名。前端数据中心的现有 URL、布局和 `/v1/admin/data-platform/*` 契约保持不变。 ## 配置 关键环境变量: ```dotenv DATA_MYSQL_URL=mysql://data_center:strong-password@mysql:3306/platform_control DATA_MYSQL_REQUIRED=true DATA_MYSQL_POOL_MIN_SIZE=2 DATA_MYSQL_POOL_MAX_SIZE=20 INTERFACE_API_SECRET=another-long-random-secret DATA_MYSQL_DIRECT_ACCESS_ENABLED=true MYSQL_HOST_BIND=127.0.0.1 MYSQL_PORT=3307 DATA_MYSQL_DIRECT_TRANSPORT=SSH 隧道(强制) DATA_MYSQL_SSH_TUNNEL_REQUIRED=true DATA_MYSQL_SSH_HOST=server.example.com DATA_MYSQL_SSH_PORT=2222 DATA_MYSQL_SSH_BIND=127.0.0.1 DATA_MYSQL_SSH_USERNAME=dbeaver DATA_MYSQL_SSH_AUTH_METHOD=SSH 私钥 / SSH Agent DATA_MYSQL_MANAGED_ACCESS_ENABLED=true DATA_MYSQL_SSH_AUTHORIZED_KEYS_FILE=/var/lib/travel-kg/dbeaver-access/authorized_keys DATA_MYSQL_SSH_HOST_PUBLIC_KEY_FILE=/var/lib/travel-kg/dbeaver-access/ssh_host_ed25519_key.pub MYSQL_ACCESS_BROKER_USER=access_broker MYSQL_ACCESS_BROKER_PASSWORD=至少24位独立随机字符串 DATA_MYSQL_ADMIN_HOST=127.0.0.1 DATA_MYSQL_ADMIN_PORT=3307 DATA_MYSQL_ADMIN_ACCOUNT_POLICY=一人一号 · 单库授权 · 禁止 root DATA_MYSQL_AUDIT_ENABLED=false DATA_SQL_CONSOLE_WRITE_ENABLED=false MYSQL_STORAGE_MOUNT=/mnt/sdr MYSQL_STORAGE_ID=prod-mysql-storage-2026-001 MYSQL_DATA_DIR=/mnt/sdr/nianxx/mysql DATA_BACKUP_ROOT=/mnt/backup/nianxx/mysql DATA_BACKUP_RETENTION_DAYS=30 DATA_BACKUP_PASSPHRASE_FILE=/etc/travel-kg/secrets/mysql-backup-passphrase DATA_BACKUP_ENABLED=false ``` `MYSQL_HOST_BIND` 在生产环境必须保持 `127.0.0.1`。远程电脑访问的是专用 SSH 网关端口,不是 MySQL 端口。`DATA_MYSQL_SSH_BIND=127.0.0.1` 只支持服务器本机 测试;服务器上线后可设置为服务器内网地址,或设置为 `0.0.0.0` 并在安全组/防火墙 中仅放行管理员固定 IP 或 VPN 网段。只有数据库审计真实启用后,才把 `DATA_MYSQL_AUDIT_ENABLED` 改成 `true`。 `access_broker` 是仅供接口中心签发/撤销个人 MySQL 账号的独立服务账号。普通 `data_center` 账号不持有 `CREATE USER` 或 `GRANT OPTION`,两者密码不得相同。 应用会记录 API 调用、记录新增/修改/软删除以及 SQL 控制台的成功、失败和拒绝 事件;SQL 审计只保存语句 SHA-256,不保存可能包含敏感值的原文。DBeaver 绕过 应用,因此仍必须由数据库审计能力单独留痕,未完成前不得开放长期写权限。 生产 MySQL 数据目录绑定到服务器独立块存储,不使用项目目录或普通 Docker named volume。Compose 启动前会核对独立磁盘身份标识、目录写权限和已有 MySQL 数据结构; 挂载丢失或路径错误时直接停止,不会初始化一个看似正常的空库。准备磁盘、迁移旧卷、 安装每日加密备份的完整流程见 `docs/DEPLOYMENT.md`。 生产 MySQL 开启 ROW Binlog、`sync_binlog=1` 与 `innodb_flush_log_at_trx_commit=1`,用于时间点恢复与事务落盘;加密备份脚本和 恢复要求见 `docs/DEPLOYMENT.md`。 `platform_control` 保存数据库目录、表定义、数据审计、接口客户端、密钥哈希、权限策略与接口调用日志。完整接口密钥不会保存,只保存带服务端 pepper 的 HMAC-SHA256 哈希。 ## 首次部署 ```bash docker compose -f docker-compose.yml -f docker-compose.server.yml up -d --build mysql dbeaver-gateway api ``` 已有 MySQL 数据卷不会重新运行初始化脚本。升级既有部署后执行一次: ```bash ./scripts/enable_managed_dbeaver_access.sh ``` 接口中心页面:`/admin/system/interfaces`。 页面以“服务器被访问”为方向:为受信任的数据管理员生成个人 SSH 密钥、独立 MySQL 账号和最小权限。接口中心不会主动连接外部数据库,也不在这个页面混入 HTTPS API 客户端、接口策略或调用日志等其他管理流程。 ## DBeaver 安全连接 DBeaver 不使用 URL 模式直接填写服务器公网地址。按两组参数配置: 1. 在接口中心选择数据库、管理员姓名和“只读/读写”,点击“生成 DBeaver 接入”; 2. 私钥由浏览器本地生成,平台只接收公钥。立即下载私钥并保存一次性 MySQL 密码; 3. `SSH` 标签页:`Host/IP=服务器域名`、`Port=2222`、`User Name=dbeaver`、认证方式选择 `Public Key` 并选择刚下载的私钥;不要启用 `Bypass host verification`,首次连接提示的 SSH 主机指纹必须与接口中心一致; 4. `Main` 标签页:`Server Host=127.0.0.1`、`Port=3307`、`Database=获授权数据库编码`,填写生成的个人 MySQL 用户名和密码; 5. 关闭 `Show all databases`;默认只授予查询权限,读写权限也不包含建库、建表、`ALTER`、`DROP` 或给他人授权。 接口中心可以直接撤销管理接入,撤销会同时删除个人 MySQL 账号和 SSH 公钥。 服务器脚本保留为故障处理备用方式: ```bash ./scripts/mysql_admin_account.sh create zhangsan tourism_data read ./scripts/mysql_admin_account.sh create lisi tourism_data write ./scripts/mysql_admin_account.sh revoke zhangsan ``` 脚本只授予指定数据库权限:`read` 为 `SELECT/SHOW VIEW`,`write` 额外包含 `INSERT/UPDATE/DELETE`,不授予建库、删库、授权、文件或系统库权限;账号连续 失败 5 次锁定一天,密码 90 天过期。MySQL 端口仍必须绑定回环地址,账号的 `'%'` 主机范围不能替代网络隔离。 完整私钥和 MySQL 密码只在生成成功时显示一次,服务器不保存私钥,也不保存可恢复 的 MySQL 密码。专用 SSH 账号被禁止终端、PTY、SFTP、Agent/X11 转发,只允许将 连接转发到 `127.0.0.1:3307`。服务器安全组只允许受控来源访问 HTTPS 与专用 SSH 端口,不开放 `3307`。 本地模拟服务器连接时使用: ```dotenv DATA_MYSQL_SSH_HOST=localhost DATA_MYSQL_SSH_BIND=127.0.0.1 DATA_MYSQL_SSH_PORT=2222 ``` 服务器部署后把 `DATA_MYSQL_SSH_HOST` 改为服务器域名;若管理员电脑不在同一内网, 还必须把 `DATA_MYSQL_SSH_BIND` 绑定到可达网卡,并用防火墙限定管理员来源 IP。 ## 迁移旧数据中心 先预览,不写入: ```bash python3 scripts/migrate_data_center_postgres_to_mysql.py ``` 确认计划后执行: ```bash python3 scripts/migrate_data_center_postgres_to_mysql.py --execute ``` 如果目标 MySQL 中已存在同编码数据库,脚本默认拒绝覆盖。只有确认目标可以重建时才使用: ```bash python3 scripts/migrate_data_center_postgres_to_mysql.py --execute --replace-target ``` 迁移会保留记录 UUID、创建/更新时间、软删除状态和数据变更审计,从而避免实体引用失效;不会修改 PostgreSQL 源数据,也不会操作 FalkorDB 或知识图谱。 ## 预留的数据接口权限模型 以下后端能力为后续 HTTPS 数据接口预留,当前 DBeaver 管理接入页面不显示: 一条接口策略包含: 1. 客户端(电脑、应用、合作方或设备); 2. 数据库; 3. 数据表或全部表; 4. `metadata/read/create/update/delete` 动作; 5. 可读字段与可写字段; 6. 可选的行级 JSON 范围,例如 `{"district":"荔波县"}`; 7. 启用/停用状态。 接口客户端无法访问 `platform_control`、MySQL 系统库或其他业务数据库,也不能通过 API 执行 SQL。每次接口调用都会记录客户端、动作、资源范围、状态码、耗时和来源 IP。