我正在尝试在MySQL启动时自动执行应用程序代码。init-file服务器选项似乎很方便,我需要知道 mysqld在使实例和数据库可用之前是否等待init-file中的所有代码完成。
我试图建立一个快速测试用例,它似乎不像我预期的那样工作:
创建一个简单的测试表和一个只插入记录的过程
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
$$
从初始化文件调用该过程:
$ 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
重新启动服务器以验证时序并检查测试表的内容:
会话 1 - 表为空:
[Wed Nov 28 15:54:26 2012]> select * from init_test_tab;
Empty set (0.00 sec)
会话 2 - 重新启动 mysqld:
# time service mysql restart
mysql stop/waiting
mysql start/running, process 3031
real 0m10.116s
user 0m0.024s
sys 0m0.068s
请注意,重新启动只需 10 秒。
会话 1 - 连接丢失(如预期):
[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]>
请注意,该过程会自动调用(如预期的那样),因为表不再为空。但是插入应该只在 sleep(300) 调用之后执行,而不是立即执行(或者,准确地说,只是在几秒钟内)。
所以现在我试图理解:
- 如果我在 init 文件中放置一个过程调用(或任何应用程序代码),它是否会按预期执行(在我的测试用例中,睡眠调用似乎被跳过了)?
- 我可以对执行的内容进行某种记录(除了修改代码本身)吗?
- 如果init-file中的代码需要时间,是否会影响MySQL实例在重启后的可用性?
谢谢迪米特
试图理解#1
是的,它会的。过去,我建议使用
init-file
为 MyISAM 表创建专用的密钥缓存:Aug 28, 2012
:交换中的 MySQL InnoDB 索引(参见建议 #3)Mar 20, 2012
:具有主键和 varchar 值的最优表设计 mysql我目前正在为我雇主公司的客户做这件事。
试图理解#2
抱歉不行。您将拥有以下之一:
SELECT 'DEBUG#1;'
...SELECT 'DEBUG#2;'
以查看它是否回显到错误文件。将这些 SELECT 查询放在代码中的不同位置。试图理解#3
仅从您在问题中发布的示例来看,他们的回答仍然是否定的。但是,为了确定,您必须让 mysqld 告诉您这一点。假设
/var/log/mysqld.log
是你的错误日志,这里是如何检查:service mysql stop
tail -f /var/log/mysqld.log
service mysql start
观察 Session1 的输出。如果你看到类似的东西
在不到 5 分钟(300 秒)内,这将确认答案是否定的,重启后 MySQL 实例的可用性不受影响。
为什么 SLEEP() 不起作用???
至于为什么
SLEEP
似乎跳过了该功能,这是我最好的猜测:早在 MySQL 5.0.12 中,SLEEP 通过一些优化被插入到查询缓存中。存储过程的内部代码可能正在优化,mysqld 决定不让
SLEEP
干扰 EXPLAIN 计划的形成及其执行。回到 MySQL 5.0 时应用了它的补丁。从 MySQL 5.0 升级到 MySQL 5.1 及更高版本时是否会丢失该补丁?这是一种可能性。另一种可能性是,
SLEEP
尽管有补丁,它还是被优化掉了。有些用于
SLEEP
嵌入互斥、执行压力测试或花哨的作业调度使用
SLEEP
并不总是按预期执行。更新 2012-11-27 15:50 EDT
如果您真的想控制该
SLEEP
功能,请不要使用该功能!创建一个检查时间流逝的循环
而不是你的代码
像这样嵌入循环:
请查看该构造是否适合您。