在升级到 MySQL 5.6 之前,请查看本节中描述的更改以确定适用于您当前的 MySQL 安装和应用程序的更改。执行任何建议的操作。
标记为不兼容更改的更改与早期版本的 MySQL 不兼容,可能需要您在升级前注意。我们的目标是避免这些更改,但有时它们是纠正比版本之间不兼容更糟糕的问题所必需的。如果适用于您的安装的升级问题涉及不兼容性,请按照说明中给出的说明进行操作。有时这涉及转储和重新加载表,或使用诸如CHECK TABLE
or
之类的语句REPAIR TABLE
。
有关转储和重新加载的说明,请参阅
第 2.11.10 节,“重建或修复表或索引”。任何涉及
REPAIR TABLE
该
USE_FRM
选项的过程都必须在升级前完成。将此语句用于与用于创建表的版本不同的 MySQL 版本(即,在升级后使用它)可能会损坏表。请参阅
第 13.7.2.5 节,“REPAIR TABLE 语句”。
从 MySQL 5.6.6 开始,几个 MySQL 服务器参数的默认值与以前的版本不同。请参阅Configuration Changes下有关这些更改的说明 ,特别是关于覆盖它们以保持向后兼容性(如果有问题)。
从 MySQL 5.6.6 开始,几个 MySQL 服务器参数的默认值与以前的版本不同。这些更改的动机是提供更好的开箱即用性能并减少数据库管理员手动更改设置的需要。随着我们获得反馈,这些更改可能会在未来的版本中进行修订。
在某些情况下,参数具有不同的静态默认值。在其他情况下,服务器会在启动时使用基于其他相关参数或服务器主机配置的公式自动调整参数大小,而不是使用静态值。例如,
back_log
现在的设置是其先前的默认值 50,按与 值成比例的量向上调整max_connections
。autosizing 背后的想法是,当服务器有可用信息来决定参数设置可能优于固定默认值时,它会这样做。下表总结了对默认值的更改。通过在服务器启动时指定一个显式值,可以覆盖其中任何一个。
范围 旧默认 新默认 back_log
50 自动调整使用 max_connections
binlog_checksum
NONE
CRC32
--binlog-row-event-max-size
1024 8192 flush_time
1800(在 Windows 上) 0 innodb_autoextend_increment
8个 64 innodb_buffer_pool_instances
1个 8(取决于平台) innodb_checksum_algorithm
INNODB
CRC32 (changed back to
INNODB
in MySQL 5.6.7)innodb_concurrency_tickets
500 5000 innodb_file_per_table
0
1
innodb_old_blocks_time
0 1000 innodb_open_files
300 自动调整使用 innodb_file_per_table
,table_open_cache
innodb_stats_on_metadata
ON
OFF
join_buffer_size
128KB 256KB max_allowed_packet
1MB 4MB max_connect_errors
10 100 sync_master_info
0 10000 sync_relay_log
0 10000 sync_relay_log_info
0 10000 关于与以前版本的兼容性,最重要的变化是:
innodb_file_per_table
启用(以前禁用)。innodb_checksum_algorithm
是CRC32
(以前 在 MySQL 5.6.7 中INNODB
改回为 )。INNODB
binlog_checksum
是CRC32
(以前NONE
)。
因此,如果您正在升级现有的 MySQL 安装,尚未更改这些参数的先前默认值,并且考虑向后兼容性,您可能希望将这些参数显式设置为其先前的默认值。例如,将这些行放在服务器选项文件中:
[mysqld] innodb_file_per_table=0 innodb_checksum_algorithm=INNODB binlog_checksum=NONE
这些设置保持兼容性如下:
在
innodb_file_per_table
启用新默认值的情况下,ALTER TABLE
升级后的操作会将InnoDB
系统表空间中的表移动到单个.ibd
文件。使用innodb_file_per_table=0
可以防止这种情况发生。设置
innodb_checksum_algorithm=INNODB
允许升级到此版本后二进制降级。如果设置为CRC32
,InnoDB 将使用旧版 MySQL 无法使用的校验和。使用
binlog_checksum=NONE
,服务器可以用作复制源,而不会导致不理解二进制日志校验和的旧副本失败。
从 MySQL 5.6.5 开始,4.1 之前的密码和
mysql_old_password
身份验证插件已弃用。以 MySQL 4.1 之前使用的旧哈希格式存储的密码不如使用本机密码哈希方法的密码安全,应避免使用。为防止使用具有 4.1 之前密码哈希的帐户进行连接,secure_auth
现在默认启用系统变量。(要允许具有此类密码哈希的帐户连接,请使用 启动服务器--secure_auth=0
。)建议 DBA 将使用
mysql_old_password
身份验证插件的帐户转换为使用mysql_native_password
。有关帐户升级说明,请参阅 第 6.4.1.3 节,“从 4.1 版之前的密码哈希和 mysql_old_password 插件迁移”。在 MySQL 5.6(5.6.6 到 5.6.10)的一些早期开发版本中,服务器可以使用不匹配的密码哈希和身份验证插件创建帐户。例如,如果默认身份验证插件是
mysql_native_password
,则此语句序列会生成一个带有插件mysql_native_password
但 pre-4.1 密码哈希(由 所使用的格式mysql_old_password
)的帐户:SET old_passwords = 1; CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password';
不匹配会产生无法连接MySQL服务器、无法使用
SET PASSWORD
withOLD_PASSWORD()
或with 等症状old_passwords=1
。从 MySQL 5.6.11 开始,这种不匹配不再发生。相反,服务器会产生一个错误:
mysql> SET old_passwords = 1; mysql> CREATE USER 'jeffrey'@'localhost' IDENTIFIED BY 'password'; ERROR 1827 (HY000): The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.
要处理受不匹配影响的帐户,DBA 可以修改帐户系统表行中 的
plugin
或 列,使其与其他列保持一致:Password
mysql.user
设置为 0,然后使用和
old_passwords
为帐户分配一个新密码 。这会将 列设置为具有 4.1 密码哈希,与 插件一致。这是修复帐户的首选方法。SET PASSWORD
PASSWORD()
Password
mysql_native_password
或者,DBA 可以将插件更改
mysql_old_password
为使插件匹配密码哈希格式,然后刷新权限。不推荐这样做,因为mysql_old_password
插件和 pre-4.1 密码散列已被弃用;期望在未来版本的 MySQL 中删除对它们的支持。
Incompatible change:列
DEFAULT
值可能对于创建表时的值有效,插入或更新行时sql_mode
的值无效sql_mode
例子: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);
在这种情况下,应该接受 0
CREATE TABLE
而拒绝0INSERT
。但是,服务器没有DEFAULT
根据当前的sql_mode
. 在示例中,INSERT
成功并插入'0000-00-00'
到DATE
列中。从 MySQL 5.6.13 开始,服务器应用适当的
sql_mode
检查以在插入或更新时生成警告或错误。如果您使用基于语句的日志记录 (
binlog_format=STATEMENT
),则复制的不兼容性是,如果升级了副本,则尚未升级的源会无错误地执行前面的示例,而INSERT
副本上的失败和复制停止。为了解决这个问题,停止源上的所有新语句并等待副本赶上。然后升级副本,然后升级源。或者,如果您无法停止新语句,请暂时更改为源 (
binlog_format=ROW
) 上的基于行的日志记录,并等待所有副本处理到此更改点为止生成的所有二进制日志。然后升级副本,然后升级源,并将源更改回基于语句的日志记录。Incompatible change : MySQL 5.6.11 and later supports ,可用于创建 分区兼容MySQL 5.1服务器的表(=1)。(Bug #14521864,Bug #66462)尽管从 MySQL 5.5.31 开始的 MySQL 5.5 支持此语法,但 MySQL 5.6.10 及更早版本不接受此语法。MySQL 5.5.31 和更高版本的 MySQL 5.5 中的 mysqldump包括使用此选项转储表时的选项,但用条件注释包围它,如下所示:
CREATE TABLE ... [SUB]PARTITION BY ALGORITHM=
n
[LINEAR] KEY (...)KEY
n
ALGORITHM
CREATE TABLE t1 (a INT) /*!50100 PARTITION BY KEY */ /*!50531 ALGORITHM = 1 */ /*!50100 () PARTITIONS 3 */
将包含此类
CREATE TABLE
语句的转储导入 MySQL 5.6.10 或更早的 MySQL 5.6 服务器时,不会忽略版本注释,这会导致语法错误。因此,在导入这样的转储文件之前,您必须更改注释以便 MySQL 5.6 服务器忽略它们(通过删除字符串!50531
或将其替换为!50611
,无论它出现在哪里),或者删除它们。这不是使用 MySQL 5.6.11 或更高版本生成的转储文件的问题,其中
ALGORITHM
选项使用/*!50611 ... */
.Incompatible change:对于
TIME
、DATETIME
和TIMESTAMP
columns,MySQL 5.6.4 之前创建的表所需的存储与 5.6.4 及更高版本中创建的表所需的存储不同。这是由于 5.6.4 中的更改允许这些时间类型具有小数部分。此更改会影响依赖于行格式的语句的输出,例如CHECKSUM TABLE
. 从 MySQL 5.5 升级到 MySQL 5.6.4 或更高版本后,建议您也从 MySQL 5.5 升级到 MySQL 5.6TIME
、DATETIME
和TIMESTAMP
types。ALTER TABLE
目前允许创建包含 MySQL 5.5 和 MySQL 5.6.4(或更高版本)二进制格式的临时列的表,但这使得在.frm
文件不可用的情况下重新创建表变得更加困难。此外,从 MySQL 5.6.4 开始,上述时间类型的空间效率更高。有关 MySQL 5.6.4 中时间类型更改的更多信息,请参阅 日期和时间类型存储要求。从 MySQL 5.6.16 开始,
ALTER TABLE
将旧的临时列升级到 5.6 格式,用于ADD COLUMN
、CHANGE COLUMN
、MODIFY COLUMN
、ADD INDEX
和FORCE
操作。因此,以下语句升级包含旧格式列的表:ALTER TABLE tbl_name FORCE;
INPLACE
由于必须重建表,因此 无法使用该算法完成此转换 ,因此ALGORITHM=INPLACE
在这些情况下指定会导致错误。ALGORITHM=COPY
必要时 指定。当
ALTER TABLE
确实产生时间格式转换时,它会生成一条消息,该消息可以用SHOW WARNINGS
:显示TIME/TIMESTAMP/DATETIME columns of old format have been upgraded to the new format
。升级到 MySQL 5.6.4 或更高版本时,请注意
CHECK TABLE ... FOR UPGRADE
不会报告使用 MySQL 5.6.4 之前的格式的临时列(Bug #73008,Bug #18985579)。在 MySQL 5.6.24 中,添加了两个新的系统变量avoid_temporal_upgrade
和show_old_temporals
,以提供对时间列升级的控制(Bug #72997,Bug #18985760)。由于上面先前不兼容的更改项中描述的临时类型更改,将
ALTER TABLE ... IMPORT TABLESPACE
包含DATETIME
和TIMESTAMP
类型的 MySQL 5.6.4 之前的表(使用)导入 MySQL 5.6.4(或更高版本)失败。将具有这些临时类型的 MySQL 5.5 表导入 MySQL 5.6.4(或更高版本)是最有可能发生此问题的情况。以下过程描述了使用原始 MySQL 5.6.4 之前的
.frm
文件重新创建具有与 5.6.4(或更高版本)兼容的行结构的表的变通方法。这些过程涉及将原始 MySQL 5.6.4 之前的.frm
文件更改为使用Memory
存储引擎而不是InnoDB
,将文件复制.frm
到目标实例的数据目录,并使用ALTER TABLE
将表的存储引擎类型更改回InnoDB
。如果您的表没有外键,请使用第一个过程。如果您的表包含外键,请使用第二个过程,它有额外的步骤。如果表没有外键:
将表的原始
.frm
文件复制到要导入表空间的服务器上的数据目录。修改表的
.frm
文件以使用Memory
存储引擎而不是InnoDB
存储引擎。此修改需要更改.frm
文件中定义表的存储引擎类型的 7 个字节。使用十六进制编辑工具:将偏移位置0003处的字节,即
legacy_db_type
,由0c
(forInnoDB
)改为06
(forMemory
),如下图:00000000 fe 01 09 06 03 00 00 10 01 00 00 30 00 00 10 00
剩下的 6 个字节没有固定的偏移量。在
.frm
文件中 搜索“InnoDB
”以找到包含其他 6 个字节的行。该行如下所示:00001010 ff 00 00 00 00 00 00 06 00 49 6e 6e 6f 44 42 00 |.........InnoDB.|
修改字节,使该行显示如下:
00001010 ff 00 00 00 00 00 00 06 00 4d 45 4d 4f 52 59 00
运行
ALTER TABLE ... ENGINE=INNODB
以将表定义添加到InnoDB
数据字典。这将创建InnoDB
具有新格式的时态数据类型的表。要ALTER TABLE
成功完成操作,.frm
文件必须对应于表空间。
如果表有外键:
使用输出中的表定义重新创建具有外键的表
SHOW CREATE TABLE
。此时不正确的时间列格式无关紧要。INFORMATION_SCHEMA.TABLE_CONSTRAINTS
通过从和 中 选择外键信息,将所有外键定义转储到文本文件中INFORMATION_SCHEMA.KEY_COLUMN_USAGE
。删除所有表并完成上述过程中针对没有外键的表的步骤 1 至 4 中描述的表导入过程。
导入操作完成后,将您保存的外键定义中的外键添加到文本文件中。
不兼容的更改
latin1
:从 MySQL 5.6 开始,使用ifcharacter_set_server
isucs2
、utf16
、utf16le
或加载和搜索全文停用词文件utf32
。FULLTEXT
如果在服务器字符集为ucs2
、utf16
、utf16le
或使用索引创建了任何表utf32
使用以下语句修复它:REPAIR TABLE tbl_name QUICK;
不兼容的更改:在 MySQL 5.6.20 中,Bug #69477 的补丁将重做日志
BLOB
写入的大小限制为重做日志文件大小的 10%。由于此新限制,innodb_log_file_size
应设置为大于BLOB
表行中最大数据大小的 10 倍的值。如果您的innodb_log_file_size
设置已经是最大BLOB
数据大小的 10 倍或您的表不包含任何BLOB
数据,则无需执行任何操作。在 MySQL 5.6.22 中,重做日志
BLOB
写入限制放宽到重做日志总大小 (innodb_log_file_size
*innodb_log_files_in_group
) 的 10%。(漏洞#19498877)
从 MySQL 5.6.42 开始,与 MySQL 捆绑的zlib 库版本从 1.2.3 版本提升到 1.2.11 版本。
zlib 1.2.11 中的 zlibcompressBound()
函数返回比 zlib 版本 1.2.3 中压缩给定字节长度所需的缓冲区大小略高的估计值。该compressBound()
函数由确定创建压缩表或将行插入压缩表InnoDB
时允许的最大行大小
的函数调用。因此,
在早期版本中成功的行大小非常接近最大行大小的操作现在可能会失败
。
InnoDB
InnoDB
CREATE TABLE ...
ROW_FORMAT=COMPRESSED
INSERT
如果您有大行压缩InnoDB
表,建议您
CREATE TABLE
在升级前在 MySQL 5.6 测试实例上测试压缩表语句。
一些关键字可能在 MySQL 5.6 中保留,但在 MySQL 5.5 中没有保留。请参阅 第 9.3 节,“关键字和保留字”。这可能会导致以前用作标识符的词变得非法。要修复受影响的语句,请使用标识符引用。请参阅 第 9.2 节,“模式对象名称”。
在选择使用该
YEAR(2)
数据类型之前,您应该考虑某些问题。从 MySQL 5.6.6 开始,YEAR(2)
已弃用:YEAR(2)
现有表中的列与以前一样处理,但YEAR(2)
在新表或更改的表中将转换为YEAR(4)
. 有关详细信息,请参阅 第 11.2.5 节,“2 位 YEAR(2) 限制和迁移到 4 位 YEAR”。从 MySQL 5.6.6 开始,明确不允许将值分配
DEFAULT
给存储过程或函数参数或存储程序局部变量(例如使用 语句)。这以前不受支持,也未按允许记录,但被标记为不兼容的更改,以防现有代码无意中使用此构造。仍然允许像以前一样分配给系统变量,但 现在分配给参数或局部变量会导致语法错误。SET
var_name
= DEFAULTDEFAULT
DEFAULT
升级到 MySQL 5.6.6 或更高版本后,使用此构造的现有存储程序在调用时会产生语法错误。如果将 5.6.5 或更早版本的mysqldump文件加载到 5.6.6 或更高版本,加载操作将失败,并且必须更改受影响的存储程序定义。
在 MySQL 中,
TIMESTAMP
数据类型与其他数据类型的非标准方式不同:TIMESTAMP
未明确声明该NULL
属性的列将分配该NOT NULL
属性。(其他数据类型的列,如果未明确声明为NOT NULL
,则允许NULL
值。)设置此类列以NULL
将其设置为当前时间戳。表中的第一
TIMESTAMP
列,如果未使用NULL
属性或显式DEFAULT
orON UPDATE
子句声明,则自动分配DEFAULT CURRENT_TIMESTAMP
andON UPDATE CURRENT_TIMESTAMP
属性。TIMESTAMP
第一列之后的列,如果未使用NULL
属性或显式DEFAULT
子句声明,将自动分配DEFAULT '0000-00-00 00:00:00'
(“零”时间戳)。对于没有为此类列指定显式值的插入行,将分配该列'0000-00-00 00:00:00'
并且不会出现警告。
这些非标准行为仍然是默认行为,
TIMESTAMP
但从 MySQL 5.6.6 开始已弃用,并且此警告出现在启动时:[Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
如警告所示,要关闭非标准行为,请
explicit_defaults_for_timestamp
在服务器启动时启用新的系统变量。启用此变量后,服务器TIMESTAMP
将按如下方式处理:TIMESTAMP
未明确声明为NOT NULL
允许NULL
值的列。设置此类列以NULL
将其设置为NULL
,而不是当前时间戳。不会自动为任何
TIMESTAMP
列分配DEFAULT CURRENT_TIMESTAMP
或ON UPDATE CURRENT_TIMESTAMP
属性。必须明确指定这些属性。TIMESTAMP
声明为NOT NULL
和没有显式DEFAULT
子句的列被视为没有默认值。对于没有为此类列指定显式值的插入行,结果取决于 SQL 模式。如果启用严格 SQL 模式,则会发生错误。如果未启用严格 SQL 模式,则会为该列分配隐式默认值'0000-00-00 00:00:00'
并出现警告。这类似于 MySQL 处理其他时间类型的方式,例如DATETIME
.
要升级用于复制的服务器,请先升级副本,然后再升级源。源及其副本之间的复制应该可以工作,前提是它们都使用相同的值
explicit_defaults_for_timestamp
:关闭副本,升级它们,使用所需的值配置它们
explicit_defaults_for_timestamp
,然后将它们重新启动。副本从源接收到的二进制日志的格式中识别出源较旧(早于引入
explicit_defaults_for_timestamp
)并且对TIMESTAMP
来自源的列的操作使用旧TIMESTAMP
行为。关闭源,对其进行升级,
explicit_defaults_for_timestamp
使用在副本上使用的相同值对其进行配置,然后将其重新启动。