ITPub博客

首页 > 数据库 > MySQL > 2.11.1.2Changes Affecting Upgrades to MySQL 5.7

2.11.1.2Changes Affecting Upgrades to MySQL 5.7

原创 MySQL 作者:steven_hua 时间:2018-03-12 16:23:00 0 删除 编辑

http://blog.csdn.net/shaochenshuo/article/details/52596589

 

       那些被标记为"Known issue"和"Incompatible change"的变化,是同之前的mysql版本不兼容的,你需要特别关注。我们的目标是尽量避免两个版本之间出现这种不兼容的变化,但是有的时候我们为了解决某个严重的问题,会带来这种变化(当然这个问题肯定比两个版本间的不兼容更槽糕)。如果你在升级的过程中遇到一些不兼容问题需要特别处理时,请参照本节的不兼容说明进行处理。有时候这些处理涉及到对表进行dump然后重新导入,或者对表执行check table和repair table命令。

 

     恢复表结构的命令,必须在upgrade之前执行。如果创建表和repair table table_name USE_FRM;两个操作在不同的数据库版本下进行的(即在upgrade后执行repair操作),可能会损坏表。

 

  1. 配置变化

  

  • Incompatible change 不兼容的改变

   对于Mysql 5.7.12 --early-plugin-load参数(server command)默认值为空,如果想加载keyring_file插件你需要使用--early-plugin-load在mysql实例启动时进行指定

    Mysql 5.7.11中--early-plugin-load默认值为keyring_file,所以默认是可以使用该插件的。如果需要对innodb 表空间进行加密,需要在innodb初始化之前加载keyring_file插件。这个默认值的变化就导致了从5.7.11 升级到5.7.12或者更高版本的时候可能会出现不兼容的现象。如果你在5.7.11使用了innodb 表空间加密,那么升级时要注意指定--early-plugin-load=keyring_file来启动高版本实例。更多信息请参考Section 7.5.3.1, “Keyring Plugin Installation”。    

 

##NOTE: Mysql 5.6 升级到5.7 不需要注意该变化,因为5.6中没有引入--early-plugin-load server command

  • Incompatible change 不兼容的改变

       information_schema 数据库中包含了system variables和 status信息(保存在如下表中GLOBAL_VARIABLES,SESSION_VARIABLES,GLOBAL_STATUS,SESSION_STATUS)。到了Mysql 5.7.6中performance_schema数据库中也包含了如下信息。Mysql准备使用performance_schema中的表替换information_schema中的表,并且information_schema中的表在后面的版本中会被去除。

 

     在Mysql 5.7.6中引入了show_compatibility_56参数(但是该参数在5.7.6在后面的版本中会被去掉,因为后面的版本会删除information_schema中的system variables和status相关表)。我们把该参数设置为on,那么同Mysql 5.6兼容,可以通过查看information_schema中相关表或者通过 show variables和show status(信息来源于information_schema中相关表)获得 variables和status信息。如果把该参数设置为off,那么可以通过查询performance_schema中相关表或者通过show variables和show status(信息来源于performance_schema中相关表)获得 variables和status信息,此时查询information_schema中的GLOBAL_VARIABLES,SESSION_VARIABLES,GLOBAL_STATUS,SESSION_STATUS表时会报错。

 

    关于show_compatibility_56详细信息请见Section 6.1.5, “Server System Variables”,为了更好的理解,建议阅读下面几部分内容

  • Incompatible change 不兼容的改变

     如果你在linux系统上使用rpm包安装了Mysql 5.7.6,那么mysql的启停都是使用 systemd来控制而不是mysqld_safe,并且mysqld_safe不会被安装。这就需要你在管理数据库的时候做出一些变化,详细信息请见Section 2.5.10, “Managing MySQL Server with systemd”。   

     在Mysql 5.7.5中mysql_install_db被放在了安装目录的bin目录下(Mysql 5.6时放在scripts目录下),而Perl version被放在scripts目录下。这样如果使用in-place方式从老版本升级到Mysql 5.7.5,我们会发现bin目录和scripts目录下都存在mysql_install_db可执行文件,为了避免造成混乱,最好删除scripts目录中的mysql_install_db文件。如果需要使用mysql_install_db 文件,使用bin目录下的文件。

     5.7.6及以后的版本中mysql_install_db位置已经不是很重要了,因为已经使用mysqld --initialize或者mysqld --initialize-insecure来对数据库进行初始化。

 

  • Incompatible change 不兼容的改变

到了Mysql 5.7.5版本,sql_mode发生了如下变化

  • 对于事务型存储引擎,STRICT_TRANS_TABLES默认启用。
  • 在5.7.5版本中ONLY_FULL_GROUP_BY的实现更加复杂,并且是默认启用的。所以升级前需要注意是否对之前的应用产生影响。
  • Mysql 5.7.5中sql_mode的默认值为ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES, NO_ENGINE_SUBSTITUTION
  • 到Mysql 5.7.5 ONLY_FULL_GROUP_BY 已经被加入到ANSI 中。

如果你发现因为启用ONLY_FULL_GROUP_BY导致某些应用语句出错,你可以考虑使用如下方法进行处理:

  • 如果可以的话,修改报错的语句,在 group by中加入select出现的没有进行聚合处理的所有字段,或者对 group by 中没有实现但是在select 后出现的没有进行聚合处理的字段使用ANY_VALUE()函数。例子如下:

mysql> SELECT name, address, MAX(age) FROM t GROUP BY name;  

ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP  

BY clause and contains nonaggregated column 'mydb.t.address' which  

is not functionally dependent on columns in GROUP BY clause; this  

is incompatible with sql_mode=only_full_group_by  

## 因为启用了only_full_group_by,所以上面的查询报错,我们可以把语句改写成如下两种方式,来解决  

SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;  

或者  

SELECT name, address, MAX(age) FROM t GROUP BY name,address;  

  • 如果不能修改应用中的语句,那么就去掉sql_mode中ONLY_FULL_GROUP_BY限制。

 

 

  1. System Table Changes  >>系统表的变化

 

  •     在Mysql 5.7.6版本中 mysql.user表中的password字段已经没有了,密码被存储在authentication_string字段中。如果你使用的是in-place方式升级到Mysql 5.7.6 在执行mysql_upgrade的时候会对系统表进行处理(把原来password中的内容移动到authentication_string中)。
  •     如果你选择使用logical upgrade 升级老版本到Mysql 5.7.6,那么在使用mysqldump备份老版本数据库的时候要记得加上 --add-drop-table和--flush-privileges 这两个参数。(因为两个版本中系统表结果已经发生了变化,所以必须加上--add-drop-table,因为涉及到mysql.user表的insert操作,所以加上--flush-privileges使账户生效)

     logical upgrade procedure中已经说明,先导入老版本的dump文件,然后执行mysql_upgrade。

 

 

  1. Server Changes  服务器的变化
  •      到了Mysql 5.7.5 已经不支持pre-4.1 password hashing这种密码加密方式,这就可能会导致升级的时候产生兼容性问题。如果要升级的老版本数据库中用了这种密码加密方式,那么需要修改。在Mysql 5.7.5之前版本中old_passwords参数可选值如下:

Value   Password Hashing Method Associated

 Authentication Plugin  

0   MySQL 4.1 native hashing 

mysql_native_password  

1   Pre-4.1 (“old”) hashing

mysql_old_password  

2   SHA-256 hashing

sha256_password 

  • 到Mysql 5.7.5 mysql_old_password 加密插件(对应pre-4.1 password hashing方法)已经不支持了。如果老版本的数据库中有这样的用户,升级后在启动Mysql 5.7.5及以上数据库实例的时候,会在error log中给出"unkown plugin"警告信息。关于这样的用户在升级过程中的处理方法,请见Section 7.5.1.3, “Migrating Away from Pre-4.1 Password Hashing and the mysql_old_password Plugin”。
  • --secure-auth参数在Mysql 5.7.5之前版本中是用来控制,是否允许处用了pre-4.1 password hashing加密的用户登录数据库的,可选值有on和off(即1和0)。但是在Mysql 5.7.5中该参数只有一个值即on,即在Mysql 5.7.5及以后版本都是不允许使用pre-4.1 password hashing加密用户登录的。并且这个参数在后面的版本中将不再被支持(pre-4.1 password hashing加密方式都不支持了,这个参数也就没有存在的意义了)
  • 在Mysql 5.7.5及更高版本中--skip-secure-auth 选项已经不再被支持,启动时使用该命令行参数会报错
  • 在Mysql 5.7.5中 secure_auth只有一个可选值即on(也就是1)
  • 在Mysql 5.7.5及更高版本中 old_passwords参数 已经不支持设置为1
  • 在Mysql 5.7.5及更高版本中 已经不支持OLD_PASSWORD()函数。

 

  • Incompatible change 不兼容的改变

    在Mysql 5.6.6时 YEAR(2)日期类型已经被弃用。到了Mysql 5.7.5时 YEAR(2)日期类型已经不被支持了。如果你打算把你的低版本数据库升级到Mysql 5.7.5及更高版本,那么旧版本中所有的YEAR(2)类型的列都必须要转成YEAR(4)类型。执行mysql_upgrade可以完成这种转换,关于转换的详细情况请见“YEAR(2) Limitations and Migrating to YEAR(4)”. Running mysql_upgrade after upgrading is one of the possible conversion strategies. 

 

  • Incompatible change 不兼容的改变

     到了Mysql 5.7.2 要求mysql.user表中每条记录的plugin列都不能为空,如果为空,如果为空,就无法使用该用户登录数据库。如果你的旧版本数据库mysql.user表中存在这样的记录,就需要进行处理。(其实也不需要我们特别处理,因为在升级过程中的当我们执行mysql_upgrade时就处理了该问题)。

当你准备升级到5.7.6及更高版本时,可以通过如下方法处理mysql.user plugin列为空的记录:

 

使用in-place方式升级时处理方法如下:

  1. Stop the old (MySQL 5.6) server
  2. Upgrade the MySQL binaries in place by replacing the old binaries with the new ones
  3. Start the MySQL 5.7 server normally (no special options)
  4. Run mysql_upgrade to upgrade the system tables  >>就是在这一步中处理了mysql.user中plugin列为空的记录
  5. Restart the MySQL 5.7 server

使用逻辑方式升级时处理方法如下:

  1. To generate the dump file, run mysqldump with the --add-drop-table option and without the --flush-privileges option
  2. Stop the old (MySQL 5.6) server
  3. Upgrade the MySQL binaries in place (replace the old binaries with the new ones)
  4. Start the MySQL 5.7 server normally (no special options)
  5. Reload the dump file (mysql < dump_file)
  6. Run mysql_upgrade to upgrade the system tables  >>就是在这一步中处理了mysql.user中plugin列为空的记录
  7. Restart the MySQL 5.7 server

当你准备升级到5.7.6以下的5.7版本时(如果Mysql 5.7.2),可以通过如下方法处理mysql.user plugin列为空的记录:

使用in-place方式升级时处理方法如下:

  1. Stop the old (MySQL 5.6) server
  2. Upgrade the MySQL binaries in place (replace the old binaries with the new ones)
  3. Restart the server with the --skip-grant-tables option to disable privilege checking
  4. Run mysql_upgrade to upgrade the system tables
  5. Restart the server normally (without --skip-grant-tables)

使用逻辑方式升级时处理方法如下:

  1. To generate the dump file, run mysqldump without the --flush-privileges option
  2. Stop the old (MySQL 5.6) server
  3. Upgrade the MySQL binaries in place (replace the old binaries with the new ones)
  4. Restart the server with the --skip-grant-tables option to disable privilege checking
  5. Reload the dump file (mysql < dump_file)
  6. Run mysql_upgrade to upgrade the system tables
  7. Restart the server normally (without --skip-grant-tables)

mysql_upgrade 默认是使用Mysql实例的root用户运行的,如果mysql root账户过期,那么mysql_upgrade执行会失败。我们需要先重置root账户密码然后再次执行mysql_upgrade。

shell> mysql -u root -p
Enter password:
****  <- enter root password here
mysql>
ALTER USER USER() IDENTIFIED BY 'root-password'; # MySQL 5.7.6 and up
mysql>
SET PASSWORD = PASSWORD('root-password');        # Before MySQL 5.7.6
mysql>
quit

shell> mysql_upgrade -p
Enter password:
****  <- enter root password here

如果我们使用了--skip-grant-tables启动mysql实例,那么修改的密码是不会立即生效的,但是当你运行过mysql_upgrade后却发现可以用修改后的密码登录数据库,这是因为mysql_upgrde处理过程中执行了flush_privileges操作。

 

 

  • Incompatible change 不兼容的改变

生产环境中可能会出现这样的情况,在建表的时候使用某个默认值是合法的,但是在插入的时候确变成不合法的了。例子如下:(例子中在建表前把sql_mod设置为空,建表成功,然后在插入前重新设置了sql_mode,所以插入失败,当然这个是针对mysql 5.7.2以上的版本来说)

SET sql_mode = '';
CREATE TABLE t (d DATE DEFAULT 0);
SET sql_mode = 'NO_ZERO_DATE,STRICT_ALL_TABLES';
INSERT INTO t (d) VALUES(DEFAULT);

 

  • Incompatible change 不兼容的改变

为了使audit log plugin 更好的和Oracle Audit Vault兼容,我们对audit log plugin进行了几处改动。对于升级我们需要注意的是audit log记录格式发生了变化。下面列出了升级前后audit log格式

<AUDIT_RECORD
 TIMESTAMP="2013-04-15T15:27:27"
 NAME="Query"
 CONNECTION_ID="3"
 STATUS="0"
 SQLTEXT="SELECT 1"
/>

 

如果你的数据库使用了审计,那么避免新老格式的审计日志写进同一个文件,你可以进行如下处理:

  1. Stop the server.  >>停mysql 实例
  2. Rename the current audit log file manually. This file will contain only old-format log entries.  >>指定新的审计日志路径
  3. Update the server and restart it. The audit log plugin will create a new log file, which will contain only new-format log entries. >>升级数据库,然后启动升级后的数据库(这时会根据我们指定的路名和文件名创建新的审计日志)

 

  1. InnoDB Changes
  • Incompatible change 不兼容的改变

     为了使innodb的崩溃恢复更高效,Mysql 5.7.5 引入了新的格式的redo log。因此如果你进行in-place upgrade,在关闭数据库实例的时候,要指定innodb_fast_shutdown为0或者1.在"Performing an In-Place Upgrade"中建议指定innodb_fast_shutdown=0,然后关闭数据库实例(当然这种关闭实例的方式,可能耗时比较长)。

 

  • Incompatible change 不兼容的改变

     在Mysql 5.7.8和Mysql 5.7.9中 undo log中有关spatial columns列的信息不足(同更高版本相比),这个变化可能会导致升级失败。所以在准备使用in-place 方式升级5.7.8 或者5.7.9 到Mysql 5.7.10 及更高版本时,关闭数据库实例时innodb_fast_shutdown=0 ,清理undo logs。

  • Incompatible change 不兼容的改变

    在Mysql 5.7.8 中undo log中有关virtual columns and virtual column indexes的信息不足(同更高版本相比),这个变化可能会导致升级失败。所以在准备使用 in-place方式升级5.7.8升级到Mysql 5.7.9或者更高版本时,关闭数据库实例时指定innodb_fast_shutdown=0 ,清理undo logs。

  • Incompatible change 不兼容的改变

    在Mysql 5.7.9及之后版本,在创建redo log文件时,会在第一个日志文件(ib_logfile0)中会包format version identifier和 identifies the MySQL version(text 字符串)相关信息。这个变化要求我们在准备使用in-place方式升级到Mysql 5.7.9及更高版本时,关闭数据库实例时指定innodb_fast_shutdown=0或者1.

  • Incompatible change 不兼容的改变

    在Mysql 5.7.9中innodb 表的默认 row format为DYNAMIC(之前版本默认格式是COMPACT)。我们可以通过5.7.9中引入的参数innodb_default_row_format来指定默认row format格式,该参数可选值为DYNAMIC (the default), COMPACT, and REDUNDANT

   

     对于升级前就存在的表可能它们的row format还是为之之前版本默认的COMPACT,当我们对这些进行任何会引起rebuild table的操作时,这些表的row format会修改为此当时innodb_default_row_format指定的值。在没有对这些表进行rebulid操作之前,这些表会一直使用之前的row format。

 

  1. SQL Changes
  • Incompatible change 不兼容的改变

    在Mysql 5.7.5 通过使用metadata locking subsystem对GET_LOCK()进行了重新实现,他的功能也得到了扩展

  • 在之前的版本中GET_LOCK()函数在同一时间只能获得一个锁,在获取第二个锁的时候,会自动释放已经存在的锁。在Mysql 5.7.5及之后的版本中可以同时获得多个锁。

在升级数据库之前那些使用了GET_LOCK() 只能同时持有一个锁,会自动释放已经存在锁功能的应用必须做出相应的修改。

  • 因为允许同时持有多个锁,这样就存在了死锁的可能,通过MDL subsystem发现死锁,当死锁发生时报出ER_USER_LOCK_DEADLOCK 错误。
  • 因为 MDL subsystem强制限制锁的名字不能超过64 characters,所以这个限制也同样适用于 named locks。当然在Mysql 5.7.5之前的版本中named locks是没有这个限制的
  • Locks acquired with GET_LOCK() now appear in the Performance Schema metadata_locks table. The OBJECT_TYPE column says USER LEVEL LOCK and the OBJECT_NAME column indicates the lock name.  >>
  • A new function, RELEASE_ALL_LOCKS() permits release of all acquired named locks at once.

 

  • The optimizer now handles derived tables and views in the FROM clause in consistent fashion to better avoid unnecessary materialization and to enable use of pushed-down conditions that produce more efficient execution plans. However, for statements such as DELETE or UPDATE that modify tables, using the merge strategy for a derived table that previously was materialized can result in an ER_UPDATE_TABLE_USED error:

 

mysql> DELETE FROM t1
    ->
WHERE id IN (SELECT id
    ->
             FROM (SELECT t1.id
    ->
                   FROM t1 INNER JOIN t2 USING (id)
    ->
                   WHERE t2.status = 0) AS t);
ERROR 1093 (HY000): You can't specify target table 't1'
for update in FROM clause

 

  • The error occurs when merging a derived table into the outer query block results in a statement that both selects from and modifies a table. (Materialization does not cause the problem because, in effect, it converts the derived table to a separate table.) To avoid this error, disable the derived_merge flag of theoptimizer_switch system variable before executing the statement:
    SET optimizer_switch = 'derived_merge=off';

    The derived_merge flag controls whether the optimizer attempts to merge subqueries and views in the FROM clause into the outer query block, assuming that no other rule prevents merging. By default, the flag is on to enable merging. Setting the flag to off prevents merging and avoids the error just described. For more information, see Section 9.2.1.18.3, “Optimizing Derived Tables and View References”.
  • Some keywords may be reserved in MySQL 5.7 that were not reserved in MySQL 5.6. See Section 10.3, “Keywords and Reserved Words”.
  • After upgrading, it is recommended that you test optimizer hints specified in application code to ensure that the hints are still required to achieve the desired optimization strategy. Optimizer enhancements can sometimes render certain optimizer hints unnecessary. In some cases, an unnecessary optimizer hint may even be counterproductive.

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/807718/viewspace-2151741/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-05-16

  • 博文量
    117
  • 访问量
    190326