数据库线上操作流程规范
1.提前评估
生产操作前必须评估操作的后果,包括不限于以下性能风险检查项:
实例级别(存在大表数据库DDL需要与DBA确认操作时间窗口)
锁规模(存在锁升级和锁堆积风险时避免操作)
并发数(并发活跃线程数>200,并发连接数>3500时禁止操作)
阻塞状态(存在大量阻塞时禁止操作)
无大事务(存在running状态未提交事务时禁止操作)
资源负载(出现资源报警的节点禁止操作)
确认操作不影响业务的前提下,可提交工单,原则上所有生产操作必须提工单,在工单审批流程结束后,方可执行相关任务。
1.场景:增加字段
操作流程
1.保证增加字段的类型、长度、精度和业务的匹配性
2.如果新增字段设置not null,则需要考虑字段默认值,老数据问题,考虑老数据insert是否报错,添加not null字段会给老的数据设置默认值,表中如果老数据非常多
且并发访问高,很有可能导致大面积的阻塞等待以及产生大事务,先不带not null加上列,再更改列默认值,再批量订正老数据,然后再加上not null属性。
回滚方案
1. 大表的新增字段不允许回滚。因为回滚即删掉字段,会导致锁表,持续时间很长进而导致一序列的严重问题。
2. 普通表的新增字段如果是发布失败,后续还会有二次发布,也不考虑回滚。
3. 普通表如果应用有足够的理由要求回滚,则回滚。
2.场景:新建索引
操作流程
1.在已有表上新建索引操作会对数据库造成一定的风险,操作尽量安排在凌晨避开高峰期操作,新上项目发布新建操作可以与项目发布同时(重大变更除外)。
2.在核心表和字段创建索引,需要关注新索引影响的范围是单个sql还是会影响其他sql,应该事前在SQL全文索引中,检查并整理出可能影响到的sql.
3.大表不允许在生产环境直接给字段创建索引,创建一张和原表结构和数据一样的表,只是表名不同,操作此表添加索引,之后考虑平滑迁移替换原生产表。
4.在已有表上建索引操作属于重大变更,操作前须告知团队成员和DBA评估风险,通过以后可提交工单申请处理。
回滚方案
1.如果新建后导致其他sql执行计划发生了意想不到的变化,直接删除索引。
2.若创建索引长时间没有响应,系统仍可控的话,不要轻易尝试回滚,试着找出阻塞的原因。
3.场景:删除索引
操作流程
1.首先要明确因何种原因删除索引,根据原因确定删除方案和时间,操作尽量安排在凌晨避开高峰期操作。
2.准备删除索引脚本或命令,如果是删除不会被用到的索引,需要确保没有sql引用该索引。
3.删除索引前必须准备好回滚方案,copy出索引的完整定义放置变更单中,以便能及时回滚。
4.在已有表上删除索引操作属于重大变更,操作前须告知团队成员和DBA评估风险,通过以后可提交工单申请处理。
回滚方案
1.删除索引的过程存在一定风险,重建后也可能会导致单条或多条sql改变执行计划,直接或间接影响到数据库和应用,必须准备好回退方案。
2.因事先保存了索引创建的完整定义,回滚的第一选择是创建一个和原先一样的索引,可参考《新建索引》
4.场景:Truncate表
操作流程
1.明确truncate操作是不可逆操作.
2.提前协商所清理数据是否需要备份。truncate操作不推荐备份,因为都是临时数据或不重要数据,对业务影响较小。
3.核心表严禁truncate操作,防止数据无法回滚。
3.truncate操作属于重大变更,操作前须告知团队成员和DBA评估风险,通过以后可提交工单申请处理。
回滚方案
1.如果数据有备份,则直接从备份里恢复。
2.如果数据无备份,马上联系DBA,打开备份库或者从库,然后对数据进行恢复。
5.场景:删除表
操作流程
1.整理依赖该表的对象,包含存储过程、视图、触发器等。
2.根据表和其依赖对象,整理还在使用表的服务,对服务进行改造、下线处理。
3.在监控系统中对该表进行持续一周以上的监控,保证表无写入和读取等操作。
4.完成以上步骤之后,对表结构进行备份,包含存储过程、视图等结构,并将表进行重命名,研发人员配合监控服务一周以上,保证无任何异常。
5.删除表操作属于重大变更,操作前须告知团队成员和DBA评估风险,通过以后可提交工单申请处理。
回滚方案
1.上面删除表的过程中,回退可能出现在两个地方:
a表重命名的回退,修改为原来表名。
b表删除的回退,使用表的备份结构进行回滚。
2.操作规范
1. DDL规范:
DDL操作同一个表的多个列时,合并成一个SQL,减少DDL执行时的资源和临时表消耗;
表必须有主键,例如自增主键
在创建数据表时,必须添加如下两个字段,字段类型、默认值与更新时机必须与下面所写一致
`create_stime` datetime not null DEFAULT CURRENT_TIMESTAMP comment '行插入时间',
`update_stime` datetime not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '行修改时间'
或
`create_time` datetime not null DEFAULT CURRENT_TIMESTAMP comment '行插入时间',
`update_time` datetime not null DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '行修改时间'
2. DML规范:
update、delete语句必须包含where条件
不使用SELECT *,只获取必要的字段
大批量delete、update、insert时,需要分批操作,将大事务拆分成小事务.
大量删除数据前需要做好备份
3. 索引规范:
禁止使用外键约束,避免锁升级DML性能影响和群集同步逻辑的影响
一张表中索引不要超过20个,避免生成次优执行计划和写入代价,索引不是越多越好,按实际需要进行创建
不在索引列进行数学运算和函数运算
不在离散度低列上建立索引,避免冗余或重复索引
联合索引要按选择性排序,字段总数建议不超过4个
4. 归档和备份规范:
确保所有生产库存在完备的备份方案和任务
有效生产数据的大量删除(>6个月),必须做归档后进行
5. 禁止规范:
禁止使用视图
禁止使用触发器
禁止使用存储过程
禁止使用event scheduler
3.工单流程
1. 原则上所有生产操作必须提工单,在工单审批流程结束后,方可执行相关任务;
2. 对于已经影响生产的紧急情况,需要立即操作的,也需要实例的负责人或更高级负责人进行操作内容和时间的显式确认,可以是企业微信,邮件形式,且事后补提工单;
3. 对于无法通过性能风险检查项又必须要执行的,必须告知dba负责人和业务负责人相关风险,在讨论制定完备的操作和回滚方案后方可执行,避免不可预料的生产风险;
4. 对于联系不到业务负责人及上级负责人的情况(比如半夜上线的意外bug),在非生产时间窗口,通过性能风险检查项的情况下,并且非破坏性操作的,可以执行相关操作,但务必在24小时内补提工单.