2012-01-25 16 views
11

Amo i trigger per una ragione: funzionano e basta. Detesto i trigger per una ragione: quando non funzionano, dimentica di provare a eseguire il debug. O dolce frustrazione.Debug di trigger MySQL

In pratica, desidero visualizzare la query di aggiornamento, cancellazione, inserimento, ecc. Eseguita. Voglio vedere quella query ... da qualche parte, nel mio terminale o in un log, esattamente come e quando MySQL lo esegue, e possibilmente qualsiasi output/errore corrispondente. Pensieri/hack?

Sto provando a eseguire il debug di una query di aggiornamento con alcuni join e cosa no. Le mie domande sono molto più complesse, ma per brevità ecco un esempio.

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 ; 

Ecco alcune contesto supplementare che può aiutare a influenzare un suggerimento o risposta. Ancora una volta, sono meno interessato alla semantica/sintassi e più interessato a vedere MySQL eseguire la query, ma a tutti i costi, sono aperto a qualsiasi cosa a questo punto.

  • Strace non funziona/mostra query.
  • Ambiente non replicato MA se i registri del cestino mostrano istruzioni di trigger, lo imposterò sicuramente.
  • "show full processlist" mostra l'esecuzione del trigger e/o le istruzioni eseguite all'interno (non le vedo mai dopo aver eseguito l'elenco di processi completo fino a quando perl è in grado di eseguirlo ma potrei semplicemente mancarlo)?
  • Il log delle query generali non mostra queste query (certamente non il log degli errori).
  • Non sto usando alias (più).
  • Nessun errore di sintassi durante la creazione del trigger.
  • L'istruzione IF funziona.
  • Quando inserisco i NUOVI valori in una tabella "test/temp" ed eseguo manualmente la query di aggiornamento funziona (sono addirittura arrivato a inserire l'intera query di aggiornamento)
  • Non riesco a mostrare tu la query ma, come ho appena detto, funziona quando eseguo manualmente se ciò aiuta.
  • Ho rimosso tutti i caratteri errati, le schede, i ritorni a capo, i newline, ecc.
  • Il socket MySQL mostrerebbe solo la connessione locale/dati ma non i funzionamenti interni MySQL, penso.
  • MyISAM quindi i log INNODB non sono un'opzione
  • lsof non sembra mostrare nient'altro che sia utile.
  • Sto usando MySQL 5.0.77 su CentOS 5.5.

risposta

3

È possibile debug triggers utilizzando dbForge Studio for MySQL. Prova la versione di prova.

Esiste una descrizione dettagliata del processo di debug del trigger nella documentazione: Debugging \ Debuging Stored Routine \ How To: avviare il debug del trigger.

+0

Sì, un passo in è in grigio. Presumibilmente perché è un processo? – Justin

+0

Il comando 'Passa a' deve essere attivo dal codice di procedura memorizzato. Hai seguito le istruzioni passo passo (Come: avviare il debug del trigger)? – Devart

+0

Grazie Devart! Un bel pezzo di software. – Justin

0

PROCEDURA MYSQL => incron => tail -f 'mysql_dynamic.log'

una stored procedure può essere invocato in un trigger, ma non restituire alcun

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 

ora in qualsiasi punto in un trigger è possibile richiamare

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 

per macchine Linux apt-get install incron(debian incron tutorial)

Crea la cartella in cui mysql inietterà foo_file

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

e aggiungere seguente lavoro incron

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

Creare script eseguibile "/ percorso/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 

Ora osservate il file collezionista

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

C'è an alternate way of testing it by having a temporary debug table. Nell'esempio qui, lo creano in un proprio database debug.

Fase 1: Creare una tabella

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) 
) 

Fase 2: Creare SP di debug per riempire la tabella di debug

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 $$ 

Fase 3: invocare la SP di debug nel vostro trigger

In questo modo,

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 $$ 

Di conseguenza la tabella di debug sarebbe riempito come segue,

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