在升级到8.0之前需要充分考虑版本变化带来的使用兼容性的问题,其中不兼容的部分需要特别关注,建议升级大版本前做充分的测试。下面简单介绍下MySQL8.0的部分变化。
不同于之前的版本将字典数据存储在元数据文件和非事务系统表中,MySQL8.0将包含数据库对象的全局数据字典存储在事务表中。在使用上如果设置了innodb_read_only 参数会导致所有表的创建、删除、analyze、修改表引擎操作无法执行。CREATE TABLE dst_tbl LIKE src_tbl 要求src_tbl必须是base table。mysqldump和mysqlpump不会导出information_schema,不会导出MySQL Schema中数据字典表,需导出存储过程和事件需指定–routines和–events选项,并且用户需要全局select权限。
MySQL8.0将默认身份验证插件从mysql_native_password变更为caching_sha2_password,客户端需要验证现有版本是否支持。
[ERROR] [MY-011087] [Server] Different lower_case_table_names settings for server ('0') and data dictionary ('1'). [ERROR] [MY-010020] [Server] Data Dictionary initialization failed. [ERROR] [MY-010119] [Server] Aborting
mysql> CREATE TABLESPACE ts11 ADD DATAFILE '/data/mysql/log/test/../ts11.ibd'; ERROR 3121 (HY000): The ADD DATAFILE filepath cannot contain circular directory references. mysql> CREATE TABLESPACE ts11 ADD DATAFILE '/data/mysql/log/ts11.ibd'; Query OK, 0 rows affected (10.02 sec)
部分默认配置的变化。
根据版本变化及官方升级教程,列举出以下几点注意事项:
MySQL 8.0 中的更改:了解升级前应注意的更改。某些更改可能需要执行操作。
MySQL 8.0 中的新增功能:了解已弃用和已删除的功能。如果您使用其中任何一个功能,升级可能需要更改这些功能。
MySQL 8.0 中添加、弃用或删除的服务器和状态变量和选项”。如果使用已弃用或删除的变量,则升级可能需要更改配置。
建议先升级到最新版本,然后再升级到下一个版本。例如,在升级到 MySQL 8.0 之前升级到最新的 MySQL 5.7 版本。不支持跳过版本的升级。例如,不支持直接从 MySQL 5.6 升级到 8.0。
升级方式有2种,in-place升级和logical升级
关闭现有版本MySQL,将二进制或包替换成新版本并在现有数据目录上启动MySQL并执行升级任务的方式,称为in-place升级。升级过程分为以下几步:
逻辑升级是指使用逻辑备份从旧版本MySQL中导出数据,安装新版本MySQL并导入数据的升级方式。由于可能存在的不兼容问题会导致导入失败,导出前需要做升级前检查,导入前可能还需要对备份文件进行修改。
升级步骤如下:
mysqldump -u root -p --add-drop-table --routines --events --all-databases --force > data-for-upgrade.sql
#8.0.16以后的版本 mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir --upgrade=FORCE & #8.0.16之前的版本 mysql_upgrade -u root -p mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir & #确认升级成功后,mysql schema中两张不再使用的表可以自行清理 DROP TABLE mysql.event; DROP TABLE mysql.proc;
升级MySQL时需要对现版本MySQL中的数据字典和元数据等进行更新。在MySQL Schema中需更新数据字典表和系统表,在其他Schema中需要更新一些内置的MySQL持有的表,如performance_Schema、information_schema和sys schema等。
升级过程大致分为两个部分,升级数据字典和升级服务。
在8.0.16之前需使用mysql_upgrade执行除数据字典表外的其余升级步骤,在8.0.16以后该步骤由MySQL服务在启动后执行。MySQL服务会根据升级到的版本以及in-place或logical升级的指示确定是否执行所有的升级步骤。
8.0.16开始启动参数–upgrade= 控制MySQL服务在启动时执行自动升级的动作。
--upgrade=AUTO MySQL升级所有过时的内容 --upgrade=NONE MySQL跳过升级步骤,可能会导致报错 --upgrade=MINIMAL MySQL在必要时升级数据字典表,information_schema和information_schema。这可能会导致部分功能不能正常使用,例如MGR。 --upgrade=FORCE MySQL会升级所有的内容,这会检查所有schema的所有对象,导致MySQL需要更长的时间启动。此模式下MySQL会重新创建系统表 if they are missing。
MySQL 8.0.16 开始,MySQL 不推荐使用mysql_upgrade。取而代之的是server upgrade的升级方式。
升级的时间和操作都会大幅度缩短,操作步骤也减少了很多,更方便了用户。
在 mysqld 额外添加了一个新的选项 --upgrade。可选值为 NONE,AUTO,MINIMAL,FORCE。
--使用方法 /usr/local/mysql/bin/mysqld --upgrade=NONE 参数解释: NONE:不尝试进行升级 AUTO:默认选项,MySQL 进行数据字典升级和服务升级 MINIMAL:仅升级数据字典 FORCE:强制升级,类似旧的 mysql_upgrade –force
MySQL 8.0.16 新的升级方式,总体来说分为2个步骤。
可能出现的问题:
2.升级系统表、用户表:可以从备份还原中恢复。
--创建数据库并批量插入数据 CREATE DATABASE IF NOT EXISTS pijiake; CREATE TABLE IF NOT EXISTS `pijiake`.`test_user`( `id` INT UNSIGNED AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `age` INT(11) NOT NULL, `sex` VARCHAR(16), PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `pijiake`.`test_user` (name, age, sex) VALUES ('张三', 18, '男'), ('赵四', 17, '女'), ('刘五', 16, '男'), ('周七', 19, '女'); select * from `pijiake`.`test_user`; CREATE DATABASE IF NOT EXISTS xiaomiaoao; CREATE TABLE IF NOT EXISTS `xiaomiaoao`.`test_user`( `id` INT UNSIGNED AUTO_INCREMENT, `name` VARCHAR(255) NOT NULL, `age` INT(11) NOT NULL, `sex` VARCHAR(16), PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `xiaomiaoao`.`test_user` (name, age, sex) VALUES ('张三', 18, '男'), ('赵四', 17, '女'), ('刘五', 16, '男'), ('周七', 19, '女'); select * from `xiaomiaoao`.`test_user`;
在执行升级操作前需要做一些检查工作,确认准备工作是否就绪,避免升级过程中出现异常。
下面的例子中就存在一个不兼容的问题,ymh.t1表是一个MyISAM引擎的分区表,需将该表引擎调整为innodb后方可升级。
MySQL JS > util.checkForServerUpgrade('root@127.0.0.1:3307', {"password":"XXXX", "targetVersion":"8.0.26", "configPath":"/etc/my3307.cnf"}) The MySQL server at 127.0.0.1:3307, version 5.7.23-log - MySQL Community Server (GPL), will now be checked for compatibility issues for upgrade to MySQL 8.0.26... 1) Usage of old temporal type No issues found 2) Usage of db objects with names conflicting with new reserved keywords No issues found 3) Usage of utf8mb3 charset No issues found 4) Table names in the mysql schema conflicting with new tables in 8.0 No issues found 5) Partitioned tables using engines with non native partitioning Error: In MySQL 8.0 storage engine is responsible for providing its own partitioning handler, and the MySQL server no longer provides generic partitioning support. InnoDB and NDB are the only storage engines that provide a native partitioning handler that is supported in MySQL 8.0. A partitioned table using any other storage engine must be altered—either to convert it to InnoDB or NDB, or to remove its partitioning—before upgrading the server, else it cannot be used afterwards. More information: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-configuration-changes ymh.t1 - MyISAM engine does not support native partitioning 6) Foreign key constraint names longer than 64 characters No issues found 7) Usage of obsolete MAXDB sql_mode flag No issues found 8) Usage of obsolete sql_mode flags No issues found 9) ENUM/SET column definitions containing elements longer than 255 characters No issues found 10) Usage of partitioned tables in shared tablespaces No issues found 11) Circular directory references in tablespace data file paths No issues found 12) Usage of removed functions No issues found 13) Usage of removed GROUP BY ASC/DESC syntax No issues found 14) Removed system variables for error logging to the system log configuration No issues found 15) Removed system variables No issues found 16) System variables with new default values Warning: Following system variables that are not defined in your configuration file will have new default values. Please review if you rely on their current values and if so define them before performing upgrade. More information: https://mysqlserverteam.com/new-defaults-in-mysql-8-0/ back_log - default value will change collation_server - default value will change from latin1_swedish_ci to utf8mb4_0900_ai_ci event_scheduler - default value will change from OFF to ON explicit_defaults_for_timestamp - default value will change from OFF to ON innodb_autoinc_lock_mode - default value will change from 1 (consecutive) to 2 (interleaved) innodb_max_dirty_pages_pct_lwm - default value will change from_0 (%) to 10 (%) innodb_undo_log_truncate - default value will change from OFF to ON innodb_undo_tablespaces - default value will change from 0 to 2 log_error_verbosity - default value will change from 3 (Notes) to 2 (Warning) max_error_count - default value will change from 64 to 1024 optimizer_trace_max_mem_size - default value will change from 16KB to 1MB performance_schema_consumer_events_transactions_current - default value will change from OFF to ON performance_schema_consumer_events_transactions_history - default value will change from OFF to ON transaction_write_set_extraction - default value will change from OFF to XXHASH64 17) Zero Date, Datetime, and Timestamp values Warning: By default zero date/datetime/timestamp values are no longer allowed in MySQL, as of 5.7.8 NO_ZERO_IN_DATE and NO_ZERO_DATE are included in SQL_MODE by default. These modes should be used with strict mode as they will be merged with strict mode in a future release. If you do not include these modes in your SQL_MODE setting, you are able to insert date/datetime/timestamp values that contain zeros. It is strongly advised to replace zero values with valid ones, as they may not work correctly in the future. More information: https://lefred.be/content/mysql-8-0-and-wrong-dates/ global.sql_mode - does not contain either NO_ZERO_DATE or NO_ZERO_IN_DATE which allows insertion of zero dates session.sql_mode - of 1 session(s) does not contain either NO_ZERO_DATE or NO_ZERO_IN_DATE which allows insertion of zero dates 18) Schema inconsistencies resulting from file removal or corruption No issues found 19) Tables recognized by InnoDB that belong to a different engine No issues found 20) Issues reported by 'check table x for upgrade' command No issues found 21) New default authentication plugin considerations Warning: The new default authentication plugin 'caching_sha2_password' offers more secure password hashing than previously used 'mysql_native_password' (and consequent improved client connection authentication). However, it also has compatibility implications that may affect existing MySQL installations. If your MySQL installation must serve pre-8.0 clients and you encounter compatibility issues after upgrading, the simplest way to address those issues is to reconfigure the server to revert to the previous default authentication plugin (mysql_native_password). For example, use these lines in the server option file: [mysqld] default_authentication_plugin=mysql_native_password However, the setting should be viewed as temporary, not as a long term or permanent solution, because it causes new accounts created with the setting in effect to forego the improved authentication security. If you are using replication please take time to understand how the authentication plugin changes may impact you. More information: https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatibility-issues https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-replication Errors: 1 Warnings: 17 Notices: 0 1 errors were found. Please correct these issues before upgrading to avoid compatibility issues. #修改t1表引擎为InnoDB mysql> alter table t1 engine=innodb; Query OK, 0 rows affected (0.02 sec) Records: 0 Duplicates: 0 Warnings: 0
MySQL Shell的util.checkForServerUpgrade工具主要做了以下检查,当然我们也可以手动进行相关的检查。
可执行以下命令检查上述问题:
mysqlcheck -u root -p --all-databases --check-upgrade
不应存在非InnoDB或NDB引擎的分区表,如存在需变更引擎或转换成非分区表。可通过以下SQL检查:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';
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' );
不得有外键约束名称长度超过 64 个字符的表,如存在则删除后重建。可用以下SQL检查:
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);
#5.7版本以下SQL检查 SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single'; #8.0早期版本以下SQL检查 SELECT DISTINCT NAME, SPACE, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLES WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single'; #如存在,可使用reorganize partition命令将共享表空间中的分区迁移到 file-per-table表空间 ALTER TABLE $table_name REORGANIZE PARTITION $partition_name INTO (partition_definition TABLESPACE=innodb_file_per_table);
mysql> SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != LOWER(TABLE_NAME) AND TABLE_TYPE = 'BASE TABLE'; mysql> SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME != LOWER(SCHEMA_NAME);
如果出现上述问题导致的升级失败,MySQL会将变更还原,这时删除redo log并重启5.7版本实例即可。注意关闭前一定设置innodb_fast_shutdown=0。
升级需求:将8.0.26升级到8.0.33
确保业务已停止,保证数据一致性
--查询数据库中哪些线程正在执行 show processlist;
select version() 或 mysql -V 或 show variables like '%version%'
--多个数据库备份成1个文件 mysqldump -uroot -p --databases xiaomiaoao pijiake > /root/all-databases2213.sql --备份test数据库 mysqldump -uroot -p test > /data/mysqldb/tmp/test_exp_$(date +%F).sql
如果升级失败能更快的回退
--停止数据库 systemctl stop mysqld --安装目录备份 cp -r /data/mysqldb/mysql /data/mysqldb/mysql_bak_`date +%F` --数据目录备份 cp -r /data/mysqldb/data /data/mysqldb/data_bak_`date +%F` --配置文件备份 cp /etc/my.cnf /etc/my5_bak_`date +%F`.cnf
再次查看运行情况,确认关闭情况 Active: inactive (dead)
systemctl status mysqld systemctl stop mysqld systemctl status mysqld
#1.安装介质上传至/opt/下 #2.解压安装包 tar -xvf mysql-8.0.33-el7-x86_64.tar.gz -C /data/ #4.文件夹重命名为mysql8 mv /data/mysql* /data/mysql8033 #5.更改文件夹所属 chown -R mysql.mysql /data/mysql8033
--备份原配置文件 cp /etc/my.cnf /etc/my.cnf.bak_`date +%F` --更改配置文件 安装目录
cd /data/mysql8033/support-files ls -l /etc/init.d/mysqld #如果该文件存在跳过第3条命令 cp mysql.server /etc/init.d/mysqld vi /etc/init.d/mysqld #确认或更改basedir或datadir参数 service mysqld start 或mysql.service start service mysqld status
--问题描述 [root@top132:/data/mysql813/mysql8/support-files]$ service mysqld start Starting MySQL........................................................................................................ ERROR! The server quit without updating PID file (/data/mysql813/data8/top132.pid). 解决办法: /etc/my.cnf中的pid路径需指向basedir
升级需求:将5.7.42升级到8.0.13,以In-Place方式直接升级到MySQL8.0.13。
原版本 | 5.7.42 | Centos7.6 x86_64 |
---|---|---|
新版本 | 8.0.13 | Centos7.6 x86_64 |
关闭现有版本MySQL,将二进制或包替换成新版本并在现有数据目录上启动MySQL并执行升级任务的方式,称为in-place升级。升级过程分为以下几步:
确保业务已停止,保证数据一致性
--查询数据库中哪些线程正在执行 show processlist;
#查版本 mysql -V 或 mysql> select version(); +------------+ | version() | +------------+ | 5.7.42-log | +------------+ 1 row in set (0.00 sec)
场景1:查询所有数据库的总大小
--查询所有数据库的总大小 use information_schema; select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES; --统计一下所有库数据量 SELECT SUM(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024/1024 AS total_mb FROM information_schema.TABLES; --统计每个库大小 SELECT table_schema,SUM(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024/1024 AS total_mb FROM information_schema.TABLES group by table_schema;
场景2:查看指定数据库的大小
use information_schema; select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='pijiake';
场景3:记录数
--查看所有数据库各容量大小 select table_schema as '数据库', sum(table_rows) as '记录数', sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)', sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)' from information_schema.tables group by table_schema order by sum(data_length) desc, sum(index_length) desc; --查看所有数据库各表容量大小 select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables order by data_length desc, index_length desc; --查看指定数据库容量大小(例:查看mysql库容量大小) select table_schema as '数据库', sum(table_rows) as '记录数', sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)', sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)' from information_schema.tables where table_schema='test'; --查看指定数据库各表容量大小(例:查看mysql库各表容量大小) select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables where table_schema='test' order by data_length desc, index_length desc;
--多个数据库备份成1个文件 mysqldump -uroot -p --databases xiaomiaoao pijiake > /root/all-databases2213.sql --备份test数据库 mysqldump -uroot -p test > /data/mysqldb/tmp/test_exp_$(date +%F).sql
如果升级失败能更快的回退
--停止数据库 systemctl stop mysqld --安装目录备份 cp -r /data/mysqldb/mysql /data/mysqldb/mysql_bak_`date +%F` --数据目录备份 cp -r /data/mysqldb/data /data/mysqldb/data_bak_`date +%F` --配置文件备份 cp /etc/my.cnf /etc/my5_bak_`date +%F`.cnf
#1.安装介质上传至/opt/下 #2.创建目录 mkdir -p /data/mysqldb813 #3.解压安装包 tar -xvf mysql-8.0.13-el7-x86_64.tar.gz -C /data/mysqldb813 #4.文件夹重命名为mysql8 mv /data/mysqldb813/mysql* /data/mysqldb813/mysql813 #5.更改文件夹所属 chown -R mysql.mysql /data/mysqldb813
因5.7版本与8.0版本参数有所不同,为了能顺利升级,需要更改部分配置参数。主要注意sql_mode、basedir、密码认证插件及字符集设置,其他参数最好还是按照原5.7的来,不需要做调整。
更改/etc/my.conf配置,末尾添加关键配置
#add for 8.0 sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION character-set-server = utf8 collation-server = utf8_general_ci basedir = /data/mysqldb813/mysql813 skip_ssl default_authentication_plugin=mysql_native_password
https://blog.csdn.net/weixin_42689212/article/details/121293222
--1.进入原5.7 mysql命令行 正确关闭数据库 法1: mysqladmin -uroot -p shutdown [root@mysql]# mysql -uroot -p Enter password: #使用mysql shell 命令util.checkForServerUpgrade('root@127.0.0.1:3307', {"password":"XXXXX", "targetVersion":"8.0.26", "configPath":"/etc/my3307.cnf"}) 检查升级到目标版本8.0.26,确认没有error级别的问题 Errors: 0 Warnings: 17 Notices: 0 #检查没有未提交的xa事务 mysql> xa recover; Empty set (0.00 sec) # 确保数据都刷到硬盘上,更改成0 mysql> show variables like 'innodb_fast_shutdown'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_fast_shutdown | 1 | +----------------------+-------+ 1 row in set (0.00 sec) mysql> set global innodb_fast_shutdown=0; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'innodb_fast_shutdown'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_fast_shutdown | 0 | +----------------------+-------+ mysql> shutdown; Query OK, 0 rows affected (0.00 sec) mysql> exit #查看进程和端口后,已无输出记录,确保已停止 [root@localhost mysqldb8]# ps -ef | grep mysql root 6330 6202 0 07:35 pts/0 00:00:00 mysql -uroot -p -P2213 test root 6466 6202 0 09:18 pts/0 00:00:00 mysql -uroot -p root 6522 6293 0 09:58 pts/1 00:00:00 mysql -uroot -p root 6603 6551 0 10:14 pts/3 00:00:00 grep --color=auto mysql [root@localhost mysqldb8]# ss -ntl | grep 2213
因目标版本8.0.13,直接在现有数据目录上启动新版本MySQL。由MySQL服务执行升级任务,可指定–upgrade=FORCE参数
[root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql --upgrade=FORCE & [1] 6611 [root@localhost mysqldb8]# 2023-10-15T02:20:11.533316Z mysqld_safe Logging to '/data/mysqldb/log/mysqld_error.log'. 2023-10-15T02:20:11.557198Z mysqld_safe Starting mysqld daemon with databases from /data/mysqldb/data 2023-10-15T02:20:12.121520Z mysqld_safe mysqld from pid file /data/mysqldb/data/mysqld.pid ended 会一直卡住不用担心
cd /data/mysqldb813/mysql813/bin ./mysql_upgrade -uroot -p select version(); --输出+-----------+ | version() | +-----------+ | 8.0.13 | +-----------+ 说明数据库平滑升级成功了
因basedir由/data/mysqldb/mysql变成了/data/mysqldb8/mysql8,故相关环境变量修改如下
将mysql5.7的环境变量参数更改为mysql8.0的
#更改环境变量 [root@localhost ~]# vi .bash_profile ... MYSQL_DATA=/data/mysqldb/data #mysql5.7弃用 #export PATH=$PATH:/data/mysqldb/mysql/bin #export MYSQL_HOME=/data/mysqldb/mysql #add for mysql8.0 export MYSQL_HOME=/data/mysqldb813/mysql813 export PATH=$PATH:/data/mysqldb813/mysql813/bin #生效环境变量 [root@localhost ~]# source .bash_profile #查看版本 [root@localhost ~]# mysql -V mysql Ver 8.0.13 for el7 on x86_64 (MySQL Community Server - GPL) 或 [root@localhost ~]# mysql -uroot -p root@localhost :(none) 10:40:24>select version(); +-----------+ | version() | +-----------+ | 8.0.13 | +-----------+ 1 row in set (0.00 sec) root@localhost :(none) 10:40:30>exit
--停止mysql5系统服务 systemctl stop mysqld systemctl disable mysqld --配置mysql8系统服务 cp /usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/mysqld8.service [root@localhost ~]# cat /usr/lib/systemd/system/mysqld8.service [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 ExecStart=/data/mysqldb813/mysql813/bin/mysqld --defaults-file=/data/mysqldb/my.cnf LimitNOFILE=65536 LimitNPROC=65536 systemctl start mysqld8 systemctl enable mysqld8 systemctl status mysqld8
至此,数据库由5.7成功升级至8.0!对比MySQL安装过程及升级过程,发现二者很相似,其实升级过程并不复杂,复杂的是升级后的验证及兼容测试,特别是对于复杂的业务库,MySQL版本升级还是要小心的。真实环境建议先升级从库,验证无误后再逐步对主库进行升级。
--问题描述 [root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysql -uroot -p Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysqldb/data/mysql.sock' (2) --问题处理 找到 mysql.sock find / -name mysql.sock --更改/etc/my.cnf 更改为上一步找到的mysql.sock文件目录
--问题描述 2023-10-15T10:20:12.102785+08:00 0 [ERROR] [MY-000077] [Server] /data/mysqldb8/mysql8/bin/mysqld: Error while setting value 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER' to 'sql_mode'. --查看报错日志 sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER --问题原因 8.0以上已经取消了NO_AUTO_CREATE_USER这个关键字,在my.cnf中的sql_mode中删掉这个关键字重启即可 是每次升级后sql_mode的值。逗号后面都会自动加上空格导致无法启动,要手动删掉空格 --问题处理 去掉sql_mode中的NO_AUTO_CREATE_USER sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 再次启动 [root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql & 或 systemctl restart mysqld8 systemctl status mysqld8
升级需求:将5.7.42升级到8.0.13,升级方式
原版本 | 5.7.42 | Centos7.6 x86_64 |
---|---|---|
新版本 | 8.0.13 | Centos7.6 x86_64 |
逻辑升级是指使用逻辑备份从旧版本MySQL中导出数据,安装新版本MySQL并导入数据的升级方式。由于可能存在的不兼容问题会导致导入失败,导出前需要做升级前检查,导入前可能还需要对备份文件进行修改。
升级主要步骤:
#8.0.16以后的版本 mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir --upgrade=FORCE & #8.0.16之前的版本 mysql_upgrade -u root -p mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir & #确认升级成功后,mysql schema中两张不再使用的表可以自行清理 DROP TABLE mysql.event; DROP TABLE mysql.proc;
升级需求:将5.7.42升级到8.0.27,以In-Place方式直接升级到MySQL8.0.27。
原版本 | 5.7.42 | Centos7.6 x86_64 |
---|---|---|
新版本 | 8.0.27 | Centos7.6 x86_64 |
确保业务已停止,保证数据一致性
--查询数据库中哪些线程正在执行 show processlist;
#查版本 mysql -V 或 mysql> select version(); +------------+ | version() | +------------+ | 5.7.42-log | +------------+ 1 row in set (0.00 sec)
场景1:查询所有数据库的总大小
--查询所有数据库的总大小 use information_schema; select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES; --统计一下所有库数据量 SELECT SUM(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024/1024 AS total_mb FROM information_schema.TABLES; --统计每个库大小 SELECT table_schema,SUM(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH)/1024/1024 AS total_mb FROM information_schema.TABLES group by table_schema;
场景2:查看指定数据库的大小
use information_schema; select concat(round(sum(DATA_LENGTH/1024/1024),2),'MB') as data from TABLES where table_schema='test';
场景3:记录数
--查看所有数据库各容量大小 select table_schema as '数据库', sum(table_rows) as '记录数', sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)', sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)' from information_schema.tables group by table_schema order by sum(data_length) desc, sum(index_length) desc; --查看所有数据库各表容量大小 select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables order by data_length desc, index_length desc; --查看指定数据库容量大小(例:查看mysql库容量大小) select table_schema as '数据库', sum(table_rows) as '记录数', sum(truncate(data_length/1024/1024, 2)) as '数据容量(MB)', sum(truncate(index_length/1024/1024, 2)) as '索引容量(MB)' from information_schema.tables where table_schema='test'; --查看指定数据库各表容量大小(例:查看mysql库各表容量大小) select table_schema as '数据库', table_name as '表名', table_rows as '记录数', truncate(data_length/1024/1024, 2) as '数据容量(MB)', truncate(index_length/1024/1024, 2) as '索引容量(MB)' from information_schema.tables where table_schema='test' order by data_length desc, index_length desc;
--多个数据库备份成1个文件 mysqldump -uroot -p --databases xiaomiaoao pijiake > /root/all-databases2213.sql --备份test数据库 mysqldump -uroot -p test > /data/mysqldb/tmp/test_exp_$(date +%F).sql
如果升级失败能更快的回退
--停止数据库 systemctl stop mysqld --安装目录备份 cp -r /data/mysqldb/mysql /data/mysqldb/mysql_bak_`date +%Y%m%d` --数据目录备份 cp -r /data/mysqldb/data /data/mysqldb/data_bak_`date +%Y%m%d` --配置文件备份 cp /etc/my.cnf /etc/my5.cnf_bak_`date +%Y%m%d`
#1.安装介质上传至/opt/下 #2.创建目录 mkdir -p /data/mysqldb8 #3.解压安装包 tar -xvf mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz -C /data/mysqldb8 #4.文件夹重命名为mysql8 mv /data/mysqldb8/mysql* /data/mysqldb8/mysql8 #5.更改文件夹所属 chown -R mysql.mysql /data/mysqldb8
因5.7版本与8.0版本参数有所不同,为了能顺利升级,需要更改部分配置参数。主要注意sql_mode、basedir、密码认证插件及字符集设置,其他参数最好还是按照原5.7的来,不需要做调整。
更改/etc/my.conf配置,末尾添加关键配置
#add for 8.0 sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION character-set-server = utf8 collation-server = utf8_general_ci basedir = /data/mysqldb8/mysql8 skip_ssl default_authentication_plugin=mysql_native_password
https://blog.csdn.net/weixin_42689212/article/details/121293222
--1.进入原5.7 mysql命令行 正确关闭数据库 法1: mysqladmin -uroot -p shutdown [root@mysql]# mysql -uroot -p Enter password: #使用mysql shell 命令util.checkForServerUpgrade('root@127.0.0.1:3307', {"password":"XXXXX", "targetVersion":"8.0.26", "configPath":"/etc/my3307.cnf"}) 检查升级到目标版本8.0.26,确认没有error级别的问题 Errors: 0 Warnings: 17 Notices: 0 #检查没有未提交的xa事务 mysql> xa recover; Empty set (0.00 sec) # 确保数据都刷到硬盘上,更改成0 mysql> show variables like 'innodb_fast_shutdown'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_fast_shutdown | 1 | +----------------------+-------+ 1 row in set (0.00 sec) mysql> set global innodb_fast_shutdown=0; Query OK, 0 rows affected (0.00 sec) mysql> show variables like 'innodb_fast_shutdown'; +----------------------+-------+ | Variable_name | Value | +----------------------+-------+ | innodb_fast_shutdown | 0 | +----------------------+-------+ mysql> shutdown; Query OK, 0 rows affected (0.00 sec) mysql> exit #查看进程和端口后,已无输出记录,确保已停止 [root@localhost mysqldb8]# ps -ef | grep mysql root 6330 6202 0 07:35 pts/0 00:00:00 mysql -uroot -p -P2213 test root 6466 6202 0 09:18 pts/0 00:00:00 mysql -uroot -p root 6522 6293 0 09:58 pts/1 00:00:00 mysql -uroot -p root 6603 6551 0 10:14 pts/3 00:00:00 grep --color=auto mysql [root@localhost mysqldb8]# ss -ntl | grep 2213
因目标版本8.0.27,直接在现有数据目录上启动新版本MySQL。由MySQL服务执行升级任务,可指定–upgrade=FORCE参数
[root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql --upgrade=FORCE & [1] 6611 [root@localhost mysqldb8]# 2023-10-15T02:20:11.533316Z mysqld_safe Logging to '/data/mysqldb/log/mysqld_error.log'. 2023-10-15T02:20:11.557198Z mysqld_safe Starting mysqld daemon with databases from /data/mysqldb/data 2023-10-15T02:20:12.121520Z mysqld_safe mysqld from pid file /data/mysqldb/data/mysqld.pid ended 会一直卡住不用担心
[root@localhost mysqldb8]# mysql -uroot -p root@localhost :(none) 10:36:19>select version(); +-----------+ | version() | +-----------+ | 8.0.27 | +-----------+ 1 row in set (0.00 sec) 说明数据库平滑升级成功了
因basedir由/data/mysqldb/mysql变成了/data/mysqldb8/mysql8,故相关环境变量修改如下
将mysql5.7的环境变量参数更改为mysql8.0的
#更改环境变量 [root@localhost ~]# vi .bash_profile ... MYSQL_DATA=/data/mysqldb/data #mysql5.7弃用 #export PATH=$PATH:/data/mysqldb/mysql/bin #export MYSQL_HOME=/data/mysqldb/mysql #add for mysql8.0 export MYSQL_HOME=/data/mysqldb8/mysql8 export PATH=$PATH:/data/mysqldb8/mysql8/bin #生效环境变量 [root@localhost ~]# source .bash_profile #查看版本 [root@localhost ~]# mysql -V mysql Ver 8.0.27 for Linux on x86_64 (MySQL Community Server - GPL) 或 [root@localhost ~]# mysql -uroot -p root@localhost :(none) 10:40:24>select version(); +-----------+ | version() | +-----------+ | 8.0.27 | +-----------+ 1 row in set (0.00 sec) root@localhost :(none) 10:40:30>exit
--停止mysql5系统服务 systemctl stop mysqld systemctl disable mysqld --配置mysql8系统服务 cp /usr/lib/systemd/system/mysqld.service /usr/lib/systemd/system/mysqld8.service [root@localhost ~]# cat /usr/lib/systemd/system/mysqld8.service [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 ExecStart=/data/mysqldb8/mysql8/bin/mysqld --defaults-file=/data/mysqldb/my.cnf LimitNOFILE=65536 LimitNPROC=65536 systemctl start mysqld8 systemctl enable mysqld8 systemctl status mysqld8
至此,数据库由5.7成功升级至8.0!对比MySQL安装过程及升级过程,发现二者很相似,其实升级过程并不复杂,复杂的是升级后的验证及兼容测试,特别是对于复杂的业务库,MySQL版本升级还是要小心的。真实环境建议先升级从库,验证无误后再逐步对主库进行升级。
--问题描述 [root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysql -uroot -p Enter password: ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/data/mysqldb/data/mysql.sock' (2) --问题处理 找到 mysql.sock find / -name mysql.sock --更改/etc/my.cnf 更改为上一步找到的mysql.sock文件目录
--问题描述 2023-10-15T10:20:12.102785+08:00 0 [ERROR] [MY-000077] [Server] /data/mysqldb8/mysql8/bin/mysqld: Error while setting value 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION,NO_AUTO_CREATE_USER' to 'sql_mode'. --问题原因 8.0以上已经取消了NO_AUTO_CREATE_USER这个关键字,在my.cnf中的sql_mode中删掉这个关键字重启即可 是每次升级后sql_mode的值。逗号后面都会自动加上空格导致无法启动,要手动删掉空格 --问题处理 将sql_mode替换为如下: sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 再次启动 [root@localhost mysqldb8]# /data/mysqldb8/mysql8/bin/mysqld_safe --defaults-file=/etc/my.cnf --user=mysql & 或 systemctl restart mysqld8 systemctl status mysqld8
升级需求:将5.7.42升级到8.0.27,升级方式
原版本 | 5.7.42 | Centos7.6 x86_64 |
---|---|---|
新版本 | 8.0.27 | Centos7.6 x86_64 |
逻辑升级是指使用逻辑备份从旧版本MySQL中导出数据,安装新版本MySQL并导入数据的升级方式。由于可能存在的不兼容问题会导致导入失败,导出前需要做升级前检查,导入前可能还需要对备份文件进行修改。
升级主要步骤:
#8.0.16以后的版本 mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir --upgrade=FORCE & #8.0.16之前的版本 mysql_upgrade -u root -p mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to/8.0-datadir & #确认升级成功后,mysql schema中两张不再使用的表可以自行清理 DROP TABLE mysql.event; DROP TABLE mysql.proc;
1.STRICT_TRANS_TABLES:如果插入或更新操作反了表定义的约束条件,则会导致警告或错误2.NO_ZERO_IN_DATE:禁止在日期中使用零值,例如0000-00-00’
3.NO_ZERO_DATE:禁止日期列中的零值,默认情况下,MySQL允许使用0000-00-00表示无效日期
4.ERROR_FOR_DIVISION_BY_ZERO:如果除数为零,则会引发错误
5.NO_ENGINE_SUBSTITUTION: 如果指定了一个不存在的存储引擎,MySQL将引发错误
innodb_fast_shutdown有3个值:
默认是1 可选0 1 2
支持全动态局设置
使用场景:在做数据库关闭升级的时候 set global innodb_fast_shutdown=0,这个时候能最大保障数据的完整性。
设置为1:关闭MySQL的时候不会做清除脏页和插入缓冲区的合并操作,也不会将脏页刷新到磁盘
设置为0:会做清除脏页和插入缓冲区的合并操作,也会将脏页全部刷新到磁盘上面去,但是这个时候关闭的速度也是最慢的
设置为2:不会做清除脏页和插入缓冲区的合并操作,也不会将脏页刷新到磁盘,但是会刷新到redo log里面,再下次启动mysql的时候恢复
参考链接:https://zhuanlan.zhihu.com/p/426007112