MySQL常用安装方式有3种:rpm安装、yum安装、二进制文件安装。
本文介绍rpm安装方式。
组件安装操作步骤参考 组件安装部署手册模板,根据不同组件的安装目标,部分操作可以省略。
本文将按照该参考步骤执行。
一、获取组件可执行程序库,包括主程序,此为组件的基本文件
首先卸载mysql已安装版本,其中,CentOS 7中将mysql替换成了mysql的一个分支产品mariadb,所以需要确认mysql与mariadb未安装或已卸载。
如果系统系统安装时基本环境选择了服务器或开发环境,则mariadb确认会安装。
1.检查是否已安装
[root@localhost local]# yum list installed | grep mysql
[root@localhost local]# yum list installed | grep mariadb
mariadb-libs.x86_64 1:5.5.68-1.el7 @anaconda
2.逐个卸载已安装组件,可以使用 mariadb* 卸载全部相关
[root@localhost local]# yum remove mariadb-libs.x86_64 #可以mariadb*全部卸载
已加载插件:fastestmirror, langpacks
正在解决依赖关系
依赖关系解决
移除 1 软件包 (+1 依赖软件包)
安装大小:17 M
是否继续?[y/N]:y
删除:
mariadb-libs.x86_64 1:5.5.68-1.el7
作为依赖被删除:
postfix.x86_64 2:2.10.1-9.el7
完毕!
3.获取rpm安装包
创建 /usr/local/mysql 目录,cd到此目录,通过wget分别获取组件包,或者在windows下载完成后上传到此目录。
官方下载社区版mysql community server
选择相应的系统版本以及mysql版本(CentOS与Red Hat Enterprise相同),然后下载对应rpm包,其中,mysql核心组件包括4个,也可以下载集成所有组件的捆绑包,解压后得到核心组件包
- 核心组件包(从上到下为依赖关系)
- mysql-community-common-5.7.35-1.el7.x86_64.rpm
- mysql-community-libs-5.7.35-1.el7.x86_64.rpm mysql-community-client-5.7.35-1.el7.x86_64.rpm mysql-community-server-5.7.35-1.el7.x86_64.rpm
- 捆绑包,解压后包括以上核心组件包 mysql-5.7.35-1.el7.x86_64.rpm-bundle.tar
4.安装组件
注意:mysql依赖 libaio组件,部分云服务器(如阿里云)缺少该组件,安装mysql前可以先检查确认,如果未安装,通过yum安装即可
按照组件依赖顺序,分别执行
rpm -ivh mysql-community-common-5.7.22-1.el7.x86_64.rpm rpm -ivh mysql-community-libs-5.7.22-1.el7.x86_64.rpm rpm -ivh mysql-community-client-5.7.22-1.el7.x86_64.rpm rpm -ivh mysql-community-server-5.7.22-1.el7.x86_64.rpm
二、安装系统服务
rpm安装完成后,自动生成系统服务,且默认设置开机启动(等同 systemctl enable mysqld)
[root@localhost mysql]# find / -name mysqld.service
/etc/systemd/system/multi-user.target.wants/mysqld.service
/usr/lib/systemd/system/mysqld.service
#其中,/etc/systemd下的文件,为/usr/lib/systemd下文件的软连接,效果为开机启动,即 systemctl enable mysqld 设置开机启动的结果
[root@localhost ~]# ll /etc/systemd/system/multi-user.target.wants/mysqld.service
lrwxrwxrwx 1 root root 38 1月 26 09:57 /etc/systemd/system/multi-user.target.wants/mysqld.service -> /usr/lib/systemd/system/mysqld.service
附mysqld.service文件,主要关注[service]节点,指定了服务运行用户与用户组,以及pidfile进程ID文件路径
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/var/run/mysqld/mysqld.pid
# Disable service start and stop timeout logic of systemd for mysqld service.
TimeoutSec=0
# Execute pre and post scripts as root
PermissionsStartOnly=true
# Needed to create system tables
ExecStartPre=/usr/bin/mysqld_pre_systemd
# Start main service
ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS
# Use this to switch malloc implementation
EnvironmentFile=-/etc/sysconfig/mysql
# Sets open_files_limit
LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false
三、主程序加入到环境变量
yum安装后,在 /usr/sbin/ 目录下自动生成 mysqld 主程序文件
[root@localhost ~]# ll /usr/sbin/mysqld
-rwxr-xr-x 1 root root 252577496 11月 30 04:45 /usr/sbin/mysqld
四、配置文件
mysql配置文件为my.cnf,mysql启动时默认按照如下顺序搜索my.cnf
[root@localhost mysql]# mysql --help | grep my.cnf
order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf
建议统一使用 /etc/my.cnf,作为环境部署规范,避免不同服务器配置路径不一致,增加运维成本。
常用配置项如下
#[mysqld]配置组为mysql服务运行参数配置,java、navicat等客户端连接使用该部分socket配置
[mysqld]
#MySQL监听端口
port=3307 #更改默认端口,可能需要关闭SELinux,否则启动失败,提示端口无法绑定
#mysql日志时间默认为utc,改为与系统一致
log_timestamps=SYSTEM
#指定MySQL数据库文件保存目录
datadir=/data/mysql/data
#mysql以socket文件方式作为通信接口
socket=/data/mysql/mysql.sock
#是否支持符号链接,即数据库或表可以存储在my.cnf中指定datadir之外的分区或目录,为0不开启
symbolic-links=0
#错误日志位置
log-error=/data/mysql/log/mysqld.log
#比较名字时忽略大小写,创建表时,大写字母将转为小写字母
lower_case_table_names=1
#跳过权限检查,用于mysql服务修复
#skip-grant-tables
#[mysql]配置组用于mysql命令连接,如mysql -u xxx -p
[mysql]
#mysql以socket文件方式作为通信接口
socket=/data/mysql/mysql.sock
#[client]配置组用于mysql工具连接,如mysqladmin
[client]
#mysql以socket文件方式作为通信接口
socket=/data/mysql/mysql.sock
特别关注:配置文件中指定的所有路径,请在启动前确保已存在
关于服务名称
MySQL服务在不同系统中表现为不同的服务名称,如rpm系统中(如CentOS)为mysqld,在Debian系统中则为mysql。
关于服务运行管理
在一些系统中,MySQL服务会提供 mysqld_safe安全启动脚本,在my.cnf中也会相应配置[mysqld_safe]参数。
但是在支持systemd的系统(如CentOS)中,MySQL服务以mysqld.service方式保存在/etc/systemd/xxx 下,通过systemctl命令管理,比mysqld_safe更安全高效,所以不在有mysqld_safe启动脚本,同时不支持[mysqld_safe]配置。
关于pid-file配置
pid-file配置项为[mysqld_safe]配置组,systemd模式下[mysqld]配置组不兼容,默认在 mysqld.service 文件中指定,
所以,如果需要自定义pid-file,需要修改 mysqld.service文件(共2处需要修改),
然后执行 systemctl daemon-reload 刷新systemd配置,最后重启服务。
五、运行用户
如上述mysqld.service脚本内容,mysql运行指定了用户mysql与用户组mysql,rpm安装会自动创建该用户与用户组。
在my.cnf中配置了 datadir、socket、log-error路径,所以需要为这些目录配置运行用户归属,以及配置运行用户权限。
#目录归属
chown -R mysql:mysql /data/mysql/
#用户权限
chmod -R 755 /data/mysql/
六、开机启动
请参考教程 Linux开机启动方案
七、服务启动运行
1.启动MySQL服务
systemctl start mysqld
service mysqld start #service命令会自动重定向为以上systemctl命令执行
2.服务启动后,MySQL会根据 datadir 目录下是否有完整的数据库文件自动判断是否执行初始化操作,如果有文件但不完整,则启动失败,需要删除目录重建后启动。
如果第一次安装,MySQL会初始化数据库目录,创建超级管理员用户 root,并生成临时登录密码,第一次登录服务器必须先修改密码,否则无法执行其他操作。
临时密码输出在log-error指定的文件
[root@localhost mysql]# grep 'temporary password' /data/mysql/log/mysqld.log
2022-01-26T02:37:37.450312Z 1 [Note] A temporary password is generated for root@localhost: jTabE1TlXl!<
3.本地使用 root 登录MySQL,输入以上临时密码
[root@localhost mysql]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.37
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
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>
4.修改root用户密码,否则无法执行其他操作(只能使用ALTER USER语句修改)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Mysql.pass.123';
mysql> use mysql;
mysql> select user,host,authentication_string,select_priv from user;
+---------------+---------------+-------------------------------------------+-------------+
| user | host | authentication_string | select_priv |
+---------------+---------------+-------------------------------------------+-------------+
| root | localhost | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y |
| mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N |
| mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N |
| root | 192.168.11.31 | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y |
| testuser | 192.168.11.31 | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y |
| testuser | % | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y |
+---------------+---------------+-------------------------------------------+-------------+
6 rows in set (0.00 sec)
mysql>
特别关注:系统默认启用了SELinux内核模块(安全子系统),所以在服务绑定/监听某些端口时,提示无访问权限,此时需要禁用SELinux,修改 /etc/selinux/config 文件,设置SELINUX=disabled
Can't start server: Bind on TCP/IP port: Permission denied
特别关注:selinux设置完成需要重启生效,如果当前不方便重启,可以执行 setenforce 0 临时关闭selinux,下次重启是配置再生效
特别关注:系统默认启用了防火墙,请在启动服务前关闭防火墙,或在防火墙中添加服务端口
5.授权用户远程登录
MySQL初始化后默认只有root用户可以登录,且只支持localhost域,即本地登录,所以根据项目需要,可以对root授权其他网络登录,与可以创建专用新用户并授权其他网络登录。
授权远程登录可以通过以下方式
更新mysql.user表
mysql> update user set host='IP或%' where user='用户' and host='现有域';
mysql> flush privileges;
GRANT
语法:GRANT 权限列表(逗号分隔) ON 数据库.数据表 TO '用户'@'域' IDENTIFIED BY '密码';
#grant语句自动创建用户以及设置密码
#权限支持 create、update、select、lete、drop、execute等,也可以指定 all privileges 授权所有权限
#grant语句最后可以指定 WITH GRANT OPTION 指定用户可以将权限传递授权给其他用户。
#数据库与数据表支持 * 指定全部,如 testdb.* 或 *.*,其他情况只能一条授权一个数据表
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.11.31' IDENTIFIED BY 'Mysql.pass.123' WITH GRANT OPTION;
6.开始使用,java、navicat等工具可以正常连接
使用前,请确认防火墙关闭 或 防火墙已经添加MySQL服务端口(3307 TCP、UDP)。
特别关注:关于数据库连接
1.关于数据库连接数量限制
MySQL服务器在实例级别(max_connections)与用户级别(max_user_connections),都可以限制最大连接数,设置过高或过低,都会影响业务正常运行。
max_connections默认为100,设置过低,会出现【Too many connections】异常;
max_user_connections默认为0,即不限制,但最大不超过max_connections,可以全局设置(所有用户生效),也可以针对用户设置(授权,该用户生效),设置过低,会出现【has already more than 'max_user_connections' active connections】异常;
以上2个参数如果设置过高,会造成MySQL服务器保持过多连接,从而过度消耗服务器资源,造成MySQL服务整体性能下降。
所以,最大连接数的具体配置,需要根据实际业务场景,如用户数量评估,客户端数量评估等来做规划,同时客户端做好数据库连接的有效管理,比如使用连接池,及时关闭无用的连接等。
2.关于查看当前配置
max_connections为数据库实例全局配置,使用以下命令查看
show global variables like 'max_connections'; show variables like 'max_connections'; select @@max_connections; select @@global.max_connections;
max_user_connections全局配置使用以下命令查看
show global variables like 'max_user_connections'; show variables like 'max_user_connections'; select @@max_user_connections; select @@global.max_user_connections;
max_user_connections用户配置使用以下命令查看
show grants for root@'%'; select user,max_user_connections from mysql.user;
生效优先级:max_user_connections用户配置 > max_user_connections全局配置 > max_connections全局配置,直到找到非0的配置值,但总数不会超过 max_connections。
3.关于设置最大连接数
max_connections全局配置、max_user_connections全局配置,可以通过以下方式设置,建议max_user_connections根据用户个数(n)以及用户活跃度配置为 max_connections/n 再向上浮动一定比例,兼容用户活跃度不平均的场景
#my.cnf配置文件
[mysqld] max_connections=500 max_user_connections=300 #参数设置(登录mysql后执行) set global max_connections=500; set global max_user_connections=300;
max_user_connections用户配置需要在用户级别设置,可以通过以下方式
#grant with方式 grant privileges on *.* to user@'host' with max_user_connections 300; #update用户表方式 update mysql.user set max_user_connections=300 where user='user' and host='host'; flush privileges;
4.关于运行时监控
MySQL服务器运行中,可以通过 max_used_connections 状态值判断数据库连接数量设置是否合理,理想情况下,max_used_connections / max_connections * 100% ≈ 85%
mysql> show status like 'max_used_connections'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | Max_used_connections | 250 | +----------------------+-------+ 1 row in set (0.01 sec)
特别关注:关于MySQL日志管理
MySQL日志管理比较特殊,请参考 Linux日志管理经验总结(crontab+logrotate)
特别关注:关于MySQL用户密码
MySQL用户信息保存在系统数据库 mysql 的数据表 user 中,一条完整的用户信息主要包括如下信息
- 用户名,初始化时默认有 root、mysql.session(内置用户)、mysql.sys(内置用户)
- 登录域,即允许哪些网络环境使用该用户登录,可以设置localhost、ip、%(所有网络)
- 密码,通过 password() 加密算法加密,不可逆
- 权限,每个权限为一个字段
user表主键为 user + host,所以同一用户可以根据不同 登录域 生成多条记录,且同时生效。
mysql> select user,host,authentication_string,select_priv,update_priv from user; +---------------+---------------+-------------------------------------------+-------------+-------------+ | user | host | authentication_string | select_priv | update_priv | +---------------+---------------+-------------------------------------------+-------------+-------------+ | root | localhost | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y | Y | | mysql.session | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N | N | | mysql.sys | localhost | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | N | N | | root | 192.168.11.31 | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y | Y | | testuser | 192.168.11.31 | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y | Y | | testuser | localhost | *140E40879A3B1DAC8B6E5D9ED6D2400C3F9EA54A | Y | Y | +---------------+---------------+-------------------------------------------+-------------+-------------+ 6 rows in set (0.00 sec) mysql>
MySQL默认密码策略如下
mysql> show variables like '%validate_password%'; +--------------------------------------+--------+ | Variable_name | Value | +--------------------------------------+--------+ | validate_password_check_user_name | OFF | | validate_password_dictionary_file | | | validate_password_length | 8 | #8位 | validate_password_mixed_case_count | 1 | #大小写 | validate_password_number_count | 1 | #数字 | validate_password_policy | MEDIUM |#密码强度 | validate_password_special_char_count | 1 |#特殊字符 +--------------------------------------+--------+ 7 rows in set (0.00 sec) mysql>
可以修改默认密码策略,生产环境不建议修改
set global validate_password_policy=0; #弱口令 set global validate_password_length=4; #密码长度为4,此为允许的最小长度
附录:修改MySQL登录密码方法
1> 更新mysql.user表,需要登录MySQL执行,需要刷新权限列表生效
mysql> use mysql; #5.7前后版本密码字段不一致,且 user 表同时存在2个字段
# mysql5.7之前
mysql> update user set password=password('123456') where user='root' and host='localhost';
# mysql5.7之后
mysql> update user set authentication_string=password('123456') where user='root' and host='localhost';
mysql> flush privileges; #刷新权限列表
2> 用set password命令,需要登录MySQL执行,自动刷新权限列表
语法:set password for '用户名'@'域'=password(‘密码’)
mysql> set password for 'root'@'localhost'=password('123456');
3> alter user命令,需要登录MySQL执行,自动刷新权限列表
语法:ALTER USER '用户名'@'域' IDENTIFIED BY 'xxxx';
#初始化时root账号只有localhost
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
4> grant命令,需要登录MySQL执行,自动刷新权限列表
语法:GRANT 权限列表(逗号分隔) ON 数据库.数据表 TO '用户'@'域' IDENTIFIED BY '密码';
#grant语句自动创建用户以及设置密码
#权限支持 create、update、select、lete、drop、execute等,也可以指定 all privileges 授权所有权限
#grant语句最后可以指定 WITH GRANT OPTION 指定用户可以将权限传递授权给其他用户。
#数据库与数据表支持 * 指定全部,如 testdb.* 或 *.*,其他情况只能一条授权一个数据表
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.11.31' IDENTIFIED BY 'Mysql.pass.123' WITH GRANT OPTION;
5> mysqladmin,无需登录MySQL执行,自动刷新权限列表
语法:mysqladmin -u用户名 -p旧的密码 password 新密码
#该方式为明文传输密码,不安全
[root@localhost ~]# mysqladmin -uroot -p123456 password 1234abcd
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
New password:
Confirm new password:
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.