数据库

解决MySQL主从复制错误1595:Relay log write failure…

先交代下背景:我这边正在研究基于Docker的MariaDB Galera Cluster的自动化集群部署方案【以下简称MGC,后续有时间可以考虑分享下这个方案】,已经完成所有调试,想在生产环境部署一个MGC集群作为从先灰度测试。 生产环境主DB版本为MySQL5.5,新的MGC采用Mariadb最新10.3.12 stable版本,做好MGC集群,并导入一份从主DBdump出来的完整SQL之后,change master 开始创建主从,结果如下报错: 查了下资料,都是是磁盘满导致的,但是我这边磁盘空间、权限都没问题,于是继续检查了下MGC节点日志如下: 里面有一个关键信息:binlog_checksum failed,看来报错和这个有关系了。查了下资料,应该是Mariadb默认打开了 slave_sql_verify_checksum(MySQL版本默认关闭),而主从版本又不一致,导致checksum失败。 解决办法也很简单,在MGC各节点的配置中加上:slave_sql_verify_checksum=0 ,关闭这个特性即可,具体有没有负面影响暂未深入研究。
阅读全文
数据库

MySQL在线DDL修改表结构的简单经验分享

在线DDL修改生产环境的大表一直是运维、DBA一个很头痛的问题,本文分享一些相关经验,希望对还在头痛的同学能有所帮助,当然更希望路过的大神,如果有更靠谱的方案能够指点一二,不吝赐教。
阅读全文
数据库

gh-ost:在线DDL修改MySQL表结构工具

在之前,我分享过一次pt-online-schema-change在线DDL的工具实践记录,在实际使用过程中,发现部门的很多老系统大量使用了触发器,从而无法使用这个工具,非常遗憾!导致很多DDL变更都必须压到空闲时候做,比如凌晨,非常苦逼。 咨询了做DBA的老同事,他将gh-ost推荐给我,基于golang语言,是github开源的一个DDL工具,gh-ost是gitHub,s Online Schema Transmogrifier/Transfigurator/Transformer/Thingy的缩写,意思是GitHub的在线表定义转换器。============  分割线之间内容摘自网络  ============ gh-ost有如下特点: 无触发器 轻量级 可暂停 动态可控 可审计 可测试 可靠 无触发器gh-ost不使用触发器,它跟踪二进制日志文件,在对原始表的修改提交之后,用异步方式把这修改内容应用到临时表中去。 gh-ost希望二进制文件使用基于行的日志格式,但这并不表示如果主库上使用的是基于语句的日志格式,就不能用它来在线修改表定义了。事实上,我们常用的方式是用一个从库把日志的语句模式转成行模式,再从这个从库上去读日志。搭一个这样的从库并不复杂。 轻量级 因为不需要使用触发器,gh-ost把修改表定义的负载和正常的业务负载解耦开了。它不需要考虑被修改的表上的并发操作和竞争等,这些在二进制日志中都被序列化了,gh-ost只操作临时表,完全与原始表不相干。事实上,gh-ost也把行拷贝的写操作与二进制日志的写操作序列化了,这样,对主库来说只是有一条连接在顺序的向临时表中不断写入数据,这样的行为与常见的ETL相当不同。 可暂停 因为所有写操作都是gh-ost生成的,而读取二进制文件本身就是一个异步操作,所以在暂停时,gh-ost是完全可以把所有对主库的写操作全都暂停的。暂停就意味着对主库没有写入和更新。不过gh-ost也有一张内部状态跟踪表,即使在暂停状态下也会向那张表中不断写入心跳信息,写入量可以忽略不计。 gh-ost提供了比简单的暂停更多的功能,除了暂停之外还可以做: 负载:与pt-online-schema-change相近的一个功能,用户可以设置MySQL指标的阈值,比如设置Threads_running=30。 复制延迟:gh-ost内置了心跳功能来检查复制延迟。用户可以指定查看哪个从库的延迟,gh-ost默认是直接查看它连上的那个从库。 命令:用户可以写一些命令,根据输出结果来决定要不要开始操作。比如:SELECT HOUR(NOW()) BETWEEN 8 and 17. 上述所有指标即使在修改表定义的过程中也可以动态修改。 标志位文件:生成一个标志位文件,gh-ost就会立刻暂停。删除文件,gh-ost又会恢复工作。 用户命令:通过网络连上gh-ost,通过命令让它暂停。 动态可控如果别的工具在修改过程中产生了比较高的负载,DBA只好把它停掉再修改配置,比如把一次拷贝的数据量改小些,然后再从头开始修改过程。这样的反复操作代价非常大。 gh-ost通过监听TCP或者unix socket文件来获取命令。即使有正在进行中的修改工作,用户也可以向gh-ost发出命令修改配置,比如可以这样做: echo throttle | socat - /tmp/gh-ost.sock:这是暂停命令。也可以输入no-throttle 修改运行参数,gh-ost可以接受这样的修改方式来改变它的行为:chunk-size=1500, max-lag-millis=2000, max-load=Thread_running=30 可审计用上面所说的相同接口也可以查看gh-ost的状态,查看当前任务进度、主要配置参数、相关MySQL实例的情况等。这些信息通过网络发送命令就可以得到,因此就给了运维人员极大的灵活性,如果是使用别的工具的话一般只能是通过共享屏幕或者不断跟踪日志文件最新内容。 可测试 读取二进制文件内容的操作完全不会增加主库的负载,在从库上做修改表结构的操作也和在主库上做是非常相象的(当然并不完全一样,但主要来说还是差不多的)。 gh-ost自带了--test-on-replica选项来支持测试功能,它允许你在从库上运行起修改表结构操作,在操作结束时会暂停主从复制,让两张表都处于同步、就绪状态,然后切换表、再切换回来。这样就可以让用户从容不迫地对两张表进行检查和对比。 我们在GitHub是这样在生产环境测试gh-ost的:我们有许多个指定的生产从库,在上面不提供服务,只是周而复始地不断地把所有表定义都改来改去。对于我们生产环境地每一张表,小到空表,大到几百GB,都会通过修改存储引擎的方式来进行修改(engine=innodb),这样并不会真正修改表结构。在每一次这样的修改操作最后我们都会停掉主从复制,再把原始表和临时表的全量数据都各做一次校验和,然后比较两个校验和,要求它们是一致的。然后我们恢复主从复制,再继续测试下一张表。我们生产环境的每一张表都这样用gh-ost在从库上做过好多次修改测试。 可靠的 所有上述讲到的和没讲到的内容,都是为了让你对gh-ost的能力建立信任。毕竟,大家在做这件事的时候已经使用类似工具做了好多年,而gh-ost只是一个新工具。 我们在从库上对gh-ost进行测试,在去主库上做第一次真正改动之前我们在从库上成功地试了几千次。所以,请你也在从库上开始测试,验证数据是完好无损的,然后再把它用到生产环境。我们希望你可以放手去试。 当你执行了gh-ost之后,也许你会看见主库的负载变高了,那你可以发出暂停命令。用echo throttle命令生成一个文件,看看主库的负载会不会又变得正常。试一下这些命令,你就可以知道你可以怎样控制它的行为,你的心里就会安定许多。 你发起了一次修改操作,然后估计完成时间是凌晨2点钟,可是你又非常关心最后的切换操作,非常想看着它切换,这可怎么办?只需要一个标志位文件就可以告诉gh-ost推迟切换了,这样gh-ost会只做完拷贝数据的操作,但不会切换表。它还会仍然继续同步数据,保持临时表的数据处于同步状态。等第二天早上你回到办公室之后,删除标志位文件或者向gh-ost发送命令echo unpostpone,它就会做切换了。我们不希望软件强迫我们看着它做事情,它应该把我们解放出来,让人去做人该做的事。 谈到估计完成时间,--exact-rowcount选项非常有用。在最开始时要在目标表上做个代价比较大的SELECT COUNT(*)操作查出具体要拷多少行数据,gh-ost就会对它要做多少工作有了一个比较准确的估计。接下来在拷贝的过程中,它会不断地尝试更新这个估计值。因为预计完成的时间点总是会不断变化,所以已经完成的百分比就反而比较精确。如果你也曾经有过非常痛苦的经历,看着已经完成99%了可是剩下的一点操作却继续了一个小时也没完,你就会非常喜欢我们提供的这个功能。 gh-ost工作模式【要着重看】gh-ost工作时可以连上多个MySQL实例,同时也把自己以从库的方式连上其中一个实例来获取二进制日志事件。根据你的配置、数据库集群架构和你想在哪里执行修改操作,可以有许多种不同的工作模式。 模式一、连上从库,在主库上修改 这是gh-ost默认的工作模式,它会查看从库情况,找到集群的主库并且连接上去。修改操作的具体步骤是: 在主库上读写行数据; 在从库上读取二进制日志事件,将变更应用到主库上; 在从库上查看表格式、字段、主键、总行数等; 在从库上读取gh-ost内部事件日志(比如心跳); 在主库上完成表切换; 如果主库的二进制日志格式是Statement,就可以使用这种模式。但从库就必须配成启用二进制日志(log_bin, log_slave_updates),还要设成Row格式(binlog_format=ROW),实际上gh-ost会在从库上帮你做这些设置。 事实上,即使把从库改成Row格式,这仍然是对主库侵入最少的工作模式。 模式二、直接在主库上修改 如果没有从库,或者不想在从库上操作,那直接用主库也是可以的。gh-ost就会在主库上直接做所有的操作。仍然可以在上面查看主从复制延迟。 主库必须产生Row格式的二进制日志; 启动gh-ost时必须用--allow-on-master选项来开启这种模式; 模式三、在从库上修改和测试 这种模式会在从库上做修改。gh-ost仍然会连上主库,但所有操作都是在从库上做的,不会对主库产生任何影响。在操作过程中,gh-ost也会不时地暂停,以便从库的数据可以保持最新。 --migrate-on-replica选项让gh-ost直接在从库上修改表。最终的切换过程也是在从库正常复制的状态下完成的。 --test-on-replica表明操作只是为了测试目的。在进行最终的切换操作之前,复制会被停止。原始表和临时表会相互切换,再切换回来,最终相当于原始表没被动过。主从复制暂停的状态下,你可以检查和对比这两张表中的数据。 三种模式各有优缺点,但我只关心缺点:先说模式一的缺点,模式一会在从DB上面读取binlog,可能造成数据库主从数据不一致,原因因为是主库的binlog没有完全在从库执行。所以个人感觉模式一有丢失数据的风险。 模式二任何操作都会在主库操作,或多或少会对主库负载造成影响,但是可以通过调整一些参数降低和时刻关注这些影响,所以个人推荐使用模式二。 至于模式三是偏向测试用的,这里不做过多介绍,但是模式三里有一个细节,cut-over阶段有会stop slave一个操作,其实这个操作风险特别高,有时stop slave 时间会很长,务必会对线上数据库使用造成影响,所以如果使用模式三做测试也要在线下数据库。 gh-ost在GitHub的应用现在GitHub生产环境的表修改操作全都是用gh-ost完成的。每天只要有需求来了,就将它运行起来,有时候一天会做好多次。因为它有审计和控制功能,所以我们还可以把它和我们的Chatops系统整合起来。技术人员可以对它的工作进度有非常清晰的了解,因此可以控制它的行为。在生产环境中各种指标和事件都被收集起来,让大家可以以图形化的方式看到操作情况。 ============  分割线之间内容摘自网络  ============ 下面分享gh-ost的测试使用: 1、下载程序 一直都非常喜欢go语言编写的程序,原因很单纯,大部分情况都是一个二进制就能解决问题了,无任何依赖,简直是IT界的一股清流! 从github发布地址下载最新的binary包:https://github.com/github/gh-ost/releases 解压后就一个 gh-ost 二进制文件,再次献上我坚实的膝盖。 2、常用参数 --max-load 执行过程中,gh-ost会时刻关注负载情况,负载阀值是使用者自己定义,比如数据库的最大连接数,如果超过阀值,gh-ost不会退出,会等待到负载在阀值以下继续执行。 --critical-load 这个指的是gh-ost退出阀值,当负载超过这个阀值,gh-ost会停止并退出 --chunk-size 迁移过程是一步步分批次完成的,这个参数是指事务每次提交的行数,默认是1000。 --max-lag-millis 会监控从库的主从延迟情况,如果延迟秒数超过这个阀值,迁移不会退出,等待延迟秒数低于这个阀值继续迁移。...
阅读全文
数据库

Linux系统下MongoDB的简单安装与基本操作

Mongo DB ,是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式,备受当前IT从业人员的青睐。Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB中 每一条记录都是一个Document对象。Mongo DB最大的优势在于所有的数据持久操作都无需开发人员手动编写SQL语句,直接调用方法就可以轻松的实现CRUD操作。 一、下载mongodb 前往mongodb官网下载页面:https://www.mongodb.org/downloads下载相应的版本,比如目前的Linux x64位最新版:mongodb-linux-x86_64-2.6.4.tgz 不过有点坑爹是,下载链接明明是tgz格式,结果下载后变成了gz格式: 先下载看看好了。 二、解压mongodb 得到的是mongodb-linux-x86_64-2.6.4,居然是个文件,而不是文件夹,和网上说的大相径庭: 看来前面下载的确实存在问题!实际上应该是tgz文件才对,按经验分析了一下,下载的实际上还是tgz文件,显示为gz文件只是形式上的假象!所以,gzip只解压了压缩包的外层,实际上还需要解压一层tar存档属性! 于是,先将解压后的文件重命名加上tar格式: 然后,使用tar解压即可: 将解压后的文件夹移动&重命名至/usr/local/mongodb bin下的mongod就是MongoDB的服务端进程,mongo就是其客户端,其它的命令用于MongoDB的其它用途如MongoDB文件导出等。 三、启动mongodb 启动前,先指定mongodb的data目录,如果没有就创建一个: 然后,执行如下命令即可启动mongodb:   启动成功后,可查看是否启动成功了,默认端口号是27017,当然在启动时也可以指定未使用的其它端口。 最后,将客户端mogo文件在/bin下软链接,方便随处执行:   现在使用mongo客户端访问一下该数据库: 安装成功! 四、附:基本操作 参考文章①:http://blog.csdn.net/ssyan/article/details/6927307 参考文章②:http://blog.chinaunix.net/uid-26558059-id-3211264.html
阅读全文
解决Tomcat数据连接池无法释放 WEB应用

解决Tomcat数据连接池无法释放

近段时间,公司的检测中心报表系统(SMC)的开发人员时不时找到我,说用户老是出现无法登录的情况。前些日子因为手头上有Jboss集群的测试工作,发现用户不能登录时,都是在Tomcat中将这个项目Reload一下就好了,不过只是治标而已,因为大概几个小时之后又会再次出现无法登录的情况。 今天上午,开发人员小毛又找到我,要我协助将这个问题根治一下,拖太久用户难保不投诉。 简单分析了一下,每次Reload一下就能解决无法登录的情况,自然而然就想到是不是session有问题呢?于是到Tomcat的manager界面看了下,发现并没有出现session粘滞暴涨的情况。 本来可以打开jconsole看看的,正好想起了之前用过的Tomcat检测工具:probe,于是直接从其他机器上scp了一个probe.war,丢到了webapps下面自动部署。 部署完之后,打开了probe网页管理后台发现smc项目的实时数据库连接数很高,而且只增不减!这个系统的数据池大小设置为200,此时已经是100+了,而且一直只升不降。好吧,当数据连接数达到200时,问题肯定会再次出现的。 于是我将这个问题告诉了小毛,要他自己去修改连接池释放机制(这里用的是项目单独设定的参数)。他说试过了,没有用,问下我有没有办法。 我这人记性一直欠佳,也很少去记忆一些参数设置,问我么?还我也只能问BD、GG了。。。 最终在强大的搜索引擎的帮助下,找到了相关参数说明,通过参考修改后成功解决了问题! Tomcat连接池无法释放的解决方法: 编辑项目的连接池配置文件:context.xml,参考下面的【数据库连接设置】参数说明,按照实际情况调整好各项数值,尤其是Maxidle和maxActive。并记得加上removeAbandoned=true 相关释放参数即可,我们这最终设置好的context.xml如下所示: 数据库连接设置参考: 附上作者的原文说明: 在配置DBCP连接池时,主要难以理解的主要有:removeAbandoned 、logAbandoned、removeAbandonedTimeout、maxWait这四个参数,设置了rmoveAbandoned=true那么在getNumActive()快要到getMaxActive()的时候,系统会进行无效的Connection的回收,回收的Connection为removeAbandonedTimeout(默认300秒)中设置的秒数后没有使用的Connection,激活回收机制好像是getNumActive()=getMaxActive()-2。 如果开启"removeAbandoned",那么连接在被认为泄露时可能被池回收. 这个机制在(getNumIdle() < 2) and (getNumActive() > getMaxActive() - 3)时被触发. 举例:当maxActive=20, 活动连接为18,空闲连接为1时可以触发"removeAbandoned".但是活动连接只有在没有被使用的时间超过"removeAbandonedTimeout"时才被删除,默认300秒.在resultset中游历不被计算为被使用. logAbandoned=true的话,将会在回收事件后,在log中打印出回收Connection的错误信息,包括在哪个地方用了Connection却忘记关闭了,在调试的时候很有用。 在这里私人建议maxWait的时间不要设得太长,maxWait如果设置太长那么客户端会等待很久才激发回收事件。 通过仁兄的资料,加深了我对连接池参数的理解,非常感谢!特附上原文地址:DBCP连接池配置参数说明及优化 ,以示尊重! 问题解决之后,就来玛思阁简单的记录一下,希望能帮到有需要的同行朋友。
阅读全文
数据库

关于博客的数据库分类

这个分类是在上一次修改文章分类的时候加上的,但一直都没有添加文章,原因很简单,因为数据库是我较弱的一环,肚里确实没多少可以记录的"墨水"。所在的公司分工忒细致,数据库是和运维分开的,有专门的管理Oracle的DBA小组,所以我这样的SA就被剥夺了DB实践运维的机会。 我这个人有个不好的毛病,不喜欢按部就班的教科书式的学习知识,讨厌有的书前几章洋洋洒洒的介绍理论知识,看了就打瞌睡!最喜欢的就是在实例中学习,大把大把的理论,我非但记不住,甚至看着没精打采的! 自己也确实建立个数据库玩过,但是脑子思维,思维太塞,不知道可以加入些什么database、什么table,总之就是不知道要做什么?当然运维本身知识面太广的原因,也导致了精力确实不太够。 言归正传,作为一名运维屌丝,对数据库终归还是要掌握下的! 后续在这个分类会记录一下我的数据库学习笔记,希望勉励自己,能够坚持学习下去。
阅读全文