本文主要介绍MySQL二进制安装的方式以及简单的权限管理方法。
1 环境配置
服务器:DELL PowerEdge R740
CPU:QEMU Virtual CPU version 2.5+
内存:4GB
MySQL:5.7.21 MySQL Community Server
操作系统:Centos 7.5
内核:3.10.0-862
MySQL架构:单主
2 MySQL的安装&安全加固
MySQL有多种安装方式,例如yum安装、源码安装、二进制安装,这里我们介绍一下最流行的安装方式:二进制安装。
首先我们到MySQL的官方网站获取MySQL的二进制安装包。
官方网站地址:downloads.mysql.com/archives/co…
图1
下载页面可以选择MySQL的版本,这里以5.7.21为例。
将下载好的MySQL二进制安装包放到我们的服务器中,然后进行MySQL用户创建。
[root@dk-14 ~]# groupadd mysql
[root@dk-14 ~]# useradd mysql -r -g mysql
[root@dk-14 ~]# id mysql
uid=500(mysql) gid=500(mysql) groups=500(mysql)
用户创建完毕后,进入MySQL安装包所在的目录,将准备好的MySQL安装包进行解压,示例中将MySQL安装包放在了/usr/local/tool下面。
[root@dk-14 ~]# cd /usr/local/tool/
[root@dk-14 tool]# ls
mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz
[root@dk-14 tool]# tar -xf mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz
[root@dk-14 tool]# ls
mysql-5.7.21-linux-glibc2.12-x86_64 mysql-5.7.21-linux-glibc2.12-x86_64.tar.gz
解压完成后,将解压出来的包移动到/usr/local下面,并重命名为mysql。
[root@dk-14 tool]# mv mysql-5.7.21-linux-glibc2.12-x86_64 /usr/local/mysql
[root@dk-14 tool]# ll /usr/local/mysql/
total 36
drwxr-xr-x 2 root root 4096 Dec 6 07:18 bin
-rw-r--r-- 1 7161 31415 17987 Dec 28 2017 COPYING
drwxr-xr-x 2 root root 55 Dec 6 07:18 docs
drwxr-xr-x 3 root root 4096 Dec 6 07:17 include
drwxr-xr-x 5 root root 229 Dec 6 07:18 lib
drwxr-xr-x 4 root root 30 Dec 6 07:18 man
-rw-r--r-- 1 7161 31415 2478 Dec 28 2017 README
drwxr-xr-x 28 root root 4096 Dec 6 07:18 share
drwxr-xr-x 2 root root 90 Dec 6 07:18 support-files
将MySQL程序软链接到/usr/local/bin下面,以便使用MySQL相关命令时不需要输入绝对路径
[root@dk-14 tool]# ln -s /usr/local/mysql/bin/mysql /usr/local/bin/*
[root@dk-14 tool]# ls /usr/local/bin/
mysql mysqlcheck mysql_config_editor mysqld_multi mysqldumpslow mysql_install_db mysql_secure_installation mysql_ssl_rsa_setup mysql_upgrade
mysqladmin mysql_client_test_embedded mysqld mysqld_safe mysql_embedded mysql_plugin mysqlshow mysqltest_embedded mysqlxtest
mysqlbinlog mysql_config mysqld-debug mysqldump mysqlimport mysqlpump mysqlslap mysql_tzinfo_to_sql
[root@dk-14 tool]# mysql -V
mysql Ver 14.14 Distrib 5.7.21, for linux-glibc2.12 (x86_64) using EditLine wrapper
执行mysql -V命令,显示如上结果,说明MySQL命令安装成功,接下来进行创建MySQL的数据存放目录,并对数据目录授权。
[root@dk-14 tool]# mkdir -p /dbase/3306
[root@dk-14 tool]# cd /dbase/3306
[root@dk-14 3306]# mkdir binlog data logs relaylog tmp undo redo
[root@dk-14 3306]# **chown -R mysql:mysql ***
[root@dk-14 3306]# ll
total 0
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 binlog
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 data
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 logs
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 redo
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 relaylog
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 tmp
drwxr-xr-x 2 mysql mysql 6 Dec 6 07:39 undo
数据目录创建好并授权完毕后,配置MySQL的配置文件,定义一些基础的参数(此处只列出配置的一些基础参数,更多配置文件参数的会在后面的章节中进行学习)
[root@dk-14 3306]# mkdir -p /etc/mysql
[root@dk-14 3306]# cat /etc/mysql/my-3306.cnf
[mysqld]
basedir=/usr/local/mysql
datadir=/dbase/3306/data
socket=/tmp/mysql-3306.sock
server-id=330614
port=3306
pid-file=/dbase/3306/logs/mysql-3306.pid
log-error=/dbase/3306/logs/err.log
log_bin=/dbase/3306/binlog/mysql-bin
log_bin_index=/dbase/3306/binlog/mysql-bin.index
tmpdir=/dbase/3306/tmp
MySQL配置文件配置完毕后,使用mysqld命令和MySQL配置文件进行MySQL的初始化
[root@dk-14 3306]# mysqld --defaults-file=/etc/mysql/my-3306.cnf
--initialize --user='mysql' &
[root@dk-14 3306]# ll data/
total 12324
-rw-r----- 1 mysql mysql 56 Dec 6 07:54 auto.cnf
-rw-r----- 1 mysql mysql 435 Dec 6 07:54 ib_buffer_pool
-rw-r----- 1 mysql mysql 12582912 Dec 6 07:54 ibdata1
drwxr-x--- 2 mysql mysql 4096 Dec 6 07:54 mysql
drwxr-x--- 2 mysql mysql 8192 Dec 6 07:54 performance_schema
drwxr-x--- 2 mysql mysql 8192 Dec 6 07:54 sys
初始化完毕后,data目录下出现上述文件,并且logs/err.log中未出现ERROR信息,说明初始化成功,之后我们将初始化完成的MySQL进行启动
[root@dk-14 3306]# mysqld_safe --defaults-file=/etc/mysql/my-3306.cnf --user=mysql &
[1] 100
2019-12-06T07:58:50.643525Z mysqld_safe Logging to '/dbase/3306/logs/err.log'.
2019-12-06T07:58:50.689030Z mysqld_safe Starting mysqld daemon with databases from /dbase/3306/data
\
[root@dk-14 3306]# ps -ef | grep mysqld
root 100 35 0 07:58 pts/1 00:00:00 /bin/sh /usr/local/bin/mysqld_safe --defaults-file=/etc/mysql/my-3306.cnf --user=mysql
mysql 578 100 4 07:58 pts/1 00:00:00 /usr/local/mysql/bin/mysqld --defaults-file=/etc/mysql/my-3306.cnf --basedir=/usr/local/mysql --datadir=/dbase/3306/data --plugin-dir=/usr/local/mysql/lib/plugin --user=mysql --log-error=/dbase/3306/logs/err.log --pid-file=/dbase/3306/logs/mysql-3306.pid --socket=/tmp/mysql-3306.sock --port=3306
root 607 35 0 07:59 pts/1 00:00:00 grep mysqld
[root@dk-14 3306]# netstat -an | grep 3306
tcp 0 0 :::3306 :::* LISTEN
unix 2 [ ACC ] STREAM LISTENING 9018441 /tmp/mysql-3306.sock
MySQL启动成功后,会启动mysqld_safe和mysqld两个进程,这两个进程分别是MySQL的守护进程和主进程,并且开放操作系统的3306端口。这时候MySQL的安装步骤全部完成,我们可以对安装完毕的MySQL进行登录操作。
MySQL初始化完成后在error log中给root用户生成一个随机的默认密码,我们可以通过查看err.log获取到这个默认密码或者直接将密码过滤出来
[root@dk-14 3306]# cat logs/err.log | grep root@localhost: | awk -F ": " '{print $2}'
saEdD0p8--oj
获得这个随机的默认密码后,我们可以使用这个密码进行第一次登陆。
[root@dk-14 3306]# mysql -uroot -p'saEdD0p8--oj' -S /tmp/mysql-3306.sock
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.21-log
\
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
\
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
\
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
\
mysql>
这时候我们执行任何命令,MySQL都会提示让我们进行密码重设。
mysql> SHOW DATABASES;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
我们根据提示中的信息进行密码修改,就可以对数据库进行正常操作了。
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '12345678';
Query OK, 0 rows affected (0.05 sec)
\
mysql> SHOW DATABASES:
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.03 sec)
3 用户权限管理
数据库安装完毕后,就可以正常登录数据库了,登录数据库就需要用到数据库的用户。而数据库的用户有一套自己的管理规则,下面我们简单了解一下数据库用户的权限管理。
首先我们可以通过mysql.user表来看一下数据库的默认用户。
mysql> SELECT user,host FROM mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
3 rows in set (0.00 sec)
可以看到,在mysql 5.7中有三个默认用户,分别是mysql.session@localhost,mysql.sys@localhost,root@localhost,简单介绍一下这三个用户的用处。
mysql.sys@localhost: 用于sys schema中对象的定义。使用 mysql.sys 用户可避免DBA重命名或者删除root用户时发生的问题。该用户已被锁定,客户端无法连接。
mysql.session@localhost: 插件内部使用来访问服务器。该用户已被锁定,客户端无法连接。
root@localhost: 这个就是root账号,其用于管理。该用户拥有所有权限,可执行任何操作,localhost仅限于本地用户登录。
除了MySQL的默认账号,我们还可以自建账号来登录数据库,这里我们用默认的root用户创建一个test账号
mysql> CREATE USER test@'%' IDENTIFIED BY 'test';
Query OK, 0 rows affected (0.01 sec)
\
\
这时我们可以通过mysql.user表查看test用户的用户名、主机名以及加密后的密码
mysql> SELECT user,host,authentication_string FROM mysql.user
WHERE user='test';
+------+------+-------------------------------------------+
| user | host | authentication_string |
+------+------+-------------------------------------------+
| test | % | *94BDCEBE19083CE2A1F959FD02F964C7AF4CFC29 |
+------+------+-------------------------------------------+
1 row in set (0.00 sec)
然后我们用test用户对数据库进行登录。
[root@dk-14 3306]# mysql -utest -ptest -S /tmp/mysql-3306.sock
\
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)
可以看到,用test用户进行登录,当前只能看到information_schema库,因为现在test用户对其他数据库并没有权限,test用户的权限我们可以用SHOW GRANTS语句来看到。
mysql> SHOW GRANTS FOR test@'%';
+----------------------------------+
| Grants for test@% |
+----------------------------------+
| GRANT USAGE ON . TO 'test'@'%' |
+----------------------------------+
1 row in set (0.00 sec)
如果希望test用户查看到mysql库,可以通过GRANT语句来对test用户进行授权。
[root@dk-14 3306]# mysql -uroot -p12345678 -S /tmp/mysql-3306.sock
\
mysql> GRANT SELECT ON mysql. to 'test'@'%';*
Query OK, 0 rows affected (0.00 sec)
\
mysql> SHOW GRANTS FOR test@'%';
+-----------------------------------------+
| Grants for test@% |
+-----------------------------------------+
| GRANT USAGE ON . TO 'test'@'%' |
| GRANT SELECT ON
mysql.* TO 'test'@'%' |+-----------------------------------------+
2 rows in set (0.00 sec)
这时我们使用test用户进行登录,就可以看到mysql库了。
[root@dk-14 3306]# mysql -utest -ptest -S /tmp/mysql-3306.sock
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
+--------------------+
2 rows in set (0.00 sec)
\
mysql> USE mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
\
Database changed
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| engine_cost |
| event |
| func |
| gtid_executed |
…………
| time_zone_transition_type |
| user |
+---------------------------+
31 rows in set (0.01 sec)
上面我们看到了mysql库里面的所有的表,但如果我们只想让test用户看到mysql库的user表应该怎么设置?
[root@dk-14 3306]# mysql -uroot -p12345678 -S /tmp/mysql-3306.sock
\
mysql> REVOKE SELECT ON mysql. FROM test@'%';*
Query OK, 0 rows affected (0.01 sec)
\
mysql> GRANT SELECT ON mysql.user TO test@'%';
Query OK, 0 rows affected (0.01 sec)
\
\
\
mysql> SHOW GRANTS FOR test@'%';
+----------------------------------------------+
| Grants for test@% |
+----------------------------------------------+
| GRANT USAGE ON . TO 'test'@'%' |
| GRANT SELECT ON
mysql.userTO 'test'@'%' |+----------------------------------------------+
2 rows in set (0.00 sec)
完成赋权之后重新使用test用户登录
[root@dk-14 3306]# mysql -utest -ptest -S /tmp/mysql-3306.sock
\
mysql> USE mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
\
Database changed
mysql> SHOW TABLES;
+-----------------+
| Tables_in_mysql |
+-----------------+
| user |
+-----------------+
1 row in set (0.00 sec)
如上操作,先使用REVOKE语句回收mysql.*的SELECT权限,再用GRANT语句对mysql.user表授于SELECT权限。
如上述例子中,我们给test用户授权了mysql.user表的SELECT权限,如果我们需要再给mysql.user表一个UPDATE权限应该怎么操作呢?
mysql> GRANT UPDATE ON mysql.user TO test@'%';
Query OK, 0 rows affected (0.01 sec)
\
mysql> SHOW GRANTS FOR test@'%';
+------------------------------------------------------+
| Grants for test@% |
+------------------------------------------------------+
| GRANT USAGE ON . TO 'test'@'%' |
| GRANT SELECT, UPDATE ON
mysql.userTO 'test'@'%' |+------------------------------------------------------+
2 rows in set (0.00 sec)
如上所示,只需要再执行一下GRANT UPDATE,就能把UPDATE权限授予test用户了。
\
\
\
\
MySQL的权限有许多种,下面是所有MySQL权限的列表
图2
MySQL的权限管理可以作用在多个层次上,分别为整个服务器上、单个数据库上,单个表上,单个列上,其权限情况除了可以通过SHOW GRANTS语句查看之外,还可以通过mysql库的系统表来查看,分别可以在mysql.user、mysql.db、mysql. tables_priv、mysql. columns_priv中查询到相关信息.
例如整个服务器对应的mysql.user表:
mysql> SELECT * FROM mysql.user WHERE user='root'\G
*************************** 1. row ***************************
Host: localhost
User: root
Select_priv: Y
Insert_priv: Y
Update_priv: Y
Delete_priv: Y
Create_priv: Y
Drop_priv: Y
Reload_priv: Y
Shutdown_priv: Y
Process_priv: Y
File_priv: Y
Grant_priv: Y
References_priv: Y
Index_priv: Y
Alter_priv: Y
Show_db_priv: Y
Super_priv: Y
Create_tmp_table_priv: Y
Lock_tables_priv: Y
Execute_priv: Y
Repl_slave_priv: Y
Repl_client_priv: Y
Create_view_priv: Y
Show_view_priv: Y
Create_routine_priv: Y
Alter_routine_priv: Y
Create_user_priv: Y
Event_priv: Y
Trigger_priv: Y
Create_tablespace_priv: Y
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin: mysql_native_password
authentication_string: *84AAC12F54AB666ECFC2A83C676908C8BBC381B1
password_expired: N
password_last_changed: 2019-12-10 02:29:14
password_lifetime: NULL
account_locked: N
1 row in set (0.00 sec)
可以看到很多priv后缀的列值都是Y,说明这个用户对所有库都有对应的权限,当某个priv后缀的列值为N,而某个语句需要用到这个列对应的权限时,就会按照相同的规则依次去查询mysql.db、mysql. tables_priv、mysql. columns_priv,若遇到有Y值,则返回有权限,若全是N值,则返回没有当前权限。
安装一套mysql还是挺麻烦的,沃趣科技的QFusion可一键搭建mysql高可用集群,感兴趣的可以去官网irds.cn了解。