作者:凌洛,阿里云数据库运维专家
背景
前一段时间“删库跑路”引起大家对数据库安全的关注,都在担心如果误删的数据能不能恢复?如何恢复?阿里云数据库RDS MySQL的数据安全机制怎么样呢?怎么才能做到事前预防、事后恢复呢?阿里云数据库全方位保护您的数据安全,多角度恢复数据,这篇文章我们就来聊聊这个话题。
事前预防
事前预防可以从以下几方面看:
- 权限隔离
- 环境隔离
- 库表备份设置
- 数据库管理DMS
- 备份服务DBS
RDS MySQL从产品上做了以下完善:
权限隔离
环境隔离
曾经有一个开发误把生产当测试环境,误修改很多数据,我们要尽量的把测试、预发、生产环境隔开,降低因为环境识别错误导致的数据安全事件。
内核回收站
适用版本
MySQL 8.0
回收机制
执行DROP TABLE/DATABASE语句时,只保留相关的表对象,并移动到专门的recycle bin目录中。其它对象的删除策略如下:
如果是与表无关的对象,根据操作语句决定是否保留,不做回收。
如果是表的附属对象,可能会修改表数据的,做删除处理,例如Trigger和Foreign key。 但Column statistics不做清理,随表进入回收站。
清理机制
回收站会启动一个后台线程,来异步清理超过recycle_bin_retention时间的表对象。在清理回收站表的时候,如果遇到大表,会再启动一个后台线程异步删除大表。
设置实例备份规则
RDS MySQL默认选择整实例备份,但从去年开始我们支持了可以按库表备份,为了尽快的恢复数据,可以指定库表备份。
数据库管理DMS
DMS是一款强大的数据库管理和设计工具,直观的GUI开发环境让用户简单管理多达23种数据库,包括表结构设计、数据操作、数据开发及性能诊断优化等操作。
DMS通过研发规范、权限控制、操作拦截、数据脱敏、安全审计及变更回滚等功能有效保障数据安全。
可以将权限细分,识别出数据安全风险,从原来的审计变成拦截:
设置安全规则
建议您在刚开始就设置执行DDL、DML的规则
全流程把控
DMS从代码变更、数据变更、代码发布一条龙服务,特别是企业版融合了阿里十年的经验,审批、审计、定时执行等功能。
DBS
为数据库提供连续数据保护、低成本的备份服务。它可以为多种环境的数据提供强有力的保护,包括企业数据中心、其他云厂商、混合云及公共云。
产品功能
- 可恢复任1秒数据
实例、单库、多表、单表,备份及恢复粒度自由选择,RTO大幅降低,备份有效性实时验证
- 安全加密
无论传输,还是存储使用最严苛的加密技术,保护用户数据安全
- 低成本,免运维
低成本异地备份,让企业快速满足三级等保要求,无需为灾备提供前期成本,配置到运行只需几分钟
- 多环境支持
支持自建IDC、云上自建数据库、其他云环境的数据库备份
和RDS自带备份的区别
针对RDS数据库,DBS提供转储备份和逻辑备份,满足RDS客户的异地备份和灵活备份诉求。
针对RDS数据库,RDS提供物理备份,满足RDS客户的本地备份和快速恢复诉求。
此外,DBS还可以查询和数据分析,而RDS自带的备份是不行的。
DBS的入口
DBS控制台/官网入口
DMS侧入口
事中谨慎
DDL使用回收站
MySQL 8.0
mysql> SET SESSION RECYCLE_BIN=ON;---------------------------------------打开会话级回收站
mysql> CALL DBMS_RECYCLE.SHOW_TABLES();-------------------------------看回收站里的表
mysql> DROP TABLE tablename;--------------------------------------------------删除表
mysql> CALL DBMS_RECYCLE.PURGE_TABLE (‘<TABLE>’);-------------------清理回收站里的表
mysql> call dbms_recycle.show_tables();
+------------------+-----------------+---------------------+------------------+------------------------+------------------------+
| SCHEMA | TABLE | ORIGIN_SCHEMA | ORIGIN_TABLE | RECYCLED_TIME | PURGE_TIME |
+------------------+-----------------+---------------------+------------------+------------------------+------------------------+
| __recycle_bin__ | __innodb_1063 | product_db | t1 | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1064 | product_db | t2 | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1065 | product_db | parent | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1066 | product_db | child | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
+------------------+------------------+--------------------+------------------+------------------------+-------------------------+
操作注意事项
- 前台业务和后台运维/数据分析隔离
- 带WHERE条件
- 注意读写分离,数据统计分析类/定时任务类/大批量操作类
- 尽量避免业务高峰
- 如果有后台非程序批量修改语句,需要多人REVIEW,或走正规流程
- 操作前备份
- 每次执行DML/DDL之前,导出执行前的SQL,作为回滚脚本
- DMS上备份
事务控制
默认不开启为“否”,逐条提交,遇到失败则终止但不回滚;
开启则遇到失败则全部回滚(仅限DML,DDL不在范围内)
备份数据
默认开启为“是”,针对update、delete进行将要影响数据的全记录行insert脚本生成附件
事后恢复
DMS工单操作历史
适用场景
MySQL 5.5/5.6/5.7/8.0
DELETE/UPDATE/INSERT
开通了企业版的DMS
恢复方法
对于变更执行后出现异常不符合诉求需要回滚的,可直接工单页面内右侧-工单操作历史-查看备份,找到备份文件
下载备份脚本下载,做相应处理
重新提交变更工单
DMS数据追踪
适用场景
MySQL 5.5/5.6/5.7/8.0
少量DELETE/UPDATE/INSERT
功能特点
在线搜索日志内容,无需手工下载Binlog
支持数据的插入/更新/删除日志搜索,无需手工解析Binlog
支持逐条数据恢复,无需手工生成回滚语句
OSS Binlog(RDS会定时将Binlog备份到OSS上)
本地热Binlog(数据库服务器上Binlog)
支持非通过DMS操作的DML
内核回收站
适用场景
MySQL 8.0
DROP TABLE/SCHEMA
其它对象的删除策略是:
与表无关的对象,比如 procedure,根据操作语句决定是否保留,不做回收。
表的附属对象,比如 trigger,Foreign key,column statistics等,只要存在可能修改表数据的,做删除,比如 trigger,Foreign key。 但columns statistics不做清理,随表进入回收站。
找回方法
查看回收站表
mysql> CALL DBMS_RECYCLE.SHOW_TABLES();----------------------------------------------- 看回收站里的表
mysql>CREATE TABLE SRC_SCHEMA.SRC_TABLE LIKE SCHEMA.TABLE;-------------------- 橙色是要替换的内容
mysql>INSERT INTO SRC_SCHEMA.SRC_TABLE SELECT * FROM SCHEMA.TABLE; -------- 橙色是要替换的内容
mysql> call dbms_recycle.show_tables();
+------------------+------------------+---------------------+------------------+-----------------------+------------------------+
| SCHEMA | TABLE | ORIGIN_SCHEMA | ORIGIN_TABLE | RECYCLED_TIME | PURGE_TIME |
+------------------+------------------+---------------------+------------------+-----------------------+-------------------------+
| __recycle_bin__ | __innodb_1063 | product_db | t1 | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1064 | product_db | t2 | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1065 | product_db | parent | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
| __recycle_bin__ | __innodb_1066 | product_db | child | 2019-08-08 11:01:46 | 2019-08-15 11:01:46 |
+------------------+------------------+----------------------+------------------+---------------------+---------------------+
4 rows in set (0.00 sec)
mysql>create table product_db.t1 like __recycle_bin__. __innodb_1063;
mysql>insert into product_db.t1 select * from __recycle_bin__. __innodb_1063;
RDS克隆实例
适用场景
MySQL 所有版本
通过备份克隆出整个实例
所有误操作(DDL/DML)
指定方式
指定时间点
指定备份集
操作步骤
恢复到一个新实例
验证数据准确性
将数据迁回原实例
RDS库/表恢复
适用场景
MySQL所有版本
通过备份指定恢复误删的数据库或表
所有误操作(DDL/DML)
打开了库表备份的实例
注意事项
必须打开库/表级别备份
每次最多选择50个库/表
运行中且没有被锁定
如果要按时间点进行恢复,需要确保日志备份已开启
若要按备份集恢复,则原实例必须至少有一个备份集
DBS恢复
适用场景
支持整个实例、多个数据库、单个数据库、多张表或一张表恢复
支持秒级任意时间点恢复,并且用户可以灵活选择恢复对象