-35

我正在做 mysql 复制,作为一个愚蠢的例子,我有两个表,tableA并且tableB.

在从属设备上进行复制,tableA被允许并被tableB忽略。

replicate-do-table='dbname.tableA'

在主服务器上,正在执行此查询(我无法对主服务器进行任何更改):

UPDATE tableA as a LEFT JOIN tableB as b ON b.type = a.type
SET b.col1 = CONCAT(IFNULL(a.col1,''),'|',IFNULL(a.col2,''))

显然,我可以tableB在从属设备上创建并让它更新一个伪造的表,但是这个表特别是一个用于搜索的内存表,并且几乎不断更新,导致大量资源浪费。

有没有办法让我从复制中过滤掉这些更新,同时仍然保留tableA?我无权访问主服务器,但是如果更改不会影响他们的系统运行方式,我可以要求他们进行更改。

4

2 回答 2

11

选项 AFAIK 主要基于使复制成为ROW基于而不是STATEMENT基于。

  1. 将默认设置为ROW(这是一种蛮力方法,并且有其缺点)。
  2. 您可以将SESSIONbinlog_format 设置为ROW,但它需要SUPER用户可能没有的权限,并且出于充分的理由也不会被授予。
  3. 如果日志记录以MIXED格式发生,您可以在此处查看以强制ROW在 binlog 中添加基于条目,尝试强制无用FOUND_ROWS()UUID()调用更新很可能会触发它。

解决方案示例MIXED: 查询:

INSERT INTO sometable VALUES ('a','aa');
UPDATE sometable SET aa='bb';
UPDATE sometable SET aa='cc' WHERE UUID(); -- slight overhead, but always true

日志(使用 mysqlbinlog 进行检查),显然STATEMENT基于前 2 个,但ROW基于第 3 个:

# at 175
#130918 21:18:25 server id 1  end_log_pos 277   Query   thread_id=142   exec_time=0     error_code=0
use `test`/*!*/;
SET TIMESTAMP=1379531905/*!*/;
INSERT INTO sometable VALUES ('a','aa')
/*!*/;
# at 277
#130918 21:18:25 server id 1  end_log_pos 304   Xid = 488
COMMIT/*!*/;
# at 304
#130918 21:18:52 server id 1  end_log_pos 372   Query   thread_id=142   exec_time=0     eror_code=0
SET TIMESTAMP=1379531932/*!*/;
BEGIN
/*!*/;
# at 372
#130918 21:18:52 server id 1  end_log_pos 463   Query   thread_id=142   exec_time=0     error_code=0
SET TIMESTAMP=1379531932/*!*/;
UPDATE sometable SET aa='bb'
/*!*/;
# at 463
#130918 21:18:52 server id 1  end_log_pos 490   Xid = 497
COMMIT/*!*/;
# at 490
#130918 21:21:06 server id 1  end_log_pos 558   Query   thread_id=144   exec_time=0     error_code=0
SET TIMESTAMP=1379532066/*!*/;
BEGIN
/*!*/;
# at 558
# at 610
#130918 21:21:06 server id 1  end_log_pos 610   Table_map: `test`.`sometable` mapped to number 180
#130918 21:21:06 server id 1  end_log_pos 664   Update_rows: table id 180 flags: STMT_END_F
BINLOG '
Iv05UhMBAAAANAAAAGICAAAAALQAAAAAAAEABHRlc3QACXNvbWV0YWJsZQAC/A8DAwYAAQ==
Iv05UhgBAAAANgAAAJgCAAAAALQAAAAAAAEAAv///QJiYv0CY2P8AQAAYQJiYvwBAABhAmNj
'/*!*/;
# at 664
#130918 21:21:06 server id 1  end_log_pos 691   Xid = 578
COMMIT/*!*/;
DELIMITER ;
# End of log file
于 2013-09-18T17:41:06.367 回答
1

在我的情况下,忽略表不存在错误更有意义。这是因为我的数据库系统几乎没有改变的机会,并且有问题的更新永远不会针对我正在复制的表。

这是一个我们正在慢慢摆脱的遗留系统。

slave-skip-errors=1146

解决此问题的唯一其他可靠方法是切换到 master 上的行级 bin 日志记录,但是我无法让他们为我进行更改。

于 2013-09-23T20:39:52.283 回答