Estou tentando automatizar a execução de um código de aplicativo na inicialização do MySQL . A opção do servidor de arquivos init parece útil e eu preciso saber se o mysqld espera que todo o código no arquivo init seja concluído antes de disponibilizar a instância e os bancos de dados.
Tentei configurar um caso de teste rápido que parece não funcionar como eu esperava:
crie uma tabela de teste simples e um procedimento que apenas insere um registro
create table init_test_tab (x char);
delimiter $$
drop procedure init_test $$
create procedure init_test(p char(1))
begin
do sleep(300);
insert into init_test_tab VALUES(p);
END
$$
chame o procedimento de um arquivo init:
$ cat /var/lib/mysql/mysql-init.sql
call xxxx.init_test('y');
$ grep init /etc/mysql/my.cnf
init-file = /var/lib/mysql/mysql-init.sql
Reinicie o servidor para verificar os tempos e verifique o conteúdo da tabela de teste:
sessão 1 - a tabela está vazia:
[Wed Nov 28 15:54:26 2012]> select * from init_test_tab;
Empty set (0.00 sec)
sessão 2 - reinicie o mysqld:
# time service mysql restart
mysql stop/waiting
mysql start/running, process 3031
real 0m10.116s
user 0m0.024s
sys 0m0.068s
Observe que leva apenas 10s para reiniciar.
sessão 1 - conexão perdida (como esperado):
[Wed Nov 28 15:54:33 2012]> select * from init_test_tab;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)
ERROR:
Can't connect to the server
[Wed Nov 28 15:54:45 2012]> select * from init_test_tab;
No connection. Trying to reconnect...
Connection id: 2
Current database: xxxxx
+------+
| x |
+------+
| y |
+------+
1 row in set (0.01 sec)
[Wed Nov 28 15:54:50 2012]>
Observe que o procedimento é invocado automaticamente (como esperado), pois a tabela não está mais vazia. Mas a inserção deveria ter sido executada somente após a chamada sleep(300), não imediatamente (ou, para ser preciso, apenas em alguns segundos).
Então agora estou tentando entender:
- Se eu colocar uma chamada de procedimento (ou qualquer código de aplicativo) no arquivo init, ela será executada conforme o esperado (no meu caso de teste, a chamada de suspensão parece ter sido ignorada)?
- Eu poderia ter algum tipo de registro do que é executado (além de modificar o próprio código)?
- Se o código no arquivo init demorar, isso pode afetar a disponibilidade da instância do MySQL logo após a reinicialização?
Obrigado Dimitre
Tentando entender #1
Sim vai. No passado, eu recomendei usar
init-file
para criar keycaches dedicados para tabelas MyISAM:Aug 28, 2012
: Índice MySQL InnoDB na troca (consulte a sugestão nº 3)Mar 20, 2012
: design de tabela ideal mysql com chave primária e valor varcharAtualmente, estou fazendo isso para clientes na empresa do meu empregador.
Tentando entender #2
Infelizmente não. Você teria um dos seguintes:
SELECT 'DEBUG#1;'
...SELECT 'DEBUG#2;'
para ver se ecoa no arquivo de erro. Coloque essas consultas SELECT em lugares diferentes em seu código.Tentando entender #3
Apenas pelo exemplo que você postou na pergunta, a resposta ainda seria não. No entanto, para ter certeza, você terá que deixar o mysqld lhe dizer isso. Supondo que
/var/log/mysqld.log
seja o seu log de erros, veja como verificar:service mysql stop
tail -f /var/log/mysqld.log
service mysql start
Observe a saída de Session1. Se você ver algo como
em menos de 5 minutos (300 segundos), isso confirma que a resposta é não, a disponibilidade da instância do MySQL logo após a reinicialização não é afetada.
Por que SLEEP () não funciona ???
Quanto ao motivo pelo qual a
SLEEP
função parece ser ignorada, aqui está meu melhor palpite:No MySQL 5.0.12, o SLEEP era inserido no cache de consulta por meio de alguma otimização . Pode ser que o código interno do Stored Procedure esteja sendo otimizado e o mysqld decidiu não deixar
SLEEP
interferir na formação do plano EXPLAIN e sua execução.O patch para ele foi aplicado no MySQL 5.0 . Esse patch poderia ter sido perdido ao passar do MySQL 5.0 para o MySQL 5.1 e além? Essa é uma possibilidade. Outra possibilidade é que
SLEEP
seja otimizado apesar do patch.Alguns usam
SLEEP
para incorporar mutexing, realizar testes de estresse ou agendamento de trabalhos sofisticadosO uso
SLEEP
nem sempre funciona conforme o esperado.ATUALIZAÇÃO 2012-11-27 15:50 EDT
Se você realmente deseja controlar a
SLEEP
função, NÃO USE A FUNÇÃO!!!Crie um loop que verifica a passagem do tempo
Em vez do seu código
incorpore o loop assim:
Por favor, veja se essa construção funciona para você.