zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

MySQL · 捉虫动态 · ALTER IGNORE TABLE导致主备不一致

mysql 动态 Table 导致 一致 ALTER 主备 ignore
2023-09-14 09:00:57 时间

我们知道当一张表的某个字段存在重复值时,这个字段没办法直接加UNIQUE KEY,但是MySQL提供了一个 ALTER IGNORE TABLE的方式,可以忽略修改表结构过程中出现的错误,但是要忽略UNIQUE重复值,就需要打开old_alter_table,也就是拷贝表的方式来ALTER TABLE。

例如这样:

CREATE TABLE t1(c1 int) ENGINE = InnoDB;

INSERT INTO t1 VALUES (1), (1);

SET old_alter_table=1;

ALTER IGNORE TABLE t1 ADD UNIQUE (c1);

但是如果你是 MySQL 5.5 主备环境,你会发现备库收到这个DDL后,SQL THREAD 会给你一个无情的报错:

Error Duplicate entry 1 for key c1 on query.

Default database: test. Query: ALTER IGNORE TABLE t1 ADD UNIQUE (c1)

这是为什么呢?

其实关键问题就是这个SQL要执行成功,必须保证 old_alter_table 打开,但是 MySQL 的 SET 语句并不参与复制,因此备库只收到了一个 ALTER IGNORE TABLE,而没有先打开 old_alter_table,因此备库用的不是整表拷贝的方法来重建表,因而无法执行成功。

那我们怎么解决这个问题呢,也很简单,只要备库Slave线程也用 old_alter_table=1 来执行 ALTER IGNORE TABLE就好了。

本质上就是 mysql_alter_table() 中需要让need_copy_table= ALTER_TABLE_DATA_CHANGED(old_alter_table=1),而不是need_copy_table= ALTER_TABLE_INDEX_CHANGED(old_alter_table=0)。

因此我们只要在mysql_alter_table()函数中判断该用哪种算法的时候,给出一个可以干预的变量,让Slave线程在需要的时候可以按need_copy_table= ALTER_TABLE_DATA_CHANGED执行。

原来的代码:

 if ((thd- variables.old_alter_table

 || (table- s- db_type() != create_info- db_type)

 #ifdef WITH_PARTITION_STORAGE_ENGINE

 || partition_changed

 #endif

 need_copy_table= ALTER_TABLE_DATA_CHANGED;

我们加上判断 (‘是否启用Slave自动用 ALTER_TABLE_DATA_CHANGED 方式做ALTER IGNORE TABLE’  thd- slave_thread  ignore),就可以在我们打开控制变量的时候,强制让Slave线程用 old_alter_table=1 的方式来执行 ALTER IGNORE TABLE。

 if ((thd- variables.old_alter_table ||

 (是否启用Slave自动用 ALTER_TABLE_DATA_CHANGED 方式做ALTER IGNORE TABLE 

 thd- slave_thread ignore))

 || (table- s- db_type() != create_info- db_type)

 #ifdef WITH_PARTITION_STORAGE_ENGINE

 || partition_changed

 #endif

 need_copy_table= ALTER_TABLE_DATA_CHANGED;


【MySQL】你还不会在Docker下安装MySQL主备吗? 那什么时候就要开始考虑搭建主备架构呢, 一方面是随着业务增长,读写请求已经到达了一定的瓶颈时,我们需要考虑,另一方面为了保证数据的完整性,以保证主宕机的时候,可以快速切换。
关于Linux下MySQL主备集群负载均衡之读写分离(MaxScale)的一些记笔 分享一些MySQL(MariaDB)集群主从结构数据读写分离的笔记,关于读写分离: 一如果对于读密集型应用,可以容忍从库异步复制延迟导致的脏数据,读写分离是一种不错的负载均衡方式 如果对于脏数据零容忍,不建议这样搞,出了故障还需要考虑这个因素,不太方便定位问题 二是读写分离需要做体量评估,不能为了读写分离去读写分离,系统负载正常,完全没必要,如果扩了资源还是频繁的sql timeout,读写分离是解决方法之一 博文偏实战,内容涉及: 为什么需要负载均衡? MaxScale配置主从集群的读写分离 食用方式:了解Linux,MySQL 理解不足小伙伴帮忙指正
MySQL主备模式的数据一致性解决方案 数据一致性对于在线业务的重要性不言而喻,本专题系列,主要从阿里巴巴“去IOE”的后时代讲起,来看下阿里巴巴数据库在数据一致性解决方案
MySQL备份与主备配置 本文详细讲述了如何进行 MySQL 的全量备份、增量备份、主从备份、双主备份以及如何通过 binlog 对误操作数据进行恢复,包含大量代码和截图。
mysql 主备配置 mysql 主备配置 1、准备: master    192.168.40.129 slave        192.168.40.130 mysql版本    mysql5.7 mysql启动    service mysqld start 防火墙关闭    service iptables stop 2、修改配置     /etc/my.
db匠 rds内核团队秘密研发的全自动卖萌机. 追加特效: 发数据库内核月报. 月报传送: http://mysql.taobao.org/monthly/