RedHat 上安装多个 mysql 实例并配置 django 连接的操作记录
Redhat 服务器上原有一个 MySQL 3.23.58 的实例。现欲安装一个 5.0 的实例到另一个端口,配合 django 程序使用。今天配置过程中遇到了不少问题,所幸最终都解决了,记录如下。
在一个 linux 服务器上安装多个实例,需要指定第二个实例安装在不同的端口,和不同的 unix socket 文件,以及独立的数据存放路径等参数。
首先查看服务器上现有 mysql 的安装状态:
mysqladmin -p --host=localhost --port=3306 variables
得到现有 mysql 实例的关键信息如下:
socket | /var/lib/mysql/mysql.sock
datadir | /var/lib/mysql/
basedir | /usr/
bdb_home | /var/lib/mysql/
bdb_tmpdir | /tmp/
character_set | latin1
language | /usr/share/mysql/english/
pid_file | /var/run/mysqld/mysqld.pid
version | 3.23.58-log
下载 mysql 5.0 的源代码版本:
wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.37.tar.gz/from/http://mysql.mirrors.pair.com/
解压:
tar zxvf mysql-5.0.37
开始配置,并编译安装:
cd mysql-5.0.37
./configure --prefix=/usr/local/mysql50 --with-charset=utf8 --with-extra-charset=all --with-unix-socket-path=/tmp/mysql5037.sock --with-tcp-port=3308
make
make install
安装 mysql 默认数据库:
scripts/mysql_install_db --user=mysql
启动 mysql:
cd /usr/local/mysql50
bin/mysqld_safe --socket=/tmp/mysql5037.sock --port=3308 &
查看一下 3308 端口是否已经在监听:
netstat -anp|grep LISTEN
为方便远程管理,在防火墙中开放 3308 端口。打开 /etc/sysconfig/iptables 文件并编辑,增加下面一行:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3308 -j ACCEPT
重启 iptables 使防火墙更改生效:
service iptables restart
给 root 指定密码:
/usr/local/mysql50/bin/mysqladmin --socket=/tmp/mysql5037.sock --port=3308 -u root password '密码'
修改 root 对应的 host 为 '%' 以允许在任意 ip 访问(默认是 localhost)。需要进入 mysql 命令行:
/usr/local/mysql50/bin/mysql --socket=/tmp/mysql5037.sock --port=3308 -u root -p
mysql> use mysql;
mysql> update user set host='%' where user='root';
需要刷新授权信息:
mysql> flush privileges;
如果不行的话试试重启 mysql:
/usr/local/mysql50/bin/mysqladmin -u root --socket=/tmp/mysql5037.sock --port=3308 -p reload
可以通过 ps 命令查看 mysql 进程:
ps -ef|grep mysql
或者 ps -axjf|grep mysql
MySQL 基本是配置好了,然后我尝试了用 django 来连接新的实例。出现问题了。
在 settings.py 中原先是这样配置的:
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'xxx'
DATABASE_USER = 'root'
DATABASE_PASSWORD = 'jfksdjfksdf'
DATABASE_HOST = ''
DATABASE_PORT = ''
这个连接的是默认的 mysql 实例,3306 端口的。
于是我改成
DATABASE_HOST = ''
DATABASE_PORT = '3308'
结果发现还是在连接老的数据库。说明这个端口的指定根本没起作用。什么原因呢?
正在没办法的时候看到了这篇文章:
http://hideto.javaeye.com/blog/42996
“翻译www.djangobook.com之第五章:与数据库交互:模型”
引用其中一段:
“5,DATABASE_HOST告诉Django你连接数据库的主机,如果你的数据库和Django安装在同一台计算机上,则这项为空
如果你使用SQLite,这项为空
MySQL在这里很特殊,如果这项的值以'/'开头并且你使用MySQL,MySQL会通过Unix socket连接特殊的socket
例如DATABASE_HOST = '/var/run/mysql/'
如果你使用MySQL但这项的值不是以'/'开头,那么这项的值就假设为所连接的主机 ”
看到这里才知道 mysql 连接的 host 是需要指定 unix socket 文件的位置的(如果连接的不是实例)。
于是我试着配置成了这样:
DATABASE_HOST = '/tmp/mysql5037.sock'
DATABASE_PORT = '3308'
这个配置后还出现了几次很怪的问题。大致上是说:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
试了几次后,我终于发现,这个问题的原因在于:用于本机的 django 程序连接 mysql 的用户,其 host 字段必须是 localhost. 如果设置成 '%' 则不能访问。(这个很奇怪,因为之前我连接老的数据库时记得不是这样的。)所以,我增加了一个新的用户,将其 host 设为 localhost, 赋予了相应的权限,让 django 用这个用户来连接就可以了。root 对应的 host 仍然是 '%' 便于远程管理。
第二个错误:
_mysql_exceptions.OperationalError: (1251, 'Client does not support authentication protocol requested by server; consider upgrading MySQL client')
大致的意思是在说 mysql client 不支持服务器的某种身份验证协议。于是我查了一下网络,说是在 mysql 4.x 之后,身份验证机制发生了变化,这样一些老的客户端程序就不能适应了。我估计可能是我用的 MySQL-python 的版本比较低造成的。
解决这个问题的办法有好几种,我用了简单的一种,就是更改用户的密码格式为旧的验证方式(可能需要重启服务器并指定在 old-password 模式下运行,我没用得着这个步骤)。
大致操作就是:
mysql> set password for 'neilchen'@'localhost' = old_password('密码');
这样再重启 django 就搞定了:
nohup python manage.py runserver 0.0.0.0:9999 &
在一个 linux 服务器上安装多个实例,需要指定第二个实例安装在不同的端口,和不同的 unix socket 文件,以及独立的数据存放路径等参数。
首先查看服务器上现有 mysql 的安装状态:
mysqladmin -p --host=localhost --port=3306 variables
得到现有 mysql 实例的关键信息如下:
socket | /var/lib/mysql/mysql.sock
datadir | /var/lib/mysql/
basedir | /usr/
bdb_home | /var/lib/mysql/
bdb_tmpdir | /tmp/
character_set | latin1
language | /usr/share/mysql/english/
pid_file | /var/run/mysqld/mysqld.pid
version | 3.23.58-log
下载 mysql 5.0 的源代码版本:
wget http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-5.0.37.tar.gz/from/http://mysql.mirrors.pair.com/
解压:
tar zxvf mysql-5.0.37
开始配置,并编译安装:
cd mysql-5.0.37
./configure --prefix=/usr/local/mysql50 --with-charset=utf8 --with-extra-charset=all --with-unix-socket-path=/tmp/mysql5037.sock --with-tcp-port=3308
make
make install
安装 mysql 默认数据库:
scripts/mysql_install_db --user=mysql
启动 mysql:
cd /usr/local/mysql50
bin/mysqld_safe --socket=/tmp/mysql5037.sock --port=3308 &
查看一下 3308 端口是否已经在监听:
netstat -anp|grep LISTEN
为方便远程管理,在防火墙中开放 3308 端口。打开 /etc/sysconfig/iptables 文件并编辑,增加下面一行:
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 3308 -j ACCEPT
重启 iptables 使防火墙更改生效:
service iptables restart
给 root 指定密码:
/usr/local/mysql50/bin/mysqladmin --socket=/tmp/mysql5037.sock --port=3308 -u root password '密码'
修改 root 对应的 host 为 '%' 以允许在任意 ip 访问(默认是 localhost)。需要进入 mysql 命令行:
/usr/local/mysql50/bin/mysql --socket=/tmp/mysql5037.sock --port=3308 -u root -p
mysql> use mysql;
mysql> update user set host='%' where user='root';
需要刷新授权信息:
mysql> flush privileges;
如果不行的话试试重启 mysql:
/usr/local/mysql50/bin/mysqladmin -u root --socket=/tmp/mysql5037.sock --port=3308 -p reload
可以通过 ps 命令查看 mysql 进程:
ps -ef|grep mysql
或者 ps -axjf|grep mysql
MySQL 基本是配置好了,然后我尝试了用 django 来连接新的实例。出现问题了。
在 settings.py 中原先是这样配置的:
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'xxx'
DATABASE_USER = 'root'
DATABASE_PASSWORD = 'jfksdjfksdf'
DATABASE_HOST = ''
DATABASE_PORT = ''
这个连接的是默认的 mysql 实例,3306 端口的。
于是我改成
DATABASE_HOST = ''
DATABASE_PORT = '3308'
结果发现还是在连接老的数据库。说明这个端口的指定根本没起作用。什么原因呢?
正在没办法的时候看到了这篇文章:
http://hideto.javaeye.com/blog/42996
“翻译www.djangobook.com之第五章:与数据库交互:模型”
引用其中一段:
“5,DATABASE_HOST告诉Django你连接数据库的主机,如果你的数据库和Django安装在同一台计算机上,则这项为空
如果你使用SQLite,这项为空
MySQL在这里很特殊,如果这项的值以'/'开头并且你使用MySQL,MySQL会通过Unix socket连接特殊的socket
例如DATABASE_HOST = '/var/run/mysql/'
如果你使用MySQL但这项的值不是以'/'开头,那么这项的值就假设为所连接的主机 ”
看到这里才知道 mysql 连接的 host 是需要指定 unix socket 文件的位置的(如果连接的不是实例)。
于是我试着配置成了这样:
DATABASE_HOST = '/tmp/mysql5037.sock'
DATABASE_PORT = '3308'
这个配置后还出现了几次很怪的问题。大致上是说:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
试了几次后,我终于发现,这个问题的原因在于:用于本机的 django 程序连接 mysql 的用户,其 host 字段必须是 localhost. 如果设置成 '%' 则不能访问。(这个很奇怪,因为之前我连接老的数据库时记得不是这样的。)所以,我增加了一个新的用户,将其 host 设为 localhost, 赋予了相应的权限,让 django 用这个用户来连接就可以了。root 对应的 host 仍然是 '%' 便于远程管理。
第二个错误:
_mysql_exceptions.OperationalError: (1251, 'Client does not support authentication protocol requested by server; consider upgrading MySQL client')
大致的意思是在说 mysql client 不支持服务器的某种身份验证协议。于是我查了一下网络,说是在 mysql 4.x 之后,身份验证机制发生了变化,这样一些老的客户端程序就不能适应了。我估计可能是我用的 MySQL-python 的版本比较低造成的。
解决这个问题的办法有好几种,我用了简单的一种,就是更改用户的密码格式为旧的验证方式(可能需要重启服务器并指定在 old-password 模式下运行,我没用得着这个步骤)。
大致操作就是:
mysql> set password for 'neilchen'@'localhost' = old_password('密码');
这样再重启 django 就搞定了:
nohup python manage.py runserver 0.0.0.0:9999 &