2

在过去的 4 个小时里,我在网上搜索了一个解决方案,但我能找到的只是:

你不能。不可能的。不会发生。

我不喜欢这种方法。

我的理论是,如果它被存储在 information_schema.processlist 中的某个点,那么必须有某种方式来获取它。我试图在 processlist 表上运行触发器,但无法让它工作,我认为是因为它是一个视图。运行日志不是一个选项,因为这会影响已经拥挤的服务器上的性能,并且有许多查询正在运行,我只希望它登录特定的表,然后只登录更新..

这就是传说中的stackoverflow!在这里您可以找到解决所有问题的方法,因为那里充满了天才!!!

所以,我请求,天才在哪里!展现自己!!:-)

谢谢, 泽德

4

3 回答 3

2

这里的问题是 MySQL 触发器的范围是行级的,而不是语句级的。因此,在触发器中,您可以访问给定行中每一列的 OLD 和 NEW 值,但您无权访问导致触发器触发的语句。

关于 information_schema.processlist,该视图中实际上没有“存储”(持久化)任何内容。它只是processlist的一个SQL接口,导致触发器触发的语句在触发器范围内是不可访问的。

您说您不想启用常规查询日志,并且由于多种原因(包括 event_Time 的粒度为 1 秒),这种方法并不完美,但这里有一个示例,说明如何使用general_log 表:

SET GLOBAL GENERAL_LOG='ON';
SET GLOBAL LOG_OUTPUT='TABLE';

DELIMITER || 

CREATE TRIGGER DEBUG_DATE BEFORE UPDATE ON db.tbl FOR EACH ROW 
BEGIN 
  DECLARE Q MEDIUMTEXT; 
  SELECT argument INTO Q 
  FROM mysql.general_log 
  where thread_id = connection_id() 
  order by event_time desc 
  limit 1;

  INSERT INTO db.tbl_log (INFO) 
  VALUES (Q); 

END ||

DELIMITER ;
于 2012-05-18T14:05:18.297 回答
1

我们调查了这个问题,发现“DECLARE”在上面的示例中不起作用,并且应该在服务器上启用general_log标志。最后我们有以下触发代码:

DELIMITER $$

DROP TRIGGER IF EXISTS `our_trigger`$$
CREATE TRIGGER `our_trigger` 
BEFORE UPDATE ON `our_table_for_debug` 
FOR EACH ROW BEGIN 

SELECT argument INTO @tquery FROM mysql.general_log where thread_id = connection_id() and argument like 'update%' order by event_time desc limit 1;
INSERT INTO `our_log_table` (`query`) VALUES (@tquery);

END IF;

END$$

DELIMITER ;

“our_log_table” 是具有单个 mediumtext 字段的表,名为query. 要启用常规日志,您应该运行以下查询:general_log = 1; 或直接在mysql设置中启用它。

于 2014-10-28T09:03:58.060 回答
0
SELECT INFO FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ... ;
于 2012-05-18T11:17:20.737 回答