2012-01-25 79 views
11

我喜欢触发器的原因之一 - 他们只是工作。我讨厌触发器有一个原因 - 当它们不工作时,忘记尝试调试。哦,甜蜜的沮丧。调试MySQL触发器

基本上,我想看到更新,删除,插入等运行的查询。我想看看那个查询...在某处,在我的终端或日志中,确切地说MySQL如何以及何时执行它,以及可能的任何相应的输出/错误。思考/黑客?

我试图调试一个更新查询与几个联接和什么不是。我的查询要复杂得多,但为了简洁,这里是一个例子。

DELIMITER | 
CREATE TRIGGER ireallyhateyourightnow AFTER UPDATE ON watch_this_table 
FOR EACH ROW BEGIN 
IF (OLD.my_value != NEW.my_value) THEN 
    update 
    my_table 
    set 
    my_column = NEW.my_value; 
END IF; 
END| 
DELIMITER ; 

以下是一些可能有助于影响建议或答案的附加上下文。再一次,我对语义/语法不太感兴趣,并且更感兴趣的是看到MySQL运行查询,但无论如何,我现在对任何事情都是开放的。

  • Strace不工作/显示查询。
  • 非复制环境但是如果bin日志显示触发器语句,我一定会设置它。
  • “显示完整进程列表”显示触发器执行和/或内部执行的语句(在运行完整的进程列表之后,我从来没有看到它们像perl可以运行一样快,但我可能会错过它)?
  • 一般查询日志不显示这些查询(当然不是错误日志)。
  • 我没有使用别名(了)。
  • 创建触发器时无语法错误。
  • IF语句有效。
  • 当我将新值变成了“测试/ TEMP”表,并手动运行更新查询它的工作原理(我甚至竟以实际插入整个更新查询)
  • 我无法显示你的查询,但正如我刚才提到的,它工作时我手动运行,如果有帮助。
  • 我已经删除了所有错误的字符,制表符,回车符,换行符等。
  • 我认为MySQL套接字只会显示本地连接/数据而不是MySQL内部工作。
  • MyISAM so INNODB日志不是一个选项
  • lsof似乎没有显示任何其他的使用。
  • 我在CentOS 5.5上使用MySQL 5.0.77。

回答

3

您可以使用dbForge Studio for MySQLdebug triggers。试用试用版。

在文档中有对触发器调试过程的详细描述:调试\调试存储例程\如何:启动触发器调试。

+0

肯定,步入变灰。大概是因为这是一个试验? – Justin

+0

'Step Into'命令必须在存储过程代码中处于活动状态。你是否遵循了一步一步的指令(如何:启动触发器调试)? – Devart

+0

谢谢Devart!非常好的一块软件。 – Justin

0

MYSQL PROCEDURE => incron => tail -f'mysql_dynamic。登录”

存储过程可以在触发器中被调用,但必须在任何地方返回任何

CREATE PROCEDURE `DYN_LOG` (IN s VARCHAR(500)) 
BEGIN 
SELECT s into outfile '/var/spool/incron/mysql_dynamic_spool/foo_file'; 
DO SLEEP(.1); // create a gap beetween multiple shuts 
END 

现在在触发器可以调用

CREATE TRIGGER `trig_name` BEFORE UPDATE ON `tb_name` 
FOR EACH ROW 
BEGIN 
CALL DYN_LOG(concat_ws('\t',NEW.col1,NEW.col2)); 
... 
// rest of the code 
END 

的Linux机器apt-get install incron(debian incron tutorial)

创建mysql将注入的文件夹foo_file

mkdir -m 777 /var/spool/incron/mysql_dynamic_spool 
incrontab -e 

,并添加以下incron工作

/var/spool/incron/mysql_dynamic_spool IN_CREATE /path/foo_file_procesor [email protected]/$# 

创建可执行脚本 “/路径/ foo_file_procesor”

#!/bin/sh 
# // $1 is the foo_file absolute addres 
body="$(cat $1)" // read file content 
rm $1 
log=/var/log/mysql_dynamic.log // message collector 
echo "`date "+%y%m%d %H:%M:%S"`\t== dyn_log ==\t$body">>$log 
exit 0 

现在看集电极文件

tail -f /var/log/mysql_dynamic.log 
2

an alternate way of testing it by having a temporary debug table。在这里的例子中,他们在自己的debug数据库中创建它。

步骤1:创建表

DROP TABLE IF EXISTS debug; 
CREATE TABLE debug (
    proc_id varchar(100) default NULL, 
    debug_output text, 
    line_id int(11) NOT NULL auto_increment, 
    PRIMARY KEY (line_id) 
) 

第2步:创建调试的SP填补了调试表

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `debug_insert` $$ 
CREATE PROCEDURE `debug_insert`(in p_proc_id varchar(100),in p_debug_info text) 
begin 
    insert into debug (proc_id,debug_output) 
    values (p_proc_id,p_debug_info); 
end $$ 

DROP PROCEDURE IF EXISTS `debug_on` $$ 
CREATE PROCEDURE `debug_on`(in p_proc_id varchar(100)) 
begin 
    call debug_insert(p_proc_id,concat('Debug Started :',now())); 
end $$ 

DROP PROCEDURE IF EXISTS `debug_off` $$ 
CREATE PROCEDURE `debug_off`(in p_proc_id varchar(100)) 
begin 
    call debug_insert(p_proc_id,concat('Debug Ended :',now())); 
    select debug_output from debug where proc_id = p_proc_id order by line_id; 
    delete from debug where proc_id = p_proc_id; 
end $$ 

步骤3:调用调试的SP在trigger

像这样,

CREATE PROCEDURE test_debug() 
begin 
declare l_proc_id varchar(100) default 'test_debug'; 
    call debug_on(l_proc_id); 
    call debug_insert(l_proc_id,'Testing Debug'); 
    call debug_off(l_proc_id); 
end $$ 

其结果如下所述调试表将被填充,

+------------------------------------+ 
| debug_output      | 
+------------------------------------+ 
| Debug Started :2006-03-24 16:10:33 | 
| Testing Debug      | 
| Debug Ended :2006-03-24 16:10:33 | 
+------------------------------------+