数据库

MySQL主从报错解决:Table ‘mysql.gtid_slave_pos’ doesn’t exist

给内部一个数据库做异地热备,热备部分采用了MariaDB的galera集群模式。然后挑选其中一台作为Slave和深圳主集群做主从同步。 主集群是老环境,用的版本还是是MySQL 5.5.13。用常规办法创建主从同步 结果有如下报错: 错误信息为:Last_SQL_Error: Unable to load replication GTID slave state from mysql.gtid_slave_pos: Table 'mysql.gtid_slave_pos' doesn't exist 搜了下资料,大部分说是没有执行mysql_upgrade导致的,不过我们这边的MariaDB是Docker跑的,而且用了很长时间了,理论上应该是没问题的才对。 既然提示没有这个表:Table 'mysql.gtid_slave_pos' doesn't exist,那我就创建一个吧! 从网上找到这个建表语句: 在作为Slave的MariaDB上执行,然后重启slave后问题解决,过程如下:
阅读全文
WEB应用

解决网站404页面返回200状态码问题

好久没打理博客,突然收到CDN流量预警,发现平均每天40G流量消耗!what?就现在这个访问量,不存在的。看了下CDN日志发现有小人一直在请求博客页面,其中被请求最多的就是CCkiller防御工具那个文章地址。 呵呵,我就写一个简单的防御小工具,惹着你啦?实际上我用了CDN,也并没有安装这个工具,所以想试探、想测试效果的麻烦自己去安装使用,攻击我博客毫无意义,挂了又能怎么样? 废话就扯这么多,进入正题。 看日志的时候,我发现有大量请求到了博客其实并不存在的地址,但是返回码居然是200??这就不正常了,于是手工访问了一下一个不存在的页面,虽然WordPress在前台给我展示了一个404页面,但是浏览器显示返回码确实是200!!纳尼? 还以为WordPress更新后改了这个机制呢,把主题下的404.php加了一个强行的404返回码,发现没有任何效果。 最后发现,居然是自己以前把404页面静态化留下的坑! 原因很简单,当时经常有人攻击一些不存在的页面,也就是每次都是动态的404,服务器自然就容易高负载,因此做了一个静态化处理: 通过curl请求一个不存在的地址,触发404返回内容,然后保存在网站的某个目录下,比如xxxx下面: 然后,在Nginx Vhost下新增404响应规则: 重启Nginx之后,再访问不存在的博客页面的时候,Nginx就直接返回404.html的内容了,从而实现404页面的静态化。 但是,Nginx这里我写错了,导致每次返回404.html都是200返回码!!这样其实会误导搜索引擎的判断,以为页面是存在的。。。。大坑。 正确的Nginx配置方法应该是: 也就是不用等号,而是用空格!修改后,重启Nginx,然后访问不存在的地址发现已经是404返回码了,问题解决!
阅读全文
大数据

零门槛!基于Docker快速部署ES集群

自从接触Docker之后,对Docker简直是爱不释手,做什么都是行云流水。遇到部署开源软件需求,第一时间想到的都是有没有现成的Docker镜像?能不能直接拉起来使用? 所以,这次网平的ES集群的重建,全部使用DockerHub已有镜像完成部署,整个过程变得非常简单!本文将分享详细的部署过程,希望对ES感兴趣或即将入坑ES的同学带来一些帮助。 一、整体架构 这里,我先给出本文最终的整体架构,让大家有一个清晰的部署思路: 角色分离:本文分享的ES架构中,特意将Master和Client独立出来,后续节点的重启维护都能快速完成,对用户几乎没有影响。另外将这些角色独立出来的以后,对应的计算资源消耗也就从Data节点剥离了出来,更容易掌握Data节点资源消耗与写入量和查询量之间的联系,非常有利于集群后续的容量管理和规划,算是一个比较成熟的中小型方案,准备正儿八经开搞的同学可以参考部署。 Ps:详细的ES角色职责说明可以查看官方文档。 数据流向:Beats或自研系统上报日志到Kafka,然后Logstash从Kafka读取数据写入ES.Client,最终数据存放到ES.Data节点。用户可以通过Kibana或ES.Client的Restful接口查询数据。 本文涉及的IP的角色属性清单: 名称 服务器IP 角色 备注 Docker仓库 192.168.1.111 Docker/registry 内网私有仓库,需要外网 Kafka Cluster 192.168.1.100 Kafka/Zookeeper 192.168.1.101 Kafka/Zookeeper 192.168.1.102 Kafka/Zookeeper ES Cluster 192.168.2.100 ES: Master/Client/Kibana 128Gx35核 192.168.2.101 ES: Master/Client/Kibana 192.168.2.102 ES: Master/Client/Kibana 192.168.3.100 ES: DATA    64Gx32核 2TBx12 Ps:预算充足的强烈推荐上SSD硬盘,可以极大的提高集群性能! 192.168.3.101 ES: DATA 192.168.3.102 ES: DATA 192.168.3.103 ES: DATA  本文涉及的部分参数简单解释(更多详细解释请咨询搜索引擎): 本文涉及的部分参数简单解释(更多详细解释请咨询搜索引擎): 二、Docker资源 1、Docker私有仓库搭建(针对内网环境) ①、在有外网的服务器 192.168.1.111 上进行如下操作: Ps:若内部没有外网服务器,可以使用离线导出导入(save/load)的方案来做本地仓库,具体参考我之前整理的Docker入门教程-->传送门 ②、docker启动后,开始拉取所需镜像: 以下镜像均位于dockerHub,拉取龟速,这里可以使用阿里云的dockerHub加速服务(腾讯云的仅支持腾讯云服务器内网使用) zookeeper 镜像主页:https://hub.docker.com/_/zookeeper/ kafka 镜像主页: https://hub.docker.com/r/wurstmeister/kafka/ Elastic 镜像主页:https://www.docker.elastic.co/ Ps:6.X版本强制启用了content-type头部请求,比较烦,本文选择5.X的最后一个版本,实际使用请自行抉择。 完成以上步骤,我们就在192.168.1.111上建立了一个Docker私有仓库,地址是 192.168.1.111:5000。 2、所有服务器节点都安装要docker,并开启私有仓库支持 vim /etc/sysconfig/docker 添加兼容私有仓库非https协议配置: 启动Docker: 完成这一步之后,Docker环境已准备完毕。 三、部署Kafka集群 Ps:若只是单纯部署ES集群,而不需要用到kafka,可以跳过本步骤 1、部署zookeeper ①、部署节点1 ②、部署节点2 ③、部署节点3 2、部署kafka ①、部署节点1 ②、部署节点2 只需要修改如下参数,其他和节点1代码一样: ③、部署节点3 同上所述,只需要修改如下参数: 完成之后,我们就使用纯Docker搭建了一个Kafka集群。 四、部署ES集群 1、内核参数优化 vim /etc/sysctl.conf 最后,执行 sysctl -p 生效 3、创建挂载目录 Master节点:...
阅读全文
数据库

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 会监控从库的主从延迟情况,如果延迟秒数超过这个阀值,迁移不会退出,等待延迟秒数低于这个阀值继续迁移。...
阅读全文