升级版本选择准则和建议

MySQL升级必须遵循以下一些原则和建议:

支持从MySQL5.7升级到8.0。请注意,仅支持正式发行版本之间的升级。

  • 不支持跨大版本的升级,如从5.6升级到8.0是不支持的。
  • 建议升级大版本前先升级到当前版本的最近小版本,如5.7先升级到5.7.35后再升级到8.0。
  • 在大版本内部GA的小版本可以直接升级,如从8.0.9直接升级到8.0.26。
  • MySQL8.0的一些变化

    在升级到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选项,并且用户需要全局selet权限。

    • Authentication Plugin

    MySQL8.0将默认身份验证插件从mysql_native_password变更为caching_sha2_password,客户端需要验证现有版本是否支持。

    • Configuration Changes
    • MySQL8.0开始只有InnoDB和NDB引擎支持分区表,升级前需确保不存在非InnoDB引擎的分区表。
    • 部分error code被启用,详见
    • 默认字符集从latin1变更为utf8mb4,默认排序规则为utf8mb4_0900_ai_ci。注意这可能会导致新旧数据库对象的字符集不一致,造成隐式类型转换的问题。
    • 8.0.11版本开始,如使用与初始化配置不同的lower_case_table_names值启动数据库时会报错。
    • [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
    • Server Changes
    • 8.0.11开始部分账户管理功能被删除,如Grant命令修改用户非权限特性,NO_AUTO_CREATE_USER模式,PASSWORD() 函数和 old_passwords 系统变量。
    • 8.0.11开始删除了部分兼容 SQL 模式:DB2、MAXDB、MSSQL、MYSQL323、MYSQL40、ORACLE、POSTGRESQL、NO_FIELD_OPTIONS、NO_KEY_OPTIONS、NO_TABLE_OPTIONS。
    • 从 MySQL 8.0.3 开始,空间数据类型允许 SRID 属性,以明确指示存储在列中的值的空间参考系统 (SRS)。并删除了部分非ST_前缀的空间函数。详见在线切换binlog format增加了更多限制。
    • InnoDB Changes
      • information_Schema中,innodb_sys_% 改名为 innodb_%
      • zlib库版本从1.2.3升级到1.2.11。
      • 只读变量innodb_directories应该包含file-per-table和绝对路径创建的通用表空间文件的路径。
      • undo日志从系统表空间移出。默认会在innodb_undo_directory指定位置(未指定则在data dir)创建两个undo表空间。从5.7升级到8.0时innodb-fast-shutdown需设置成0。
      • 8.0.17开始在创建表空间时,路径不允许含 circular directory reference(/../);升级前可以查询INFORMATION_SCHEMA.INNODB_DATAFILES表检查表空间路径。mysql> CREATE TABLESPACE ts11 ADD DATAFILE '/data/mysql/log/test/..;;
        ERROR 3121 (HY000): The ADD DATAFILE filepath cannot contain circular directory references.
        mysql> CREATE TABLESPACE ts11 ADD DATAFILE '/data/mysql/log;;
        Query OK, 0 rows affected sec)
    • SQL change
      • group by 不再支持DESC和ASC,GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
      • 保留字变更。
      • 升级后建议测试optimizer hints,在8.0中部分hint可能不再适用。
    • 部分默认配置的变化。

    升级过程包含哪些操作

    升级MySQL时需要对现版本MySQL中的数据字典和元数据等进行更新。在MySQL Schema中需更新数据字典表和系统表,在其他Schema中需要更新一些内置的MySQL持有的表,如performance_Schema、information_schema和sys schema等。

    升级过程大致分为两个部分,升级数据字典和升级服务。

    • 升级数据字典包括升级MySQL Schema中的数据字典表,以及performance schema,information_schema。升级数据字典表时,如当前版本低于期望版本,则服务器将创建新版本的数据字典表并将持久化的元数据拷贝到新表,在新旧表做原子性替换后重新初始化数据字典。服务器启动后会按需执行,可以使用 --upgrade=NONE(8.0.16以后)或–no-dd-upgrade (8.0.16之前)参数启动MySQL,阻止数据字典表的升级。
    • 升级服务及其余升级任务,包括MySQL Schema中的非数据字典表,sys schema和用户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 Shell使用u进行检查,返回内容包括不符合迁移要求的问题,error的问题需要迁移前修改。

    下面的例子中就存在一个不兼容的问题,ymh.t1表是一个MyISAM引擎的分区表,需将该表引擎调整为innodb后方可升级。

    MySQL JS > u('root@127.0.0.1:3307', {"password":"XXXX", "targetVersion":"8.0.26", "configPath":"/etc;}) 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: 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: 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: global.sql_mode - does not contain either NO_ZERO_DATE or NO_ZERO_IN_DATE which allows insertion of zero dates - 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 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: 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 sec) Records: 0 Duplicates: 0 Warnings: 0

    MySQL Shell的u工具主要做了以下检查,当然我们也可以手动进行相关的检查。

    • 不应存在以下问题
      • 使用过时的数据类型和函数的表。如5.6.4之前的不支持小数点的时间格式。需在执行In-place升级前执行repair table修复。
      • 没有孤立的.frm文件。
      • 触发器不能缺失或空的definer或无效的creation context。
    • 可执行以下命令检查上述问题: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%';
    • 检查是否使用了8.0新增的保留字。
    • MySQL Schema中不应存在8.0数据字典表同名的表,可用以下SQL检查:
    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);
    • sql_mode系统参数不能含前面提到弃用模式。
    • 视图中不能有显式定义超过64个字符的列名。可查看INFORMATION_SCHEMA.VIEWS检查。
    • 表和存储过程中单个枚举和SET列元素不能超过255个字符或1020个字节。
    • 升级到8.0.13版本前,包括系统表空间和通用表空间在内的共享表空间中不能存在表分区。
    #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);
    • 查询和存储过程中不能在group by子句中使用ASC或者DESC。
    • 不能使用8.0中不支持的功能和配置参数。
    • 从 MySQL 8.0.19 开始,如果lower_case_table_names=1,升级过程会检查表和模式名称以确保所有字符都是小写。如果发现表或架构名称包含大写字符,升级过程将失败并显示错误。
    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。

    Linux系统升级Binary或Package-based安装的MySQL

    在这种场景下可以选择in-place或者logical方式进行升级。

    • in-place升级

    关闭现有版本MySQL,将二进制或包替换成新版本并在现有数据目录上启动MySQL并执行升级任务的方式,称为in-place升级。升级过程分为以下几步:

    1. 完成升级前检查,并处理不合规问题。
    2. 如果使用了XA事务,升级前通过命令xa recover未提交XA事务,并使用xa commit或xa rollback命令提交或回滚。
    3. 如当前版本低于5.7.11且使用了加密表空间,升级前轮换keyring的master keyALTER INSTANCE ROTATE INNODB MASTER KEY。
    4. 将innodb_fast_shutdown改为0或1。
    5. 关闭现版本MySQL。
    6. 升级MySQL二进制文件或软件包。
    7. 在现有数据目录上启动新版本MySQL。如果有加密的 InnoDB 表空间,请使用 --early-plugin-load选项加载keyring插件。如升级失败请删除redolog,启动5.7版本并修复错误,设置innodb_fast_shutdown为0后关闭MySQL。再使用8.0版本MySQL启动。
    8. 如目标版本小于8.0.16,MySQL启动后还需执行mysql_upgrade后重启MySQL。

    如下所示:

    #当前版本为5.7.23 mysql> select @@global.version; +------------------+ | @@global.version | +------------------+ | 5.7.23-log | +------------------+ 1 row in set sec) #使用mysql shell 命令u('root@127.0.0.1:3307', {"password":"XXXXX", "targetVersion":"8.0.26", "configPath":"/etc;}) 检查升级到目标版本8.0.26,确认没有error级别的问题 Errors: 0 Warnings: 17 Notices: 0 No fatal errors were found that would prevent an upgrade, but some potential issues were detected. Please ensure that the reported issues are not significant before upgrading. #检查没有未提交的xa事务 mysql> xa recover; Empty set sec) #将innodb_fast_shutdown改为0或1 mysql> set global innodb_fast_shutdown=0;select @@global.innodb_fast_shutdown; Query OK, 0 rows affected sec) +-------------------------------+ | @@global.innodb_fast_shutdown | +-------------------------------+ | 0 | +-------------------------------+ 1 row in set sec) #关闭MySQL mysql> shutdown; Query OK, 0 rows affected sec) #因目标版本8.0.26,直接在现有数据目录上启动新版本MySQL。由MySQL服务执行升级任务,可指定--upgrade=FORCE参数 [root@node1 ~]# cd /usr/local [root@node1 bin]# ./mysqld_safe --defaults-file=/etc --user=mysql --upgrade=FORCE & [1] 106547 [root@node1 bin]# mysqld_safe Adding '/usr/lib; to LD_PRELOAD for mysqld 2021-10-15T03:24:11.019020Z mysqld_safe Logging to '/data/mysql3307/log;. 2021-10-15T03:24:11.073416Z mysqld_safe Starting mysqld daemon with databases from /data/mysql3307/data #启动后查看当前服务版本,确认已升级到目标版本 mysql> \s -------------- mysql Ver 8.0.26 for Linux on x86_64 (Source distribution) Connection id: 11 Current database: Current user: root@127.0.0.1 SSL: Cipher in use is ECDHE-RSA-AES128-GCM-SHA256 Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 8.0.26-debug Source distribution Protocol version: 10 Connection: 127.0.0.1 via TCP/IP Server characterset: utf8mb4 Db characterset: utf8mb4 Client characterset: utf8mb4 Conn. characterset: utf8mb4 TCP port: 3307 Binary data as: Hexadecimal Uptime: 2 min 39 sec Threads: 2 Questions: 11 Slow queries: 0 Opens: 656 Flush tables: 4 Open tables: 35 Queries per second avg: 0.069 --------------
    • logical升级

    逻辑升级是指使用逻辑备份从旧版本MySQL中导出数据,安装新版本MySQL并导入数据的升级方式。由于可能存在的不兼容问题会导致导入失败,导出前需要做升级前检查,导入前可能还需要对备份文件进行修改。

    升级步骤如下:

    1. 对旧版本数据做全量导出。mysqldump -u root -p --add-drop-table --routines --events --all-databases --force > da
    2. 关闭当前版本数据库。
    3. 安装8.0版本数据库并初始化(从error log中获取’root’@'localhost’用户初始密码)。
    4. 在新的数据目录中启动MySQL8.0,并重置初始密码。
    5. 将备份文件导入mysql -u root -p --force < da。如导出文件包含系统表,则不建议导入时开启GTID(gtid_mode=ON)。
    6. 执行剩余的升级操作。目标版本大于8.0.16时需重启服务器,启动时使用–upgrade=FORCE参数。8.0.16之前的版本先执行mysql_upgrade再重启MySQL。
    #8.0.16以后的版本 mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to --upgrade=FORCE & #8.0.16之前的版本 mysql_upgrade -u root -p mysqladmin -u root -p shutdown mysqld_safe --user=mysql --datadir=/path/to & #确认升级成功后,mysql schema中两张不再使用的表可以自行清理 DROP TABLE my; DROP TABLE my;

    墨天轮原文链接:(复制到浏览器或者点击“阅读原文”立即查看)

    关于作者

    杨明翰,云和恩墨服务总监。拥有MySQL、TDSQL、TiDB、openGauss等认证。长期从事MySQL、PG、Redis、MongoDB的数据库技术服务。现负责云和恩墨西区开源数据库交付运维工作;热衷于开源数据库产品的研究。

    END

    由中国DBA联盟和墨天轮主办的 2021数据技术嘉年华 将于11月19日-20日在北京丽都皇冠假日酒店盛大召开。

    1.《数据字典怎么导出?终于找到答案了MySQL8.0版本升级建议及各类场景的操作方法》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。

    2.《数据字典怎么导出?终于找到答案了MySQL8.0版本升级建议及各类场景的操作方法》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。

    3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/gl/3033557.html