Chinaunix

标题: 【讨论中】mysql启动脚本mysqld_safe的疑惑 [打印本页]

作者: baiyaj    时间: 2012-12-03 10:41
标题: 【讨论中】mysql启动脚本mysqld_safe的疑惑
本帖最后由 cenalulu 于 2012-12-04 10:19 编辑

最近搭建了一个mysql cluster的测试环境,在启动sql节点时,使用mysqld_safe脚本启动,出现一个很奇怪的问题,在/etc/my.cnf中,配置了一个参数:
plugin_dir=/web/mysql/mysqlc/lib/plugin/
启动命令是:
mysqld_safe --ledir=/web/mysql/mysqlc/bin &
按说启动后,脚本里面的plugin_dir变量就应该是参数文件里配置的变量,但是实际得到的是mysql默认的,也就是:
/usr/local/mysql/lib/plugin

仔细研究了mysqld_safe脚本,发现脚本中,有个函数parse_arguments(),用来解析参数文件中的一些必要参数,这里把plugin_dir这个变量解析出来,赋给了脚本变量$PLUGIN_DIR,
但是,在调用这个函数之前,脚本就有一段代码对$PLUGIN_DIR这个变量做了是否为空的判断,并据此定义$plugin_dir的值:
if [ -n "${PLUGIN_DIR}" ]; then
  plugin_dir="${PLUGIN_DIR}"
else
  # Try to find plugin dir relative to basedir
  for dir in lib/mysql/plugin lib/plugin
  do
    if [ -d "${MY_BASEDIR_VERSION}/${dir}" ]; then
      plugin_dir="${MY_BASEDIR_VERSION}/${dir}"
      break
    fi
  done
  # Give up and use compiled-in default
  if [ -z "${plugin_dir}" ]; then
    plugin_dir='/usr/local/mysql/lib/plugin'
  fi
fi
plugin_dir="${plugin_dir}${PLUGIN_VARIANT}"
注意,我是经过反复测试后确认,这段代码是在调用parse_arguments之前就执行了,所以$PLUGIN_DIR为空,自然$plugin_dir也就是默认值了,既然$PLUGIN_DIR还没有初始化,就做判断,这里的逻辑是不是有问题,这是我疑惑的地方!
不知道有没有哪位高手研究过这个脚本,请帮忙看看

作者: cenalulu    时间: 2012-12-03 13:18
你说的这段是初始化,之后会调用parse_arguments 把配置文件的所有参数过一遍,进行赋值。

建议执行

my_print_defaults --loose-verbose mysqld server
my_print_defaults --loose-verbose mysqld_safe safe_mysqld
把结果贴出来看看配置情况。
/etc/my.cnf 也贴出来看看
作者: baiyaj    时间: 2012-12-03 14:27
mysql服务运行情况:
[mysql@localhost bin]$ mysqld_safe --ledir=/web/mysql/mysqlc/bin  &
[1] 2013
[mysql@localhost bin]$ 121203 14:17:55 mysqld_safe Logging to '/web/mysql/mysqld_data//error.log'.
121203 14:17:55 mysqld_safe Starting mysqld daemon with databases from /web/mysql/mysqld_data/

[mysql@localhost bin]$
[mysql@localhost bin]$ ps -ef|grep mysql
mysql     2013 25224  0 14:17 pts/0    00:00:00 /bin/sh /web/mysql/mysqlc/bin/mysqld_safe --ledir=/web/mysql/mysqlc/bin
mysql     2551  2013  3 14:17 pts/0    00:00:00 /web/mysql/mysqlc/bin/mysqld --basedir=/web/mysql/mysqlc/ --datadir=/web/mysql/mysqld_data/ --plugin-dir=/usr/local/mysql/lib/plugin --log-error=/web/mysql/mysqld_data//error.log --pid-file=/web/mysql/mysqld_data//mysqld.pid --socket=/web/mysql/mysqld_data/mysql.sock --port=3306
mysql     2582 25224  0 14:18 pts/0    00:00:00 ps -ef
mysql     2583 25224  0 14:18 pts/0    00:00:00 grep mysql
root     25219 17927  0 09:26 ?        00:00:00 sshd: mysql [priv]
mysql    25223 25219  0 09:26 ?        00:00:00 sshd: mysql@pts/0
mysql    25224 25223  0 09:26 pts/0    00:00:00 -bash
[mysql@localhost bin]$ my_print_defaults --loose-verbose mysqld server
--user=mysql
--character-set-server=utf8
--basedir=/web/mysql/mysqlc/
--datadir=/web/mysql/mysqld_data/
--pid-file=mysqld.pid
--socket=/web/mysql/mysqld_data/mysql.sock
--port=3306
--skip_name_resolve
--ndb-cluster-connection-pool=2
--ndbcluster=1
--ndb-connectstring=192.168.21.51:1186
--ndb-force-send=1
--ndb-use-exact-count=0
--ndb-extra-logging=1
--ndb-batch-size=24M
--ndb-autoincrement-prefetch-sz=1024
--engine-condition-pushdown=1
--default-storage-engine=ndbcluster
--server-id=1
--log-error=error.log
--key_buffer_size=256M
--max_allowed_packet=16M
--sort_buffer_size=512K
--read_buffer_size=256K
--read_rnd_buffer_size=512K
--myisam_sort_buffer_size=8M
--memlock=0
--skip_name_resolve
--sysdate_is_now=1
--max-connections=500
--thread-cache-size=128
--query_cache_type=0
--query_cache_size=0
--table_open_cache=1024
--lower-case-table-names=0
[mysql@localhost bin]$ my_print_defaults --loose-verbose mysqld_safe safe_mysqld
--pid-file=mysqld.pid
--log-error=error.log
--basedir=/web/mysql/mysqlc/
--datadir=/web/mysql/mysqld_data/
[mysql@localhost bin]$


my.cnf内容:
# All files in this package is subject to the GPL v2 license
# More information is in the COPYING file in the top directory of this package.
# Copyright (C) 2011 severalnines.com

[MYSQLD]
user=mysql
character-set-server=utf8
basedir=/web/mysql/mysqlc/
datadir=/web/mysql/mysqld_data/
plugin_dir=/web/mysql/mysqlc/lib/plugin/
pid-file=mysqld.pid
socket=/web/mysql/mysqld_data/mysql.sock
port=3306
skip_name_resolve
ndb-cluster-connection-pool=2
ndbcluster=1
ndb-connectstring="192.168.21.51:1186"
ndb-force-send=1
ndb-use-exact-count=0
ndb-extra-logging=1
ndb-batch-size=24M
ndb-autoincrement-prefetch-sz=1024
engine-condition-pushdown=1

default-storage-engine=ndbcluster

#REPLICATION SPECIFIC - GENERAL
#server-id must be unique across all mysql servers participating in replication.
server-id=1
#REPLICATION SPECIFIC - MASTER
#log-bin=binlog
#binlog-format=ROW
#expire-logs-days=5
#LOGS
log-error=error.log
#log
#log-slow-queries
#OTHER THINGS, BUFFERS ETC
key_buffer_size = 256M
max_allowed_packet = 16M
sort_buffer_size = 512K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
#thread_cache_size=1024
myisam_sort_buffer_size = 8M
memlock=0
skip_name_resolve
sysdate_is_now=1
max-connections=500
thread-cache-size=128
###QUERY CACHE IS DISABLED
###THE QUERY CACHE IN MYSQL CLUSTER  CAN HAMPER PERFORMANCE A LOT. HENCE IT IS DISABLED
###BECAUSE INVALIDATION OF IT TAKES TIME (REMEMBER, IT IS A DISTRIBUTED ENVIRONMENT)
###ONLY ENABLE IT AND USE SQL_CACHE TO CACHE ONLY CERTAIN QUERIES ON READONLY TABLES
query_cache_type = 0
query_cache_size = 0
table_open_cache=1024
lower-case-table-names=0

[MYSQL]
socket=/web/mysql/mysqld_data/mysql.sock
[client]
socket=/web/mysql/mysqld_data/mysql.sock

[MYSQLD_SAFE]
pid-file=mysqld.pid
log-error=error.log
basedir=/web/mysql/mysqlc/
datadir=/web/mysql/mysqld_data/


my.cnf里的plugin_dir=/web/mysql/mysqlc/lib/plugin/
没有起作用

作者: ruochen    时间: 2012-12-03 15:56
本帖最后由 ruochen 于 2012-12-03 15:58 编辑

我show global variables like '%plugin%';
看到5.1版本没有最后的/,5.5最后有/

plugin_dir=/web/mysql/mysqlc/lib/plugin
basedir=/web/mysql/mysqlc
这样看看呢?


看到脚本里面plugin_dir="${MY_BASEDIR_VERSION}/${dir}"

作者: baiyaj    时间: 2012-12-03 17:27
去掉了斜杠后
mysql> show global variables like '%plugin%';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| plugin_dir    | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+
1 row in set (0.00 sec)
还是一样的
作者: lk-2010    时间: 2012-12-04 10:01
激动中,好像发现了问题,可是网却断了~

发现好像是下划线和中划线的问题。

把配置文件中的plugin_dir=改成plugin-dir试试,感觉应该是这个问题。
作者: baiyaj    时间: 2012-12-04 10:06
谢谢楼上,不过不是这个问题,已经试过了;
plugin-dir是mysqld_safe脚本调用mysqld程序时,传的参数,而这个参数值,应该是从配置文件的plugin_dir获取的,问题就是配置文件里的这个值,没有获取到,就是想确认下是不是脚本的bug
作者: cenalulu    时间: 2012-12-04 10:19
my_print_defaults --loose-verbose mysqld server 的结果可以看出。
mysqld_safe 并不会从 /etc/my.cnf 中的 [mysqld] section中取 plugin_dir 变量。只接收命令行来的 --plugin_dir 配置。
两种方法:
1. 通过 mysql.server , 即 service mysqld start 的方式启动
2. shell 调用 mysqld_safe 的时候,手工加上 --plugin_dir 参数
作者: baiyaj    时间: 2012-12-04 10:32
谢谢
1,使用mysqld方式启动,能正确从my.cnf中读取plugin_dir参数,没有问题
2,使用mysqld_safe命令行指定方式,无论--plugin_dir=或--plugin--dir=都不行

另外,我发现在parse_arguments()中遍历参数时,DATADIR和PLUGIN_DIR都获取到了正确的值,而在最后为mysqld命令拼接时,使用了DATADIR和plugin_dir,也就是说最终的命令,plugin_dir不是从parse_arguments()中获取的,那获取的那个PLUGIN_DIR没有赋给plugin_dir,这里是我疑问的地方,究竟是我没看懂还是就是bug呢拼接的代码:
cmd="`mysqld_ld_preload_text`$NOHUP_NICENESS"
for i in  "$ledir/$MYSQLD" "$defaults" "--basedir=$MY_BASEDIR_VERSION" \
  "--datadir=$DATADIR" "--plugin-dir=$plugin_dir" "$USER_OPTION"
do
  cmd="$cmd "`shell_quote_string "$i"`
  echo "cmd $cmd"
done
cmd="$cmd $args"

回复 8# cenalulu


   

作者: ruochen    时间: 2012-12-04 10:52
我们这里单实例都是定制的mysqld
作者: lk-2010    时间: 2012-12-04 11:07
回复 9# baiyaj

嗯,不要激动。

你是说读入到$PLUGIN_DIR,而拼接用的是$plugin_dir,并且从$PLUGIN_DIR设置$plugin_dir是在读入之前?
越来越复杂。

既然使用mysqld直接获取没有问题,说明问题还在mysqld_safe上。

另外我看你的my_print_defaults mysqld server输出中没有获取到配置文件中的plugin_dir,这是怎么回事?
   
作者: baiyaj    时间: 2012-12-04 11:25
回复 11# lk-2010


    那是因为在配置文件里把plugin_dir注掉了,加上后执行:
[mysql@localhost bin]$ my_print_defaults --loose-verbose mysqld server
--user=mysql
--character-set-server=utf8
--basedir=/web/mysql/mysqlc/
--datadir=/web/mysql/mysqld_data/
--plugin_dir=/web/mysql/mysqlc/lib/plugin
--pid-file=mysqld.pid
--socket=/web/mysql/mysqld_data/mysql.sock
--port=3306
--skip_name_resolve
--ndb-cluster-connection-pool=2
--ndbcluster=1
--ndb-connectstring=192.168.21.51:1186
--ndb-force-send=1
--ndb-use-exact-count=0
--ndb-extra-logging=1
--ndb-batch-size=24M
--ndb-autoincrement-prefetch-sz=1024
--engine-condition-pushdown=1
--default-storage-engine=ndbcluster
--server-id=1
--log-error=error.log
--key_buffer_size=256M
--max_allowed_packet=16M
--sort_buffer_size=512K
--read_buffer_size=256K
--read_rnd_buffer_size=512K
--myisam_sort_buffer_size=8M
--memlock=0
--skip_name_resolve
--sysdate_is_now=1
--max-connections=500
--thread-cache-size=128
--query_cache_type=0
--query_cache_size=0
--table_open_cache=1024
--lower-case-table-names=0
这里读的应该只是配置文件,而不是实际运行时的状态

作者: lk-2010    时间: 2012-12-04 11:50
回复 12# baiyaj

注释掉了,那就没问题。
另外LZ的mysqld_safe是系统自带的吗?要么把代码贴出来,我怀疑是mysqld_safe读入、赋值、缺省值、或者先后处理的问题。

我的没有设置plugin_dir相关的:
root@lost:/tmp# grep -i plugin /usr/bin/mysqld_safe
root@lost:/tmp#
   
作者: baiyaj    时间: 2012-12-04 11:56
回复 13# lk-2010


    mysqld_safe是系统自带的,代码太多,本来不想贴的,上传个附件吧,文件来自mysql-cluster-gpl-7.2.9-linux2.6-x86_64.tar.gz
mysqld_safe.rar (7.75 KB, 下载次数: 10)

非常感谢

作者: lk-2010    时间: 2012-12-04 14:20
前后仔细查看了几遍,有几个疑问:
1. mysqld_safe设置plugin参数时顺序是这样的:设置plugin_dir->读入到PLUGIN_DIR->使用plugin_dir
因为在设置plugin_dir时,PLUGIN_DIR为空, 因此得到的plugin_dir必为缺省值。
这样可以看到从配置文件和/或命令行读入的值没有用上。所以造成了传递给mysqld的不是配置文件中的值,而是缺省值。

2. 对照MY_BASEDIR_VERSION,DATADIR的使用方式(与PLUGIN_DIR一样都是大写变量名),前两种都是设置、读入、使用的一致,因此没有问题。
而PLUGIN_DIR却很奇怪,不知道脚本这样用有什么特殊的用意?

总之还是觉得脚本使用变量的顺序很奇怪,不知是哪里漏掉没注意到?

作者: baiyaj    时间: 2012-12-04 14:48
回复 15# lk-2010


   感谢楼上的辛勤劳动对于mysqld_safe使用PLUGIN_DIR读取变量,最后又使用plugin_dir拼接命令,本来没有问题,问题出在没有将非空的PLUGIN_DIR赋给plugin_dir,最后使得plugin_dir没有得到预期的值,疑问就在这里,不知道是另有玄机,还是确实是脚本的bug

作者: baiyaj    时间: 2012-12-06 15:31
临时解决的办法,在mysqld_safe脚本的变量声明部分,加上一句:
PLUGIN_DIR=/web/mysql/mysqlc/lib/plugin
目前,先这样测试,起码服务的参数都是正确的了
作者: sundysundy    时间: 2012-12-11 19:08
这种问题,先用strace 跟踪一下,就知道在那出了问题啊,




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2