外观
OceanBase 表结构变更
表结构变更类型
在线变更
在线变更是指在不影响数据库正常运行的情况下进行表结构变更,适合生产环境使用。在线变更的特点:
- 变更过程中不阻塞读写操作
- 支持大表变更
- 变更时间长,资源消耗大
- 支持回滚
离线变更
离线变更是指在停止数据库服务或暂停业务的情况下进行表结构变更,适合测试环境或维护窗口使用。离线变更的特点:
- 变更速度快
- 资源消耗小
- 会阻塞读写操作
- 不支持回滚
在线表结构变更
变更命令
sql
ALTER TABLE table_name ADD COLUMN column_name column_type [NOT NULL] [DEFAULT default_value];
ALTER TABLE table_name MODIFY COLUMN column_name column_type [NOT NULL] [DEFAULT default_value];
ALTER TABLE table_name DROP COLUMN column_name;
ALTER TABLE table_name ADD INDEX index_name (column_name);
ALTER TABLE table_name DROP INDEX index_name;
ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name;
ALTER TABLE table_name RENAME TO new_table_name;变更示例
sql
-- 添加列
ALTER TABLE employees ADD COLUMN department_id INT NOT NULL DEFAULT 0;
-- 修改列
ALTER TABLE employees MODIFY COLUMN department_id BIGINT NOT NULL DEFAULT 0;
-- 删除列
ALTER TABLE employees DROP COLUMN department_id;
-- 添加索引
ALTER TABLE employees ADD INDEX idx_department_id (department_id);
-- 删除索引
ALTER TABLE employees DROP INDEX idx_department_id;
-- 重命名列
ALTER TABLE employees RENAME COLUMN department_id TO dept_id;
-- 重命名表
ALTER TABLE employees RENAME TO staff;变更监控
sql
-- 查看当前正在执行的 DDL 任务
SHOW DDL;
-- 查看 DDL 任务历史
SHOW DDL HISTORY;
-- 查看 DDL 任务详情
SELECT * FROM oceanbase.DBA_OB_DDL_JOBS WHERE JOB_ID = job_id;变更优化
并行变更
sql
-- 设置并行度
ALTER SYSTEM SET enable_parallel_ddl = TRUE;
ALTER SYSTEM SET parallel_ddl_workers = 8;
-- 在变更命令中指定并行度
ALTER TABLE employees ADD COLUMN department_id INT NOT NULL DEFAULT 0 PARALLEL 8;批量变更
sql
-- 批量添加列
ALTER TABLE employees
ADD COLUMN department_id INT NOT NULL DEFAULT 0,
ADD COLUMN position VARCHAR(50) NOT NULL DEFAULT '',
ADD COLUMN salary DECIMAL(10,2) NOT NULL DEFAULT 0.00;变更时间窗口
- 选择业务低峰期进行表结构变更
- 避免在高并发时段进行大表变更
- 对于超大型表,考虑分批次变更
离线表结构变更
变更步骤
备份数据
bashobclient -h127.0.0.1 -P2881 -uroot -p -c -A oceanbase -e "BACKUP DATABASE employees TO 'backup_path';"停止业务
- 暂停应用服务
- 停止读写操作
执行变更
sqlALTER TABLE employees ADD COLUMN department_id INT NOT NULL DEFAULT 0;验证变更
sqlDESCRIBE employees; SELECT COUNT(*) FROM employees;恢复业务
- 启动应用服务
- 恢复读写操作
变更工具
OBDDL
bash
# 安装 OBDDL 工具
wget https://mirrors.aliyun.com/oceanbase/community/stable/el/7/x86_64/obddl-2.2.70-1.el7.x86_64.rpm
yum install -y obddl-2.2.70-1.el7.x86_64.rpm
# 使用 OBDDL 执行变更
obddl --cluster=obcluster --tenant=business --sql="ALTER TABLE employees ADD COLUMN department_id INT NOT NULL DEFAULT 0;"OCP
- 通过 OceanBase Cloud Platform (OCP) 界面执行表结构变更
- 支持图形化监控变更进度
- 支持变更回滚
大表结构变更
变更策略
分批次变更
sql
-- 分批次添加索引
ALTER TABLE large_table ADD INDEX idx_column1 (column1) PARALLEL 16;
ALTER TABLE large_table ADD INDEX idx_column2 (column2) PARALLEL 16;预排序
sql
-- 预排序表数据
ALTER TABLE large_table ORDER BY column1;临时表替换
创建临时表
sqlCREATE TABLE large_table_new LIKE large_table; ALTER TABLE large_table_new ADD COLUMN new_column INT NOT NULL DEFAULT 0;导入数据
sqlINSERT INTO large_table_new SELECT *, 0 FROM large_table;替换表
sqlRENAME TABLE large_table TO large_table_old, large_table_new TO large_table;验证数据
sqlSELECT COUNT(*) FROM large_table; SELECT COUNT(*) FROM large_table_old;清理旧表
sqlDROP TABLE large_table_old;
变更监控
sql
-- 查看变更进度
SELECT * FROM oceanbase.DBA_OB_DDL_JOBS WHERE JOB_TYPE = 'ALTER TABLE' AND STATUS = 'RUNNING';
-- 查看变更资源使用
SELECT * FROM oceanbase.GV$OB_DDL_TASK WHERE JOB_ID = job_id;
-- 查看变更日志
SELECT * FROM oceanbase.GV$OB_DDL_LOG WHERE JOB_ID = job_id ORDER BY TIMESTAMP;变更回滚
在线变更回滚
sql
-- 取消正在执行的 DDL 任务
KILL DDL job_id;
-- 回滚已完成的 DDL 任务
ROLLBACK DDL job_id;离线变更回滚
停止业务
- 暂停应用服务
- 停止读写操作
恢复备份
bashobclient -h127.0.0.1 -P2881 -uroot -p -c -A oceanbase -e "RESTORE DATABASE employees FROM 'backup_path';"恢复业务
- 启动应用服务
- 恢复读写操作
变更注意事项
数据类型变更
- 避免将大数据类型转换为小数据类型,可能导致数据截断
- 转换数据类型时,确保数据兼容
- 对于字符类型,注意字符集和排序规则的一致性
索引变更
- 避免在高并发时段添加或删除索引
- 对于大表,考虑使用并行索引创建
- 定期维护索引,删除无用索引
分区表变更
- 分区表的结构变更可能影响所有分区
- 考虑分区表的分布策略
- 对于超大型分区表,考虑分批次变更
约束变更
- 添加 NOT NULL 约束前,确保列中没有 NULL 值
- 添加 UNIQUE 约束前,确保列中没有重复值
- 添加 FOREIGN KEY 约束前,确保引用关系正确
常见问题(FAQ)
Q1: 在线表结构变更会影响数据库性能吗?
A1: 在线表结构变更会消耗数据库资源,可能影响性能,具体影响程度取决于:
- 表的大小
- 变更类型
- 并发度
- 数据库负载
建议在业务低峰期进行在线表结构变更,并监控数据库性能。
Q2: 如何处理表结构变更失败?
A2: 处理表结构变更失败的步骤:
- 查看错误信息
- 分析失败原因
- 修复问题
- 重新执行变更或回滚变更
Q3: 大表结构变更需要多长时间?
A3: 大表结构变更的时间取决于:
- 表的大小
- 变更类型
- 并行度
- 数据库资源
对于 TB 级别的表,在线变更可能需要数小时甚至数天。
Q4: 如何避免表结构变更导致的业务中断?
A4: 避免业务中断的方法:
- 使用在线表结构变更
- 选择业务低峰期进行变更
- 对于大表,考虑使用临时表替换方法
- 提前测试变更方案
- 准备回滚计划
Q5: 表结构变更会导致锁表吗?
A5: 在线表结构变更不会锁表,读写操作可以正常进行。离线表结构变更会锁表,阻塞读写操作。
Q6: 如何监控表结构变更进度?
A6: 监控表结构变更进度的方法:
- 使用 SHOW DDL 命令
- 查询 oceanbase.DBA_OB_DDL_JOBS 视图
- 使用 OCP 监控界面
- 查看数据库日志
Q7: 表结构变更可以回滚吗?
A7: 在线表结构变更支持回滚,离线表结构变更不支持回滚。对于离线变更,建议提前备份数据,以便在变更失败时恢复。
Q8: 如何优化表结构变更性能?
A8: 优化表结构变更性能的方法:
- 增加并行度
- 选择业务低峰期进行变更
- 使用批量变更
- 对于大表,考虑使用临时表替换方法
- 优化数据库配置
Q9: 表结构变更会影响复制吗?
A9: 表结构变更会同步到备库,可能影响复制延迟。建议在变更前检查复制状态,变更后监控复制延迟。
Q10: 如何处理表结构变更导致的复制延迟?
A10: 处理复制延迟的方法:
- 增加备库资源
- 优化复制配置
- 对于大表变更,考虑在备库先执行变更
- 监控复制延迟,必要时暂停变更
表结构变更最佳实践
变更前准备
评估变更影响
- 分析变更对性能的影响
- 评估变更时间
- 识别风险点
备份数据
- 全量备份
- 增量备份
- 日志备份
测试变更
- 在测试环境验证变更
- 测试变更前后的性能差异
- 验证数据完整性
制定变更计划
- 变更时间窗口
- 变更步骤
- 回滚计划
- 验证方法
变更执行
监控数据库状态
- CPU 使用率
- 内存使用率
- IO 负载
- 并发连接数
执行变更
- 按照计划执行变更
- 监控变更进度
- 记录变更日志
验证变更
- 检查表结构
- 验证数据完整性
- 测试业务功能
- 监控性能变化
变更后维护
监控性能
- 持续监控数据库性能
- 分析变更对性能的影响
- 优化数据库配置
更新文档
- 更新表结构文档
- 更新变更日志
- 记录经验教训
清理资源
- 删除临时表
- 清理备份文件
- 释放资源
变更案例
案例一:在线添加列
场景:为员工表添加部门 ID 列
步骤:
- 评估影响:表大小 100GB,预计变更时间 2 小时
- 备份数据:执行全量备份
- 测试变更:在测试环境验证
- 执行变更:在业务低峰期(凌晨 2:00)执行
- 监控变更:使用 SHOW DDL 监控进度
- 验证变更:DESCRIBE 表结构,SELECT 验证数据
- 恢复业务:监控性能,确保正常
结果:变更成功,业务未中断,性能影响在可接受范围内。
案例二:大表索引创建
场景:为 1TB 订单表添加索引
步骤:
- 评估影响:预计变更时间 8 小时
- 备份数据:执行全量备份
- 优化配置:设置并行度为 16
- 执行变更:在周末业务低峰期执行
- 监控变更:使用 OCP 监控进度和资源使用
- 验证变更:查看索引状态,测试查询性能
- 恢复业务:监控查询性能,确保提升
结果:变更成功,查询性能提升 10 倍,资源使用在可接受范围内。
案例三:临时表替换
场景:为 500GB 用户表添加多个列
步骤:
- 创建临时表:包含新列
- 导入数据:使用 INSERT INTO SELECT 导入
- 验证数据:比较新旧表数据量
- 替换表:使用 RENAME TABLE 原子替换
- 验证业务:测试业务功能
- 清理旧表:删除旧表
结果:变更时间仅 30 分钟,业务中断时间不到 1 秒。
