【问题标题】:Mysql replication with UPDATE JOIN on an ignored table在忽略的表上使用 UPDATE JOIN 进行 Mysql 复制
【发布时间】:2013-09-22 10:51:53
【问题描述】:

我正在做 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,''))

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

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

【问题讨论】:

    标签: mysql replication


    【解决方案1】:

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

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

    slave-skip-errors=1146
    

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

    【讨论】:

      【解决方案2】:

      选项 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() 调用很可能会触发它。

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-09-02
        • 1970-01-01
        • 1970-01-01
        • 2021-11-12
        • 1970-01-01
        • 1970-01-01
        • 2018-03-18
        • 1970-01-01
        相关资源
        最近更新 更多