docs: OSC/gh-ost 完整技术文档
- 为什么需要OSC + 三种方案对比(Native/gh-ost/pt-osc) - 场景推荐矩阵: 按数据库类型/环境/DDL类型 - 平台13项配置说明 - API接口文档(analyze/dry-run/execute/status) - gh-ost最佳实践(执行流程/大表参数/暂停恢复/回滚) - 云数据库特殊说明(Aurora/PolarDB/RDS/自建)
This commit is contained in:
1 parent
78986fe5bf
commit
ce8bb9710b
1 file changed
+309
@@ -0,0 +1,309 @@
|
||||
# OSC (Online Schema Change) 指南
|
||||
|
||||
> SQL-Platform-Pro 集成了多种在线 DDL 变更方案,根据数据库类型、版本、环境自动推荐最优策略。
|
||||
|
||||
## 一、为什么需要 OSC?
|
||||
|
||||
传统 `ALTER TABLE` 在大表上执行时会**锁表**,导致业务不可用:
|
||||
|
||||
| 问题 | 影响 |
|
||||
|---|---|
|
||||
| **锁表** | MDL 写锁阻塞所有读写请求 |
|
||||
| **全表拷贝** | 按 row copy 重建表,耗时随数据量线性增长 |
|
||||
| **不可暂停** | 一旦开始无法中途停止,只能 kill |
|
||||
| **主从延迟** | 大事务导致 binlog 积压,从库大幅延迟 |
|
||||
|
||||
OSC 工具通过**创建影子表 + 增量同步**的方式,实现**不锁表**的在线变更。
|
||||
|
||||
---
|
||||
|
||||
## 二、平台支持的三种 DDL 方案
|
||||
|
||||
### 1. Native DDL (MySQL 官方)
|
||||
|
||||
MySQL 8.0+ 内置的 INSTANT DDL 能力,**零拷贝、秒级完成**。
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **最低版本** | MySQL 8.0.12 |
|
||||
| **原理** | 只修改数据字典元数据,不拷贝数据 |
|
||||
| **支持的 DDL** | ADD COLUMN (末尾)、DROP COLUMN、ADD INDEX、DROP INDEX、MODIFY 默认值 |
|
||||
| **不支持的** | CHANGE COLUMN 类型、ADD COLUMN 指定位置 (8.0.28 以下)、RENAME COLUMN |
|
||||
| **语法** | `ALTER TABLE t ADD COLUMN c INT, ALGORITHM=INSTANT;` |
|
||||
|
||||
**优势**:最快、最简单、零风险
|
||||
**劣势**:部分 DDL 类型不支持,回退到 INPLACE/COPY 时仍可能锁表
|
||||
|
||||
### 2. gh-ost (GitHub 开源)
|
||||
|
||||
GitHub 开发的在线 DDL 工具,通过 **binlog 流式同步**实现零锁变更。
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **GitHub** | https://github.com/github/gh-ost |
|
||||
| **原理** | 创建影子表 → 拷贝数据 → 通过 binlog 实时同步增量变更 → 原子 cut-over 切换 |
|
||||
| **依赖** | MySQL binlog_format=ROW, binlog_row_image=FULL |
|
||||
| **特点** | 无触发器、可暂停/恢复、实时进度输出、支持回滚 |
|
||||
|
||||
**优势**:
|
||||
- 不使用触发器,对数据库性能影响最小
|
||||
- 可随时暂停 (`--postpone-cut-over-flag-file`)
|
||||
- 实时进度 (`Copy: 100000/500000 20.0%`)
|
||||
- 支持回滚 (保留旧表)
|
||||
|
||||
**劣势**:
|
||||
- 需要开启 binlog
|
||||
- 需要安装 gh-ost 二进制
|
||||
- 单机 MySQL 需加 `--allow-on-master`
|
||||
|
||||
### 3. pt-online-schema-change (Percona)
|
||||
|
||||
Percona Toolkit 中的 OSC 工具,通过**触发器**同步增量变更。
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **官网** | https://docs.percona.com/percona-toolkit/pt-online-schema-change.html |
|
||||
| **原理** | 创建影子表 → 拷贝数据 → 通过 AFTER INSERT/UPDATE/DELETE 触发器同步增量 |
|
||||
| **依赖** | MySQL 5.1+ |
|
||||
| **状态** | 平台预留接口,暂未集成 |
|
||||
|
||||
**优势**:兼容性好,MySQL 5.1+ 都支持
|
||||
**劣势**:触发器对高并发场景性能影响较大
|
||||
|
||||
---
|
||||
|
||||
## 三、方案对比
|
||||
|
||||
| 维度 | Native INSTANT | gh-ost | pt-osc |
|
||||
|---|---|---|---|
|
||||
| **执行速度** | ⚡ 秒级 | 🔄 数据量相关 | 🔄 数据量相关 |
|
||||
| **锁表风险** | ❌ 无 | ❌ 无 (cut-over 瞬间 <1s) | ❌ 无 (cut-over 瞬间 <1s) |
|
||||
| **性能影响** | 无 | 低 (binlog 解析) | 中 (触发器开销) |
|
||||
| **可暂停** | N/A | ✅ | ✅ |
|
||||
| **进度可见** | N/A | ✅ 百分比 | ❌ |
|
||||
| **支持回滚** | ❌ | ✅ 保留旧表 | ✅ 保留旧表 |
|
||||
| **Binlog 要求** | 无 | ROW + FULL | 无 |
|
||||
| **MySQL 版本** | 8.0.12+ | 5.6+ | 5.1+ |
|
||||
| **云数据库** | ✅ 推荐 | ⚠️ 需开 binlog | ⚠️ 需开 binlog |
|
||||
|
||||
---
|
||||
|
||||
## 四、场景推荐矩阵
|
||||
|
||||
### 按数据库类型
|
||||
|
||||
| 场景 | 推荐方案 | 原因 |
|
||||
|---|---|---|
|
||||
| **AWS Aurora MySQL** + 任何 DDL | Native DDL | Aurora 原生 DDL 已深度优化,开 binlog 影响性能和存储成本 |
|
||||
| **阿里云 PolarDB MySQL** + ADD/DROP COLUMN | Native DDL | PolarDB 自带 Instant DDL,秒级完成 |
|
||||
| **阿里云 RDS MySQL** + 大表 DDL | gh-ost + `--aliyun-rds` | RDS 权限受限,gh-ost 有专用适配模式 |
|
||||
| **自建 MySQL 8.0+** + 小表 | Native INSTANT | 版本支持,秒级完成,无需额外工具 |
|
||||
| **自建 MySQL 8.0+** + 大表生产 | gh-ost | 可暂停+进度可见+回滚安全 |
|
||||
| **自建 MySQL 5.7** + 大表 | gh-ost | 5.7 无 INSTANT,必须用 OSC 工具 |
|
||||
|
||||
### 按环境
|
||||
|
||||
| 场景 | 推荐方案 | 原因 |
|
||||
|---|---|---|
|
||||
| **开发/测试环境** | Native DDL | 数据量小,即使 COPY 也很快 |
|
||||
| **预发布环境** | gh-ost dry-run | 先预检,确认变更可行性 |
|
||||
| **生产环境** + 表 < 10万行 | Native DDL | 小表无风险 |
|
||||
| **生产环境** + 表 > 10万行 | gh-ost | 行数超阈值,安全起见用 OSC |
|
||||
| **生产环境** + 表 > 1000万行 | gh-ost + chunk_size=500 | 大表限流,降低对线上影响 |
|
||||
|
||||
### 按 DDL 类型
|
||||
|
||||
| DDL 操作 | MySQL 8.0+ INSTANT | 推荐 |
|
||||
|---|---|---|
|
||||
| `ADD COLUMN` (末尾) | ✅ 支持 | Native INSTANT |
|
||||
| `DROP COLUMN` | ✅ 支持 (8.0.12+) | Native INSTANT |
|
||||
| `ADD INDEX` | ❌ INPLACE | gh-ost (大表) 或 Native INPLACE (小表) |
|
||||
| `DROP INDEX` | ❌ INPLACE | Native INPLACE (不拷贝数据) |
|
||||
| `MODIFY COLUMN` 类型 | ❌ COPY | **必须 gh-ost** |
|
||||
| `CHANGE COLUMN` | ❌ COPY | **必须 gh-ost** |
|
||||
| `ADD COLUMN` (指定位置 AFTER) | ✅ 支持 (8.0.29+) | 版本够用 Native,否则 gh-ost |
|
||||
| `DROP PRIMARY KEY` | ❌ COPY | **必须 gh-ost** |
|
||||
|
||||
---
|
||||
|
||||
## 五、平台配置说明
|
||||
|
||||
平台通过 `system_settings` 表管理 gh-ost 策略,共 13 项配置:
|
||||
|
||||
### 基础配置
|
||||
|
||||
| 配置项 | Key | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 全局开关 | `ghost_enabled` | `false` | 关闭后所有 gh-ost API 返回 403 |
|
||||
| 默认执行模式 | `ghost_default_mode` | `dry_run` | `dry_run`=仅预检, `execute`=真实执行 |
|
||||
| OSC 优先级 | `ghost_osc_priority` | `native_first` | `native_first` / `ghost_first` / `ghost_only` |
|
||||
| 环境模式 | `ghost_env_mode` | `development` | `development`=Native优先, `production`=强制gh-ost |
|
||||
| 云数据库类型 | `ghost_cloud_type` | `self_hosted` | `self_hosted` / `aliyun_rds` / `polardb` / `aws_aurora` |
|
||||
|
||||
### 自动触发条件
|
||||
|
||||
| 配置项 | Key | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 行数阈值 | `ghost_auto_trigger_rows` | `10` (万) | 表行数超过此值自动推荐 gh-ost |
|
||||
| DDL 类型 | `ghost_auto_trigger_ddl` | `ADD COLUMN,...` | 匹配这些 DDL 类型自动触发 |
|
||||
|
||||
### 执行参数
|
||||
|
||||
| 配置项 | Key | 默认值 | 说明 |
|
||||
|---|---|---|---|
|
||||
| 二进制路径 | `ghost_path` | `/usr/local/bin/gh-ost` | gh-ost 可执行文件路径 |
|
||||
| Chunk Size | `ghost_default_chunk_size` | `1000` | 每批拷贝行数 |
|
||||
| 最大负载 | `ghost_max_load` | `Threads_running=25` | 超过则限流 |
|
||||
| 临界负载 | `ghost_critical_load` | `Threads_running=50` | 超过则立即终止 |
|
||||
| 复制延迟 | `ghost_max_lag_millis` | `1500` | 超过此延迟限流 (ms) |
|
||||
| 允许主库执行 | `ghost_allow_on_master` | `true` | 单机/无从库需开启 |
|
||||
|
||||
---
|
||||
|
||||
## 六、API 接口
|
||||
|
||||
### 智能分析 (推荐第一个调用)
|
||||
|
||||
```bash
|
||||
POST /api/v1/ghost/analyze
|
||||
{
|
||||
"instance_id": 3,
|
||||
"database": "mydb",
|
||||
"table": "users",
|
||||
"alter": "ADD COLUMN phone VARCHAR(20) DEFAULT ''"
|
||||
}
|
||||
|
||||
# 响应
|
||||
{
|
||||
"enabled": true,
|
||||
"ddl_types": ["ADD COLUMN"],
|
||||
"needs_osc": false,
|
||||
"recommended_tool": "native",
|
||||
"reason": "开发/测试环境,建议使用 Native DDL",
|
||||
"mysql_version": "8.4.9",
|
||||
"supports_instant": true,
|
||||
"cloud_type": "self_hosted",
|
||||
"table_rows": 150000,
|
||||
"config": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
### Dry-Run (预检,不实际执行)
|
||||
|
||||
```bash
|
||||
POST /api/v1/ghost/dry-run
|
||||
{
|
||||
"instance_id": 3,
|
||||
"database": "mydb",
|
||||
"table": "users",
|
||||
"alter": "ADD COLUMN phone VARCHAR(20) DEFAULT ''"
|
||||
}
|
||||
```
|
||||
|
||||
### Execute (真实执行变更)
|
||||
|
||||
```bash
|
||||
POST /api/v1/ghost/execute
|
||||
{
|
||||
"instance_id": 3,
|
||||
"database": "mydb",
|
||||
"table": "users",
|
||||
"alter": "ADD COLUMN phone VARCHAR(20) DEFAULT ''"
|
||||
}
|
||||
```
|
||||
|
||||
### 查看配置
|
||||
|
||||
```bash
|
||||
GET /api/v1/ghost/config
|
||||
```
|
||||
|
||||
### 任务状态
|
||||
|
||||
```bash
|
||||
GET /api/v1/ghost/tasks
|
||||
GET /api/v1/ghost/status/:taskId
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、gh-ost 最佳实践
|
||||
|
||||
### 生产环境执行流程
|
||||
|
||||
```
|
||||
1. POST /ghost/analyze → 确认推荐方案
|
||||
2. POST /ghost/dry-run → 预检连接/权限/binlog
|
||||
3. 确认 dry-run 成功
|
||||
4. POST /ghost/execute → 真实执行
|
||||
5. GET /ghost/status/:id → 监控进度
|
||||
```
|
||||
|
||||
### 大表参数建议
|
||||
|
||||
| 表行数 | chunk_size | max_load | 说明 |
|
||||
|---|---|---|---|
|
||||
| < 100万 | 1000 | Threads_running=25 | 默认配置 |
|
||||
| 100万-1000万 | 500 | Threads_running=20 | 适当限流 |
|
||||
| > 1000万 | 200-500 | Threads_running=15 | 严格限流 |
|
||||
| > 1亿 | 100 | Threads_running=10 | 极限限流 + 业务低峰执行 |
|
||||
|
||||
### 紧急暂停/恢复
|
||||
|
||||
gh-ost 支持运行时暂停,通过 flag 文件控制:
|
||||
|
||||
```bash
|
||||
# 暂停 cut-over (数据同步继续,不切换表)
|
||||
touch /tmp/gh-ost.mydb.users.postpone
|
||||
|
||||
# 恢复
|
||||
rm /tmp/gh-ost.mydb.users.postpone
|
||||
```
|
||||
|
||||
### 回滚方案
|
||||
|
||||
gh-ost 执行完成后**旧表保留**(`_old` 后缀),确认无问题后手动删除:
|
||||
|
||||
```sql
|
||||
-- 确认新表数据正确后,删除旧表
|
||||
DROP TABLE IF EXISTS `users_old`;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 八、云数据库特殊说明
|
||||
|
||||
### AWS Aurora MySQL
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **推荐方案** | Native DDL |
|
||||
| **binlog** | 默认关闭,开启影响性能和存储成本 |
|
||||
| **如果必须用 gh-ost** | 需在 Cluster Parameter Group 开启 binlog + `binlog_format=ROW` + `binlog_row_image=FULL` |
|
||||
| **平台 flag** | `ghost_cloud_type=aws_aurora` → 自动加 `--aws` |
|
||||
|
||||
### 阿里云 PolarDB MySQL
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **推荐方案** | Native DDL (PolarDB 自带 Instant DDL) |
|
||||
| **DDL 优化** | 大部分 ALTER 秒级完成,无需 OSC 工具 |
|
||||
| **如果必须用 gh-ost** | 需开启 binlog,官方 FAQ 确认支持 |
|
||||
|
||||
### 阿里云 RDS MySQL
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **推荐方案** | 小表 Native,大表 gh-ost |
|
||||
| **gh-ost 适配** | 需加 `--aliyun-rds` flag |
|
||||
| **权限** | RDS 不授 SUPER 权限,gh-ost 有专门适配 |
|
||||
| **平台 flag** | `ghost_cloud_type=aliyun_rds` → 自动加 `--aliyun-rds` |
|
||||
|
||||
### 自建 MySQL
|
||||
|
||||
| 项目 | 说明 |
|
||||
|---|---|
|
||||
| **推荐方案** | MySQL 8.0.12+ 小表 Native,大表 gh-ost |
|
||||
| **前置条件** | `binlog_format=ROW` + `binlog_row_image=FULL` |
|
||||
| **单机环境** | 需加 `--allow-on-master`(平台默认开启) |
|
||||
| **主从环境** | 优先在从库执行,主库自动同步 |
|
||||
Reference in new issue
Block a user