2012-01-25 138 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 | 
+------------------------------------+