关于dba:ClickHouse-挺快esProc-SPL-更快

开源剖析数据库ClickHouse以快著称,真的如此吗?咱们通过比照测试来验证一下。 ClickHouse vs Oracle先用ClickHouse(简称CH)、Oracle数据库(简称ORA)一起在雷同的软硬件环境下做比照测试。测试基准应用国内宽泛认可的TPC-H,针对8张表,实现22条SQL语句定义的计算需要(Q1到Q22)。测试采纳单机12线程,数据总规模100G。TPC-H对应的SQL都比拟长,这里就不具体列出了。 Q1是简略的单表遍历计算分组汇总,比照测试后果如下: <img alt=".." src="http://img.raqsoft.com.cn/docx/1657614854913100.png"> CH计算Q1的体现要好于ORA,阐明CH的列式存储做得不错,单表遍历速度很快。而ORA次要吃亏在应用了行式存储,显著要慢得多了。 然而,如果咱们加大计算复杂度,CH的体现怎么样呢?持续看TPC-H的Q2、Q3、Q7,测试后果如下: <img alt=".." src="http://img.raqsoft.com.cn/docx/1657614854984100.png"> 计算变得复杂之后,CH性能呈现了显著的降落。Q2波及数据量较少,列存作用不大,CH性能和ORA简直一样。Q3数据量较大,CH占了列存的便宜后超过了ORA。Q7数据也较大,然而计算简单,CH性能还不如ORA。 做简单计算快不快,次要看性能优化引擎做的好不好。CH的列存占据了微小的存储劣势,但居然被ORA用行式存储赶上,这阐明CH的算法优化能力远不如ORA。 TPC-H的Q8是更简单一些的计算,子查问中有多表连贯,CH跑了2000多秒还没有出后果,应该是卡死了,ORA跑了192秒。Q9在Q8的子查问中减少了like,CH间接报内存不足的谬误了,ORA跑了234秒。其它还有些简单运算是CH跑不进去的,就没法做个总体比拟了。 CH和ORA都基于SQL语言,然而ORA能优化进去的语句,CH却跑不进去,更证实CH的优化引擎能力比拟差。 坊间传说,CH只善于做单表遍历运算,有关联运算时甚至跑不过MySQL,看来并非虚妄胡说。想用CH的同学要掂量一下了,这种场景到底能有多大的适应面? esProc SPL退场开源esProc SPL也是以高性能作为宣传点,那么咱们再来比拟一下。 依然是跑TPC-H来看 : <img alt=".." src="http://img.raqsoft.com.cn/docx/1657614855059100.png"> Q2、Q3、Q7这些较简单的运算,SPL比CH和ORA跑的都快。CH跑不出后果的Q8、Q9,SPL别离跑了37秒和68秒,也比ORA快。起因在于SPL能够采纳更优的算法,其计算复杂度低于被ORA优化过的SQL,更远低于CH执行的SQL,再加上列存,最终是用Java开发的SPL跑赢了C++实现的CH和ORA。 大略能够失去论断,esProc SPL无论做简略计算,还是简单计算性能都十分好。 不过,Q1这种简略运算,CH比SPL还是略胜了一筹。仿佛能够进一步证实后面的论断,即CH特地善于简略遍历运算。 且慢,SPL还有秘密武器。 SPL的企业版中提供了列式游标机制,咱们再来比照测试一下:在8亿条数据量下,做最简略的分组汇总计算,比照SPL(应用列式游标)和CH的性能。(采纳的机器配置比后面做TPC-H测试时略低,因而测出的后果不同,不过这里次要看相对值。) 简略分组汇总对应CH的SQL语句是: SQL1: <pre>SELECT mod(id, 100) AS Aid, max(amount) AS AmaxFROM test.tGROUP BY mod(id, 100)</pre> 这个测试的后果是下图这样: <img alt=".." src="http://img.raqsoft.com.cn/docx/1657614855135100.png"> SPL应用列式游标机制之后,简略遍历分组计算的性能也和CH一样了。如果在TPC-H的Q1测试中也应用列式游标,SPL也会达到和CH同样的性能。 测试过程中发现,8亿条数据存成文本格式占用磁盘15G,在CH中占用5.4G,SPL占用8G。阐明CH和SPL都采纳了压缩存储,CH的压缩比更高些,也进一步证实CH的存储引擎做得的确不错。不过,SPL也能够达到和CH同样的性能,这阐明SPL存储引擎和算法优化做得都比拟好,高性能计算能力更加平衡。 以后版本的SPL是用Java写的,Java读数后生成用于计算的对象的速度很慢,而用C++开发的CH则没有这个问题。对于简单的运算,读数工夫占比不高,Java生成对象慢造成的连累还不显著;而对于简略的遍历运算,读数工夫占比很高,所以后面测试中SPL就会比CH更慢。列式游标优化了读数计划,不再生成一个个小对象,使对象生成次数大幅升高,这时候就能把差距拉回来了。单纯从存储自身看,SPL和CH相比并没有显著的优劣之分。 接下来再看惯例TopN的比照测试,CH的SQL是: SQL2: <pre>SELECT * FROM test.t ORDER BY amount DESC LIMIT 100</pre> 比照测试后果是这样的: <img alt=".." src="http://img.raqsoft.com.cn/docx/1657614854638100.png"> 单看CH的SQL2,惯例TopN的计算方法是全排序后取出前N条数据。数据量很大时,如果真地做全排序,性能会十分差。SQL2的测试后果阐明,CH应该和SPL一样做了优化,没有全排序,所以两者性能都很快,SPL稍快一些。 也就是说,无论简略运算还是简单运算,esProc SPL都能更胜一筹。 进一步的差距差距还不止于此。 正如后面所说,CH和ORA应用SQL语言,都是基于关系模型的,所以都面临SQL优化的问题。TPC-H测试证实,ORA能优化的一些场景CH却优化不了,甚至跑不出后果。那么,如果面对一些ORA也不会优化的计算,CH就更不会优化了。比如说咱们将SQL1的简略分组汇总,改为两种分组汇总后果再连贯,CH的SQL写进去大抵是这样: SQL3: <pre>SELECT *FROM (SELECT mod(id, 100) AS Aid, max(amount) AS AmaxFROM test.tGROUP BY mod(id, 100)) AJOIN (SELECT floor(id / 200000) AS Bid, min(amount) AS BminFROM test.tGROUP BY floor(id / 200000)) BON A.Aid = B.Bid</pre> ...

December 15, 2022 · 2 min · jiezi

关于dba:SQL审核-SQLESQL审核平台体验报告

作者:刘新旺 MySQL DBA,专一于 MySQL 数据库多年,现就职一家本地生存服务类互联网公司,负责数据库相干工作。 本文起源:原创投稿 *爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明来源。 产品概述体验环境体验产品:SQLE软件版本:sqle-ce-1.2111.0-pre2部署环境:CentOS Linux release 7.9.2009 (Core)产品介绍SQLE( https://opensource.actionsky.... )是由上海爱可生信息技术股份有限公司 开发并开源,反对多场景审核,反对标准化上线流程,原生反对 MySQL 审核且数据库类型可扩大的 SQL 审核工具。需要剖析产品定位 互联网时代,一个 app 可能承载成千盈百万用户的应用;其业务规模之大,更新迭代之快,泛滥业务线日常上线 SQL 之多;DBA 对上线 SQL 的审核和执行工作变得非常忙碌,如何高效的保障SQL语句的高效执行和品质,对于零碎的高效运行和短暂稳固有着很大的影响。用户需要剖析 外围需要为:开发人员自助、平台初审、DBA 复审、执行上线。用户细分 次要应用人员:开发人员和 DBA ;开发人员心愿便捷、高效、自主可控的上线业务 SQL ;DBA 心愿便捷、高效、平安、高质量的审核 SQL 上线。产品剖析产品结构图 通过SQLE的产品结构图咱们能够看到,SQLE 的界面设计较简洁,工作台能够看到与本人相干的待办工作;首页列表搁置外围性能【工单】审核,其它性能收集到平台治理中;【规定】能够思考支出到【平台治理】中;【审核打算】也能够思考支出到【平台治理】中,审核的后果能够集成到工单中,不便对立进行解决。 产品应用流程图 通过 SQLE 的流程图能够看到,整体流程分为两个两个局部,一个是根底配置,配置好了根底配置当前,就能够执行上线流程了;对于审核不合格的性能仍旧能够执行工单,没有起到主动审核的意义,对于ERROR级别的谬误能够主动驳回不与上线;进入工单页面后不能很好的发现审核操作按钮(工单进度局部),须要下拉窗口能力发现;能够把审核操作放到审核后果列表前面加一个操作列,体验会更加敌对。下图为缩放67%后能力看到上面的审核操作. 性能体验剖析(1)创立SQL工单-SQL语句不反对输出联想,倡议减少输出联想,进步录入效率 (2)创立SQL工单-SQL语句对于显著语法错误不能及时提醒,倡议减少语法错误提醒,提前发现显著问题 (3)创立SQL工单-SQL语句输入框高度过高,点击审核后不不便查看到后果,倡议升高高度减少宽度 (4)创立SQL工单-工单不反对自定义上线工夫,同时也不反对定时上线 体现层平台整体以白灰色色调为主,配色稳重简洁,不同状态以不同色彩显示区别,猜想应该是用的ant design组件库;页面列表和CURD页面不够简洁和清晰,有待优化。竞品剖析 SQLEArchery审核✓✓查问×✓执行✓✓备份×✓告诉email钉钉、企业微信、邮件告诉流程✓✓白名单企业版慢日志审核企业版只有收集展现,暂无审核审核打算反对 MyBatis Scanner×扩大反对插件化反对插件化应用感触因为工夫无限,仅是集体测试体验;SQLE 整体设计不错,合乎当初支流平台的各方面特色;次要几个设计点我比拟喜爱: DB 类型和实例关联模版这个治理力度很细数据源关联流程,使审批粒度更加粗疏,治理更加不便SQL 白名单,应答非凡状况,防止业务被规定卡死,同时防止管理人员间接操作数据库;sql 指纹相当于提供了统配性能,更加不便审核打算是个好货色;对于想集成 CI/CD 是一个很好的参考 审核反对插件化,更易扩大后端应用 go 语言开发,部署兼容性和性能更加敌对

December 23, 2021 · 1 min · jiezi

关于dba:DM8-安装前准备工作

本机系统为 MacOS;装置零碎为 CentOS;应用的虚拟机产品为 Parallels Desktop。 手续为: 数字签名校验;查问零碎信息;创立装置用户;查看零碎限度;查看零碎内存以及存储空间;敞开防火墙和 selinux 策略;数字签名校验因为下载的试用版,所以跳过这一步骤。 查问零碎信息查问零碎信息的起因:看 DM8 是否能装置到本台机器上。临时还不晓得,除了根底要求,有哪些机器是 DM8 不能装置的。 查询方法如下:getconf LONG_BIT:查问零碎位数: lsb_release -a:查问操作系统 release 信息;第一次执行会找不到命令,而后零碎提醒须要装置 redhat-lsb-core 这个包,装置实现之后就可应用此命令了。 cat /etc/issue:查问零碎信息; uname -a:查问零碎名称; 创立装置用户创立装置用户的起因:不应该应用 root 权限的用户来装置以及运行 DM,免得缩小对操作系统的影响。 创立用户的办法: 创立装置用户组:dminstall groupadd -g 12349 dminstall查问是否装置胜利: cat /etc/group个别装置胜利会在最初一项呈现 创立装置用户 dmdba useradd -u 12345 -g dminstall -m -d /home/dmdba -s /bin/bash dmdba查问是否创立胜利: cat /etc/shadow如果创立胜利会在最初一项呈现 初始化用户明码: passwd dmdba退出登录,而后以 dmdba 此账号登录。查看操作系统限度起因:在 Linux 零碎中,因为 ulimit 的存在,可能会对程序应用操作系统资源进行限度。 应用 ulimit -a 查问所有的参数: 批改 ulimit 的资源限度1 ulimit -n 65536:批改最大文件关上数为 65536。 此批改仅在本会话失效。批改选项在前面列出。2 批改配置文件。文件地址为:/etc/security/limits.conf。在此文件中增加: ...

November 29, 2021 · 1 min · jiezi

关于dba:我们又错过了一艘船数据库的征程是星辰大海

导语 | 关系型数据库体系曾经走过了50年的历程,这期间数据库曾经成为数字化时代的外围组件。近年来,国产数据库更是百花齐放,走上历史舞台。在历史倒退的每个阶段,数据库技术都经验了哪些关键性的演进,在将来,数据库技术又将走向何方?本文由云和恩墨CEO、腾讯云TVP 盖国强在 Techo TVP开发者峰会「数据的冰与火之歌——从在线数据库技术,到海量数据分析技术」 的《万象更新——数据库技术的倒退与将来》演讲分享整顿而成,为大家详尽介绍数据库技术的要害演进阶段、当先的技术摸索方向,论述国内数据库倒退的最新动向。点击可观看精彩演讲视频 一、数据库行业的三大趋势我带来的主题是“万象更新”,明天,用这四个字来掂量中国的数据库畛域是恰到好处的,市场上大量国产数据库不断涌现,不同的国产数据库在不同的场景里找到了更广大的利用空间,这是数据库时代的中国时刻。 为了阐释这些观点,首先分享我对行业的一些判断。 1. 走进新数据库时代首先我认为数据库的技术倒退通过了三个时代:从商业数据库时代到开源时代,再演进到明天——我称之为新数据库时代。留神,很多人把明天这个时代称作“云数据库时代”,然而我更违心用一个“新”字,因为国外和国内的数据库市场呈现出不同的倒退格局。 商业数据库时代次要是以Oracle为代表,衍生了一系列商业数据库软件公司,这个时代,很多国产数据库公司在十分晚期就开始了摸索。 第二个时代是以MySQL为代表的开源数据库时代,开源成就了互联网,明天大家应用了很多腾讯的服务、产品,为什么可能失去疾速的、便宜的甚至是收费的互联网服务?就是因为互联网的底座是由收费和开源的精力承载,开源技术成就了互联网。 第三,明天进入了新数据库时代。开源数据库技术依靠云产生了价值,过来开源技术很难被评估产生了多少商业销售和商业价值,但明天在云上它们能够被贩售,它的价值就能够被量度。昨天Gartner收回的报告提到微软数据库曾经超过了Oracle,成为了寰球市场的第一,中国市场上腾讯云、阿里云和华为云是三大数据库的领先者,这阐明什么?这阐明在新的时代里云成为了数据库最重要的一个阵地。 然而中国的数据库畛域还呈现出了新的特质——百花齐放的数据库生态。因为国产数据库的自主翻新和迭代起步晚,仍要重走一遍国外的技术路,这是中国数据库呈现出的不同格局。TDSQL是从2012年就开始的,明天有一系列的国产数据库在市场上锋芒毕露。 2. 数据库成为云上的终极之战第二个大的趋势是什么呢?是数据库最终成为了云上的终极之战。 因为云最根本的特质是以IaaS为根底,当实现了IaaS这一层的建设,紧接着是PaaS层,PaaS这一层就必须解决数据库的问题,谁可能率先买通PaaS层,谁就可能博得竞争劣势。 举个AWS的例子,AWS在2019年发表将7500个Oracle数据库都彻底替换,为什么它是一个十分重要的事件?因为在每年甲骨文的寰球大会上,Oracle都会讥笑一次亚马逊:你们在云上卖开源的数据库、卖你们本人的云数据库,但其实你却要从我这儿购买大量的Oracle License。所以亚马逊就收回承诺,要把它们全副替掉,在2019年实现了。在这个替换的过程中最终出现进去的实质是什么?我援用了亚马逊在替换实现之后他们的首席布道官的一段话,他说咱们传统的DBA大部分工作工夫耗费在数据库的扩容、存储的扩容以及License许可的会谈上,而传统DBA所做的这些工作明天都能够通过云自助来实现,这是实质上的变动,这个实质的变动是互联网的技术、云的技术使得传统工作能够自动化实现,我认为这实质上是改革的外围。 3. toB市场是数据库成败要害在中国市场略有不同,我认为在中国市场未来会是一个私有云和混合云长期共存的时代,而且公有云依然会占有广大的市场。在这个倒退格局之下会呈现出一种什么样的数据库格局? 我把它概括为,将云的体验最终要转移到数据上,既然不是所有的数据库、数据都能上到私有云,那么咱们就须要将私有云那些最佳的用户体验、主动自治的个性转移到公有的数据环境部署上,这在剖析报告里被称为叫TPC,是说仅仅有了IaaS和基础设施,不能成为一个真正的公有云,还须要具备互联网的用户体验、真正云的弹性伸缩等外围能力。所以我认为在数据库畛域,尤其在中国市场高低一步的格局就是云的体验云下化,最终云上和云下会趋于统一,云会成为将来惟一的基础设施提供状态,只不过还有私有、公有的两种说法而已,实质内核趋同。 二、数据库技术的学术界观点方才谈的是咱们在工业界生产实践中看到的几大趋势:从商业到开源到云时代,从云上到云下,云上体验的云下化。咱们再来看看学术界在探讨什么,在思考什么。 近五十年间图灵奖所授予的5个数据库畛域的大神,第一个是巴赫曼,他是网状数据库的发起者。第二个是科德,他是咱们明天所在探讨的关系型数据库的缔造者,通过他1970年发表的一篇论文,催生了整个关系型数据库波澜壮阔的大格局,他在1981年取得了图灵奖。第三位是格雷,他是事务实践的深刻探索者,他在工业实现上是包含微软等数据库产品的灵魂人物。第四位是迈克尔·斯通布雷克传授,他在2014年取得了图灵奖,也发动了很多数据库我的项目的守业公司。和大家重点分享一下在2021年刚刚取得了图灵奖的乌尔曼,他的次要成就是在教学畛域,他写过十分驰名的龙书,是很多数据科学家的启蒙导师。 大家能够略微思考一下这样的演进过程产生了一些什么变动?从最早的实践奠基人到事务的探索者;再到斯通布雷克在工业界的产品化的尝试——从关系型行存到列存、到大数据,他摸索了很多畛域;再回归到明天咱们说乌尔曼,他是从学术界、从学校的教育开始,去从新思考这些数据库实践是不是依然有摸索、翻新、变革的可能性。我方才和李海翔老师探讨,他说最近他在思考的就是这样一些事件,试图从事务模型上再做出新的考虑翻新。所以我把它看成是关系型数据库实践倒退到山穷水复疑无路,但大家开始回头来看在这些基础理论上是不是还有柳暗花明的机会,这是我的观点。 乌尔曼传授在他最近的论文里提出了这样一个观点,叫“数据迷信之战”。所以大家曾经看到了我提到了两个和平,一场是说数据库是云上的终极之战,这是大家公认的;第二场是数据迷信之战。在很长一段时间内数据库畛域有一种乐观的声音,大家说数据库管理系统正在变得无关紧要,做数据库的人常常在谈的一句话是“咱们是不是又错过了一艘船”,这艘船是数据迷信。数据迷信的蓬勃发展、炽热的现状让做数据库的人感觉是不是咱们又错过了一班最好的邮轮。然而乌尔曼传授提出,数据库以及因为数据库研究所产生的技术依然是数据迷信最实质的内核,这个没有变,数据库系统的外围始终是如何尽最大的可能去解决最大的数据量,并且应该去钻研所有数据。我认为他把数据库的实质又从新论述进去了,咱们钻研数据库的人、钻研数据技术的人想做的是什么呢?就是存储所有数据,钻研所有数据,最初在这些数据里产生洞察。如果人工智能可能在数据迷信里施展真正的翻新作用,那这个世界能够变得更美妙,然而它的底座肯定是一些原生的数据。 三、Oracle 数据库的外围演进和翻新1. 宏观演进既然学术界有这样一些认识,认为存储所有数据、钻研所有数据依然是数据管理系统的实质,那我想跟大家回顾一下在明天数据库畛域里仍处于王者位置的Oracle是怎么走完这条路的。 我略微列举了一下从Oracle8到明天走过的要害历程。在Oracle8这个版本上,大家看到Oracle曾经推出了互联网版本8i,Oracle看互联网看得晚吗?不是,它从1998年开始就把产品定义为i,为互联网而生,1998年是什么时候?很多90后那时可能还在幼儿园,但那时的互联网曾经在探讨数据库了。Oracle针对并行处理做研发、数据库原生的XML反对,这正好是我入行的时候,所以我最早就钻研了这个技术在数据库里的实现。到了Oracle9i做了什么?它做了集群,并且集群真正走向成熟了,就是共享存储的分布式集群,Oracle开发本人的Linux发行版,开始做数据库的自动化技术。到了2004年Oracle10g的时候,做了Oracle自动化存储管理技术,这是一个十分胜利的产品,它间接导致了市场上做存储软件的一些公司隐没了,所以你能够设想它的影响力,这是十分重要的技术事件。 再到了2008年,进入Oracle11这个版本,它开始开发一体机产品,开始做数据库端的读写拆散等技术,然而留神在这里我重点标出了一个工夫点:2006年,AWS这时推出了S3技术,我认为Oracle数据库在倒退的历程中只错过了一件事件,就是云。当AWS在2006年推出S3的时候,Oracle创始人在2008年是这样回复的,他说我认为云是用新瓶装了老酒,没有新的技术创新,是大家炒作的一个概念。可是咱们当初回头去看,他的判断出错了,也正是因为这一步的判断出错,大家看到了当初数据库畛域的领先者都是在云上胜利的这些厂商,比方微软的云胜利了,所以微软变成了数据库的第一,Oracle降落到了第二位。所以咱们说洞察将来十分难,然而十分重要,它事关生死,这也是咱们明天在这里探讨数据库将来的起因。 咱们疾速向下推动,Oracle在2017年推出的12c版本里开始做分布式,并不是像大家了解的Oracle没有分布式。在2018年的时候18c把它的集群也做成了分片式的架构,也反对了IOT。到了2019年在19c中它反对了智能化的索引——我认为智能化索引是一个翻新,真正曾经用到生产实践中了。再到20c——当初Oracle每年会公布一个版本,以年度进行命名,然而留神,因为疫情的起因其实20c没有公布,会合并到往年公布21c——长久化内存被利用到数据库里了,这阐明什么?阐明Oracle数据库依然是一个具备创新力的产品,正在一直地把当先的技术用到数据库的内核中去,提供新的生产力,这里包含人工智能的索引,这些都代表了明天的前沿。包含它的多模、软硬联合——所以Oracle所走的这些技术路线在明天数据库畛域看起来少数都是对的,它只错过了云这一件事件。 2. 宏观演进我方才讲的其实是几个宏观上的概念,在宏观上我找了一些小的要点跟大家剖析一下。 数据库明天着眼于性能向前演进最重要的是什么?是把原来的串行点打散变成并行点,其实就是微小的性能晋升,不论是Oracle还是TDSQL,还是其余国产数据库,明天最次要的翻新、性能晋升是在做这样的事件。我举几个简略的例子:比方从Oracle9i的时候,开始把共享内存池进行分片拆分,拆成了七份;通过ASM把存储进行分布式地打散;把过程进行主从拆分。比方从12c,把日志写过程变成了主从,在几十年的历程中Oracle的日志写过程只有一个,单过程写日志,然而从12c开始变成了主从,这是一个艰巨的扭转,咱们晓得绝大多数数据库的性能瓶颈会产生在日志的同步落盘上,大家都在做优化。19c的实时统计信息,再加上到明天的19c智能化索引——其实这个智能化索引的思路比较简单,它就是把人的思维模仿进去,通过人的专家系统进行思考创立一个什么样的索引,去进行尝试确认,性能晋升保留,性能降落则删除——然而真正落到工业实现实属不易。在20c里,提出了主动的参数调节以及自治的主备切换等等,把这些能力都融入数据库中,这是Oracle走过的40多年的技术改革之路,它依然在这条路上向前飞驰。 四、以腾讯TDSQL为例,国产数据库的演进之路咱们再来看国产数据库如何走技术演进之路。我后面提到了关系型数据库技术从1970年科德博士的一篇论文开始,曾经走过了50年的历程,这50年在咱们做数据库的人眼里,很多时候感觉关系型数据库曾经快到止境了,它将来的路在哪里?我认为关系型数据库将来的路应该在中国,为什么在中国呢?是因为中国有最宏大的数据基础设施、最集中式的数据利用零碎,所以这是我的判断。 如果咱们在中国看,至多很多业务零碎是省级集中的,而一个比拟大的省份就可能有上亿的人口,这样集中式的数据基础设施在国外是不可设想的。关系型数据库实践走到明天为什么能够有冲破?我认为就肯定是在利用中找到冲破,所以其实我也在看腾讯TDSQL的倒退演进进化,从让TDSQL逐渐地能用和走向成熟,这是实现了第一步迭代。第二步迭代,它必须在内部走到最广大的用户群体、用户场景去应用,最值得大家关注的案例就是微众银行。微众银行明天做到的是单日交易峰值有6亿笔,最高TPS能够达到10万笔,这是一个什么概念?6亿笔的交易大家能够想像,这是多宽广的一个用户群体可能发明进去的交易,这样频繁的、高频的交易肯定会促使数据库一直地去欠缺、提高。如果大家用过Oracle的话会晓得Oracle数据库在生产零碎中能承载的交易峰值和并发的交易笔数,如果你可能见到一个超过每秒1万笔交易的Oracle数据库,曾经是一个微小的挑战,然而明天在互联网的模式下,在分布式的架构下,海量的利用、海量的高并发能够被反对,所以这是我认为在中国的场景下能够带来的催化剂,这些催化剂会促使数据库找到新的向上的空间。 开展来说,一旦一个开源数据库要利用到金融外围上,必须解决的外围问题是什么?第一个是数据安全问题,如何让数据保障一致性是相对可信赖的,TDSQL进行了数据强统一的革新,主从节点默认是强同步的,这是一个技术创新。第二,当咱们应用了分布式架构,也就意味着须要治理的数据节点会迅速收缩,原来繁多的数据库存储,当初在这种架构下可能会有成千盈百的数据节点,这样成千盈百的数据节点不可能再依赖人去做数据保护,因为做不到了,所以这外面有一组数据,有1万个服务节点在微众银行运行,怎么办?它肯定要依赖于高度自动化的监控和故障解决伎俩,最好是不须要人染指,我认为这也是数据技术倒退的重要将来。有了这些之后,我方才提到整个TDSQL是基于分布式构建的,读写拆散是它的根本要义,这样一个零碎在反对这样的场景下逐步找到了将来的倒退之路。 这是一个两年前的案例,TDSQL在张家港农商行的客户场景下,把过来的金融交易外围彻底代替。微众银行是一家互联网银行,它的先天劣势是没有历史包袱,然而对于一个传统银行,它的数据架构、数据利用是非常复杂的,不仅有交易、存取款、账户,还要有对账,这样简单的业务场景如何在一个新的数据库架构上落地,其实很艰难。这个案例腾讯和最终客户应该是通过两年多的工夫才推到线上,当初看来后果是十分好的,一主三备模式,秒级的故障切换,我始终在关注。 但这个案例里给我另外一个十分重要的信息是TDSQL所提供的赤兔和扁鹊零碎成为了自动化运维的一个根基,为什么我认为这十分重要?将来的数据库肯定不是一个繁多的数据库内核零碎,而应该是一个数据库生态体系,蕴含了自动化运维、自治的主备切换、自治的高可用等个性,这些个性也是Oracle明天在做的,我认为在将来会是十分具备竞争力的外围个性。 五、数据库技术倒退的将来方向总结一下,方才是所察看到的行业利用的变动、数据库技术从实践到实际的变动、Oracle的变动包含TDSQL的倒退,当初看数据库的演进将来应该是什么样?首先我说数据库的更迭代替肯定不是重走一次长征路,不能用国产数据库把商业数据库替换了,然而不好用,这样用户是没方法承受的,所以它肯定不应该是性能和体验的降级,而应该是降级,但如何能力降级?我认为这五大方向是咱们应该思考的: 第一是分布式,分布式能解决的是弹性伸缩、故障自愈,这两者同样重要,更重要的是当呈现故障的时候不须要人紧急染指,它能够自愈。 第二是智能化,将人工智能技术利用到数据库里,比方去解决DBA过来所面临的外围挑战。DBA过来做优化,很大一部分工作是帮数据库去优化索引,所以Oracle在这一步上优先做的是智能索引,变成自动化,惯例的根底工作实现了,索引变成智能的,执行打算是可控的,那么数据库就不再须要特地多的人力染指。 第三是多模化,这一点是有争议的。我后面提到了亚马逊把7500个Oracle数据库替换成了本人的云数据库,能够设想会用多少个云数据库去替换原来的7500个Oracle?很可能是75000个甚至是75万个,为什么?因为Oracle是一个多模数据库,外面能够存储大对象、IOT等各种类型的数据,只管这种混合存储并不一定都可能达到最佳,然而对于用户呈现出的界面是最简略的。我认为数据库的倒退肯定也是分分合合的历程,走向分,最终也会走向合,繁多的界面输入对于用户是最佳的,如果扩散,那就要实现高度自动化。 第四是软硬一体,数据库技术肯定不是独立倒退的,它肯定能够依赖硬件技术的提高获得卓越的性能晋升,所以为什么很多数据库明天都在打造一体机?通过高速的网络以及高速NVME存储晋升整体的性能,所以软硬协同倒退不可短少,未来最外围的是数据库技术应该下压到CPU处理器一级去做优化,我认为这是能够做到的,而且在中国将来肯定也能够做到。 第五是云化交融,云会成为将来惟一的状态。尽管私有云和公有云依然是两个世界,然而会趋同,技术栈、用户体验都会趋同,而且云上体验云下化是数据库技术倒退当下一个最重要的趋势。 所以这五个观点交融在一起,代表了我对将来数据库倒退的一些判断。反复一下,如果国产数据库心愿让用户取得更好的体验而非降级,只有一个门路去补救,就是自动化,通过自动化的生态和工具去解决这方面的问题,内核可能还比不上国内一流水准,然而自动化能够帮忙用户不去面对底层简单的基础设施。 最初点一下题,叫DBA的冰与火之歌。已经很多DBA敌人一度陷入迷茫,尤其是在Oracle营垒的DBA们,他说在国产数据库的浪潮之下Oracle的DBA们还能生存吗?很多人常常问我会被历史淘汰吗?我说不会,首先咱们认为数据肯定会变成将来数字企业的外围资产,它会越来越重要,这是大家公认的一个前提。第二整个数据库的运行还是绝对简单的,它波及到了主机、网络、存储,是一个全栈的技能需要,具备肯定的技术壁垒,所以DBA们不要胆怯就业。第三从原来的数据库治理,你积攒的所有教训在明天能够找到更广大的待业空间,如果咱们充沛了解Oracle或者MySQL技术,你甚至能够变成一个国产数据库的产品设计师、产品治理师、内核开发者,如果你能把对国外数据库的先进技术变成产品设计和实现驱动,你就变成了咱们国产数据库的外围驱动力,所以国产时代咱们的路不是变窄了,是变宽了,职业路线更加广阔亮堂。DBA这个群体是十分乐于摸索、分享、总结的一群人,只有咱们具备了这样的能力,将咱们原有的学习转移到新的技术路线上来一点都不简单。 最初我还有一个思考,新的时代,咱们做数据库的要记住这两句话:一主一备双引擎,商用开源两相宜。只学一个数据库肯定不够,商业和开源都要接触、学习,并且相互校对。有一个主修、一个辅修,能够抉择两个科目。在这个国产的时代,从短期看咱们往往是高估了难度,从长期看咱们总是低估了时机,春江水暖鸭先知,如果你意识到了这个行业的改革,尽早转型,尽早投身到国产数据库的浪潮中去,那咱们就是抓住机遇的第一批人。只有躬身入局,才可能当先一步。 讲师简介盖国强云和恩墨CEO、腾讯云TVP 云和恩墨创始人,ACDU 主席。中国地区最驰名的Oracle技术推广者之一,他的专著《深刻解析Oracle》、《循序渐进Oracle》等书籍受到Oracle技术爱好者的宽泛好评。2009年,盖国强学生创立了云和恩墨,致力于为中国用户提供业余的数据服务、产品和解决方案,云和恩墨的 dbPaaS产品和专家服务,曾经服务了国内外500多加企业级客户。2019年,他发动创建墨天轮技术社区和ACDU(All China DBA Union),致力于继续的数据常识和利用的流传和推广。

May 17, 2021 · 1 min · jiezi

关于dba:DBA日常工作

1. 引言本指南旨在简要地列出Sybase ASE系统管理员(DBA)所需的日常保护工作。一般说来,在实现这些操作后,所治理的ASE数据库能够长期安全可靠地运行。本指南着重的是what to do,而不是how to do,也即是说本指南并不会具体地介绍如何进行这些日常工作,但会给出相应的参考手册。咱们认为作为一个合格的数据库管理员,应及早发现可能导致的问题,而不是等到呈现问题时才来解决。依据Sybase技术支持人员的教训,在呈现问题时,因工夫急切,数据库管理员所采取的一些紧急措施往往容易导致更重大的问题。因而,本手册着重介绍的是一些事先的预防、查看措施,而不是预先的解决。 思考到目前仅ASE12.5.0有中文手册,因而,本指南所指出的参考的手册和章节均应用英文版手册的名称和章节。 另外,须要留神的是,本指南只是 guide,理论生产环境差别甚大,请灵便把握。如 2.10 和 2.11 节就不适宜 7*24 运行的零碎。同时,后期公布的本指南的 PDF 版本不再更新。 本指南的撰写过程中,失去了Sybase广州办事处胡道军、周海涛工程师的大力支持和斧正。SybaseBBS的敌人们也自私地奉献出他们贵重的教训和意见。在此真诚地示意谢意。 1.1.适宜的读者本指南所面向的读者次要是Sybase ASE 数据库管理员,应具备Sybase ASE数据库基本知识,能独立进行数据库的基本操作。 本指南能够为那些心愿制订适宜所在组织的ASE数据库保护制度的管理人员提供参考。 1.2.约定本手册听从以下字体和格调约定: 元素 示例 书名、章节名 《__System Administration Guide Volume 2__》 、 Developing a Backup and Recovery Plan 定期频度 每周一次 存贮过程或、命令 sp_addserver targetservername 2.日常保护工作2.1.定期备份master库Master库是ASE最外围的零碎库,它记录了所有数据库的物理和逻辑信息。因而其备份工作独立成节。 倡议master数据库的备份频度为每周一次。同时,在进行任何零碎表操作之前和之后,应当时/立刻备份master库。如: disk init 、 sp_addumpdevice 、 sp_dropdevice 、磁盘镜像命令、 sp_addsegment 、 sp_dropsegment 或 sp_extendsegment 等。 Master数据库的备份能够采纳在服务进行后,间接复制master.dat文件的形式进行。 无关备份master数据库的详细信息,请参考Sybase手册之 《__System Administration Guide Volume 2__》 中的 Developing a Backup and Recovery Plan 一章。 ...

January 31, 2021 · 2 min · jiezi

关于dba:DBA的40条军规

1、波及业务上的批改/删除数据,在失去业务方、CTO的邮件批准前方可执行,执行前提前做好备份,必要时可逆。 2、所有上线需要必须走工单零碎,口头告诉视为有效。 3、在对大表做表构造变更时,如批改字段属性会造成锁表,并会造成从库提早,从而影响线上业务,必须在凌晨0:00 后业务低峰期执行,另对立用工具 pt-online-schema-change 防止锁表且升高提早执行工夫。 应用范例: #pt-online-schema-change --alter="add index IX_id_no(id_no)" --no-check-replication-filters --recursion-method=none --user=dba --password=123456 D=test,t=t1 --execute 对于MongoDB创立索引要在后盾创立,防止锁表。 应用范例: db.t1.createIndex({idCardNum:1},{background:1}) 4、所有线上业务库均必须搭建MHA高可用架构,防止单点问题。 5、给业务方开权限时,明码要用MD5加密,至多16位。权限如没有特殊要求,均为select查问权限,并做库表级限度。 6、删除默认空明码账号。 delete from mysql.user where user='' and password=''; flush privileges; 7、汇总库开启Audit审计日志性能,呈现问题时方可追溯。 行为规范 8、禁止一个MySQL实例寄存多个业务数据库,会造成业务耦合性过高,一旦呈现问题会殃及池鱼,减少了定位故障问题的难度。通常采纳多实例解决,一个实例一个业务库,互不烦扰。 9、禁止在主库上执行后盾治理和统计类的性能查问,这种简单类的SQL会造成CPU的升高,进而会影响业务。 10、批量荡涤数据,须要开发和DBA独特进行审查,应避开业务高峰期时段执行,并在执行过程中察看服务状态。 11、促销流动等应提前与DBA当面沟通,进行流量评估,比方提前一周减少机器内存或扩大架构,避免DB呈现性能瓶颈。 12、禁止在线上做数据库压力测试。 根本标准 13、禁止在数据库中存储明文明码。 14、应用InnoDB存储引擎。 反对事务,行级锁,更好的恢复性,高并发下性能更好。InnoDB表防止应用COUNT(*)操作,因外部没有计数器,须要一行一行累加计算,计数统计实时要求较强能够应用memcache或者Redis。*15、表字符集对立应用UTF8。 不会产生乱码危险。*16、所有表和字段都须要增加中文正文。 不便别人、不便本人。*17、不在数据库中存储图片、文件等大数据。 图片、文件更适宜于GFS分布式文件系统,数据库里寄存超链接即可。*18、防止应用存储过程、视图、触发器、事件。 MySQL是OLTP利用,最善于简略的增、删、改、查操作,但对逻辑计算剖析类的利用,并不适宜,所以这部分的需要最好通过程序上实现。 19、防止应用外键,外键用来爱护参照完整性,可在业务端实现。 外键会导致父表和子表之间耦合,非常影响SQL性能,呈现过多的锁期待,甚至会造成死锁。*20、对事务一致性要求不高的业务,如日志表等,优先选择存入MongoDB。 其本身反对的sharding分片性能,加强了横向扩大的能力,开发不必过多调整业务代码。*库表设计规范 21、表必须有主键,例如自增主键。 这样能够保证数据行是依照程序写入,对于SAS传统机械式硬盘写入性能更好,依据主键做关联查问的性能也会更好,并且还不便了数据仓库抽取数据。从性能的角度来说,应用UUID作为主键是个最不好的办法,它会使插入变得随机。*22、禁止应用分区表。 分区表的益处是对于开发来说,不必批改代码,通过后端DB的设置,比方对于工夫字段做拆分,就能够轻松实现表的拆分。但这外面波及一个问题,查问的字段必须是分区键,否则会遍历所有的分区表,并不会带来性能上的晋升。此外,分区表在物理构造上仍旧是一张表,此时咱们更改表构造,一样不会带来性能上的晋升。所以应采纳切表的模式做拆分,如程序上须要对历史数据做查问,可通过union all的形式关联查问。另外随着工夫的推移,历史数据表不再须要,只需在从库上dump进去,即便捷地迁徙至备份机上。字段设计规范 23、用DECIMAL代替FLOAT和DOUBLE存储准确浮点数。浮点数的毛病是会引起精度问题,请看上面一个例子: mysql> CREATE TABLE t3 (c1 float(10,2),c2 decimal(10,2)); Query OK, 0 rows affected (0.05 sec) ...

January 31, 2021 · 2 min · jiezi

你真的了解SQL吗SQL优化最佳实践作者带你重新了解SQL

一、SQL :一种熟悉又陌生的编程语言这里有几个关键词;“熟悉”、“陌生”、“编程语言”。 说它“熟悉”,是因为它是DBA和广大开发人员,操作数据库的主要手段,几乎每天都在使用。说它“陌生”,是很多人只是简单的使用它,至于它是怎么工作的?如何才能让它更高效的工作?却从来没有考虑过。 这里把SQL归结为一种“编程语言”,可能跟很多人对它的认知不同。让我们看看它的简单定义(以下内容摘自百度百科) 结构化查询语言(Structured Query Language),简称SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。结构化查询语言是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的不同数据库系统, 可以使用相同的结构化查询语言作为数据输入与管理的接口。结构化查询语言语句可以嵌套,这使它具有极大的灵活性和强大的功能。总结一句话,SQL是一种非过程化的的编程语言,可通过它去访问关系型数据库系统。 二、你真的了解“SQL”吗?下面我会通过一个小例子,看看大家是否真正了解SQL。 这是一个很简单的示例,是关于SQL语句执行顺序的。这里将一个普通的SELECT语句,拆分为三个子句。那么在实际的执行过程中,是按照什么顺序处理的呢?这里有A-F六个选项,大家可以思考选择一下… 最终的答案是D,即按照先执行FROM子句,然后WHERE子句,最后是SELECT部分。 针对上面的示例,让我们真实构造一个场景,通过查看执行计划看看是否按照我们选择的顺序执行的。关于执行计划的判读,我后面会专门谈到。这里我先解释一下整个执行过程。 第一步,是按照全表扫描的方式访问了对象表(EMP)。对应于语句中的FROM部分。第二步,是对提取出的结果集进行了过滤(filter部分),即将满足条件的记录筛选出来。对应于语句中的WHERE部分。第三步,是对满足条件的记录进行字段投射,即将需要显示的字段提取出来。对应于语句中的SELECT部分。 这是一个详细的SQL各部分执行顺序的说明。 通过对执行顺序的理解,可以为我们未来的优化工作带来很大帮助。一个很浅显的认识就是,优化动作越靠前越好。 三、SQL现在是否仍然重要?这里引入了一个新的问题,在现有阶段SQL语言是否还重要? 之所以引入这一话题,是因为随着NOSQL、NEWSQL、BIGDATA等技术逐步成熟推广,“SQL语言在现阶段已经变得不那么重要”成为一些人的观点。那实际情况又是如何呢? 让我们先来看一张经典的图。图中描述了传统SMP架构的关系型数据库、MPP架构的NEWSQL、MPP架构的NoSQL不同方案的适用场景对比。 从上面的“数据价值密度、实时性”来看,传统关系型数据库适合于价值密度更高、实时性要求更高的场景(这也就不难理解类似账户、金额类信息都是保存在传统关系型数据库中);MPP架构的NewSQL次之,MPP架构的NoSQL更适合于低价值、实时性要求不高的场景。 从下面的“数据规模”来看,传统关系型数据库适合保存的大小限制在TB级别,而后两者可在更大尺度上(PB、EB)级保存数据。 从下面的“典型场景”来看,传统关系型数据库适合于OLTP在线交易系统;MPP架构的NewSQL适合于OLAP在线分析系统;而NoSQL的使用场景较多(利于KV型需求、数据挖掘等均可以考虑)。 最后从“数据特征”来看,前两者适合于保存结构化数据,后者更适合于半结构化、乃至非结构化数据的保存。 归纳一下,不同技术有其各自特点,不存在谁代替谁的问题。传统关系型数据库有其自身鲜明特点,在某些场合依然是不二选择。而作为其主要交互语言,SQL必然长期存在发展下去。 我们再来对比一下传统数据库与大数据技术。从数据量、增长型、多样化、价值等维度对比两种技术,各自有其适用场景。 对于大数据领域而言,各种技术层出不穷。但对于广大使用者来说,往往会存在一定的使用门槛,因此现在的一种趋势就是在大数据领域也引入“类SQL”,以类似SQL的方式访问数据。这对于广大使用者来说,无疑大大降低了使用门槛。 解答一些疑问: NoSQL、NewSQL已经超越了传统数据库,SQL没有了用武之地! 各种技术有着各自适合的不同场景,不能一概而论。SQL语言作为关系型数据库的主要访问方式,依然有其用武之地。 以后都是云时代了,谁还用关系型数据库! 对于价值密度高,严格一致性的场景,仍然适合采用关系型数据库作为解决方案。 我编程都是用OR Mapping工具,从不需要写SQL! 的确,引入OR Mapping工具大大提高了生产效率,但是它的副作用也很明显,那就是对语句的运行效率失去了控制。很多低效的语句,往往是通过工具直接生成的。这也是为什么有的Mapping工具还提供了原始的SQL接口,用来保证关键语句的执行效率。 大数据时代,我们都用Hadoop、Spark了,不用写SQL啦! 无论是使用Hadoop、Spark都是可以通过编写程序完成数据分析的,但其生产效率往往很低。这也是为什么产生了Hive 、Spark SQL等“类SQL”的解决方案来提高生产效率。 数据库处理能力很强,不用太在意SQL性能! 的确,随着多核CPU、大内存、闪存等硬件技术的发展,数据库的处理能力较以前有了很大的增强。但是SQL的性能依然很重要。后面我们可以看到,一个简单SQL语句就可以轻易地搞垮一个数据库。 SQL优化,找DBA就行了,我就不用学了! SQL优化是DBA的职责范畴,但对于开发人员来讲,更应该对自己的代码负责。如果能在开发阶段就注重SQL质量,会避免很多低级问题。 我只是个运维DBA,SQL优化我不行! DBA的发展可分为“运维DBA->开发DBA->数据架构师…”。如果只能完成数据库的运维类工作,无疑是技能的欠缺,也是对各人未来发展不利。况且,随着Paas云的逐步推广,对于数据库的运维需求越来越少,对于优化、设计、架构的要求越来越多。因此,SQL优化是每个DBA必须掌握的技能。 现在优化有工具了,很简单的! 的确现在有些工具可以为我们减少些优化分析工作,会自动给出一些优化建议。但是,作为DBA来讲,不仅要知其然,还要知其所以然。况且,数据库优化器本身就是一个非常复杂的组件,很难做到完全无误的优化,这就需要人工的介入,分析。 优化不就是加索引嘛,这有啥! 的确,加索引是一个非常常用的优化手段,但其不是唯一的。且很多情况下,加了索引可能导致性能更差。后面,会有一个案例说明。 四、SQL仍然很重要! 我们通过一个示例,说明一下理解SQL运行原理仍然很重要。 这是我在生产环境碰到的一个真实案例。Oracle数据库环境,两个表做关联。执行计划触目惊心,优化器评估返回的数据量为3505T条记录,计划返回量127P字节,总成本9890G,返回时间999:59:59。 从执行计划中可见,两表关联使用了笛卡尔积的关联方式。我们知道笛卡尔连接是指在两表连接没有任何连接条件的情况。一般情况下应尽量避免笛卡尔积,除非某些特殊场合。否则再强大的数据库,也无法处理。这是一个典型的多表关联缺乏连接条件,导致笛卡尔积,引发性能问题的案例。 从案例本身来讲,并没有什么特别之处,不过是开发人员疏忽,导致了一条质量很差的SQL。但从更深层次来讲,这个案例可以给我们带来如下启示: 开发人员的一个疏忽,造成了严重的后果,原来数据库竟是如此的脆弱。需要对数据库保持一种"敬畏"之心。电脑不是人脑,它不知道你的需求是什么,只能用写好的逻辑进行处理。不要去责怪开发人员,谁都会犯错误,关键是如何从制度上保证不再发生类似的问题。五、SQL优化法则下面我们来看看常见的优化法则。这里所说的优化法则,其实是指可以从那些角度去考虑SQL优化的问题。可以有很多种方式去看待它。下面列举一二。 这里来自阿里-叶正盛的一篇博客里的一张图,相信很多人都看过。这里提出了经典的漏斗优化法则,高度是指我们投入的资源,宽度是指可能实现的收益。从图中可见,“减少数据访问”是投入资源最少,而收益较多的方式;“增加硬件资源”是相对投入资源最多,而收益较少的一种方式。受时间所限,这里不展开说明了。 这是我总结的一个优化法则,简称为“DoDo”法则。 第一条,“Do Less or not do!”翻译过来,就是尽量让数据库少做工作、甚至不做工作。 ...

July 11, 2019 · 1 min · jiezi

DBA职业发展之路去IOE等挑战之下DBA将何去何从

开篇随着近些年来,开源、自动化、云化的兴起,DBA职业也正悄然发生一些变化。经常有朋友咨询我,职业发展规划;特别是近期Oracle的大幅裁员之后,针对DBA这一职业未来该如何发展?本文是个人对此问题的一些看法,仅供各位参考! 数据是核心 将DBA单词分解一下。其对应的 操作对象:数据操作介质:库操作角色:管理员这里的核心是数据,也是DBA这一角色最大的价值所在。他们最了解数据、最懂得数据的价值;因此DBA后续可发展的一些方向,也基本是与数据有关。 此外,对于数据要有更加宏观的认识,无论是企业的自有数据,还是外部获得;无论是关系数据,还是其他模式数据;无论是保存在数据库中,还是其他诸如日志等介质中,数据对企业都非常有价值,要将数据作为一种"资产"来管理。只有上升到这样的高度,数据相关岗位的价值也就凸显出来。 阶段不同,侧重不同 企业对数据应用水平不同,因而造成工作重心及岗位需求也有所不同。下面简单描述下各个层次: 层次一,是以数据库维护为主,常见表现是"救火队员"型。很多初创企业,都经历过这一过程。数据库维护基本靠人,随着运维体量的增加,需要线性增加人员。整体数据应用水平,基本处于简单、粗放型。层次二,仍是以数据库维护为主,但已形成较为完善的运维体系。除了基础运维之外,甚至可以考虑一些预防性的措施,提高整体的运维效益。这一阶段的体系化建设,往往是通过文档、运维平台等沉淀下来。数据库作为基础设施层,已可提供较好的数据存储、计算能力输出。但此阶段尚未从更高角度去考虑数据问题,仍仅限于运维层面。层次三,数据设计应用阶段,企业已不满足数据简单的"存取类"需求,而是从更高的应用角度,考虑如何提高整体数据应用水平。这个阶段会增加数据库架构、设计,加强业务端数据优化工作。表现为增加产品DBA的角色,加大数据库架构权重等。层次四,数据架构治理阶段,企业不单从某个应用、某条业务线去考虑数据问题,而是公司整体层面做数据的顶层设计。考虑建立专门的机构(如数据委员会)或岗位-首席数据官(CDO)。近些年来,颇为火热的"数据中台",正是为迎合这一需求而产生的。基础运维工作,繁琐枯燥 作为基础类的运维工作,数据库的要求是比较高的。上图简单罗列了部分工作,对DBA日常繁琐工作可见一斑。正是基于这点,平台化、自动化、云化的诉求,不断被提出。进而间接对DBA的能力提出了更高的要求。 DBA职能,向上进化 基于前面数据应用水平所谈到的,企业内部DBA也对应承担了几类职能。自下而上的是数据物理架构、逻辑架构和业务架构。公司内应用水平高低,也决定了DBA各类工作的比例侧重不同。随着公司数据应用水平的不断提高,DBA工作重心也应从下层逐步转向中上层。 数据物理架构,对应为"运维DBA",工作重心为基础架构的建设。数据逻辑架构,对应为"产品DBA",工作重心为数据库架构、架构设计及SQL质量问题。数据业务架构,对应为"数据架构师-DA",工作重心在于数据治理、管理类工作。DBA面临冲击不断 近些年来,DBA职位受到很大一些冲击,我摘其重要的几项说明下。 去IOE,阿里最早提出"去IOE"的叫法。它的提出,让人们第一次领悟到,企业的核心应用是可以不依赖于传统的国外大型商业数据库,进而提出了一种新的解决思路。开源与商业,企业发展阶段不同,对于开源还是商业软件的使用存在类似上图的收益/成本曲线。当发展到一定阶段时,是必须要考虑引入开源。企业要从技术战略角度出发,考虑这一问题。"四化",数据库基础运维工作,经历了从手工、脚本、工具、平台的发展阶段。其发展特点表现为"四化"(平台化、可视化、自动化、智能化)。这一发展方向也对DBA的技能要求产生了一些变化,特别是对研发的技能要求已成为必要条件。云,是未来的发展方向。从全球范围来看,云生态的数据库占比在8%,未来预计在3~5年内,会提升到20%~30%。这无疑是巨大的飞跃。对于DBA而言,云环境下的数据库工作有别于传统环境,需要从多方面去适应,工作重心也要有所调整。技术 OR 管理 DBA职业发展,向上面临的第一个选择就是发展方向,是走管理路线还是技术路线。上图给大家描述了两种不同方向的区别,个人可根据自己特质,对号入座。这里要避免一个误区,就是"以管理为上",这其实就是官本位思想的体现。不是每个人都适合管理路线,放在不恰当的位置上,对人的发展是一种摧残。 客观判断,承认上限 在明确了发展路线之后,就需要对自身的发展阶段有所判断。无论是技术还是管理,都存在这样一个进化理论,即越走向高级阶段,其淘汰率越高。要客观、理性地认识到自己所处的阶段。从上述比例也可以看出,能走到高阶职位的毕竟是少数。虽然可以通过一些方式(后面会谈到)做突破,但是仍然有较大概率无法取得既定目标。此时,要勇于承认这一点,调整自己的职业定位,谋求新的发展方向。 高度与广度 + 全局思维 取得职业发展突破,有两个小的建议。 高度与广度。在职业发展初期,需要有个快速成长的"原始积累期"。这里谈到的原始积累,不是财富,而是技术技能。要在某专一领域,尽量达到自己的技术高点。会存在某个点,你已经无法突破达到更高的高度时,要谨慎分析原因。如确实非主观原因,那么要坦然接受它。剩下来的技术发展,可考虑横向发展,即将自己打造成"T字型"人才。上面谈到的高点很重要,它会决定你的技术"视野"。全局思维。即不要仅仅从技术角度考虑问题,特别是达到一定高度之后,可更多地尝试从业务角度、人的角度考虑之前面临的问题,也许你就会有新的发现。全局思维,会有助于你发现原有发展阶段的瓶颈点,实现突破。DBA职业选择路线 前面讲了很多,那么DBA职业发展可考虑哪些方向呢?下面试图给出一些可能的选择。以下仅仅是本人根据自己所熟悉的领域给出的选择,不代表全部。 选择:数据库技术、数据库业务 -数据库技术。这是一个比较容易的选择,即在某数据库领域里不断精进自己,以达到一个更高的目标。职业定位是首席DBA、DBA专家等。如果考虑这个发展方向,建议考虑乙方或云厂商,因为他们对技术本身要求更高。甲方角色,受限于自身环境,一般很难有需要不断突破的技术氛围。 数据库业务。将数据库技术与公司业务相结合,突出在某业务领域的数据能力。这是需要在某行业打磨多年,充分了解其业务特点,不断抽象出其数据要求。这一方向可考虑行业的头部公司或者是专为某行业服务的ISV。选择:内核研发、数据库架构 -数据库内核研发,是相对"小众"的一类人才需求,一般只有大型企业/云厂商或数据库厂商会考虑设置。其专业性较强,人员素质要求也较高。建议选择高起点的一些企业,对个人长期职业发展有利。 数据库架构师,这是一个相对综合类的职位。"架构"的含义比较模糊,各企业对架构师角色的定位也各不相同。一般能考虑设置数据库架构师角色的企业,都是有一定规模,企业内数据应用比较复杂的情况。下面根据我所在公司的实际场景,尝试给出一个数据库架构师的技能图谱,供各位参考。一家之言:数据库架构师技能图谱 上图罗列对数据库架构师本身要求的十二项基本能力要求,各项能力的要求不同,我通过左侧的饼图比例大小予以说明。当然能符合全部要求的人,少之又少。公司可根据侧重,有所取舍。上述技能要求,可大致分为四类: -数据自身技能,如数据库、大数据、数据治理、数仓等 关联领域技能,如基础设施、云、容器等研发方向技能,如DevOps等综合技能类,如业务思维、软技能(如沟通技巧)选择:数据架构、数据产品 -数据架构,不同于"数据库架构"。数据架构,更强调于顶层设计,需要对数据有全局的思维,帮助企业做好整体数据规划设计工作。它不在拘泥于某种技术,而是着眼于数据整合、安全、共享、价值、资产等问题。 数据产品,也是一种综合类职位。需要对技术本身有一定深入的了解,但更强调其技术广度。此外需要有产品化思维,能将业务需求,转换为产品功能设计。选择:解决方案架构、数据库布道者 -解决方案架构,往往是从"售前架构"、"技术顾问"等角色体现出来。其核心要点是具备一定技术能力的同时,还要有甲方思维,能够了解用户痛点,能从技术角度帮助客户解决现有问题。这里不光是销售自己的产品,更重要的是给客户带来价值。 数据库布道者,少数的选择,只针对有一定技术影响力的人员才可以考虑。是一种偏向于自由职业者的选择。选择:数据治理、数据仓库 -数据治理,是一项比较"浩大"的工程。随着企业对数据的重视程度越来越高,这一岗位也愈发重要起来。其强调几个关键过程域的活动,提升企业整体数据应用水平。右图中给出的DAMA的过程域图例,供大家参考。 数据仓库,是一个处于转型中的职位,传统的数仓做法,目前已不适应现代企业要求。但其核心的数据建模理论,还是具有指导意义的。因此各大互联网公司,均有自己颇有特色的数仓实践。可以考虑大厂或行业头部客户作为选择。选择:大数据、运维开发 -大数据,作为大"DBA"的范畴,大数据领域某种意义上将也是一种数据库。当然它有其自身的特殊性,表现为技术分散、变化快、没有统一标准、对研发能力有一定要求等。 DevOps,运维开发。适合有一定研发基础的DBA选择。选择:项目管理、技术管理 -项目管理,DBA是一个比较综合类的职位,在沟通、协调、组织方面,与项目管理有相似在之处。因此,可以考虑转型做项目管理类职位。 技术管理,DBA职位的涉及的技术领域较广,如稍加留意是可以涉猎很多关联领域。这与技术管理类对技能诉求,有一定相似。再加上其对软技能的要求,是可以考虑将技术管理作为发展方向。在圈子中也发现不过高级管理人员,都是DBA出身,不无一定道理。写在最后 面对一个充满不确定性的未来,唯一能确定的就是变化。让我们拥抱变化,努力改变今天的自己! 内容来源:韩锋老师于ACMUG沙龙(北京站)的分享,首发公众号-韩锋频道,欢迎关注。宜信技术学院

July 3, 2019 · 1 min · jiezi

解DBA之惑数据库承载能力评估及优化手段

作为DBA,有时会被挑战类似这样的问题: 如果现有业务规模增加10倍、100倍,数据库是否能够支撑?下个月我们搞大促,数据库这边没问题吧?计划进行去O工作,代码逻辑不变,数据库从Oracle切换到MySQL,MySQL能支撑业务吗?服务器采购选型,到底哪款服务器更适合我们呢?面对诸如上面的这些质疑,DBA应该如何面对? 身为DBA该如何评估现有资源使用情况? 如果现有数据库资源确实无法支撑,又该本着什么原则进行改造呢? 本文是针对上面问题的一些经验总结,供大家参考。 一、评估工作面对这样的问题,首先要进行评估工作,可遵循下面的步骤: 1、建立性能基线针对系统运行现状,建立性能基线。将业务指标与性能指标建立起对应关系。这里所说的性能指标包括CPU、MEM、DISK、NET等。在诸多资源中,肯定存在不均衡的情况,短板的资源最有可能成为业务增长后的瓶颈。在具体操作上,可首先确定一个业务高峰时间段,通过监控平台或监控工具收集系统各资源的使用情况。然后依据收集的信息,分析可能的性能短板在哪里。 对于DBA来说,对自己掌管系统的性能使用情况要了然于胸。通过对业务的了解,将业务指标映射到性能指标上,就可以很容易地推断出现有系统可承载的最大业务量。此外,对于可能影响承载业务增长的短板,也会有比较清晰的认识。 一般来说,数据库类的应用是重资源消耗类的应用。对CPU、MEM、DISK、NET等,均有较大的消耗。但由于不同硬件发展水平不均衡,各数据库资源消耗特点也不同,因此需要具体问题具体分析。 下面谈谈我对硬件发展及与数据库关系的一点个人观点: CPU相对于其他硬件而言,CPU技术发展较快。随着CPU主频提高及多核CPU技术的发展,CPU提供的计算能力往往不会成为系统的性能瓶颈。但我们需要注意的是,有些数据库是无法完全利用CPU的能力(例如MySQL就是这样)。此时,为了充分利用CPU的资源,可以考虑诸如"多实例混跑"的方案,提高CPU利用率。 MEM随着内存技术的发挥,内存的价格越来越便宜。现在我们在生产环境中,可以见到128、256GB,甚至TB级的内存也不罕见。一般来说,数据库通常会利用内存作为缓冲区,大内存的配置对数据库的性能有着比较明显的提升。此外,数据库自身技术也在适应着大内存的场景,通常采用的策略是划分子池。将管理的单位进一步细分,例如Oracle中的Sub Pool、MySQL中的多instance buffer pool。 NET随着GigE、10GbE、InfiniBand技术的飞速发展,低延迟、高带宽的服务品质给数据库乃至整个IT系统带来了很多变化。常见的应用领域有: 加速分布式数据库,例如Oracle RAC。加速大数据处理,例如提升Hadoop MapReduce处理。存储架构的变革,从Scale-Up向Scale-Out演变。容灾方案,主备策略…DISK相对于其他硬件技术发展而言,传统的机械式磁盘是相对而言发展最慢的,其往往也是最容易成为数据库的性能瓶颈。随着闪存技术的横空出世,为存储技术带来的一种变革。下面我们来看看主要性能指标的对比: 从上述指标来看,使用闪存技术后,存储能力大大提高,消除了系统最大的瓶颈。这也是为什么很多DBA都在不同场合,大力推荐使用闪存,其对于数据库性能的提升会带来质的飞跃。但与此同时,我们也应该注意到,传统关系型数据库是按照磁盘IO模型设计的,没有考虑到闪存技术,现在属于软件落后于硬件的阶段;相对而言,闪存技术对于非关系型模型更有优势。 很多基于传统设计的优化理论发生了变化,例如: 索引聚簇因子的问题。这一点是需要我们在考虑数据库优化时,主要注意的。此外,NoSQL的性能优势因为传统数据库结合闪存技术,而变得不明显。需要在架构选择时加以分析。 2、建立业务压力模型根据业务特征,建立业务压力模型。简单理解就是将业务模拟抽象出来,便于后面进行压力放大测试。要做到这一步,需要对业务有着充分的了解和评估。 下面通过一个小例子说明一下: 这个表格模拟了某个类电商的业务,其包含的主要模块及模块中的主要操作。针对不同的操作其交易复杂度不同 (交易复杂度可理解为执行SQL语句的个数)。根据不同的读写情况,区分是数据读还是数据写。在估算了业务总量(交易量)的情况下,很容易推算出数据操作的量。通过这种方式将业务压力模型转化为数据压力模型。此处的难点在于对业务逻辑的抽象能力及对模块业务量的比例评估。 有了上述概览的表格后,针对每一种业务操作,可细化其操作。最终将其抽象成SQL语句及对应的访问特征。其伪代码可描述为 可依据上述伪代码,编制压力测试代码。通过一些工具调用测试代码,产生模拟测试的压力。例如我经常使用的oradbtest/mydbtest(原阿里楼方鑫的一个测试工具)或sysbench等,都是不错的压力测试工具。 建议企业根据自身情况,整理出自己的业务压力模型。这在系统改造、升级、扩容评估、新硬件选型等多种场合都很有用处。它要比厂商提供的类似TPCC测试报告,更有意义。据我了解,很多规模较大的公司都有比较成熟的压力模型。 3、模拟压力测试要想考察现有数据库能否承载增长后的业务压力,最好的方式就是模拟压力测试。观察在近似真实的压力下,数据库的表现。重点观察,数据库的承载力变化、主要性能瓶颈等。通常可以有两种方式,一种是从真实环境导流(并可根据需要放大流量,可利用类似TCPCOPY等工具);一种是根据前面整理的业务压力模型,通过压力工具模拟压力。前者适用于已有项目的扩容评估、系统改造评估等,后者适用于新上项目原型方案评估、性能基准测试等场景。 上述模拟压力测试结果中,暴露出的性能瓶颈点,就是我们后面需要着重改进、优化的方向。 二、优化层次及步骤针对上面的评估结果,来确定后面的改进、优化方案。可遵循如下一些步骤: 1、分析瓶颈点根据上面的评测结果,分析性能瓶颈点。针对不同瓶颈点,可采取不同的一些策略。有时候性能测试时全流程的,对于一个复杂系统来说,要明确定位到性能瓶颈点比较困难。此时,可借助一些APM工具,量化整个访问路径,协助找到瓶颈。也可以类似上面的做法,做好抽象工作,只对数据库端施加压力,观察数据库行为,判读数据库是否为瓶颈。如判断就是数据库的承载能力不够,可按照不同层次进行考虑。 在整个评估数据库承载能力中,这一步骤是最复杂的、也是最难的一部分。要区分清楚是否是数据库承载能力不足,还是其他组件的问题。即使明确是数据库的问题,也要分清楚是整体or局部的问题;是单一业务功能慢,还是整体都比较慢;是偶尔会慢,还是一直都很慢等等。这些问题的界定有助于后面明确问题层次,采取不同的策略进行解决。 针对数据库承载能力不足,我将常见出现问题进行了层次划分,可简单分为语句级、对象级、数据库级、数据库架构级、应用架构级、业务架构级。不同层次采取的方式也有所不同,下面分别描述一下。 2、层次-语句级如性能核心问题,只是某条SQL语句的问题,可有针对性地进行优化。这种方式是侵入性比较小的一种优化方式,其影响范围也比较小。下面对比常见的语句级优化方法。说明一下,下面方法已经排除了诸如统计信息不准确等其他因素,仅从SQL语句本身优化方式考虑。 改写SQL通过改写语句,达到调整执行计划,提高运行效率的目的。这种方式的缺点是需要研发人员修改原代码,然后再进行部署上线的过程。此外,有些使用O/R Mapping工具产生的SQL,无法直接修改语句,也无法使用此方法。 使用Hint很多种数据库都提供了提示(Hint)的功能。通过这种方式来指定语句的执行过程。这种方式同样需要修改源代码,经历部署上线的过程。此外,这种修改方式还存在适应性较差的问题。因为其指定了特有的执行过程,随着数据规模、数据特征的变化,固化的执行过程可能不是最佳方式了。这种方式实际上是放弃了优化器可能产生的最优路径。 存储概要、SQL概要、计划基线在Oracle中还内置了一些功能,它们可以固化某一条语句的执行方式,从本质上来讲,其原理和上面使用Hint差不多。其缺点也类似上面。 调整参数有时也可通过调整某些参数,进而改变语句的执行计划。但是这种方式要注意适用范围,不要在全局使用,避免影响较多的语句。在会话级使用也要控制范围,避免产生较大影响。 3、层次-对象级如性能核心问题,在SQL层面无法解决,需要考虑对象层面的调整。这种情况要比较慎重,需要充分评估可能带来的风险及收益。一个对象的结构修改,可以涉及到数百条、甚至数千条和此相关语句的执行计划变更。如不做充分测试的情况下,很难保证不出问题。如果是Oracle数据库,可考虑使用SPA评估一下。其他数据库的话,可提前手工收集一下相关语句,模拟修改后重放上述语句,评估性能变化。 1)影响因素 在对象级进行调整,除了考虑对其他语句的性能影响外,还需要考虑其他因素。常见的以下这些: 数据库维护成本常见的例如索引。通过添加索引,往往可以起到加速查询的目的;但是增加索引,会导致数据DML成本的增加。 运维成本常见的例如全局分区索引。全局分区索引在进行分区维护动作后,会导致索引失效,需要自动或手动进行维护索引动作。 存储成本常见的索引,索引结构是数据库中真实占据空间的结构。在以往的一些案例中,甚至出现过索引总大小超过表大小的情况,因此新增时要评估其空间使用。 2)全生命周期管理 这里还有另外一个很重要的概念——“对象全生命周期管理”,简单来说就是对象的生老病死。在很多系统中,对象从新建开始,数据不断增加、膨胀,当数据规模达到一定量级后,各种性能问题就出现了。对一个百万级的表和亿万级的表,其查询性能肯定不能同日而语。因此,在对象设计初期,就要考虑相关的归档、清理、转储、压缩策略,将存储空间的评估与生命周期管理一起考虑。 很多性能问题,在做了数据清理后都迎刃而解。但数据清理往往是需要代价的,必须在设计之初就考虑这个问题。在做数据库评审的时候,除了常规的结构评审、语句评审外,也要考虑这部分因素。 4、层次-数据库级到了这个层面,问题往往已经比较严重了。一般情况下,数据库的初始配置都是基于其上面运行系统的负载类型进行专门配置的。如果运行一段时间后,出现性能问题,经评估是属于全局性问题的,可以考虑进行数据库级别的调整。但是这种配置往往代价也比较大,例如需要专门的停机窗口操作等。而且这种操作的风险性也比较大,有可能会带来很多不确定因素,因此要慎而又慎。 5、层次-数据库架构级如性能核心问题,无法在上述层面解决,可能就需要调整数据库架构。常见的例如采取读写分离的访问方式、分库分表存储方式等。这种对应用的侵入性很强了,有些情况下甚至不亚于重构整个系统。 例如,随着业务的发展,系统的数据量或访问量超出了预期,通过单一数据库无法满足空间或性能要求。此时,可能就需要考虑采用一种分库分表策略,来满足这部分的需求。但其改造难度,往往比重新开发一套系统还要大。 比如,我们可能需要一个数据中间层,来屏蔽后面的分库分表细节。这个中间层可能需要完成语句解析、访问路由、数据聚合、事务处理等一系列功能。即使使用了中间层产品,对于应用来说,数据库的功能也会相对“弱化”,应用级代码不得不进行很多的调整来适应这种变化。此外,如何把一个线上正在运行的系统,顺利平稳地迁移到新的结构下,这无疑又是一个给飞驰的跑车换轮胎的问题等等。 如果项目在运行中,出现了数据库架构级的调整,很有可能说明在前期项目设计规划阶段出现了失误,或者对项目的业务预期出现了偏差。因此,这两点一定在初始阶段进行充分的评估,并在设计上保留有充分的“弹性”。 6、层次-应用架构级有些情况下,单纯依靠数据库是无法解决的,需要综合考虑整个应用架构。在整个系统架构中,数据库往往处于系统的最末端,其扩展性是最差的。因此,在应用架构设计初期,就应该本着尽量不要对数据库产生压力的原则进行设计。或者即使有大的压力,系统可以采取自动降级等方式保证数据库的平稳运行。 常见的例如增加缓存、通过MQ实现削峰填谷等。通过增加缓存,可以大幅度减少对数据库的访问压力,提高整体系统的吞吐能力。引入MQ,则可以将对数据库的压力以“稳态”的形式,向数据库持续施压,而不至于被某个异常高峰压死。 7、层次-业务架构级最后一种情况是从业务角度进行一些调整。这往往是一种妥协,通过做适当的减法保证系统的整体运行。甚至不排除牺牲一部分用户体验等方式,来满足大部分用户的可用性。这就需要我们的架构师对系统能提供的能力要很清楚,对业务也要有充分的了解。对于承载什么样的业务,及为了承载业务所需要花费的代价成本有充分的认知,才可以做出一些取舍。 这里要避免一些误区,认为技术是“万能”的。技术可以解决一定的问题,但不能解决所有问题,或者解决所有问题的成本代价是难以接受的。这个时候,从业务角度稍作调整,就可以达到“退一步海阔天空”的结果。 拓展阅读:自制小工具大大加速MySQL SQL语句优化(附源码) 全面解析Oracle等待事件的分类、发现及优化 ...

June 27, 2019 · 1 min · jiezi

赋能社区PingCAP-University-培训课程-20-重磅升级

经过半年时间的持续打磨,PingCAP University 迎来了一次重大升级,发布「培训课程 2.0」。作为世界级的开源项目,经过四年的发展,TiDB 在越来越多的场景里落地,正逐渐被视为行业内的分布式数据库“事实标准”。随着用户社区技术服务体系的建立和优化,TiDB 社区力量日益壮大,在 GitHub 上已累计获得 Star 数近 2w,目前已有 300+  用户将 TiDB 用于线上生产环境,超过 1400 家进行测试 ,在互联网、银行、证券、高端制造、大型零售等行业均有广泛应用。这些成果的背后都离不开社区用户的积极反馈和社区开发者的贡献。 “我们十分珍视这份信任,将继续把「用户至上」的观念和理念发挥到极致,与用户一起成长,并进一步赋能社区,培养更多的一流 NewSQL 人才 ,打造高质量高活跃度的 TiDB 技术社区。这是我们开办 PingCAP University 的初衷。”PingCAP 联合创始人崔秋表示。 PingCAP 于 2018 年底正式成立 PingCAP University,开设的 TiDB DBA 官方认证培训课程于 2019 年 1 月正式落地。目前,首批线下培训已经开展 10 余期,得到了社区伙伴的广泛响应。培训开办半年以来 PingCAP University 在实践中保持与学员的沟通,持续打磨课程,近期正式推出升级后的 2.0 版本。在保留高密度干货、理论和实操相结合的一贯特点之外,本次升级有以下方面的优化: 课程内容扩展:2.0 课程增加了分布式事务原理、存储引擎内核原理、计算引擎内核原理、优化器深度解析等内容,整个课程深入浅出、更加完整和体系化;优化学习曲线:2.0 课程分为基础篇、高级进阶篇和扩展篇三个层次,层层递进,能满足不同层级的学员,从入门到进阶一次搞定;知其然,更知其所以然:2.0 课程不但教学员如何操作,还会讲解 TiDB 计算、存储、调度等底层架构原理,以及时下火热的云原生技术、混合数据库(HTAP),让学员们能从深度和广度更好地了解和使用 TiDB,深刻理解数据库发展的新趋势;理论实践两手抓:2.0 课程延续了 1.0 课程的设计,理论知识和实操课程并重。在实操课程,我们给每个学员配备了硬件环境,从安装部署升级、数据迁移、到跨机房多活高可用部署,老师都会全程通过 Demo show 的方式, 让学员们真正可以快速学以致用。PingCAP University  官方网校(https://university.pingcap.com/) 已正式上线,欢迎进入线上网校学习,免费线上基础课程有助于学员快速了解 TiDB 产品全貌。学员除了可以在线自主学习外,还可以在讲师集中答疑中深入交流,优秀学员还可享受线下培训的奖励计划。 ...

June 11, 2019 · 1 min · jiezi

PingCAP University 免费开放线上课程,快来点亮「TiDB DBA」技能点吧!

去年年底 我们启动了 PingCAP University 培训认证计划,获得了社区伙伴们的广泛响应。PingCAP University 已经开展五期线下培训,百余名学员在 PingCAP 北京&上海 Office 参加了为期 4 天的 PCTP 线下培训,大家表示干货密度相·当·高。 <center>线下培训部分学员合影</center> TiDB 社区的日益壮大,除了得益于所有开发者们的贡献,更离不开用户在使用过程中不断积极反馈的力量。随着 TiDB 应用场景的迅速扩展,我们听到了越来越多的用户在使用上的反馈,由此我们也建立了良性的用户社区技术服务体系。在为大家提供技术服务的同时我们也希望「授人以渔」,通过一套完整的官方技术培训课程,让更多的社区伙伴掌握 TiDB 部署、运维及调优等实操技能,提高自主响应和解决问题的速度,同时帮助社区伙伴们拓展技术前沿视野,迅速成长,壮大 TiDB 社区人才队伍。 接下来,我们将继续拓展 PingCAP University 培训认证计划的广度和深度,让更多社区伙伴有机会参与进来,与 TiDB 社区一起共同成长。今天先公开一个 “小惊喜” : PingCAP University 课程网站已正式上线,并全部免费开放,内容包括 TiDB 基础知识及架构、管理及使用,TiDB 生态工具架构及原理,以及 TiDB 行业实践。欢迎大家登录 https://university.pingcap.com/ 学习! 线下培训也在如火如荼的开展中,期待大家踊跃报名~线下培训强调实操技能的提升,包括 TiDB 集群搭建、性能调优及故障诊断、SQL 优化及业务开发实践、跨机房高可用与灾难恢复等内容。 (报名方式:邮件至 university-cn@pingcap.com 或直接联系您的客户总监) 通过 PingCAP University 的线上&线下培训及考核,我们希望可以帮助大家实现: 独立部署、运维和调优 TiDB 集群的能力,深入理解 TiDB 最佳实践。提升自身在分布式计算/存储领域的前沿技术视野。PingCAP 还将为通过考核认证的学员颁发「初级/高级 TiDB DBA」官方认证证书。 课程信息 温馨提示 :线上课程由大家自主安排学习,考试认证及线下培训报名请发邮件至 university-cn@pingcap.com 咨询或直接联系您的客户总监。 ...

April 22, 2019 · 1 min · jiezi

MySQL集群搭建(5)-MHA高可用架构

前面的文章介绍了怎么从单点开始搭建MySQL集群,列表如下MySQL 安装(二进制版)MySQL集群搭建(1)-主备搭建MySQL集群搭建(2)-主主从模式MySQL集群搭建(3)-MMM高可用架构MySQL集群搭建(4)-MMM+LVS+Keepalived今天说另一个常用的高可用方案: MHA1 概述1.1 MHA 简介MHA - Master High Availability 是由 Perl 实现的一款高可用程序,出现故障时,MHA 以最小的停机时间(通常10-30秒)执行 master 的故障转移以及 slave 的升级。MHA 可防止复制一致性问题,并且易于安装,不需要改变现有部署。MHA 由MHA manager和MHA node组成, MHA manager是一个监控管理程序,用于监控MySQL master状态; MHA node是具有故障转移的工具脚本,如解析 MySQL 二进制/中继日志,传输应用事件到Slave, MHA node在每个MySQL服务器上运行。出自 MHA WikiMHA manager调用MHA node工具脚本的方式是SSH到主机上然后执行命令,所以各节点需要做等效验证。1.2 MHA 怎么保证数据不丢失当Master宕机后,MHA会尝试保存宕机Master的二进制日志,然后自动判断MySQL集群中哪个实例的中继日志是最新的,并将有最新日志的实例的差异日志传到其他实例补齐,从而实现所有实例数据一致。然后把宕机Master的二进制日志应用到选定节点,并提升为 Master。具体流程如下:尝试从宕机Master中保存二进制日志找到含有最新中继日志的Slave把最新中继日志应用到其他实例,实现各实例数据一致应用从Master保存的二进制日志事件提升一个Slave为Master其他Slave向该新Master同步从切换流程流程可以看到,如果宕机Master主机无法SSH登录,那么第一步就没办法实现,对于MySQL5.5以前的版本,数据还是有丢失的风险。对于5.5后的版本,开启半同步复制后,真正有助于避免数据丢失,半同步复制保证至少一个 (不是所有)slave 在 master 提交时接收到二进制日志事件。因此,对于可以处理一致性问题的MHA 可以实现"几乎没有数据丢失"和"从属一致性"。1.3 MHA 优点和限制优点开源,用Perl编写方案成熟,故障切换时,MHA会做日志补齐操作,尽可能减少数据丢失,保证数据一部署不需要改变现有架构限制各个节点要打通SSH信任,有一定的安全隐患没有 Slave 的高可用自带的脚本不足,例如虚IP配置需要自己写命令或者依赖其他软件需要手动清理中继日志1.4 MHA 常用两种复制配置单 master,多 slave M(RW) |+——-+——-+S1(R) S2(R) S3(R)这种复制方式非常常见,当Master宕机时,MHA会选一个日志最新的主机升级为Master, 如果不希望个节点成为Master,把no_master设为1就可以。多 master, 多 slave M(RW)—-M2(R, candidate_master=1) |+——-+——-+S1(R) S2(R)双主结构也是常见的复制模式,如果当前Master崩溃, MHA会选择只读Master成为新的Master2 数据库环境准备本次演示使用复制方式是主主从,主主从数据库搭建方式参考以前文章2.1 节点信息IP系统端口MySQL版本节点读写说明10.0.0.247Centos6.533065.7.9Master读写主节点10.0.0.248Centos6.533065.7.9Standby只读,可切换为读写备主节点10.0.0.249Centos6.533065.7.9Slave只读从节点10.0.0.24Centos6.5–manager-MHA Manager10.0.0.237—–VIP2.2 架构图2.3 参考配置Master1[client]port = 3306default-character-set=utf8mb4socket = /data/mysql_db/test_db/mysql.sock[mysqld]datadir = /data/mysql_db/test_dbbasedir = /usr/local/mysql57tmpdir = /tmpsocket = /data/mysql_db/test_db/mysql.sockpid-file = /data/mysql_db/test_db/mysql.pidskip-external-locking = 1skip-name-resolve = 1port = 3306server_id = 2473306default-storage-engine = InnoDBcharacter-set-server = utf8mb4default_password_lifetime=0auto_increment_offset = 1auto_increment_increment = 2#### log ####log_timestamps=systemlog_bin = /data/mysql_log/test_db/mysql-binlog_bin_index = /data/mysql_log/test_db/mysql-bin.indexbinlog_format = rowrelay_log_recovery=ONrelay_log=/data/mysql_log/test_db/mysql-relay-binrelay_log_index=/data/mysql_log/test_db/mysql-relay-bin.indexlog_error = /data/mysql_log/test_db/mysql-error.log#### replication ####log_slave_updates = 1replicate_wild_ignore_table = information_schema.%,performance_schema.%,sys.%#### semi sync replication settings #####plugin_dir=/usr/local/mysql57/lib/pluginplugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"loose_rpl_semi_sync_master_enabled = 1loose_rpl_semi_sync_slave_enabled = 1Master2[client]port = 3306default-character-set=utf8mb4socket = /data/mysql_db/test_db/mysql.sock[mysqld]datadir = /data/mysql_db/test_dbbasedir = /usr/local/mysql57tmpdir = /tmpsocket = /data/mysql_db/test_db/mysql.sockpid-file = /data/mysql_db/test_db/mysql.pidskip-external-locking = 1skip-name-resolve = 1port = 3306server_id = 2483306default-storage-engine = InnoDBcharacter-set-server = utf8mb4default_password_lifetime=0auto_increment_offset = 2auto_increment_increment = 2#### log ####log_timestamps=systemlog_bin = /data/mysql_log/test_db/mysql-binlog_bin_index = /data/mysql_log/test_db/mysql-bin.indexbinlog_format = rowrelay_log_recovery=ONrelay_log=/data/mysql_log/test_db/mysql-relay-binrelay_log_index=/data/mysql_log/test_db/mysql-relay-bin.indexlog_error = /data/mysql_log/test_db/mysql-error.log#### replication ####log_slave_updates = 1replicate_wild_ignore_table = information_schema.%,performance_schema.%,sys.%#### semi sync replication settings #####plugin_dir=/usr/local/mysql57/lib/pluginplugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"loose_rpl_semi_sync_master_enabled = 1loose_rpl_semi_sync_slave_enabled = 1Slave[client]port = 3306default-character-set=utf8mb4socket = /data/mysql_db/test_db/mysql.sock[mysqld]datadir = /data/mysql_db/test_dbbasedir = /usr/local/mysql57tmpdir = /tmpsocket = /data/mysql_db/test_db/mysql.sockpid-file = /data/mysql_db/test_db/mysql.pidskip-external-locking = 1skip-name-resolve = 1port = 3306server_id = 2493306default-storage-engine = InnoDBcharacter-set-server = utf8mb4default_password_lifetime=0read_only=1#### log ####log_timestamps=systemlog_bin = /data/mysql_log/test_db/mysql-binlog_bin_index = /data/mysql_log/test_db/mysql-bin.indexbinlog_format = rowrelay_log_recovery=ONrelay_log=/data/mysql_log/test_db/mysql-relay-binrelay_log_index=/data/mysql_log/test_db/mysql-relay-bin.indexlog_error = /data/mysql_log/test_db/mysql-error.log#### replication ####log_slave_updates = 1replicate_wild_ignore_table = information_schema.%,performance_schema.%,sys.%#### semi sync replication settings #####plugin_dir=/usr/local/mysql57/lib/pluginplugin_load = “rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"loose_rpl_semi_sync_master_enabled = 1loose_rpl_semi_sync_slave_enabled = 13 安装配置 MHA3.1 下载 MHA进入 MHA 下载页面 Downloads, 下载Manager和Node节点安装包,由于我的服务器是centos6,所以下载了MHA Manager 0.56 rpm RHEL6和MHA Node 0.56 rpm RHEL63.2 安装 MHANode安装在所有主机(包括Manager)上执行# 安装依赖yum install perl perl-devel perl-DBD-MySQL# 安装 node 工具rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpmManager安装在 Manager 主机上执行# 安装依赖yum install -y perl perl-devel perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes# 安装 managerrpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpmMHA Installation3.3 创建 MHA 管理用户管理用户需要执行一些数据库管理命令包括STOP SLAVE, CHANGE MASTER, RESET SLAVEcreate user mha_manager@’%’ identified by ‘mha_manager’;grant all on . to mha_manager@’%’;flush privileges;3.4 增加 MySQL 用户 sudo 权限配置 VIP 需要有 sudo 权限打开/etc/sudoers文件, 增加一条root ALL=(ALL) ALL# 这个是增加的mysql ALL=(ALL) NOPASSWD: ALL然后把Defaults requiretty注释掉# Defaults requiretty3.5 配置各主机免密码登陆所有主机执行# 进入 mysql 用户su - mysql# 生成密钥对, 执行命令,然后按回车ssh-keygen -t rsa# 复制公钥到相应主机ssh-copy-id mysql@10.0.0.247ssh-copy-id mysql@10.0.0.248ssh-copy-id mysql@10.0.0.249ssh-copy-id mysql@10.0.1.243.6 配置 Manager新建/etc/masterha目录,我们把配置文件放到这里mkdir /etc/masterha创建配置文件/etc/masterha/app1.cnf, 写上配置[server default]manager_workdir=/etc/masterha # 设置 manager 的工作目录, 可以自己调整manager_log=/etc/masterha/manager.log # 设置 manager 的日志文件master_binlog_dir=/data/mysql_log/test_db # 设置 master binlog 的日志的位置master_ip_failover_script= /etc/masterha/script/master_ip_failover # 设置自动 failover 时的切换脚本, 脚本参考附件master_ip_online_change_script= /etc/masterha/script/master_ip_online_change # 设置手动切换时执行的切换脚本, 脚本参考附件user=mha_manager # 设置管理用户, 用来监控、配置 MySQL(STOP SLAVE, CHANGE MASTER, RESET SLAVE), 默认为 rootpassword=mha_manager # 设置管理用户密码repl_user=repl # 设置复制环境中的复制用户名repl_password=repl # 设置复制用户的密码ping_interval=1 # 发送 ping 包的时间间隔,三次没有回应就自动进行 failoverremote_workdir=/tmp # 设置远端 MySQL 的工作目录report_script=/etc/masterha/script/send_report # 设置发生切换后执行的脚本# 检查脚本secondary_check_script= /usr/bin/masterha_secondary_check-s 10.0.0.247 -s 10.0.0.248 shutdown_script=”” #设置故障发生后关闭故障主机脚本(可以用于防止脑裂)ssh_user=mysql #设置 ssh 的登录用户名[server1]hostname=10.0.0.247port=3306[server2]hostname=10.0.0.248port=3306candidate_master=1 # 设置为候选 master, 如果发生宕机切换,会把该节点设为新 Master,即使它不是数据最新的节点check_repl_delay=0 # 默认情况下,一个 Slave 落后 Master 100M 的中继日志,MHA 不会选择它作为新的 Master,因为这对于 Slave 恢复数据要很长时间,check_repl_delay=0 的时候会忽略延迟,可以和 candidate_master=1 配合用[server3]hostname=10.0.0.249port=3306no_master=1 # 从不将这台主机升级为 Masterignore_fail=1 # 默认情况下,如果有 Slave 节点挂了, 就不进行切换,设置 ignore_fail=1 可以忽然它创建配置文件/etc/masterha/app2.cnf, 以备用Master 为 Master, 方便切换后启动MHA[server default]manager_workdir=/etc/masterha # 设置 manager 的工作目录, 可以自己调整manager_log=/etc/masterha/manager.log # 设置 manager 的日志文件master_binlog_dir=/data/mysql_log/test_db # 设置 master binlog 的日志的位置master_ip_failover_script= /etc/masterha/script/master_ip_failover # 设置自动 failover 时的切换脚本master_ip_online_change_script= /etc/masterha/script/master_ip_online_change # 设置手动切换时执行的切换脚本user=mha_manager # 设置管理用户, 用来监控、配置 MySQL(STOP SLAVE, CHANGE MASTER, RESET SLAVE), 默认为 rootpassword=mha_manager # 设置管理用户密码repl_user=repl # 设置复制环境中的复制用户名repl_password=repl # 设置复制用户的密码ping_interval=1 # 发送 ping 包的时间间隔,三次没有回应就自动进行 failoverremote_workdir=/tmp # 设置远端 MySQL 的工作目录report_script=/etc/masterha/script/send_report # 设置发生切换后执行的脚本# 检查脚本secondary_check_script= /usr/bin/masterha_secondary_check -s 10.0.0.248 -s 10.0.0.247shutdown_script=”" #设置故障发生后关闭故障主机脚本(可以用于防止脑裂)ssh_user=mysql #设置 ssh 的登录用户名[server1]hostname=10.0.0.248port=3306[server2]hostname=10.0.0.247port=3306candidate_master=1 # 设置为候选 master, 如果发生宕机切换,会把该节点设为新 Master,即使它不是数据最新的节点check_repl_delay=0 # 默认情况下,一个 Slave 落后 Master 100M 的中继日志,MHA 不会选择它作为新的 Master,因为这对于 Slave 恢复数据要很长时间,check_repl_delay=0 的时候会忽略延迟,可以和 candidate_master=1 配合用[server3]hostname=10.0.0.249port=3306no_master=1 # 从不将这台主机升级为 Masterignore_fail=1 # 默认情况下,如果有 Slave 节点挂了, 就不进行切换,设置 ignore_fail=1 可以忽然它注意:使用的时候去掉注释3.7 配置切换脚本管理 VIP 方式MHA管理VIP有两种方案,一种是使用Keepalived,另一种是自己写命令实现增删VIP,由于Keepalived容易受到网络波动造成VIP切换,而且无法在多实例机器上使用,所以建议写脚本管理VIP。当前主机的网卡是eth0, 可以通过下列命令增删 VIPup VIPsudo /sbin/ifconfig eth0:1 10.0.0.237 netmask 255.255.255.255down VIPsudo /sbin/ifconfig eth0:1 down配置切换脚本master_ip_failover , master_ip_online_change和send_report脚本在附录里面更改 mysql 配置MHA的检测比较严格,所以我们把除Master外的节点设为read_only, 有必要可以写进配置文件里面# mysql shellset global read_only=1;MHA需要使用中继日志来实现数据一致性,所以所有节点要设置不自动清理中继日志# mysql shellset global relay_log_purge=0;也可以写入配置文件# my.cnfrelay_log_purge=0MHA 常用命令Managermasterha_check_ssh 检查 MHA 的 SSH 配置状况 masterha_check_repl 检查 MySQL 复制状况masterha_manger 启动 MHAmasterha_stop 停止 MHAmasterha_check_status 检测当前 MHA 运行状态masterha_master_monitor 检测 master 是否宕机masterha_master_switch 手动故障转移masterha_conf_host 添加或删除配置的 server 信息Nodesave_binary_logs 保存 master 的二进制日志apply_diff_relay_logs 对比识别中继日志的差异部分purge_relay_logs 清除中继日志(MHA中继日志需要使用这个命令清除)命令的使用方法可以通过执行命令 –help 得到验证 SSH 是否成功、主从状态是否正常在 manager 节点执行 masterha_check_ssh –conf=/etc/masterha/app1.cnf 检测SSH状态,下面是执行结果[mysql@chengqm ~]$ masterha_check_ssh –conf=/etc/masterha/app1.cnfThu Dec 20 19:47:18 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.Thu Dec 20 19:47:18 2018 - [info] Reading application default configuration from /etc/masterha/app1.cnf..Thu Dec 20 19:47:18 2018 - [info] Reading server configuration from /etc/masterha/app1.cnf..Thu Dec 20 19:47:18 2018 - [info] Starting SSH connection tests..Thu Dec 20 19:47:19 2018 - [debug] Thu Dec 20 19:47:18 2018 - [debug] Connecting via SSH from mysql@10.0.0.247(10.0.0.247:22) to mysql@10.0.0.248(10.0.0.248:22)..Thu Dec 20 19:47:19 2018 - [debug] ok.Thu Dec 20 19:47:19 2018 - [debug] Connecting via SSH from mysql@10.0.0.247(10.0.0.247:22) to mysql@10.0.0.249(10.0.0.249:22)..Thu Dec 20 19:47:19 2018 - [debug] ok.Thu Dec 20 19:47:19 2018 - [debug] Thu Dec 20 19:47:19 2018 - [debug] Connecting via SSH from mysql@10.0.0.248(10.0.0.248:22) to mysql@10.0.0.247(10.0.0.247:22)..Thu Dec 20 19:47:19 2018 - [debug] ok.Thu Dec 20 19:47:19 2018 - [debug] Connecting via SSH from mysql@10.0.0.248(10.0.0.248:22) to mysql@10.0.0.249(10.0.0.249:22)..Thu Dec 20 19:47:19 2018 - [debug] ok.Thu Dec 20 19:47:20 2018 - [debug] Thu Dec 20 19:47:19 2018 - [debug] Connecting via SSH from mysql@10.0.0.249(10.0.0.249:22) to mysql@10.0.0.247(10.0.0.247:22)..Thu Dec 20 19:47:20 2018 - [debug] ok.Thu Dec 20 19:47:20 2018 - [debug] Connecting via SSH from mysql@10.0.0.249(10.0.0.249:22) to mysql@10.0.0.248(10.0.0.248:22)..Thu Dec 20 19:47:20 2018 - [debug] ok.Thu Dec 20 19:47:20 2018 - [info] All SSH connection tests passed successfully.在 manager 节点执行 masterha_check_repl –conf=/etc/masterha/app1.cnf 检测同步状态,下面是执行结果[mysql@chengqm ~]$ masterha_check_repl –conf=/etc/masterha/app1.cnfThu Dec 20 20:05:03 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.Thu Dec 20 20:05:03 2018 - [info] Reading application default configuration from /etc/masterha/app1.cnf..Thu Dec 20 20:05:03 2018 - [info] Reading server configuration from /etc/masterha/app1.cnf..Thu Dec 20 20:05:03 2018 - [info] MHA::MasterMonitor version 0.56.Thu Dec 20 20:05:03 2018 - [info] Multi-master configuration is detected. Current primary(writable) master is 10.0.0.247(10.0.0.247:3306)Thu Dec 20 20:05:03 2018 - [info] Master configurations are as below: Master 10.0.0.247(10.0.0.247:3306), replicating from 10.0.0.248(10.0.0.248:3306)Master 10.0.0.248(10.0.0.248:3306), replicating from 10.0.0.247(10.0.0.247:3306), read-only================ 省略 ==================Thu Dec 20 20:05:08 2018 - [info] /etc/masterha/script/master_ip_failover –command=status –ssh_user=mysql –orig_master_host=10.0.0.247 –orig_master_ip=10.0.0.247 –orig_master_port=3306 Thu Dec 20 20:05:08 2018 - [info] OK.Thu Dec 20 20:05:08 2018 - [warning] shutdown_script is not defined.Thu Dec 20 20:05:08 2018 - [info] Got exit code 0 (Not master dead).MySQL Replication Health is OK.出现 MySQL Replication Health is OK. 表示成功如果出现Failed to get master_ip_failover_script status with return code 255:0这个错误,就注释掉master_ip_failover脚本的FIXME_xxx注意:要想正常运行,系统路径必须要有 mysqlbinlog 和 mysql 命令4 启动和测试4.1 启动使用脚本管理 VIP 不会自动设置 VIP,所以先手动在 Master 设置 VIP[root@cluster01 ~]# /sbin/ifconfig eth0:1 10.0.0.237 netmask 255.255.255.255[root@cluster01 ~]# ifconfigeth0 Link encap:Ethernet HWaddr FA:16:3E:DE:80:33 inet addr:10.0.0.247 Bcast:10.0.255.255 Mask:255.255.0.0 inet6 addr: fe80::f816:3eff:fede:8033/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:17333247 errors:0 dropped:0 overruns:0 frame:0 TX packets:5472004 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1476157398 (1.3 GiB) TX bytes:1064253754 (1014.9 MiB)eth0:1 Link encap:Ethernet HWaddr FA:16:3E:DE:80:33 inet addr:10.0.0.237 Bcast:10.0.0.237 Mask:255.255.255.255 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1…启动 MHA Manager[mysql@chengqm ~]$ nohup /usr/bin/masterha_manager –conf=/etc/masterha/app1.cnf –ignore_last_failover &[1] 21668–ignore_last_failover 忽略上次切换。MHA每次故障切换后都会生成一个app1.failover.complete这样的文件,如果不加这个参数,需要删除这个文件才能再次启动检查启动日志[mysql@chengqm ~]$ tail -18 /etc/masterha/manager.log Fri Dec 21 13:56:39 2018 - [info] 10.0.0.247(10.0.0.247:3306) (current master) +–10.0.0.248(10.0.0.248:3306) +–10.0.0.249(10.0.0.249:3306)Fri Dec 21 13:56:39 2018 - [info] Checking master_ip_failover_script status:Fri Dec 21 13:56:39 2018 - [info] /etc/masterha/script/master_ip_failover –command=status –ssh_user=mysql –orig_master_host=10.0.0.247 –orig_master_ip=10.0.0.247 –orig_master_port=3306 VIP Command: start=sudo /sbin/ifconfig eth0:1 10.0.0.237 netmask 255.255.255.255 stop=sudo /sbin/ifconfig eth0:1 downCheck script.. OK Fri Dec 21 13:56:39 2018 - [info] OK.Fri Dec 21 13:56:39 2018 - [warning] shutdown_script is not defined.Fri Dec 21 13:56:39 2018 - [info] Set master ping interval 1 seconds.Fri Dec 21 13:56:39 2018 - [info] Set secondary check script: /usr/bin/masterha_secondary_check -s 10.0.0.247 -s 10.0.0.248Fri Dec 21 13:56:39 2018 - [info] Starting ping health check on 10.0.0.247(10.0.0.247:3306)..Fri Dec 21 13:56:39 2018 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn’t respond..日志中显示 Ping(SELECT) succeeded, waiting until MySQL doesn’t respond 表示启动成功如果查看Master的general日志,会发现MHA不断执行SELECT 1 As Value检查命令4.2 失效转移我们模拟Master数据库宕机的情况[root@cluster01 ~]# ps -ef | grep mysqlmysql 20061 1 0 11:19 pts/0 00:00:00 /bin/sh /usr/local/mysql57/bin/mysqld_safe –defaults-file=/data/mysql_db/test_db/my.cnf –datadir=/data/mysql_db/test_db –pid-file=/data/mysql_db/test_db/mysql.pidmysql 20494 20061 0 11:19 pts/0 00:00:21 /usr/local/mysql57/bin/mysqld –defaults-file=/data/mysql_db/test_db/my.cnf –basedir=/usr/local/mysql57 –datadir=/data/mysql_db/test_db –plugin-dir=/usr/local/mysql57/lib/plugin –log-error=/data/mysql_log/test_db/mysql-error.log –pid-file=/data/mysql_db/test_db/mysql.pid –socket=/data/mysql_db/test_db/mysql.sock –port=3306[root@cluster01 ~]# kill -9 20061 20494查看MHA日志可以看到整个切换过程Fri Dec 21 14:04:49 2018 - [warning] Got error on MySQL select ping: 2006 (MySQL server has gone away)Fri Dec 21 14:04:49 2018 - [info] Executing secondary network check script: /usr/bin/masterha_secondary_check -s 10.0.0.247 -s 10.0.0.248 –user=mysql –master_host=10.0.0.247 –master_ip=10.0.0.247 –master_port=3306 –master_user=mha_manager –master_password=mha_manager –ping_type=SELECTFri Dec 21 14:04:49 2018 - [info] Executing SSH check script: save_binary_logs –command=test –start_pos=4 –binlog_dir=/data/mysql_log/test_db –output_file=/tmp/save_binary_logs_test –manager_version=0.56 –binlog_prefix=mysql-binMonitoring server 10.0.0.247 is reachable, Master is not reachable from 10.0.0.247. OK.Fri Dec 21 14:04:49 2018 - [info] HealthCheck: SSH to 10.0.0.247 is reachable.Monitoring server 10.0.0.248 is reachable, Master is not reachable from 10.0.0.248. OK.Fri Dec 21 14:04:49 2018 - [info] Master is not reachable from all other monitoring servers. Failover should start.=============== 省略 ================Fri Dec 21 14:04:52 2018 - [info] Forcing shutdown so that applications never connect to the current master..Fri Dec 21 14:04:52 2018 - [info] Executing master IP deactivation script:Fri Dec 21 14:04:52 2018 - [info] /etc/masterha/script/master_ip_failover –orig_master_host=10.0.0.247 –orig_master_ip=10.0.0.247 –orig_master_port=3306 –command=stopssh –ssh_user=mysql VIP Command: start=sudo /sbin/ifconfig eth0:1 10.0.0.237 netmask 255.255.255.255 stop=sudo /sbin/ifconfig eth0:1 downDisabling the VIP on old master: 10.0.0.247 SIOCSIFFLAGS: Cannot assign requested addressFri Dec 21 14:04:52 2018 - [info] done.=============== 省略 ================Fri Dec 21 14:04:53 2018 - [info] Starting master failover..Fri Dec 21 14:04:53 2018 - [info] From:10.0.0.247(10.0.0.247:3306) (current master) +–10.0.0.248(10.0.0.248:3306) +–10.0.0.249(10.0.0.249:3306)To:10.0.0.248(10.0.0.248:3306) (new master) +–10.0.0.249(10.0.0.249:3306)Fri Dec 21 14:04:53 2018 - [info]=============== 省略 ================Fri Dec 21 14:04:53 2018 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST=‘10.0.0.248’, MASTER_PORT=3306, MASTER_LOG_FILE=‘mysql-bin.000005’, MASTER_LOG_POS=154, MASTER_USER=‘repl’, MASTER_PASSWORD=‘xxx’;Fri Dec 21 14:04:53 2018 - [info] Executing master IP activate script:Fri Dec 21 14:04:53 2018 - [info] /etc/masterha/script/master_ip_failover –command=start –ssh_user=mysql –orig_master_host=10.0.0.247 –orig_master_ip=10.0.0.247 –orig_master_port=3306 –new_master_host=10.0.0.248 –new_master_ip=10.0.0.248 –new_master_port=3306 –new_master_user=‘mha_manager’ –new_master_password=‘mha_manager’ VIP Command: start=sudo /sbin/ifconfig eth0:1 10.0.0.237 netmask 255.255.255.255 stop=sudo /sbin/ifconfig eth0:1 downSet read_only=0 on the new master.Enabling the VIP - 10.0.0.237 on the new master - 10.0.0.248 =============== 省略 ================Fri Dec 21 14:04:55 2018 - [info] 10.0.0.248: Resetting slave info succeeded.Fri Dec 21 14:04:55 2018 - [info] Master failover to 10.0.0.248(10.0.0.248:3306) completed successfully.查看新Master VIP[mysql@cluster02 ]$ ifconfigeth0 Link encap:Ethernet HWaddr FA:16:3E:66:7E:E8 inet addr:10.0.0.248 Bcast:10.0.255.255 Mask:255.255.0.0 inet6 addr: fe80::f816:3eff:fe66:7ee8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:40197173 errors:0 dropped:0 overruns:0 frame:0 TX packets:10470689 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:4063358126 (3.7 GiB) TX bytes:2269241789 (2.1 GiB)eth0:1 Link encap:Ethernet HWaddr FA:16:3E:66:7E:E8 inet addr:10.0.0.237 Bcast:10.0.0.237 Mask:255.255.255.255 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1可以看到VIP已经成功切换查看新Master的general日志,可以看到MHA的操作过程, 下面展示部分日志…2018-12-21T14:04:41.782336+08:00 5525 Query SHOW SLAVE STATUS2018-12-21T14:04:41.788318+08:00 5525 Query STOP SLAVE IO_THREAD2018-12-21T14:04:41.900734+08:00 5525 Query SHOW SLAVE STATUS2018-12-21T14:04:42.044801+08:00 5525 Query SHOW SLAVE STATUS2018-12-21T14:04:42.668581+08:00 5525 Query SHOW SLAVE STATUS2018-12-21T14:04:42.670336+08:00 5525 Query STOP SLAVE SQL_THREAD…2018-12-21T14:04:42.863904+08:00 5526 Query SET GLOBAL read_only=0…2018-12-21T14:04:43.950986+08:00 5527 Query SET @rpl_semi_sync_slave= 1…查看Slave的general日志,可以看到Slave会重新指向2018-12-21T14:04:04.835218+08:00 90 Query STOP SLAVE IO_THREAD2018-12-21T14:04:04.955706+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:05.092123+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.018838+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.034225+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.036613+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.038475+08:00 90 Query STOP SLAVE SQL_THREAD2018-12-21T14:04:06.160142+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.162224+08:00 90 Query STOP SLAVE2018-12-21T14:04:06.163171+08:00 90 Query SHOW SLAVE STATUS2018-12-21T14:04:06.164554+08:00 90 Query RESET SLAVE2018-12-21T14:04:06.825564+08:00 90 Query CHANGE MASTER TO MASTER_HOST = ‘10.0.0.248’ MASTER_USER = ‘repl’ MASTER_PASSWORD = <secret> MASTER_PORT = 3306 MASTER_LOG_FILE = ‘mysql-bin.000005’ MASTER_LOG_POS = 1542018-12-21T14:04:06.981718+08:00 90 Query SET GLOBAL relay_log_purge=02018-12-21T14:04:06.982802+08:00 90 Query START SLAVE注意: MHA在切换完成后会结束 Manager 进程4.3 手动切换切换后Master为Cluster2, 把Cluster1重新指向Cluster2,现在测试一下手动切换,把Master切回Cluster1, 命令如下masterha_master_switch –conf=/etc/masterha/app2.cnf –master_state=alive –new_master_host=10.0.0.247 –new_master_port=3306 –orig_master_is_new_slave–orig_master_is_new_slave 是将原master切换为新主的slave,默认情况下,是不添加的。下面是执行过程, 有两个地方要回答 yes/no[mysql@chengqm ]$ masterha_master_switch –conf=/etc/masterha/app2.cnf –master_state=alive –new_master_host=10.0.0.247 –new_master_port=3306 –orig_master_is_new_slave……It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before switching. Is it ok to execute on 10.0.0.248(10.0.0.248:3306)? (YES/no): yes……Sun Dec 23 16:50:48 2018 - [info] From:10.0.0.248(10.0.0.248:3306) (current master) +–10.0.0.247(10.0.0.247:3306) +–10.0.0.249(10.0.0.249:3306)To:10.0.0.247(10.0.0.247:3306) (new master) +–10.0.0.249(10.0.0.249:3306) +–10.0.0.248(10.0.0.248:3306)Starting master switch from 10.0.0.248(10.0.0.248:3306) to 10.0.0.247(10.0.0.247:3306)? (yes/NO): yes……Sun Dec 23 16:51:36 2018 - [info] 10.0.0.247: Resetting slave info succeeded.Sun Dec 23 16:51:36 2018 - [info] Switching master to 10.0.0.247(10.0.0.247:3306) completed successfully.切换成功,查看Cluster1的VIP[mysql@cluster01 ]$ ifconfigeth0 Link encap:Ethernet HWaddr FA:16:3E:DE:80:33 inet addr:10.0.0.247 Bcast:10.0.255.255 Mask:255.255.0.0 inet6 addr: fe80::f816:3eff:fede:8033/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:20585872 errors:0 dropped:0 overruns:0 frame:0 TX packets:5519122 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:1785787985 (1.6 GiB) TX bytes:1068115408 (1018.6 MiB)eth0:1 Link encap:Ethernet HWaddr FA:16:3E:DE:80:33 inet addr:10.0.0.237 Bcast:10.0.0.237 Mask:255.255.255.255 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1注意:手动切换的时候先把 MHA Manager 停了4.4 停止 MHA停止 MHA 的命令如下,就不演示了masterha_stop –conf=配置文件5 总结总的来说,MHA是一套非常优秀而且使用比较广的高可用程序,它可以自动补齐日志使得一致性有保证,部署的时候不需要改变原有架构就可以使用。但是使用起来还是有一点复杂的,因为MHA不接管VIP,所以要自己写脚本实现,而且只保证Master高可用,没有Slave高可用,还有就是中继日志要自己设定时任务来清理。不管怎么说,在没有更好的方案下,MHA还是值得使用的。附master_ip_failover 脚本#!/usr/bin/env perluse strict;use warnings FATAL => ‘all’;use Getopt::Long;use MHA::DBHelper;my ( $command, $ssh_user, $orig_master_host, $orig_master_ip, $orig_master_port, $new_master_host, $new_master_ip, $new_master_port, $new_master_user, $new_master_password);my $vip = ‘10.0.0.237’;my $key = ‘1’;my $ssh_start_vip = “sudo /sbin/ifconfig eth0:$key $vip netmask 255.255.255.255”;my $ssh_stop_vip = “sudo /sbin/ifconfig eth0:$key down”;GetOptions( ‘command=s’ => $command, ‘ssh_user=s’ => $ssh_user, ‘orig_master_host=s’ => $orig_master_host, ‘orig_master_ip=s’ => $orig_master_ip, ‘orig_master_port=i’ => $orig_master_port, ’new_master_host=s’ => $new_master_host, ’new_master_ip=s’ => $new_master_ip, ’new_master_port=i’ => $new_master_port, ’new_master_user=s’ => $new_master_user, ’new_master_password=s’ => $new_master_password,);exit &main();sub main { print “\n\n VIP Command: start=$ssh_start_vip stop=$ssh_stop_vip\n\n”; if ( $command eq “stop” || $command eq “stopssh” ) { # $orig_master_host, $orig_master_ip, $orig_master_port are passed. # If you manage master ip address at global catalog database, # invalidate orig_master_ip here. my $exit_code = 1; eval { print “Disabling the VIP on old master: $orig_master_host \n”; &stop_vip(); # updating global catalog, etc $exit_code = 0; }; if ($@) { warn “Got Error: $@\n”; exit $exit_code; } exit $exit_code; } elsif ( $command eq “start” ) { # all arguments are passed. # If you manage master ip address at global catalog database, # activate new_master_ip here. # You can also grant write access (create user, set read_only=0, etc) here. my $exit_code = 10; eval { my $new_master_handler = new MHA::DBHelper(); # args: hostname, port, user, password, raise_error_or_not $new_master_handler->connect( $new_master_ip, $new_master_port, $new_master_user, $new_master_password, 1 ); ## Set read_only=0 on the new master $new_master_handler->disable_log_bin_local(); print “Set read_only=0 on the new master.\n”; $new_master_handler->disable_read_only(); $new_master_handler->disconnect(); print “Enabling the VIP - $vip on the new master - $new_master_host \n”; &start_vip(); $exit_code = 0; }; if ($@) { warn $@; # If you want to continue failover, exit 10. exit $exit_code; } exit $exit_code; } elsif ( $command eq “status” ) { print “Check script.. OK \n”; # do nothing exit 0; } else { &usage(); exit 1; }}sub start_vip() { ssh $ssh_user\@$new_master_host \" $ssh_start_vip \";}sub stop_vip() { return 0 unless ($ssh_user); ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \";}sub usage { print"Usage: master_ip_failover –command=start|stop|stopssh|status –orig_master_host=host –orig_master_ip=ip –orig_master_port=port –new_master_host=host –new_master_ip=ip –new_master_port=port\n";}master_ip_online_change 脚本#!/usr/bin/env perl# Copyright (C) 2011 DeNA Co.,Ltd.## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc.,# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA## Note: This is a sample script and is not complete. Modify the script based on your environment.use strict;use warnings FATAL => ‘all’;use Getopt::Long;use MHA::DBHelper;use MHA::NodeUtil;use Time::HiRes qw( sleep gettimeofday tv_interval );use Data::Dumper;my $_tstart;my $_running_interval = 0.1;my ( $command, $orig_master_is_new_slave, $orig_master_host, $orig_master_ip, $orig_master_port, $orig_master_user, $orig_master_password, $orig_master_ssh_user, $new_master_host, $new_master_ip, $new_master_port, $new_master_user, $new_master_password, $new_master_ssh_user);GetOptions( ‘command=s’ => $command, ‘orig_master_is_new_slave’ => $orig_master_is_new_slave, ‘orig_master_host=s’ => $orig_master_host, ‘orig_master_ip=s’ => $orig_master_ip, ‘orig_master_port=i’ => $orig_master_port, ‘orig_master_user=s’ => $orig_master_user, ‘orig_master_password=s’ => $orig_master_password, ‘orig_master_ssh_user=s’ => $orig_master_ssh_user, ’new_master_host=s’ => $new_master_host, ’new_master_ip=s’ => $new_master_ip, ’new_master_port=i’ => $new_master_port, ’new_master_user=s’ => $new_master_user, ’new_master_password=s’ => $new_master_password, ’new_master_ssh_user=s’ => $new_master_ssh_user,);my $vip = ‘10.0.0.237’;my $key = ‘1’;my $ssh_start_vip = “sudo /sbin/ifconfig eth0:$key $vip netmask 255.255.255.255”;my $ssh_stop_vip = “sudo /sbin/ifconfig eth0:$key down”;exit &main();sub current_time_us { my ( $sec, $microsec ) = gettimeofday(); my $curdate = localtime($sec); return $curdate . " " . sprintf( “%06d”, $microsec );}sub sleep_until { my $elapsed = tv_interval($_tstart); if ( $_running_interval > $elapsed ) { sleep( $_running_interval - $elapsed ); }}sub get_threads_util { my $dbh = shift; my $my_connection_id = shift; my $running_time_threshold = shift; my $type = shift; $running_time_threshold = 0 unless ($running_time_threshold); $type = 0 unless ($type); my @threads; my $sth = $dbh->prepare(“SHOW PROCESSLIST”); $sth->execute(); while ( my $ref = $sth->fetchrow_hashref() ) { my $id = $ref->{Id}; my $user = $ref->{User}; my $host = $ref->{Host}; my $command = $ref->{Command}; my $state = $ref->{State}; my $query_time = $ref->{Time}; my $info = $ref->{Info}; $info = s/^\s*(.?)\s$/$1/ if defined($info); next if ( $my_connection_id == $id ); next if ( defined($query_time) && $query_time < $running_time_threshold ); next if ( defined($command) && $command eq “Binlog Dump” ); next if ( defined($user) && $user eq “system user” ); next if ( defined($command) && $command eq “Sleep” && defined($query_time) && $query_time >= 1 ); if ( $type >= 1 ) { next if ( defined($command) && $command eq “Sleep” ); next if ( defined($command) && $command eq “Connect” ); } if ( $type >= 2 ) { next if ( defined($info) && $info = m/^select/i ); next if ( defined($info) && $info = m/^show/i ); } push @threads, $ref; } return @threads;}sub main { if ( $command eq “stop” ) { ## Gracefully killing connections on the current master # 1. Set read_only= 1 on the new master # 2. DROP USER so that no app user can establish new connections # 3. Set read_only= 1 on the current master # 4. Kill current queries # * Any database access failure will result in script die. my $exit_code = 1; eval { ## Setting read_only=1 on the new master (to avoid accident) my $new_master_handler = new MHA::DBHelper(); # args: hostname, port, user, password, raise_error(die_on_error)_or_not $new_master_handler->connect( $new_master_ip, $new_master_port, $new_master_user, $new_master_password, 1 ); print current_time_us() . " Set read_only on the new master.. “; $new_master_handler->enable_read_only(); if ( $new_master_handler->is_read_only() ) { print “ok.\n”; } else { die “Failed!\n”; } $new_master_handler->disconnect(); # Connecting to the orig master, die if any database error happens my $orig_master_handler = new MHA::DBHelper(); $orig_master_handler->connect( $orig_master_ip, $orig_master_port, $orig_master_user, $orig_master_password, 1 ); $orig_master_handler->disable_log_bin_local(); ## Waiting for N * 100 milliseconds so that current connections can exit my $time_until_read_only = 15; $tstart = [gettimeofday]; my @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} ); while ( $time_until_read_only > 0 && $#threads >= 0 ) { if ( $time_until_read_only % 5 == 0 ) { printf”%s Waiting all running %d threads are disconnected.. (max %d milliseconds)\n", current_time_us(), $#threads + 1, $time_until_read_only * 100; if ( $#threads < 5 ) { print Data::Dumper->new( [$] )->Indent(0)->Terse(1)->Dump . “\n” foreach (@threads); } } sleep_until(); $tstart = [gettimeofday]; $time_until_read_only–; @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} ); } ## Setting read_only=1 on the current master so that nobody(except SUPER) can write print current_time_us() . " Set read_only=1 on the orig master.. “; $orig_master_handler->enable_read_only(); if ( $orig_master_handler->is_read_only() ) { print “ok.\n”; } else { die “Failed!\n”; } ## Waiting for M * 100 milliseconds so that current update queries can complete my $time_until_kill_threads = 5; @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} ); while ( $time_until_kill_threads > 0 && $#threads >= 0 ) { if ( $time_until_kill_threads % 5 == 0 ) { printf”%s Waiting all running %d queries are disconnected.. (max %d milliseconds)\n", current_time_us(), $#threads + 1, $time_until_kill_threads * 100; if ( $#threads < 5 ) { print Data::Dumper->new( [$] )->Indent(0)->Terse(1)->Dump . “\n” foreach (@threads); } } sleep_until(); $_tstart = [gettimeofday]; $time_until_kill_threads–; @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} ); } ## Terminating all threads print current_time_us() . " Killing all application threads..\n"; $orig_master_handler->kill_threads(@threads) if ( $#threads >= 0 ); print current_time_us() . " done.\n"; $orig_master_handler->enable_log_bin_local(); $orig_master_handler->disconnect(); print “Disabling the VIP on old master: $orig_master_host \n”; &stop_vip(); ## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK $exit_code = 0; }; if ($@) { warn “Got Error: $@\n”; exit $exit_code; } exit $exit_code; } elsif ( $command eq “start” ) { ## Activating master ip on the new master # 1. Create app user with write privileges # 2. Moving backup script if needed # 3. Register new master’s ip to the catalog database# We don’t return error even though activating updatable accounts/ip failed so that we don’t interrupt slaves’ recovery.# If exit code is 0 or 10, MHA does not abort my $exit_code = 10; eval { my $new_master_handler = new MHA::DBHelper(); # args: hostname, port, user, password, raise_error_or_not $new_master_handler->connect( $new_master_ip, $new_master_port, $new_master_user, $new_master_password, 1 ); ## Set read_only=0 on the new master $new_master_handler->disable_log_bin_local(); print current_time_us() . " Set read_only=0 on the new master.\n"; $new_master_handler->disable_read_only(); $new_master_handler->enable_log_bin_local(); $new_master_handler->disconnect(); print “Enabling the VIP - $vip on the new master - $new_master_host \n”; &start_vip(); ## Update master ip on the catalog database, etc $exit_code = 0; }; if ($@) { warn “Got Error: $@\n”; exit $exit_code; } exit $exit_code; } elsif ( $command eq “status” ) { # do nothing exit 0; } else { &usage(); exit 1; }}sub start_vip() { return 0 unless ($new_master_ssh_user); ssh $new_master_ssh_user\@$new_master_host \" $ssh_start_vip \";}sub stop_vip() { return 0 unless ($orig_master_ssh_user); ssh $orig_master_ssh_user\@$orig_master_host \" $ssh_stop_vip \";}sub usage { print"Usage: master_ip_online_change –command=start|stop|status –orig_master_host=host –orig_master_ip=ip –orig_master_port=port –new_master_host=host –new_master_ip=ip –new_master_port=port\n"; die;}send_report 脚本#!/usr/bin/perluse strict;use warnings FATAL => ‘all’;use Getopt::Long;#new_master_host and new_slave_hosts are set only when recovering master succeededmy ( $dead_master_host, $new_master_host, $new_slave_hosts, $subject, $body, $title, $content);GetOptions( ‘orig_master_host=s’ => $dead_master_host, ’new_master_host=s’ => $new_master_host, ’new_slave_hosts=s’ => $new_slave_hosts, ‘subject=s’ => $subject, ‘body=s’ => $body,);# 调用外部脚本$title="[mha switch]";$content="date +'%Y-%m-%d %H:%M' old_master=".$dead_master_host." new_master=".$new_master_host;system(“sh /etc/masterha/script/send_report.sh $title $content”);exit 0;清理中继日志定时任务下面是我的定时任务,参数自行替换, workdir 需要和中继日志在同一个盘# 每小时清理一次0 * * * * (/usr/bin/purge_relay_logs –user=mha_manager –password=mha_manager –disable_relay_log_purge –port=3306 –workdir=/tmp/relaylogtmp >> /var/log/purge_relay_logs.log 2>&1)MHA Wiki: https://github.com/yoshinorim… ...

December 23, 2018 · 16 min · jiezi