介绍

从系统管理员或 DBA 的角度来讲, 总期望将线上的各种变更限制在一个可控的范围内, 减少一些不确定的因素. 这样做有几点好处:

. 记录线上的库表变更;
. 对线上的库表变更有全局的了解;
. 如果有问题, 方便回滚操作;

从这三点来看, 有很多种方式可以实现, 比如通过 migrate 等工具强制所有的操作都以统一的方式执行, 这需要开发人员做更多的配合, 所以这类工具在非规模话的业务场景中较难实现; 另外管理员或 DBA 也可以通过知识库比如 redmine 等类似的方式记录变更, 不过不可控因素很多, 特别依赖上线的流程, 也容易出现纰漏. 这就引申出本文要介绍的如何跟踪线上库表的变更, 下文以 MySQL 数据库介绍说明.

跟踪的方式

在 Postgresql 中, 由于触发器对各种操作都有很好的支持, 我们完全可以通过触发器的形式来记录所有 DDL 语句的变更. 与此相比, MySQL 则显得较为弱小, 我们只能以其它方式实现类似的目标. 下面以中间件, log, binlog, 注册 slave, mysqldiff 五种方式进行介绍.

1. 中间件

现有的中间件 atlaskingshardmycat 等, 都以 proxy 的角色部署于程序和 MySQL 之间, 所有发往 MySQL 的 sql 都通过 proxy 进行转发. 如下图所示, 我们可以在 proxy 层面增加一些 DDL, DML 相关语句的记录, 达到跟踪变更的目的.

    +------+        +-------+        +-------+
| app | ---> | proxy | ---> | MySQL |
+------+ +-------+ +-------+

这种方式自由度较高, 大家都可以随意定制. 不过需要一些开发能力, 另外 sql 的过滤也会影响到查询的性能, 通过中间件来直接修改表结构等操作也是有风险较大的方式.

2. log

这种方式很简单, 打开 MySQL 的 general log 或 audit log 即可记录所有的 sql 语句. 这种方式比较适合开发环境, 线上环境如果开启会产生很多日志, 弊远远大于利, 也不利于维护;

3. binlog

管理员或 DBA 同样可以解析 MySQL 的 binlog 来过滤表或权限的变更. 这种方式本质上等同第二种方式, 线上数据库需要开启 binlog 选项, 解析 binlog 也是很耗资源的操作. 线上如果实例较多, 这种方式特别不可取.

4. 注册 slave

注册 slave 的意思即通过 MySQL 的主从协议伪造一个假的 slave, 这样 master 会把所有的更新都发送过来, 再进行一些过滤的操作. 这种方式在同步数据或增量消费的场景特别适合, 这里只用于记录表或权限的变更确实是大材小用, 线上实例较多的话也不可取. 典型的工具有 myreplicationtungsten-replicator 以及阿里的 canal 等.

5. mysqldiff

实际上权限和表变更本身是低频率的操作事件, 上述的四种方式虽然都可以达到目标, 但本质上都是很耗费资源的操作. 考虑到这点, 我们可以通过对比的方式来实现权限及表结构变更的跟踪, 详见 sys-mysql-diff 工具. 考虑到通用性, sys-mysql-diff 工具每次都需要获取指定库的所有表的定义语句, 通过对比来生成对应的 DDL 语句. mysqldiff 则是对 sys-mysql-diff 工具的封装, 可以批量跟踪多个实例.

如何使用 mysqldiff

mysqldiff 工具是在 sys-mysql-diff 工具的基础上进行了一层封装, 所以本质上是通过 sys-mysql-diff 工具跟踪线上库的变化. 在实际的运用中, 需要注意以下几点:

1. 配置文件

mysqldiff 所需要的配置参考以下:

[backend]
dsn = user_mysqlmon:xxxxxxxx@tcp(10.0.21.17:)/mysqldiff?charset=utf8 [test3301]
host = 10.0.21.5
port =
db = test
user = user_mysqldiff
pass = xxxxxxxx
tag = host_location [test3306]
host = 10.0.21.7
port =
db = percona
user = user_mysqldiff
pass = xxxxxxxx
tag = host_location

2. 权限

所有的变更结果都会保存到指定的 MySQL 库中的 mysql_diff 表, 即上述的 [backend] 部分, 对于该表需要 select, insert, update 相关的权限. 被跟踪的实例则是 [testXXXX] 部分, 由于需要查看表结构和用户权限所以需要 select 和 grant option 权限. 我们以 user_mysqlmon 用户为 [backend] 的用户, 以 user_mysqldiff 为 [testXXXX] 部分的用户为例, 需要赋予他们以下权限:

grant select,insert,update on mysqldiff.* to user_mysqlmon@`10.0.21.%`;
grant select on *.* to user_mysqldiff@`10.0.21.%` with grant option;

配置中的 db = information_schema 则表示跟踪所有的数据库;

3. 运行

运行 mysqldiff 命令进行跟踪:

# ./mysqldiff -conf conf.cnf -verbose
// :: ---------------------------
changes from 10.0.21.5:
changes from 10.0.21.7:
DROP TABLE `emp`;
SET GLOBAL wait_timeout = ;
// :: insert 10.0.21.17:/percona ok
// :: ---------------------------

insert ... ok 一行表示将结果插入到了 [backend] 中.

总结

以 mysqldiff 方式跟踪库表及权限的变化相对简单方便, 比起其它方式算得上轻便. 另外也不受业务场景和管理员习惯的制约, 相对很通用. 不过其也有自身的缺陷, 在短时间内经常变更的表则很难跟踪, mysqldiff 仅能记录最后一次的变更. 另外管理员需要严格限制配置文件的权限, 最好给予 0600 的权限仅限当前用户查看. 不过整体而言, 要跟踪线上库表权限的变更, mysqldiff 是一个较为合适且通用的工具.

如何有效的跟踪线上 MySQL 实例表和权限的变更的更多相关文章

  1. 线上Mysql数据库崩溃事故的原因和处理

    前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...

  2. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(八)线上Mysql数据库崩溃事故的原因和处理

    前文提要 承接前文<一次线上Mysql数据库崩溃事故的记录>,在文章中讲到了一次线上数据库崩溃的事件记录,建议两篇文章结合在一起看,不至于摸不着头脑. 由于时间原因,其中只讲了当时的一些经 ...

  3. 原创 记录一次线上Mysql慢查询问题排查过程

    背景 前段时间收到运维反馈,线上Mysql数据库凌晨时候出现慢查询的报警,并把原始sql发了过来: --去除了业务含义的sql update test_user set a=1 where id=1; ...

  4. 记一次排查线上MySQL死锁过程,不能只会curd,还要知道加锁原理

    昨晚我正在床上睡得着着的,突然来了一条短信. 啥,线上MySQL死锁了,我赶紧登录线上系统,查看业务日志. 能清楚看到是这条insert语句发生了死锁. MySQL如果检测到两个事务发生了死锁,会回滚 ...

  5. 【MySQL】实现线上千万数据表添加字段操作以及缓存刷新

    需求背景: 由于业务需求,需要在线上用户表添加渠道字段,用于区分不同渠道注册的用户,目前该表有20+个字段,8个索引 线上用户数据大概1500W左右,需要不停机增加数据库字段,同时需要刷新Redis缓 ...

  6. mysql线上数据库单表超过200G的处理

    tbl_user_data占用了大量磁盘空间,数据表占用大概200G,索引30G左右,查询非常慢,影响业务的支持进行现在需要对它进行清理 临时解决方案是将原表重命名,新建一个和这个表相同的空表来替换( ...

  7. 线上mysql内存持续增长直至内存溢出被killed分析(已解决)

    来新公司前,领导就说了,线上生产环境Mysql库经常会发生日间内存爆掉被killed的情况,结果来到这第一天,第一件事就是要根据线上服务器配置优化配置,同时必须找出现在mysql内存持续增加爆掉的原因 ...

  8. 一次线上Mysql数据库崩溃事故的记录

    文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写代码的速度也在提升,感觉很欣慰,毕竟是在一直进步,但是过程中也有许许多多的曲折,也踩过了数不尽的坑坑洼洼,从一个连百度都不知道用的萌 ...

  9. Spring+SpringMVC+MyBatis+easyUI整合进阶篇(七)一次线上Mysql数据库崩溃事故的记录

    作者:13 GitHub:https://github.com/ZHENFENG13 版权声明:本文为原创文章,未经允许不得转载. 文章简介 工作这几年,技术栈在不断更新,项目管理心得也增加了不少,写 ...

随机推荐

  1. gulp 学习笔记

    以这次学习gulp为契机来同时了解和学习node相关的知识和概念,比如 npm,package.json等,为以后学习node打好基础. 目录   npm     查看模块     安装模块      ...

  2. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  3. 借助case,实现更丰富的分组查询统计

    根据fileD6的前4位分组    分别统计该组  5种企业类型fileD31的数量 create or replace view jyjc_bycity as select substr(fileD ...

  4. Python:认识变量和字符串

    几个月前,我开始学习个人形象管理,从发型.妆容.服饰到仪表仪态,都开始做全新改造,在塑造个人风格时,最基础的是先了解自己属于哪种风格,然后找到参考对象去模仿,可以是自己欣赏的人.明星或模特等,直至最后 ...

  5. WebService学习--股票走势图+天气预报实现

        互联网上面有很多的免费webService服务,我们可以调用这些免费的WebService服务,将一些其他网站的内容信息集成到我们的Web应用中显示,下面就以获取股票数据和天气预报为例进行学习 ...

  6. HttpClient研究学习总结

    Http协议非常的重要,HttpClient相比传统JDK自带的URLConnection,增加了易用性和灵活性(具体区别,日后我们再讨论),它不仅是客户端发送Http请求变得容易,而且也方便了开发人 ...

  7. java.net.SocketException: Broken pipe 异常可能的原因

    org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Broken pipe at org.apa ...

  8. 蓝桥杯-扑克牌移动-java

    /* (程序头部注释开始) * 程序的版权和版本声明部分 * Copyright (c) 2016, 广州科技贸易职业学院信息工程系学生 * All rights reserved. * 文件名称: ...

  9. bootstrap+masonry.js写瀑布流

    最近在用bootstrap写一个网站,其中有个图文展示的页面要用到瀑布流的效果.因为项目要求,项目要以bootstrap为基准,不准私自添加内联样式.内部样式,所以,自己写瀑布流就不行了,所以,根据要 ...

  10. Linux添加硬盘和挂载

    1.使用fdisk -l 查看硬盘的详细信息 分析: 2.分区初始化 fdisk /dev/sdb 分析:各个参数的解析                   1. 输入 m 显示所有命令列示. 2. ...