不论是即将开发的程序,还是开发过程中必不可少的git、wiki等工具,它们都需要用数据库来保存自身的数据,所以搭建服务器的第一步自然是先把mysql搭起来。

1. 安装mysql-server

第一步当然是要安装好mysql-server。虽然通过apt默认源亦可完成安装,但是看mysql官方说明推荐用他们的源,就照着办吧!

1
2
3
4
5
6
7
8
# 切到/tmp目录,下载官方apt源的配置文件并安装
cd /tmp
wget http://dev.mysql.com/get/mysql-apt-config_0.8.1-1_all.deb
dpkg -i mysql-apt-config_0.8.1-1_all.deb
# 更新软件源,安装mysql-server
apt update
apt install mysql-server

配置源的时候会问你想安装哪些组件、什么版本,作为服务器,只需要安装mysql-server,而出于稳定性考虑,选择5.7的稳定版本;安装的过程中,会要求输入数据库root用户的密码,总共就这2步操作~

2. 修改数据库端口和路径

刚刚安装好的mysql-server有一些配置可能不完全适用于我们的环境,因此需要修改一下,主要是数据库端口和路径。修改配置之前需要先停止mysql服务,顺带着复习下服务的简单操作。

1
2
3
4
5
6
7
8
# 启动mysql服务
service mysql start
# 停止mysql服务
service mysql stop
# 查看mysql服务当前状态
service mysql status

2.1 配置文件在哪

网上说,mysql默认从这4个地方寻找配置文件,以先找到的为准,而ubuntu系统中,配置文件默认是下面的第2个

1
2
3
4
/etc/my.cnf
/etc/mysql/my.cnf
/usr/etc/my.cnf
~/.my.cnf

但是有点奇怪,打开这第2个文件,里面只有一行

1
!includedir /etc/mysql/conf.d/

字面上的意思应该是加载/etc/mysql/conf.d/下的文件,再打开这个目录,只有一个配置组是[mysql]的空的配置文件。

进一步看了下,真正的配置文件应该是/etc/mysql/mysql.cnf,因为它进一步加载了/etc/mysql/mysql.conf.d/mysqld.cnf文件,而我们要修改的[mysqld]配置组正位于其中。这个问题还待熟悉mysql配置的同学解释下哈。

2.2 修改数据库端口

mysql默认监听3306端口,这是大多数人都知道的。但是呢,出于安全考虑,线上服务基本上不会保持默认端口,甚至都不会开启这附近的端口区间。要修改这个默认监听的端口,只需要修改(添加)port配置项等号后面的数字

1
2
port = 10086
bind-address = 0.0.0.0

顺带着地,把bind-address配置项也修改一下,它的默认值是localhost,也就意味着只能从本机连接到mysql服务,这不符合我们的需求,将它改成上面的0.0.0.0即放开这个限制。

2.3 修改数据库路径

mysql默认将数据库及自身的许多重要文件放置在/var/lib/mysql这个目录下,对大多数云主机来说,这个目录就位于系统盘中,这样即不方便也不安全,再者我们的云主机都购买了数据盘呢,显然应该将这个目录移出来。

如果不放心到底是不是这个目录,可以登录mysql命令行,运行一下

1
show variables like '%dir%';

其中data_dir变量的值就是当前数据库的路径。

接着即可修改配置文件中的data_dir配置项了

1
2
datadir = /data/mysql
log-error = /data/logs/mysql/error.log

顺带着的,可以将log的路径也修改一下。修改完路径别忘了把已有的文件复制过去,复制的时候千万留意权限的变化。

3. 踩坑时间

敲!黑!板!以为这样就万事大吉,可以重启服务了?嗯,重启是没报错,可是配置也没有生效啊……

3.1 那啥AppArmor

实话说,我也不知道这是啥,资料显示是ubuntu的一种沙箱机制吧,反正2.3节修改数据库路径的时候,少了这一步可不行(惯性思维了,以前Windows上没这一步),而且就是它导致了没报错、配置却不生效。

一开始我看了这篇文章,相应地修改了/etc/apparmor.d/usr.sbin.mysqld和/etc/apparmor.d/abstractions/mysql两个文件。

结果好了,启动报错还没有任何日志输出,谷歌一下大部分结果出错的还都是mysqld.service而不是我遇到的mysql.service

1
Job for mysql.service failed. See 'systemctl status mysqld.service' and 'journalctl -xn' for details.

幸运的是后来又找到了另一篇文章。这篇文章提到了另一种思路,为数据库路径起个别名,而不是直接改掉路径。

需要修改的文件变成了/etc/apparmor.d/tunables/alias,打开这个文件,赫然发现这么一行

1
2
# Or if mysql databases are stored in /home:
alias /var/lib/mysql/ -> /data/mysql/,

真的是柳暗花明啊,改之,然后别忘了先重启apparmor服务,后重启mysql服务/。瞄一眼新的数据库路径,文件的修改时间变了,日志也写进来了,Oh yeah~

3.2 登录不了了

改完了总得测试下吧?

1
mysql -uroot -p

曾经的mysql>提示符没看到,看到的是

1
ERROR 1698 (28000): Access denied for user 'root'@'localhost'.

密码肯定没错,如果本地都不能以root登录,那未必……,更奇怪的是,加上sudo就可以登录,看来是权限又给我桶啥篓子了(所以我说前面复制文件的时候注意权限),可检查了一番似乎又没啥问题

继续谷歌吧,解决方案这回倒不难找,可人家多是安装了mariadb导致的,我并没有哇!

反正最终的解决方案就是重新建了个root用户,刚好我这边会有多个应用共用一个数据库,为了控制好权限,每个应用有自己的数据库用户名和密码,就当是复习下mysql用户操作了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 删除用户root
drop user 'root'@'localhost';
# 创建用户root 只允许从localhost登录 密码123456
create user 'root'@'localhost' identified by '123456';
# 修改root用户密码(直接重置密码后会要求执行以下命令)
alter user 'root'@'localhost' identified by '123456';
# 赋予用户root全部权限 允许转授权
grant all privileges on *.* to 'root'@'localhost' with grant option;
# 权限立即生效
flush privileges;

内容就是这些了,如果有同学能帮我解释踩下的几个坑,欢迎留言。