运维不背锅!继续两年纪据库“0毛病”的运维优化之道 - 51CTO.COM
|
|
|
|
挪动端

运维不背锅!继续两年纪据库“0毛病”的运维优化之道

运维团队每天忙着应付种种非常,持久处于高压形态下。本文作者将分享这两年他对一些运维题目的剖析和团队办理的办法。

作者:刘书安泉源:DBAplus社群|2018-05-08 09:49

技能沙龙 | 邀您于8月25日与国美/AWS/转转三位专家配合讨论小顺序电商实战

运维团队每天忙着应付种种非常,持久处于高压形态下。本文作者将分享这两年他对一些运维题目的剖析和团队办理的办法。

各人好,我是来自安全科技数据库技能部运维团队的刘书安,从 2014 年开端,共同安全团体的互联网金融转型。

我们运维的数据库从单纯的 Oracle 数据库转向多种数据库的运维,以后办理的各种数据库的实例曾经超越了一万个。在这种状况下,我们延续两年坚持了数据库零毛病的形态。

现实上在之前,运维团队也是每天忙着应付种种非常,持久处于高压形态下。之后颠末我们团队一系列的优化和改革,现在零碎已波动许多。这时期也的确发作了许多事变。

接上去就跟各人复杂引见一下我们这两年对一些运维题目的剖析和团队办理的办法,抛砖引玉一下。

题目处理

起首我们从这张图提及:

这个是扁鹊向魏王引见他们三兄弟的医术:

  • 扁鹊本人是在病人不可救药时用虎狼之药将对方救活。
  • 扁鹊的二哥是在他人生小病时将人治愈。
  • 扁鹊的年老则是在病情未发时根除病因让人防止抱病。

在扁鹊看来,三团体的医术排序应该是:年老>二哥>扁鹊;但活着人眼里倒是:扁鹊>二哥>年老。

我比拟认同扁鹊的观念,由于我不断都以为 DB 的运维职员不该该只是背锅侠,而是应该把本人当成大夫来看待题目,不但是存眷题目的处理,更需求多存眷怎样防止题目的发作。

我们在数据库非常时去处理题目,他人能够会以为我们是妙手,能把题目处理好、事变处置失。

但实践上这时的运维曾经是一个主动式的处置,即使我们用了最快的手腕去处理,毛病曾经发作了,能够还形成了比拟严峻的影响。

假如我们能提早发明这些题目并处理失,就能防止许多毛病和影响的发作。因而在我看来,运维绝对拙劣的手腕应该是:在做架构或设计时就把能想到的题目事后处理失,确保零碎的可拓展性和高可用性。

运维也应该多从架构的角度去思索题目,并将这些题目提早处理好,而非主动地等候题目发作后才去处理。

接上去和各人引见我们团队处理的三个案例,以及之后我们经过什么方法防止题目的发作:

案例一

这是我们在 2016 年处理的案例,事先 Oracle 数据库的版本是 11.2.0.4,这种数据库运用 SPM 固化 TOP SQL 的实行方案,确保零碎的波动。

事先非常的题目是,简直每次发完大的版本后,已有的功用都市几多遭到影响,有一些语句的实行方案会发作非常。

我们发明,绝大少数语句都和这个语句是相似的,两头有一个 SKIP SCAN(腾跃式扫描),很分明可以看出它是一个输出工夫(对着用户的),有一个范畴盘问。

以是我们事先就根本判别题目出在这里了,运用的处理方案是经过重新固化实行方案来选择好的实行方案。

接着就开端剖析题目发生的缘由。

关于索引腾跃式扫描而言,在普通状况下,假如运维索引的第一个列没有效到,当它开端运用到第二个列时,就只能用腾跃式的办法去停止一个索引扫描。

而在剖析题目缘由时,由于相似的语句比拟多,我们事先在固化了几十条后,发明另有源源不时的相似语句呈现,就思索到题目能够并没有那么复杂。

以是我们又停止了进一步剖析,最初发明能够是索引的统计信息有题目。于是我们就重新搜集了索引的统计信息,至此,相似的语句题目才算是处理了。

但实在这个题目并没有彻底完毕:

我们在处置完后又重新剖析了这个索引的题目,发明索引第一列是一个空值,但不晓得是谁在空列和输出工夫上建了一个契合索引,招致这个索引有能够会被运用。

发明题目后,我们就盘问了这个索引的拜访方法,看看能否全都是 INDEX SKIP SCAN。

厥后发明,根本上拜访这个索引的语句都用的是这种索引腾跃式扫描,以是我们事先就把这个索引设置为不行用,前面把它删除了。

相似的索引,我们事先处置了有三个,之后这个零碎就没有再呈现如许相似的题目。

SPM 也是一种固化实行方案的方法,但为什么在这个库里,SPM 会生效呢?

之后我们剖析了它的缘由:是由于每次发版本时,有能够会多查一些字段,招致语句发作变革。

SPM 这类的固化实行方案的方法都和语句有强联系关系,只需语句上有一个小小的窜改,都市招致固化的方法生效。这也是每次更新版本语句都市发作非常的缘由之一。

之后我们持续剖析,为什么这个工夫索引有这品种似题目?

这是我们之前整理的一个案例剖析的缘由:我们在做索引的范畴盘问时,它的选择率公式如下 :

但是在差别状况下,比方这种右侧索引,比方创立工夫、更新工夫、输出工夫,我们写入数据都是用 sysdate 写入的,那么它永久都在索引列的右侧,相似这种方法是往外面拔出数据的。

但是我们统计信息的搜集又不是一个及时搜集的,次要是对一些大表,比方一个一万万的表能够要到 10%,也便是 100 万的 DMR 量;更大的表的DMR量会更大。

这就会招致我们的统计信息和以后的值永久是过期的,就会发生上面的题目。

关于这三个盘问来说:第一个盘问发作在无效范畴内,以是它可以反应出一个比拟真实的数据;第二个盘问也可以反应一局部。

但第三个盘问就相称于完成一个超范畴的盘问,盘算出一个很低的值,如许就会招致我们的语句偏非常。

更坑的是在 OLPP 零碎里,新数据盘问的几率永久比老数据的大,越新的数据被拜访的几率越高,这也招致我们的语句每次都市呈现非常的状况。

发明这些题目后,我们立刻睁开了一个举动,便是把数据库里一切与工夫索引相干的字段都提取一下。

然后活期修正索引字段下面的 HIGH VALUE,统计信息外面的 HIGH VALUE,就能防止呈现这种题目。

如上图所示,是一个范畴盘问的状况,即在一个索引前导列的区别,相似于我们在创立工夫和 OWNER 之间建索引。

假如把创立工夫放在后面,把 OWNER 放在前面便是第一种状况;假如把 OWNER 放在后面,把 CREATED 放在前面便是第二种状况。

如今来剖析这两个差别索引的区别:

当我们把创立工夫放在后面时,有一个很大的题目,我们经过工夫字段去盘问时很难做到等值盘问,即不行能去发明每分每秒拔出的值。

关于这种盘问,我们普通都运用范畴盘问,比方查一个月或一天、一周的数据。

以是各人可以看到,假如我在这个语句外调这一分钟、这一天 DBMGR 创立的状况,在第一个索引里它整个范畴都市触及到,随后取相干联的三个值。

但是在第二个索引里,三个值是连在一同的,由于 DBMGR 是有序的,工夫也是有序的,它们就可以完成只触及到本人相干值的值。

这外面另有一些粗大的区别:假如我先辈行范畴盘问,后做等值盘问,关于如许的索引,Filter 时就会多做一个 Filter 步调。

但假如把这个次序调解一下,就不会有这种状况。以是我们在做这种契合索引创立的时分,就肯定要只管即便把等值盘问的放在后面。

之前有一个说法:在选择契合索引的前导列时,要把选择率比拟低的值放在前导列。

但我们以为这个说法是不美满的:比方关于一个工夫字段而言,一天有 86400 秒,100 天就能够有 800 多万的差别值,一年会有更多差别值。

可假如把这个作为前导列,偶然候是不合适的,由于对它来说,有能够我们是需求盘问一天或一个月的数据,而一年有 365 天,或许说十二个月。因而更精确的说法应该是把盘问条件中选择率低的列做为复合索引的前导列。

以是经过这个案例,我们就把运维题目的处理分红了三个步调:

  • 疾速处理题目,确保使用规复。关于运维职员来说,规复使用是第一位的。
  • 看题目是不是反复性发作的。比方后面说的案例一,假如我们事先的处置方案仅是固化实行方案,或是搜集统计信息,你没有方法包管它当前不会再呈现相似的状况。

假如我们运用的是搜集统计信息的方法,能够再过一个月或两个月,这种状况又会再次发作,以是基本的处理方案是找到这个题目发作的缘由,确保这次题目处理后不会再复发。

  • 防止题目,看这个题目能否属于个性题目、其他库里有没有相似题目。假如有相似题目,就要构成一种标准,去防止这种题目的发作。

尤其是关于一些新的使用来说,只要当你订定标准、让开辟恪守后,后续才会增加相似题目的发作,否则就会演化成我们一边处理题目,新题目又源源不时发作的状况,最初我们只能不时地去处理这种反复发作的题目。

我记得之前有一个案例便是个性题目:事先是在一个实践的库里,我们剖析发明它存在内存走漏的题目,但并没有立刻开端处置,后果第二天另一个库也发作内存走漏,于是我们不得不告急重启。

事先我们剖析出题目是由某一个 Bug 招致后,就搜刮谁人 Bug 相干的信息,发明早在两三年前(2014 年)曾经有同事处理了这个题目。

只不外在另一个库里还打了相应的 PATCH 来处理题目,但便是由于没有把这个题目推行到一切零碎里,排查能否其他库也存在这个题目而惹起的。

从那之后我们就特殊留意这种个性题目,假如每个零碎、每个题目都要发作一次,价钱真实是太大了。

以是我们尽能够在发明个性题目后就处理失,只管即便扫除其他库也发作相似题目的状况。

案例二

第二个案例是一个版本为 12.1.0.2 的 Oracle 数据库,每到早晨总会不定时田主机 CPU 继续到 100%,使用同时会创立少量的数据到数据库中。

事先我们的应急方案是把这种相干的等候工夫全部批量 Kill 失,由于这些零碎是在比拟中心的库里,根本上每个零碎被 Kill 失的历程有几千个,价钱照旧比拟大的。

厥后这个题目发作两次后,我们开端动手重点剖析题目,经过 ASH 剖析发明,呈现这个非常等候是由于一个很复杂的语句—— SELECT USER FROM SYS.DUAL。

之后我们就经过这个语句来一步步联系关系, 看究竟是哪个中央挪用的,后果发明是在一个使用用户的登录 TRIGGER 中的用户判别步调。

这个 USER 是 Oracle 的外部函数,但便是这么复杂的一个语句,就让整个库都 Hang 住了。

然后我们开端剖析缘由,我们经过 ASH 发明该语句在我们规复使用前有重新加载的进程。

事先我们疑心是硬件招致的,就经过这种方法去剖析,后果发明是在早晨 10 点时被 Oracle 的主动义务做了一个统计信息的主动搜集。

搜集完后,又由于它是一个登录的 Trigger,用户在不时登录,在做登录剖析时这个语句就没方法剖析,以是才招致用户源源不时地卡在那边。

而使用是需求新建衔接的,新建的衔接又无法进到库外面,就会招致衔接数越来越多,全都卡在那边。最初我们经过锁定 dual 表统计信息的搜集来从基本上处理这个题目。

案例三

第三个案例有两个题目,但厥后我们发明这两个题目是由相反的缘由惹起的。

我们有一个数据库是从 10.2.0.5.X 晋级到 10.2.0.5.18 版本,晋级后会不定时呈现 cursor:pin 相干的一些等候。

实在呈现 cursor:pin 是很正常的,由于这个数据库的负载比拟高,变革也较高,但题目是它是在晋级之后呈现的。运营以为这是晋级之后呈现的非常,我们就开端动手剖析题目的缘由。

第二个题目是我们在应急时发明的,偶然非常呈现时,某个库里有些语句的实行次数会特殊高,乃至 15min 能到达上亿次,这关于一个正常的业务零碎来说,呈现这么高的实行频率是不正常的。

之后我们就去剖析这些题目,发明这两个题目有相反的一些点:比方语句两头呈现了个函数挪用;比方说这个状况下,A 表假如拜访的数据量较大时,这些函数就有能够被挪用许多次。

我们发明,有一个语句,它实行一次能够会呈现十几万次的函数挪用。假如在挪用的进程中,联系关系的那张表的实行方案发作了变革,比方说A表走了一个全程扫描,那能够会呈现几万万次的函数挪用。

事先我们也总结了一些关于经过什么样的办法去疾速定位、能否是函数挪用招致的见解。

在 Oracle 10g 之前的确没有什么好的方法,由于它外面没有一个表现的联系关系,就能够经过代码去扫描,去找对应的语句。

在 Oracle 11g 后会比拟复杂一些,经过 AS 值相干的 TOP LEVEL SQL ID 就可以间接联系关系到是哪个语句调的函数招致的题目。

这里另有一个题目是函数挪用。由于它挪用的函数能够都是特殊快的,但次数又会比拟高,功能动摇能够带来比拟大的影响。

之前我们有一个案例就发作在月尾顶峰,我们事先发明某个数据库中会呈现许多 CBC 的等候,厥后又发明有一个小表被频仍拜访,谁人小表就 100 多行数据,但能够它相干的语句每隔 15min 就挪用了上万万次。

实在这么高的并发下,呈现这种 CBC 的等候是很正常的。不外由于它只要 100 多行数据,且都会合在一个数据块里,以是才招致这个数据块特殊热,就会不断呈现这种 CBC 的等候。

于是我们就找方法处理这个热块的题目,但又由于不克不及在月尾冲业绩时停运来做修正。

以是我们就想了一个方案:建一个 PCT FREE 99 的索引,把表一切列的数据都包括出来,确保每个索引块外面只保存了一行数据,变相地把这 100 多行数据分到 100 多个块里。

做了这个操纵后,CBC 相干的题目被处理了,也顺遂地撑过了业务顶峰期,但是第二天月初的报表发明又失坑里了。

由于我们在每个月月初需求上报给羁系的一个报表,这种报表是属于一个长事件。

但是它在谁人报内外面也是调了之前优化的谁人索引,优化后的语句固然低落顶峰期 CBC 的等候,但由于它是要拜访 100 多个数据块,单次拜访从 0.25 毫秒酿成了 1 毫秒,相称于服从低落了 4 倍。

由于报表是一种长事件的处置,相称于谁人历程比原来多花了一倍多的工夫也没跑完。

以是之后我们发明这个题目后,又不得不把谁人索引给干失了,让它规复原来那种形态。

尤其是如今对 IT 的要求越来越高,时限的要求也越来越高,许多零碎根本都是用这种矫捷的开辟方法尽快地上线。

新零碎上线有一个很大的题目便是刚上线时压力都不会很大、负载也不高,但实在许多题目在开端阶段被隐蔽了。

比及真正发作题目时,负载高了或许压力大了再去处理题目,难度就会比拟大一点。

尤其关于数据库来说,数据库量小的时分,比方说 300、500M 的数据,这个表格怎样整改都很复杂,但比及这个表涨到 300、500G 乃至 1、2T 时再想去做这个表数据类的整改,难度就会大许多。

比方说,我们之前做分期表整改时会用这种在线重界说的方法,但关于一些比拟大的表,几百 G 乃至上 T 的表,再用这种在线重界说的方法,就会遇到林林总总的 Bug。

厥后坑踩多了,我们如今关于大表的分表改革便是先同步汗青数据级改革,后做一个数据增量,办法会庞大许多。

但实在假如在开端阶段,我们关于这种大表就曾经设计好它的分区,尤其在工夫索引上,基于工夫去做一个分区,可以防止许多题目。

为什么我们的汗青库里有那么多工夫索引?

很大的一个缘由是有许多报表是基于工夫去盘问的,比方说要查这一个月或许这一天新增的一些数据的状况,都需求经过工夫的字段去拜访。

我之前就见过许多关于工夫的索引,但最初却由于工夫索引的特性,招致零碎源源不时地呈现林林总总的题目。

假如在设计阶段把这些大表提早就设计身分区表,完全可以防止这些不用要的题目。

运维办理

由于各个公司详细状况差别,我接上去就复杂引见一下我司关于运维办理的一些做法,给各人做个参考。

变卦办理

绝对来说,我们公司的变卦办理比拟严厉,后续能够会愈加严厉。

变卦管控

关于变卦管控,比方在白昼严禁做任何变卦,任务工夫内任何变卦都不克不及做,即使是一些告急或毛病的修复,也是需求经过部分担任人确认、向导赞同后才可以做的,确保危害可控。

变卦流程

能够每个公司都有变卦流程,但我们公司有一个比拟特别的中央。由于一些兼容数据库的要求能够会高一些,流程管控的每个局部都要确保到位。

变卦方案

我们的变卦方案是每团体要提早去做评审和验证,包罗订定方案的同事和施行操纵的同事,就需求变卦施行职员提早在一个情况下做完好的验证,确保每个步调都是验证经过的。

标准办理

架构标准

我本人之前在做架构师时,订定林林总总的标准是一项重点的任务。能够是养成习气了,如今也和各人一同订定林林总总的运维标准。

但我本人感觉最深的是:标准肯定要有一致的规范,假如做不到一致就有能够会在后续发生题目。

比方我们之前有些开辟测试情况不是那么标准,如今想改革做主动化时,发明基本就做不起来,由于每个库的状况纷歧样,主动化的剧本不行能顺应一切状况来做这种规范化的改革。

把它弄成不规范是很复杂的,但要想把不规范的改成规范的,难度就大了,尤其是在我们曾经构成习气之后。

运维标准

在 2014 年前,我们做的是纯 Oracle 数据库的运维,由于之前树立的是一个传统的金融企业,运维的都是 Oracle 数据库,但 2014 年后我们逐渐转向了互联网金融。

因而我们连续研讨了 MySQL、PG、Redis、MongDB、SQL Server、HBase 等 7、8 种数据库,在运维进程中遇的坑就会比拟多。

最后有许多规范,但没有一个是最佳的理论,许多也是依据业界、本人的经历订定出来的;另有种种差别的数据库里,差别的团队订定了差别规范,最初就有林林总总的规范了。

以是我们在运维中会发明林林总总的题目,最初要强迫去做这方面的标准整改。

并且,之前的规范大局部都没有颠末大范围运用和大范围负载的验证,许多规范并不那么一致、标准和无效。

因而,我们在运维进程中关于这种标准,照旧在不时地去优化和改良,终究许多状况在没有遇到时,你真的是没有方法去处理这个题目。

标准优化

举个例子,最后我们并没有规则 Redis 肯定要和使用放在统一个网络地区,但随着 Redis 的负载添加,我们发明防火墙曾经接受不了。

事先安全的 WiFi 刚上线不久,但关于 Redis 的拜访,几个实例每秒都有高达上万次挪用,整个防火墙都撑不住了,还差点招致一个比拟严峻的毛病。

在处理这个题目后,我们就订定了一条强迫的标准:Redis 这种高并发拜访的数据库,肯定要和使用放在一同,不克不及有呈现跨墙拜访的状况。

以是这个标准也是不时去优化的,包罗我们运维的一些规范。由于在最后创立规范时,我们能够会由于运用工夫不长而思索不到一些题目。

我印象比拟深入的是 MySQL 刚引入时的一个题目,关于软件的版本没有明白到小版本。

厥后乃至呈现有 MySQL 停库时是 5.6.22 的版本,在维护完成后就被启动成 5.6.16 的版本。

最初是经过不时地优化来确保我们的标准和实践是相联合的,防止这种题目的发作。

职员开展

团队认识

关于团队这块,需求提拔每团体在团队中的作用,需求确保团队里的每团体都是有备份的。假如开展成分开谁都不可,那对团队的全体开展来说是不正常的。

以是我们在布置任务时,关于比拟紧张的任务,我会只管即便不让熟习的同事反复去做,而是只管即便让一些不熟习的同事到场去做。

之前每走一个资深成员,都市分明觉得到团队的全体技艺或知识少了一块。为了防止相似题目的发作,从 2017 年开端我们就订定了一些战略,让各人做知识技艺的分享,每周抽取两个下战书,每个下战书抽取一到两个小时做分享。

另一个战略是技艺的积聚,即把我们在任务中遇到息争决的一些题目都录入题目办理零碎。

如许做有两个益处:

  • 可以把反复的题目记载上去,由于我们想要去剖析哪些题目是反复发作的、哪些是有个性的,就需求有一个如许的零碎去拉对应的题目清单,最初去处理题目。
  • 即使职员流失了,他们之前处理的一些题目和技艺也能让团队其别人发明,不至于每走一团体就留下一个坑。

以是我们是经过这种手腕来只管即便防止职员流失或变化给团队带来的一些题目。

但说究竟,这种事这是没方法完全防止的,由于数据库运维有肯定的庞大度,需求依托不时地发作毛病、处理毛病,包罗一些人为失误来提拔。

权责清楚

我们的轮班职员是 7×24 小时,即上三班的方法来轮班的。之前团队有一个比拟严峻的题目,当一件事变发作了,轮班职员有能够将题目交代给下一班次;或是晋级给其别人后,就以为与本人没有干系了。

另有便是危害认识不强,有一些操纵没有评价过影响就开端在消费库里操纵。

事先我们也发作了不少题目,厥后在外部重点提拔两点认识:责任人认识和危害认识。

起首你需求在消费做步伐前,确保要做的操纵会有什么影响、招致什么结果,不克不及在做完后才去想这个题目:比方说我们如今每天变卦,都需求提早把剧本和手册做好,让值班职员熟习。

操纵会有什么结果?后续有什么非常会发作?应对办法又是什么?……这些都是需求提早评价好的。

技艺提拔

关于技艺提拔,固然须要的培训是必不行少的,但我们以为要害照旧要靠本人的学习、了解和在理论中的积聚,并没有什么好的捷径去完成,大多时分照旧要经过不时地处理题目、发明题目乃至包罗出错的价钱来提拔的。

刘书安,安全科技数据库技能部运维团队司理,以后任职于安全科技数据库技能部运维团队,有十余年的数据库办理经历,有多年纪据库架构设计和运维办理经历,熟习功能调优和毛病处置。现在次要担任安全科技数据库运维的办理任务,团队担任运维的数据库品种包罗 Oracle、PostgreSQL、MySQL、Redis、MongoDB 等少数数据库的运维办理任务。

【编辑引荐】

  1. 从0到1,滴滴DB主动化运维架构理论
  2. 阿里千亿买卖面前,运维怎样做到“0”毛病公布?
  3. 企业纷繁上云 IT运维怎样借力AI完成智能化
  4. 运维的苦,谁懂?一次“心有余悸”的迁库阅历!(有彩蛋)
  5. 一位女运维的自述:3年为公司节流10亿元!
【责任编辑:武晓燕 TEL:(010)68476606】

点赞 0
分享:
各人都在看
猜你喜好

读 书 +更多

网管员必读——超等网管经历谈

本书是一本以示例方式间接面向使用的网络办理图书。书中以少量示例和少量适用网络办理与毛病扫除经历引见了以后网络办理任务的各次要方面。...

订阅51CTO邮刊

点击这里检查样刊

订阅51CTO邮刊