MySQL部分表复制配置下存在的运维风险、原因及一种方案

大家都知道 replicate-wild-do-table可以配置只同步部分表,由于其支持通佩符,带来便利。但也存在一些风险。

问题描述:

假设M、S两个MySQL Server, S设置为M的从库,且设置replicate-wild-do-table=test.a%.

此时在M库按照如下顺序操作:

1) create table a1(f int);

2) alter table a1 rename to b1;

3) alter table b1 rename to a1;

此时分别在M、S中show tables发现,M中有a1, S中只有b1.

原因是步骤3没有在S中重放。

相关代码:

在主从过程中,从库S会将主库的所有命令都写入本地日志,但在执行之前会先判断是否符合replicate[-wild]-do-table的条件。

从库判断表名是否符合同步条件则是在rpl_filter.cc:tables_ok中,判断的输入是thd.lex.query_tables。 而对于alter语句,在解析过程中仅将源表信息放入query_tables中,导致在执行步骤3时,判断b1不符合模式a%, 因此不予重放。

换个策略也不行:

第一反应是是否可以对于alter语句将目标表也放入tables_ok中判断?当然可以,但就算改成这个策略,仍不能解决这个问题。可以看看这个操作序列。

1) create table a1(f int);

2) alter table a1 rename to b1;

3) alter table b1 rename to c1;

4) alter table c1 rename to a1;

可以看到就算是新策略,步骤3在S中仍然无法重放,在M执行步骤4的时候,S上仍会报错(c1不存在)

运维风险:

因此这个不算MySQL的bug,但在我们平时使用时却存在风险:我们在在线DDL的时候,经常会把一个表先转储到一个临时表中,在临时表中做完擦作后再替换原表。若此时从库上用replicate-wild-do-table作了限制,而临时表又不符合这个条件,则当主库在将临时表替换原表的时候,会导致从库上不会执行此操作,造成不一致。

当然如果我们足够小心,使用一个符合条件的表名作临时表就没这问题了,关键是:这个是要靠人小心来保证,不保险----ddl之前还要去确认所有从库上的配置,也挺麻烦。

一个方案:

出现此问题的最根本原因,是在S上执行步骤2时,将表名从符合a%条件的a1改成b1,导致之后的不可逆。

因此可以在从库上增加一个配置,是否允许重放这种命令。

只需要在判断是否重放的位置,增加判断目标表名是否符合replilcate-wild-do-table的条件,若不符合,直接返回执行失败。并报错到Last_error中。

剩下的就是配合监控了。监控后就可以按照需要重新处理,如需要让S继续重放以免M重新操作,则在S中把临时表的文件名也加入replicate-wild-do-table即可。

时间: 2024-09-27 13:24:02

MySQL部分表复制配置下存在的运维风险、原因及一种方案的相关文章

Asp.net 默认配置下,Session莫名丢失的原因及解决办法

Asp.net 默认配置下,Session莫名丢失的原因及解决办法 正常操作情况下Session会无故丢失.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 这次到CSDN上搜了一下帖子,发现好多人在讨论这个问题,然后我又google了一下,发现微软网站上也有类似的内容. 现在我就把原因和解决办法写出来. 原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: <sessio

MySQL 关于表复制 insert into 语法的详细介绍

web开发中,我们经常需要将一个表的数据插入到另外一个表,有时还需要指定导入字段,设置只需要导入目标表中不存在的记录,虽然这些都可以在程序中拆分成简单sql来实现,但是用一个sql的话,会节省大量代码.下面我以mysql数据库为例分情况一一说明:两张表:insertTest和insertTest2,前者中有测试数据 复制代码 代码如下: create table insertTest(id int(4),name varchar(12)); insert into insertTest valu

MySQL 关于表复制 insert into 语法的详细介绍_Mysql

web开发中,我们经常需要将一个表的数据插入到另外一个表,有时还需要指定导入字段,设置只需要导入目标表中不存在的记录,虽然这些都可以在程序中拆分成简单sql来实现,但是用一个sql的话,会节省大量代码.下面我以mysql数据库为例分情况一一说明:两张表:insertTest和insertTest2,前者中有测试数据 复制代码 代码如下: create table insertTest(id int(4),name varchar(12));insert into insertTest value

极端环境下的IT运维案例

去年秋天,随着飓风桑迪的步步紧逼,整个美国东海岸都开始严阵以待:Robertory自然也不能例外,他正盘算着如何建立并运行一整套IT体系.但时间紧迫,从组织技术团队到让系统投付运行,他只剩下几个小时可以支配. 这时候,尽快选择正确方向就成了他的第一要务. Robertory是美国红十字会灾难服务技术组的负责人.他的工作是确保红十字会的急救人员在现场工作中拥有必要的技术支持,即使是在飓风肆虐之时也不例外. "大多数IT人士在谈到自然灾害时,第一反应都是赶紧卷服务器跑路.但我们的选择正好相反.我们关

mysql克隆表(复制表结构与表数据)

可能有一种情况,当需要一个完全相同的副本表CREATE TABLE ... SELECT不适合需要,因为副本必须包含相同的索引,默认值,依此类推. 按下面的步骤,可以处理这种情况. 使用SHOW CREATE TABLE得到一个CREATE TABLE语句中指定源表的结构,索引等. 修改语句更改表名称的克隆表,并执行该语句.通过这种方式将有确切的克隆表. 或者,如果需要进行表的内容复制,使用INSERT INTO ... SELECT语句也可以搞定. 实例: 试试下面的例子来创建一个克隆表tut

CentOS6系统MySQL主从数据库复制配置详解(1/3)

查看mysql端口是开启 netstat -tanl | grep 3306 MySQL用户的授权 mysql -uroot -p 查看现有的用户授权表 select user,host,password from mysql.user; 测试连接到其他mysql服务器 mysql -uroot -p -h192.168.0.100 授权用户user1,密码456所有权限从192.168.1.181主机访问本服务器的所有数据库. grant all on *.* to slave@192.168

Linux下MySQL数据库主从同步配置

说明: 操作系统:CentOS 5.x 64位 MySQL数据库版本:mysql-5.5.35 MySQL主服务器:192.168.21.128 MySQL从服务器:192.168.21.129 准备篇: 说明:在两台MySQL服务器192.168.21.128和192.168.21.129上分别进行如下操作 备注: 作为主从服务器的MySQL版本建议使用同一版本! 或者必须保证主服务器的MySQL版本要高于从服务器的MySQL版本! 一.配置好IP.DNS .网关,确保使用远程连接工具能够连接

【重磅推荐】MySQL大表优化方案(最全面)

当MySQL单表记录数过大时,增删改查性能都会急剧下降,可以参考以下步骤来优化: 单表优化 除非单表数据未来会一直不断上涨,否则不要一开始就考虑拆分,拆分会带来逻辑.部署.运维的各种复杂度,一般以整型值为主的表在千万级以下,字符串为主的表在五百万以下是没有太大问题的.而事实上很多时候MySQL单表的性能依然有不少优化空间,甚至能正常支撑千万级以上的数据量: 字段 尽量使用TINYINT.SMALLINT.MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED VARCHAR的

运维侠客行杭州站沙龙回顾 | 云时代下的运维管理实践(附干货下载)

我们处在一个巨变的时代,在云计算.大数据和物联网等新技术.新理念不断更新的大背景下,企业同时面临着数字化和"互联网+"转型的双重挑战,企业对于"稳态IT"和"敏态IT"都提出了强烈的需求,如何推进双态环境下的技术演进变成全行业共同面临的难题. 在这样一个"时空交错"中,优云软件推出了一个名为:"运维侠客行"的线下沙龙品牌,杭州作为首站,活动当天汇聚了来自不同行业和企业的运维从业人员,其中有几十年的运维老兵,