线上MySQL部署的一个问题
- 2019 年 11 月 6 日
- 筆記
01 问题起因 目前在线上安装MySQL现在都是通过平台化操作的,平台化的后台操作逻辑也是将安装的脚本直接运行。昨天在安装的过程中总是出现错误,错误的提示信息大概如下:
/usr/local/mysql/bin/mysqld Starting MySQL (Percona Server)...The server quit without updating PID file (/data/mysql_4306/tmp/mysql.pid).[FAILED] 2019-01-19 10:33:44 start to install plugins... 2019-01-19 :: install plugin successed... mysql.py not running test Sanity_Check: MySQL install Failed....
可以看到,提示的是pid文件没有更新就退出了。
这样换了端口反反复复试了几次,确定了不是偶然现象,于是开始分析这个问题的原因。
02
分析过程 首先想到是否是系统本身的问题(第一时间肯定是想把锅往外面甩,哈哈),简单梳理了一下目前系统资源的交付过程:

可以看到目前的交付方式是DBA提供资源的相关参数,由系统的负责人去分配相关的IP地址,查找相关的物理机器,然后通过一个模板机进行克隆,这台模板机上面安装好了相关的软件,包括mysql、python、pip、mha等等,之前的环境也一直是通过这个模板机克隆的。
于是询问系统负责人模板机最近是否做过改动,确定没有改动之后,排除了这个环节的问题。再次确认此次资源交付的相关克隆操作是否跟之前的保持一致,经过核实,克隆方法确实保持一致,所以排除了资源交付方面的问题(这个问题肯定是在我们这里了,可能是脚本不对?)。
重新分析这个问题,既然平台操作是跑一个脚本,那就直接在系统上跑这个脚本,看看是否可行。但是在这个环节上,遇到了一些意外情况,先来看下面两个mysql服务初始化的语句:
#两种启动方式 [root@hb30-dba-mysql-124-153 mysql_4308]# /usr/local/mysql/bin/mysqld --initialize-insecure --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql [root@hb30-dba-mysql-124-153 mysql_4308]# [root@hb30-dba-mysql-124-153 mysql_4308]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql --initialize-insecure Killed [root@hb30-dba-mysql-124-153 mysql_4308]# ll
第一种启动方式和第二种启动方式唯一的区别是–initialize-insecure的位置,一个放在前面,一个放在后面,但是输出的结果不一样,第一种方式没有任何反应,第二种方式输出一个killed的字样。
看到这里我有些疑惑,第一种方式为什么初始化的时候没有任何的输出?于是使用mysql_install_db的方式初始化了一下,注意,mysql_install_db是老式的启动方法,它不包含–initialize这个参数,官网给出的启动方法如下:

启动后,提示信息如下:
[root@hb30-dba-mysql-- bin]# /usr/local/mysql/bin/mysql_install_db --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql -- :: [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize -- :: [ERROR] Child process: /usr/local/mysql/bin/mysqldterminated prematurely with errno= -- :: [ERROR] Failed to execute /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql_4308/my.cnf --bootstrap --datadir=/data/mysql_4308/data --lc-messages-dir=/usr/local/mysql/share --lc-messages=en_US --basedir=/usr/local/mysql -- server log begin -- -- server log end --
看提示是显示子进程错误,于是上网查询这个错误的解决办法:添加参数–no-defaults,进行初始化。并且,切记要放在参数的首位!否则,不产生作用,具体的链接如下:
https://www.aliyun.com/jiaocheng/162994.html 大家可以自行查看。
然后添加了相关的–no-default参数,重新启动:
[root@hb30-dba-mysql-124-153 mysql_4308]# /usr/local/mysql/bin/mysql_install_db --no-defaults --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql 2019-01-19 :: [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize 2019-01-19 :: [WARNING] The bootstrap log isn't empty: 2019-01-19 :: [WARNING] 2019-01-19T03::26.678349Z [Warning] --bootstrap is deprecated. Please consider using --initialize instead
发现使用mysql_install_db可以启动成功,这三条提示需要注意一下,是告诉用户尽量使用mysqld来代替mysql_install_db来进行启动。既然mysql_install_db能够启动成功,那么mysqld的方式加上这个–no-defaults参数呢?是不是也能启动成功?重新试了一把,结果如下:
[root@hb mysql_4308]# /usr/local/mysql/bin/mysqld --no-defaults --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql_4308/data 2019-01-19T03:02:54.467412Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2019-01-19T03::54.798722Z [Warning] InnoDB: New log files created, LSN= 2019-01-19T03::54.833748Z [Warning] InnoDB: Creating foreign key constraint system tables. 2019-01-19T03::54.887780Z [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: b77b7967-1b96-11e9-b902-005056b7d988. 2019-01-19T03::54.888214Z [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened. 2019-01-19T03::55.170151Z [Warning] CA certificate ca.pem is self signed. 2019-01-19T03::55.215208Z [Note] A temporary password is generated for root@localhost: jo#>rkucb0V
发现也可以启动成功,到此,我得到了一种解决方式,虽然不好,但是能够将服务安装上。
再来看上面的第二种启动方式,为什么将–initialize-insecure放在后面可以出现一个killed字样的提示信息,为什么进程被kill了?我又重新把这个问题复现了一遍,如下:
[root@hb30-dba-mysql-124-153 mysql_4308]# /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql --initialize-insecure & [] [root@hb30-dba-mysql-124-153 mysql_4308]# ps -ef|grep mysqld root : pts/ :: /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql --initialize-insecure root : pts/ :: grep mysqld [root@hb30-dba-mysql-124-153 mysql_4308]# []+ Killed /usr/local/mysql/bin/mysqld --defaults-file=/data/mysql_4308/my.cnf --datadir=/data/mysql_4308/data --basedir=/usr/local/mysql --initialize-insecure
这里咨询了一下同事,查询了一下系统的/var/log/message这个文件,最终得到了答案:OOM
[root@hb30-dba-mysql-124-153 mysql_4308]# tail -f /var/log/messages Jan 19 11:47:07 hb30-dba-mysql-124-153 kernel: [87747] 99 87747 30204 1 0 0 0 python Jan 19 11:47:07 hb30-dba-mysql-124-153 kernel: [88491] 0 88491 114576 1 3 0 0 salt-minion Jan 19 11:47:07 hb30-dba-mysql-124-153 kernel: Out of memory: Kill process (dnsmasq) score or sacrifice child Jan :: hb30-dba-mysql-124-153 kernel: Killed process , UID , (dnsmasq) total-vm:kB, anon-rss:kB, file-rss:kB
到这里,问题才算基本上定位了,就是系统的内存不够了,于是先查看了下当前的剩余内存,再查看了当前配置文件my.cnf当中的内存值,如下:
[root@hb30-dba-mysql-124-153 mysql_4308]# free -m total used free shared buffers cached Mem: 3817 196 3620 0 4 46 -/+ buffers/cache: 144 3672 Swap: 5119 66 5053 ############### InnoDB Variables ############### transaction_isolation = READ-COMMITTED # InnoDB Buffer and Cache Variables innodb_buffer_pool_size='2400M' innodb_buffer_pool_instances = 8
将内存暂时改为200M,再次启动,发现可以正常启动了:
[root@hb mysql_4308]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql_4308/data 2019-01-19T03:02:54.467412Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details). 2019-01-19T03::54.798722Z [Warning] InnoDB: New log files created, LSN= 2019-01-19T03::54.833748Z [Warning] InnoDB: Creating foreign key constraint system tables. 2019-01-19T03::54.887780Z [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: b77b7967-1b96-11e9-b902-005056b7d988. 2019-01-19T03::54.888214Z [Warning] Gtid table is not ready to be used. Table 'mysql.gtid_executed' cannot be opened. 2019-01-19T03::55.170151Z [Warning] CA certificate ca.pem is self signed. 2019-01-19T03::55.215208Z [Note] A temporary password is generated for root@localhost: jo#>rkucb0V
回过头想想,之所以使用–no-defaults参数可行的原因也是跳过了配置文件中的内存值参数,所以才能成功的。这个问题算是暂时告一段落了,但是依旧包含几个疑问:
- 参数位置不同为什么会导致启动的结果不同?
- 为什么一样的模板克隆出来的结果,这个实例上面的内存不能设置过大?即使free -m显示有足够的内存空间。这一点还是值得深究。

03
分析过程总结 这个问题的分析过程我大概总结了下,这里列出来,算是一种借鉴思路:
问题:mysql实例无法部署
问题分析过程:
(1).是否系统源有问题?核实系统源。
(2).是否系统操作人员操作有误?核实操作过程
(3).错误提示分析,将平台化操作转化为脚本化操作
(4).针对脚本化操作中的问题,分类进行分析。首先分析–no-defaults参数,然后再分析进程被kill的原因
(5).根据最终的结果,综合得出结论,给出暂定的解决方案
(6).遗留问题跟进