【问题标题】:Finding Query that Triggered a Trigger查找触发触发器的查询
【发布时间】:2016-05-26 16:03:53
【问题描述】:

是否可以通过触发器获取触发它的查询或查询的主 ID?

目前我们大致有:

Delete from Table1 where id = 1

id 是该表的主 ID,1 只是一个示例记录)

我想记录查询或被删除行的id(因为有人错误地删除了记录(非恶意))。对于triggerBEFORE DELETE ON,这似乎是一个简单的过程,但我不知道如何解决导致trigger 触发的父查询。

我打算:

DELIMITER $$
    CREATE TRIGGER Table1_Row_Being_Deleted
        BEFORE DELETE ON Table1
            INSERT INTO deleted_Table1 (deleting_date, tableid) values(now(), ?);
    END$$
DELIMITER;

但我不知道该为? 放什么。我见过的所有其他线程和文档都有静态值,或者影响了表中的每一行。

【问题讨论】:

  • 要删除的id是old.id。表名是“Table1”(触发器始终属于特定表,因此您在创建触发器时知道该表名)。您应该使用FOR EACH ROW,否则您不会记录多次删除。而且您不知道哪个语句试图删除该行。即使删除失败(例如由于外键),您也会记录,您可以使用after delete 仅记录成功的删除。
  • you can't know which statement tries to delete the row 这正是我需要知道的。没有可以追踪的系统级事件吗?如果我使用after delete,记录是不是已经消失了,还是暂时存储在内存中并且仍然可以访问?一个查询中永远不会有 2 条被删除的记录,所以我不必担心一个查询中有多个删除。
  • old 是一个特殊的行,即使在删除后也包含该值。要跟踪您的查询,您可能需要查看performance_schema.events_statements 和/或performance_schema.events_statements_history(您必须为最后一个选项设置一个选项),它们包含活动和过去的查询。它们没有直接链接到您的触发事件,但也许您可以以某种方式链接(例如,通过时间戳,或者通过检查表名是否在字符串中,尽管当然可以间接删除一行,所以表名可能不在查询文本中,或保存多个查询并稍后检查)
  • 是的,old 就是答案。谢谢,您应该将其发布为答案。
  • 是的,我将其作为答案发布并添加了有关事件日志的内容,可能也会有所帮助。

标签: mysql sql-delete delete-row database-trigger


【解决方案1】:

触发器和触发触发器的查询之间没有直接联系。但是您可以使用performance schema 搜索所有活动查询并记录它们。其中之一应该是调用者的查询。

create trigger Table1_Row_Being_Deleted after delete on Table1 
for each row
  insert into deleted_Table1(id, dt, user, qry) 
  select old.id, now(), user(), performance_schema.events_statements_current.sql_text
  from performance_schema.events_statements_current; 

这将记录每个活动查询,因此会记录很多噪音,因为不知道正确的查询。由于它可以是间接查询(例如来自过程),因此正确的查询并不总是具有独特的部分,例如“从 table1 中删除”。因此,请查找每次出现问题时都会出现在日志表中的常见查询。

我在这里使用了after delete 触发器,所以它只会在delete 成功时记录,您可能希望使用before delete 触发器来记录,即使delete 稍后会失败(例如,因为外键约束)。

old.id(以及整行old)包含该行在被删除之前的值(因此您仍然可以在此处使用它来记录条目)。

performance schemaevents_statements_current-log 通常默认启用。检查来自

的结果
select * from performance_schema.events_statements_current;

它至少应该包含一个带有 select-query 本身的行(因为当时这是一个活动的查询)。如果它是空的(或者您无权使用它或它不存在),您应该检查show variables like 'performance_schema'; 是否会显示ON。您可能需要设置权限或一些日志记录选项,请参阅Query Profiling Using Performance Schema

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 1970-01-01
    • 2012-07-28
    • 2011-09-05
    • 1970-01-01
    相关资源
    最近更新 更多