【问题标题】:Trigger on slave only仅在从属设备上触发
【发布时间】:2018-02-23 13:47:32
【问题描述】:

我正在尝试在从属设备上为 RBR (https://mariadb.com/kb/en/library/running-triggers-on-the-slave-for-row-based-events/) 运行触发器。 我在 master 上创建了一个这样的表:

CREATE TABLE `t1` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `mobile` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

在奴隶上,我有这个触发器:

CREATE TRIGGER t1_obfus AFTER INSERT ON `t1`
FOR EACH ROW
UPDATE `t1`
SET `mobile` = LEFT(MD5(NEW.`mobile`), 20);

这不起作用。我在SHOW SLAVE STATUS 收到以下错误:

Last_SQL_Error:无法在表 d1.t1 上执行 Write_rows_v1 事件;无法更新存储函数/触发器中的表“t1”,因为它已被调用此存储函数/触发器的语句使用。错误代码:1442;处理程序错误 HA_ERR_GENERIC;事件的主日志 mariadb-bin.000004, end_log_pos 454

然后我将触发器修改为:

CREATE TRIGGER t1_obfus BEFORE INSERT ON `t1`
FOR EACH ROW
UPDATE `t1`
SET NEW.`mobile` = LEFT(MD5(NEW.`mobile`), 20)
WHERE id = NEW.id;

但它仍然没有工作。然后我在slave上创建了一个新表:

CREATE TABLE t1_2 (
    id BIGINT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
    mobile VARCHAR(20)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

并将我的触发器修改为:

CREATE TRIGGER t1_obfus BEFORE INSERT ON `t1_2`
FOR EACH ROW
INSERT INTO `t1_2` (id, mobile)
VALUES (NEW.id,LEFT(MD5(NEW.`mobile`), 20));

现在复制开始工作,但表 t1_2 中没有数据。我该如何解决这个问题?

【问题讨论】:

  • 第一对无法解决错误消息本身中解释的原因,无论它是否是仅从属触发器:触发器无法更新它所在的表调用。你想通过第二对表/触发器来实现什么?自然不会影响复制,因为新的触发器与它无关。由于您仅在从属设备上创建了t1_2,这意味着您没有在主设备上插入它,因此不会复制此类插入并且不使用触发器。如果你尝试在slave上插入t1_2,你会得到和以前一样的错误。
  • 在下次发布之前,请尽量将代码格式化为其他人可以阅读。
  • @underscore_d 当然。

标签: mysql database mariadb


【解决方案1】:

如果您使用基于行的复制,从属设备上的触发器将不起作用。 如official documentation中所述:

块引用 如果您希望触发器在主服务器和从服务器上都执行——可能是因为您在主服务器和从服务器上有不同的触发器——您必须使用基于语句的复制。但是,要启用从端触发器,不必专门使用基于语句的复制。仅对需要此效果的那些语句切换到基于语句的复制就足够了,其余时间使用基于行的复制。

【讨论】:

  • 我使用的是 MariaDB。您提供的文档适用于 MySQL。另外,请参阅我的问题中 RBR 文章的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-26
  • 2018-01-19
相关资源
最近更新 更多