数据库管理

安装与升级

配置文件

默认选项从一下文件的给定顺序依次读取:

1
2
3
C:\WINDOWS\my.ini C:\WINDOWS\my.cnf
C:\my.ini C:\my.cnf
D:\InstallPath\mysql\my.ini D:\InstallPath\mysql\my.cnf

在解压根目录新建文件my.ini,内容如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8mb4
[mysqld]
# 设置日志记录输出
log_output=TABLE,FILE
# 指定error log文件
log-error=error.log
# 设置general log
general_log=1
general_log_file=general.log
# 启用slow query log
slow_query_log=1
slow_query_log_file=slow_query.log
# 允许的最大数据包大小
max_allowed_packet = 500M
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=/usr/local/bin/mysql
# 设置mysql数据库的数据的存放目录
datadir=/usr/local/bin/mysql/data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8mb4
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password

mysql5.7

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8
#ssl-mode=DISABLED
[mysqld]
#允许的最大数据包大小
max_allowed_packet = 500M
# 设置3306端口
port=3306
# 设置mysql的安装目录
basedir=D:\\Developer\\mysql-5.7
# 设置mysql数据库的数据的存放目录
datadir=D:\\Developer\\mysql-5.7\\data
# 允许最大连接数
max_connections=200
# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统
max_connect_errors=10
# 服务端使用的字符集默认为UTF8
character-set-server=utf8
# 创建新表时将使用的默认存储引擎
default-storage-engine=INNODB
# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password
#timestamp默认值设置
explicit_defaults_for_timestamp=true
#允许任意导入导出,可设置为dirName
secure-file-priv=''

Docker安装

拉取镜像

1
2
# TAG: latest, 8.0.18, 8.0, 8
docker pull mysql

启动mysql实例

1
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

some-mysql是要赋给容器的名称,my-secret-pw是MySQL root用户的密码,tag是要指定的MySQL版本。

从mysql命令行连接

1
docker run -it --network some-network --rm mysql mysql -hsome-mysql -uexample-user -p

此命令启动另一个运行mysql命令的mysql容器实例,而不是原来的mysql容器。其中some-mysql就是原来的mysql容器(连接到some-network)。

此镜像也可作为非Docker或远程实例的客户端

1
docker run -it --rm mysql mysql -hsome.mysql.host -usome-mysql-user -p

通过容器shell查看日志

如下命令会运行mysql容器中的bash

1
docker exec -it some-mysql bash

日志可通过Docker容器日志查看

1
docker logs some-mysql

使用自定义配置文件

默认的MySQL配置可在/etc/mysql/my.cnf找到,也可能!includedir额外的目录例如/etc/mysql/conf.d/etc/mysql/mysql.conf.d

如果/my/custom/config-file.cnf就是我们自定义的配置文件名和路径,可以使用如下命令启动mysql容器:

1
docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

将会启动一个新的some-mysql容器,使用/etc/mysql/my.cnf/etc/mysql/conf.d/config-file.cnf合并后的配置启动MySQL实例,后者的优先级更高。

也可以不用cnf文件配置,直接将配置选项发送给mysqld

1
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci

查看完整的选项列表使用如下命令

1
docker run -it --rm mysql:tag --verbose --help

环境变量

启动mysql映像时,可以通过在docker run命令行上传递一个或多个环境变量来调整MySQL实例的配置。请注意,如果使用已包含数据库的数据目录启动容器,则以下任何变量都将无效:容器启动时,任何现有数据库都将保持不变。

MySQL自身的环境变量列表可在https://dev.mysql.com/doc/refman/8.0/en/environment-variables.html查看。

环境变量 说明
MYSQL_ROOT_PASSWORD MySQL root用户的密码,此环境变量为必需的
MYSQL_DATABASE 指定镜像启动时需创建的数据库,如果提供了用户名/密码,则该用户拥有此数据库的全部权限,等同于GRANT ALL
MYSQL_USER, MYSQL_PASSWORD 一起使用以创建新用户和密码,此用户将会拥有MYSQL_DATABASE中数据库的全部权限
MYSQL_ALLOW_EMPTY_PASSWORD 设置为yes允许容器以root用户的空白密码启动。
MYSQL_RANDOM_ROOT_PASSWORD 设置为yes为root用户创建随机密码,此密码会打印出来
MYSQL_ONETIME_PASSWORD 设置root用户密码在初始化完成后自动失效,第一次登录时必须修改密码
|MYSQL_INITDB_SKIP_TZINFO|默认情况下,入口点脚本会自动加载CONVERT_TZ()函数所需的时区数据。如果不需要,则任何非空值都将禁用时区加载。|

_FILE加到上述环境变量后面,以读取文件中值赋给相应的变量。例如

1
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/mysql-root -d mysql:tag

目前此特性只支持MYSQL_ROOT_PASSWORD, MYSQL_ROOT_HOST, MYSQL_DATABASE, MYSQL_USER,和MYSQL_PASSWORD

初始化新实例

首次启动容器时,将创建一个具有指定名称的新数据库,并使用提供的配置变量对其进行初始化。 此外,它将执行在/docker-entrypoint-initdb.d中找到的扩展名为.sh,.sql和.sql.gz的文件。 文件将按字母顺序执行。可以通过将SQL dump加载到该目录中并为自定义镜像提供贡献的数据来轻松地填充mysql服务。默认情况下,SQL文件将导入到MYSQL_DATABASE变量指定的数据库中。

文件储存

在宿主机上创建数据目录/my/own/datadir,并创建使用此目录的mysql容器:

1
docker run --name some-mysql -v /my/own/datadir:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

如果从已有数据目录创建新容器,则无需指定$MYSQL_ROOT_PASSWORD变量。

使用任意用户运行

如果需要以指定UID/GID运行mysqld,则可将--user指定为任意值(root/0除外)

1
2
3
4
$ mkdir data
$ ls -lnd data
drwxr-xr-x 2 1000 1000 4096 Aug 27 15:54 data
$ docker run -v "$PWD/data":/var/lib/mysql --user 1000:1000 --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag

导入导出数据库文件

1
2
3
4
# 导出
docker exec some-mysql sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /some/path/on/your/host/all-databases.sql
# 恢复
docker exec -i some-mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"' < /some/path/on/your/host/all-databases.sql

二进制文件安装

Windows: 解压zip文件到安装位置,注意以管理员身份运行命令行工具。

Linux:
MySQL依赖libaio库,所以必须先安装此库:

1
2
3
4
5
6
7
# Yum-based
shell> yum search libaio  # search for info
shell> yum install libaio # install library

# APT-based
shell> apt-cache search libaio # search for info
shell> apt-get install libaio1 # install library

基于Linux的安装过程可简化为如下命令流程(需root权限),不必再执行后续步骤,如果要自定义安装则忽略此内容:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
shell> groupadd mysql
shell> useradd -r -g mysql -s /bin/false mysql
shell> cd /usr/local
shell> tar xvf /path/to/mysql-VERSION-OS.tar.xz
shell> ln -s full-path-to-mysql-VERSION-OS mysql
shell> cd mysql
shell> mkdir mysql-files
shell> chown mysql:mysql mysql-files
shell> chmod 750 mysql-files
shell> bin/mysqld --initialize --user=mysql
shell> bin/mysql_ssl_rsa_setup
shell> bin/mysqld_safe --user=mysql &
# Next command is optional
shell> cp support-files/mysql.server /etc/init.d/mysql.server

创建选项文件

如果您在运行服务器时需要指定启动选项,那么可以在命令行中指示它们,或者将它们放在选项文件中。对于每次服务器启动时使用的选项,您会发现使用选项文件来指定MySQL配置是最方便的。在以下情况下尤其如此:

  • 安装或数据目录位置与缺省位置(C:\Program Files\MySQL\MySQL Server 8.0C:\Program Files\MySQL\MySQL Server 8.0\data)不同。
  • 需要调优服务器设置,例如内存、缓存或InnoDB配置信息。

MySQL服务器在Windows上启动,它在几个位置查找选项文件,例如Windows目录、C:\和MySQL安装目录。Windows目录的名称通常类似于C:\WINDOWS。可以使用以下命令从WINDIR环境变量的值确定其确切位置:

1
C:\> echo %WINDIR%

MySQL首先在my.ini文件中的每个位置中查找选项,然后在my.cnf文件中查找选项。但是,为了避免混淆,最好只使用一个文件。如果您的PC使用引导加载程序,其中C:不是引导驱动器,那么您唯一的选择是使用my.ini文件。无论使用哪个选项文件,都必须是纯文本文件。

注意:当使用MySQL Installer安装MySQL Server时,它将在默认位置创建my.ini,并且执行MySQL Installer的用户被授予对这个新的my.ini文件的完全权限。
换句话说,确保MySQL Server用户具有读取my.ini文件的权限。

可以使用任何文本编辑器(如记事本)创建和修改选项文件。例如,如果MySQL安装在E:\mysql中且数据目录位于E:\mydata\data中,则可以创建包含[mysqld]部分的选项文件,以指定basedirdatadir选项的值:

1
2
3
4
5
[mysqld]
# set basedir to your installation path
basedir=E:/mysql
# set datadir to the location of your data directory
datadir=E:/mydata/data

使用(向前)斜杠而不是反斜杠在选项文件中指定Microsoft Windows路径名。 如果你使用反斜杠,请将它们加倍:

1
2
3
4
5
[mysqld]
# set basedir to your installation path
basedir=E:\\mysql
# set datadir to the location of your data directory
datadir=E:\\mydata\\data

ZIP存档不包含data目录。 要通过创建数据目录并填充mysql系统数据库中的表来初始化MySQL安装,请使用--initialize--initialize-insecure初始化MySQL。

如果要在其他位置使用数据目录,则应将data目录的全部内容复制到新位置。 例如,如果要将E:\mydata用作数据目录,则必须执行以下两项操作: 1.将整个data目录及其所有内容从默认位置(例如C:\Program Files\MySQL\MySQL Server 8.0\data)移动到E:\mydata。 2.每次启动服务器时,使用--datadir选项指定新数据目录位置。

选择MySQL服务器类型

下表显示了Windows上MySQL 8.0中可用服务器。

二进制 说明
mysqld 使用named-pipe支持优化二进制文件
mysqld-debug mysqld类似,但是使用完全调试和自动内存分配检查进行编译

所有前面的二进制文件都针对现代英特尔处理器进行了优化,但应该适用于任何英特尔i386级或更高级别的处理器。 分发中的每个服务器都支持同一组存储引擎。 SHOW ENGINES语句显示给定服务器支持的引擎。 所有Windows MySQL 8.0服务器都支持数据库目录的符号链接。 MySQL支持所有Windows平台上的TCP/IP。 如果使用--enable-named-pipe选项启动服务器,Windows上的MySQL服务器也支持命名管道。 有必要明确使用此选项,因为某些用户在使用命名管道时遇到关闭MySQL服务器的问题。 默认情况下,无论平台如何都使用TCP/IP,因为在许多Windows配置中,命名管道比TCP/IP慢。

初始化data目录

1
2
3
@REM Windows
bin\mysqld --initialize --console
bin\mysqld --initialize-insecure --console

可不要–console,只是为了显示结果。

1
2
3
# Linux
bin/mysqld --initialize --user=mysql
bin/mysqld --initialize-insecure --user=mysql

以root用户运行命令并指定–user选项,或者直接以mysql用户运行命令可去掉–user选项。

如果mysqld无法正确识别安装目录或data目录,可使用如下命令

1
2
3
bin/mysqld --initialize --user=mysql
  --basedir=/opt/mysql/mysql
  --datadir=/opt/mysql/mysql/data

如果需要指定选项文件,则使用如下命令:

1
2
3
@REM Windows
bin\mysqld --defaults-file=C:\my.ini
   --initialize --console
1
2
3
# Linux
bin/mysqld --defaults-file=/opt/mysql/mysql/etc/my.cnf
  --initialize --user=mysql

服务器会检查data目录是否存在,如果data目录存在且不为空就会报错。在这种情况下,移除data目录重新试一次。

启动MySQL server

如果安装包含mysqld_safe,则按如下方式启动:

1
shell> bin/mysqld_safe --user=mysql &

请使用root用户运行mysqld_safe并指定–user选项,或者使用mysql用户运行此命令可省略该选项。

如果不是采用二进制包安装则不包含mysqld_safe,采用如下命令:

1
2
3
4
5
systemctl {start|stop|restart|status} mysqld # RPM platforms
systemctl {start|stop|restart|status} mysqld # Debian platforms
# OR
service mysqld {start|stop|restart|status} # RPM platforms
service mysql {start|stop|restart|status} # Debian platforms
Windows启动停止MySQL

在Windows上使用如下命令:

1
2
mysqld --console
mysqladmin -u root shutdown

如果看到mysqld.exe: ready for connections. Version: ‘8.0.15’ socket: '’ port: 3306 证明启动成功,此窗口会持续输出产生的新日志,这时我们需要打开新窗口继续我们的操作。如果去掉console选项,会在data文件夹下的.err文件中会有产生的日志,也可以使用–log-error选项自定义设置。

作为Windows服务启动MySQL

先使用上面的命令关闭MySQL,然后安装服务

mysqld --install

服务启动/停止

net start mysql
net stop mysql

作为服务启动时,MySQL没有console访问权限,日志需在data文件夹下的.err文件中查看,也可以使用mysqladmin shutdown命令停止服务。如果不想安装为自启动服务,可以使用如下命令:

mysqld --install-manual

如果要移除服务,先停止服务后,使用如下命令:

mysqld --remove
解决MySQL启动问题

如果启动MySQL中存在问题,可以尝试如下办法:

  • 在数据目录中查找名称为host_name.err和host_name.log的文件,其中host_name是服务器主机的名称。 然后检查这些文件的最后几行。 使用tail显示它们:
1
2
shell> tail host_name.err
shell> tail host_name.log
  • 确保服务器知道在哪里可以找到数据目录。

编译服务器时,默认数据目录位置是硬编码的。 要确定默认路径设置是什么,请使用–verbose和–help选项调用mysqld。 如果数据目录位于系统上的其他位置,请在命令行或选项文件中使用mysqld或mysqld_safe的–datadir选项指定该位置。 否则,服务器将无法正常工作。 作为–datadir选项的替代方法,您可以使用–basedir指定mysqld安装MySQL的基本目录的位置,mysqld会在那里查找数据目录。

如果mysqld当前正在运行,您可以通过执行以下命令找出它正在使用的路径设置:

1
2
3
shell> mysqladmin variables
# OR
shell> mysqladmin -h host_name variables

host_name是MySQL服务器主机的名称。

测试MySQL sever

使用mysqladmin验证服务器是否正在运行。 以下命令提供简单的测试,以检查服务器是否已启动并响应连接:

1
2
shell> bin/mysqladmin version
shell> bin/mysqladmin variables

如果无法连接到服务器,请指定-u root选项以root身份连接。 如果您已经为root帐户分配了密码,则还需要在命令行中指定-p并在出现提示时输入密码。 例如:

1
2
shell> bin/mysqladmin -u root -p version
Enter password: (enter root password here)

要查看使用mysqladmin可以执行的其他操作,请使用–help选项调用它。下例是一个自定义操作:

1
shell> bin/mysqladmin -u root version status proc

验证您是否可以关闭服务器(如果root帐户已有密码,请包含-p选项):

1
shell> bin/mysqladmin -u root shutdown

确认您可以再次启动服务器。 通过使用mysqld_safe或直接调用mysqld来完成此操作。 例如:

1
shell> bin/mysqld_safe --user=mysql &

使用mysqlshow查看存在哪些数据库:

1
2
3
4
5
6
7
8
9
shell> bin/mysqlshow
+--------------------+
|     Databases      |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

已安装数据库的列表可能有所不同,但始终至少包含mysql和information_schema。

如果指定数据库名称,mysqlshow将显示数据库中的表列表:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
shell> bin/mysqlshow mysql
Database: mysql
+---------------------------+
|          Tables           |
+---------------------------+
| columns_priv              |
| component                 |
| db                        |
| default_roles             |
| engine_cost               |
| func                      |
| general_log               |
| global_grants             |
| gtid_executed             |
| help_category             |
| help_keyword              |
| help_relation             |
| help_topic                |
| innodb_index_stats        |
| innodb_table_stats        |
| ndb_binlog_index          |
| password_history          |
| plugin                    |
| procs_priv                |
| proxies_priv              |
| role_edges                |
| server_cost               |
| servers                   |
| slave_master_info         |
| slave_relay_log_info      |
| slave_worker_info         |
| slow_log                  |
| tables_priv               |
| time_zone                 |
| time_zone_leap_second     |
| time_zone_name            |
| time_zone_transition      |
| time_zone_transition_type |
| user                      |
+---------------------------+

使用mysql程序从mysql schema中的表中选择信息:

1
2
3
4
5
6
shell> bin/mysql -e "SELECT User, Host, plugin FROM mysql.user" mysql
+------+-----------+-----------------------+
| User | Host      | plugin                |
+------+-----------+-----------------------+
| root | localhost | caching_sha2_password |
+------+-----------+-----------------------+

升级MySQL

升级内容

1
shell> mysqld --verbose --help

数据库升级分为两步:

  • 第1步:数据字典升级。
  • 第2步:服务器升级。

在MySQL 8.0.16之前,mysql_upgrade执行第2步。在启动服务器之后,DBA应该手动调用mysql_upgrade。

从MySQL 8.0.16开始,服务器执行以前由mysql_upgrade处理的所有任务。 虽然升级仍然是两步操作,但服务器同时执行它们,从而使过程更简单。

从MySQL 8.0.16开始,–upgrade服务器选项控制服务器在启动时是否以及如何执行自动升级:

  • 如果没有选项或者--upgrade=AUTO,服务器会升级它确定为过期的任何内容(步骤1和2)。
  • 如果--upgrade=NONE,则服务器不会升级任何内容(跳过步骤1和2),但如果必须升级数据字典,则还会退出并显示错误。使用过时的数据字典运行服务器是不可能的;服务器坚持要么升级要么退出。
  • 使用--upgrade=MINIMAL,服务器会在必要时升级数据字典(步骤1),但不执行任何其他操作(跳过步骤2)。
  • 使用--upgrade=FORCE,服务器会在必要时升级数据字典(步骤1)并强制升级其他所有内容(步骤2)。使用此选项预计服务器启动需要更长时间,因为服务器会检查所有模式中的所有对象。

如果服务器认为不需要(例如,数据目录中的mysql_upgrade_info文件已包含当前服务器版本),FORCE对于强制执行第2步操作很有用。 FORCE与AUTO的不同之处在于,使用FORCE,服务器会重新创建系统表,如缺少帮助表或时区表。

准备升级

  1. 检查内容:
  • 没有表和函数使用过时的数据类型
  • 没有orphan .frm 文件
  • 没有缺失或空定义或无效创建内容的触发器

使用如下命令检查如上内容:

1
mysqlcheck -u root -p --all-databases --check-upgrade

如果mysqlcheck报告任何错误,立即修复。

  1. 检查是否有分区的表使用了没有原生分区支持的引擎:
1
2
3
4
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE NOT IN ('innodb', 'ndbcluster')
AND CREATE_OPTIONS LIKE '%partitioned%';

任何查到的表必须改为使用InnoDB引擎或者取消分区。使用如下语句更改表储存引擎:

1
ALTER TABLE table_name ENGINE = INNODB;

使用如下语句取消表分区:

1
ALTER TABLE table_name REMOVE PARTITIONING;
  1. 检查是否有先前非保留关键字在新版本的MySQL中成为关键字,如果有,使用``符号引用关键字。
  2. 检查在MySQL 5.7中mysql系统数据库中是否包含MySQL 8.0中数据字典相同名称的表
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE LOWER(TABLE_SCHEMA) = 'mysql'
and LOWER(TABLE_NAME) IN
(
'catalogs',
'character_sets',
'check_constraints',
'collations',
'column_statistics',
'column_type_elements',
'columns',
'dd_properties',
'events',
'foreign_key_column_usage',
'foreign_keys',
'index_column_usage',
'index_partitions',
'index_stats',
'indexes',
'parameter_type_elements',
'parameters',
'resource_groups',
'routines',
'schemata',
'st_spatial_reference_systems',
'table_partition_values',
'table_partitions',
'table_stats',
'tables',
'tablespace_files',
'tablespaces',
'triggers',
'view_routine_usage',
'view_table_usage'
);

任何查到的表必须使用RENAME TABLE重命名,并修改受影响的应用程序。 5. 必须没有表的外键约束名称长于64个字符

1
2
3
4
5
6
7
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME IN
  (SELECT LEFT(SUBSTR(ID,INSTR(ID,'/')+1),
               INSTR(SUBSTR(ID,INSTR(ID,'/')+1),'_ibfk_')-1)
   FROM INFORMATION_SCHEMA.INNODB_SYS_FOREIGN
   WHERE LENGTH(SUBSTR(ID,INSTR(ID,'/')+1))>64);

任何查到的表必须使用ALTER TABLE将约束名称改为小于等于64个字符 6. 在sql_mode系统变量设置中没有定义弃用的SQL模式。 7. 若要升级到MySQL8.0,则必须没有表或存储过程的单独ENUM或SET列元素超过255字符或1020字节。 8. 升级到MySQL 8.0.13以上版本时,必须没有分区表存在于共享的InnoDB表空间中,包括系统表空间和通用表空间。

1
2
3
4
5
6
/*从MySQL 5.7升级*/
SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES 
  WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';
/*从MySQL 8.0升级*/
SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLES 
  WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';

将查询到的表从共享表空间移到file-per-table表空间

1
2
ALTER TABLE table_name REORGANIZE PARTITION partition_name 
  INTO (partition_definition TABLESPACE=innodb_file_per_table);
  1. MySQL 8.0.12以下的数据库中的查询和存储过程停止在GROUP BY中使用ASCDESC排序,请改为使用ORDER BY子句。
  2. MySQL 5.7安装必须没有使用MySQL 8.0中不再支持的特性。比如一些服务器选项和状态变量。

执行升级

原地升级

in-place升级需要停止旧MySQL服务器,将旧的二进制文件和包换成新的,重启并更新即可。

  1. 如果在InnoDB中使用了XA事务,在升级之前运行XA RECOVER,以检查未提交的事务。如果返回结果,则使用XA COMMITXA ROLLBACK提交或回滚XA事务。
  2. 如果有加密的InnoDB表空间,执行以下语句以rotate the keyring master key
1
ALTER INSTANCE ROTATE INNODB MASTER KEY;
  1. 如果正常运行配置了innodb_fast_shutdown设置为2(冷关闭)的MySQL服务器,使用如下语句将其配置为快或慢关闭
1
2
SET GLOBAL innodb_fast_shutdown = 1; -- fast shutdown
SET GLOBAL innodb_fast_shutdown = 0; -- slow shutdown

使用快或慢关闭,InnoDB将其undo日志和数据文件保持为可以处理升级后文件格式变化的情况。

  1. 关闭旧MySQL服务器,例如
1
mysqladmin -u root -p shutdown
  1. 解压新的二进制安装或安装新的包
  2. 使用现有的数据文件夹启动新MySQL服务器,例如
1
mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &

如果此步骤失败,MySQL将全部数据文件更改重置,在这种情况下,应该移除全部redo日志文件,并将旧的MySQL版本用相同的数据目录启动。 7. 如果使用MySQL 8.0.16及以后版本则完成升级,如果升级之前的版本,则还需要执行如下步骤

1
2
3
4
mysql_upgrade -u root -p
# 还需要重启MySQL服务器,以确保更改生效
mysqladmin -u root -p shutdown
mysqld_safe --user=mysql --datadir=/path/to/existing-datadir &
逻辑升级

逻辑升级涉及到使用备份或导出工具如mysqldump或mysqlpump将SQL从旧MySQL实例导出,安装新的MySQL实例并将SQL应用到新实例。

警告:将提取到的旧SQL应用到新版本,如果新版本出现了一些不兼容的变化就会导致错误。所以旧SQL可能需要修改以备逻辑升级。

  1. 将之前的MySQL安装的现有数据导出
1
2
3
mysqldump -u root -p
  --add-drop-table --routines --events
  --all-databases --force > data-for-upgrade.sql

对mysqldump使用--routines--events选项以导出存储过程,使用--all-databases选项导出包括mysql在内的全部数据库。

  1. 关闭旧服务器
1
mysqladmin -u root -p shutdown
  1. 安装新版本,并初始化新data文件夹。
1
mysqld --initialize --datadir=/path/to/8.0-datadir
  1. 使用新data目录启动MySQL
1
mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir &
  1. 重置root密码
1
2
shell> mysql -u root -p
Enter password: ****  <- enter temporary root password
1
mysql> ALTER USER USER() IDENTIFIED BY 'your new password';
  1. 将之前导出的sql文件加载到新数据库,例如
1
mysql -u root -p --force < data-for-upgrade.sql
  1. 后续升级步骤
1
2
3
4
5
6
7
# MySQL 8.0.16及以后
mysqladmin -u root -p shutdown
mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir --upgrade=FORCE &
# 之前版本
mysql_upgrade -u root -p
mysqladmin -u root -p shutdown
mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir &

注意,升级过程并不更新区表的内容,使用mysql_upgrade程序升级也不更新help表的内容。

针对MySQL 5.7版本,移除mysql中不再使用的两个表

1
2
DROP TABLE mysql.event;
DROP TABLE mysql.proc;
集群升级

集群升级采用和原地升级相同的方法

  1. 升级MGM节点。
  2. 一次升级一个数据节点。
  3. 一次升级一个API节点(包括MySQL服务器)。

升级检查工具

除了上述的手动检查,可以使用升级检查工具完成相同的工作。

util.checkForServerUpgrade()函数帮助确认MySQL是否准备好升级。