ProxySQL之连接复用(multiplexing)以及相关问题说明

ProxySQL在连接池(persistent connection poll)的基础上,还有一个连接复用的概念 multiplexing connection,官方的wiki里没有很明确的说明,但在作者的一些 blog post 和 issue 里能找到解答: https://github.com/sysown/proxysql/issues/939#issuecomment-287489317 由于SQL可以路由,一个客户端连接上来,可能会到多个 hostgroup 发起连接。复用的意思是,一个后端DB的连接,可以“同时”被多个客户端使用。 传统的连接池,会在客户端断开连接(会话)后,把连接放回到池里。在ProxySQL中,由于连接复用,连接会在sql语句执行结束后,便将连接放回到池里(客户端会话可能并没有断开),这样便可大大提高后端连接的使用效率,而避免前段请求过大导致后端连接数疯长。 但这样做有时候并不安全,比如应用端连接时指定了 set NAMES xxx,然后执行查询,那么由于multiplexing可能导致两个语句发到不同的DB上执行,继而没有按照预期的字符集执行。proxysql考虑到了这种情况: 连接会话里创建了临时表,CREATE TEMPORARY table xxxx... select @开头的变量,如select @@hostname 手动开启了事务,start transaction, commit, rollback等等 连接设置了自己的用户变量,比如set names xxx, set autocommit x, set sql_mode=xxx, set v_uservar=xx等等 第1,2,3点会根据路由规则,会自动禁用multiplex,发到对应hostgroup后,连接未断开之前不会复用到其它客户端。具体是发到主库还是从库,与匹配的规则有关。 issue #941 和 #917 都有提到临时表丢失的问题,可以用不同的rule来避免 下面对上面几点一一说明。 1. 临时表与用户变量(验证 1, 2) 以下注意连接的会话窗口及执行顺序,admin打头的是在proxysql管理接口上执行。 -- [session 1] mysql client proxysql (ecdba@10.0.100.36:6033) [(none)]> select 1; +---+ | 1 | +---+ | 1 | +---+ -- [session 2] proxysql admin cli select * from stats_mysql_processlist; Empty set (0....

April 17, 2017 · admin

ProxySQL之读写分离与分库路由演示

本文演示使用ProxySQL来完成读写分离和后端分库的一个实际配置过程,安装及配置项介绍见前文 ProxySQL之安装及配置详解。 环境 instance0: 10.0.100.100 (db0,db2,db4,db6) instance1: 10.0.100.101 (db1,db3,db5,db7) instance2: 10.0.100.102 (db2,db6,db10,db14) instance3: 10.0.100.103 (db3,db7,db11,db15) instance0 slave: 192.168.10.4:3316 instance1 slave: 192.168.10.4:3326 instance2 slave: 192.168.10.4:3336 instance3 slave: 192.168.10.4:3346 proxysql node0: 10.0.100.36 现在想达到这样一个目的:客户端应用连接上 proxysql 的ip:port,连接时指定分库db名,执行sql时自动路由到对应的实例、对应的库。考虑下面的部署结构: 任何一个proxysql节点都是对等的,路由请求到后端instance的各个database上。 1. 配置后端DB -- proxysql admin cli insert into mysql_servers(hostgroup_id,hostname,port,weight,weight,comment) values (100, '10.0.100.100', 3307, 1, 'db0,ReadWrite'), (1000, '10.0.100.100', 3307, 1, 'db0,ReadWrite'),(1000, '192.168.10.4', 3316, 9, 'db0,ReadOnly'); insert into mysql_servers(hostgroup_id,hostname,port,weight,weight,comment) values (101, '10.0.100.101', 3307, 1, 'db1,ReadWrite'), (1001, '10.0.100.101', 3307, 1, 'db1,ReadWrite'),(1001, '192....

April 17, 2017 · admin

ProxySQL之安装及配置详解

ProxySQL是一个高性能的MySQL中间件,拥有强大的规则引擎。具有以下特性: 连接池,而且是 multiplexing 主机和用户的最大连接数限制 自动下线后端DB 延迟超过阀值 ping 延迟超过阀值 网络不通或宕机 强大的规则路由引擎 实现读写分离 查询重写 sql流量镜像 支持prepared statement 支持Query Cache 支持负载均衡,与gelera结合自动failover 集这么多优秀特性于一身,那么缺点呢就是项目不够成熟,好在作者一直在及时更新,并且受到 Percona 官方的支持。 1. 安装 从 https://github.com/sysown/proxysql/releases 下载相应的版本。这里我选择 proxysql-1.3.5-1-centos67.x86_64.rpm,也是当前最新稳定版。 yum localinstall proxysql-1.3.5-1-centos67.x86_64.rpm -y 可以马上启动了: /etc/init.d/proxysql start Starting ProxySQL: DONE! proxysql有个配置文件 /etc/proxysql.cnf,只在第一次启动的时候有用,后续所有的配置修改都是对SQLite数据库操作,并且不会更新到proxysql.cnf文件中。ProxySQL绝大部分配置都可以在线修改,配置存储在 /var/lib/proxysql/proxysql.db 中,后面会介绍它的在线配置的设计方式。 proxysql 启动后会像 mysqld 一样,马上fork一个子进程,真正处理请求,而父进程负责监控子进程运行状况,如果crash了就拉起来。 编译安装 安装高版本 gcc-4.8 # cd /etc/yum.repos.d # wget https://copr.fedoraproject.org/coprs/rhscl/devtoolset-3/repo/epel-6/rhscl-devtoolset-3-epel-6.repo \ -O /etc/yum.repos.d/rhscl-devtoolset-3-epel-6.repo # yum install -y scl-utils policycoreutils-python # yum --disablerepo='*' --enablerepo='rhscl-devtoolset-3' install devtoolset-3-gcc devtoolset-3-gcc-c++ devtoolset-3-binutils # yum --enablerepo=testing-devtools-2-centos-6 install devtoolset-3-gcc devtoolset-3-gcc-c++ devtoolset-3-binutils 上一步会把 GCC 安装到以下目录 /opt/rh/devtoolset-3/root/usr/bin 接下来需要修改系统的配置,使默认的 gcc 和 g++ 命令使用的是新安装的版本。启用SCL环境中新版本GCC: # scl enable devtoolset-3 bash 现在查看 g++ 的版本号: # gcc --version 编译安装proxysql # cd proxysql-master # make # make install 2....

April 10, 2017 · admin

清明闲扯

这个清明假期,没有做特意的安排,4月1日晚上的时候冒出个想法——去爬七娘山。后来考虑天太热,便作罢了,正好抽一点时间整理些近来的事情。 ** 关于博客 很早在朋友圈看到 多说 要关闭的消息,不久后也收到了邮件。全国第一的评论系统,说倒就倒,到底是没有好的营收模式,看到网上一堆评论说挺惋惜的,但那么多用户评论数据在上面,价值可想而知,不应遭此地步。在2014年刚用 多说 的时候,就感觉到它后台基本上没有人在维护了,自身管理后台都有不少问题,提反馈也没响应。 选择网易云跟帖,把它替换掉了,并把以前的评论数据迁移了过来,就是人和人对不上号,以前那些网友找不到自己的评论,抱歉了。不过能用就行,还是多添点内容,也已经过了纠结样式主题的年纪了。有时候看到后台的评论,或者通过其它途径辛苦找到我的,给我了继续写博的动力。 再一个就是搜索功能,以前用的 swiftype 是在去年的时候,不免费了,只提供企业版。它提供的站内搜索引擎功能,十分强大,也很美观,后台管理能看到许多的分析数据,可是它偏偏就突然收费了,而且298$/m,不能接受。也是秉着能用的原则,装上了 hexo-generator-search 模块。 网站统计,现在是cnzz和百度站长的都在用,看了下每天还是有个400-600的独立访客,想想要整一个稍微过得去的 about 页面了。见这里 http://xgknight.com/about/ 。同时也才最近才加上leancloud访问量显示功能。 噢,对了,新加了个打赏的功能,孰知坚持写博不易,意思意思。 -- updated 2017-04-28 -- 把微信打赏改成了支付宝,这样方便知道对方是谁。 ** 关于职业 本职工作呢,是一名 DBA 。上周末听香港MySQL用户组主席 Ivan Ma 讲,他们那么没有很清楚的把职位分为是 MySQL DBA 还是 Oracle DBA,他们许多都是不论什么类型的数据库,包括nosql,都得上。我对自身的定位也是,MySQL可以是看家本领,必须深入理解,熟悉它的周边生态圈,积累优化经验。但是像Redis,Mongo,HBase甚至ES这些都必须要有一定的了解,还有像python/go一两门拿得出手的开发语言。 相继前后有好几位同行通过微博、QQ、微信,找到我,请教些问题。有些可能我也并不能马上明确的回答,但是要么自己做个验证,也能很快有结论,要么提供一些建议、方向,或者一些风险点,总之尽我所能。一对一讨论,是能快速学习和加深理解非常有效的途径。 在叶老师知数堂的优化班里,进去之前自己还是有一定基础的,主要是查一查知识的盲点,认识一些行业内的圈子。所以在群里,基本上不参与无关话题的讨论,偶尔回复技术相关的,再者也真没那个闲工夫。 最近一直在处理一个矛盾——职业与工作。个人花工作时间来学习研究,与外部群体讨论,短时间内在工作上可能看不到效果。我们不像开发人员,开发有项目推动,我们基本上都是问题驱动,为了解决这个问题(无论是具体的,还是平台的,甚至架构的),当我们并没有处理经验的时候,往往需要了解和对比大量资料。但最后能有多少应用在工作中的,很难说。能解决一个问题,叫工作;解决好一个问题,叫职业。同样是解决,而且一般在任期内不会复发,显然后者对个人的投入和收获,都更大。 我们的DBA工作充斥了许多的表结构审核、修改线上业务数据,以及慢sql优化、隐患问题追踪等等,也一直在思考一种好的工具平台,但是这样一个数据库运维体系的建立,前期要投入的精力和时间可想而知,而另一边,日常有源源不断的琐事或者问题要处理,到底何为紧急?虽然现在大部分工作,组内几个人好像都做得过来,但说实在的,人肉运维以及效率,都有许多可以改进的地方。然而就是需要在众多繁琐运维事务中,找个时间把该做的平台先做好。 目前还是在摸索,并有些眉目了,开发工作看来也只能靠自己了…… 本文链接地址:http://xgknight.com/2017/04/02/qingming-2017/

April 2, 2017 · admin

一次艰辛的字符集转换历程 ACMUG分享

本文的ppt是3月25日在中国MySQL用户组2017深圳活动上,我所做的一个主题分享,关于实际生产使用mysql过程中与字符集有关的一些坑。 这个总结其实自己去年一直也想去做,前后花了2个多月的时间,最后所有库无痛完成迁移转化。在2017年二月中下旬的时候微信上请教周董(去哪儿周彦韦大师)一个问题,因为以前也聊过一些,所以他突然问我要不要在3月份的活动上做个主题分享。当时有点不敢想,毕竟之前2次有关培训都是在公司内部的,而这次对外的分享,且不说台下听众有牛人存在,演讲嘉宾里面可各个都是大师级别的,所以当时没有马上答应。过了两天,偶然想到关于字符集这个经历可以讲一讲,不是为了展示自己有多牛B,只是分享下整个问题的处理经验,放低姿态。列了个提纲发给了周董,10分钟不到周董说定了。向经理请示了下没问题,这下赶着鸭子都得上了…… 毕竟第一次公开在这样的场合演讲,说不紧张肯定是假的,所以早早的就在准备ppt,一边回顾,一边画图。上阵前一天晚上还在对演示稿微调,并尽量控制时间。 闲话不多说,PPT奉上: {% pdf http://github.com/seanlook/sean-notes-comment/raw/main/static/mysql-ppt-charset-conversion-acmug-sean.pdf 1000 800 %} IT大咖说有录视频: http://www.itdks.com/dakashuo/detail/700 后来自己复看了一下,没啥大毛病,内容都交代清楚了,就是感觉确实舞台经验,表述上还有待加强。 同时这里是当天的活动掠影,阅读原文可看视频: ACMUG 2017 Tech Tour 深圳站掠影 http://mp.weixin.qq.com/s/-QNRhnN0kBtLkiWVIUS-QQ 下方是中国MySQL用户组(ACMUG)的公众号,欢迎关注: 原文连接地址:http://xgknight.com/2017/03/27/mysql-ppt-charset-conversion-acmug/

March 27, 2017 · admin

index merge 引起的死锁分析

在看线上一个 MySQL innodb status 时,发现有死锁信息,而且出现的频率还不低。于是分析了一下,把过程记录下来。 1. 概要 表结构脱敏处理: CREATE TABLE t_mytb1 ( f_id int(11) unsigned NOT NULL AUTO_INCREMENT, f_fid int(11) unsigned NOT NULL DEFAULT '0', f_sid int(11) unsigned NOT NULL DEFAULT '0', f_mode varchar(32) NOT NULL DEFAULT '', f_read int(11) unsigned NOT NULL DEFAULT '0', f_xxx1 int(11) unsigned NOT NULL DEFAULT '0', f_xxx2 int(11) unsigned NOT NULL DEFAULT '0', f_wx_zone int(11) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (f_id), KEY idx_sid (f_sid), KEY idx_fid (f_fid) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 死锁信息: LATEST DETECTED DEADLOCK ------------------------ 2017-02-28 13:58:29 7f25a3efd700 *** (1) TRANSACTION: TRANSACTION 4907718431, ACTIVE 0.010 sec fetching rows mysql tables in use 3, locked 3 LOCK WAIT 154 lock struct(s), heap size 30248, 10 row lock(s) LOCK BLOCKING MySQL thread id: 13589250 block 13589247 MySQL thread id 13589247, OS thread handle 0x7f25a17e3700, query id 27061926722 11.xx.52.xx ecweb Searching rows for update UPDATE `d_db1`.`t_mytb1` SET `f_read` = f_read+1 WHERE (f_fid=91243) AND (f_sid=100) AND (f_mode='浏览器') *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13288 page no 375 n bits 352 index `PRIMARY` of table `d_db1`.`t_mytb1` trx id 4907718431 lock_mode X locks rec but not gap waiting Record lock, heap no 245 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 0000a63b; asc ;;; 1: len 6; hex 0001246304a7; asc $c ;; 2: len 7; hex 7f000ac0162428; asc $(;; 3: len 4; hex 00016470; asc dp;; 4: len 4; hex 00000064; asc d;; 5: len 9; hex e6b58fe8a788e599a8; asc ;; 6: len 4; hex 0000244f; asc $O;; 7: len 4; hex 0000007c; asc |;; 8: len 4; hex 00000000; asc ;; 9: len 4; hex 00000000; asc ;; *** (2) TRANSACTION: TRANSACTION 4907718435, ACTIVE 0.007 sec fetching rows mysql tables in use 3, locked 3 154 lock struct(s), heap size 30248, 3 row lock(s) MySQL thread id 13589250, OS thread handle 0x7f25a3efd700, query id 27061926757 11.xx.104.xxx ecweb Searching rows for update UPDATE `d_db1`.`t_mytb1` SET `f_read` = f_read+1 WHERE (f_fid=91248) AND (f_sid=100) AND (f_mode='浏览器') *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 13288 page no 375 n bits 352 index `PRIMARY` of table `d_db1`.`t_mytb1` trx id 4907718435 lock_mode X locks rec but not gap Record lock, heap no 245 PHYSICAL RECORD: n_fields 10; compact format; info bits 0 0: len 4; hex 0000a63b; asc ;;; -- 42555 1: len 6; hex 0001246304a7; asc $c ;; -- 4905436327 2: len 7; hex 7f000ac0162428; asc $(;; 3: len 4; hex 00016470; asc dp;; -- 91248 4: len 4; hex 00000064; asc d;; -- 100 5: len 9; hex e6b58fe8a788e599a8; asc ;; 6: len 4; hex 0000244f; asc $O;; -- 9295 7: len 4; hex 0000007c; asc |;; -- 124 8: len 4; hex 00000000; asc ;; 9: len 4; hex 00000000; asc ;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 13288 page no 202 n bits 1272 index `idx_sid` of table `d_db1`.`t_mytb1` trx id 4907718435 lock_mode X locks rec but not gap waiting Record lock, heap no 705 PHYSICAL RECORD: n_fields 2; compact format; info bits 0 0: len 4; hex 00000064; asc d;; -- 100 1: len 4; hex 0000a633; asc 3;; -- 42547 *** WE ROLL BACK TRANSACTION (2) 乍一看很奇怪,tx1和tx2 两个 UPDATE 各自以 f_fid 为条件更新的记录互不影响才对,即使 91243,91248 两个值有可能出现在同一条数据上(因为f_fid上是二级索引),那顶多也就是个更新锁等待,谁后来谁等待,怎么会出现互相争用对方已持有的锁,被死锁检测机制捕获? 当然,把 update 语句拿到数据库中 EXPLAIN 一下就可以看出端倪。这里不妨先分析一下输出的锁情况: 先看 Tx2 (对应trx id 4907718435) : RECORD LOCKS space id 13288 page no 375 n bits 352 告诉我们是表空间id 13288 (可从 information_schema.INNODB_SYS_DATAFILES 查到对应ibd文件) 即 t_mytb1 表,第 375 号页面的 245 位置的记录被锁,并且是 idx PRIMARY 上的记录锁(注:本实例隔离级别为RC)。 Tx2正持有这把记录锁。 因为是聚集索引,显示了完整记录 0: 主键f_id=42555 1: DB_TRX_ID = 4905436327 2: DB_ROLL_PTR指向undo记录的地址 3: f_fid=91248 4: f_sid=100 ... 然而Tx2还在等待一个记录锁(lock_mode X locks rec but not gap waiting),但这把锁来自二级索引 idx_sid 索引上的记录锁。在 RC 级别下没有GAP lock,行锁除了加在符合条件的二级索引 f_sid=100 上外,还会对主键加record lock。 二级索引值: ...

March 11, 2017 · admin

MySQL根据离线binlog快速“闪回”

昨天突然有个客户说误操作,自己删除了大量数据,CTO直接将我拉到一个讨论组里,说要帮他们恢复数据。他们自己挖的坑,打算让开发那边根据业务日志去恢复,被告知只记录的删除主键这样的信息,物理删除,无能为力。 上服务器看了下记录的日志,发现好几台上面都有被误删的记录输出。阿里RDS虽然可以克隆一个恢复到删除时间点前的实例,但这散落的几万个id找起来费力,还有就是几个表之间关联的数据也要恢复,觉得麻烦。 想到 MySQL 的闪回方案。以前看过好几篇相关文章,甚至差点自己用python撸一个来解析binlog,反转得到回滚sql,实在没空,这下要急用了。赶紧找了下网上“现成的方案”。 正文开始 MySQL(含阿里RDS)快速闪回可以说是对数据库误操作的后悔药,flashback功能可以将数据库返回到误操作之前。但是即使oracle数据库也只支持短时间内的闪回。 网上现有开源的MySQL闪回实现,原理都是解析binlog,生成反向sql: (必须为row模式) 对于 delete 操作,生成insert (DELETE_ROWS_EVENT) 对于 update 操作,交换binlog里面值的顺序 (UPDATE_ROWS_EVENT) 对于 insert 操作,反向生成delete (WRITE_ROWS_EVENT) 对于多个event,要逆向生成sql 开源实现: https://github.com/58daojia-dba/mysqlbinlog_flashback https://github.com/danfengcao/binlog2sql/ 上面两种实现方式,都是通过 python-mysql-replication 包,模拟出原库的一个从库,然后 show binary logs 来获取binlog,发起同步binlog的请求,再解析EVENT。但是阿里云 RDS 的binlog在同步给从库之后,** 很快就被 purge 掉了 。如果要恢复 ** 昨天 的 ** 部分数据 **,两种方案都是拿不到binlog的。也就是闪回的时间有限。 还有一些比较简单的实现,就是解析 binlog 物理文件,实现回滚,如 binlog-rollback.pl ,试过,但是速度太慢。 为了不影响速度,又想使用比较成熟的闪回方案,我们可以这样做: 借助一个自建的 mysqld 实例,将已purge掉的binlog拷贝到该实例的目录下 在自建实例里,提前创建好需要恢复的表(结构),因为工具需要连接上来从 information_schema.columns 获取元数据信息 拷贝的时候,可以替换掉mysql实例自己的binlog文件名,保持连续 可能要修改 mysql-bin.index,确保文件名还能被mysqld识别到 重启mysql实例,show binary logs 看一下是否在列表里面 接下来就可以使用上面任何一种工具,模拟从库,指定一个binlog文件,开始时间,结束时间,得到回滚SQL 再根据业务逻辑,筛选出需要的sql ...

March 3, 2017 · admin

关于MySQL自增主键的几点问题(下)

AUTO-INC waiting 锁等待 这是生产环境出现的现象,某日下午5点业务高峰期,我们的 慢查询快照抓取程序 报出大量线程阻塞,但是1分钟以后就好了。于是分析了当时的 processlist 和 innodb status 现场记录,发现有大量的 AUTO-INC waiting: ![auto-inc-lock-wait][1] 当时想这是得多大的并发量,才会导致 AUTO_INCREMENT 列的自增id分配出现性能问题,不太愿意相信这个事实(后面就再也没出现过)。了解一番之后(见 关于MySQLz自增主键问题(上篇)),发现这个表级别的 AUTO-INC lock 就不应该在业务中存在,因为 innodb_autoinc_lock_mode为1,普通业务都是 simple inserts,获取自增id是靠内存里维护的一个互斥量(mutex counter)。 问题拿到知数堂优化班上课群里讨论过,也只是猜测是不是慢查询多了导致负载高,或者当时磁盘遇到什么物理故障阿里云那边自动恢复了。再后来怀疑是不是因为插入时带了 auto_increment 列的值(我们有个redis incr实现的自增id服务,虽然这一列有 AAUTO_INCREMENT 定义,但实际已经从发号器取id了),会导致锁的性质会变? 为了弄清这个疑问,特意去看了下mysql源码,发现如果插入的自增值比表当前AUTOINC值要大,是直接update mutex counter: 看源码的时候也打消了另一个疑虑:show engine innodb status 看到的 AUTO-INC 有没有可能不区分 表级自增锁和互斥量计数器 两种自增方案,只是告诉你自增id获取忙不过来? 实际不是的,代码里面有明确的定义是 autoinc_lock还是autoinc_mutex: // dict0dict.cc : #ifndef UNIV_HOTBACKUP /********************************************************************//** Acquire the autoinc lock. */ UNIV_INTERN void dict_table_autoinc_lock( /*====================*/ dict_table_t* table) /*!< in/out: table */ { mutex_enter(&table->autoinc_mutex); } /********************************************************************//** Unconditionally set the autoinc counter....

February 17, 2017 · admin

关于MySQL自增主键的几点问题(上)

前段时间遇到一个InnoDB表自增锁导致的问题,最近刚好有一个同行网友也问到自增锁的疑问,所以抽空系统的总结一下,这两个问题下篇会有阐述。 1. 划分三种插入类型 这里区分一下几种插入数据行的类型,便于后面描述:(纯逻辑上的划分) “Simple inserts” 简单插入,就是在处理sql语句的时候,能够提前预估到插入的行数,包括 INSERT / REPLACE 的单行、多行插入,但不含嵌套子查询以及 INSERT ... ON DUPLICATE KEY UPDATE。 “Bulk inserts” 本文暂且叫做 大块插入,不能提前预知语句要插入的行数,也就无法知道分配多少个自增值,包括 INSERT ... SELECT, REPLACE ... SELECT, 以及 LOAD DATA 导入语句。InnoDB会每处理一行记录就为 AUTO_INCREMENT 列分配一个值。 “Mixed-mode inserts” 混合插入,比如在 “简单插入” 多行记录的时候,有的新行有指定自增值,有的没有,所以获得最坏情况下需要插入的数量,然后一次性分配足够的auto_increment id。比如: # c1 是 t1 的 AUTO_INCREMENT 列 INSERT INTO t1 (c1,c2) VALUES (1,'a'), (NULL,'b'), (5,'c'), (NULL,'d'); 又比如 INSERT ... ON DUPLICATE KEY UPDATE,它在 update 阶段有可能分配新的自增id,也可能不会。 2. 三种自增模式:innodb_autoinc_lock_mode 在以 5.6 版本,自增id累加模式分为: ** 传统模式**...

February 16, 2017 · admin

监控MySQL你还应该收集表信息

1. Story 也许你经常会被问到,库里某个表最近一年的内每个月的数据量增长情况。当然如果你有按月分表比较好办,挨个 show table status,如果只有一个大表,那估计要在大家都休息的时候,寂寞的夜里去跑sql统计了,因为你只能获取当前的表信息,历史信息追查不到了。 除此以外,作为DBA本身也要对数据库空间增长情况进行预估,用以规划容量。我们说的表信息主要包括: 表数据大小(DATA_LENGTH) 索引大小(INDEX_LENGTH) 行数(ROWS) 当前自增值(AUTO_INCREMENT,如果有) 目前是没有看到哪个mysql监控工具上提供这样的指标。这些信息不需要采集的太频繁,而且结果也只是个预估值,不一定准确,所以这是站在一个全局、长远的角度去监控(采集)表的。 本文要介绍的自己写的采集工具,是基于组内现有的一套监控体系: InfluxDB:时间序列数据库,存储监控数据 Grafana:数据展示面板 Telegraf:收集信息的agent 看了下 telegraf 的最新的 mysql 插件,一开始很欣慰:支持收集 Table schema statistics 和 Info schema auto increment columns。试用了一下,有数据,但是如前面所说,除了自增值外其他都是预估值,telegraf收集频率过高没啥意义,也许一天2次就足够了,它提供的 IntervalSlow选项固定写死在代码里,只能是放缓 global status 监控频率。不过倒是可以与其它监控指标分开成两份配置文件,各自定义收集间隔来实现。 最后打算自己用python撸一个,上报到influxdb里 :) 2. Concept 完整代码见 GitHub项目地址:DBschema_gather 实现也特别简单,就是查询 information_schema 库的 COLUMNS、TABLES 两个表: SELECT IFNULL(@@hostname, @@server_id) SERVER_NAME, %s as HOST, t.TABLE_SCHEMA, t.TABLE_NAME, t.TABLE_ROWS, t.DATA_LENGTH, t.INDEX_LENGTH, t.AUTO_INCREMENT, c.COLUMN_NAME, c.DATA_TYPE, LOCATE('unsigned', c.COLUMN_TYPE) COL_UNSIGNED # CONCAT(c.DATA_TYPE, IF(LOCATE('unsigned', c.COLUMN_TYPE)=0, '', '_unsigned')) FROM information_schema....

December 4, 2016 · admin