domingo, 12 de maio de 2013

Usando o MySQL planejador de eventos

Original post: http://anothermysqldba.blogspot.com/2013/05/using-mysql-event-scheduler.html

MySQL planejador de eventos é muito eficaz para programar coisas diferentes que você precisar deles. 
Abaixo está um exemplo simples de como usar eventos e também como você pode usar o planejador de eventos de forma diferente através de um mestre e um escravo. 

Primeiro, verifique o status do seu planejador de eventos: 




> show variables like '%event%';
+---------------------------------------------------+-------+
| Variable_name | Value |
+---------------------------------------------------+-------+
| event_scheduler | OFF |
| performance_schema_events_waits_history_long_size | 10000 |
| performance_schema_events_waits_history_size | 10 |
+---------------------------------------------------+-------+


Para ativá-lo, você pode usar o seguinte comando ou você também pode configurá-lo em seu arquivo my.cnf. 

set GLOBAL event_scheduler=ON; 


Vou criar um banco de dados apenas para esta demo 


create database events_test;
use events_test;


Para um teste no mestre vou usar esta tabela simples no banco de dados events_test. 


CREATE TABLE `foobar` (
`time_recorded` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
); 


Eu gosto de ter meus eventos executar procedimentos armazenados, porque eu posso testar o procedimento facilmente antes de empurrá-lo para um evento. 

delimiter //
CREATE PROCEDURE mastereventtest()
BEGIN
insert into foobar values (NOW());
END//
delimiter ; 


Agora eu vou ter este evento executado a cada minuto apenas para esta demo 



CREATE EVENT mastereventtest
ON SCHEDULE EVERY 1 MINUTE
COMMENT 'testing master events'
DO
call mastereventtest();




Confirmar que o é no sistema. 



> show create event mastereventtest\G
*************************** 1. row ***************************
Event: mastereventtest
sql_mode: NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
time_zone: SYSTEM
Create Event: CREATE DEFINER=`root`@`localhost` EVENT `mastereventtest` ON SCHEDULE EVERY 1 MINUTE STARTS '2013-05-12 21:25:22' ON COMPLETION NOT PRESERVE ENABLE COMMENT 'testing master events' DO call mastereventtest()
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci





> show events \G
*************************** 1. row ***************************
Db: events_test
Name: mastereventtest
Definer: root@localhost
Time zone: SYSTEM
Type: RECURRING
Execute at: NULL
Interval value: 1
Interval field: MINUTE
Starts: 2013-05-12 21:25:22
Ends: NULL
Status: ENABLED
Originator: 1
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci



Também vou criar um evento no escravo e desde que eu planejo fazer isso eu preciso desativar os eventos que eu quero off. Então eu vou alterar o mastereventtest evento no servidor SLAVE. 


ALTER EVENT mastereventtest disable on slave; 



Vou novamente criar uma tabela diferente no escravo apenas sob o banco de dados events_test, que foi replicada 


CREATE TABLE `foo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
); 


Mais uma vez eu gostaria de criar um procedimento para usar com meus eventos. Isso não é necessário, mas apenas torna mais fácil para testar. 

delimiter //
CREATE PROCEDURE slaveeventtest()
BEGIN
insert into foo values ();
END//
delimiter ; 


Este será o evento que eu executar no slave 


CREATE EVENT slaveeventtest
ON SCHEDULE EVERY 2 MINUTE
COMMENT 'testing master events'
DO
call slaveeventtest(); 





Confirme que também é feito no sistema 



> show create event slaveeventtest\G
*************************** 1. row ***************************
Event: slaveeventtest
sql_mode: NO_AUTO_VALUE_ON_ZERO,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
time_zone: SYSTEM
Create Event: CREATE DEFINER=`root`@`localhost` EVENT `slaveeventtest` ON SCHEDULE EVERY 2 MINUTE STARTS '2013-05-12 21:14:08' ON COMPLETION NOT PRESERVE ENABLE COMMENT 'testing master events' DO call slaveeventtest()
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci 





> show events\G

Db: events_test
Name: slaveeventtest
Definer: root@localhost
Time zone: SYSTEM
Type: RECURRING
Execute at: NULL
Interval value: 2
Interval field: MINUTE
Starts: 2013-05-12 21:14:08
Ends: NULL
Status: ENABLED
Originator: 3
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci




Você também pode consultar o esquema de informações para informações sobre o evento 




> select * from information_schema.EVENTS\G




Para depurar um evento o melhor local para verificar se o seu log de erro. 

Tenha em mente que quando você verificar os eventos no slave, você verá ambos os eventos 



> > show events \G
*************************** 1. row ***************************
Db: events_test
Name: mastereventtest
Definer: root@localhost
Time zone: SYSTEM
Type: RECURRING
Execute at: NULL
Interval value: 1
Interval field: MINUTE
Starts: 2013-05-12 21:25:22
Ends: NULL
Status: SLAVESIDE_DISABLED
Originator: 3
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
*************************** 2. row ***************************
Db: events_test
Name: slaveeventtest
Definer: root@localhost
Time zone: SYSTEM
Type: RECURRING
Execute at: NULL
Interval value: 2
Interval field: MINUTE
Starts: 2013-05-12 21:14:08
Ends: NULL
Status: ENABLED
Originator: 3
character_set_client: utf8
collation_connection: utf8_general_ci
Database Collation: latin1_swedish_ci
2 rows in set (0.01 sec) 






Agora funcionou? 

Se você executar um programa processlist você será capaz de ver o estado atual segmento de eventos e você pode ler mais sobre os resultados do estado aqui: 


Você deve estar vendo: Esperando ativação próxima 
I também têm resultados nas tabelas: 



root@localhost [events_test]> select * from foobar;
+---------------------+
| time_recorded |
+---------------------+
| 2013-05-12 21:25:22 |
| 2013-05-12 21:26:22 |
| 2013-05-12 21:27:22 |
| 2013-05-12 21:28:22 |
| 2013-05-12 21:29:22 |
| 2013-05-12 21:30:22 |
| 2013-05-12 21:31:22 |
| 2013-05-12 21:32:22 |
+---------------------+
8 rows in set (0.00 sec)

root@localhost [events_test]> select * from foo;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
+----+
8 rows in set (0.00 sec) 








Deixar cair ou desativar eventos: 

CASO SE CAIR EXISTE mastereventtest; 
ALTER mastereventtest EVENTO desativar;