mysql数据备份
为什么写这个话题,原因很简单,在实现业务逻辑的时候很多更新操作没有校验where后面的条件,导致整个表的数据被更新了,工作这么多年了,从入行到现在还在不时的发生,当然避免的方式有很多,但是难免还是有这样的情况发生。
说下我的解决方案:
mysql设置 没有where条件的update delect 禁止执行,它是完全可以做到的,就是你后面想对整个表操作的时候写sql要麻烦一点。 设置 sql_safe_updates 属性就可以
还有一种就是在代码实现层写一个全局的拦截校验 比如我们常用的框架mybatisplus 重写下BlockAttackInnerInterceptor 类拦截报错就能解决。
public class CustomBlockAttackInnerInterceptor extends BlockAttackInnerInterceptor {@Overridepublic void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout){super.beforePrepare(sh,connection,transactionTimeout);PluginUtils.MPStatementHandler handler = PluginUtils.mpStatementHandler(sh);MappedStatement ms = handler.mappedStatement();SqlCommandType sct = ms.getSqlCommandType();String sql = sh.getBoundSql().getSql();if (sct == SqlCommandType.UPDATE || sct == SqlCommandType.DELETE){// 检查 SQL 是否为 UPDATE 或 DELETE,且没有 WHERE 子句if (sqlIsWhere(sql)) {throw new ApiException("UPDATE and DELETE statements without a WHERE clause are not allowed!");}}}private boolean sqlIsWhere(String sql) {// 这里实现逻辑来检查 SQL 是否包含 WHERE 子句String lowerCaseSql = sql.trim().toLowerCase();return !lowerCaseSql.contains("where");}@Overrideprotected void processDelete(Delete delete, int index, String sql, Object obj) {this.checkWhere(delete.getTable().getName(), delete.getWhere(), "Prohibition of full table deletion");}@Overrideprotected void processUpdate(Update update, int index, String sql, Object obj) {this.checkWhere(update.getTable().getName(), update.getWhere(), "Prohibition of table update operation");}}
让上面的类生效你还需要配置
@Configuration
public class MybatisPlusConfig {/*** 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题(该属性会在旧插件移除后一同移除)*/@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new CustomBlockAttackInnerInterceptor());interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}}
上面是我解决问题的实现思路。
数据问题遇到了几次,木已成舟就只能恢复数据,上面方案做完在我的认知里就没有问题。
但是数据库数据恢复还是很有必要在这里说的,原因也很简单我经历数据库mysql中的一些数据文件被加密了,没发读了,一个表被全量更新了,但是其他的业务还在在继续,而且还不能停服务,前期的系统业务架构很重要,做好了也不会有这样的问题,还是那句木已成舟回不去了。
需要定期的dump整个数据库,做全量备份,然后定时的做binglog备份,通过全量+增量的方式,当有问题的时候我们可以快速的恢复数据。