大版本升級(jí)最佳實(shí)踐
本文介紹PolarDB MySQL版的5.6、5.7版本和MySQL 5.6、5.7版本升級(jí)至PolarDB MySQL版的8.0版本的優(yōu)勢(shì)、預(yù)檢查以及兼容性說(shuō)明等內(nèi)容。
8.0版本介紹
版本發(fā)布日期
8.0.1版本發(fā)布于2019年12月3日。
8.0.2版本發(fā)布于2020年7月22日。
版本優(yōu)勢(shì)
8.0版本增強(qiáng)了架構(gòu)和內(nèi)核能力,為用戶處理業(yè)務(wù)提供了更靈活的技術(shù)解決方案,性能提升明顯。詳情請(qǐng)參見功能特性。
預(yù)檢查
PolarDB MySQL版的5.6、5.7版本和MySQL 5.6、5.7版本向的8.0版本升級(jí)過(guò)程中,經(jīng)常會(huì)遇到性能、語(yǔ)法兼容以及周邊組件是否支持的問(wèn)題。查詢的性能問(wèn)題一般是由于優(yōu)化器升級(jí)導(dǎo)致執(zhí)行計(jì)劃有變化,此類問(wèn)題需要對(duì)性能低下的語(yǔ)句進(jìn)行針對(duì)性的性能優(yōu)化,單獨(dú)的性能問(wèn)題基本不會(huì)引發(fā)業(yè)務(wù)報(bào)錯(cuò)以及代碼改寫的問(wèn)題,此類問(wèn)題不在本文討論范圍之內(nèi)。
本文主要討論兼容性問(wèn)題,此類問(wèn)題需要在數(shù)據(jù)庫(kù)升級(jí)過(guò)程中,更新相應(yīng)的代碼或更改環(huán)境配置,引發(fā)此類問(wèn)題的主要原因?yàn)榘姹旧?jí)后部分語(yǔ)法的變化以及特性的更新和移除。如果確保上述內(nèi)容不存在問(wèn)題,可以跳過(guò)下面章節(jié)進(jìn)行升級(jí),詳情請(qǐng)參見大版本一鍵升級(jí)。
預(yù)檢查功能會(huì)提供一個(gè)簡(jiǎn)要清單,幫助您在升級(jí)前更好的了解升級(jí)過(guò)程中可能需要注意的問(wèn)題。如果下述內(nèi)容存在對(duì)應(yīng)的問(wèn)題,請(qǐng)參考配置兼容性章節(jié)進(jìn)行操作和檢查。
確保沒有使用廢棄的數(shù)據(jù)類型、函數(shù)和功能,廢棄清單信息請(qǐng)參見Features Removed in MySQL 8.0。
確保觸發(fā)器(Triggers)沒有丟失、空的definer或無(wú)效的內(nèi)容。
確保只有InnoDB引擎的分區(qū)表。
確保關(guān)鍵字和保留關(guān)鍵字沒有沖突,詳情請(qǐng)參見Keywords and Reserved Words。
確保沒有和MySQL 5.6、5.7版本的系統(tǒng)數(shù)據(jù)庫(kù)、MySQL 8.0版本新增的
INNODB_
開頭的詞典表名沖突。確保不依賴于
INFORMATION_SCHEMA
下的GLOBAL
、LOCAL
、VARIABLES
、STATUS
表。確保
sql_mode
中沒有使用廢棄的變量設(shè)置,詳情請(qǐng)參見參數(shù)兼容。確保表和存儲(chǔ)過(guò)程單個(gè)
ENUM
或SET
列元素的長(zhǎng)度不超過(guò)255個(gè)字符或1020個(gè)字節(jié)。確保表的分區(qū)不在共享
InnoDB tablespaces
表空間中。確保查詢SQL語(yǔ)句中的GROUP BY子句不帶有ASC或DESC。
說(shuō)明8.0.2.2.11.1版本及以上的版本,在控制臺(tái)上將
loose_group_by_compatible_sorting
參數(shù)的值設(shè)置為TRUE后可以開啟兼容模式,兼容模式支持在SQL語(yǔ)句中使用帶有ASC或DESC的GROUP BY子句。在控制臺(tái)上設(shè)置參數(shù)值的操作步驟請(qǐng)參見設(shè)置集群參數(shù)和節(jié)點(diǎn)參數(shù)。確保外鍵約束名稱不超過(guò)64個(gè)字符。
為了增強(qiáng)Unicode的支持,推薦您將使用utf8mb3(已廢棄)或utf8(utf8mb3字符集的別名)字符集的對(duì)象更改為utf8mb4字符集。更多信息請(qǐng)參見The utf8mb3 Character Set (3-Byte UTF-8 Unicode Encoding)。
升級(jí)前需要進(jìn)行備份,以避免升級(jí)過(guò)程中可能遇到的其它問(wèn)題。
兼容性說(shuō)明
引擎和分區(qū)表兼容性
在 8.0版本中,創(chuàng)建MyISAM類型的分區(qū)將導(dǎo)致使用沒有此類型支持的存儲(chǔ)引擎的分區(qū)表創(chuàng)建語(yǔ)句失敗并出現(xiàn)錯(cuò)誤(ER_CHECK_NOT_IMPLEMENTED)
。有關(guān)將表從MyISAM轉(zhuǎn)換至InnoDB引擎,請(qǐng)參見將表從MyISAM轉(zhuǎn)換為InnoDB。
存儲(chǔ)引擎現(xiàn)支持分區(qū)處理程序,且服務(wù)器不再支持通用引擎分區(qū)。
InnoDB還提供僅 8.0版本支持的本機(jī)分區(qū)處理程序的存儲(chǔ)引擎。您需要在升級(jí)服務(wù)器前,將其它存儲(chǔ)引擎的分區(qū)表的存儲(chǔ)引擎轉(zhuǎn)換為InnoDB存儲(chǔ)引擎,或刪除對(duì)應(yīng)分區(qū)表,否則后續(xù)將無(wú)法使用。如有類似分區(qū),請(qǐng)您提前轉(zhuǎn)換引擎后再進(jìn)行升級(jí)。檢查引擎語(yǔ)法如下:
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE ENGINE NOT IN ('innodb','ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned';
或
SELECT DISTINCT NAME,SPACE,SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES
WHERE NAME LIKE '%#P#%' AND SPACE_TYPE NOT LIKE 'Single';
將引擎更改為InnoDB引擎語(yǔ)法如下:
ALTER TABLE part ENGINE = INNODB;
Query OK, 0 rows affected (0.09 sec)
刪除對(duì)應(yīng)分區(qū)表語(yǔ)法如下:
ALTER TABLE part REMOVE PARTITIONING;
Query OK, 0 raws affected (0.06 sec)
如果使用MySQLdump從MySQL 5.6、5.7版本服務(wù)器創(chuàng)建的轉(zhuǎn)儲(chǔ)文件中將數(shù)據(jù)導(dǎo)入至 8.0版本的服務(wù)器,需確保創(chuàng)建分區(qū)表的任何語(yǔ)句都沒有同時(shí)指定不被支持的存儲(chǔ)引擎,您可以通過(guò)刪除對(duì)分區(qū)的全部引用、將存儲(chǔ)引擎指定為InnoDB
或允許將參數(shù)default_storage_engine = InnoDB
設(shè)置為InnoDB的默認(rèn)值的方法實(shí)現(xiàn)該要求。識(shí)別在升級(jí)到MySQL 8.0版本之前必須更改的分區(qū)表的方法請(qǐng)參見為升級(jí)準(zhǔn)備安裝。有關(guān)分區(qū)限制詳細(xì)信息請(qǐng)參見與存儲(chǔ)有關(guān)的分區(qū)限制。
字符集和排序規(guī)則兼容性
MySQL 8.0版本的默認(rèn)字符集為utf8mb4。 MySQL 8.0版本和PolarDB MySQL版的character_set_server
值均默認(rèn)為utf8,您可以根據(jù)業(yè)務(wù)需求進(jìn)行調(diào)整。為支持Unicode,推薦您將使用的utf8mb3字符集轉(zhuǎn)換為使用utf8mb4字符集。詳細(xì)信息請(qǐng)參見utf8mb3字符集。
MySQL 8.0版本新增default_collation_for_utf8mb4參數(shù),該參數(shù)的作用為當(dāng)字符集為utf8mb4時(shí),根據(jù)默認(rèn)排序規(guī)則排序,該參數(shù)的默認(rèn)值為utf8mb3_0900_ai_ci,且該默認(rèn)值只是MySQL中replication使用的內(nèi)部參數(shù)。
若您在從低版本同步到高版本的過(guò)程中沒有遇到lllegal mix of collations
的錯(cuò)誤,不建議您將該默認(rèn)值修改為utf8mb4_general_ci或utf8mb4_0900_ai_ci
。
utf8mb4_0900_ai_ci:基于官方Unicode的規(guī)則做通用的排序和比較,準(zhǔn)確度高,但比對(duì)速度稍慢。
utf8mb4_general_ci:精簡(jiǎn)集合的排序規(guī)則,目的是提供簡(jiǎn)化的設(shè)計(jì)來(lái)加快比對(duì)速度,雖然沒有遵循Unicode的規(guī)則,但在相同情況下結(jié)果符合預(yù)期。
排序規(guī)則和字符集不同,它只和排序和有關(guān),其中ai表示口音不敏感,即排序時(shí)e,è,é,ê和?之間沒有區(qū)別;ci表示不區(qū)分大小寫,即排序時(shí)p和P之間沒有區(qū)別。
在8.0版本向低版本反向同步或dump同步時(shí),可能會(huì)存在兼容性問(wèn)題。
在DTS低版本與高版本雙向同步場(chǎng)景下容易出現(xiàn)異常,您需要使用MySQL 5.6、5.7和PolarDB MySQL版5.6、5.7版本默認(rèn)的排序字符集,否則DTS反向同步的時(shí)候會(huì)出現(xiàn)異常。
由于排序規(guī)則問(wèn)題,創(chuàng)建視圖時(shí)可能會(huì)報(bào)錯(cuò)
lllegal mix of collations
,例如當(dāng)您使用了convert(a.c1 using utf8mb4)=b.c1
時(shí),可能會(huì)報(bào)上述錯(cuò)誤。當(dāng)您使用convert(exp using utf8mb4)且不指定collation時(shí),MySQL會(huì)按照utf8mb4查詢,返回的
charset number
值為255。255對(duì)應(yīng)的collation即為MySQL 8.0版本默認(rèn)的utf8mb4_0900_ai_ci
。修改
default_collation_for_utf8mb4
或在DDL中指定列名、表名或數(shù)據(jù)庫(kù)名時(shí),collation都不會(huì)起作用。如果您需要使用convert
函數(shù),需要在語(yǔ)句中加入collation,如(convert(a.c1 using utf8mb4)collate utf8mb4_general_ci)=b.c1
。修改
default_collation_for_utf8mb4
參數(shù)的默認(rèn)值,如將默認(rèn)值修改為utf8mb4_general_ci
,會(huì)導(dǎo)致出現(xiàn)如下問(wèn)題:無(wú)法正確讀取SYS庫(kù)及其相關(guān)函數(shù),報(bào)錯(cuò)
lllegal mix of collations(utf8mb4_0900_ai_ci.IMPLICIT) and (utf8mb4_general_ci.IMPLICIT) for operation'='
。從8.0.1版本升級(jí)到8.0.2時(shí),升級(jí)失敗。該參數(shù)是8.0版本新增加的參數(shù),建議不要修改該參數(shù),如果必須使用其它值,請(qǐng)?jiān)趫?zhí)行升級(jí)操作前,前往配額中心,在配額名稱為default_collation_for_utf8mb4的操作列,單擊申請(qǐng),申請(qǐng)將參數(shù)的默認(rèn)值重置為
utf8mb4_0900_ai_ci
,升級(jí)完成后,需要將默認(rèn)值再修改為utf8mb4_general_ci
。
參數(shù)兼容性
lower_case_table_names
從MySQL 8.0.11版本開始,禁止lower_case_table_names
使用與服務(wù)器初始化時(shí)不同的設(shè)置來(lái)啟動(dòng)服務(wù)器。各種數(shù)據(jù)字典、表字段使用的排序規(guī)則基于lower_case_table_names
服務(wù)器初始化時(shí)定義的設(shè)置,使用不同的設(shè)置重新啟動(dòng)服務(wù)器時(shí),會(huì)導(dǎo)致標(biāo)識(shí)符的排序和比較方式引入不一致。在PolarDB MySQL版 8.0版本中,集群區(qū)分大小寫無(wú)法在初始化完成后再次更改,您需要在購(gòu)買 8.0版本的集群時(shí)選定集群是否區(qū)分大小寫。關(guān)于lower_case_table_names
參數(shù)詳情請(qǐng)參見lower_case_table_names。
sql_mode
為避免 8.0集群?jiǎn)?dòng)失敗,請(qǐng)通過(guò)NO_AUTO_CREATE_USER
從MySQL選項(xiàng)文件的系統(tǒng)變量sql_mode
設(shè)置中刪除所有集群。
您的系統(tǒng)變量設(shè)置中不得定義過(guò)時(shí)的SQL模式,否則sql_mode
會(huì)引起許多不同的行為,在版本升級(jí)時(shí)需要確認(rèn)對(duì)齊。需要取消的配置項(xiàng)如下:
DB2, MAXDB, MSSDL, MYSQL323, MYSQL40, ORACLE, POSTGRESQL, NO_FIELD_OPTIONS, NO_KEY_OPTI
以上配置項(xiàng)大多為組合配置,需要注意是否有不一致的mode選項(xiàng)。例如:
sql_mode=TRADITIONAL
等于配置如下項(xiàng):STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISIC
在MySQL5.6、5.7和 5.6、5.7版本默認(rèn)配置時(shí),
sql_mode=TRADITIONAL
等于配置如下項(xiàng):STRICT_TRANS_TABLES, STRICT_ALL_TABLES, NO_ZERO_IN_DATE, NO_ZERO_DATE, ERROR_FOR_DIVISIC_BY_ZERO, NO_AUTO_CREATE_USER, and NO_ENGINE_SUBSTITUTION
對(duì)比上述配置項(xiàng),可以看到5.6、5.7版本中多了NO_AUTO_CREATE_USER
選項(xiàng),在8.0版本已經(jīng)禁止GRANT
語(yǔ)句隱式創(chuàng)建賬號(hào),5.6、5.7版本雖然添加了NO_AUTO_CREATE_USER
選項(xiàng),但在指定identified by
時(shí),可以使用GRANT
創(chuàng)建賬號(hào)。
5.6版本恢復(fù)操作說(shuō)明
如果您發(fā)現(xiàn)啟用ONLY_FULL_GROUP_BY
導(dǎo)致現(xiàn)有應(yīng)?程序查詢被拒絕,可以使用以下方法恢復(fù)操作:
如果可以修改有問(wèn)題的查詢,請(qǐng)去除
select
投影列、HAVING
條件或ORDER BY
列表中的非聚集列,這些列既不在GROUP BY
中,也不與GROUP BY
列有任何函數(shù)關(guān)系。或者您可以使用ANY_VALUE()
函數(shù)。如果無(wú)法修改有問(wèn)題的查詢(例如它是由第三方應(yīng)用程序生成的),請(qǐng)將服務(wù)器啟動(dòng)時(shí)的系統(tǒng)變量
sql_mode
設(shè)置為not enable ONLY_FULL_GROUP_BY
。例如,當(dāng)描述不是
GROUP BY
的一部分,且沒有應(yīng)用聚合函數(shù)(例如MIN
或MAX
)時(shí),會(huì)出現(xiàn)如下情況:5.6版本:
SELECT id, invoice_id, description FROM invoice_line_items GROUP BY invoice_id; +----+------------+-------------+ | id | invoice_id | description | +----+------------+-------------+ | 1 | 1 | New socks | | 3 | 2 | Shoes | | 5 | 3 | Tie | +----+------------+-------------+ 3 rows in set (0.00 sec)
8.0版本:
SELECT id, invoice_id, description FROM invoice_line_items GROUP BY invoice_id; ERROR 1055 (42000): Expression #3 of SELECT list is not in GROUP BY clause and contains
5.6版本INFORMATION_SCHEMA系統(tǒng)和狀態(tài)變量信息的表
MySQL 5.6和PolarDB MySQL版 5.6版本INFORMATION_SCHEMA
中包含系統(tǒng)和狀態(tài)變量信息的表在 8.0版本中被廢棄,廢棄表如下:
INFORMATION_SCHEMA.GLOBAL_VARIABLES
INFORMATION_SCHEMA.SESSION_VARIABLES
INFORMATION_SCHEMA.GLOBAL_STATUS
INFORMATION_SCHEMA.SESSION_STATUS
8.0版本中將上述廢棄的表遷移至PERFORMANCE_SCHEMA
中。
performance_schema.global_variables
performance_schema.session_variables
performance_schema.variables_by_thread
performance_schema.global_status
performance_schema.session_status
performance_schema.status_by_thread
performance_schema.status_by_account
performance_schema.status_by_host
performance_schema.status_by_user
如果您直接使用該視圖,推薦使用SHOW
命令代替,而非直接使用相應(yīng)的視圖。
SHOW VARIABLES
SHOW STATUS
視圖/表/關(guān)鍵字兼容性
InnoDB相關(guān)視圖
INFORMATION_SCHEMA
中基于InnoDB系統(tǒng)表的視圖被數(shù)據(jù)字典表的內(nèi)部系統(tǒng)視圖所取代。影響InnoDB INFORMATION_SCHEMA
的視圖已重命名,在系統(tǒng)應(yīng)用中直接訪問(wèn)InnoDB相關(guān)視圖時(shí),需要確認(rèn)應(yīng)用中是否已經(jīng)修改。關(guān)于參數(shù)INFORMATION_SCHEMA
的詳細(xì)信息請(qǐng)參見NFORMATION_SCHEMA Tables。
重命名的InnoDB信息模式視圖
舊名稱 | 新名稱 |
INNODB_SYS_COLUMNS | INNODB_COLUMNS |
INNODB_SYS_DATAFILES | INNODB_DATAFILES |
INNODB_SYS_FIELDS | INNODB_FIELDS |
INNODB_SYS_FOREIGN | INNODB_FOREIGN |
INNODB_SYS_FOREIGN_COLS | INNODB_FOREIGN_COLS |
INNODB_SYS_INDEXES | INNODB_INDEXES |
INNODB_SYS_TABLES | INNODB_TABLES |
INNODB_SYS_TABLESPACES | INNODB_TABLESPACES |
INNODB_SYS_TABLESTATS | INNODB_TABLESTATS |
INNODB_SYS_VIRTUAL | INNODB_VIRTUAL |
在MySQL 5.6、5.7和PolarDB MySQL版 5.6、5.7版本中不能存在PolarDB MySQL版 8.0版本新增的同名視圖,在MySQL 5.7或PolarDB MySQL版 5.7版本的集群中執(zhí)行如下語(yǔ)句,如果有返回則需要確認(rèn)如何對(duì)此類表進(jìn)行處理,此項(xiàng)檢查建議您在自建集群上云升級(jí)時(shí)執(zhí)行。
'indexes',
'parameter_type_elements',
'parameters',
'resource_groups',
'routines',
'schemate',
'st_spatial_reference_systems',
'table_partition_systems',
'table_partition_values',
'table_partitions',
'table_states',
'tables',
'tablespace_files',
'tablespaces',
'triggers',
'view_routine_usage'
);
suppose
+--------------+--------------+
| TABLE_SCHEMA | TABLE_NAME |
+--------------+--------------+
| mysql | catalogs |
+--------------+--------------+
1 rows in set (0.00 sec)
在MySQL 5.6或 5.6版本的集群中執(zhí)?如下語(yǔ)句,如果有返回則需要確認(rèn)如何對(duì)此類表進(jìn)?處理,此項(xiàng)檢查建議您在?建集群上云升級(jí)時(shí)執(zhí)?。
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',
上述出現(xiàn)的此類用戶表應(yīng)在升級(jí)前重命名或刪除,重命此類用戶表語(yǔ)法如下:
ALTER TABLE catalogs RENAME user_catalogs;
Query OK, 0 rows affected (0.05 sec)
刪除此類用戶表語(yǔ)法如下:
DROP TABLE catalogs;
Query OK, 0 rows affected (0.06 sec)
視圖兼容
在MySQL 8.0版本之前的版本,您最多可以創(chuàng)建具有255個(gè)字符的顯示列名的視圖。為遵守列名的最大長(zhǎng)度,MySQL 8.0版本不支持顯示列名超過(guò)64個(gè)字符的視圖,目前這些視圖只能通過(guò)在MySQL 5.6、5.7版本中執(zhí)行SHOW CREATE VIEW
來(lái)識(shí)別。
SHOW CREATE VIEW v1;
+------+------------------------------------------------------------------------------------------------
| View | Create View
+------+------------------------------------------------------------------------------------------------
| v1 | CREATE ALGORITHM=UNDEFINED DEFINER='root'@'localhost' SQL SECURITY DEFINER VIEW
+------+------------------------------------------------------------------------------------------------
1 row in set (0.00 sec)
因此,您需要在升級(jí) 8.0版本前修改視圖名稱。
ALTER VIEW v1(a12345678901234567890) AS SECLECT 1;
5.6版本系統(tǒng)表兼容
mysql.user
系統(tǒng)表的Password
列,在MySQL 5.7.6后的版本及8.0版本中被刪除。所有憑據(jù)都存儲(chǔ)在authentication_string
列中,包括之前版本存儲(chǔ)在該Password
列中的數(shù)據(jù)。
5.6版本INNODB表兼容
DYNAMIC
替換COMPACT
為InnoDB表的隱式默認(rèn)?格式。配置選項(xiàng) innodb_default_row_format
指定默認(rèn)的InnoDB?格式,允許DYNAMIC
的值包括COMPACT
(默認(rèn)值)、 和REDUNDANT
。升級(jí)到 8.0后,除?您明確定義?格式(ROW_FORMAT)
,否則您創(chuàng)建的任何新表都需要使?定義的?格式 。對(duì)于未顯式定義ROW_FORMAT
選項(xiàng)或使?的現(xiàn)有表ROW_FORMAT=DEFAULT
,任何重建表的操作都會(huì)將表的?格式更改為定義的格式:innodb_default_row_format
。更多詳細(xì)信息請(qǐng)參見表的?格式。
5.6版本GET_LOCK函數(shù)兼容
GET_LOCK()
功能在MySQL 5.7.5及之后的版本中使?元數(shù)據(jù)鎖定(MDL)?系統(tǒng)重新實(shí)現(xiàn),并且其功能已得到擴(kuò)展:
以前版本中,
GET_LOCK()
?次只允許獲取?個(gè)命名鎖,第?次調(diào)用GET_LOCK()
時(shí)釋放所有現(xiàn)有鎖。8.0版本中GET_LOCK()
允許同時(shí)獲取多個(gè)命名鎖,并且不會(huì)釋放現(xiàn)有鎖。依賴于
GET_LOCK()
釋放所有先前鎖的?為的應(yīng)?程序必須針對(duì)新?為進(jìn)?修改。獲取多個(gè)鎖的能?可能會(huì)在客戶端之間引?死鎖。MDL?系統(tǒng)檢測(cè)死鎖且
ER_USER_LOCK_DEADLOCK
在發(fā)?這種情況時(shí)返回錯(cuò)誤。MDL?系統(tǒng)對(duì)鎖名稱添加了64個(gè)字符的限制,因此該限制也適?于命名鎖。之前版本沒有強(qiáng)制執(zhí)??度限制。
獲取的鎖
GET_LOCK()
現(xiàn)在出現(xiàn)在Performance Schema metadata_locks
中。OBJECT_TYPE
列表示USER LEVEL LOCK
,OBJECT_NAME
列表示鎖定名稱。8.0版本支持
RELEASE_ALL_LOCKS()
允許?次釋放所有獲得的命名鎖。
更多信息請(qǐng)參見鎖定功能。
類型兼容
枚舉和集合類型兼容
表或存儲(chǔ)過(guò)程的單個(gè)ENUM
或SET
列元素的長(zhǎng)度不得超過(guò)255個(gè)字符或1020個(gè)字節(jié)。
5.6版本YEAR類型
廢棄YEAR(2)
類型,需要?YEAR(4)
替換YEAR(2)
。
5.6版本類型數(shù)據(jù)插入兼容
將負(fù)值插??符號(hào)列時(shí)會(huì)報(bào)錯(cuò)。示例如下:
創(chuàng)建?個(gè)包含?符號(hào)列的表:
CREATE TABLE test (id int unsigned);
插??個(gè)負(fù)值。
INSERT INTO test VALUES (-1);
5.6版本中顯示結(jié)果如下:
Query OK, 1 row affected, 1 warning (0.01 sec)
8.0版本中顯示結(jié)果如下:
ERROR 1264 (22003): Out of range value for column 'a' at row 1
數(shù)據(jù)除以零會(huì)報(bào)錯(cuò)。示例如下:
創(chuàng)建測(cè)試表:
CREATE TABLE test2 (id int unsigned);
數(shù)據(jù)除以零。
INSERT INTO test2 VALUES (0/0);
5.6版本顯示結(jié)果如下:
Query OK, 1 row affected (0.01 sec)
8.0版本顯示結(jié)果如下:
ERROR 1365 (22012): Division by 0
字符超?插?報(bào)錯(cuò)。示例如下:
將20個(gè)字符的字符串插?10個(gè)字符的列會(huì)報(bào)錯(cuò)。創(chuàng)建?個(gè)包含10個(gè)字符的列的表:
CREATE TABLE test3 (a varchar(10));
插?更?的字符串。
INSERT INTO test3 VALUES ('abcdefghijklmnopqrstuvwxyz');
5.6版本顯示結(jié)果如下:
Query OK, 1 row affected, 1 warning (0.00 sec)
8.0版本顯示結(jié)果如下:
ERROR 1406 (22001): Data too long for column 'a' at row 1
?標(biāo)準(zhǔn)零?期插??期時(shí)間列會(huì)報(bào)錯(cuò)。示例如下:
創(chuàng)建?個(gè)包含?期時(shí)間列的表。
CREATE TABLE test3 (a datetime);
插?0000-00-00 00:00:00。
INSERT INTO test3 VALUES ('0000-00-00 00:00:00');
5.6版本顯示結(jié)果如下:
Query OK, 1 row affected, 1 warning (0.00 sec)
8.0版本顯示結(jié)果如下:
ERROR 1292 (22007): Incorrect datetime value: '0000-00-00 00:00:00' for column 'a' at ro
5.7版本JSON類型中INT類型數(shù)據(jù)變化
JSON中的部分INT類型被添加了.0變成類似1.0或者9999.0,初步確認(rèn)是 5.7和 8.0版本對(duì)JSON里面雙精度處理方式不同而導(dǎo)致,解決方案需要做DTS數(shù)據(jù)校驗(yàn),如有需求您可以在配置DTS界面配置數(shù)據(jù)校驗(yàn)。
5.x舊式類型兼容
舊式decimal、舊式varchar、舊式TIME/DATETIME和TIMESTAMP等數(shù)據(jù)類型分別在MySQL 5.0、MySQL 5.1和MySQL 5.6版本中已過(guò)時(shí),由于二進(jìn)制升級(jí)一直持續(xù)到MySQL 5.6、5.7版本,所以在MySQL 8.0版本中不被支持。這些表可以通過(guò)在升級(jí)前在MySQL 5.6、5.7版本中運(yùn)行CHECK TABLE...FOR UPGRADE
或使用帶有check-upgrade
選項(xiàng)的mysqlcheck
來(lái)識(shí)別。此外,使用舊式TIME/DATETIME和TIMESTAMP的表還可以通過(guò)啟用會(huì)話變量來(lái)識(shí)別,
check table 41_decimal for upgrade;
+-----------------+-------+----------+------------------------------------------------
| Table | Op | Msg_type | Msg_text
+-----------------+-------+----------+------------------------------------------------
| test.41_decimal | check | error | Table upgrade required for `test`.`41_decimal`.
+-----------------+-------+----------+-------------------------------------------------
1 row in set (0.00 sec)
check table 55_temporal for upgrade;
+------------------+-------+----------+------------------------------------------------
| Table | Op | Msg_type | Msg_text
+------------------+-------+----------+------------------------------------------------
| test.55_temporal | check | error | Table upgrade required. Please do "REPAIR TABLE
1 row in set (0.00 sec)
nisha@nisha-PORTEGE-Z30-A:~/workspace1/mysql-5.7/dbg-5.7/client/mysqlcheck --user=root
error : Table upgrade required for `test`.`41_decimal`. Please dump/reload table to
test.55_temporal
error : Table upgrade required. Please do "REPAIR TABLE `55_temporal`" or dump/reloa
test.child OK
test.geom OK
test.jemp OK
test.jemp_myisam OK
test.opening_lines OK
使用此類數(shù)據(jù)類型的表無(wú)法升級(jí),應(yīng)通過(guò)REPAIR TABLE
修復(fù),并為舊式varchar、舊式decimal轉(zhuǎn)儲(chǔ)和重新加載:
REPAIR TABLE 55_temporal;
+------------------+--------+----------+---------------------------------------------------
| Table | Op | Msg_type | Msg_text
+------------------+--------+----------+---------------------------------------------------
| test.55_temporal | repair | Note | TIME/TIMESTAMP/DATETIME columns of old format have
| test.55_temporal | repair | status | OK
+------------------+--------+----------+---------------------------------------------------
2 rows in set (0.01)
Dump:
$./client/mysqldump --databases test --socket=5.6/data/mysql.sock --user=root>test.sql
Restore:
.\ test.sql
關(guān)鍵詞與保留字
PolarDB MySQL版 8.0版本可以通過(guò) information_schema.KEYWORDS
表查看當(dāng)前版本的關(guān)鍵詞與保留字,不得有關(guān)鍵字或保留字違規(guī)的情況。PolarDB MySQL版 8.0版本中可能保留了部分以前未保留的關(guān)鍵字,詳情請(qǐng)參見關(guān)鍵字和保留字。建議所有自定義內(nèi)容(表名、字段名、函數(shù)名)等全部規(guī)避使用。除此之外,KICKOUT
是 PolarDB MySQL版 8.0的保留關(guān)鍵字。因此,若您已經(jīng)在MySQL 5.6、5.7或原生MySQL 8.0版本上使用該關(guān)鍵字作為對(duì)象名稱(如表名、字段名、存儲(chǔ)過(guò)程名等),在遷移到PolarDB MySQL版 8.0版本前,請(qǐng)您先修改對(duì)象名稱避免使用該關(guān)鍵字,否則遷移時(shí),將會(huì)出現(xiàn)錯(cuò)誤碼為1064的語(yǔ)法報(bào)錯(cuò)。
SQL兼容性
GRANT授權(quán)
在MySQL 8.0.11中,刪除了部分與賬戶管理相關(guān)、已棄用的功能,例如使用GRANT語(yǔ)句修改用戶賬戶的非特權(quán)特性。
GRANT REPLICATION CLIENT ON *.* TO 'odps'@'%'; You are not allowed to create a user with
create user;
grant privielges;
不支持GROUP BY ASC/DESC
自MySQL 8.0.13開始,已刪除不推薦使用的子句ASC和DESC限定符GROUP BY,之前依賴GROUP BY排序的查詢可能會(huì)產(chǎn)生與之前MySQL版本不同的結(jié)果。要生成給定的排序順序,您需要提供一個(gè)GROUP BY子句。示例如下:
將SQL語(yǔ)句
select id,count(*) from sbtest.sbtest1 where id < 10 group by id desc
改寫為:
select id,count(*) from sbtest.sbtest1 where id < 10 group by id order by id
PolarDB MySQL版 8.0.2.2.11.1版本及以上的版本,不需要執(zhí)行以上改寫操作。您只需要在控制臺(tái)上將loose_group_by_compatible_sorting
參數(shù)的值設(shè)置為TRUE,即可直接在SQL語(yǔ)句中使用帶有ASC或DESC的GROUP BY子句。在控制臺(tái)上設(shè)置參數(shù)值的操作步驟請(qǐng)參見設(shè)置集群參數(shù)和節(jié)點(diǎn)參數(shù)。
外鍵約束定義
在MySQL 5.6、5.7版本中,定義FOREIGN KEY
的InnoDB不得帶有CONSTRAINT
的關(guān)鍵字且指定外鍵約束名稱不得超過(guò)64個(gè)字符。在MySQL 8.0之前的版本中,當(dāng)您未明確指定外鍵約束名稱時(shí),InnoDB會(huì)通過(guò)在表名后附加_ibfk_X
來(lái)自動(dòng)生成外鍵約束名稱,其中X
是一個(gè)數(shù)字。如果表名是多字節(jié)64字符,如下面示例中使用的?里爾表名 имя_базы_в_кодировке_утф8_длиной_больше_чем_45имя_азы_в_кодировк
,則自動(dòng)生成的外鍵約束名稱將超過(guò)64個(gè)字符。應(yīng)通過(guò)刪除約束并確保外鍵約束名稱不超過(guò)64個(gè)字符來(lái)添加具有顯式約束名稱的約束來(lái)更改這些表。
ALTER TABLE `имя_базы_в_кодировке_утф8_длиной_больше_чем_45имя_азы_в_кодировк` DR
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE `имя_базы_в_кодировке_утф8_длиной_больше_чем_45имя_азы_в_кодировк` AD
Query OK, 0 rows affected (0.13 sec)
Records: 0 Duplicates: 0 Warnings: 0
5.7版本空間函數(shù)
在MySQL 5.7中,不推薦使?多個(gè)名稱下可?的部分空間函數(shù)。示例如下:
CREATE TABLE t_gcol_dep (fid INTEGER NOT NULL PRIMARY KEY, g POINT GENERATED ALWA
Query OK, 0 rows affected, 1 warning (0.07 sec)
show warnings;
+---------+------+---------------------------------------------------------------------
| Level | Code | Message
+---------+------+---------------------------------------------------------------------
| Warning | 1287 | 'POINTFROMTEXT' is deprecated and will be removed in a future releas
+---------+------+---------------------------------------------------------------------
1 row in set (0.00 sec)
由于空間函數(shù)名稱更改,這些空間函數(shù)在 8.0版本中已被刪除。此更改有助于命名約定保持?致,即函數(shù)以ST_
開頭(精確執(zhí)?操作情況下)或者以MBR
開頭(執(zhí)?基于最?邊界矩形的操作情況下),使?此類函數(shù)?成的列應(yīng)在升級(jí)前更改。已刪除空間函數(shù)的列表請(qǐng)參見Features Removed in MySQL 8.0。 您需要更改?成的列以使?相應(yīng)的ST_
或MBR
函數(shù)。
ALTER TABLE t_gcol_dep MODIFY g POINT GENERATED ALWAYS AS (ST_POINTFROMTEXT(POINT
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
觸發(fā)器兼容
MySQL 5.0.17之前的CREATE TRIGGER
不?持definer屬性。此類具有缺失/空定義器屬性或?效創(chuàng)建上下?(即character_set_client
、collation_collection
、數(shù)據(jù)庫(kù)排序規(guī)則屬性)的觸發(fā)器定義?直存在導(dǎo)致MySQL 5.6、5.7版本時(shí)?法升級(jí)。這些觸發(fā)器可以通過(guò)在MySQL 5.6、5.7版本中運(yùn)?帶有檢查升級(jí)選項(xiàng)的mysqlcheck或CHECK TABLE
來(lái)識(shí)別。
$./client/mysqlcheck --user=root --socket=5.7/data/mysql.sock --databases triggers --ch
triggers.t1
Warning : No definer attribute for trigger 'triggers'.'trg_t1_before_insert'. The trig
Warning : No definer attribute for trigger 'triggers'.'t1_bi'. The trigger will be act
Warning : No definer attribute for trigger 'triggers'.'trg_t1_after_insert_1'. The tri
Warning : No definer attribute for trigger 'triggers'.'trg_t1_after_insert'. The trigg
Warning : No definer attribute for trigger 'triggers'.'trg_t1_after_insert_3'. The tri
Warning : No definer attribute for trigger 'triggers'.'trg_t1_before_update_3'. The tr
Warning : No definer attribute for trigger 'triggers'.'trg_t1_before_update'. The trig
Warning : No definer attribute for trigger 'triggers'.'trg_t1_after_update'. The trigg
Warning : No definer attribute for trigger 'triggers'.'trg1'. The trigger will be acti
status : OK
triggers.t2 OK
check table t1;
+-------------+-------+----------+-----------------------------------------------------
| Table | Op | Msg_type | Msg_text
+-------------+-------+----------+-----------------------------------------------------
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'trg_t1_
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'t1_bi'.
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'trg_t1_
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'trg_t1_
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'trg_t1_
| triggers.t1 | check | Warning | No definer attribute for trigger 'triggers'.'trg_t1_
您需要轉(zhuǎn)儲(chǔ)或重新加載此類觸發(fā)器解決此類問(wèn)題:
Dump:
$./client/mysqldump --databases triggers --socket=5.6/data/mysql.sock --user=root>trigge
Restore:
.\ triggers.sql
客戶端兼容性
對(duì)于Java應(yīng)?來(lái)說(shuō),MySQL Connector/J升級(jí)到8.0以上版本,連接賬戶需要連接器/J 8.0.9或更?版本的 caching_sha2_password
。如果未在數(shù)據(jù)源中將dataworks
設(shè)置為utf8,可能會(huì)出錯(cuò),建議修改數(shù)據(jù)庫(kù)名。在的連接串中增加:characterEncoding=utf8&com.mysql.jdbc.faultInjection.serverCharsetIndex=
使Java客戶端在連接中顯性指定session級(jí)別字符集。
Unknown system variable 'tx_read_only'兼容性
MySQL和 8.0版本中已經(jīng)刪除tx_read_only
環(huán)境變更,需要使?transaction_read_only
代替。
即需要將:
select @@tx_read_only
改寫為:
select @@transaction_read_only
常見問(wèn)題
并行查詢導(dǎo)致的排序問(wèn)題
8.0版本開始?持并?查詢能?,并?掃描由于隨機(jī)訪問(wèn)數(shù)據(jù)會(huì)導(dǎo)致MySQL默認(rèn)串?掃描的順序每次隨機(jī)變化,尤其是涉及到分?的SQL。如果您需要?成給定的排序順序,請(qǐng)?zhí)峁?個(gè)ORDER BY
?句保證順序。
5.6版本子查詢問(wèn)題
5.6版本子查詢中的order by
不再起作用,例如:
SELECT *
FROM
(
SELECT * FROM `information_schema`. TABLES
ORDER BY table_name DESC
) AS sg
GROUP BY table_name
內(nèi)層的order by
會(huì)被5.7、8.0版本的優(yōu)化器忽略,您需要通過(guò)修改語(yǔ)句解決這個(gè)問(wèn)題,最簡(jiǎn)單的方法是添加limit
使排序生效,例如:
SELECT *
FROM
(
SELECT * FROM `information_schema`. TABLES
ORDER BY table_name DESC limit 10000 # 需要?夠?的?數(shù)
) AS sg
GROUP BY table_name
5.6版本派?表問(wèn)題
優(yōu)化器現(xiàn)在以?致的?式處理?句中的派?表和視圖,使用FROM
以更好地避免不必要的物化,并允許使?、產(chǎn)?更有效的執(zhí)?計(jì)劃的下推條件。但在 8.0版本以及修改表之類的語(yǔ)句中, DELETE
對(duì)UPDATE
之前實(shí)現(xiàn)的派?表使?合并策略可能會(huì)導(dǎo)致ER_UPDATE_TABLE_USED
錯(cuò)誤:
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
將派?表合并到外部查詢塊中會(huì)導(dǎo)致從表中選擇和修改表語(yǔ)句時(shí)發(fā)?錯(cuò)誤。(物化不會(huì)導(dǎo)致問(wèn)題,因?yàn)樗鼘?shí)際上將派?表轉(zhuǎn)換為了單獨(dú)的表。)為避免此類錯(cuò)誤的解決?法是在執(zhí)?語(yǔ)句前禁?使用系統(tǒng)變量的derived_merge
標(biāo)志optimizer_switch
:
SET optimizer_switch = 'derived_merge=off';
該derived_merge
標(biāo)志控制優(yōu)化器是否嘗試將FROM
?句中的?查詢和視圖合并到外部查詢塊中。假設(shè)沒有其他規(guī)則阻?合并,默認(rèn)情況下,該標(biāo)志是on啟?合并。設(shè)置標(biāo)志off阻止合并,可以避免上述描述的錯(cuò)誤。更多信息請(qǐng)參見使用合并或?qū)崿F(xiàn)優(yōu)化派生表和查看引用。
在UNION
語(yǔ)句中,要將ORDER BY
或LIMIT
應(yīng)?于單獨(dú)查詢塊SELECT
,請(qǐng)將SELECT
?句放在括號(hào)內(nèi) :
(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
在 8.0版本中,要求必須使?括號(hào),MySQL之前的版本可能允許這樣的語(yǔ)句不帶括號(hào)。
相關(guān)文檔
MySQL官方5.6、5.7、8.0版本差異比較: