CentOS 7 安装 MySQL 8.0及常见问题

Scroll Down

参考:https://dev.mysql.com/doc/refman/8.0/en/linux-installation-yum-repo.html

本文使用 MySQL 官方支持的 yum 方式快速安装 MySQL 8.0。

1.添加 MySQL Yum 仓库

下载 MySQL 仓库 rpm 文件

wget --no-check-certificate https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm

安装 rpm 文件

yum localinstall mysql80-community-release-el7-3.noarch.rpm

可使用以下命令检测仓库是否添加成功

yum repolist enabled | grep "mysql.*-community.*"

## 可以看到类似如下结果:
## mysql80-community/x86_64               MySQL 8.0 Community Server            129

2.安装 8.0 版本

使用以下命令可查看所有可用的 MySQL 安装源

yum repolist all | grep mysql
## 只查看可用的
yum repolist enabled | grep mysql

安装

yum install mysql-community-server

3.启动 MySQL 8.0

systemctl start mysqld

systemctl status mysqld

4.修改默认的密码

MySQL 8 首次启动时会默认随机创建一个密码,可以在日志中查到。
连接上MySQL之后可以使用命令修改密码,注意使用IDENTIFIED WITH修改密码认证方式,默认的方式是:caching_sha2_password,如果不修改会报错。

grep 'temporary password' /var/log/mysqld.log

# 类如:
# 2019-07-22T05:40:11.606393Z 5 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: iigyAg5mJ5+q

mysql -uroot -p

# 更新密码,并且修改加密规则 
mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxxxxx' PASSWORD EXPIRE NEVER;
## 经测试,MySQL8下无需 FLUSH PRIVILEGES; 即可使密码修改生效。

默认情况下自动安装validate_password,实现的默认密码策略要求密码至少包含一个大写字母,一个小写字母,一个数字和一个特殊字符,并且密码长度至少为8个字符。

5.外网客户端访问

默认只允许本机访问,可以在服务端登陆 MySQL,修改 user 表登陆用户的 host。

mysql>

use mysql;
update user set host='%' where user='root';
# 使需该立即生效
FLUSH PRIVILEGES;

不过,一般不建议配置root远程访问,可单独配置一个账号:

CREATE USER 'user1'@'%' IDENTIFIED BY 'password1';	
GRANT ALL PRIVILEGES ON `xxdb`.* TO 'user1'@'%';
GRANT SELECT ON `performance_schema`.* TO 'user1'@'%';
#REVOKE ALL PRIVILEGES ON `xxdb`.* FROM 'user1'@'%';
#DROP USER 'user1'@'%';
FLUSH PRIVILEGES;

还修改密码验证模式为:mysql_native_password模式,默认是caching_sha2_password,其他客户端连接会报找不到插件。

ALTER USER 'user1'@'%' IDENTIFIED WITH mysql_native_password BY 'password1' PASSWORD EXPIRE NEVER;

6.使用 Yum 安装其他 MySQL 产品和组件

可以使用 Yum 来安装和管理 MySQL 的各个组件。其中一些组件托管在 MySQL Yum 存储库的子存储库中。
例如,MySQL Connectors 可以在 MySQL Connectors Community 子仓库中找到,而 MySQL Workbench 可以在 MySQL Tools Community 中找到。可以使用以下命令从 MySQL Yum 仓库列出适用于对应平台的所有MySQL 组件的软件包。

yum --disablerepo=\* --enablerepo='mysql*-community*' list available

7.使用 Yum 更新 MySQL

除了安装,还可以使用 MySQL Yum 仓库对 MySQL和组件执行更新。可参考“使用MySQL Yum存储库升级MySQL”

8.Connector/J

Connector/J 即 mysql-connector-java,Connector/J 和各版本 MySQL 支持情况可参考:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-versions.html。

官方推荐使用:8.0

// https://mvnrepository.com/artifact/mysql/mysql-connector-java
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.47'
// VS
compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.16'

9.MySQL 8 常见问题

9.1 修改默认的密码模式

mysql默认的密码模式为caching_sha2_password,会使一些客户端无法连接到服务,可以修改为mysql_native_password

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'xxx' PASSWORD EXPIRE NEVER;
# 实测mysql8 下使用IDENTIFIED WITH不需要FLUSH

9.2 添加外网其他账号访问权限

CREATE USER 'xxuser'@'%' IDENTIFIED BY 'xxpassword';	
GRANT ALL PRIVILEGES ON `xxdb`.* TO 'xxuser'@'%';
GRANT SELECT ON `performance_schema`.* TO 'xxuser'@'%';
//REVOKE ALL PRIVILEGES ON `xxdb`.* FROM 'xxuser'@'%';
//DROP USER 'xxuser'@'%';
FLUSH PRIVILEGES;

9.3 使用触发器报错

## 如果使用触发器报错
You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)

如果变量设置为1,MySQL不会对创建存储函数实施这些限制,执行sql:

set global log_bin_trust_function_creators = 1;

9.4 使用group by报错

mysql 5.7 使用 group by 报错:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 

或者 mysql 8 报错:

which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

需要修改/etc/my.cnf,在[mysqld]下添加:

sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

如果是8以上,需要删除NO_AUTO_CREATE_USER,已经取消该参数

sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

重启mysql后,即可解决。

可以使用select @@sql_mode验证是否生效。

10.Docker 下安装 MySQL 8

直接运行命令安装(注意指定初始root密码):

# 运行server
docker run -d --name mysql8 -v /etc/mysql8:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=NewPassword -p 3306:3306 -p 33060:33060 mysql:8.0.17

连接客户端修改默认的加密规则:

# 客户端
docker exec -it {mysql8容器id} /bin/bash
## 连接后使用mysql -u,找到 mysql 库
mysql -uroot -pNewPassword

可参考第9节命令修改密码模式:

## 修改密码模式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'NewPassword';

## 开放外网连接(docker安装貌似自动生成了一个%的,无需执行该句了)
update user set Host='%' where User='root';
FLUSH PRIVILEGES;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'WITH GRANT OPTION;

11.附录

附上自己ECS使用的一个配置文件/etc/my.cnf(包含慢sql配置和部分参数优化):

[client]  
host=localhost
user=root
password=xxx
default-character-set=utf8

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci

default_authentication_plugin=mysql_native_password

## ONLY_FULL_GROUP_BY
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'

## Binary Logging
log-bin=mysql-bin
server-id=1
binlog_format=ROW
binlog_cache_size=2M
binlog_order_commits=OFF
max_binlog_size=500M

## slow query
slow_query_log=1
long_query_time=1
#log_queries_not_using_indexes=ON

# innodb 设置
innodb_open_files=300
innodb_buffer_pool_size=1024M
innodb_purge_threads=1
#innodb_flush_log_at_trx_commit=2
innodb_log_buffer_size=2M
innodb_log_file_size=32M
#innodb_log_files_in_group=3
innodb_max_dirty_pages_pct=75
innodb_lock_wait_timeout=0
#innodb_buffer_pool_load_at_startup=1
#innodb_buffer_pool_dump_at_shutdown=1
#innodb_lru_scan_depth=2000
innodb_io_capacity=2000
innodb_io_capacity_max=4000

#----------------优化配置
# 支持符号链接,就是可以通过软连接的方式,管理其他目录的数据库,最好不要开启,当一个磁盘或分区空间不够时,可以开启该参数将数据存储到其他的磁盘或分区
symbolic-links=0
# 设置autocommit=0,则用户将一直处于某个事务中,直到执行一条commit提交或rollback语句才会结束当前事务重新开始一个新的事务(调试模式时使用)
#autocommit=0
# MySQL读入缓冲区的大小
read_buffer_size = 16M
# MySQL的随机读缓冲区大小、MySQL的顺序读缓冲区大小
read_rnd_buffer_size = 8M
sort_buffer_size = 8M
# 连接超时时间、保持时间、最大传输数据包大小
wait_timeout=2880000
interactive_timeout=2880000
max_allowed_packet=100M
# 连接缓存池大小、临时表大小、临时存放位置
join_buffer_size=128M
tmp_table_size=64M
#tmpdir = /tmp

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid