有没有好的方法来检测MySQL是否“就绪”?

9
我不是MySQL专家。
我有一个安装MySQL、启动mysqld并使用mysql进行一些初始化的脚本。
目前,为了使其工作,我进入一个循环(抱歉,伪代码混合了多种语言):
mysqld_safe /* ... */ & /* ampersand to start in background so we can continue */
while(fileDoesNotExist("/tmp/mysql.sock")) {
    sleepFor100ms();
}
mysql -u root /* and so forth */ initialize.sql

这似乎可以工作(!),但存在多个问题:

  • 轮询的方式不太好,
  • 我对MySQL不够了解,不知道查看硬编码路径名/tmp/mysql.sock是否明智。

然而,与尝试(例如)消耗和解析mysqld_safe的stdout(或stderr?)以确定服务器是否已启动相比,这要容易得多。

我的具体问题是是否有一种方法可以发出阻塞启动mysqld的命令:我可以发出任何命令来阻塞,直到数据库已启动,然后退出(并分离,也许留下PID文件),并且有一个停止命令的伴侣吗? (或者允许我读取PID文件并发出自己的SIGTERM?)

我的更广泛的问题是,我是否走在正确的轨道上,或者是否有完全不同且更容易(对我来说“更容易”必须是轻量级的;我对安装一堆工具如Puppet或DbMaintain / Liquibase之类的工具不那么感兴趣)的方法来解决我所阐述的问题?也就是说,从包含MySQL的.gz文件开始,安装用户区MySQL并初始化数据库?


在这里提问,无论您是否是专家都没有必要。 - tadman
谢谢你的欢迎之意。我只是觉得提供一些背景信息会有所帮助,这样大家就不会在我的头上说话了。 :) - David P. Caldwell
不确定您是否不知道使用shell的方法来完成这件事。耐心等待文件出现有什么不好的呢?该文件的位置并不容易推断,但可能根据您的平台在/etc/my.cnf中定义。 - tadman
通常情况下,如果我在进行轮询操作,我会觉得自己做错了什么;这样会浪费资源等等。总的来说,这种方法似乎很不专业。如果这是唯一的方法,那就只能这样了,但这让我猜想我可能没有理解清楚。 :) - David P. Caldwell
1
嗨@user1762087——请看我在被接受的答案下的评论。最终我使用了PID文件,因为由于我控制安装和配置,所以我可以直接查看默认的PID文件位置,这非常简单。 - David P. Caldwell
显示剩余6条评论
2个回答

9

查看mysqld的init shell脚本。它们进行轮询,使用一个名为wait_for_pid()的函数。

该函数检查pid文件是否存在,如果尚不存在,则等待1秒钟,然后再次尝试。默认情况下有一个超时时间为900秒,超时后它会放弃等待并得出结论:它无法启动(并输出完全没有帮助的消息“服务器退出而未更新PID文件”)。

您不必猜测pid文件在哪里。如果您正在启动mysqld_safe,您应该告诉它应该使用--pid-file选项创建pid文件的位置。

一个棘手的问题是,直到mysqld初始化后pid文件才会被创建。如果需要使用InnoDB日志文件执行崩溃恢复,并且日志文件很大,则可能需要一段时间。因此,即使超时时间为900秒,也可能不够长,您会得到虚假错误,即使超时后mysqld成功启动。

您还可以阅读mysqld的错误日志或控制台输出。它最终应输出一行指示“准备好连接”的内容。

要读取直到获得此行,然后终止读取,可以使用:

tail -f | sed -e '/ready for connections/q'

谢谢。我想我的方法比我想象中更接近最佳方法,但我感谢关于PID文件的建议。有两件事情我更喜欢这个解决方案:(1)即使我选择“猜测”位置(mysqld_safe似乎选择从安装目录派生的默认路径),这意味着如果我有多个安装,我不会将一个错误地认为是另一个,(2)正如您所提到的,我可以明确指定路径以获得清晰度或鲁棒性。谢谢! - David P. Caldwell
是的,PID文件在数据目录中有一个默认位置。这个默认位置也可以在一个或多个my.cnf文件中被覆盖。所以猜测是困难的。最好指定位置,这将覆盖my.cnf或内置默认设置中的任何设置。 - Bill Karwin
对于我的使用情况,我正在进行安装,因此您提到的某些危险对我来说不那么重要,而且我可能会决定DRY的简单性更好;在我的情况下,我只关心PID文件在哪里,这是在初始化数据库时进行安装脚本时的事情。只要我的mysqld_safe执行将其放置在可预测的位置,我就知道要检测哪个PID文件(而不是在命令行和轮询循环中重复它),这将使脚本尽可能小。 - David P. Caldwell

1
你可以使用


mysqladmin -h localhost status

或者使用纯Bash解决方案,例如wait-for-it

./wait-for-it.sh --timeout 10 -h localhost -p 3306

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接