手动安装mysql

在战舰少女贴吧里,偶尔能看到的一个说法叫做“这活动我用脚打都能过”,意思是活动关卡很容易(实际上有时候并非真的那么简单,仅仅是调侃)。在安装mysql这件事情上,也有用脚安装和用手安装两种。

典型的用脚安装就是使用系统的包管理器。例如在我的LinuxMint系统中,在shell中键入下列命令就可以装上mysql

sudo apt-get install mysql-server

遗憾的是,包管理器并不是任何时候都可用的。举个例子:以前在UC,研发团队是可以申请到一些机器用于分配给开发人员使用的,但如果要在上面使用数据库,那么多半需要开发人员自己动手部署。此外,只要掌握了手动部署单个mysql实例的方法,就可以轻松地在一台机器上部署多个mysql实例了,而这正是我最近需要完成的一个任务。为了方便自己很久之后查阅,也为了帮到其他有此类需求的程序员,我写了这篇手动安装的指南。

初始化数据库

安装mysql的第一步,是创建数据库运行所需要的一系列文件。在5.7.6版本之前的mysql中,这个过程是由mysql_install_db这个脚本完成的。在5.7.6的发行版中,这个功能被集成到了mysqld中,下面的操作也是基于mysqld实现的。mysqld提供了执行用于初始化的命令行选项:

  • --initialize
  • --initialize-insecure

--initialize-insecure会为数据库的root账户设置空的密码,方便稍后登录,因此将选用这一个初始化的方法。

为了初始化数据库,还需要指定mysql的安装目录和存放数据文件的目录。安装目录即mysql的二进制安装包解压缩后生成的目录,而存放数据文件的目录则可以自由选择。这两个路径分别传递给mysqld的--basedir和--datadir参数。为了方便起见,也为了避免mysqld启动后读取了已存在的mysql配置文件造成干扰,我将这两个参数写到了配置文件中。在我的机器上配置文件路径是~/local/mysql/my.cnf,内容如下

[mysqld]
basedir = /home/liutos/local/mysql
datadir = /home/liutos/data/mysql/data

需要注意的是,根据官方文档的说明,datadir所设置的目录,必须为一个尚不存在的目录或者是一个空目录。在我的系统中,/home/liutos/data/mysql/data是一个尚未创建的目录。

现在可以进行初始化了。因为在我的系统上解压缩后的目录为~/local/mysql,因此在shell中执行的命令为

cd ~/local/mysql/
./bin/mysqld --defaults-file=/home/liutos/local/mysql/my.cnf --initialize-insecure --user=`whoami`

启动数据库服务

完成初始化后就可以启动mysqld了。启动的命令为

./bin/mysqld_safe --defaults-file=/home/liutos/local/mysql/my.cnf --user=`whoami` > /dev/null 2>&1 &

由于在我的系统中,已经使用包管理器安装了mysql服务并且正在监听着3306端口,为此必须修改即将启动的mysqld进程所监听的端口。监听的端口号可以通过配置文件来指定,修改后的配置文件如下

[mysqld]
basedir = /home/liutos/local/mysql
datadir = /home/liutos/data/mysql/data
port = 3307 # 新增该行

现在可以执行刚才的启动命令了。成功启动后,使用netstat -apn | grep '3307'应当可以看到类似下文的输出

tcp6       0      0 :::3307                 :::*                    LISTEN      30898/mysqld

登录数据库

一番波折,终于可以登录了。因为当初是使用--initialize-insecure执行初始化的,root账户没有登录密码,因此在shell中键入下列命令登录

mysql -u root --skip-password -h 127.0.0.1 -P 3307

登录后建议为root账户设置登录密码。例如,我要给root账户设置密码为1234567,就执行下列SQL语句

ALTER USER 'root'@'localhost' IDENTIFIED BY '1234567';

UNIX socket配置

按照上述步骤启动后,mysqld会在系统的/tmp目录下创建一个mysql.sock文件。此时如果再按照上述步骤是无法启动另一个mysql实例的,因此每一个mysqld必须使用单独的.sock文件。这可以通过配置文件来实现,在我的系统上的配置如下

[mysqld]
basedir = /home/liutos/local/mysql
datadir = /home/liutos/data/mysql/data
port = 3307
socket = /home/liutos/local/mysql/mysql.sock # 新增该行