实践MySQL多实例/多版本实践 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - 作者:臭豆腐[trydofor.com] - 日期:2005-02-23 - 授权:署名-非商业-保持一致 1.0 协议 - 声明:拷贝、分发、呈现和表演本作品,请保留以上全部信息。 0. 文档目录 ^^^^^^^^^^ [[<=$INDEX]] 1. 实现目标 ^^^^^^^^^^^^ 1) 同一版本的多个实例同时运行。 两个4.1.9的实例分别于3301,3302端口监听并提供服务。 2) 不同版本的单个实例同时运行。 4.1.9和5.0.2的实例分别于3304,3305端口监听并提供服务。 3) 不同版本的多个实例同时运行。 4.1.9的2个实例分别于3301,3302端口监听并提供服务。 5.0.2的2个实例分别于3308,3309端口监听并提供服务。 2. 必要准备 ^^^^^^^^^^^ 2.1. 运行环境 ^^^^^^^^^^^^^ =============== tty : root@trydofor =================== cat /proc/version >Linux version 2.4.20-8 (bhcompile@porky.devel.redhat.com)(gcc version >3.2.2 20030222(Red Hat Linux 3.2.2-5))#1 Thu Mar 13 17:54:28 EST 2003 ls -l |grep mysql|awk '{print $5,$9}' >33368998 mysql-max-5.0.2-alpha-pc-linux-i686.tar.gz >28195102 mysql-standard-4.1.9-pc-linux-gnu-i686.tar.gz ======================================================= 2.2. 理论基础 ^^^^^^^^^^^^^ mysqld 读取配置文件的顺序. 1) /etc/my.cnf, Global options. 2) $DATADIR/my.cnf, Server-specific options. 3) defaults-extra-file, The file specified with --defaults-extra-file=path, if any 4) ~/.my.cnf, User-specific options. mysqld 多进程运行的必要条件是以下项目必须独立分开。 * pid-file * datadir * socket * port 3. 安装程序 ^^^^^^^^^^^ =============== tty : root@trydofor =================== #添加mysql组和用户 groupadd mysql useradd -g mysql mysql #解包到/usr/local tar -xzf mysql-standard-4.1.9-pc-linux-gnu-i686.tar.gz -C /usr/local tar -xzf mysql-max-5.0.2-alpha-pc-linux-i686.tar.gz -C /usr/local #建立软链接,方便操作 cd /usr/local ln -s mysql-standard-4.1.9-pc-linux-gnu-i686 mysql4 ln -s mysql-max-5.0.2-alpha-pc-linux-i686 mysql5 #初始化data,更改文件属性 cd mysql4 scripts/mysql_install_db --user=mysql chown -R root . chown -R mysql data chgrp -R mysql . #复制data,以供单版本多实例分配 cp -a data data_1 cp -a data data_2 #初始化data,更改文件属性 cd ../mysql5 scripts/mysql_install_db --user=mysql chown -R root . chown -R mysql data chgrp -R mysql . #复制data,以供单版本多实例分配 cp -a data data_1 cp -a data data_2 ======================================================= 4. 配置与测试 ^^^^^^^^^^^^^^^ 利用 $MYSQL/bin/mysqld_multi 来实现,需要把$MYSQL/bin放入$PATH。 其实,通过启动多个 $MYSQL/bin/mysqld_safe 脚本也实现, 不过 mysqld_multi 提供了更方便更简单的途径,不用有点可惜:) 4.1. 单版本多实例的实现 ^^^^^^^^^^^^^^^^^^^^^^^ 4.1.1. 配置mysql ^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== cat >/usr/local/mysql4/my_multi.cnf <EOF [mysqld_multi] mysqld = /usr/local/mysql4/bin/mysqld_safe mysqladmin = /usr/local/mysql4/bin/mysqladmin user = root [mysqld1] socket = /tmp/mysql_4_1.sock port = 3301 pid-file = /usr/local/mysql4/data_1/hostname.pid datadir = /usr/local/mysql4/data_1 log = /usr/local/mysql4/data_1/hostname.log user = mysql [mysqld2] socket = /tmp/mysql_4_2.sock port = 3302 pid-file = /usr/local/mysql4/data_2/hostname.pid datadir = /usr/local/mysql4/data_2 log = /usr/local/mysql4/data_2/hostname.log user = mysql OEF ======================================================= 4.1.2. 启动mysql ^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== pwd >/usr/local/mysql4 #启动mysqld2个实例 (GNR1和GNR2) bin/mysqld_multi --config-file=./my_multi.cnf start 1,2 >Starting mysqld daemon with databases from /usr/local/mysql4/data_1 >Starting mysqld daemon with databases from /usr/local/mysql4/data_2 #查看端口是否被监听 netstat -lt |grep 33 >tcp 0 0 *:3301 *:* LISTEN >tcp 0 0 *:3302 *:* LISTEN ======================================================= 4.1.3. 测试mysql ^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== pwd >/usr/local/mysql4 #通过mysql_4_1.sock连接3001端口的mysql(GNR1) bin/mysql -u root -S /tmp/mysql_4_1.sock -e "SELECT @@VERSION;" #停止3001端口的mysql(GNR1) bin/mysqld_multi --config-file=./my_multi.cnf stop 1 >STOPPING server from pid file /usr/local/mysql4/data_1/hostname.pid >050223 08:56:04 mysqld ended #再次连接(GNR4),系统会提示错误 bin/mysql -u root -S /tmp/mysql_4_1.sock -e "SELECT @@VERSION;" >ERROR 2002 (HY000): >Can't connect to local MySQL server through socket '/tmp/mysql_4_1.sock' (2) #相同的步骤测试3002端口的mysql(GNR2),输出与上相同 bin/mysql -u root -S /tmp/mysql_4_2.sock -e "SELECT @@VERSION;" bin/mysqld_multi --config-file=./my_multi.cnf stop 2 bin/mysql -u root -S /tmp/mysql_4_2.sock -e "SELECT @@VERSION;" ======================================================= 4.2. 多版本单实例的实现 ^^^^^^^^^^^^^^^^^^^^^^^ 本目标利用启动多个 $MYSQL/bin/mysqld_safe 脚本实现 4.2.1. 配置mysql ^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== #在mysql4/data目录中添加配置文件my.cnf (也可以通过命令行参数实现) cat >/usr/local/mysql4/data/my.cnf<EOF [mysqld] socket = /tmp/mysql_4_4.sock port = 3304 basedir = /usr/local/mysql4 default-character-set = gbk EOF #在mysql5/data目录中添加配置文件my.cnf (也可以通过命令行参数实现) cat >/usr/local/mysql5/data/my.cnf<EOF [mysqld] socket = /tmp/mysql_5_5.sock port = 3305 basedir = /usr/local/mysql5 default-character-set = gbk EOF ======================================================= 4.2.2. 启动与测试 ^^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== #分别启动mysql4和mysql5 cd /usr/local/mysql4 bin/mysqld_safe --user=mysql --pid-file=data/hostname.pid --datadir=data & cd /usr/local/mysql5 bin/mysqld_safe --user=mysql --pid-file=data/hostname.pid --datadir=data & #查看端口是否被监听 netstat -lp|grep 33 >tcp 0 0 *:3304 *:* LISTEN >tcp 0 0 *:3305 *:* LISTEN #查看mysql版本 bin/mysql -u root -S /tmp/mysql_4_4.sock -e "SELECT @@VERSION;" bin/mysql -u root -S /tmp/mysql_5_5.sock -e "SELECT @@VERSION;" #检测mysql5 bin/mysql -u root -S /tmp/mysql_5_5.sock #停止mysql bin/mysqladmin -u root -S /tmp/mysql_4_4.sock shutdown bin/mysqladmin -u root -S /tmp/mysql_5_5.sock shutdown ======================================================= 4.3. 多版本多实例的实现 ^^^^^^^^^^^^^^^^^^^^^^^ 利用启动多个 $MYSQL/bin/mysqld_multi 脚本实现,其方法同目标1 4.3.1. 配置mysql ^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== #仿造目标1方法,创建mysql5的配置 cat >/usr/local/mysql5/my_multi.cnf [mysqld_multi] mysqld = /usr/local/mysql5/bin/mysqld_safe mysqladmin = /usr/local/mysql5/bin/mysqladmin user = root [mysqld1] socket = /tmp/mysql_5_8.sock port = 3308 pid-file = /usr/local/mysql5/data_1/hostname.pid datadir = /usr/local/mysql5/data_1 log = /usr/local/mysql5/data_1/hostname.log user = mysql [mysqld2] socket = /tmp/mysql_5_9.sock port = 3309 pid-file = /usr/local/mysql5/data_2/hostname.pid datadir = /usr/local/mysql5/data_2 log = /usr/local/mysql5/data_2/hostname.log user = mysql EOF ======================================================= 4.3.2. 启动与测试 ^^^^^^^^^^^^^^^^^ =============== tty : root@trydofor =================== cd /usr/local/mysql4 bin/mysqld_multi --config-file=./my_multi.cnf start 1,2 >Starting mysqld daemon with databases from /usr/local/mysql4/data_1 >Starting mysqld daemon with databases from /usr/local/mysql4/data_2 netstat -lt |grep 33 >tcp 0 0 *:3301 *:* LISTEN >tcp 0 0 *:3302 *:* LISTEN >tcp 0 0 *:3308 *:* LISTEN >tcp 0 0 *:3309 *:* LISTEN bin/mysql -u root -S /tmp/mysql_4_1.sock -e "SELECT @@VERSION;" bin/mysql -u root -S /tmp/mysql_4_1.sock -e "SELECT @@VERSION;" bin/mysql -u root -S /tmp/mysql_5_8.sock -e "SELECT @@VERSION;" bin/mysql -u root -S /tmp/mysql_5_9.sock -e "SELECT @@VERSION;" bin/mysql -u root -S /tmp/mysql_5_8.sock ======================================================= 5. 常见问题 ^^^^^^^^^^^ * 系统环境变量的设定 很多linux发行版都把/usr/local/mysql加入了$PATH,同时/usr/bin/下 还有很多mysql命令和脚本。如果不注意,可能启动了错误版本的命令。 * $MYSQL/scripts/mysql_install_db 初始化不成功 这时要停掉系统中运行的mysqld,否则就要修改mysql_install_db 才能成功运行。---- 我是没有成功修改过:( * $MYSQL/bin/mysqld_multi 启动多本版可能不正确 即,把msyql4和mysql5写在一个配置文件指定不同的中通过一个mysqld_multi启动。 [mysqld_multi] user = root [mysqld4] socket = /tmp/mysql_4_4.sock port = 3304 pid-file = /usr/local/mysql4/data/hostname.pid datadir = /usr/local/mysql4/data log = /usr/local/mysql4/data/hostname.log user = mysql [mysqld5] socket = /tmp/mysql_5_5.sock port = 3305 pid-file = /usr/local/mysql5/data/hostname.pid datadir = /usr/local/mysql5/data log = /usr/local/mysql5/data/hostname.log user = mysql 当用mysql5中的mysqld_multi启动时,查看mysql版本都显示5的信息 使用4)中的语句测试,都不通过。原因尚在调查中... * 下面语句在mysql5上可以成功通过(主要是最后一句) use test; drop table if exists t3; create table t3 ( userid bigint(20) not null default 0 ); drop procedure if exists bug8116; create procedure bug8116(in _userid int) select * from t3 where userid = _userid; call bug8116(42); * /usr/local/mysql4/bin/mysqld_safe 的启动参数 --socket=/tmp/mysql_4_1.sock --port=3301 --pid-file=/usr/local/mysql4/data_1/hostname.pid --datadir=/usr/local/mysql4/data_1 --log=/usr/local/mysql4/data_1/hostname.log --user=mysql 也可以cat /usr/local/mysql4/bin/mysqld_safe * /usr/local/mysql4/bin/mysqld_multi 的启动错误 WARNING! my_print_defaults command not found! .... FATAL ERROR: Tried to use mysqladmin in group [mysqld1], but no mysqladmin binary was found.Please add "mysqladmin=..." in group [mysqld_multi], or in group [mysqld1]. .... 解决办法,#export PATH=$PATH:/usr/local/msyql4/bin 可以把高版本的path加入,也可以利用不同用户分别加入和启动。 如果使用mysqld_safe单独启动每个服务器,可以不加入PATH * 如果要深入研究mysql的启动,还是要好好理解一下他的启动脚本 :) 6. 参考资料 ^^^^^^^^^^^ * [[Using Option Files=>http://dev.mysql.com/doc/mysql/en/option-files.html]] * [[The mysqld_safe Server Startup Script=>http://dev.mysql.com/doc/mysql/en/mysqld-safe.html]] * [[The mysqld_multi Program for Managing Multiple MySQL Servers=>http://dev.mysql.com/doc/mysql/en/mysqld-multi.html]] * [[Running Multiple Servers on Unix=>http://dev.mysql.com/doc/mysql/en/multiple-unix-servers.html]] * [[MySQL Lists: internals: bk commit into 5.0 tree (pem:1.1857) BUG#8116=>http://lists.mysql.com/internals/22163]]