在忽略的表上使用UPDATE JOIN进行Mysql复制

时间:2013-09-17 20:31:16

标签: mysql replication

我正在进行mysql复制,作为一个愚蠢的例子,我有两个表,tableAtableB

在要复制的从属设备上,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的同时从复制中过滤掉这些更新?我无法访问主服务器,但如果这是一个不会影响系统运行的变化,我可以要求他们进行更改。

2 个答案:

答案 0 :(得分:11)

选项AFAIK主要基于使复制基于ROW,而不是基于STATEMENT

  1. 将默认值设置为ROW(这是一种强力方法,并且有其缺点)。
  2. You can set the SESSION binlog_format to ROW,但它需要用户可能没有的SUPER权限,并且出于正当理由不会被授予。
  3. 如果以MIXED格式you can look around here to force a ROW based entry in the binlog进行日志记录,则尝试在更新中强制执行无用的FOUND_ROWS()UUID()调用很可能会触发它。
  4. 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日志记录,但是我无法让他们为我做出更改。