引言
正式分享之前,先对最近热门的删库事件做一点反思。作为 DBA 应如何加强预防,改进措施防止再出现类似事件呢?我认为主要从三点出发:一是流程规范,二是技术支撑,三是安全制度。
之所以没有把技术支撑放在第一点,是因为对于现在暴露出来的许多问题,更多是在流程和规范方面设计不合理,在完善整个流程和规范的基础上,再做技术的补充。
从技术层面来说,一定要完善备份恢复体系。在现今的技术支撑方面存在一个短板,我们更多是在恢复单个环境,对于整个业务集群的恢复方面做得比较薄弱。
最后一定要完善安全制度,安全问题在工作中地位变得越来越重要。
一、技术变化
对于数据库运维开发和管理相关的工作可以浓缩为四点:
第一是技术的变化。
第二是优化和设计。
第三保证业务高可用,我们需要提高系统整体的高可用,和业务结合起来做到真正的业务高可用。
最后是业务自助,尤其在疫情大背景下显得更加重要,很多事情其实不需要太多的沟通环节,如果能够做到自助化服务,整体工作的衔接会比较流畅。
以我入行时经历过的一个难忘的坑说起。
同事很久交给我一套 MySQL 环境,我看到的是主从的环境,有一天收到一条报警,是从库服务器文件系统问题。我又仔细看了一下发现这个从库竟然没有开 binlog,所以这是一个假的从库,但是这个业务是关键业务,摆明是一个坑。
要修复这个问题,就需要重启从库的服务,需要重新搭建 slave 节点。本来以为重启一个 binlog 没有什么大问题,但是发现数据库停不掉,或者起不来,起来有一些业务反馈连不上数据库,还有一些反馈的操作日志显示数据连接有异常,逐个做排查,发现这些问题都超出我们计划之外,可谓是一波三折。
所以很多看起来很简单,没有技术含量的事情,在实际工作中,会碰到很多比较具体的问题。我们在实际的工作应用中碎片化,琐碎化的事务会比较多,重复性也会比较多。
从技术的变化来说,我最早是做 Oracle,逐步切换到 MySQL 和运维开发方向。经常听到很多人评判一个数据库哪一个好,哪一个不好,哪个大框架下更吃香。从我经历了 Oracle 到 MySQL 过程,感受到的是技术在逐渐返璞归真。
DBMS 榜单是显示整个数据库的排行榜,可以看出 Oracle、MySQL 关系型数据库排名稳定靠前,在这个过程中,一些 NoSQL 发展也很不错。
我们以 MySQL 为例,大概十几年前,从原来的 Sun 公司分离,之后到 Oracle 公司,MySQL 有一个逐渐分裂的过程。
下图列出了一些 MySQL 的组件服务,十多年之后,可以看到一些从属引擎已经被替代了,有一些被放弃了,而一些像 innoDB 引擎在 Oracle 官方支持下不断加强。
所以技术是在不断迭代,不断的演进过程中,而归真的部分是你会发现原来在互联网如火如荼的 MySQL,在走入 8.0 版本之后很多功能都开始和 Oracle 的设计有相似之处,所以风水也是轮流转,很多问题不是单纯的技术问题。
二、优化和设计
关于对数据库的优化,主要体现在优化思维的转变。
早些年会大量对 SQL 进行分析优化,因为原来的业务场景比较复杂,导致很多的 SQL 写得比较长,有时能达到几百行,整个逻辑关系比较复杂,需要优化。
但是在现在互联网场景下面,这样的场景开始减少。原先的优化思维是要做得更多,但现在更多要求做得更少,直至达到至简设计的要求。
举一个例子,我们之前有个业务是做商业数据库迁移到 MySQL,原先它的 QPS 是 50 万,我们把服务的负载进行分布式改造,改完了以后 QPS 变成了 2 万。从 50 万到 2 万,它的性能反而更容易扩展、更稳定。
我们原先是希望支撑更多的 QPS,但是发现通过这样一个逻辑改造,做得更少的情况下,能够更好地满足原来场景,这就是在优化思维层面上比较大的转变之一。
现在复杂的 SQL 变得越来越少了,为了保证技术和业务的兼容性,很多业务的调用都在尽可能做到至简。
设计更多也需要从系统层面考虑,大家经常会关注千万级大表的优化方式?其实对于千万级大表的优化,可以拆成三个部分对待:
数量级:千万级
对象:数据表
目标:优化
千万级大表做优化过程中,一方面需要了解数据表的属性,针对不同的属性,需要在不同的层面做相应优化。在这个过程中,SQL 优化和索引的优化只是数据库优化过程中的一个相对较小的一个环节。
业务上的表主要有三大类。第一是状态表,也就是 OLTP 表,状态表数据相对来说比较稳定。第二是流水表,状态随着时间的变化发生变化的一些行为就叫流水表,像日志等等都是流水表。第三就是字典表,用于配置通用业务,核心思路是要配置得小而简,避免所有配置丢到一起。
在明确这样的基本概念下,再来看整体优化,比如一些规范的设计,需要在业务层优化,对业务不断做拆分。架构层更多要和业务结合起来分析业务的具体使用场景,比如是在线业务,离线业务还是统计分析业务等等,根据不同场景做相应优化。
千万级大表做优化需要考虑架构层和业务层,架构层可以使用中间件技术实现读写分离,包括负载均衡相关的技术,从兼容角度,可以参考 HTAP 相关概念,兼容 TP 和 AP 的业务,架构并不局限于 MySQL,要选择适合的场景。
从业务层来说,使用场景也有很多业务考量,比如业务拆分,把一个混合的业务拆分成一些独立的业务。包括表里面的状态、历史数据都可以做分离。比如对数据拆分,可以按照日期拆,也可以按照分区模式拆等。
相关的表,可以理解跟人的性格一样,一些业务场景可能是读多写少,另一些是读少写多。这意味着单纯使用 MySQL 肯定有瓶颈。读多写少应尽可能和缓存结合,例如现在很多直播技术是基于缓存的基础。对于读少写多场景,有一些使用业务提交或者队列技术。还有降低写入的频率,比如原先写入的频率是每十秒钟更新一次,如果从业务场景来说,允许改造成一分钟更新一次等等,这样一些使用的方式都可以对千万级大表实现优化的效果。
现实很多工作中还会涉及到极限的优化。比如我们之前做了一个大型分布式集群,做核心业务线的发布。原来的延迟是在 1.5 毫秒,写的延迟在 5 毫秒以内,以整个集群状态来看,读的延迟是不满足当时的上线标准,写的延迟勉强够。
在这样场景下进行毫秒级的优化,我们准备了一个密集压测的环境,不断调整和迭代优化方案。最终从 1.5 毫秒逐步演进到 0.68 毫秒,写延迟从 5.0 毫秒,逐步演进到 2.7 毫秒。这个过程涉及到整个系统架构,包括对一些 SQL 逻辑的调整,在细微变化中,我们把整个延迟逐步控制在一个相对比较理想的状态。
其实很多业务中对于备份恢复的关注是不够的。备份恢复可以用来做什么?通常在我们理解中备份是静态的,静态意味着对业务来说是不可见的,不可见就意味着不可用,对很多公司和业务看来有一点“鸡肋”,但是备份恢复在没问题的时候看似没有什么用,但是出了问题就变得相当有用了。
换一个思路,可以试着从另外一个角度构建出来可以折腾的备份。折腾的意思就是我们对于业务的误操作可以做到数据的闪回,例如对五分钟之前的一个操作,可以很快做恢复,而不用做全程的恢复。
比如业务测试数据,线上业务如果做增持的压测风险很高,如果需要在完全对等的数据量的环境下做压测评估,可以通过备份恢复环境评估真实的模拟,有点类似租户一样,用完了以后可以释放。
备份可以从快照方式理解,整个设计思想就是一次全量,永远增量。达到这样的目标之后,无论是存储的空间、备份的效率都会变得更加理想。
三、业务高可用
对于冷热数据的分离,可以根据 binlog 数据的抽取实现数据的闪回。
现在大家更多考虑的是系统和数据库层面的高可用,而很少关注整个业务的高可用。举个例子,有一个很重要的真实场景业务,大概 800 级的数据量,需要我们整个压测模拟做完后构建一套新的数据服务,但是整个数据的迁移到切换没有统一的维护窗口,如何实现平滑的数据迁移和整个业务的切换呢?我们设计了如下的方式:
第一是是旁路的概念,原来已有的数据服务,和一个新的数据服务做相关的重构,需要经过一个架构,将已有的数据服务打开,把新的数据复制上去,这样业务就会打在新的数据服务上,再在新的数据服务上做数据迁移和数据集合等一些服务操作。
到了正式切换的时候,先做一个全量的迁移。比如准备早上十点开始做一个完整迁移,下午三点完成。早上十点到下午三点期间的增量数据怎么同步呢?就需要进行增量的同步和在线的集合。
把原来数据旁路的服务停掉,做完了全量同步之后,再做增量的同步,在这个过程中产生的数据量相对 800 量级来说比较少,也会比较快。比如增量用时 10 分钟,这样三点到三点十分这 10 分钟之内还会出现一个增量,这个增量该怎么做呢?那就做在线稽核。
所以整个数据的追平使用增量的同步和在线稽核补充,然后不断做数据比对。比如做幂等查验,把上面数据覆盖成新的数据服务的数据,达到整个数据完全追平在线稽核。之后再把真正的写流量迁过来,原有上层的入口服务流量这一层调度的时候会把已有的服务和新的数据服务写一份,对业务来说,读取会更直观。
如果已经验证完成之后,再通过上层的分布式集群服务,将上层的流量切换到新的数据服务上,即使是出现问题,也可以实现快速的回退,把流量从上一步切换过来。因为这两端数据是幂等性的设计,所以这一个过程可以不断做增量和在线的稽核。
四、业务自助
对于业务自助,其实是一把“双刃剑”,对于后端服务来说,可以节省时间,很多的不必要的沟通和协调可以通过自助的方式解决。对业务来说,也不用做额外的沟通,整个过程中,可以提供相关的一些自助服务。比如 SQL 自动化上线,SQL 自动化审核,慢日志平台设计优化等等。
我们日常的思维习惯是先看一些近期的慢日志性能情况,SQL 最近运行情况,有什么样的瓶颈,然后分析出哪一些 SQL 是应该重点关注的,哪一些需要做优化,然后提取 SQL 相关数据,逐步优化。
整个思维习惯我们可以用潜台词“汇报”的思路做一些阐述。比如查看慢日志,为什么查看?就是想确认有没有问题。如果有问题我们想确认这个问题严重不严重。我需要更多关注哪一些 SQL,更关注哪一些问题?对于这些关注的问题,我们有什么样的一些建议和解决方法?所以从慢日志的优化来说,有相应的一些业务自助设计。
有没有问题?我们可以通过趋势图分析,比如 CPU 负载高了,基本上是 SQL 的性能比较差。问题呈现可以通过分数可视化的方式,这样对于使用者会有直观的感觉。
也可以通过概览的方式把这些问题概要列出来,把这些 SQL 做一些分组和聚合,提取出一些关键的点。然后分辨哪一些问题是需要重点关注的?再通过相关明细的信息。比如索引、字段、表格的设计等等可以得到更全面的分析给出相关建议。一般来说都会存在二八原则,优化掉 20%的问题,会达到 80%的收益。
如果要看一些更明细的信息,比如需要添加缩影,看 SQL 的明细,对于每一个 SQL 可以生成明细的图表,SQL 完整语句是什么样,SQL 历史的执行和执行时长也都可以看到。
优化中经常会看 SQL 执行计划,比如走了“圈表”,在什么地方走“圈表”,这个表涉及到哪一些表,展开看到表的字段和设计。有时候我们优化这个 SQL 之后发现其他 SQL 也产生问题,因为我们做的是单一的优化,没有更全面的分析,所以可以引入相关的 SQL 优化。
这些表优化以后,可能会对下面的 SQL 也产生影响。整个优化过程中,可以不断的做对比,看潜在的 SQL 有没有受到一些影响,在优化的时候可以并行把这样的 SQL 关联评估一下。
整个工作当中,像业务自助,优化设计,包括业务高可用等技术,很多都不是单一的,而要用从全面的角度、更综合的态度出发解决问题,不是会什么技术就一定要用什么技术,而是根据适合的场景做相应的评估和设计。
在这个过程中,会发现积累很多问题,对这些问题的解决会逐步形成自己的一个知识体系。我们需要构建自己的知识体系,处理各种问题的时候,会碰到很多的信息,可以把它们做归纳和梳理,最后可以得到相应精华要点,沉淀出一些真正有价值的知识。
结语
其实做数据库运维、开发相关的工作,日常任务碎片化程度比较高,很容易抓不到重点。在这个过程中,也会让很多人变得浮躁,沉不下心来。所以我们要选择对自己比较有利的方向不断梳理和总结,形成你自己的理解,沉淀属于自己的真正有价值的知识体系。
我最后为大家分享一下我自身职业沉淀的整个过程?我大概是在 2014 年开始写博客,最初的想法是为了解决问题,比如 Oracle 出了问题,解决之后过了一段时间又遇到这个问题,但是之前解决的过程却已经忘了,又得重新花时间解决了一遍,后来我就把这个过程完整梳理一遍,用文章的形式将操作过程整理出来。
当然一开始只是为了便利自己,积累到一定程度之后,有很多朋友看到了我的一些博客内容,他们可能也会碰到类似这些问题,但最终解决的背景和步骤并不一样,很多问题也是通过和大家的交流,不断扩充得到的,整个过程开始从一个利己的事情变成利人的事情。
再达到一定的沉淀之后,我发现处理很多问题和案例都存在一定的共性,经过不断的梳理,最终形成一整套知识体系。这也是我写《Oracle DBA 工作笔记》这本书的初衷,所以我觉得很多事情都贵在坚持,在你坚持总结的过程中,你会发现这样的过程对自己益处会相当大。
Q&A
Q:监控平台是内部研发的吗?
A:这个平台是内部研发的,我们整个设计是基于前后端分离的方式,后端做一些 API 接口的设计完善,前端做了一些可视化的渲染。
Q:请教一下如何快速的修复语句,是在线修复,还是有什么样的优化体系?
A:在线修复第一种是 SQL,它不是幂等的,比如说做一个 RB Date,是有时间维度,这个基于维度可能不需要做恢复,可能通过语句性做密等恢复。比说 Delay 没有做,整个表删了,改错了,这个做闪回是比较热的 binlog,其实做在线 SQL 的提取,这个层面做在线修复,都是比较快的。
Q:千万级或者是亿万的表有什么好的归档方式呢?这些表是每时每刻都有大量的 DML?
A:首先对于数据量我们定义是千万级,或者亿级甚至更高。有什么好的归档方式呢?其实提到归档的方式,按照我的理解更多是属于流水表,流水表的归档方式在设计中可以参考很多拆分的体系,通过日期的方式拆分,或者通过分区的方式拆分。如果通过日期的方式拆分,相对来说比较方便,你归档的时候,比如说用日期表换月表,日期表是 10 月 21 日,11 月 21 日的时候可以把 10 月 21 日的表直接归档,归档推到大数据或者是推到数仓,你推送之后数据下沉之后可以直接召回,不涉及到数据库 Delay 操作。
如果表每时每刻都有大量 DML,这个 DML 也可以拆分。如果你的千万级或者亿万的数据量依然有大量的 DML,建议考虑其他的架构设计方案。包括考虑业务拆分这一层。目前来看亿万级使用 NoSQL 可能会是比较好的方式。
Q:怎么从零搭建数据库运维系统?有什么好的开源工具推荐?
A:数据库运维管理系统搭建涉及到几个方面。运维开发层面着重于怎么构建数据库运维体系。首先你需要具备一定的运维开发的能力,从零搭建的程中,个人迭代代价比较高,开源好的工具比如 Ops Manager,在此基础上做迭代,逐步做前后端分离。
在这个过程中,需要考虑前后端分离怎么在运维系统中更好落地?对于很多运维,如果你具备后端开发能力,但是前端开发能力不足,怎么把短板补上?主要是做前后端分离,后端通过 API 进行集成,这样可以少一些困扰。
Q:对慢日志平台这一块很感兴趣,可以聊聊这个工具的架构和思路吗?
A:慢日志平台,开发工具我们是基于 Python,你用 shell 开发都可以。
架构方面,整个平台设计,分为慢日志采集,慢日志分析,慢日志模型,最后是前端的渲染。慢日志采集有不同环境,不同的 IDC 服务,我们可以在不同 IDC 生成一百套慢日志,我们都提取出来到分布式节点,把一些慢日志提取出来,提取汇总到一个服务节点上,在这个服务节点上使用 PT 工具对慢日志做分析,我们做的分析就是基于原始的分析,把 SQL 提取之后,把数据上传到运维系统,通过 API 方式上传,在运维系统里面定义一些模型,比如快照、日志、慢日志个数,定义快照的表和模型,排行榜也有这样一个模型,包括时长分布,详情等等都会有相应不同的表设计,包括像一些明细都是一套完整的设计。
优化建议这块是可选插件式服务。比如对于优化建议行业里也有这样一些比如 SQLWhether 可以做基础优化建议,可以把这块做集成。
包括做执行计划和表的字段等等,执行计划是在线采集出来的,在慢日志本身不体现。像结构信息,如果你公司的表设计有版本管理、生命周期管理,可以直接从里面提取出来这些结构的信息。如果没有也可以实时采集这些信息,这些信息可以基于模型里面做关联,关联后就可以分析出来了。
整个的模型做完了之后,再和前端做对接,有一些相关的 API 对接。像 CPU 趋势图完全是监控的数据,我们把监控数据提供相应的 API,根据相应时间维度提取,提取概要的数据,然后可以做相关的分析,看和 CPU 负载有没有关系等等。
采集工具开发其实对于开发语言没有严格的限制,我们可以用 Shell 也可以用 Python,我们当时使用的是 python。
Q:数据整体迁移到新平台时除了考虑安全性,还需要考虑什么?
A:数据迁移到整个新平台,其实不光是需要考虑安全性,其实更多是有两层的考量,有技术层面的考量,有对整个业务层面的考量。
比如说原来用的商业数据库,其实使用开源技术是大技术趋势方向。另外就是更多引入一套分布式的设计,分布式设计尽可能落地推广,大体是这样。在这个过程中,比如说也有很多的策略,我们原来业务有很多是耦合的,比如说实现一些同步的方式,同步过程中一旦有阻塞,整个是一个链式的影响,实现业务的方式以后,可能按照系统的设计包括架构设计相对来说会更有弹性。真正基于一些综合的考量,不光是一些安全性,包括像一些扩展性,比如说原有的集中式管理服务,比如说你服务的压力负载容量扩两倍、四倍,原来的负载是不是能支撑。基于分布式服务是不是能更快做扩容和缩容,这个也是考虑相对来说长期规划的过程。
Q:索引截图那部分是采集平台展示的方式,还是人工上传的?
A:整个索引部分其实刚刚说了,如果你有生命周期管理,或者有一个版本管理,你可以在自己模型或者数据级里面提取出来,如果没有的话,可以进行实时采集,展开以后可以看到相关索引的信息。
Q:慢日志排行榜和慢日志时长分布的时间维度是?
A:慢日志排行榜其实做了慢日志生成,有时间维度,比如 1 点到 3 点,2 点到 3 点,这个时间报告是不一样。我们生成这个维度采集的频率是 30 分钟采一次。
Q:可以做到对这些 SQL 黑名单做拦截吗?
A:对这些 SQL 做黑名单拦截,可以使用审计的插件实现。如果作为 SQL 黑名单这个显示做拦截,其实在模型层指定的时候做一层过滤就可以。
Q:数据库如何查询死锁信息,并快速定位死锁的故障?
A:首先数据库里面默认是有一个死锁的参数,大家如果用 5.7 以上的版本,默认会把数据库死锁的日志都打到数据库的 errorlog。如果更快速定位这个死锁的故障可以用两种方式:
第一可以通过把这个数据库的日志对接到 ES 里面做死锁的检测,更快速。
第二可以做相应监控巡检的方式,把这块信息绑定起来。
Q:对于初入行数据运维职业发展有什么建议?
A:如果你想入行做 DBA,首先要对某一个数据库非常感兴趣,你需要不断钻研这些技术。从技术发展来说,技术的变化一定是非常快的。
先把一门技术做得精通,然后再去逐步的扩展你的知识范围。因为倘若熟练掌握这个技术以后,再学习其他的方式相对来说会比较快。关于职业发展,我觉得需要踏实一点,你碰到一些问题,需要总结梳理出来,形成自己的知识,这样对你后续的职业发展会有很大帮助。
Q:从 Oracle 转 MySQL 跨度难吗?
A:从技术来说跨度难度不大。因为 Oracle 整个体系相对来说是比较全的,你在学习 MySQL 的时候,会发现很多的问题理解起来说比较容易的。MySQL 转 Oracle 相对来说比较难一些,但是 MySQ 其实会有更广阔的想象空间。包括在架构层面,MySQL 在高可用架构等等这样一些服务的层面,它的社区红利还是非常不错的。
很多人为什么觉得转得特别难呢?通常是因为工作当中没有那样的环境,不管你怎么迭代
或者是自己做这样一些练习,跟真实的环境处理还是有一些差别的。所以要从从心态上做出转变,要坚持下来,当然这个过程中你也要做很多方面的调整。
Q:已有数据服务和备用数据服务的数据同步和校对有什么实现方式?
A:其实对于表的设计来说,首先它不是一个一锅炖的业务,对于业务来说首先是密等性,从业务模型来说首先一定保证整体设计思路是对状态表的服务做同步和集合。在这个时间段之内,做增量同步的时候,其实一种是根据时间做的。原来是 200,我们在这个时间段之内增加 100,再做增量的时候,其实会把它的状态从 200 变成 300。然后如果在这个过程中,实时发生变化,我们会拿这个数据和线上的数据做一个在线的集合。在这个时间段之内不断做集合,集合确认数据是正确的,如果是不正确的,我们会把这个线上的数据覆盖过来。
数据同步这块有比较多的方法,你要提取的方式,因为数据量非常小。比如说基于时间的维度提取,可以根据这个差都可以提取。另外提一下,我们这个在线同步是基于缓存持续,我们不是直接对线上直接做同步,而是在第三方有数据同步的方式,会把这个数据放到池子,通过数据队列方式把这个数据进行消费。这个过程同步的过程不要影响已有的服务,同步完了之后再做线上集合。
作者介绍:
杨建荣,dbaplus 社群联合发起人,竞技世界资深 DBA,腾讯云最具价值专家(TVP)。前搜狐畅游数据库专家,Oracle ACE。具有十多年数据库开发和运维经验,目前专注于开源技术、运维自动化和性能调优。《Oracle/MySQL DBA 工作笔记》作者,每天通过微信、博客进行技术分享,已连续坚持 2100 多天。
本文转载自公众号云加社区(ID:QcloudCommunity)。
原文链接:
https://mp.weixin.qq.com/s/jnMILaFoL6groPF9xOMvQg
评论