我正在进行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,''))
显然我可以在slave上创建tableB
并让它更新一个伪表,但是这个表特别是一个内存表,用于搜索并且几乎不断更新导致很多资源浪费。
我是否可以在保留tableA
的同时从复制中过滤掉这些更新?我无法访问主服务器,但如果这是一个不会影响系统运行的变化,我可以要求他们进行更改。
答案 0 :(得分:11)
选项AFAIK主要基于使复制基于ROW
,而不是基于STATEMENT
。
ROW
(这是一种强力方法,并且有其缺点)。SESSION
binlog_format to ROW
,但它需要用户可能没有的SUPER
权限,并且出于正当理由不会被授予。MIXED
格式you can look around here to force a ROW
based entry in the 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
答案 1 :(得分:0)
在我的情况下,更有意义的是忽略表格不存在错误。这是因为我的数据库系统几乎没有机会改变,所讨论的更新永远不会针对我正在复制的表格。
这是一个遗留系统,我们正在慢慢离开。
slave-skip-errors=1146
解决这个问题的唯一其他可靠方法是切换到主服务器上的行级bin日志记录,但是我无法让他们为我做出更改。