Mysql Note
Mysql Note
0 Release Notes
Abstract
This document contains release notes for the changes in each release of MySQL 8.0, up through MySQL 8.0.36.
For information about changes in a different MySQL series, see the release notes for that series.
For additional MySQL 8.0 documentation, see the MySQL 8.0 Reference Manual, which includes an overview
of features added in MySQL 8.0 (What Is New in MySQL 8.0), and discussion of upgrade issues that you may
encounter for upgrades from MySQL 5.7 to MySQL 8.0 (Changes in MySQL 8.0).
Downgrade from MySQL 8.0 to MySQL 5.7, or from a MySQL 8.0 release to a previous MySQL 8.0 release, is not
supported. The only supported alternative is to restore a backup taken before upgrading. It is therefore imperative
that you back up your data before starting the upgrade process.
Updates to these notes occur as new product features are added, so that everybody can follow the development
process. If a recent version is listed here that you cannot find on the download page (https://dev.mysql.com/
downloads/), the version has not yet been released.
The documentation included in source and binary distributions may not be fully up to date with respect to release
note entries because integration of the documentation occurs at release build time. For the most up-to-date
release notes, please refer to the online documentation instead.
For help with using MySQL, please visit the MySQL Forums, where you can discuss your issues with other
MySQL users.
Table of Contents
Preface and Legal Notices ............................................................................................................ 2
Changes in MySQL 8.0.35 (Not yet released, General Availability) .................................................. 3
Changes in MySQL 8.0.34 (2023-07-18, General Availability) ......................................................... 3
Changes in MySQL 8.0.33 (2023-04-18, General Availability) ....................................................... 14
Changes in MySQL 8.0.32 (2023-01-17, General Availability) ....................................................... 22
Changes in MySQL 8.0.31 (2022-10-11, General Availability) ....................................................... 34
Changes in MySQL 8.0.30 (2022-07-26, General Availability) ....................................................... 48
Changes in MySQL 8.0.29 (2022-04-26, General Availability) ....................................................... 63
Changes in MySQL 8.0.28 (2022-01-18, General Availability) ....................................................... 79
Changes in MySQL 8.0.27 (2021-10-19, General Availability) ....................................................... 97
Changes in MySQL 8.0.26 (2021-07-20, General Availability) ...................................................... 117
Changes in MySQL 8.0.25 (2021-05-11, General Availability) ...................................................... 139
Changes in MySQL 8.0.24 (2021-04-20, General Availability) ...................................................... 140
Changes in MySQL 8.0.23 (2021-01-18, General Availability) ...................................................... 155
Changes in MySQL 8.0.22 (2020-10-19, General Availability) ...................................................... 171
Changes in MySQL 8.0.21 (2020-07-13, General Availability) ...................................................... 189
Changes in MySQL 8.0.20 (2020-04-27, General Availability) ...................................................... 210
Changes in MySQL 8.0.19 (2020-01-13, General Availability) ...................................................... 229
Changes in MySQL 8.0.18 (2019-10-14, General Availability) ...................................................... 252
Changes in MySQL 8.0.17 (2019-07-22, General Availability) ...................................................... 271
1
MySQL 8.0 Release Notes
Legal Notices
Copyright © 1997, 2023, Oracle and/or its affiliates.
License Restrictions
This software and related documentation are provided under a license agreement containing
restrictions on use and disclosure and are protected by intellectual property laws. Except as expressly
permitted in your license agreement or allowed by law, you may not use, copy, reproduce, translate,
broadcast, modify, license, transmit, distribute, exhibit, perform, publish, or display any part, in any
form, or by any means. Reverse engineering, disassembly, or decompilation of this software, unless
required by law for interoperability, is prohibited.
Warranty Disclaimer
The information contained herein is subject to change without notice and is not warranted to be error-
free. If you find any errors, please report them to us in writing.
If this is software, software documentation, data (as defined in the Federal Acquisition Regulation), or
related documentation that is delivered to the U.S. Government or anyone licensing it on behalf of the
U.S. Government, then the following notice is applicable:
U.S. GOVERNMENT END USERS: Oracle programs (including any operating system, integrated
software, any programs embedded, installed, or activated on delivered hardware, and modifications
of such programs) and Oracle computer documentation or other Oracle data delivered to or accessed
by U.S. Government end users are "commercial computer software," "commercial computer software
documentation," or "limited rights data" pursuant to the applicable Federal Acquisition Regulation and
agency-specific supplemental regulations. As such, the use, reproduction, duplication, release, display,
disclosure, modification, preparation of derivative works, and/or adaptation of i) Oracle programs
(including any operating system, integrated software, any programs embedded, installed, or activated
on delivered hardware, and modifications of such programs), ii) Oracle computer documentation and/
or iii) other Oracle data, is subject to the rights and limitations specified in the license contained in
the applicable contract. The terms governing the U.S. Government's use of Oracle cloud services
are defined by the applicable contract for such services. No other rights are granted to the U.S.
Government.
This software or hardware is developed for general use in a variety of information management
applications. It is not developed or intended for use in any inherently dangerous applications, including
2
MySQL 8.0 Release Notes
applications that may create a risk of personal injury. If you use this software or hardware in dangerous
applications, then you shall be responsible to take all appropriate fail-safe, backup, redundancy, and
other measures to ensure its safe use. Oracle Corporation and its affiliates disclaim any liability for any
damages caused by use of this software or hardware in dangerous applications.
Trademark Notice
Oracle, Java, MySQL, and NetSuite are registered trademarks of Oracle and/or its affiliates. Other
names may be trademarks of their respective owners.
Intel and Intel Inside are trademarks or registered trademarks of Intel Corporation. All SPARC
trademarks are used under license and are trademarks or registered trademarks of SPARC
International, Inc. AMD, Epyc, and the AMD logo are trademarks or registered trademarks of Advanced
Micro Devices. UNIX is a registered trademark of The Open Group.
This software or hardware and documentation may provide access to or information about content,
products, and services from third parties. Oracle Corporation and its affiliates are not responsible
for and expressly disclaim all warranties of any kind with respect to third-party content, products,
and services unless otherwise set forth in an applicable agreement between you and Oracle. Oracle
Corporation and its affiliates will not be responsible for any loss, costs, or damages incurred due to
your access to or use of third-party content, products, or services, except as set forth in an applicable
agreement between you and Oracle.
This documentation is NOT distributed under a GPL license. Use of this documentation is subject to the
following terms:
You may create a printed copy of this documentation solely for your own personal use. Conversion
to other formats is allowed as long as the actual content is not altered or edited in any way. You shall
not publish or distribute this documentation in any form or on any media, except if you distribute the
documentation in a manner similar to how Oracle disseminates it (that is, electronically for download
on a Web site with the software) or on a CD-ROM or similar medium, provided however that the
documentation is disseminated together with the software on the same medium. Any other use, such
as any dissemination of printed copies or use of this documentation, in whole or in part, in another
publication, requires the prior written consent from an authorized representative of Oracle. Oracle and/
or its affiliates reserve any and all rights to this documentation not expressly granted above.
Documentation Accessibility
For information about Oracle's commitment to accessibility, visit the Oracle Accessibility Program
website at
http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc.
3
MySQL 8.0 Release Notes
• Binary Logging
• C API Notes
• Compilation Notes
• Bugs Fixed
This new capability is one several that provide DBAs more complete control over password
management. For more information, see Password Management. (WL #15751)
For additional information about using audit_log plugin installation scripts, see Installing or
Uninstalling MySQL Enterprise Audit. (Bug #35252268)
• MySQL Enterprise Audit now supports using the scheduler component to configure and execute a
recurring task to flush the in-memory cache. For setup instructions, see Enabling the Audit Log Flush
Task. (WL #15567)
Binary Logging
• Several functions now are added to the libmysqlclient.so shared library that enable developers
to access a MySQL server binary log: mysql_binlog_open(), mysql_binlog_fetch(), and
mysql_binlog_close().
Our thanks to Yura Sorokin for the contribution. (Bug #110658, Bug #35282154)
C API Notes
• In the calling function, len is initialized to 0 and never changed if net->vio is null. This fix adds a
check of net before dereferencing vio.
4
MySQL 8.0 Release Notes
• A variable in the async client was uninitialized in certain code paths. It is fixed by always initializing
the variable.
Compilation Notes
• Microsoft Windows: For Windows, improved MSVC_CPPCHECK support; and check for MSVC
warnings similar to "maintainer" mode. For example, check after all third party configurations are
complete. (Bug #35283401)
• Updated the bundled ICU files from version 69.1 to version 73 for the icu-data-files package.
(Bug #35353708)
• ZSTD sources bundled in the source tree were upgraded to ZSTD 1.5.5 from 1.5.0. (Bug
#35353698)
• Initialize the internal MEM_ROOT class memory with garbage using the TRASH macro to make
easier to reproduce bugs caused by reading initialized memory allocated from MEM_ROOT. (Bug
#35277644)
• We now determine stack direction at runtime rather than at configure time. (Bug #35181008)
• Changed the minimum Bison version requirement from v2.1 to v3.0.4. For macOS, this may require
installing Bison via a package manager such as Homebrew. (Bug #35154645, Bug #35191333)
• MySQL now sets LANG=C in the environment when executing readelf to avoid problems with non-
ASCII output.
Our thanks to Kento Takeuchi for the contribution. (Bug #111190, Bug #35442825)
• On macOS, MySQL would not compile if rapidjson was installed via Homebrew. The workaround
was to brew unlink rapidjson. (Bug #110736, Bug #35311140)
• MySQL would not build with -DWITH_ZLIB=system; it'd complain about not finding the system zlib
library despite finding it. (Bug #110727, Bug #110745, Bug #35307674, Bug #35312227)
5
MySQL 8.0 Release Notes
removal in a future version of MySQL, and move applications depending on it to another solution,
such as those mentioned previously. (WL #15652)
• Replication: The sync_relay_log_info server system variable is deprecated in this release, and
getting or setting this variable or its equivalent startup option --sync-relay-log-info now raises
a warning.
Expect this variable to be removed in a future version of MySQL; applications which make use of it
should be rewritten not to depend on it before this happens. (Bug #35367005, WL #13968)
• Replication: The binlog_format server system variable is now deprecated, and subject to
removal in a future version of MySQL. The functionality associated with this variable, that of
changing the binary logging format, is also deprecated.
The implication of this change is that, when binlog_format is removed, only row-based binary
logging, already the default in MySQL 8.0, will be supported by the MySQL server. For this reason,
new installations should use only row-based binary logging, and existing ones using the statement-
based or mixed logging format should be migrated to the row-based format. See Replication
Formats, for more information.
Setting or selecting the values of any of the variables just mentioned now raises a warning. (WL
#13966, WL #15669)
• Previously, if the audit_log plugin was installed without the accompanying audit tables and
functions needed for rule-based filtering, the plugin operated in legacy filtering mode. Now, legacy
filtering mode is deprecated. New deprecation warnings are emitted for legacy audit log filtering
system variables. These deprecated variables are either read-only or dynamic.
(Read-only) audit_log_policy now writes a warning message to the MySQL server error log
during server startup when the value is not ALL (default value).
• Changing an existing value using SET syntax during a MySQL client session now writes a warning
message to the client log.
• Persisting a variable using SET PERSIST syntax during a MySQL client session now writes a
warning message to the client log.
6
MySQL 8.0 Release Notes
(WL #11248)
• MySQL enables control of FIPS mode on the server side and the client side using a system variable
and client option. Application programs can use the MYSQL_OPT_SSL_FIPS_MODE option to
mysql_options() to enable FIPS mode on the client. Alternatively, it is possible to handle FIPS
mode directly through OpenSSL configuration files rather than using the current server-side system
variable and client-side options. When MySQL is compiled using OpenSSL 3.0, and an OpenSSL
library and FIPS Object Module are available at runtime, the server reads the OpenSSL configuration
file and respects the preference to use a FIPS provider, if one is set. OpenSSL 3.0 is certified for use
with FIPS.
To favor the OpenSSL alternative, the ssl_fips_mode server system variable, --ssl-fips-
mode client option, and the MYSQL_OPT_SSL_FIPS_MODE option now are deprecated and subject
to removal in a future version of MySQL. A deprecation warning prints to standard error output when
an application uses the MYSQL_OPT_SSL_FIPS_MODE option or when a client user specifies the --
ssl-fips-mode option on the command line, through option files, or both.
Prior to being deprecated, the ssl_fips_mode server-side system variable was dynamically
settable. It is now a read-only variable (accepts SET PERSIST_ONLY, but not SET PERSIST or SET
GLOBAL). When specified on the command line or in the mysqld-auto.cnf option file (with SET
PERSIST_ONLY) a deprecation warning prints to the server error log. (WL #15631)
• Previously, the MySQL server processed a version-specific comment without regard as to whether
any whitespace followed the MySQL version number contained within it. For example, the comments
/*!80034KEY_BLOCK_SIZE=1024*/ and /*!80034 KEY_BLOCK_SIZE=1024*/ were handled
identically. Beginning with this release, when the next character following the version number in
such a comment is neither a whitespace character nor the end of the comment, the server issues a
warning: Immediately starting the version comment after the version number
is deprecated and may change behavior in a future release. Please insert a
whitespace character after the version number.
You should expect the whitespace requirement for version-specific comments to become strictly
enforced in a future version of MySQL.
• The MySQL client library currently supports performing an automatic reconnection to the server if it
finds that the connection is down and an application attempts to send a statement to the server to be
executed. Now, this feature is deprecated and subject to removal in a future release of MySQL.
The related MYSQL_OPT_RECONNECT option is still available but it is also deprecated. C API
functions mysql_get_option() and mysql_options() now write a deprecation warning to the
standard error output when an application specifies MYSQL_OPT_RECONNECT. (WL #15766)
7
MySQL 8.0 Release Notes
The functions SESSION_USER(), USER(), and SYSTEM_USER() are also supported in all of the
cases just mentioned. By way of example, the following sequence of statements now works similarly
to what is shown here, with the precise output dependent on your environment:
mysql> TABLE t;
+-------------------+-------------------+-------------------+-------------------+
| c1 | c2 | c3 | c4 |
+-------------------+-------------------+-------------------+-------------------+
| sakila@localhost | sakila@localhost | sakila@localhost | sakila@localhost |
+-------------------+-------------------+-------------------+-------------------+
1 row in set (0.00 sec)
When used in this way, these functions are also included in the output of SHOW CREATE TABLE
and SHOW COLUMNS, and referenced in the COLUMN_DEFAULT column of the Information Schema
COLUMNS table where applicable.
If you need to insure that values having the maximum possible length can be stored in such a
column, you should make sure that the column can accommodate at least 288 characters (255 for
the user name and 32 for the host name, plus 1 for the separator @). For this reason—while it is
possible to use one of these functions as the default for a CHAR column, it is not recommended due
to the risk of errors or truncation of values. (Bug #17809, Bug #11745618)
• Packaging: Beginning with this release, binary archive packages previously named using -
el7-x86_64.tar and -el7-x86_64.tar.gz are now named using -linux-glibc2.17-
x86_64.tar and -linux-glibc2.17-x86_64.tar.gz, respectively. For example, if you
used mysql-8.0.33-el7-x86_64.tar to install or upgrade to MySQL 8.0.33, you should use
mysql-8.0.34-linux-glibc2.17-x86_64.tar for installing or upgrading to MySQL 8.0.34.
The naming change reflects the fact that these binaries are intended to be compatible with any Linux
system using glibc2.17 or newer; this includes Enterprise Linux 7, EL8, and EL9.
• Binary packages that include curl rather than linking to the system curl library have been upgraded to
use curl 8.1.2. (Bug #35329529)
8
MySQL 8.0 Release Notes
Bugs Fixed
• Important Change: The default value of the connection_memory_chunk_size server system
variable, when introduced in MySQL 8.0.28, was mistakenly set at 8912. This fix changes the default
to 8192, which is the value originally intended. (Bug #35218020)
• NDB Cluster: The fix for a previous issue introduced a slight possibility of unequal string values
comparing as equal, if any Unicode 9.0 collations were in use, and the collation hash methods
calculated identical hash keys for two unequal strings. (Bug #35168702)
References: See also: Bug #27522732. This issue is a regression of: Bug #30884622.
• InnoDB: Possible congestion due to purging a large number of system threads has been fixed. (Bug
#35289390, Bug #110685)
• InnoDB: ddl::Aligned_buffer now uses the standard memory allocator and not kernel memory
management. (Bug #35194732, Bug #110411)
• InnoDB: An upgrade from MySQL 5.7 to MySQL 8.0.32 might fail due to deprecated configuration
parameters innodb_log_file_size or innodb_log_files_in_group. The workaround is to
start MySQL 8.0.32 with --innodb-redo-log-capacity=206158430208. (Bug #35155280)
• InnoDB: The rules for aggregating entries in the redo log have been fixed. (Bug #34752625, Bug
#108944)
• InnoDB: Several errors due to tablespace deletion and the buffer pool have been fixed. (Bug
#34330475, Bug #107689)
• Packaging; Group Replication: The group replication plugin from the Generic Linux packages did
not load on some platforms that lacked a compatible version of tirpc. (Bug #35323208)
• Replication: By design, all DDL operations (including binary log operations such as purging the
binary log) acquire a shared lock on the BACKUP_LOCK object, which helps to prevent simultaneous
backup and DDL operations. For binary log operations, we checked whether any locks existed
on BACKUP_LOCK but did not check the types of any such locks. This caused problems due to
the fact that binary log operations should be prevented only when an exclusive lock is held on the
BACKUP_LOCK object, that is, only when a backup is actually in progress, and backups should be
prevented when purging the binary log.
Now in such cases, instead of checking for locks held on the BACKUP_LOCK object, we acquire a
shared lock on BACKUP_LOCK while purging the binary log. (Bug #35342521)
• Replication: In all cases except one, when mysqlbinlog encountered an error while reading
an event, it wrote an error message and returned a nonzero exit code, the exception being for
the active binary log file (or any binary log where the format_description_log_event had the
LOG_EVENT_BINLOG_IN_USE_F flag set), in which case it did not write a message, and returned
exit code 0, thus hiding the error.
Now mysqlbinlog suppresses only those errors which are related to truncated events, and when
doing so, prints a comment rather than an error message. This fix also improves the help text for the
--force-if-open option. (Bug #35083373)
• Replication: Compressed binary log event handling was improved. (Bug #33666652)
• Replication: A transaction consisting of events each smaller than 1 GiB, but whose total size was
larger than 1 GiB, and where compression did not make it smaller than 1 GiB, was still written to
the binary log as one event bigger than 1 GiB. This made the binary log unusable; in effect, it was
corrupted since neither the server nor other tools such as mysqlbinlog could read it.
9
MySQL 8.0 Release Notes
Now, when the compressed data grows larger than 1 GiB, we fall back to processing the transaction
without any compression. (Bug #33588473)
• Group Replication: In a group replication setup, when there was a source of transactions other than
the applier channel, the following sequence of events was possible:
1. Several transactions being applied locally were already certified, and so were associated with
a ticket, which we refer to as Ticket 2, but had not yet been committed. These could be local or
nonlocal transactions.
2. A view is created with Ticket 3, and must wait on transactions from Ticket 2.
3. The view change (VC1) entered the GR applier channel applier and waited for the ticket to
change to 3.
4. Another group change, and another view change (VC2), occurred while the transactions from
Ticket 2 were still completing.
This gave rise to the following issue: There was a window wherein the last transaction from Ticket
2 had already marked itself as being executed but had not yet popped the ticket; VC2 popped
the ticket instead but never notified any of the participants. This meant that VC1 continued to wait
indefinitely for the ticket to change, and with the additional effect that the worker could not be killed.
We fix this by checking for the need to break each second so that this loop is responsive to changes
in the loop condition; we also register a new stage, so that the loop is more responsive to kill signals.
(Bug #35392640)
• Group Replication: When a group action was sent to the group and the connection was killed
on the coordinator, group members were in different states, with members which received the
coordinated action waiting for the member that executed it, and the member which started execution
having nothing to process, which caused problems with coordination of the group.
Now in such cases, we prevent this issue from occurring by causing group actions to wait until all
members have completed the action. (Bug #34815537)
• JSON: When the result of JSON_VALUE() was an empty string and was assigned to a user variable,
the user variable could in some cases be set to NULL instead, as shown here:
With this fix, the query just shown now returns (1, 0), as expected. (Bug #35206138)
10
MySQL 8.0 Release Notes
• JSON: Some JSON schemas were not always processed correctly by JSON_SCHEMA_VALID().
(Bug #109296, Bug #34867398)
• In rare cases, MySQL server could exit rather than emit an error message as expected. (Bug
#35442407)
• The internal resource-group enhancement added in MySQL 8.0.31 and refactored in MySQL 8.0.32
is now reverted. (Bug #35434219)
• An in-place upgrade from MySQL 5.7 to MySQL 8.0, without a server restart, could result in
unexpected errors when executing queries on tables. This fix eliminates the need to restart the
server between the upgrade and queries. (Bug #35410528)
• A fix in MySQL 8.0.33 made a change for ORDER BY items already resolved so as not to resolve
them again (as is usually the case when a derived table is merged), but this did not handle the case
in which an ORDER BY item was itself a reference. (Bug #35410465)
• Some pointers were not always released following statement execution. (Bug #35395965)
• Some instances of subqueries within stored routines were not always handled correctly. (Bug
#35377192)
• Fortified parsing of the network packet data sent by the server to the client. (Bug #35374491)
• Encryption enhancements now strengthen compliance and remove the use of deprecated APIs. (Bug
#35339886)
• When a column reference given by table name and column name was looked up in the function
find_item_in_list(), we ignored that the item searched for might not have a table name, as it
was not yet resolved. We fix this by making an explicit check for a null table name in the sought-after
item. (Bug #35338776)
• Queries using LIKE '%...%' ran more poorly than in previous versions of MySQL. (Bug
#35296563)
As part of this fix, push() now returns true on error. (Bug #35237721)
• The authentication_oci plugin is fixed to allow federated and provisioned users to connect to a
DB System as a mapped Proxy User using an ephemeral key-pair generated through the OCI CLI.
(Bug #35232697)
• Some queries using common table expressions were not always processed correctly. (Bug
#35231475)
• The internal function compare_pair_for_nulls() did not always set an explicit return value.
(Bug #35217471)
• Removed the clang-tidy checks that clash with the MySQL coding style. (Bug #35208735)
• Some subqueries using EXISTS in both the inner and outer parts of the query were not handled
correctly. (Bug #35201901)
11
MySQL 8.0 Release Notes
• Rotated audit log files now always reset the ID value of the bookmark to zero, rather than continuing
the value from the previous file. (Bug #35200070)
• Errors were not always propagated correctly when evaluating items to be sorted by filesort. (Bug
#35195181)
• The fix for a previous issue with ROLLUP led to a premature server exit in debug builds. (Bug
#35168639)
• When transforming subqueries to a join with derived tables, with the containing query being grouped,
we created an extra derived table in which to do the grouping. This process moved the initial select
list items from the containing query into the extra derived table, replacing all of the original select list
items (other than subqueries, which get their own derived tables) with columns from the extra derived
table.
This logic did not handle DEFAULT correctly due to the manner in which default values were
modelled internally. This fix adds support for DEFAULT(expression) in queries undergoing the
transform previously mentioned. This fix also solves an issue with item names in metadata whereby
two occurrences of the same column in the select list were given the same item name as a result of
this same transform. (Bug #35150085, Bug #35101169)
• A query of the form SELECT * FROM t1 WHERE (SELECT a FROM t2 WHERE t2.a=t1.a +
ABS(t2.b)) > 0 should be rejected with Subquery returns more than 1 row, but when the
subquery_to_derived optimization was enabled, the transform was erroneously applied and the
query returned an incorrect result. (Bug #35101630)
• Handling of certain potentially conflicting GRANT statements has been improved. (Bug #35089304)
• A query using both MEMBER OF() and ORDER BY DESC returned only a partial result set
following the creation of a multi-valued index on a JSON column. This is similar to an issue fixed in
MySQL 8.0.30, but with the addition of the ORDER BY DESC clause to the prblematic query. (Bug
#35012146)
• The debug server asserted on certain operations involving DECIMAL values. (Bug #34973932)
• All instances of adding and replacing expressions in the select list when transforming subqueries
to use derived tables and joins have been changed so that their reference counts are maintained
properly. (Bug #34927110)
• Index Merge (see Index Merge Optimization) should favor ROR-union plans (that is, using RowID
Ordered Retrieval) over sort-union plans if they have similar costs, since sort-union requires
additionally sorting of the rows by row ID whereas ROR-union does not.
For each part of a WHERE clause containing an OR condition, the range optimizer gets the best
range scan possible and uses all these range scans to build an index merge scan (that is, a sort-
union scan). If it finds that all the best range scans are also ROR-scans, the range optimizer
always proposes a ROR-union scan because it is always cheaper than a sort-union scan. Problems
arose when the best range scan for any one part of an OR condition is not a ROR-scan, in which
case, the range optimizer always chose sort-union. This was true even in cases, where it might be
advantageous to choose a ROR-scan (even though it might not be the best range scan to handle
one part of the OR condition), since this would eleminate any need to sort the rows by row ID.
12
MySQL 8.0 Release Notes
Now, in such cases, when determining the best range scan, the range optimizer also detects whether
there is any possible ROR-scan, and uses this information to see whether each part of the OR
condition has at least one possible ROR-scan. If so, we rerun the range optimizer to obtain the best
ROR-scan for handling each part of the OR condition, and to make a ROR-union path. We then
compare this cost with the cost of a sort-union when proposing the final plan. (Bug #34826692, Bug
#35302794)
• Selecting from a view sometimes raised the error Illegal mix of collations ... for
operation '=' when the collation used in the table or tables from which the view definition
selected did not match the current session value of collation_connection. (Bug #34801210)
• Valid MySQL commands (use and status) and C API functions (mysql_refresh,
mysql_stat, mysql_dump_debug_info, mysql_ping, mysql_set_server_option,
mysql_list_processes, and mysql_reset_connection) could write an error message to
the audit log, even though running the command or calling the function emitted no such error. (Bug
#33966181)
• Increased the maximum fixed array size to 8192 instead of 512. This fixes an issue with
mysqladmin extended status requests, which can exceed 512 entries.
• The function used by MySQL to get the length of a directory name was enhanced. (Bug #28047376)
• Executing a query with an implicit aggregation should return exactly one row, unless the query has a
HAVING clause that filters out the row, but a query with a HAVING clause which evaluated to FALSE
sometimes ignored this, and returned a row regardless. (Bug #14272020)
• For a query with a derived condition pushdown where a column in the condition needs to be
replaced, a matching item could not found, even when known to be present, when the replacement
item was wrapped in a ROLLUP while the matching item was not. (Bug #111665, Bug #35570065)
• The presence of an unused window function in a query, along with an ORDER BY that could have
been eliminated, led to an unplanned server exit. (Bug #111585, Bug #35168639, Bug #35204224,
Bug #35545377)
• ORDER BY RANDOM_BYTES() had no effect on query output. (Bug #111252, Bug #35148945, Bug
#35457136)
• Fixed an issue which could occur when loading user-defined functions. (Bug #110576, Bug
#35242734)
Our thanks to Dmitry Lenev for the contribution. (Bug #110494, Bug #35218030)
• The mysqldump utility could generate invalid INSERT statements for generated columns. (Bug
#110462, Bug #35208605)
13
MySQL 8.0 Release Notes
• During optimization, range-select tree creation uses logic which differs based on the left-hand side
of the IN() predicate. For a field item, each value on the right-hand side is added to an OR tree to
create the necessary expression. In the case of a row item comparison (example: WHERE (a,b)
IN ((n1,m1), (n2, m2), ...)), an expression in disjunctive normal form (DNF) is needed. A
DNF expression is created by adding an AND tree with column values to an OR tree for each set of
RHS values, but instead the OR tree was added to the AND tree causing the tree merge to require
2
exponential time due to O(n ) runtime complexity. (Bug #108963, Bug #34758905)
• When using SELECT to create a table and the statement has an expression of type GEOMETRY,
MySQL could generate an empty string as the column value by default. To resolve this issue, MySQL
no longer generates default values for columns of type GEOMETRY under these circumstances. Our
thanks to Tencent for the contribution. (Bug #107996, Bug #34426943)
• For index skip scans, the first range read set an end-of-range value to indicate the end of the first
range, but the next range read did not clear the stale end-of-range value and applies this stale value
to the current range. Since the indicated end-of-range boundary had already been crossed in the
previous range read, this caused the reads to stop, causing multiple rows to be missed in the result.
We fix this by making sure in such cases that the old end-of-range value is cleared. (Bug #107460,
Bug #34235624, Bug #34982949)
• Compilation Notes
• Component Notes
• Bugs Fixed
Compilation Notes
• Microsoft Windows: Added MSVC Code Analysis support for Visual Studio 2017 and higher. This
adds a new MSVC_CPPCHECK (defaults to OFF) CMake option that either enables or disables this
analysis on the current directory and its subdirectories. (Bug #34828882)
• Downgraded curl deprecation warnings to -Wno-error for curl versions greater than 7.86 when
MySQL is built with a GNU compiler or clang. (Bug #35111625)
14
MySQL 8.0 Release Notes
• Removed the deprecated Docs/mysql.info file from the build system. (Bug #34960126)
• Added a top-level .clang-tidy file and associated .clang.tidy files in the strings/ and
mysys/ directories. Also enabled compdb support to enable clang-tidy usage on header files. (Bug
#34917075)
• Removed several unmaintained or unused C++ source files for functionality such as uca-dump and
uctypedump. (Bug #34898978)
• Added a CMake build option to enable colorized compiler output for GCC and Clang when compiling
on the command line. To enable, pass -DFORCE_COLORED_OUTPUT=1 to CMake. (Bug #34897192)
• On Windows, also install .pdb files for associated .dll files if they are found for 3rd-party libraries.
(Bug #34863555)
• Enterprise Linux 8 and Enterprise Linux 9 builds now use GCC 12 instead of GCC 11. (Bug
#34829151)
• Building with -static-libgcc -static-libstdc++ now also builds the bundled protobuf with static libraries,
as required.
Thanks to Alex Xing for the contribution. (Bug #110216, Bug #35123848)
Component Notes
• INSTALL COMPONENT now includes the SET clause, which sets the values of component system
variables while installing one or more components. The new clause reduces the inconvenience and
limitations associated with the other ways of assigning variable values. For usage information, see
INSTALL COMPONENT Statement. (WL #10916)
• Any occurrence of COLLATE followed by the name of a user-defined collation in an SQL statement
You should expect support for user-defined collations to be removed in a future version of MySQL.
(WL #14277)
An improved table-based dictionary registry replaces the file-based dictionary used by the plugin.
For a summary of the differences between the component and plugin implementations, see Data-
15
MySQL 8.0 Release Notes
Masking Components Versus the Data-Masking Plugin. Existing plugin users should uninstall the
server-side plugin and drop its loadable functions before installing the new MySQL Enterprise Data
Masking and De-Identification components. (Bug #33851601, WL #12641)
For more information on this interface, see the Server telemetry traces service section in the MySQL
Source Code documentation.
• TELEMETRY_ACTIVE column was added to the threads table. Indicates whether the thread has
an active telemetry session attached.
(WL #15059)
• Replication: As part of ongoing work to change old terminology used in MySQL products, the
terms “master”, “slave”, and “MTS” have been replaced in error messages relating to MySQL
Replication by “source”, “replica”, and “MTA”, respectively. This includes all error messages listed
in messages_to_clients.txt and messages_to_error_log.txt relating to replication; the
present task does not perform this replacement for messages used in other contexts.
See the MySQL 8.0 Error Message Reference, for more information. (Bug #108422, Bug #34594819,
WL #14191)
• Binary packages that include curl rather than linking to the system curl library have been upgraded to
use curl 7.88.1. (Bug #34828111)
• The use of a generated column with DEFAULT(col_name) to specify the default value for a named
column is not permitted and now emits an error message. (Bug #34463652, Bug #34369580)
• The new TELEMETRY_LOG_ADMIN privilege now enables telemetry log configuration. This privilege
is defined by the telemetry_log plugin, which is deployed exclusively through MySQL HeatWave
on AWS. (Bug #111395, Bug #35494180)
• It is now possible to return the Statement ID to the client for successfully executed
statements. To enable this per session, add statement_id to the value of
session_track_system_variables, or set session_track_system_variables to the
special value * (asterisk). (WL #15418)
16
MySQL 8.0 Release Notes
Bugs Fixed
• NDB Cluster: Occasional temporary errors which could occur when opening a table from the
NDB dictionary while repeatedly performing concurrent schema operations were not retried. (Bug
#34843889)
• NDB Cluster: During iteration, ordered index scans retain a cursor position within each concurrently
scanned ordered index fragment. Ordered index fragments are modified and balanced as a result
of committing DML transactions, which can require scan cursors to be moved within the tree. When
running with query threads configured (AutomaticThreadConfig set to 1), multiple threads can
access the same index fragment tree structure, and the scans of multiple threads can have their
cursors present in the same structure.
The current issue arose due to an assumption in the logic for moving scan cursors when committing
DML operations that all scan cursors belonged to the LDM thread owning the index fragment, which
did not allow for the possibility that such fragments might belong to query threads. (Bug #33379702)
• InnoDB: Error messages related to innodb_doublewrite moved to the error log. (Bug
#34883045, Bug #109330)
• InnoDB: Prevent online DDL operations from accessing out-of-bounds memory. (Bug #34750489,
Bug #108925)
• InnoDB: ALTER TABLE ... AUTO_INCREMENT could be set to less than MAX + 1 and not forced
to MAX + 1. (Bug #33419246, Bug #105092)
• Partitioning: Some IN() queries on partitioned tables were not always handled correctly. (Bug
#34801284)
• Partitioning: Queries using the INDEX_MERGE optimizer hint was not handled correctly in all cases.
(Bug #34797257)
• Replication: XA transactions whose XIDs contained null bytes could not be recovered. (Bug
#34918985)
• Replication: When binlog_order_commits was set equal to 1, for any two transactions and
for any sub-step of the commit phase, the transaction that was written to the binary log first did not
always execute the sub-step first, as expected. (Bug #34703698)
• Replication: Some binary log events were not always handled correctly. (Bug #34617506)
• Replication: The binary log recovery process did not report all possible error states. (Bug
#33658850)
• Replication: When a transaction failed, as a side effect, extraneous error messages relating the
replication data repositories were written to the log. Now in such cases, we suppress such error
messages, which are not directly related to the issue of the failed transaction or its cause. (Bug
#19820134)
17
MySQL 8.0 Release Notes
• Replication: Setting binlog_order_commits to OFF could lead to a missed GTID in the next
binary log file's Previous_gtids event.
Our thanks to Yewei Xu and the Tencent team for the contribution. (Bug #109485, Bug #34930969)
• Replication: Corrected the SQL statements suggested in the error message text for
ER_RPL_REPLICA_ERROR_RUNNING_QUERY.
Our thanks to Dan McCombs for the contribution. (Bug #109154, Bug #34822612)
• Replication: A hash scan builds a hash of changes, scans the target table or index, and applies any
matching change for the current entry. In the build phase, it uses only the before image, and skips
any after image. Problems arose in some cases because generated columns were computed for the
(skipped) after image, leading to replication errors. This is fixed by not computing generated columns
any longer for seek-only calls such as hash scans.
Our thanks to dc huang for the contribution. (Bug #107366, Bug #34198907)
• Replication: In certain rare cases, it was possible to set gtid_mode=OFF for one session while
another session, after WAIT_FOR_EXECUTED_GTID_SET() was issued by a user in this second
session, was still waiting for the next GTID set from the first session. This could result in the second
session waiting indefinitely for the function to return. (Bug #99921, Bug #31505993)
• Group Replication: In certain cases, the group replication secondary node unexpectedly shut down
while purging the relay log. (Bug #34397106)
• Group Replication: When shutting down the Group Replication plugin, the order in which
the associated events were reported the error log sometimes led to confusion. To remove
any doubts, we now make sure that Plugin group_replication reported: 'Plugin
'group_replication' has been stopped. is in fact the last log message relating to the
shutdown, written only when all other events associated with shutting down the plugin have been
logged. (Bug #109345, Bug #34887491)
• In certain cases, CONVERT(utf8mb3_column USING UTF16) was rejected with the error Cannot
convert string '\x--...' from binary to utf16. (Bug #35129361)
• When joining two tables on a string column, and the column from one of the tables has an additional
predicate comparing it with a temporal literal, constant propagation in some cases incorrectly caused
the join condition to be modified such that it used temporal rather than string semantics when
comparing the strings. This caused incorrect results to be returned from the join. (Bug #35115909)
• When replacing subqueries in transforms, the internal flag showing whether a given query block
contains any subqueries (PROP_SUBQUERY) was not updated afterwards. (Bug #35060385)
18
MySQL 8.0 Release Notes
• A client setting the character set to an impermissible client character set (ucs2, utf16, utf16le,
or utf32) could cause unexpected behavior when the client used an authentication plugin. (Bug
#35054579)
• EXPLAIN ANALYZE displayed 0 when the average number of rows was less than 1. To fix this, we
now format numbers in the output of EXPLAIN ANALYZE and EXPLAIN FORMAT=TREE such that
numbers in the range 0.001-999999.5 are printed as decimal numbers, and numbers outside this
range are printed using engineering notation (for example: 1.23e+9, 934e-6). In addition, trailing
zeroes are no longer printed, and numbers less than 1e-12 are printed as 0.
This helps ensure consistent precision regardless of the number's value and improve readability,
while producing minimal rounding errors. (Bug #34990948)
• The NTILE() function did not work correctly in all cases. (Bug #34986665)
• Transforming a correlated scalar subquery to a derived table led to a wrong result for InnoDB tables
when the subquery included duplicate predicates. An example of a query which could be affected by
this issue is shown here:
SELECT * FROM t1
WHERE (
SELECT t2.a FROM t2
WHERE t2.a = t1.a AND t2.a = t1.a
) > 0;
(Bug #34973220)
• Fixed an assert in sql/item_strfunc.cc that could potentially lead to issues with the SPACE()
function. (Bug #34962821)
• Using ROW_COUNT() as the length argument to LPAD() or RPAD() did not perform as expected.
(Bug #34961236)
• A query with a window function having an expression with a CASE function in its ORDER BY clause
could lead to a server exit. (Bug #34933045)
• The fix for a previous issue introduced an assertion in debug builds when optimizing a HAVING
clause. (Bug #34923792)
• When using mysqld_multi, the system that obscures "--password" usage as "--password=*****"
would also match "--password-history" and "--password-require-current" definitions as "--password",
but now explicitly checks for "--password=" instead. (Bug #34918740)
• In some cases, calling the mysql_bind_param() C API function could cause the server to become
unresponsive. (Bug #34869076)
• The authentication_oci_client plugin was unable to open a valid configuration file if any of
its entries contained an equals sign character separated by spaces (for example, key_file = /
home/user/.oci/oci_api_key.pem). Now, both 'key=value' and 'key = value' entry formats
are supported. (Bug #34864078)
• Incorrect results were returned when the result of an INTERSECT or EXCEPT operation was joined
with another table. This issue affected these operations in such cases when used with either
DISTINCT or ALL. (Bug #34843764)
• When preparing a view query, the operation used the system character set (instead of the character
set stored in data dictionary) and then reported an invalid character-string error. (Bug #34800905)
• Prepared statements that operate on derived tables, including views, could stop unexpectedly due to
problems with the code for reopening tables after an error. (Bug #34798403)
19
MySQL 8.0 Release Notes
• Removed an assertion raised in certain cases by the RANDOM_BYTES() function in debug builds.
(Bug #34781507)
• There was an issue in how persisted variables were set on startup, causing certain variables not to
get properly set to their persisted value. (Bug #34751419)
• The MAKETIME() function did not perform correctly in all cases. (Bug #34745241)
• Some functions with multiple arguments did not produce the expected results. (Bug #34741801)
• A table reference in an ORDER BY outside the parenthesized query block in which the table
was used, and which query block had no LIMIT or ORDER BY of its own, raised an error. (Bug
#34704011)
• A left join with an impossible condition as part of an ON clause was not optimized as in MySQL 5.7,
so that in MySQL 8.0, the query executed more quickly without the impossible condition than with it.
An example of such a query, impossible condition included, is SELECT * FROM t1 JOIN t2 ON
t1.c1=t2.c1 AND 1=2. (Bug #34668756)
• When a user defined function was part of a derived table that was merged into the outer query block,
or was part of a subquery converted to a semi-join, knowledge of whether this UDF was deterministic
(or not) was lost during processing. (Bug #34666531)
• With JSON logging enabled and an event subclass specified in the audit log filter definition, an empty
item ("" : { }) was appended to the end of the logged event. (Bug #34659904)
• The server did not always shut down cleanly after uninstalling the audit log plugin. (Bug #34594035)
• Certain antijoins were not handled correctly by the server. (Bug #34370673)
• When the MySQL 5.7 Optimizer has 2 choices for an index to filter rows, one primary and one
secondary, it picks a range scan on the secondary index because the range scan uses more key
parts. MySQL 8.0 did not use this logic, instead choosing the primary index to filter rows with WHERE
clause filtering. Primary key use is not suitable in such cases due to the presence of LIMIT, and due
to the nature of data distribution. The secondary index was not considered while resolving order by
due to constant elimination. This resulted in much different query plans in MySQL 5.7 and MySQL
8.0 for the same query.
We solve this issue in MySQL 8.0 by skipping the constant key parts of the index during order-by
evaluation only if the query is constant-optimized, which can be done at this time, but not during
LIMIT analysis. (Bug #34291261)
• The MySQL data dictionary caches failed lookups of se_private_id values (IDs which are not
found), which speeds up execution of code specific to InnoDB, relying on the fact that InnoDB does
not reuse these IDs. This assumption does not necessarily hold for other storage engines, most
notably NDB, where this problem was resolved previously by not using this cache.
We extend the previous fix made for NDB so that the cache lookup is now employed only when the
table uses the InnoDB storage engine. (Bug #34145006)
• Unexpected results were seen in some queries using DENSE_RANK(), possibly with the addition of
WITH ROLLUP. (Bug #34099408)
20
MySQL 8.0 Release Notes
• Some CTEs that did not use any tables were not always handled correctly. (Bug #33725542)
• Accessing rows from a window frame of a window function call present only in the query's ORDER BY
list raised an error. (Bug #33069747)
• PERCENT_RANK() used with ORDER BY column did not return the correct result. (Bug #33064174)
• The --exclude-tables and --include-tables mysqlpump options did not handle views. (Bug
#21303549)
• AVG(...) OVER (ROWS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING) did not return
the correct result. (Bug #109725, Bug #35013880)
• A query of the form SELECT 1 FROM t1 WHERE NOT EXISTS (VALUES ROW(1), ROW(2))
caused an assert in debug builds when the subquery_to_derived optimizer switch was enabled.
(Bug #109723, Bug #35014318)
• mysqlimport did not escape reserved word table names when used with the --delete option.
(Bug #109711, Bug #34999015)
• When cloning a condition to push down to a derived table, characters in strings representing
conditions were converted to utfmb4 correctly only for values less than 128 (the ASCII subset), and
code points outside the ASCII subset were converted to invalid characters, causing the resulting
character strings to become invalid. For derived tables without UNION, this led to problems when a
column name from the derived table used characters outside the ASCII subset, and was used in the
WHERE condition. For derived tables with UNION, it created problems when a character outside the
ASCII subset was present in a WHERE condition.
We fix these issues by initializing the string used for representing the condition in such cases to the
connection character set. (Bug #109699, Bug #34996488)
• Using --single-transaction with mysqldump version 8.0.32 required either the RELOAD or
FLUSH_TABLES privilege. This requirement now applies only when both gtid_mode=ON (default
OFF) and with --set-gtid-purged = ON|AUTO (default AUTO). (Bug #109685, Bug #109701,
Bug #34993824, Bug #34998910, Bug #35020512)
• Fixed a number of issues present in the internal documentation for the scramble generator algorithm
in sha256_scramble_generator.cc and sha2_password_common.cc.
Our thanks to Niklas Keller for the contribution. (Bug #109576, Bug #34967141)
• CREATE USER IF NOT EXISTS added a password history entry even when the user already
existed and the password was not updated. This caused a subsequent ALTER USER statement to be
rejected. (Bug #109415, Bug #34906592)
21
MySQL 8.0 Release Notes
• Many joins using eq_ref access did not perform as well as in previous versions. This issue was first
reported in MySQL 8.0.29. (Bug #109361, Bug #34891365)
• A hash outer join sometimes incorrectly matched NULL with a decimal zero or an empty string that
used a non-padding collation, leading to erroneous results. (Bug #109211, Bug #34837464)
• An object used internally by ALTER INSTANCE RELOAD TLS was not freed until the number
of readers reached 0, under the assumption is that the number of readers should reach 0 fairly
frequently. The read lock held during an SSL handshake is generally an expensive operation, with
network calls, so when roundtrips between the client and the server took excessively long, the lock
was held for a relatively long amount of time. This meant that, when changing the value of this object
and there were a sufficient number of incoming SSL connections being made, the number of readers
might not reach 0 in a reasonable length of time, leaving the thread holding the lock using 100% of
the CPU until the lock was released.
We fix this by adding a wait after setting the pointer to this object to a new value, but before releasing
the old object.
Our thanks to Sinisa Milivojevic for the contribution. (Bug #107567, Bug #34284186)
• If mysqldump or mysqlpump could not convert a field's default value to UTF-8 (for instance, if the
field was of type BINARY and the default value did not coincide with valid UTF-8), the operation
produced results that were not valid to import. Further, using the --hex-blob option did not resolve
the issue. We now convert the default value to the system character set. If this fails, the server sends
the value as hexadecimal instead to make it more human-readable. (Bug #104840, Bug #33322551)
• A connection using the C API (libmysqlclient) client library could fail with the FUTURE crypto
policy. (Bug #104778, Bug #33316709)
• While cloning a temporary table for a common table expression which used shared materialization,
the cloned temp table was not marked as using hash deduplication, leading to wrong results. We
now set the hash field for the cloned temporary table correctly, and update the hidden field count to
take this into account. (Bug #102251, Bug #32383712)
• CREATE EVENT and ALTER EVENT assumed that all values passed to them (other than in a DO
clause) resolved as scalars without actually checking the values. This led to assertions when any
such values actually rows.
We now perform an explicit check for the number of columns when resolving such items, and report
an error when one produces a row and not a scalar value. (Bug #57552, Bug #11764690)
• A view reference whose underlying field is a constant is not marked as constant when the reference
is part of an inner table of an outer join. It was found that, when pushing a condition down to a
derived table, the reference was stripped off and only the underlying field was cloned, which made it
a constant, and led to wrong results.
To fix this problem, we ensure that we do not push such a condition down to the derived table by
adding a check to see first whether the table used by the condition matches the derived table or is
a constant expression; only when it is one or the other of these do we actually push the condition
down. (Bug #34661, Bug #11747971)
• C API Notes
• Compilation Notes
22
MySQL 8.0 Release Notes
• Keyring Notes
• Pluggable Authentication
• Bugs Fixed
Authentication Notes
• The server could return LDAP_OPERATIONS_ERROR for LDAP authentication failures, rather than
only for actual LDAP server errors such as when an AD domain is not accessible. Now, the server
returns LDAP_AUTHENTICATION_ERROR, a MySQL-specific error code, to indicate authentication
errors. (Bug #100333, Bug #31680279)
C API Notes
• The sha256_password_auth_client_nonblocking() function always returned an error, even
when the public key was available. (See the MySQL Server Doxygen documentation, available at
https://dev.mysql.com/doc/index-other.html.) Our thanks to Facebook for the several fixes in this
patch. (Bug #34556764)
Compilation Notes
• Microsoft Windows: The authentication_ldap_sasl server plugin is no longer built for
Windows as only the client is supported for SASL-based LDAP authentication. (Bug #34448155)
• On Windows, compiling MySQL server using VS 2022 would emit an error about two projects named
"parser-t" if tests and the NDB storage engine were enabled. The tests were renamed to avoid
conflict on case-insensitive operating systems. (Bug #34790413)
• On MacOS, silenced deprecation warnings generated by Xcode 14; this includes suggestions to
use snprintf(3) instead of sprintf(3), and warnings about possible loss of precision from 64 to 32 bit
integers. (Bug #34776172)
• Removed the boost library usage from the plugins. (Bug #34694419)
• Removed all 3rd party files named 'Makefile' as they were not used. (Bug #34648199)
• Located and removed unused code; located it using fastcov. (Bug #34583577)
• Improved code related to building the ndbcluster plugin by fixing warnings generated with 'gcc 11.2.0
RelWithDebInfo on Ubuntu 22.04' and 'gcc 8.3.1 on el6'. (Bug #34384889)
• Now use full file paths for the Bison and Flex source files to help simplify debugging and gcov
reports. (Bug #109022, Bug #34776151)
• Building MySQL would fail if the building user lacked access to the mysqld temporary directory. Now
--no-defaults is used when creating the INFO_BIN file. (Bug #108947, Bug #34756282)
23
MySQL 8.0 Release Notes
This affects statements using such an identifier for the name of any database, table, view, column,
stored program, or alias. Identifiers beginning with a dollar sign are still permitted only when they are
quoted—that is, delimited by single or double quote marks (' or "), or by backtick characters (`),
depending on the server SQL mode. Example:
mysql> TABLE $t; # Unquoted, produces warning
+------+
| a |
+------+
| 1 |
| 2 |
+------+
2 rows in set, 1 warning (0.00 sec)
User variables are not affected by this change. For example, the statement SELECT 1 INTO @$x
does not produce a warning.
See Schema Object Names, for more information. (Bug #34785775, WL #15422)
• Previously, legacy compression-control parameters were deprecated and replaced with new
configuration parameters for greater control over the use of compression in connections to the
server. The new and deprecated parameters are:
24
MySQL 8.0 Release Notes
Now, the following client programs print a deprecation warning to standard error when a client user
invokes one of the programs with --compress (or -C, if applicable): mysqlpump, mysqlcheck,
mysql, mysqladmin, mysqlbinlog, mysqldump, mysqlimport, mysqlshow, mysqlslap,
mysql_upgrade, and mysqltest.
The mysqlbackup --compress option has different capabilities and is not deprecated. (WL
#13292)
STOP REPLICA;
START REPLICA;
The effect of these statements is that the replica now adds an invisible primary key for tables whose
creation is replicated by channel ch1, but does not do so for any keyless table that is created in the
context of ch2.
See CHANGE REPLICATION SOURCE TO Statement, and Generated Invisible Primary Keys, for
further information. (WL #15419)
Keyring Notes
• Host names of endpoints specified in component_keyring_oci configuration files, and obtained
from the Oracle Cloud Infrastructure Console or by querying the Oracle Cloud Infrastructure API,
now can retain the https:// prefix that previously had to be removed when generating a MySQL
configuration for the Oracle Cloud Infrastructure Vault keyring component. (Bug #34636297)
Pluggable Authentication
• On Windows, the client-side Kerberos authentication plugin now supports GSSAPI through the
MIT Kerberos library. It is possible to choose between SSPI and GSSAPI at runtime using a new
plugin option supported by the authentication_kerberos_client authentication plugin on
Windows. Client users invoke mysql or mysqldump with the --plugin-authentication-
kerberos-client-mode command-line option to set the mode to GSSAPI. The default mode
of the authentication_kerberos_client plugin is SSPI, previously the only authentication
method on Windows.
25
MySQL 8.0 Release Notes
For more information, see Connection Commands for Windows Clients in GSSAPI Mode. (WL
#15336)
For example, the following CREATE TABLE and DROP TABLE statements now raise warnings, as
shown here:
mysql> CREATE TABLE full (c1 INT, c2 INT);
Query OK, 0 rows affected, 1 warning (0.03 sec)
To execute the statements without the warnings, encase the table name in each of them with
backtick characters (`), like this:
mysql> CREATE TABLE `full` (c1 INT, c2 INT);
Query OK, 0 rows affected (0.03 sec)
The use of FULL in the right hand side of a value assignment is not affected by this change. For
example, the SET statement shown here remains valid:
mysql> SHOW VARIABLES LIKE '%metadata%';
+---------------------------------------+---------+
| Variable_name | Value |
+---------------------------------------+---------+
| binlog_row_metadata | MINIMAL |
| innodb_stats_on_metadata | OFF |
| performance_schema_max_metadata_locks | -1 |
| resultset_metadata | FULL |
+---------------------------------------+---------+
4 rows in set (0.00 sec)
26
MySQL 8.0 Release Notes
For more information, see Keywords and Reserved Words. (WL #15241)
• It is now possible to set the default format for the output of any EXPLAIN statement which obtains
a query execution plan, and which has no FORMAT option, using the explain_format system
variable added in this release. Like the FORMAT option, this variable can take any of the values
TRADITIONAL, JSON, or TREE. DEFAULT is also supported as a synonym for TRADITIONAL.
(DEFAULT is not supported with the FORMAT option for EXPLAIN.) Suppose the value of
explain_format is TREE; in this case, the output from any such EXPLAIN statement uses the
tree-based format, as though FORMAT=TREE had been specified as part of the EXPLAIN statement.
Any value set for explain_format is overridden by a FORMAT option. This means that, if
explain_format is set to TREE, supplying FORMAT=JSON when invoking EXPLAIN causes the
value of explain_format to be ignored, and the result is displayed using the JSON format.
explain_format also affects the behavior of EXPLAIN ANALYZE; since this statement supports
only the TREE format, if the value of explain_format is not TREE, this means that any EXPLAIN
ANALYZE statement that does not specify the TREE format explicitly raises the error This version
of MySQL doesn't yet support 'EXPLAIN ANALYZE with format format'.
The new system variable has both global and session scope, can be persisted, and can be set from
the command line (as --explain-format) or in a my.cnf option file.
See the description of explain_format. See also Obtaining Execution Plan Information, and
Obtaining Information with EXPLAIN ANALYZE, for further information and examples. (WL #15040)
• Two columns added to the Performance Schema tp_thread_state table in this release make
it possible to identify a thread's type, and to map threads in this table to those in the Performance
Schema threads table. The type of thread is now shown in the tp_thread_state table's
TP_THREAD_TYPE column, and the thread's unique ID in the THREAD_ID column. For more
information, see The tp_thread_state Table. (Bug #34020058)
• Binary packages that include curl rather than linking to the system curl library have been upgraded to
use curl 7.86.0. (Bug #34828111)
27
MySQL 8.0 Release Notes
• The internal resource-group enhancement added in MySQL 8.0.31 is refactored, but it continues to
support the Resource_group_supported status variable. (Bug #34702833, Bug #34699751)
Bugs Fixed
• Important Change: The implementation of the max_join_size system variable, although
documented as a maximum number of rows or disk seeks, did not check the number of rows or disk
seeks directly, but instead treated max_join_size as the maximum estimated cost to permit. While
cost and row count are correlated, they are not the same, and this could lead to unexpected results
when some large queries were allowed to proceed.
In this release, we change how max_join_size is used, so that it now actually limits the maximum
number of row accesses in base tables. If the estimate indicates that a greater number of rows must
be read from the base tables, an error is raised. This makes the actual behavior better reflect what is
documented. (Bug #83885, Bug #25118903)
• InnoDB: Undetectable problems after upgrade from 8.0.28, crash and corruption.
Any new row inserted after upgrade will have all columns added with ALGORITHM=INSTANT
materialized and have version=0.
In the new implementation, a column added with ALGORITHM=INSTANT will fail if the
maximum possible size of a row exceeds the row size limit. So new rows with materialized
ALGORITHM=INSTANT columns will always be within row size limit. (Bug #34558510)
• InnoDB: No more garbled UTF characters in SHOW ENGINE INNODB STATUS (Bug #34486877,
Bug #108111)
• InnoDB: Alter handler adjusted so that adding more than 1024 columns with ALGORITHM=INSTANT
no longer causes a crash. (Bug #34378513, Bug #107854)
• InnoDB: After a column added with ALGORITHM=INSTANT, an online rebuild DDL no longer
crashes. (Bug #33788578, Bug #106279)
• InnoDB: Several adaptive hash index (AHI) code optimizations and improvements were
implemented, addressing various issues including potential race conditions. (Bug #33601434)
• Replication: After MySQL was started with --server-id=0, trying to change the server ID by
using SET PERSIST server_id=N (where N is an integer greater than zero) and restarting the
server had the following results:
• Any replication SQL statement such as START REPLICA was rejected with
ER_SLAVE_CONFIGURATION.
To fix this problem, we now ensure that such checks use the value of the server variable rather than
the value passed to the startup option. (Bug #34412816)
28
MySQL 8.0 Release Notes
• Replication: When replicating compressed binary log events generated by the NDB binary log
injector, relay log positions were not updated in the multithreaded applier, thus causing replication to
hang. (Bug #33889030)
• Replication: Issuing STOP REPLICA SQL_THREAD while the SQL thread was handling a
transaction caused replication to stop immediately, instead of waiting 60 seconds for the event group
to complete before shutting down the SQL thread as expected.
The root cause of this issue was due to the internal variable storing the last event start time not being
reset after the SQL thread was restarted.
We fix this by resetting the variable holding the last event start time whenever the SQL thread is
started. (Bug #33646899)
• Replication: While their wording might imply otherwise, the log messages Setting
super_read_only=ON (ER_GRP_RPL_SUPER_READ_ON) and Setting super_read_only=OFF
(ER_GRP_RPL_SUPER_READ_OFF) were written only after the operations were attempted, and not
beforehand, or while the operations were ongoing. This sometimes led to confusion when setting
the variable was rejected, and this was logged prior to the set attempt itself being logged. To keep
this from happening, these messages are now logged just prior to attempting the operation. (Bug
#108843, Bug #34728079)
• Replication: The relay_log_space_limit system variable is a 64-bit value, but its valid
maximum was specified internally as that of a 32-bit value. (Bug #106323, Bug #33799840)
• Replication: Eliminated an unnecessary update of the gtid_executed table which was performed
when rotating the binary logs. (Bug #106116, Bug #33759477)
A group that was bootstrapped with single-leader enabled but with its protocol version downgraded
to one that did not support it reported WRITE_CONSENSUS_SINGLE_LEADER_CAPABLE
equal to 0, as expected, but attempting to join an instance to the group using
group_replication_paxos_single_leader = 0 was not possible.
To solve this problem, we change the behaviour and make the value of
group_replication_paxos_single_leader consistent with the communication version that
the group is running. Since this variable was introduced in MySQL 8.0.27, it is not known or used in
any previous version, and so we now enforce the following rules:
• When a node tries to join a group that is running MySQL 8.0.26 or earlier and
we are version 8.0.27 or later, we reject the attempt with an error stating that
group_replication_paxos_single_leader must be OFF before joining the group
In addition, we also change the value checked to determine whether changing the group
leader is allowed after running group_replication_set_communication_protocol().
Previously, this was the runtime value of group_replication_paxos_single_leader,
which takes effect only after a group reboot. Instead, when we run
group_replication_set_communication_protocol(), we now use the value
shown by the replication_group_communication_information table's
WRITE_CONSENSUS_SINGLE_LEADER_CAPABLE column, described previously. (Bug #34555045,
Bug #34828311)
29
MySQL 8.0 Release Notes
• Group Replication: In a 3 node cluster, all nodes were killed due to running out of memory.
Subsequently, after all nodes were restarted successfully, attempting to bring the cluster back online
caused the node that had been the primary to hang.
For more information, see Rebooting a Cluster from a Major Outage. (Bug #108339, Bug
#34564856)
The root cause of this issue was that the primary might log out of order the
View_change_log_event with which the secondary rejoined; when the secondary used the
primary as the group donor, this could cause the secondary to catch up with the group improperly
and, eventually, generate incorrect GTIDs for the group transactions. The group replication primary
ensures that the View_change_log_event is logged after all preceding transactions, but there
was a window during which transactions ordered after the View_change_log_event on the group
global order could be logged before the event.
To solve this issue, we now make sure that transactions ordered before a view are always logged
before the View_change_log_event, and that transactions ordered after a view are always logged
after this event. This is now done by the binary log ticket manager, which guarantees the order in
which transactions in the binary log group commit are committed. (Bug #104980, Bug #33405699)
• Some remote connections to the server were not handled correctly. This issue arose as the result of
a previous fix for an issue with require_secure_transport. (Bug #34857411)
• Some query plans were not stable due to nondeterministic sorting of Key_use_array in
sql_optimizer.cc; now we sort it with std::stable_sort() instead of std::sort(). (Bug
#34823952)
• Binary packages that include OpenLDAP rather than linking to the system OpenLDAP library were
upgraded to use version 2.5.13. (Bug #34815046)
• In some cases, an unexpected packet sent by the server to a MySQL client program during
authentication could result in an infinite loop. (Bug #34805922)
• GIS data was not always handled correctly in windowing functions. (Bug #34778646)
• A thread remained bound to the CPU of a dropped resource group even after it was assigned to the
user default resource group (USR_default). USR_default has 0 CPU priority and no CPU affinity,
so with this fix, the thread now is able to run any CPU with USR_default. (Bug #34748973)
• With JSON logging enabled, calling the audit_log_rotate() function did not rotate the file as
expected. A rotated file name consists of the timestamp from the last event logged into the file. When
the file is empty, last timestamp is the same as the timestamp in the already created file. To fix this
issue, the function now uses the current time to name the file if the file is empty. (Bug #34733508)
30
MySQL 8.0 Release Notes
• Some queries having multiple lateral derived tables did not produce the expected result. (Bug
#34716246)
• The bundled zlib library has been upgraded to zlib 1.2.13; zlib 1.2.13 is now the minimum zlib version
supported. (Bug #34711762, Bug #34711758)
• Using the MAX_EXECUTION_TIME optimizer hint with a value greater than the stated maximum kept
an upgrade to MySQL 8.0.30 from completing; this caused the server to report a warning which was
interpreted by the upgrade process as an unrecoverable error. (Bug #34607401)
• In certain cases, evaluation of window functions was not performed correctly. (Bug #34572136)
• Some CTEs were not processed correctly. (Bug #34572040, Bug #34634469)
• Values returned from functions or operators that convert a value to FLOAT (CAST(... AS FLOAT),
CONVERT(..., FLOAT), JSON_VALUE(... RETURNING FLOAT)) may have extra precision
in their internal representation, since they are stored in double precision internally. This sometimes
caused unexpected results when checking such values for equality, such as SELECT DISTINCT
returning duplicates and comparison operators incorrectly reporting two equal values as unequal.
We fix this problem by stripping off the extra double precision from the values before returning them,
and by making any conversion from float to string in these conversion operators use float format
instead of double format. (Bug #34554755)
• Upgrading from MySQL 5.7 to MySQL 8.0 with a very large number of tables in a single database
caused the server to consume excessive memory. It was found that, during the process of checking
whether tables could be upgraded, we fetched all the data dictionary Table objects upfront,
processing each and fetching its name, then performed CHECK TABLE ... FOR UPGRADE on
the list. Fetching all objects beforehand was not necessary in this case, and contributed greatly to
memory consumption.
To correct this problem, we now fetch one Table object at a time in such cases, performing any
required checks, fetching its name, and releasing the object, before proceeding with the next one.
(Bug #34526001)
• When creating natural join columns, a hidden column added as part of a materialized derived table
is used in constructing the join condition, which is later used to check whether the join eligible for
pushdown to derived tables. The current issue arose when this column was not retrieved from the
derived table due to it being hidden; this occurred even when the condition pushdown optimization
was not enabled. We solve this problem by rejecting all hidden columns added internally, and not
merely for hidden columns added for functional indexes. (Bug #34523627)
• Types were not derived consistently from user variables. This could be seen, for example, by
executing the following statements repeatedly:
In this particular case, the output of the SHOW CREATE TABLE statement showed
`@max_error_count` text the first time, and `@max_error_count` mediumblob in
successive iterations. (The second is correct.) (Bug #34523475)
31
MySQL 8.0 Release Notes
• Following work done in MySQL 8.0.23 to improve host resolution for user accounts, the time
needed for CREATE USER to complete increased significantly, particularly when running many such
statements in close succession.
Prior to upgrading to this release, you can work around this issue when issuing many such
statements in succession by preceding them with a single CREATE USER 'fakeuser' ACCOUNT
LOCK (you can use any user name that does not conflict with existing ones for this). When finished,
you can (and should) clean up by issuing the following statements:
DROP USER 'fakeuser';
FLUSH PRIVILEGES;
For more information, see Access Control, Stage 1: Connection Verification. (Bug #34449016)
• The data_masking server-side plugin could emit a runtime error and halt unexpectedly. (Bug
#34445632)
• Some multiply nested queries were not performed correctly. (Bug #34377854)
• When merging a derived table, a nested join condition is added to the derived table and the
underlying tables are added to this join nest. In addition, the join condition is associated with the
derived table.
Evaluation for range access is skipped if the table is an inner table of an outer join or if the table
is an inner table and the join is not a semijoin. For a derived table, the underlying base table was
treated as being of the latter kind, range analysis was skipped, and the range access method was
thus unavailable.
To fix this problem, we now evaluate for range access when the embedding table is a derived
table, and ensure that the join condition associated with the derived table is used for the range
optimization. (Bug #34347116)
• A LOAD DATA INFILE statement issued with a subquery could cause the server to return an
incorrect warning (Subquery returns more than 1 row). (Bug #34336033)
• Improved handling of resource allocation for internal temporary tables. (Bug #34174001)
• A specific column added after a drop using the INSTANT algorithm could cause a data error and a
server exit. (Bug #34122122)
The optimizer in this case pushed down 1 = derived.col1 into the union, removing the
contribution from SELECT 2, which led to an erroneous result. We now no longer push the condition
down in such cases. (Bug #33910786)
• Some parenthesized query expressions with either or both of ORDER BY and LIMIT were not always
handled correctly. (Bug #33725530)
• Reimplemented retention of item trees having multiple references, by using a reference count in
every Item object. Also removed old code no longer needed due to this change. (Bug #33725415)
• An assert occurred in InnoDB during upgrade of the data dictionary when the definition of the
innodb_ddl_log table changed, even when such changes were effectively null operations, such
as updating utf8 and utf8_bin in table and column definitions to utf8mb3 and utf8mb3_bin,
respectively. (Bug #33688509)
32
MySQL 8.0 Release Notes
• Data and GTIDs backed up by mysqldump were inconsistent when the options --single-
transaction and --set-gtid-purged=ON were both used. This was because, between the
start of the transaction by mysqldump and the fetching of GTID_EXECUTED, GTIDs on the server
could have increased already. With this fix, a FLUSH TABLES WITH READ LOCK is performed
before fetching GTID_EXECUTED, to ensure that its value is consistent with the snapshot taken by
mysqldump.
Limitation: This fix adds a requirement for the RELOAD privilege when using --single-
transaction to execute FLUSH TABLES WITH READ LOCK; the MySQL team is investigating a
solution. (Bug #33630199, Bug #105761)
• Some grouped queries were not always handled correctly. (Bug #33294005, Bug #33349994)
• When multifactor authentication used the auth_socket authentication plugin for the first factor, the
server executed the wrong code during the second-factor authentication workflow and returned an
error message. The second factor could be any authentication plugin. (Bug #33192223)
• Use of a wild card as a column identifier in an INSERT statement was allowed by the parser even
though the syntax is not supported, which led to an assert in debug builds and a silent rejection
of the statement in release builds. This construction has been removed as a possibility from the
grammar, and is now handled strictly as a syntax error. (Bug #33142665)
• In prepared statements, some types of subqueries could cause a server exit. (Bug #33100586)
• Some floating-point literals were not always handled correctly. (Bug #32824429)
• A DELETE statement with a table alias could result in an intermittent server exit. (Bug #32762229)
• Moved INFO_SRC and INFO_BIN from the mysql-common package to the mysql-community-
server-core package, the same package as mysqld and more consistent with RPM packaging. (Bug
#32752147)
• Some queries making use of MATCH() within a HAVING clause were not handled correctly. (Bug
#32616816, Bug #32934558, Bug #34782389)
• A CREATE VIEW statement that contained a subquery sometimes led to an assertion in debug
builds. (Bug #108783, Bug #34703610)
• The deduction of data types for dynamic parameters passed as parameters to a user-defined SQL
function was correct only for a single parameter; with more than one parameter, no such deduction
was performed for the second and following parameters, with the result that their types were always
reported erroneously to clients as MYSQL_TYPE_INVALID. (Bug #108545, Bug #34629157)
• The internal function clone_os_copy_file_to_buf() did not advance the buffer position in the
event of a partial read.
Our thanks to Laurynas Biveinis for the contribution. (Bug #108317, Bug #34543194)
• Views that access system views could encounter an access-denied error during normal use if the
pushdown condition included expressions that used native functions from the system view. (Bug
#108202, Bug #34515868)
• When using window functions, the current row could reevaluate itself based on the wrong record in
some cases. (Bug #108008, Bug #34431996)
33
MySQL 8.0 Release Notes
• A condition pushdown into a UNION of queries having LIKE clauses did not preserve the correct
character set, leading to an (erroneous) empty result.
2. By adding, in the internal parse_expression() function, a character set prefix to any literal
character string that is cloned.
• The audit_log server-side plugin always logged an entire multiple query, rather than logging only
the specific part of the query that was executed. Changing when the query length is set resolves the
issue. (Bug #107390, Bug #34207811)
• Following an upgrade to MySQL 8.0.27 a specific query started consuming comparatively high
amounts of memory whenever it was run within a stored procedure. (Bug #107327, Bug #34190122)
• When a mysqld startup option was used with the maximum- prefix, the upper bound for the
corresponding system variable was set but its current value was not checked against or adjusted
according to the new limit and thus could in some cases be greater than the stated maximum. We
fix this by adjusting the current value if it is larger than the new user defined maximum value. (Bug
#99029, Bug #31072098)
• The mysql_stmt_close() C API function could stop responding after a prepared statement was
canceled using KILL QUERY. (Bug #84470, Bug #25584097)
• Compilation Notes
• Component Notes
• Keyring Notes
• Optimizer Notes
• Bugs Fixed
34
MySQL 8.0 Release Notes
Compilation Notes
• Microsoft Windows: Fixed all C++ deprecation warnings by not using deprecated C++ STL
features. (Bug #33985941)
• Renamed internal Performance Schema functions from _utf8* to _utf8mb4* as they've used utf8mb4
since v8.0.11. (Bug #34351301)
• Fixed linker flags for clang/ubsan to workaround a LLVM/Clang related integer issue as described in
LLVM bug #16404. (Bug #34311325)
• Updated helper scripts to use 'utf8mb3' for charsets/collations instead of 'utf8' for future compatibility.
Renamed functions and data structures used to handle utf8mb3 character sets and collations to help
clarify their utf8mb3 usage. (Bug #34263480, Bug #34025412)
• Cleaned up CMake code, and simplified INFO_BIN and INFO_SRC. (Bug #34139084)
Component Notes
• New component services now enable server components and plugins to query within the local
server. The new MySQL command services are similar to C API functions in libmysql, except they
do not expose protocol internals to the client. For information about these services, see the MySQL
Server Doxygen documentation, available at https://dev.mysql.com/doc/index-other.html. Search for:
• s_mysql_mysql_command_factory
• s_mysql_mysql_command_options
• s_mysql_mysql_command_query
• s_mysql_mysql_command_query_result
• s_mysql_mysql_command_field_info
• s_mysql_mysql_command_error_info
(WL #14293)
Keyring Notes
• MySQL Keyring previously implemented Oracle Cloud Infrastructure Vault Keyring keystore
capabilities using a server plugin, but now is transitioning to use the MySQL component
infrastructure. The new keyring component has similarities to the existing keyring_oci plugin, but
is configured differently and can access keys that were created using the keyring_oci plugin when
a similar set of configuration options are used to initialize the new component. For configuration
details, see Using the Oracle Cloud Infrastructure Vault Keyring Component.
• During startup, the server determines which keyring component to load using a manifest file,
and the loaded component consults its own configuration file when it initializes. See Keyring
Component Installation.
35
MySQL 8.0 Release Notes
Optimizer Notes
• Important Change: The MySQL Optimizer's internal management of set operations has been
improved, with the following effects:
• Bodies of parenthesized query expressions can now be nested to in combination with UNION. For
example, the query shown here, previously rejected with error ER_NOT_SUPPORTED_YET, is now
allowed:
(
(SELECT a, b, c FROM t ORDER BY a LIMIT 3) ORDER BY b LIMIT 2
) ORDER BY c LIMIT 1;
• When collapsing parenthesized expression bodies, MySQL now follows the semantics specified in
the SQL standard, so that a higher outer limit cannot override an inner lower one. This means that
the expression (SELECT ... LIMIT 3) LIMIT 5 can return at most three rows.
• UNION DISTINCT and UNION ALL can now be nested in arbitrary combinations.
The maximum nesting level supported in all the cases just listed is 63; this follows any simplifications
or merging performed by the parser. See Parenthesized Query Expressions, for more information.
(Bug #103954, WL #11350)
• An outer reference in a derived table pointing to a table in a JOIN operation that was not available for
the subquery to be reported (incorrectly) as valid, whereas such a reference without a derived table
was correctly reported as invalid.
In a related issue, an outer reference to a derived table placed inside the VALUES clause of an
INSERT statement was not recognized as valid, whereas a similar reference without a derived table
was so recognized. Now such a reference to a derived table is accepted within VALUES.
In both cases, we fix the problem by making sure that the correct name resolution context is used for
the outer reference. (Bug #32678303, Bug #34131822)
• SETUP_INSTRUMENTS:
• FLAGS
• THREADS:
• CONTROLLED_MEMORY
• MAX_CONTROLLED_MEMORY
• TOTAL_MEMORY
• MAX_TOTAL_MEMORY
36
MySQL 8.0 Release Notes
• MAX_CONTROLLED_MEMORY
• MAX_TOTAL_MEMORY
• MAX_CONTROLLED_MEMORY
• MAX_TOTAL_MEMORY
• MAX_SESSION_CONTROLLED_MEMORY
• MAX_SESSION_TOTAL_MEMORY
• PREPARED_STATEMENTS_INSTANCES:
• MAX_CONTROLLED_MEMORY
• MAX_TOTAL_MEMORY
The following columns were added to the sys schema STATEMENT_ANALYSIS and X
$STATEMENT_ANALYSIS views:
• MAX_CONTROLLED_MEMORY
• MAX_TOTAL_MEMORY
The PROPERTIES column of the SETUP_INSTRUMENTS table was updated with the
controlled_by_default flag.
You can also add, or remove, non-global memory instruments to the set of controlled-memory
instruments by setting the value of the FLAGS column of SETUP_INSTRUMENTS.For example:
(WL #14432)
This capability is provided through an extension to ANALYZE TABLE ... UPDATE HISTOGRAM.
The following statement sets the histogram for column col_name of table tbl_name to the
histogram's JSON representation json_data:
You can confirm afterwards this by checking the value of the HISTOGRAM column of the Information
Schema COLUMN_STATISTICS table.
37
MySQL 8.0 Release Notes
Our thanks to Kaiwang Chen for this contribution to MySQL. (Bug #104040, Bug #33012389, WL
#15123)
• In this release MySQL adds support for the SQL standard INTERSECT and EXCEPT table operators.
query_a INTERSECT query_b includes only rows appearing in both result sets.
query_a EXCEPT query_b returns any rows from the result set of query_a which are not in the
result of query_b.
INTERSECT and EXCEPT both support DISTINCT and ALL, with DISTINCT the default in both
cases. (This is the same as for UNION).
See INTERSECT Clause, and EXCEPT Clause, for additional information and examples. (Bug
#1309, Bug #31336, Bug #11747209, Bug #11744757, WL #349)
For more information, see The Rewriter Query Rewrite Plugin. (WL #14527)
• Important Change: For platforms on which OpenSSL libraries are bundled, the linked OpenSSL
library for MySQL Server has been updated to version 1.1.1q. Issues fixed in OpenSSL version
1.1.1q are described at https://www.openssl.org/news/cl111.txt and https://www.openssl.org/news/
vulnerabilities.html. (Bug #34414695)
• InnoDB: Two new status variables are provided for monitoring online buffer pool resizing
operations. The Innodb_buffer_pool_resize_status_code status variable
reports a status code indicating the stage of an online buffer pool resizing operation. The
Innodb_buffer_pool_resize_status_progress status variable reports a percentage value
indicating the progress of each stage.
For more information, see Configuring InnoDB Buffer Pool Size. (WL #15175)
• Replication: When replication filtering is in use, a replica no longer raises replication errors related
to privilege checks or require_row_format validation for events which are filtered out. Previously,
all privileges were checked in the applier, with some being checked before applying filters and others
38
MySQL 8.0 Release Notes
not until after; with this release, privilege checks are now deferred until after all replication filters have
been applied. In addition, prior to this release, checks for require_row_format equal to 1 took
place on both the receiver and the applier; now the applier alone performs this check, before any
filters are evaluated.
This makes it possible to filter out any transactions that fail validation, using existing replication
filters, and for the replica to accept only that part of the database to which a given user has been
granted access, as long as updates to this part of the database are replicated only in row-based
format. Another instance in which this might be desirable is when migrating to MySQL Database
Service from on-premise or cloud services which use administration tables to which the inbound
replication user does not have access.
Privilege checks protect against updating critical tables on the replica. Checking
require_row_format protects against replicating unsafe operations; this is used in conjunction
with privilege checks, because the guaranteed absence of unsafe operations removes the need for
some session context initialization and cleanup actions, which in turn removes the need to grant
privileges for those operations.
Other behavior changes associated with this work are noted in the following list:
• The receiver thread no longer errors out when an event that violates require row format validation
is received; the applier thread no longer errors out when an event that violates require row format
validation is handled and subsequently filtered out due to replication filters.
• The applier thread no longer errors out for Query log events that are filtered out due to lack of
privileges for setting any of the system variables listed here:
• pseudo_thread_id
• sql_require_primary_key
• default_table_encryption
This is because setting the variable and checking whether the applier is authorized to set it are
now performed only after filtering takes place. If an event is filtered out, the applier does not try to
set the variable, and thus never fails a check whether it has the necessary privileges to do so.
• The applier thread no longer errors out on privilege checks when an Execute_load_query
event is handled and ends up being filtered out due to replication filters. This is also the
case when an Append_block or Begin_load_query event is applied, and a subsequent
Execute_load_query event is handled and then filtered out.
• The applier thread no longer errors out on privilege checks or require_row_format checks
for Delete_file events. These events are not filterable, because they do not contain the table
name or database name, so we assume they are filtered out. We assume this to be safe because
Delete_file events do not alter database state.
• The applier thread no longer creates or deletes files in the filesystem during the
handling of Append_block or Delete_file events, when there is a user account
configured by PRIVILEGE_CHECKS_USER and it does not have the FILE privilege, nor if
require_row_format is enabled.
• For a replication event altered by --replicate-rewrite-db, any privilege checks apply to the
rewritten database.
See How Servers Evaluate Replication Filtering Rules, and Replica Errors During Replication, for
more information. (Bug #33704306, Bug #33733677, WL #15032)
39
MySQL 8.0 Release Notes
• Binary packages that include curl rather than linking to the system curl library have been upgraded to
use curl 7.85.0. (Bug #34138733, Bug #34614578)
A transaction delay can be used in cases where parallel transactions affect the performance of other
operations due to resource contention. For example, if parallel transactions affect index creation or
an online buffer pool resizing operation, you can configure a transaction delay to reduce resource
contention while those operations are running. (WL #15277)
• Thread pool plugin features previously only available with MySQL Database Service, are now
available in MySQL Enterprise Edition.
• The TP_CONNECTION_ADMIN privilege enables a user to access the server with a privileged
connection. When the limit defined by thread_pool_max_transactions_limit has been
reached, new connections cannot access the server. A privileged connection ignores the limit
defined by thread_pool_max_transactions_limit and permits connecting to the server to
increase the transaction limit, remove the limit, or kill running transactions.
(WL #15293)
• Activating MySQL Server’s offline mode, which is done by changing the value of the offline_mode
system variable to ON, now requires the CONNECTION_ADMIN privilege in addition to the
SYSTEM_VARIABLES_ADMIN privilege (or the deprecated SUPER privilege, which covers both these
privileges). Sessions whose users have the CONNECTION_ADMIN privilege remain connected when
offline mode is activated, and users with that privilege can make new connections to an offline server
instance. The new requirement means that administrators who can activate offline mode cannot
inadvertently lock themselves out by doing so. (WL #13400)
• Added the read-only build_id system variable. On Linux systems, a 160-bit SHA1 signature is
generated at compile time; this value, converted to a hexadecimal string, provides a unique identifier
for the build. This value is written in the server log at startup.
This variable is not supported on platforms other than Linux. (WL #15161)
40
MySQL 8.0 Release Notes
Bugs Fixed
• Incompatible Change: The service pfs_plugin_table, deprecated since MySQL 8.0.14, is
removed in this release.
Plugins or components using this service must be updated to use pfs_plugin_table_v1 and
pfs_plugin_column_* instead. (Bug #34361827)
• Important Change; Replication: Query log events filtered by the default database whenever --
replicate-do-db or --replicate-ignore-db was used included XA START, XA END, XA
COMMIT, and XA ROLLBACK (but not XA PREPARE or XA COMMIT ONE_PHASE), regardless of the
binary log format.
• When XA START or XA END was filtered out, the sequence of XA statements within the first part of
the transaction were rendered invalid, which made the replica stop with an error.
• When XA START and XA END were preserved while XA COMMIT or XA ROLLBACK was filtered
out, then a transaction could remain in the prepared state indefinitely on the replica.
To prevent either of these problems from occurring, we no longer filter XA START, XA END, XA
COMMIT, or XA ROLLBACK statements by the default database with --replicate-do-db or --
replica-ignore-db. (Bug #106201, Bug #33764808)
• InnoDB: After upgrading to a release that supports row versions for columns added or dropped
using ALGORITHM-INSTANT, a failure occurred during an instant ADD COLUMN operation on a table
with a nullable column and an instantly added column. (Bug #34488482)
• InnoDB: Adding a virtual column and dropping a column in the same ALTER TABLE statement
raised an invalid debug assertion failure. (Bug #34467592)
• InnoDB: The physical position of columns were not set correctly after dropping a column and
renaming an existing column to the name of the dropped column. (Bug #34463089)
• InnoDB: A DDL operation on a corrupted partitioned table raised an assertion failure. (Bug
#34293555)
• InnoDB: An index block latch order violation during histogram sampling blocked concurrent inserts
and could cause a deadlock failure. (Bug #34282448, Bug #34174927, Bug #107299)
• InnoDB: An ALTER TABLE operation executed while a data load operation was in progress raised
an assertion failure. (Bug #34267618)
• InnoDB: InnoDB memory leaks during MySQL server initialization, identified by Address Sanitizer
(ASAN) builds, were fixed. (Bug #34156050)
• InnoDB: During recovery, a tablespace object associated with encrypted undo tablespace pages
that were fetched from disk did not contain the encryption keys required to decrypt the pages,
resulting in a failure. (Bug #34148143)
• InnoDB: In debug builds, a descending b-tree scan raised a debug assertion failure. (Bug
#34144951)
• InnoDB: A column added using ALGORITHM=INSTANT was visible in read views created before the
DDL operation that added the column. (Bug #33937504)
41
MySQL 8.0 Release Notes
• InnoDB: A failure occurred while upgrading a MySQL instance with a MySQL 5.6 data directory
containing user-created table with a particular table ID. Assignment of that table ID resulted in
assignment of conflicting data dictionary table IDs while upgrading from MySQL 5.7 to MySQL 8.0.
• InnoDB: A buffer block containing intrinsic temporary table page was relocated during page
traversal, causing an assertion failure. (Bug #33715694)
• InnoDB: Dropping a table with a discarded tablespace caused an assertion failure. (Bug #33232978)
• InnoDB: Page I/O reads not completed before shutdown reached the flush phase caused an
assertion failure in cases where pages had change buffer merges to be completed after the I/O read.
(Bug #33192496)
• InnoDB: A TRUNCATE TABLE operation failed to free an acquired mutex in specific cases. (Bug
#107858, Bug #34380370)
• InnoDB: In debug builds, importing a tablespace without a .cfg file for table with an instantly added
or dropped column raised an assertion failure. (Bug #107517, Bug #34307874)
Thanks to Alex Xing for the contribution. (Bug #106952, Bug #34051207)
• InnoDB: A debug assertion failure occurred while redoing a space deletion during recovery. (Bug
#103482, Bug #32819101)
• InnoDB: An InnoDB startup message that specified the number of object pools was removed to
avoid confusion with the number of buffer pool instances. (Bug #80248, Bug #22653060)
• Partitioning: A partitioned table was not repartitioned as expected when an ALTER TABLE
statement acted to change the character set of any of its columns. The root cause of this was that,
when determining whether a change in character set could be done as an in-place alter operation,
we did not consider whether any columns affected by the character set change were part of the
table's partitioning expression. Since such a change might lead to a repartitioning of the table, it
could not be done in place. Now when a change in character set is planned, we also check whether
this affects any columns that are part of a partitioning expression; if not, then we can perform the
operation in place. (Bug #106884, Bug #34031693)
• Replication: When a single event caused multiple updates to the same row of a table on a replica,
the change could not be applied if the replica had a primary key on the table that did not exist in the
source. The hash-based row lookup algorithm now operates in this situation even if a primary key is
present in the replica’s table. (Bug #34114296)
• Replication: When a single statement generated multiple write events for different tables on a
replica, extra auto-increment columns in the replica’s tables were only cleaned up for the last event
generated. They were not cleaned up at all if the last event did not involve a table with an extra auto-
increment column. The cleanup process now always takes place for multiple write events. (Bug
#34095290)
42
MySQL 8.0 Release Notes
• Replication: It was possible in some rare instances of flushing or synchronization errors for the
server to attempt an update of the endpoint of the binary log using invalid values for both the file and
position within the file, leading to undefined behavior.
• Replication: Operations using the SID of a invalid GTID log event sometimes led to undefined
behavior.
We solve this issue by ensuring that the SID is always initialized, even when it belongs to an invalid
GTID log event. (Bug #33784022)
• An additional byte (each) is required to save the length of the user variable, the number of
database IDs stored in binlog_accessed_db_names, and the type of microseconds
In addition, master_data_written, which was not actually used, has been removed. (Bug
#33713071)
• Replication: If a group configuration change is in progress, new members cannot join. The error
message issued in this scenario now states what operation is in progress, such as a primary
election, a swap between single primary mode and multi-primary mode, or a change of group
communication protocol. (Bug #32766981)
• Replication: When the binary log sender thread waited for updates with heartbeats enabled, it
sometimes missed update signals, so that changes were not replicated until the next signal was
issued and noticed by the thread.
Our thanks to Facebook for the contribution. (Bug #104491, Bug #33176377)
• Group Replication: The START REPLICA and STOP REPLICA statements were permitted for the
Group Replication applier channel (group_replication_applier), but stopping and starting the
channel manually can leave online members of the replication group incapable of committing remote
transactions. These statements can no longer be used for the channel when Group Replication is
running. (Bug #34231291)
• Group Replication: A deadlock could occur when Group Replication was started on a server
instance, but errors such as incompatible configuration caused the member to leave immediately.
The service registry now manages the registration and deregistration of services by an alternative
process that avoids the issue. (Bug #34194893)
• Group Replication: In an InnoDB ClusterSet, in the event of a commit order deadlock and
subsequent retry, Group Replication could roll back a transaction during certification with an error
43
MySQL 8.0 Release Notes
stating that the GTID for the transaction had already been used. The error is now only returned if the
GTID has been used on the server instance as well as in the group. (Bug #34157846)
• Group Replication: After checking a transaction commit has no conflicts and is in the correct order,
Group Replication reports back to the committing session. When the event scheduler thread was
started, Group Replication was not able to find the committing session, resulting in the member
entering ERROR state and leaving the group. The procedure to locate the committing session was
extended to find daemon threads, as used to start the event scheduler thread. Thanks to Lou Shuai
for the contribution. (Bug #107635, Bug #34312482)
• Calling many stored procedures from the same connection led the server to consume an ever-
increasing amount of virtual memory. (Bug #35110491)
• Strings containing many leading zeros were incorrectly marked as overflowing when converting them
to decimal, causing the value returned to be the maximum decimal value for the given precision and
scale.
We fix this by replacing all leading zeros in such cases with a single 0, prior to conversion. (Bug
#34479194)
• Differences between the WSAPoll function on Windows and the poll() function on Unix-like
systems caused thread pool code on Windows to consider invalid file descriptors or sockets as ready
for I/O. (Bug #34478731)
• If a MySQL instance at MySQL 8.0.27 or above joined a replication group running at MySQL
8.0.26, the member action mysql_start_failover_channels_if_primary was
removed to match the member actions configuration for to the rest of the group. However, if
the instances were upgraded to run at MySQL 8.0.27 or above, the member action was not
reinstated unless group_replication_reset_member_actions() was issued on a
server that then bootstrapped the group. Joining members now check if the member action
mysql_start_failover_channels_if_primary is available to them, and add it to their
member actions configuration if it is. (Bug #34464526)
• A constant expression used in the SELECT list of a query was not always handled correctly by the
server. (Bug #34418412)
• Some string functions accepting multiple arguments did not process all of the arguments properly.
(Bug #34393009)
• Columns of type YEAR created for temporary tables holding UNION results were not always
guaranteed to be of the correct length. (Bug #34370933)
• If a view (v1) accessed another view (v2), and if v2 was recreated, then SHOW COLUMNS FROM
v1 reported an invalid view error. This issue could occur only when the user was granted global
privileges with roles, but not table-level privileges. It is fixed by checking for global privileges if table-
level privileges are absent. (Bug #34341533)
• Added a missing error check after an item evaluation when reading const tables. (Bug #34327798)
• Reparsing and cloning of derived tables was not always handled correctly in certain cases. (Bug
#34317258, Bug #34408241)
• Pushing a condition down to a derived table with set operations when multiple query blocks were
present was not always handled correctly. (Bug #34306361)
44
MySQL 8.0 Release Notes
• A startup failure during RSA key creation resulted in empty or incomplete keys. Keys are now
generated in a fail-safe manner. (Bug #34274914)
• When comparing two string values with explicit COLLATE clauses, these should have the same
collation, else the comparison should be rejected, but this was not always enforced.
• A CREATE USER operation read from binary log failed to execute on a replica server due to an
unexpected syntax error. (Bug #34178823)
• A precision mismatch could sometimes occur in a CAST to FLOAT operation on an integer value,
when using SQL_SMALL_RESULT as opposed to SQL_BIG_RESULT (see SELECT Statement).
For SQL_BIG_RESULT, the value was truncated according to the inherent precision of an IEEE 32 bit
floating point value, which is the correct behavior. With SQL_SMALL_RESULT, the precision from the
original integer value was preserved; this happened because the value was copied to a temporary
table which supported only double precision values, and these values were later copied back to the
client.
We fix this by distinguishing the type of floating point value when copying such values to a temporary
table, so that double precision values are stored as type double and single precision values are
stored as type float. (Bug #34167787)
• Executed codespell on the majority of source code, and fixed the reported spelling errors in the
code comments. (Bug #34163323)
• In certain cases, when checking an internal function pointer before it was called, the wrong pointer
was validated. (Bug #34134738)
• Both the access path and the iterator for eq_ref access had a use_order member for determining
whether to use an ordered index scan. Since eq_ref always returns at most one row, ordering it is
not necessary; thus, use_order serves no purpose here, and has been removed from the access
path and the corresponding iterator. (Bug #34122706)
• Improved the ADD_GDB_INDEX CMake option to also function when loading unit tests. (Bug
#34117732)
• Removed GNU 'gold' linker support, including the associated USE_LD_GOLD CMake option. (Bug
#34094324)
• Manually created directories in a MySQL 5.7 data directory (treated as schema directories in MySQL
5.7) with special characters in the directory name or schemas and tables created with special
characters in their name using a `#mysql50#` prefix caused DDL failures after upgrading to
MySQL 8.0. In MYSQL 8.0, the special characters are replaced with question mark characters
(?) when the object names are added to the data dictionary. The name mismatch caused DDL
operations on the affected objects to fail. Upgrade now stops with an error if invalid schema and
table names are encountered.
In MySQL 5.7, you can update invalid schema and table names to a valid encoding using
mysqlcheck. To identify invalid names, run:
mysqlcheck --check-upgrade --all-databases
In MySQL 5.7, directory names that have special characters can also be updated to use valid
encoding using the following SQL syntax:
45
MySQL 8.0 Release Notes
(Bug #34066605)
• Conditions using the null-safe equals operator (<=>) can now considered by the executor as equijoin
conditions. Predicates using such conditions are not considered as equijoin predicates, but rather as
extra predicates to evaluate following the join. (Bug #34063499)
• Support was added for compiling the MySQL Enterprise Encryption component with OpenSSL 3.
(Bug #34043029)
• Executed codespell on the source code and fixed the reported spelling errors in the code
comments. (Bug #34006439)
• When one or more arguments to GREATEST() were temporal values, the order in which they were
passed to the function could affect the result. (Bug #33996054)
• A SELECT with a LEFT JOIN on a derived table containing a nested subquery as part of a WHERE
clause with an IN predicate returned incorrect results. (Bug #33971286)
• The server did not always process nested views as expected. (Bug #33876690)
• mysqlpump might not be given the correct permissions to use derived tables (tables that are
generated by a query FROM clause), causing the dump process to stop if these were present. Derived
tables are now handled separately and privileges are set for them. (Bug #33866103)
• Repeated execution of a stored routine having as a subquery a SELECT containing multiple AND, OR,
or XOR conditions led to excessive consumption and possibly eventual exhaustion of virtual memory.
(Bug #33852530)
• EXPLAIN ANALYZE provides information about the estimated cost and elapsed time for each iterator
in the query plan. We expect these numbers to be cumulative, so that the cost (or time) for a given
iterator includes the cost of any iterators on which this iterator depends. For example, the estimated
cost of joining table t1 with table t2, using a table scan of t1 followed by a primary key lookup on
t2, should be no less than the cost of scanning t1 plus the cost of the cardinality lookups on t2.
For some queries involving materialization or temporary tables, these numbers were not cumulative.
In addition, cost estimates were incorrect when materializing the result of a UNION operation and
subsequently performing a table scan on the temporary (materialized) table. (Bug #33834146, Bug
#34302461)
• Coercion of collations for comparisons of two string values was dependent upon the order of
the operands. Given one string using the utf8mb4 character set and one using utf8mb3, the
comparison was carried out using the utf8mb4 collation when the left operand was utf8mb4, and
utf8mb3 when the left operand was utf8mb3.
The root of the problem was with the special handling used for coercion of ASCII strings; since both
strings were literals, they were scanned for ASCII and non-ASCII characters, and the repertoire
property set according to this. This meant that it was possible for one string to be treated as ASCII
while the other string was not; when the utf8mb4 string was considered ASCII and thus compatible
with the utf8mb3 string it was (wrongly) converted prior to the comparison.
We fix this by using the internal MY_CS_PUREASCII property rather than MY_REPERTOIRE_ASCII;
MY_CS_PUREASCII is derived strictly from the character set, and not the actual string, which makes
determination of collation deterministic. Now in such cases, neither string is identified as ASCII,
which leads to conversion of the utf8mb3 to utf8mb4 before the comparison is performed, as
expected. (Bug #33801312)
• The scope of the connect_timeout limit was extended to full-packet reads. (Bug #33723597)
46
MySQL 8.0 Release Notes
• New validation was added to ensure that the Event Scheduler restarts automatically on the server as
expected. (Bug #33711304)
• When a prepared statement was executed with no cursor, it could return the wrong result if the
previous execution used a cursor. This issue is fixed by creating and saving two query result objects,
one for use with a cursor and one for use without a cursor. The objects are created on demand, so
if a prepared statement is never used with cursors, the cursor-specific query result object is never
created. (Bug #33535746)
• A prepared statement with parameters could fail to update a row, but the same statement with the
same data did update the row when issued as a query. The fix for the problem is to assign a default
data type to the parameters, although this can be inefficient because there is no context available for
data type propagation and a character string type is given implicitly. In this case, the best practice
is to wrap such parameter declarations in CAST clauses that supply the desired data types. (Bug
#33521861)
• For a table using the FEDERATED storage engine, if consecutive queries on the local server had
a delay between them that exceeded the remote server’s wait timeout (wait_timeout setting),
a packet error was returned on the local server. The timeout error from the remote server is now
handled correctly by the local server, and it reconnects and executes the statement again. (Bug
#33500956)
• Handled an unexpected condition which could arise during join optimization. (Bug #31401468)
• A query performing a full-text search in boolean mode on a column of a MyISAM table led to an
assertion in debug builds when the column was not of a string type. This was due to the fact that
MyISAM allows MATCH columns without indexes in boolean mode, and therefore also allows integer
columns, which are subject to constant propagation. Such queries on tables using any storage
engine other than MyISAM were not affected by this issue.
This is fixed by disabling constant propagation on the MATCH clause when the column is not of a
string type, so that we can safely assume that it contains only column references. (Bug #107638,
Bug #34311472)
• Corrected errors in comments in my_time.cc. Our thanks to Dimitry Kudryavtsev for the
contribution. (Bug #107633, Bug #34308417)
• Following changes to connection error handling in MySQL 8.0.24, if an error such as exceeding
max_allowed_packet caused the mysql client to disconnect from the server, the error was
not reset afterwards to indicate the disconnect. On subsequent queries, the original error was
returned, and automatic reconnection did not take place because the mysql client did not have a
disconnection error. The error is now reset to indicate disconnection and allow clients to reconnect.
(Bug #107605, Bug #34303841)
• Following a bug fix in MySQL 8.0.29, if the password was provided in an option file, the mysql
client did not prompt for a password if the -p option was specified at login. The client now always
prompts for a password when the -p option is specified and uses the specified password, even if an
alternative was populated from an option file. (Bug #107205, Bug #34134984)
• The alternative for the deprecated --ssl=off server option to disable the use of encrypted
connections was not working as documented, or as presented in the deprecation warning. Setting
47
MySQL 8.0 Release Notes
the tls_version system variable to the empty value (tls_version='') now works correctly for
this purpose. (Bug #106459, Bug #33858646)
• An aggregate query on a BIT column returned a value that was formatted as a bit string, but also
had the BINARY flag added automatically. New validation now checks for and skips setting the
BINARY flag for BIT results. (Bug #106241, Bug #33781442)
• SHOW SLAVE STATUS and SHOW SLAVE HOSTS used more CPU following the introduction of SHOW
REPLICA STATUS and SHOW REPLICA HOSTS than previously. (Bug #105924, Bug #33684069)
• When a NO_SKIP_SCAN hint referred to a specific index not to be used for a table skip scan, all
other possible indexes were also ignored, and, thus, a skip scan was not used for any indexes on the
table.
This occurred because processing was not performed for all possible keys for a skip scan if the
NO_SKIP_SCAN hint was not applicable to all indexes. (Bug #104670, Bug #33251616)
• Queries using WHERE column IN (list) took an increasingly excess amount of CPU time as the
list of values grew in length. (Bug #102037, Bug #32311183)
• Compilation Notes
• Keyring Notes
• Pluggable Authentication
• Security Notes
• XA Transaction Notes
• Bugs Fixed
• Important Change: When more than one language had the same collation definition, MySQL
implemented collations for only one of the languages. This meant that some languages were covered
48
MySQL 8.0 Release Notes
only by utf8mb4 Unicode 9.0 collations that are specific to other languages. This release fixes such
issues by adding language-specific collations for those languages that were previously covered only
by language-specific collations for other languages. The new collations are listed here:
• Norwegian
• (Bokmål) utf8mb4_nb_0900_ai_ci
• (Bokmål) utf8mb4_nb_0900_as_cs
• (Nynorsk) utf8mb4_nn_0900_ai_ci
• (Nynorsk) utf8mb4_nn_0900_as_cs
• utf8mb4_sr_latn_0900_ai_ci
• utf8mb4_sr_latn_0900_as_cs
• utf8mb4_bs_0900_ai_ci
• utf8mb4_bs_0900_as_cs
• Bulgarian:
• utf8mb4_bg_0900_ai_ci
• utf8mb4_bg_0900_as_cs
• Galician:
• utf8mb4_gl_0900_ai_ci
• utf8mb4_gl_0900_as_cs
• utf8mb4_mn_cyrl_0900_ai_ci
• utf8mb4_mn_cyrl_0900_as_cs
Compilation Notes
• On Enterprise Linux, fixed ADD_LINUX_RPM_FLAGS so that the initial values of
CMAKE_C_FLAGS and CMAKE_CXX_FLAGS are used before modifying them. (Bug #34131794)
• On Windows, deprecation warnings (C4996) were globally disabled with the /wd4996 command-
line option; now deprecation warnings are disabled on the localized level where appropriate. (Bug
#33975638)
49
MySQL 8.0 Release Notes
• On Windows, improved the generated INFO_BIN and INFO_SRC files. (Bug #33972317, Bug
#34052301)
• Improved GCC 8 support to include -lstdc++fs in order to use std::filesystem. (Bug #33939798)
To achieve the same result (that is, use single threading) without the warning, set
replica_parallel_workers=1 instead. (WL #13956)
• The --skip-host-cache server option is now deprecated, and subject to removal in a future
release.
• The --old-style-user-limits option causes the server to enforce user limits as they were prior
to MySQL 5.0.3, and is intended for backwards compatibility with very old releases. This option is
now deprecated, and using it now raises a warning. You should expect this option to be removed in
a future release of MySQL, and so you are advised to begin now to remove any dependency your
MySQL applications might have on this option. (WL #13228)
The definition of the generated key column added to an InnoDB table by GIPK mode is shown here:
The name of the generated primary key is always my_row_id; you cannot, while GIPK mode is in
effect, use this as a column name in a CREATE TABLE statement that creates a new InnoDB table
unless it includes an explicit primary key.
You cannot alter a generated invisible primary key while GIPKs are in effect, with one exception: You
can toggle the visibility of the GIPK using ALTER TABLE tbl CHANGE COLUMN my_row_id SET
VISIBLE and ALTER TABLE tbl CHANGE COLUMN my_row_id SET INVISIBLE.
By default, generated invisible primary keys can be seen in the output of SHOW CREATE
TABLE and SHOW INDEX; they are also visible in MySQL Information Schema tables such
as the COLUMNS and STATISTICS tables. You can make them hidden instead by setting
show_gipk_in_create_table_and_information_schema to OFF.
You can exclude generated invisible primary keys from the output of mysqldump using the --
skip-generated-invisible-primary-key option added in this release. mysqlpump also now
supports a --skip-generated-invisible-primary-key option which excludes GIPKs from its
output.
50
MySQL 8.0 Release Notes
For more information and examples, see Generated Invisible Primary Keys. For general information
on invisible column support in MySQL, see Invisible Columns. (Bug #34092605, WL #13784)
Keyring Notes
• The keyring_aws plugin has been updated to use the latest AWS Encryption SDK for C (version
1.9.186).
The keyring_aws_region variable supports the additional AWS regions supported by the new
SDK. Refer to the variable description for a list of supported AWS regions. (WL #14547)
See Monitoring Group Replication Memory Usage with Performance Schema Memory
Instrumentation. (WL #14726)
Pluggable Authentication
• The SASL LDAP plugin failed to properly parse Kerberos Key Distribution Center (KDC) host
information read from the Kerberos configuration file, resulting in SASL authentication error. (Bug
#31862170)
Security Notes
• It is now possible to compile the MySQL server package (mysqld + libmysql + client tools) using
OpenSSL 3.0 on supported platforms, which should not change the behavior of the server or client
programs. For additional information, see https://wiki.openssl.org/index.php/OpenSSL_3.0. (WL
#14683)
• IF EXISTS causes REVOKE to raise a warning rather than an error as long as the target user or
role does not exist.
• IGNORE UNKNOWN USER causes REVOKE to raise a warning instead of an error if the target user
or role is not known, but the statement would otherwise succeed.
For a single target user or role and a given privilege or role to be removed, using the IF EXISTS
and IGNORE UNKNOWN USER options together in the same REVOKE statement means that the
statement succeeds (albeit doing nothing, and with a warning), even if both the target user or role
and the privilege or role to be removed are unknown, as long as the statement is otherwise valid.
In the case of multiple targets, multiple privileges or roles to be removed, or both, the statement
succeeds, performing those removals which are valid, and issuing warnings for those which are not.
For more information, see REVOKE Statement. (Bug #102232, Bug #32495441, WL #14690)
51
MySQL 8.0 Release Notes
XA Transaction Notes
• Replication; Group Replication: Previously, recovery was not guaranteed when a server node
in a replication topology unexpectedly halted while executing XA PREPARE, XA COMMIT, or XA
ROLLBACK. To address this problem, MySQL now maintains consistent XA transaction state across
a topology using either MySQL “classic” Replication or MySQL Group Replication when a server
node is lost from the topology and then regained. This also means that XA transaction state is now
propagated so that nodes do not diverge while doing work within a given transaction in the event that
a server node halts, recovers, and rejoins the topology.
For any multi-server replication topology (including one using Group Replication), the XA transaction
state propagates consistently, so that all servers remain in the same state at all times. For any
such topology of any size (including a single server, as long as binary logging is enabled), it is now
possible to recover any server to a consistent state after it has halted unexpectedly and been made
to rejoin the topology after dropping out.
This enhancement is implemented for the case of a single server by adding support for a two-
phase XA prepare between the storage engine and the server's internal transaction coordinator
(ITC), with the state of the prepare retained by both. This means that the ITC can purge its internal
logs safely, without the risk of losing state, should the server halt following the purge. In the single-
node case, imposing order of execution between the storage engine and the binary log prevents
externalization of GTIDs before the corresponding changes become visible to the storage engine;
in a topology comprising multiple servers, this keeps the transaction state from being broadcast to
the topology before it is guaranteed to be locally consistent and persistent. In all cases, the state of
the XA transaction is extracted from the last binary log file to be written and synchronized with the
transaction state obtained from the storage engine.
A known issue in this release can be encountered when the same transaction XID has been used
to execute XA transactions sequentially. If there a disruption in operation occurs while the server
is processing XA COMMIT ... ONE PHASE using this same XID, after the transaction has been
prepared in the storage engine, the state between the binary log and the storage engine can no
longer be reliably synchronized.
• Important Change: For platforms on which OpenSSL libraries are bundled, the linked OpenSSL
library for MySQL Server has been updated to version 1.1.1o. Issues fixed in OpenSSL version
1.1.1o are described at https://www.openssl.org/news/cl111.txt and https://www.openssl.org/news/
vulnerabilities.html. (Bug #34133985)
• Important Change: The fido2 library included with MySQL, used with the
authentication_fido plugin, has been upgraded to version 1.8.0. (Previously, version 1.5.0 was
included with MySQL.)
• InnoDB: The innodb_doublewrite system variable, which enables or disables the doublewrite
buffer, has two new settings, DETECT_ONLY and DETECT_AND_RECOVER. With the DETECT_ONLY
setting, database page content is not written to the doublewrite buffer, and recovery does not use
the doublewrite buffer to fix incomplete page writes. This lightweight setting is intended for detecting
incomplete page writes only. The DETECT_AND_RECOVER setting is equivalent to the existing ON
setting. For more information, see Doublewrite Buffer.
Thanks to Facebook for the contribution. (Bug #32727919, Bug #103211, WL #14719)
52
MySQL 8.0 Release Notes
• InnoDB: InnoDB now supports dynamic configuration of redo log capacity. The
innodb_redo_log_capacity system variable can be set at runtime to increase or decrease the
total amount of disk space occupied by redo log files.
With this change, the number of redo log files and their default location has also changed. From
MySQL 8.0.30, InnoDB maintains 32 redo log files in the #innodb_redo directory in the data
directory. Previously, InnoDB created two redo log files in the data directory by default, and the
number and size of redo log files were controlled by the innodb_log_files_in_group and
innodb_log_file_size variables. These two variables are now deprecated.
Several status variables are provided for monitoring the redo log and redo log capacity resize
operations.
As is generally required for any upgrade, this change requires a clean shutdown before upgrading.
For more information about this feature, see Redo Log. (WL #12527)
• The order of the columns in the primary key definition for a few tables in the mysql schema has
been changed, so that the columns containing the host name and user name are together in
sequence at the start of the primary key. ACL queries on these tables are performed using only the
host name and user name, and if those columns are not together in sequence, a full table scan must
be performed to identify the relevant record. Placing the host name and user name together means
that index lookup can be used, which improves performance for CREATE USER, DROP USER, and
RENAME USER statements, and for ACL checks for multiple users with multiple privileges.
• A new mysqldump option --mysqld-long-query-time lets you set a custom value of the
long_query_time system variable for mysqldump’s session. Use the new option to increase the
elapsed time allowed for mysqldump’s queries before they are written to the slow query log file, in
order to avoid unnecessary logging. Thanks to Facebook for the contribution. (Bug #96369, Bug
#96369, Bug #30110717, WL #13447)
53
MySQL 8.0 Release Notes
• Error log components can now be loaded implicitly at startup before the InnoDB storage engine
is available. This new method of loading error log components loads and enables the components
defined by the log_error_services variable.
Previously, error log components had to be installed first using INSTALL COMPONENT and were
only loaded after InnoDB was fully available, as the list of components to load was read from the
mysql.components table, which is an InnoDB table.
• Log components are loaded early in the startup sequence, making logged information available
sooner.
• It helps avoid loss of buffered log information should a failure occur during startup.
• Loading log components using INSTALL COMPONENT is not required, simplifying error log
configuration.
For more information about this feature, see Error Log Configuration.
If you have previously installed loadable log components using INSTALL COMPONENT and you list
those components in a log_error_services setting that is read at startup (from an option file, for
example), your configuration should be updated to avoid startup warnings. For more information, see
Error Log Configuration Methods. (WL #14793)
• MySQL Enterprise Audit’s audit log file can now be extended with optional data fields to show
the query time, the number of bytes sent and received, the number of rows returned to the client,
and the number of rows examined. This data is available in the slow query log for qualifying
queries, and in the context of the audit log it similarly helps to detect outliers for activity analysis.
It is delivered to the audit log through new component services that you set up as an audit log
filtering function. The extended data fields can only be added when the audit log is in JSON format
(audit_log_format=JSON), which is not the default setting. (WL #14921)
• MySQL Server’s AES_ENCRYPT() and AES_DECRYPT() functions now support the use of a key
derivation function (KDF) to create a cryptographically strong secret key from information such as
a password or a passphrase that you pass to the function. The derived key is used to encrypt and
decrypt the data, and it remains in the MySQL Server instance and is not accessible to users. Using
a KDF is highly recommended, as it provides better security than specifying your own premade key
or deriving it by a simpler method when you use the function. The functions support HKDF (available
from OpenSSL 1.1.0), for which you can specify an optional salt and context-specific information
to include in the keying material, and PBKDF2 (available from OpenSSL 1.0.2), for which you can
specify an optional salt and set the number of iterations used to produce the key. (WL #12669, WL
#15188)
• A new system status variable Tls_library_version shows the runtime version of the OpenSSL
library that is in use for the MySQL instance. The version of OpenSSL affects features such as
support for TLSv1.3. (WL #13407)
• From MySQL 8.0.30, MySQL Enterprise Encryption’s functions are provided by a component, rather
than being installed from the openssl_udf shared library. The new functions provided by the
component use only the generally preferred RSA algorithm, not the DSA algorithm or the Diffie-
Hellman key exchange method, and they follow current best practice on minimum key size. The
component functions also add support for SHA3 for digests (provided that OpenSSL 1.1.1 is in use),
and do not require digests for signatures, although they support them.
If you upgrade to MySQL 8.0.30 from an earlier release where the functions are installed manually
from the openssl_udf shared library file, the functions you created remain available and
are supported. However, these legacy functions are deprecated from this release, and it is
recommended that you install the component instead. The component functions are backward
compatible, so RSA public and private keys, encrypted data, and signatures that were produced
54
MySQL 8.0 Release Notes
by the legacy functions can be used with the component functions. For the component functions to
support decryption and verification for content produced by the legacy functions, you must set the
new system variable enterprise_encryption.rsa_support_legacy_padding to ON (the
default is OFF).
The component functions generate public and private RSA keys in PKCS #8 format. They
allow a minimum key size of 2048 bits, which is a suitable minimum RSA key length for current
best practice. You can set a maximum key size up to 16384 bits using the system variable
enterprise_encryption.maximum_rsa_key_size, which defaults to a maximum key size of
4096 bits. (WL #15024)
• Connections whose users have the CONNECTION_ADMIN privilege are not terminated when MySQL
Server is set to offline mode, which is done by changing the value of the offline_mode system
variable to ON. Previously, checking for connections that had the CONNECTION_ADMIN privilege
could cause a race condition because it involved accessing other threads. Now, a flag for each
thread caches whether or not the user for the thread has the CONNECTION_ADMIN privilege. The
flag is updated if the user privilege changes. When offline mode is activated for the server, this flag is
checked for each thread, rather than the security context of another thread. This change makes the
operation threadsafe.
In addition, when offline mode is activated, connections whose users have the SYSTEM_USER
privilege are now only terminated if the user that runs the operation also has the SYSTEM_USER
privilege. Users that only have the SYSTEM_VARIABLES_ADMIN privilege, and do not have the
SYSTEM_USER privilege, can set the offline_mode system variable to ON to activate offline mode.
However, when they run the operation, any sessions whose users have the SYSTEM_USER privilege
remain connected, in addition to any sessions whose users have the CONNECTION_ADMIN privilege.
This only applies to existing connections at the time of the operation; users with the SYSTEM_USER
privilege but without the CONNECTION_ADMIN privilege cannot make new connections to a system in
offline mode. (WL #14317)
Bugs Fixed
• InnoDB: A TRUNCATE TABLE operation failed to remove data dictionary entries for columns that
were dropped using ALGORITHM=INSTANT.
• InnoDB: An incorrect nullable column calculation on tables with instantly added columns caused
data to be interpreted incorrectly. (Bug #34243694)
• InnoDB: After upgrading to MySQL 8.0.29, a failure occurred when attempting to access a table with
an instantly added column. (Bug #34233264)
• InnoDB: Only the physical position of instantly added columns was logged, which was not sufficient
for index recovery. The logical position of columns was also required. (Bug #34181432)
• InnoDB: The field_phy_pos debug variable in the InnoDB sources was not updated for child
tables during a cascading update operation. (Bug #34181419)
• InnoDB: The read_2_bytes() function in the InnoDB sources, which reads bytes from the log
buffer, returned a null pointer. (Bug #34173425)
• InnoDB: In the Performance Schema instrumentation for InnoDB read-write locks, lock acquisition
failures and successes for TRY (no-wait) operations were instrumented incorrectly. (Bug #34131395)
• InnoDB: In a specific locking scenario, an implicit lock was not converted to an explicit lock as
expected, triggering a lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block,
heap_no, trx) debug assertion failure. (Bug #34123159)
55
MySQL 8.0 Release Notes
• InnoDB: A check that determines if a table has instantly added columns was performed for each
column, which affected the performance of ADD and DROP COLUMN operations on tables with
numerous columns. The check is now performed once per table. (Bug #34112147)
• InnoDB: A workload that generated a large number of lock requests and numerous timeouts caused
a long semaphore wait failure. To address this issue, optimizations were implemented to reduce the
number of exclusive global lock system latches. (Bug #34097862)
• InnoDB: The m_flush_bit in the redo log block header, which was set for the first block of multiple
blocks written in a single log write call, provided no benefit and has been removed. (Bug #34091444)
• InnoDB: Fixed clang-tidy and cppcheck warnings, which included the removal of unused code and
unnecessary checks. (Bug #33957087)
• InnoDB: Recovery of a redo log file mini-transaction (mtr) caused a debug assertion failure on a
MySQL Server instance with a small innodb_log_buffer_size setting.
• InnoDB: Compiling with the WITH_VALGRIND source configuration option produced Wunused-
variable warnings. (Bug #33899862)
• InnoDB: Multiple issues with the lock-free hash table (ut_lock_free_hash_t) were addressed.
(Bug #33830934)
• InnoDB: A query on a generated column with a secondary index caused a failure. The field number
representing the position of the generated column was not valid. (Bug #33825077)
• InnoDB: Memory consumption was greater than expected when updating and inserting rows with
multi-valued index columns. The memory allocated for multi-valued columns for each row update
was held until the file handle was released. (Bug #33766482)
• InnoDB: The UT_LOCATION_HERE structure in the InnoDB sources was not used consistently. (Bug
#33436161)
• InnoDB: A table object needed to retrieve an array of values from a multi-valued index column when
computing the value of a generated column was unavailable. (Bug #32725063)
• InnoDB: A 4GB tablespace file size limit on Windows 32-bit systems has been removed. The limit
was due to an incorrect calculation performed while extending the tablespace. (Bug #28934351)
• InnoDB: Hash and random generator functions in the InnoDB sources were improved. (Bug
#16739204, Bug #23584861)
• InnoDB: A DROP TABLE operation on a table with a discarded tablespace caused an unnecessary
assertion failure. (Bug #107207, Bug #34135187)
• InnoDB: A query on a table with a JSON column returned only a partial result set after adding a
multi-valued index. (Bug #106621, Bug #33917625)
• InnoDB: Purging a record with multiple binary large object values raised an insertion failure due to a
mini-transaction (mtr) conflict. (Bug #105592, Bug #33574272)
• InnoDB: Enabling the adaptive hash index (AHI) on a high-concurrency instance caused temporary
AHI search latch contention while the hash index was being built.
Thanks to Zhou Xinjing from CDB Team at Tencent for the patch. (Bug #100512, Bug #31750840)
• Packaging: The SASL LDAP clientside plugin was missing from the MySQL Community packages
for Windows.
• Replication: When a table definition diverged between the source and the replica because the
replica had an extra primary key, updates and deletes on the replica would fail if that table had an
56
MySQL 8.0 Release Notes
index that was present both on the source and the replica. Primary keys for an InnoDB table are
automatically included in all indexes, and the replication applier needs values for all parts of the
key to be included in an event in order to search the index. Previously, the applier checked that all
the user-defined key parts were present, but the check did not cover hidden primary keys that were
automatically included. The applier now validates that both user-defined and automatically included
key parts are present in an event before using the index to search the data. (Bug #34122738)
• Replication: The write sets extracted by MySQL Replication from transactions when the
transaction_write_set_extraction system variable is enabled (which is the default) are
extracted from primary keys, unique keys, and foreign keys. They are used to detect dependencies
and conflicts between transactions. Previously, write sets involving multi-column foreign keys were
incorrectly identifying each column as a separate foreign key. The issue has now been fixed and
foreign key write sets include all referenced key columns. (Bug #34095747, Bug #34144531)
• Replication: When row-based replication was in use, a replica could sometimes override the SQL
mode value that was sent by the source, in an attempt to avoid issues with additional columns on the
slave. In extreme cases this could lead to data divergence. The problem has been corrected so the
replica now preserves the source’s SQL mode wherever possible. (Bug #33945038)
• Replication: MySQL’s semisynchronous replication did not respect the value of the
net_read_timeout system variable and forced a read timeout of one millisecond. This could
result in the function experiencing partial reads of acknowledgment messages and packets arriving
out of order, while other connections in the MySQL system were functioning correctly. The value
of the net_read_timeout system variable is now applied to connections for semisynchronous
replication. (Bug #101056, Bug #31976209)
• Replication: When the --replicate-same-server-id option was used to make the replica not
skip events that have its own server ID, if the log file was rotated, replication stopped with an error.
The log rotation event now checks and applies the current value of the option. (Bug #89375, Bug
#27492990)
• Group Replication: A deadlock could occur in Group Replication when a member was interacting
with the service infrastructure, such as a joining member checking for incompatible configuration and
then leaving the group due to it. The issue has now been fixed. (Bug #32688091)
• Group Replication: The message logged when a member tries to rejoin a Group Replication
topology when there is an old incarnation of the same server still present has been upgraded from an
informational note to a warning message. (Bug #32651024)
• API: Applications that previously used the MySQL client library to perform an automatic reconnection
to the server received the following mysql_query error after the server was upgraded:
[4031] The client was disconnected by the server because of inactivity. See wait_timeout and
interactive_timeout for configuring this behavior. (Bug #105229, Bug #34007830)
• Pushing a condition down to a derived table was not handled correctly in all cases. (Bug #34311090)
• After pushing down a condition to a derived table having a set operation, while folding an always
true boolean condition, the rewrite was not correct due to not setting abort_on_null to true for
the cloned condition when making a copy during condition pushdown to a derived table with a set
operation. (Bug #34298238)
57
MySQL 8.0 Release Notes
• A missing error return when processing an invalid ORDER BY expression in a view definition led to an
assert in debug builds. (Bug #34239456)
• MySQL Server would not compile with the latest version of Visual Studio 2022. (Bug #34231639)
• While attempting to clone a system variable during condition pushdown, the server sometimes could
not determine the correct context of the cloned expression.
To prevent this, we disallow condition pushdown to derived tables when they use system variables,
or if the underlying expressions in the derived table contain system variables. (Bug #34205559)
• On macOS 11, MySQL Server did not have the correct entitlement to generate a core dump in the
event of an unexpected server halt. A build option WITH_DEVELOPER_ENTITLEMENTS has been
added to allow a build to generate core dumps. (Bug #34163987)
• The fix for Bug #33830493 in MySQL 8.0.29 addressed the situation where if a MySQL instance
stopped unexpectedly or was restarted shortly after a SET PERSIST statement was used to record
system variable settings, the configuration file mysqld-auto.cnf could be left empty, in which case
the server restart could not proceed. The persisted system variables are now written to a backup
file, which is only renamed to mysqld-auto.cnf after the success of the write has been verified,
leaving the original mysqld-auto.cnf file still available. On a restart, if a backup file with valid
contents is found, the server reads from that file. Otherwise the mysqld-auto.cnf file is used and
the backup file is deleted. The file was not flushed to disk by this fix, so it was still possible for the
issue to occur. This patch adds those operations. (Bug #34122866)
• A select from a view that used left joins did not return any results. (Bug #34060289)
Our thanks to Yuxiang Jiang and the Tencent team for the contribution. (Bug #34057013, Bug
#106939)
• It was possible under certain conditions for EXPLAIN ANALYZE to attempt access of an iterator that
did not exist. (Bug #34051681)
• Support was added for compiling the keyring_oci plugin with OpenSSL 3. (Bug #34043013)
• For a materialized table, the output now show the number of rows materialized, rather than the
number of rows read from the materialized table.
58
MySQL 8.0 Release Notes
• Events recorded in the Performance Schema tables for thread creation and deletion were retained
until server shutdown, instead of being removed when the client connection ended. Thread creation
and deletion now takes place after the Performance Schema instrumentation is created for the user
session, so it is cleaned up when the session ends. (Bug #34019988)
• Upgraded the bundled zlib library to zlib 1.2.12. Also made zlib 1.2.12 the minimum zlib version
supported, and removed WITH_ZLIB from the WITH_SYSTEM_LIBS CMake option. (Bug
#34015600)
• The CONNECTION_ID() function, since it returns a session ID which remains constant for
the lifetime of the session, was treated as a constant function. This caused issues when
CONNECTION_ID() was used inside a trigger attached to a table which might be reused by other
sessions. We fix this by making the function const for execution, and returning the actual session ID
when the function is evaluated. (Bug #34009876)
• Executed codespell on the source code and fixed the reported spelling errors in the code
comments. (Bug #34006439)
• The MySQL Enterprise Encryption openssl_udf function library plugin was reimplemented to use
OpenSSL 3 APIs. (Bug #33992115)
• FEDERATED storage engine code was revised to address NULL pointer and variable access issues.
(Bug #33962357)
• Histograms in MySQL returned a selectivity estimate of 0 for values that outside buckets. This meant
that values might be missing from the histogram because they were missed during sampling, or
because the histogram had grown stale. To prevent this, we introduce a constant lower bound of
0.001 on the selectivity estimates produced by histograms. This choice of lower bound corresponds
to the selectivity of a value or range that we are likely to miss during sampling.
Using a constant lower bound rather than a statistical estimate for the selectivity of a missing
value has the advantage of simplicity and predictability, and provides some protection against
underestimating the selectivity due to stale histograms and within-bucket heuristics.
For more information about histograms in MySQL, see Optimizer Statistics. (Bug #33935417)
• For certain queries using a common table expression (CTE), EXPLAIN ANALYZE did not provide
any profiling data for the CTE even when the CTE was known to be executed. This happened when
the following conditions were met:
• The CTE was referenced more than once in the query plan.
• The first reference to the CTE (in the order of the output of EXPLAIN FORMAT=TREE) was never
executed.
The problem was that the CTE plan was always printed when encountering the first reference to the
CTE; if that reference was never executed, the CTE was not materialized there; and thus there was
no profiling data to print.
The fix for this issue ensures that we print the CTE plan when it is first executed, that is, the point
at which it is materialized. The output then includes profiling data. If the CTE is never executed, we
print the plan at the last reference, when there is no profiling data. (Bug #33905399)
• The output from the command mysqld --verbose --help previously showed plugin load options
as ON even when they were off by default, or turned off using an option. The output now shows the
current value for the plugin. (Bug #33870892)
59
MySQL 8.0 Release Notes
• The Server now bundles curl (7.83.1) and only uses it when alternative SSL systems are used, such
as openssl11 on EL7. (Bug #33859507, Bug #34154806)
• Debug MySQL binaries can now be built using -0g and -fno-inline. (Bug #33855533)
• The FIREWALL_EXEMPT privilege, introduced in MySQL 8.0.27, is now granted to users with the
SYSTEM_USER during upgrade. Previously, the privilege was not granted to any database user
during upgrade. (Bug #33854409)
• A correlated subquery did not use a functional index as expected. This occurred when an outer
column reference used inside the subquery was not considered as constant for subquery execution,
which allowed consideration of the functional index to be skipped.
We fix this problem by making sure to consider the outer column reference as constant while
executing the subquery. (Bug #33851055)
• Added alternate OpenSSL system package support by passing in openssl11 on EL7 or openssl3
on EL8 to the WITH_SSL Cmake option. Authentication plugins, such as LDAP and Kerberos, are
disabled as they do not support these alternative versions of OpenSSL. (Bug #33835934)
• Prepared statements with subqueries that accessed no tables, but the subquery evaluation raised an
error, triggered an assert failure in debug builds. (Bug #33773799)
• Some stored functions were not executed correctly following the first invocation. (Bug #33754993)
• When performing a query using a recursive common table expression (CTE) with a removal of a
query expression after constant predicate elimination, it is expected that when the reference count of
table objects for the CTE temporary table reaches zero, it should be possible once again to recreate
the table, but in certain cases one of the table references was not properly recorded as attached to
the CTE. (Bug #33725503)
• A number of issues with pushdown of conditions making use of outer references, relating to work
done in MySQL 8.0.22 to implement condition pushdown for materialized derived tables, have been
identified and resolved. (Bug #33725403, Bug #33725500, Bug #33725508, Bug #33725534, Bug
#33725545)
• The plan generated for a SELECT using a common table expression involves table materialization
and an index scan on the materialized table. Because the temptable engine does not yet support
all index scan methods, such queries might not always execute correctly.
With other MySQL engines, the materialization access path has special handling when the access
path is not considered basic; for temptable, an index scan was not considered basic, which led to
undefined behavior.
We fix this issue by considering the index scan access path basic, and thus avoiding use of any
index scan access methods on temptable tables. (Bug #33700735)
• The Data_free column in the INFORMATION_SCHEMA.FILES table was not updated after adding
a new data file to the InnoDB system tablespace. (Bug #33508534)
• If a plugin attempted to register a system variable with a name that duplicated that of an existing
system variable, the existing static system variable might be overwritten, and uninstalling the plugin
might leave pointers to the freed memory. The issues have now been fixed. (Bug #33451101)
• SHOW TABLES and SELECT * FROM INFORMATION_SCHEMA.TABLES did not return any results
from the Performance Schema if the user had access privileges on individual Performance Schema
tables, only. (Bug #33283709)
60
MySQL 8.0 Release Notes
• Calling a function relating to the data_masking plugin without first installing the plugin led to an
unplanned server shutdown. Functions relating to this plugin are initialized by calling init functions
which in turn access the UDF metadata service, but this is valid only when the data masking plugin is
installed. We fix this problem by adding a check to verify that the plugin is installed before initializing
such functions, and to return an appropriate error message if the plugin providing them is not
installed. (Bug #33234046)
• Under certain conditions, the server did not handle the expiration of max_execution_time or the
execution of a KILL statement correctly. (Bug #33218625)
• mysqlslap, which uses multiple threads to connect to the server, could not run with a user account
that used FIDO authentication. The issue has been fixed by an update to the FIDO library allowing
the authentication to be performed on multiple threads. (Bug #33067183)
• If an incorrect value was set for the binlog_checksum system variable during a session, a
COM_BINLOG_DUMP command made in the same session to request a binary log stream from a
source failed. The server now validates the specified checksum value before starting the checksum
algorithm setup process. (Bug #32442749)
• For slow query logging, the Slow_queries status variable was not implemented unless the slow
query log was enabled, contrary to the documentation. (Bug #28268680, Bug #91496)
• A prepared statement could accept an empty string as a valid float value, which represents a
regression from 8.0.27 behavior. This fix explicitly checks that the length of an interpreted string is
non-empty and fully interpreted as a (float) number. In addition, new verification now ensures that:
• All numeric values are supported with empty strings and strings that are all spaces.
• Regular numeric values are supported, as well as numeric values with leading and trailing spaces.
• Upgrading to MySQL 8.0.29 led to issues with existing spatial indexes (see Creating Spatial
Indexes). The root cause of the problem was a change in how geographic area computations were
performed by the included Boost library, which was upgraded to version 1.77.0 in MySQL 8.0.29.
We fix this by ensuring that we accommodate the new method whenever such computations are
performed. (Bug #107320, Bug #34184111)
• When pushing a condition down to derived table for prepared statements, we clone a condition which
also includes parameters when a derived table contains unions. When a statement needed to be
reprepared during execution—for example, when the signedness of the value specified did not match
that of the actual datatype—the parameter was not cloned correctly resulting in errors. This occurred
because the value specified for the parameter was used to print the string for reparsing, instead of a
literal ? placeholder character.
Now in such cases we set a flag QT_NO_DATA_EXPANSION for printing parameters for reparsing
which, when enabled, causes the ? placeholder to be printed, rather than the actual value. (Bug
#107230, Bug #34148712)
• On MacOS, improved Boost library detection logic for Homebrew as a potentially incompatible
system's Boost version could get used even with -DWITH_BOOST set. (Bug #107151, Bug
#34121866)
61
MySQL 8.0 Release Notes
• On RHEL 7.x, fetching the CPU cache line size returned 0 on s390x RHEL 7.x which caused
rpl_commit_order_queue and integrals_lockfree_queue to fail.
Our thanks to Namrata Bhave for the contribution. (Bug #107081, Bug #34095278)
• When the mysql client was unable to reconnect to the server following an unexpected server halt,
the process of building the completion hash allocated memory that was not freed. The reconnection
operation now does not build the completion hash if the client fails to reconnect, and the memory
concerned is freed if the client is disconnected. (Bug #106864, Bug #34019571)
Our thanks to Namrata Bhave for the contribution. (Bug #106824, Bug #33997819)
• In certain cases, incorrect results could result from execution of a semijoin with materialization, when
the WHERE clause of the subquery contained an equality. In some cases, such as when one side
of such an equality was an IN or NOT IN subquery, the equality was neither pushed down to the
materialized subquery, nor evaluated as part of the semijoin. This also caused issues with some
inner hash joins. (Bug #106710, Bug #106718, Bug #33952115, Bug #33957233)
• Comparator functions for queries like (<date column> <non-date column>) IN ((val1,
val2), (val3, val4), …) could return the wrong results. (Bug #106567, Bug #33897969)
• Fixed an assert definition in SetOsLimitMaxOpenFiles; our thanks to hongyuan li for the contribution.
(Bug #106555, Bug #33893197)
• Previously, it was assumed that, when the same non-nullable expression was used as both the first
and second arguments to LIKE, the result was always true, and so could be optimized away. This
assumption turns out not to be valid, due to the fact that LIKE treats the backslash (\) as an escape
character, even when ESCAPE is not specified. This led to different results when the condition was
used in the SELECT list as opposed to the WHERE clause. To fix the problem, we no longer perform
this optimization with LIKE, with or without an ESCAPE clause. (Bug #106444, Bug #33852756)
• In some cases, when arguments other than global transaction IDs (such as column values) were
passed to GTID_SUBSET(), the function returned values other than the expected NULL. (Bug
#106298, Bug #33793942)
• A problem with evaluation of general quantified comparison predicates occurred when the
left-hand side of the predicate was NULL. In such cases, the value of the subquery evaluation
from the last current row is saved, so that it does not need re-evaluation, but the cached value
(result_for_null_param) was not cleared between executions, so that the next execution could
re-use the result from the previous execution. One consequence of this was that, when a subquery
execution first caused zero rows to match from the subquery—which for an ALL predicate should
return TRUE—a subsequent execution causing at least one row to match also returned TRUE, even
though FALSE was expected.
To solve this issue, we now make sure to clear result_for_null_param while cleaning up the
subquery predicate following execution. (Bug #106164, Bug #33755139)
• Test cases executed with the --async-client option and shutdown commands caused
mysqltest to halt unexpectedly. (Bug #105797, Bug #33643149)
• MySQL supports the use of equiheight histograms to improve selectivity estimates. Each bucket in
an equiheight histogram for a column should contain roughly the same number of values (rows);
keeping the buckets small helps minimize any error.
When constructing an equiheight histogram, too many values were sometime placed in the same
bucket, which could result in substantial errors in selectivity estimation. We fix this by introducing a
new equiheight construction algorithm that guarantees low error, and adapts to the distribution of
62
MySQL 8.0 Release Notes
the data to make efficient use of its buckets. In addition, a new estimator for the number of distinct
values in histogram buckets provides improved worst-case error guarantees.
• Deprecation warnings returned to client programs were sent to stdout rather than stderr, which in
the case of mysqldump could mean that the dump file no longer worked because the warnings were
included in it. The issue has now been fixed and the warnings are sent to stderr. (Bug #104769,
Bug #33733529)
• Extended support for chained SSL certificates. (Bug #54158, Bug #27491518)
This release is no longer available for download. It was removed due to a critical
issue that could cause data in InnoDB tables having added columns to be
interpreted incorrectly. Please upgrade to MySQL 8.0.30 instead.
• Authentication Notes
• Compilation Notes
• Optimizer Notes
• Security Notes
• XA Transaction Notes
• X Plugin Notes
• Bugs Fixed
Authentication Notes
• The maximum size of FIDO authenticator data was increased. (Bug #33655192)
• In the output of SHOW SQL statements (SHOW CREATE TABLE, SHOW CREATE VIEW, SHOW
CREATE DATABASE)
63
MySQL 8.0 Release Notes
• The server now uses utf8mb3 in place of the alias utf8 for character set names when populating
data dictionary tables from built-in character sets. This affects the display of character set and related
information in the MySQL Information Schema tables listed here:
• CHARACTER_SETS
• COLLATIONS
• COLUMNS
• COLLATION_CHARACTER_SET_APPLICABILITY
• PARAMETERS
• ROUTINES
• SCHEMATA
This change also affects the output of the SQL SHOW CHARACTER SET, SHOW COLLATION, SHOW
CREATE DATABASE, and SHOW CREATE TABLE statements. (Bug #30624990)
Compilation Notes
• InnoDB: After addressing the associated issues, the C4100, C4127, C4245 and C4389 MSVC++
level 4 compiler warnings were re-enabled. (Bug #33437498, Bug #33571677)
• GCC 11 is now a supported compiler for building MySQL on EL7 or EL8. This compiler is available
in the devtoolset-11 (EL7) or gcc-toolset-11 (EL8) package. It is also recommended to
use GCC 11 when building third-party applications that are based on the libmysqlclient C API
library. (Bug #33730302)
• The server could not be compiled with Bison 3.8.1 or newer. (Bug #33488047)
A deprecation warning is returned only for the first nonstandard delimiter or whitespace character
encountered in the literal value. An example is shown here:
mysql> SELECT DATE"2020/02/20";
+------------------+
| DATE"2020/02/20" |
+------------------+
| 2020-02-20 |
+------------------+
1 row in set, 1 warning (0.00 sec)
64
MySQL 8.0 Release Notes
For more information and examples, see String and Numeric Literals in Date and Time Context. (WL
#13601)
You should expect this variable and the equivalent server option --replica-parallel-type to
be removed in a future MySQL release.
Values other than 1 (the default) for myisam_repair_threads produce a warning. (WL #14937)
For more information, see the descriptions of these variables in the documentation (Server System
Variables). (WL #13720)
• When an aggregation function is evaluated during optimization, it is presumed that the WHERE
condition has already been evaluated; thus, it can be removed. Before the removal, the optimizer
verifies whether the WHERE condition has any table-independent conditions by making a call to
make_cond_for_table(). When a condition was considered expensive (for example, it used a
stored procedure), it was incorrectly assumed that there was a table-independent condition. We fix
this by excluding expensive conditions in the call to make_cond_for_table().
In addition, a constant condition which was expensive to evaluate, such as f() = 1 where
function f() did not use any tables, often led to incorrect results. In most cases, if a condition
is constant for execution, it is evaluated when optimizing the WHERE condition, skipping it if it is
considered too expensive. The present issue arose due to skipping the condition while optimizing an
implicitly grouped query. To avoid this, we now evaluate such conditions prior to aggregation. (Bug
#33305617)
65
MySQL 8.0 Release Notes
• Columns used by the DEFAULT() function were not marked internally as READ when fixing its
arguments. (Bug #33142135)
Optimizer Notes
• If the column of a table being loaded using LOAD DATA was used in the WHERE clause of a subquery
used inside a SET statement, the column was reported as unknown. (Bug #33714885)
• Aggregated queries that performed an index lookup (eq_ref) could in some cases return wrong
results. This was seen when the execution plan used streaming aggregation instead of aggregation
in temporary tables.
We fix this by disabling eq_ref caching below aggregate nodes. (Bug #33491183)
• The derived materialized table condition pushdown optimization can now be used with most unions.
This means that an outer WHERE condition can now be pushed down to every query block of the
query expression of the materialized derived table or view.
Suppose we create tables t1 and t2, and then the view v based on these two tables, using the SQL
statements shown here:
CREATE TABLE t1 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
c1 INT,
KEY i1 (c1)
);
CREATE TABLE t2 (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
c1 INT,
KEY i1 (c1)
);
Now, when the query SELECT * FROM v WHERE c1 = 12 is executed, the condition c1 = 12 is
pushed down to both query blocks of view v, as shown here in the output of EXPLAIN:
mysql> EXPLAIN FORMAT=TREE SELECT * FROM v WHERE c1 = 12\G
*************************** 1. row ***************************
EXPLAIN: -> Table scan on v (cost=1.26..2.52 rows=2)
-> Union materialize (cost=2.16..3.42 rows=2)
-> Covering index lookup on t1 using i1 (c1=12) (cost=0.35 rows=1)
-> Covering index lookup on t2 using i1 (c1=12) (cost=0.35 rows=1)
This can now be done for most UNION queries. For exceptions, and additional information,
see Derived Condition Pushdown Optimization. (Bug #24012, Bug #36802, Bug #106006, Bug
#11746156, Bug #11748590, Bug #13650627, Bug #30587347, Bug #33318096, Bug #33738597,
WL #13730)
66
MySQL 8.0 Release Notes
• An EXECUTION_ENGINE column that indicates whether a query was processed on the PRIMARY
or SECONDARY engine was added to the Performance Schema statement event tables (see
Performance Schema Statement Event Tables), and to the performance_scema.threads and
performance_scema.processlist tables.
• A COUNT_SECONDARY column that indicates the number of times a query was processed on the
SECONDARY engine was added to the Performance Schema statement summary tables (see
Statement Summary Tables).
Security Notes
• For platforms on which OpenSSL libraries are bundled, the linked OpenSSL library for MySQL
Server has been updated to version 1.1.1n from 1.1.1l. Issues fixed in OpenSSL are described at
https://www.openssl.org/news/cl111.txt and at http://www.openssl.org/news/vulnerabilities.html. (Bug
#33840722, Bug #33970835)
For CREATE FUNCTION, when used to create a stored function, and for CREATE PROCEDURE,
this option prevents an error from occurring if there is already a routine having the same name. For
CREATE FUNCTION, when used to create a loadable function, the option prevents an error in the
event there already exists a loadable function having that name. For CREATE TRIGGER, the option
prevents an error from occurring if there is already a trigger with the same name, on the same table,
and in the same schema. This is intended to improve ease of use for these statements in scripting,
rapid (re)deployment, replication, and other instances of potential repeated use.
This enhancement makes the syntax of these statements more consistent with that of CREATE
DATABASE, CREATE TABLE, CREATE USER, and CREATE EVENT, all of which already support IF
NOT EXISTS. This also provides a complement to the IF EXISTS option already supported by
DROP PROCEDURE, DROP FUNCTION, and DROP TRIGGER.
For more information, see Stored Objects, as well as Function Name Resolution. See also
Replication of CREATE TABLE ... SELECT Statements. (Bug #15287, Bug #11745440, WL #14722)
XA Transaction Notes
• Group Replication: Group replication in some scenarios faced problems because it was not
possible to commit an XA transaction prepared on another connection. To address such issues,
MySQL now supports detached XA transactions; once prepared, an XA transaction is no longer
connected to the current session. This happens as part of executing XA PREPARE. The prepared XA
transaction can be committed or rolled back by another connection, and the current session can then
initiate another XA or local transaction without waiting for the prepared XA transaction to complete.
Support for this feature can be disabled, and the classic behavior reinstated, by setting the
xa_detach_on_prepare system variable introduced in this release to OFF. The default is ON,
which is recommended, especially in a replication setting.
67
MySQL 8.0 Release Notes
For more information, see XA Transaction States, as well as Server Instance Configuration. (Bug
#100163, Bug #31599926, WL #14700)
X Plugin Notes
• A difference in format between Unix socket lock files for classic MySQL protocol and X Protocol
meant that the server could not start if the file for the other protocol was present. For the benefit of
instances where it is not possible to remove the file manually, such as MySQL Database Service
instances, the protocols now use the same format for the file. (Bug #31468581)
• InnoDB: InnoDB now supports ALTER TABLE ... DROP COLUMN operations using
ALGORITHM=INSTANT.
Operations that support ALGORITHM=INSTANT only modify metadata in the data dictionary.
Table data is unaffected, making the operations instantaneous. If not specified explicitly,
ALGORITHM=INSTANT is used by default by DDL operations that support it.
Prior to MySQL 8.0.29, an instantly added column could only be added as the last column of the
table. From MySQL 8.0.29, an instantly added column can be added to any position in the table.
For more information about DDL operations that support ALGORITHM=INSTANT, see Online DDL
Operations. (WL #13899)
• Replication: Automatic purging of binary log files by the server is now controlled using the
binlog_expire_logs_auto_purge system variable introduced in this release. By default,
automatic purging is enabled (binlog_expire_logs_auto_purge set to ON); to disable it, set the
value of this variable to OFF.
• Microsoft Windows: Added jemalloc support on Windows, and enabled it for official MySQL
binaries. The new WITH_WIN_JEMALLOC CMake option accepts a directory containing
jemalloc.dll that's copied to the same directory as mysqld.exe and/or mysqld-debug.exe
and utilizes it for memory management operations. Standard memory functions are used if
jemalloc.dll is not found or does not export the required functions. An INFORMATION level log
message records whether or not jemalloc is found and used. (WL #14633)
68
MySQL 8.0 Release Notes
An optional timeout parameter is now available to let you set a timeout for running transactions.
You can set a timeout from 0 seconds (immediately) up to 3600 seconds (60 minutes) for
transactions that are running when you use the function. There is no default setting for the timeout,
so if you do not set it the former behavior of the function still applies, with no upper limit to the wait
time. When the timeout expires, for any transactions that did not yet reach their commit phase,
the client session is disconnected so that the transaction does not proceed. Transactions that
reached their commit phase are allowed to complete. When you set a timeout, it also prevents
new transactions starting on the primary from that point on. Explicitly defined transactions (with a
START TRANSACTION or BEGIN statement) are subject to the timeout, disconnection, and incoming
transaction blocking even if they do not modify any data. To allow inspection of the primary while the
function is operating, single statements that do not modify data, as listed in Permitted Queries Under
Consistency Rules, are permitted to proceed. (WL #14585)
• MySQL Server now has the capability to securely store persisted system variable values containing
sensitive data such as private keys or passwords, and restrict viewing of the values. No MySQL
Server system variables are currently marked as sensitive, but the new capability allows system
variables containing sensitive data to be persisted securely in the future. A keyring component must
be enabled on the MySQL Server instance to support secure storage for persisted system variable
values, rather than a keyring plugin, which do not support the function.
In the operating system file where persisted system variables are stored, the names and values
of sensitive system variables are stored in an encrypted format, along with a generated file key
to decrypt them. The generated file key is in turn encrypted using a master key that is stored in a
keyring. After upgrading to MySQL 8.0.29, the format of the mysqld-auto.cnf option file remains
the same until the first time a SET PERSIST or SET PERSIST ONLY statement is issued, and at
that point it is changed to a new format, even if the system variable involved is not sensitive. In the
new format, the option file cannot be read by older releases of MySQL Server.
The values of sensitive system variables are also protected when they are handled. If a
SET statement is issued for a sensitive system variable, the query is rewritten to replace the
value with “redacted” before it is logged to the general log and audit log. The new privilege
SENSITIVE_VARIABLES_OBSERVER allows a holder to view the values of sensitive system
variables in the Performance Schema tables global_variables, session_variables,
variables_by_thread, and persisted_variables, to issue SELECT statements to return their
values, and to track changes to them in session trackers for connections. Users without this privilege
cannot view those system variable values. (WL #13469)
• The keyring_okv keyring plugin, which uses the Key Management Interoperability Protocol
(KMIP) to communicate securely, is used with MySQL’s keyring service to store keyring data in a
KMIP-compatible back end keyring storage product such as Oracle Key Vault, Gemalto SafeNet
KeySecure Appliance, Townsend Alliance Key Manager, and Entrust KeyControl. The plugin now
allows you to specify more than one standby server to provide backup connections to the back end
keyring storage product if the primary server is unavailable. You can add up to 64 standby servers
69
MySQL 8.0 Release Notes
by editing the okvclient.ora file to specify the IP addresses and port numbers of the servers
as a comma-separated list in the value of the STANDBY_SERVER variable. The plugin iterates over
the standby servers until it can establish a connection, with a 20-second wait for each connection
attempt. You should therefore ensure that the list of standby servers is kept short, accurate, and
up to date, and servers that are no longer valid are removed, as they can significantly affect the
keyring_okv plugin’s connection time and therefore the server startup time. (WL #14363)
• Isolation of access to system variables is now better enforced in the server code that parses,
resolves, and executes SQL statements accessing or updating such variables. (WL #14529)
• MySQL Server now supports SSL session reuse by default with a timeout setting to control how long
the server maintains a session cache that establishes the period during which a client is permitted to
request session reuse for new connections. All MySQL client programs support session reuse. For
server-side and client-side configuration information, see Reusing SSL Sessions.
In addition, C applications now can use the C API capabilities to enable session reuse for encrypted
connections (see SSL Session Reuse). (WL #13075)
Bugs Fixed
• InnoDB: A failure occurred when attempting to purge undo records for a table with an instantly
added column. (Bug #33924532)
• InnoDB: High-priority transactions were not permitted to stop waiting when interrupted or to timeout
while waiting for a lock, preventing deadlocks from being resolved. In cases where the blocking
transaction is also high-priority, high-priority transactions are now permitted to stop waiting when
interrupted or timeout when exceeding the lock wait timeout period. If a blocking transaction is not
high-priority, high-priority transactions wait for the blocking transaction to release its locks. (Bug
#33856332)
• InnoDB: The AIO synchronization queue used on Windows was removed. The synchronous file I/O
read-write function (SyncFileIO::execute) was revised to handle files opened for both normal
and overlapped I/O, as it does on Linux. (Bug #33840645)
• InnoDB: Table version metadata was not reset after truncating all partitions of a table with an
instantly added column. (Bug #33822729)
Enabling and disabling of the standard monitor by InnoDB is now performed independently of the
user-settable innodb_status_output variable. This change addresses an issue in which the
monitor was enabled by InnoDB in a particular scenario but not set back to its previous value.
Thanks to Yuhui Wang for the contribution. (Bug #33789526, Bug #93878)
• InnoDB: The UNIV_DEBUG variant of the mem_heap_alloc() function in the InnoDB sources was
modified to improve Valgrind error detection. (Bug #33783709)
• InnoDB: A fast shutdown did not wait for all active I/O operations to finish before closing all files.
(Bug #33768584)
• InnoDB: A Clang warning reported an incorrectly placed @return command. (Bug #33734011)
• InnoDB: Values of the new record locks array (m_prebuilt->new_rec_locks[]) were not
properly synchronized when switching between partitions, causing an assertion failure due to locks
being freed or not freed as expected. (Bug #33724166)
70
MySQL 8.0 Release Notes
• InnoDB: A race condition in the function that updates the double write buffer when a write request is
completed caused a long semaphore wait error. (Bug #33712370)
• InnoDB: A function wrongly assumed that changing a record in an indexed column always requires
creating a new record in the secondary index, resulting in an lock-related assertion failure. To
address this and other similar cases, the lock_rec_convert_impl_to_expl() function that
converts an implicit record lock to an explicit record lock is now used only when an implicit record
lock is actually held. (Bug #33657235)
• InnoDB: A number of Doxygen issues in the InnoDB sources were addressed. (Bug #33603036)
• InnoDB: A missing null pointer check for an index instance caused a failure. (Bug #33600109)
• InnoDB: Starting the server after an incremental backup failed with an error indicating that page
tracking was unusable. (Bug #33521528)
• InnoDB: An assertion failure was raised during InnoDB recovery. The failure was due to a server
exit that occurred after pages were freed in a local mini-transaction before the free list and index list
could be reset. The free list and index list, which spanned the freed pages, were traversed during
recovery. (Bug #33454557)
• InnoDB: When using COMPACT or REDUNDANT row format, it was possible to create a table that
exceeded the maximum row size, which could eventually result in 'Row size too large' errors when
inserting data. BLOB prefixes were not included in the record size check performed during the
CREATE TABLE operation. (Bug #33399379)
• InnoDB: A function that retrieves the master encryption key (get_master_key()) tried to acquire
the master key ID mutex (master_key_id_mutex), which was not yet initialized. (Bug #33067891)
• InnoDB: The TempTable storage engine did not properly handle a file-full error. (Bug #32929392)
• InnoDB: A DDL log error encountered during an ALTER TABLE ... ALGORITHM=COPY operation
was not handled, causing a failure during a subsequent ALTER TABLE ... ALGORITHM=INPLACE
operation. (Bug #32716838)
• InnoDB: Purge threads processed undo records of an encrypted table for which the tablespace was
not loaded, causing a failure. (Bug #32586721)
• InnoDB: A thread posted an asynchronous I/O operation and closed itself, resulting in an operating
system file operation error. (Bug #30567295)
• InnoDB: Incorrect AUTO_INCREMENT values were generated when the maximum integer column
value was exceeded. The error was due to the maximum column value not being considered. The
previous valid AUTO_INCREMENT value should have been returned in this case, causing a duplicate
key error. (Bug #87926, Bug #26906787)
• InnoDB: Transaction lock priority was modified so that a transaction holding a shared lock and
waiting to upgrade to an exclusive lock is prioritized ahead of a another transaction waiting for an
exclusive lock on the same row. In other words, the transaction that already holds a shared lock is
granted an exclusive lock first. Some other transaction holding a shared lock on the same row can
still prevent an exclusive lock from being a granted in this scenario.
71
MySQL 8.0 Release Notes
• Partitioning: In some cases, establishing a connection to MySQL server could fail if the .ibd file for
a partition was missing. (Bug #33459653)
• Partitioning: Following work done in MySQL 8.0.17 to cause all NOT IN and NOT EXISTS
subqueries to be transformed into antijoins, the inner part of a nested outer join produced by this
transformation was not considered while pruning table partitions. (Bug #33060953)
• Replication: A deadlock caused when the network provider was being stopped could cause STOP
GROUP_REPLICATION to wait indefinitely on some group members. (Bug #33044886)
• Group Replication: Group Replication checked too late in the auto-rejoin process that a rejoining
member was the only type of instance allowed to enter a group while in an error state. The issue has
now been fixed. (Bug #33615493)
• Group Replication: Group Replication could log a warning message about a member joining while
a group configuration operation was running, in situations where there was no joining member, just a
view change. The message is now only logged when appropriate. (Bug #33378364)
• Group Replication: Group Replication now logs operating system errors returned when there is a
problem connecting to the local XCom instance, so it is easier to resolve issues such as a firewall
blocking the connection. (Bug #33189767, Bug #104523)
• Group Replication: To help prevent a primary election from hanging, Group Replication stops
waiting for a confirmation from any members that leave the group during the election. If all the
members for which confirmation was pending leave, Group Replication declares that the primary
election completed successfully. Previously, if the primary member was one of the members that left,
a primary change was incorrectly stated as having happened when that had not been able to take
place. Now, if the primary member leaves during an election, Group Replication declares the primary
election as an unsuccessful election with no primary change. (Bug #33059773)
• MySQL Server would not build EL7 on ARM when building against shared libraries that are copied
by the cmake build system, such as a non-system OpenSSL. Now --page-size is set as reported by
getconf. (Bug #33904267)
• An anonymous user with the PROCESS privilege could not select rows from the processlist table.
(Bug #33869388)
• The range optimizer did not take into account the session memory limit. (Bug #33869004)
• When sorting subqueries, the same filesort operation may be executed many times, with different
input, and so the longest add-on column may change between executions, but the buffer for this
column was not reallocated when necessary. Now, when the previously allocated buffer is sufficiently
large, we reuse it, otherwise we allocate a new one. (Bug #33865094)
• An invalid result was obtained from a common table expression that was materialized and used
in multiple query blocks, where, in the first query block that used the CTE, there were multiple
possible key definitions, which caused the internal function JOIN::finalize_derived_keys()
to move the definition of the key used into position zero, and the second query block using the CTE
manipulated an index that occupied the same position as the original position for the key chosen for
the first query block. This happened as an unintended side effect of work done in MySQL 8.0.22 to
prepare DML statements once only.
72
MySQL 8.0 Release Notes
For more information, see WITH (Common Table Expressions). (Bug #33856374)
• Improved error handling when executing stored procedures and stored functions. (Bug #33851256)
• A trigger that selected from a view did not always yield the expected result. (Bug #33847722)
• Computations performed while loading time zone information require negative values of
my_time_t. Normally, that type's minimum value is zero, corresponding to the start of the
UNIX Epoch (1970-01-01 00:00:00, with no time zone offset), which is reflected in the
constant MYTIME_MIN_VALUE. This minimum value did not work correctly for setting up the
TIME_ZONE_INFO data structures in all cases, since some time zone offsets are negative. This fix
permits negative values for my_time_t while populating the time zone information database cache.
(Bug #33837691)
• If a MySQL instance stopped unexpectedly or was restarted shortly after a SET PERSIST statement
was used to record system variable settings, the configuration file mysqld-auto.cnf could be left
empty, in which case the server restart could not proceed. The persisted system variables are now
written to a backup file, which is only renamed to mysqld-auto.cnf after the success of the write
has been verified, leaving the original mysqld-auto.cnf file still available. On a restart, if a backup
file with valid contents is found, the server reads from that file. Otherwise the mysqld-auto.cnf file
is used and the backup file is deleted. (Bug #33830493)
• filesort did not always check the lengths of string values properly when calculating sort keys.
(Bug #33830073)
• A primary key comprising the GROUP_ID and MEMBER_ID columns was added to the
mysql.firewall_membership table. (Bug #33824544)
• A fix made in MySQL 8.0.20 for an inconsistency in the rows matched value when updating an
updatable view having WITH CHECK OPTION handled this issue for an update of a single table only.
In this release, we fix the issue for multi-table UPDATE statements as well. (Bug #33815426)
• The linked ProtoBuf library for MySQL Server has been updated to version 3.19.4. Issues fixed in
the new Protobuf version are described at https://github.com/protocolbuffers/protobuf/releases. (Bug
#33813846)
• It was possible to insert invalid characters into a utf32 column. (Bug #33810558)
• Reinstalling the MySQL Enterprise Firewall plugin caused a failure. The failure was due to a call to
update a previously persisted firewall system variable before the plugin was fully initialized. (Bug
#33809478)
• Hash joins using VARCHAR or DECIMAL join columns returned an excessive number of rows. An
example using VARCHAR is shown here:
Prior to the fix, the query just shown returned four rows; now it returns two rows as expected. (Bug
#33794977)
• The INFORMATION_SCHEMA.KEY_COLUMN_USAGE table did not list invisible key columns. (Bug
#33781534)
73
MySQL 8.0 Release Notes
• The server did not perform proper cleanup after accessing a view created from a view. (Bug
#33777821)
• In a grouped query using WITH ROLLUP and a window function which ordered on an aggregate
already present in the SELECT list, an extra (and unnecessary) aggregate was added as a hidden
column when resolving the window's ordering clause. (Bug #33769911)
• The data masking mask_ssn() function returned a 'String argument width too large'
error for a valid non-constant value (data read from a database row as opposed to a hard-coded
value). Additionally, validation was not performed for zero-length constant and non-constant values
(empty strings) or for constant values that are too small. These issues were addressed for all data
masking functions that string inputs with length boundaries. (Bug #33759276)
• ROLLUP was not handled correctly in some cases with ORDER BY and a window function. (Bug
#33753245)
• Corrected a number of issues in Doxygen comments. (Bug #33734001, Bug #33734035, Bug
#33734062, Bug #33734075, Bug #33734104, Bug #33734117, Bug #33734129, Bug #33734143,
Bug #33734155, Bug #33734181, Bug #33734188, Bug #33734206)
• Statements that cannot be parsed (due, for example, to syntax errors) are no longer written to the
slow query log. (Bug #33732907)
• The message describing MySQL Enterprise Thread Pool’s initial configuration is now issued as a
SYSTEM message rather than informational, so that it is visible at the default logging level. (Bug
#33729821)
• A pre-locking optimization related to session tracking caused recursive locking in some scenarios.
(Bug #33728209)
• A union involving an IN subquery was not always handled properly when it also used an ORDER BY
clause. (Bug #33725507)
• The mysqlpump client utility could stop unexpectedly when a password prompt was requested using
command line options. If an error is encountered during this process an appropriate error message is
now returned before the client exits. (Bug #33688141)
• Implemented standard package policy to ship separate debuginfo RPMs for the following platforms:
SLES/openSUSE, and community EL6 and EL7. Commercial versions of EL6 and EL7 are now
built with the RelWithDebInfo build type instead of Debug, which greatly decreases their size. (Bug
#33663811, Bug #33684418, Bug #33664929)
• It was not possible to run mysqld with the trace log enabled. (Bug #33653824)
• When the --fido-register-factor option was used at startup for FIDO device registration, the
mysql client could use incorrect syntax in the ALTER USER statement, resulting in a failure. The
issue has now been fixed. (Bug #33650498)
• When searching a SET column value, a user variable passed as the first argument to
FIND_IN_SET() did not produce the same result as a constant value used in the same manner.
The values shown for var and str should be the same in both rows of the output from the following
query, but were not:
SET @a = 'c';
74
MySQL 8.0 Release Notes
Now we make sure in such cases to return the position of the match within the set used for the
column definition whether the value sought is a constant or a column value. (Bug #33635637)
• A SET PASSWORD operation using an authentication method that does support it produced a warning
instead of an expected error. (Bug #33635445)
• If the plugin directory was not specified at MySQL Server startup, and a user attempted FIDO device
registration, the mysql client stopped unexpectedly. The situation is now handled and an appropriate
error is reported. (Bug #33631144)
• A change made in MySQL 8.0.27 moved the EXPLAIN output for composite access paths including
filter and sort from inside the table path to the MATERIALIZE access path, but did not include
INDEX_RANGE_SCAN among the composite access paths. This could in some cases result in
undefined behavior. (Bug #33611545)
• It was not possible to revoke the DROP privilege on the Performance Schema. (Bug #33578113)
• The mysql client could stop unexpectedly when attempting FIDO device registration with a
challenge-response error. The issue has now been fixed. (Bug #33568944)
• A query returned an incorrect result when it met all of the following conditions:
• The query plan used aggregation from a temporary table. This temporary table was empty.
Given an empty table t with column c1, the statement INSERT INTO t SELECT MAX(t.c1),
RAND(0) AS x FROM t provides an example of such a query; by inserting into the same table, we
ensure that the query plan aggregates from a temporary table. The temporary table has a column
for c1, and the (single) result row picks c1 from the first row of the temporary table. If the temporary
table was empty, there was no first row, and c1 became 0; this led to the insertion of (NULL, 0)
rather than, for example, (NULL, 0.155) into t.
We fix this by not storing such columns in the temporary table. (Bug #33535379)
• Following changes in password handling in MySQL 8.0.27, if the mysql client was interrupted with
Ctrl + C, a password prompt could be issued requiring the user’s password in order to action the
interrupt. The password is now recorded when it is provided in response to a prompt (as well as
when it is provided on the command line at startup), so it can be used automatically by the new
connection that is established for the interrupt. (Bug #33514253)
• The internal keyread flag indicates reading only index entries and not full rows. When this flag
was set for an index merge scan during initialization, it was subsequently reset when initializing the
individual range scans picked as part of the index merge scan, which indicated reading rows instead
75
MySQL 8.0 Release Notes
of index entries. We fix this by setting the indexes chosen as covering indexes while reading the
index entries. (Bug #33499071)
• Data copying stalled when cloning page-compressed tables where the compressed data size on the
donor host was equivalent to the available disk space on the recipient host. The holes punched on
the recipient host were smaller than the page size, resulting in disk fragmentation that limited the
amount of space available for cloned data. The process for handling page-compressed tables on the
recipient host was modified to reduce fragmentation and improve data copying speed.
To improve the rate of flushing, the clone plugin now uses the fsync flush method when flushing
page-compressed tables on file systems that support hole punching. (Bug #33482747)
• It was possible, when creating a view, for a subquery to be evaluated during resolution when it was
deemed constant. (Bug #33438883)
• Nominally, in EXPLAIN FORMAT=TREE output, we write a number of rows only as an integer. For
a result of zero, it was difficult to determine whether this was 0.49 or 0.00001, so we add enough
precision to get one leading digit in such cases. (Bug #33426283)
• In debug builds, certain combinations of user variables of type MYSQL_TYPE_DOUBLE hit an assert
when used in the context of CAST() or CONVERT(). (Bug #33406728)
• When setting up multiple equalities, the optimizer added an outer reference when it was not required.
(Bug #33394701)
• The minimum supported version of the Boost library for MySQL builds has now been raised to
1.77.0. (Bug #33353637)
• Redundant init and checkout_access_maps function code was removed from the
Security_context class. (Bug #33339129, Bug #104915)
As of this release, schema_unused_indexes is updated even if the row is not found. (Bug
#33302400)
• Some queries using common table expressions were not handled correctly by EXPLAIN. (Bug
#33300271)
• The server did not obtain index statistics correctly for certain complex queries. (Bug #33270516)
Our thanks to Facebook for their contribution to this fix. (Bug #33165726)
• A page cleaner thread timed out as it waited for an exclusive lock on an index page held by a full-text
index creation operation on a large table. (Bug #33101844)
• For an InnoDB table, a secondary index is extended to include the table's primary key; that is, all
columns that are part of the primary key are marked as being part of all secondary indexes. An
exception to this is when a secondary index is defined as unique, server does not use the primary
key extension. This could lead to problems while setting up the read sets for dynamic range scan.
We fix this issue by making sure in the case of a unique seconary index to include all primary key
parts in the read set. (Bug #33101025)
76
MySQL 8.0 Release Notes
• An existing foreign key constraint that referenced a non-existing table could result in a connection
error after the table was created or renamed. (Bug #33054071)
• While creating a value list for an empty VALUES during execution of an INSERT statement, a hidden
element was added, which subsequently led to an assertion in debug builds. To fix the problem, we
now skip any hidden elements when the VALUES list is created.
See INSERT ... ON DUPLICATE KEY UPDATE Statement, for more information. (Bug #32774799)
• Aliases to SELECT list items in ORDER BY which were part of expressions were not resolved in the
same way as standalone aliases, so that ORDER BY alias was resolved correctly, but ORDER BY
function(alias) was not. (Bug #32695670)
• When removing a condition which was always true, a subquery referring to a view was removed
even though the subquery was itself referred to elsewhere in the query. (Bug #31946448)
• An EXPLAIN statement, if used with multiple-table UPDATE statements that contained derived tables,
could cause the server to exit. (Bug #31884434)
• A memory leak occurred if mysqldump was used on more than one table with the --order-by-
primary option. The memory allocated for sorting each table’s rows is now freed after every table,
rather than only once. (Bug #30042589, Bug #96178)
• mysqld_safe log message textual errors were corrected. Thanks to Bin Wang at China Mobile for
the contribution. (Bug #106590, Bug #33903639)
• Equivalent queries could return different results because the execution paths differed slightly. For
example, Item::val_int_from_string() and Item_string::val_int() should use the
same algorithm for string to integer conversion. (Bug #106517, Bug #33881339)
• Updated CMake rules to handle the deprecated PermissionsStartOnly systemd option. The
alternative executable prefix was added in systemd 231 (July 2016) while PermissionsStartOnly
was deprecated in systemd 240 (Dec 2018). The preferred executable prefix is now used where
available. (Bug #106468, Bug #33862323)
• Following work done in MySQL 8.0.22 to implement condition pushdown for materialized derived
tables, an implicitly grouped query with an aggregation function in some cases returned an empty set
instead of NULL. (Bug #106414, Bug #33838439)
• A prepared and executed query like 'SELECT ?' with a DATE, TIME, DATETIME, or TIMESTAMP as
the bound argument could return the wrong column type. The issue is fixed by restoring the previous
logic that reprepared such queries to give each dynamic parameter its literal value. (Bug #106352,
Bug #33813951)
• A null-safe comparison (≪=>) did not evaluate correctly for a TIMESTAMP column in a trigger. (Bug
#106286, Bug #33790919)
77
MySQL 8.0 Release Notes
• When writing DECIMAL values to the hash join buffer, the values were first normalized. This
normalization could in some cases unintentionally alter the values, which made the values fall into
the wrong hash bucket and caused incorrect results to be returned from the join.
The problem was that the normalization removed leading zeros in a manner which caused some
values to lose some of their least significant digits. We fix this by calculating the desired precision
and passing the calculated value instead of changing the original value. (Bug #106272, Bug
#33787914)
• A query having a WHERE condition of the form c NOT BETWEEN NULL AND COALESCE(a, b),
having DATETIME columns a, b, and c, with columns a and c created as NOT NULL, did not return
correct results. Further investigation showed that, in such cases, when the second or third argument
to BETWEEN was NULL, the comparison results were inverted, causing it to evaluate as NULL for
FALSE, and FALSE for NULL. (Bug #106267, Bug #33788832)
• A NULL-safe comparison between 0 (FALSE) and NULL could return TRUE, even though the
implementation responsible for evaluating an object of this type can never result in NULL and should
always return FALSE. (Bug #105773, Bug #33630225)
• The QUICK_RANGE constructor used the main thread memory root for allocating keys, rather than
the same memory root as used for allocating the QUICK_RANGE object itself. This resulted in
unexpectedly high memory usage when executing multiple queries using a range check for the query
plan. (Bug #105331, Bug #33516707)
• SELECT DISTINCT on a VARCHAR column returned 2 distinct values when the column contained an
empty string and a string consisting of a single whitespace character when the TempTable storage
engine was used (internal_tmp_mem_storage_engine = TempTable). This behavior was
incorrect when using a utf8_bin collation with PAD SPACE; trailing spaces should have been
ignored when selecting distinct values.
For temporary tables created using the TempTable storage engine, the two strings were hashed to
different values, since the TempTable hashing function always hashed zero-length data to 0. (In the
case just described, the empty string was hashed to 0 while the space character from the other string
was used to generate a nonzero hash value.)
This is now fixed by removing any special handling for zero-length data in the TempTable storage
engine's hashing function.
Our thanks to Brian Yue for the contribution. (Bug #105316, Bug #33506241)
• SELECT COUNT(*) using a multi-valued index reported the wrong number of rows. (Bug #104898,
Bug #33334928)
Our thanks to Facebook for the contribution. (Bug #104377, Bug #33139204, Bug #33165693)
• The two types of histograms supported by MySQL, singleton and equi-height, previously stored their
collections of buckets in a map and a set, respectively. This release changes both histogram types
such that they now store buckets in dynamic arrays instead, which reduces space overhead and
speeds up selectivity estimation due to reduced indirection when performing binary search on the
buckets.
Because both types of histograms are constructed by inserting buckets in sorted order, and buckets
are serialized to JSON in sorted order, there is no additional work involved in switching to a dynamic
array. (Bug #104109, Bug #33045204)
78
MySQL 8.0 Release Notes
• An invalid conversion between signed and unsigned variables led to incorrect result from a query of
the form SELECT ALL t1.c1,t2.c1 FROM t1,t2 WHERE t1.c1 > t2.c1. (Bug #102025,
Bug #32302724)
• As of this release, the Performance Schema is collation-aware (Bug #98545, Bug #30881109)
• An assert error could occur when inserting data larger than 32 bytes in the ROLE column of
setup_actors. As of this release, the ROLE column is increased from CHAR(32) to CHAR(96).
(Bug #74678, Bug #19947842)
• C API Notes
• Compilation Notes
• Optimizer Notes
• Packaging Notes
• Bugs Fixed
C API Notes
• Building C API client programs on Windows using Clang as the compiler returned various compiler
warnings, including an unused variable warning. (Bug #33520805, Bug #33520861)
Prior to upgrading, applications that may rely on the previous CONVERT() behavior should
be checked and updated as necessary. In particular, for indexes on generated columns using
CONVERT() with invalid values, you should correct such values, drop the index, then re-create it
79
MySQL 8.0 Release Notes
before upgrading to this release. In some cases, it may be simpler to rebuild the table using ALTER
TABLE table FORCE, rather than dropping and re-creating the index. See SQL Changes, for more
information. (Bug #33199145)
• The output from EXPLAIN FORMAT=TREE hex-encoded ranges for multi-valued indexes, even when
the data type was not a binary one. In addition, ranges using string types were also printed with hex-
encoded values, when they had a binary collation. The latter issue also affected regular indexes, but
was more visible with multi-valued indexes, since these always use utf8mb4_0900_bin collation.
Now, hex-encoding is used only for string types having a binary character set. Strings with non-
binary character sets are now printed in EXPLAIN FORMAT=TREE output as plain text, with escaping
for any special characters. (Bug #33343948)
• For some functions, the resolved character set was not always the same as the character set of the
first argument. (Bug #32668730, Bug #33238711)
Compilation Notes
• InnoDB: Compilation issues associated with the following MSVC++ level 4 compiler warnings were
addressed: C4201, C4701, C4702, C4703, C4706. The compiler warnings, which were previously
disabled, are now enabled. (Bug #33464699)
• InnoDB: An access violation occurred when building a debug version of MySQL using Visual Studio
2019 version 16.10 or version 16.11. The violation was due to an STL iterator bug. (Bug #33223243)
• Binary packages that include curl rather than linking to the system curl library have been upgraded to
use curl 7.80.0. (Bug #33576431)
• Inserting a value with an offset into a DATE or TIME column using the binary protocol gave a wrong
result. For example, when the connection time zone was set to GMT-5, inserting '2021-10-10
00:00:00.123+01:00' into a TIME column yielded '18:00:00'; that is, the value was
converted to the connection time zone (this should be done only with respect to DATETIME
columns).
We fix these by recognizing and adjusting for time zone offsets whenever a TIMESTAMP value with a
time zone offset is inserted into a TIME or DATE column. (Bug #33616957, Bug #33649009)
• A fix in MySQL 8.0.27 for a previous issue changed the resolved type of a boolean expression from
signed INT to unsigned BIGINT in order to simplify type handling, but what appeared then as a
harmless metadata change turned out to cause problems for some of the MySQL Connectors.
We now revert the metadata change and provide a different fix for the original problem, by adjusting
the max_length for the negation of an integer to at least two characters. (Bug #33516898)
• Sorts of some column types, including JSON and TEXT, sometimes exhausted the sort buffer if its
size was not at least 15 times that of the largest row in the sort. Now the sort buffer need only be
80
MySQL 8.0 Release Notes
only 15 times as large as the largest sort key. (Bug #103325, Bug #105532, Bug #32738705, Bug
#33501541)
From MySQL 8.0.28, client programs, including MySQL Shell, that support a --tls-version
option for specifying TLS protocols for connections to the MySQL server cannot make a TLS/SSL
connection with the protocol set to TLSv1 or TLSv1.1. If a client attempts to connect using these
protocols, for TCP connections, the connection fails, and an error is returned to the client. For socket
connections, if --ssl-mode is set to REQUIRED, the connection fails, otherwise the connection is
made but with TLS/SSL disabled.
On the server side, the following settings are changed from MySQL 8.0.28:
• For asynchronous replication, replicas can no longer set the protocol for connections to the source
server (SOURCE_TLS_VERSION option for CHANGE REPLICATION SOURCE TO) to TLSv1 or
TLSv1.1.
(WL #14775)
• The shortcuts ASCII for CHARACTER SET latin1 and UNICODE for CHARACTER SET ucs2 are
now deprecated, and you should expect their removal in a future version of MySQL. Using either of
these now raises a warning; use CHARACTER SET instead. (WL #13146)
• The character sets listed here, along with all of their collations, are now deprecated, and subject to
removal in a subsequent release of MySQL:
• ucs2
• dec
• hp8
The use of any of these character sets or their collations in SQL statements or elsewhere in the
MySQL server now produces a deprecation warning.
You should use utf8mb4 instead of any of the character sets just listed. See also The ucs2
Character Set (UCS-2 Unicode Encoding), West European Character Sets, and Central European
Character Sets. (WL #13594, WL #13595, WL #13596, WL #13597)
81
MySQL 8.0 Release Notes
read_only could also disable super_read_only if needed, but because the code was separate,
the Event Scheduler was not restarted. (Bug #33539082)
• MATCH() appears in the SELECT list, GROUP BY clause, HAVING clause, or ORDER BY clause.
Any such queries are now rejected with ER_FULLTEXT_WITH_ROLLUP. (The use of MATCH() with a
rollup column in the WHERE clause is not affected by this change, and is still permitted.)
For more information, see Full-Text Search Functions. (Bug #32565923, Bug #32996762, WL
#14697)
Previous to implementing single preparation of prepared statements in MySQL 8.0.22, TIME values
were returned in such cases; before this was done, values used as arguments and their types
were used to determine the result type of certain temporal functions at resolution time, such as
DATE_ADD(), DATE_SUB(), and ADDTIME(). Afterwards, user variable references and dynamic
parameters are considered constant for the lifetime of one execution only, requiring that the return
type be determined in another fashion, in this case from the function type. For example, the default
resolved type for DATE_ADD() was deemed to be DATETIME if the first argument was a dynamic
parameter, since DATETIME accomodates all temporal values and thus an implicit reprepare can be
avoided.
The change just described represents a regression; the problem is better solved by deriving a
more precise resolved data type, and performing a reprepare only if that does not match the actual
value of the parameter. (Such functionality was already in use in the MySQL server for numeric
parameters.) This solution is implemented by this fix.
We now parse string and numeric values when temporal values are expected. When a valid temporal
value is found, the value is converted. This fix also improves determination of resolved data types for
temporal functions.
With this fix, the DATE_ADD() and DATE_SUB() functions (and their synonyms functions
ADDDATE() and SUBDATE()) resolve types as follows:
• If the first argument is a dynamic parameter, its resolved type is DATE if the second argument is an
interval that contains some combination of YEAR, MONTH, or DAY values only; otherwise, its type is
DATETIME.
• If the first argument is resolved as DATETIME, the resolved type of the function is also DATETIME.
• If the first argument is a DATE, the resolved type of the function is also DATE, unless the interval
argument uses HOUR, MINUTE, or SECOND, in which case it is DATETIME.
82
MySQL 8.0 Release Notes
• If the first argument is a TIME value, the resolved type is also TIME, unless the interval argument
uses any of YEAR, MONTH, or DAY, in which case the resolved type of the function is DATETIME.
If none of the preceding conditions are met, the function is resolved as VARCHAR (as in MySQL
8.0.21 and earlier).
• If the first argument is a dynamic parameter, the resolved type is TIME, rather than DATETIME.
• Otherwise, the resolved type of the function is derived from the resolved type of the first argument.
In addition, for DATE_ADD() and DATE_SUB(), if the resolved type of the first argument is DATE,
and a DATETIME value is provided, the statement is reprepared so that the function has the resolved
type DATETIME. Behavior is unchanged when a TIME value is provided.
For ADDTIME() and SUBTIME(), there are no forced reprepares. (Bug #103781, Bug #32915973,
Bug #33477883, Bug #33539844)
• Previously, loadable functions and stored functions shared the same namespace and could not
have the same name. A subsequent implementation change eliminated the reason to share the
same namespace and permitted a stored function to be created with the same name as an existing
loadable function. To invoke the stored function, it is necessary to qualify it with a schema name.
The server now generates a warning if the stored function name collides with an existing loadable
function name. (Bug #33301931)
• Queries making use of the MBRContains() function did not employ all available spatial indexes.
(Bug #32975221)
• The FORMAT() function returned a formatted number without showing the thousands separator
and grouping between separators when either the es_ES or es_MX locale was specified. (Bug
#31374305)
• The result length of the GROUP_CONCAT() function was wrong when the value of
group_concat_max_len was increased. With a small group_concat_max_len value, the result
was correct. This issue was caused by arithmetic overflow.
Our thanks to Hope Lee for the contribution. (Bug #105380, Bug #33521497)
Optimizer Notes
• For a query, a range scan can be picked first and the optimizer decide that the same range scan
can be used to skip ordering. In some cases, when the requested order is not the same as the index
order, a reverse index scan is required. If the requested ordering is on the key part that is not already
used by the range scan, we update the number of used key parts for the range scan to reflect the
change. The issue occurred because the key part information was not also updated, and when it was
necessary to access key part information based on the number of key parts used.
We also now note when a reverse scan uses extended key parts, and set the correct flags for
evaluation accordingly. (Bug #33615893)
• In both optimizer trace and EXPLAIN FORMAT=TREE output, date ranges were printed as binary.
Now in such cases we print temporal values as quoted strings. (Bug #33335079)
• When a condition was pushed down, the result of evaluating assignments to user variables in the
SELECT list of the subquery were sometimes affected. For this reason, we now prevent condition
pushdown for statements with assignments to user variables.
83
MySQL 8.0 Release Notes
Our thanks to Casa Zhang and the Tencent team for the contribution. (Bug #104918, Bug
#33341080)
• When the join buffer was set to certain arbitrary sizes, the number of chunk files created for hash
joins was too small. This meant that each file contained more rows than could fit in the join buffer,
so that the probe chunks needed to be read multiple times. This was caused by using integer
division when computing how many chunk files are needed; we fix this by using floating-point division
instead.
Our thanks to Øystein Grøvlen for the contribution. (Bug #104186, Bug #33073354)
• A query using aggregation on a BIT type could return different results depending on the indexes
or join type employed. This was due to the fact that a DML statement using such an aggregation
caches the BIT values using an integer type, and later looks up and converts to a string format for
output. The current issue arose because this lookup treated the BIT value as an integer, resulting in
an incorrect string value.
This is fixed by adding a new internal class for cached BIT values which can convert bit values to
string formats correctly.
Our thanks to Hope Lee for the contribution. (Bug #100859, Bug #31894023)
• When a DML statement containing an outer DISTINCT query with a subquery inside a HAVING
clause, the inner subquery attempts to use a column reference for a column from the outer
DISTINCT query, but this should be allowed only if the subquery is used somewhere outside of the
HAVING, or if the outer SELECT does not use grouping. The current issue came about because such
a query was allowed to run even though neither of these conditions were met.
To fix this, the column reference check is expanded to detect an invalid column reference of this sort,
and to return an error if it does.
Our thanks to Song Zhibai for the contribution. (Bug #97742, Bug #30617496)
Packaging Notes
• The GnuPG build key used to sign MySQL downloadable packages has been updated. The previous
GnuPG build key is set to expire on 2022-02-16. For information about verifying the integrity and
authenticity of MySQL downloadable packages using GnuPG signature checking, or to obtain a copy
of our public GnuPG build key, see Signature Checking Using GnuPG.
Due to the GnuPG key update, systems configured to use repo.mysql.com may report a signature
verification error when upgrading to MySQL 5.7.37 and higher or to MySQL 8.0.28 and higher using
apt or yum. Use one of the following methods to resolve this issue:
1. Manually reinstall the MySQL APT or YUM repository setup package from https://dev.mysql.com/
downloads/.
2. Download the MySQL GnuPG public key and add it your system GPG keyring.
• For MySQL APT repository instructions, see Appendix A: Adding and Configuring the MySQL
APT Repository Manually.
• For MySQL YUM repository instructions, see Upgrading MySQL with the MySQL Yum
Repository.
(Bug #33587308)
• The bundled libedit library was upgraded to version 20210910-3.1. (Bug #33568767)
84
MySQL 8.0 Release Notes
• events_statements_current
• events_statements_history
• events_statements_history_long
CPU_TIME is the time spent on CPU for the current thread, expressed in picoseconds.
• events_statements_summary_by_thread_by_event_name
• events_statements_summary_by_account_by_event_name
• events_statements_summary_by_user_by_event_name
• events_statements_summary_by_host_by_event_name
• events_statements_summary_global_by_event_name
• events_statements_summary_by_digest
• events_statements_summary_by_program
• prepared_statements_instances
SUM_CPU_TIME is the CPU time spent on the current thread, expressed in picoseconds, for
the corresponding aggregations.
• statement_analysis
• user_summary_by_statement_type
• user_summary_by_statement_latency
• host_summary_by_statement_type
85
MySQL 8.0 Release Notes
• host_summary_by_statement_latency
• processlist
• session
CPU latency is the CPU time spent on the current thread, expressed in human-readable form.
• x$statement_analysis
• x$user_summary_by_statement_type
• x$host_summary_by_statement_type
• x$processlist
• x$session
• x$user_summary_by_statement_latency
• x$host_summary_by_statement_latency
CPU latency is the CPU time spent on the current thread, expressed in picoseconds.
Our thanks to Facebook for their contribution to this fix. (Bug #32202060, Bug #101764, WL #14779)
In order to use a large number of windows, it may be necessary to increase the value of the
thread_stack server system variable. (Bug #33279604)
• InnoDB: InnoDB now supports ALTER TABLE ... RENAME COLUMN operations using
ALGORITHM=INSTANT.
Operations that support ALGORITHM=INSTANT only modify metadata in the data dictionary.
Table data is unaffected, making the operations instantaneous. If not specified explicitly,
ALGORITHM=INSTANT is used by default by DDL operations that support it.
For more information about this and other DDL operations that support ALGORITHM=INSTANT, see
Online DDL Operations. (WL #14785)
• It is theoretically possible for a user with sufficient permissions using MySQL Enterprise Audit
to mistakenly create an “abort” item in the audit log filter that prevents themselves and other
administrators from accessing the system. From MySQL 8.0.28, the AUDIT_ABORT_EXEMPT
privilege is available to permit a user account’s queries to always be executed even if an “abort” item
would block them. Accounts with this privilege can therefore be used to regain access to a system
following an audit misconfiguration. The query is still logged in the audit log, but instead of being
rejected, it is permitted due to the privilege.
Accounts created in MySQL 8.0.28 or later with the SYSTEM_USER privilege have the
AUDIT_ABORT_EXEMPT privilege assigned automatically when they are created. The
AUDIT_ABORT_EXEMPT privilege is also assigned to existing accounts with the SYSTEM_USER
privilege when you carry out an upgrade procedure with MySQL 8.0.28 or later, if no existing
accounts have that privilege assigned. (WL #14670)
86
MySQL 8.0 Release Notes
• The tmp_table_size variable now defines the maximum size of individual in-memory internal
temporary tables created by the TempTable storage engine. An appropriate size limit prevents
individual queries from consuming an inordinate amount global TempTable resources. See Internal
Temporary Table Storage Engine. (WL #14647)
• The innodb_open_files variable, which defines the number of files InnoDB can have open at
one time, can now be set at runtime using a SELECT innodb_set_open_files_limit(N)
statement. The statement executes a stored procedure that sets the new limit.
To prevent non-LRU manged files from consuming the entire innodb_open_files limit, non-LRU
managed files are now limited to 90 percent of the innodb_open_files limit, which reserves 10
percent of the innodb_open_files limit for LRU managed files.
The innodb_open_files limit now includes temporary tablespace files, which were not counted
toward the limit previously. (WL #14591)
In addition, on compatible platforms, CONVERT_TZ() now performs time zone conversion beyond
2038, up to '3001-01-18 23:59:59.999999' UTC. If the datetime argument exceeds this value,
the argument is returned unchanged. This “no-op” behavior is the same as previously with values
beyond '2038-01-19 03:14:07.999999' UTC.
The behavior of the TIMESTAMP type is also unaffected by this change; its maximum allowed value
remains '2038-01-19 03:14:07.999999' UTC, regardless of platform. For dates futureward of
this, use the MySQL DATETIME type instead. (WL #14630)
• This release introduces monitoring and limiting of memory allocation on a global and per-user
basis. You can now observe the total memory consumed by all user connections by checking the
value of the Global_connection_memory status variable, which must be enabled by setting
global_connection_memory_tracking = 1.
The total includes memory used by system processes, or by the MySQL root user, although these
users are not subject to disconnection due to memory usage.
Memory used by the InnoDB buffer pool is not included in the total.
You can control indirectly how often the status variable is updated by adjusting
connection_memory_chunk_size; Global_connection_memory is updated only when the
total memory usage varies by more than this amount.
You can specify limits on resource consumption per user connection by setting
connection_memory_limit; any user whose memory usage exceeds this amount
cannot issue additional queries. You can also impose a global memory limit by setting
global_connection_memory_limit. Whenever Global_connection_memory exceeds the
global limit, no regular users can issue new queries requiring memory usage. System users such as
MySQL root are not bound by these limits. (WL #13458)
87
MySQL 8.0 Release Notes
Bugs Fixed
• InnoDB: The minimum I/O buffer size calculated during an index creation operation did not align with
the I/O block size, permitting a record to exceed the buffer boundary. (Bug #33570629)
• InnoDB: The ut::make_unique library function in the InnoDB sources now permits specifying the
type of field allocated. (Bug #33538461)
• InnoDB: A Performance Schema instrumentation was added for tracking redo log buffer memory
allocations. (Bug #33527660)
• InnoDB: Warnings printed to the error log for long semaphore waits did not provide information
about the latch owner. (Bug #33509386)
• InnoDB: A latch release and reacquisition mechanism was introduced to reduce the amount of time
that threads spend in critical sections protected by a global lock system latch. (Bug #33502610, Bug
#33563523)
• InnoDB: A hole punch operation on Windows caused a failure. The operation was performed as an
overlapped (asynchronous) operation, which requires a OVERLAPPED structure containing a handle
to an event object. The OVERLAPPED structure was not provided. (Bug #33496778)
• InnoDB: The ut_time() infrastructure in the InnoDB sources was replaced with a type-checked
standard library implementation. (Bug #33460092)
• InnoDB: Numerous Trying to access missing tablespace errors were printed to the error
log following a restore operation. (Bug #33437625)
• InnoDB: The buf_validate() function in the InnoDB sources was optimized, improving
performance on debug builds.
• InnoDB: On a NUMA-enabled system, the page size of memory chunks allocated to the buffer pool
did not align with the system page size in certain scenarios, causing in the following error: Failed
to set NUMA memory policy of buffer pool page frames to MPOL_INTERLEAVE.
(Bug #33406701)
• InnoDB: Two instances of std::unique_ptr with mem_heap in the InnoDB sources now use the
Scoped_heap() wrapper, which uses a stateless function object instead of a pointer to a function.
(Bug #33405520)
• InnoDB: The m_end_range flag in the prebuilt struct, which is set to true when the end of the
range is exceeded while populating the prefetch cache, was not set to false when the prefetch cache
was reset (initialized). As a result, in cases where the end of the range is not exceeded and the
handler is reused, the m_end_range flag could be set incorrectly the next time the prefect cache is
used. (Bug #33384537)
• InnoDB: Column metadata in the data dictionary was not updated when a new table ID was
assigned to a table after discarding the table's tablespace during a table import operation. (Bug
#33319149)
88
MySQL 8.0 Release Notes
• InnoDB: Setting the innodb_interpreter debug-only system variable to NULL caused a failure.
(Bug #33316661)
• InnoDB: Full-text index creation file management was improved. (Bug #33270893)
• InnoDB: An update operation that inserted a new row into a temporary table used for aggregation
caused the temporary table to be moved to disk and the update operation to be retried on the new
on-disk temporary table. A BLOB pointer in the record data prepared before the temporary table was
moved to disk was rendered stale, causing a failure. (Bug #33242407)
• InnoDB: A race condition between threads attempting to deinitialize and initialize statistics for the
same table raised and assertion failure. (Bug #33135425)
• InnoDB: Allocation of large pages is now handled by a library designed to handle this. In cases
where the large page allocation mechanism cannot be used, a fallback mechanism allocates regular
aligned pages. Fallback can occur when large page address space is exhausted, when large page
support is disabled by the underlying hardware or operating system architecture, or when large
page support in MySQL is disabled explicitly (--large-pages=0). Occurrences of ut_allocator
functions for allocation and deallocation of large pages have been replaced by the new library
functions. (Bug #33119009, Bug #33118309, Bug #33149501, Bug #32135935)
• InnoDB: Functions belonging to a new InnoDB library responsible for dynamic storage management
of suitably aligned types has replaced the functions previously used for this purpose. (Bug
#33110341)
• InnoDB: Dynamic allocation of suitably aligned types is now handled by a library which is compatible
with Performance Schema. (Bug #33110312)
• InnoDB: While a purge thread was freeing LOB pages at end of a purge batch, a required index data
structure was freed, causing a failure. (Bug #32918325)
• InnoDB: InnoDB dynamic allocation routine limitations prevented dynamic allocation of an array
of constructible types. The limitations have been addressed, permitting allocation of default
constructible types, non-default constructible types, and types that are both default and non-default
constructible. (Bug #32714047)
• InnoDB: When using READ COMMITTED or READ UNCOMMITTED, certain queries executed on
a table inside of a trigger or function prevented concurrent transactions on the same table. The
acquired locks were too restrictive. (Bug #32636792)
• InnoDB: Hole punch functionality was not working as expected for tablespace pages that were
encrypted and compressed, for most pages on Windows, and for Windows volumes that do not
implement Microsoft volume management functions. (Bug #32136255)
• InnoDB: Replacing the ut_time() infrastructure with a type-checked standard library (std)
implementation in MySQL 8.0.28 caused a performance regression. The regression was due the
time library used by std clocks, which generates system calls. Low resolution clocks are now used
instead. (Bug #107763, Bug #34352870)
89
MySQL 8.0 Release Notes
• Packaging: Added an icu-data-files RPM that was separated from the server package. This
is a package of ICU data files needed by MySQL regular expressions. (Bug #35162346)
This was caused by the result of a check for any unsafe expressions defined for a generated column
(in the internal variable thd->safe_to_cache_query), which was later checked again without
being cleared while parsing the partition expression, leading to an error even when the partition
expression did not refer to the problematic generated column expression. Now in such cases, we
reset thd->safe_to_cache_query before parsing the partition function.
• Partitioning: A query using an index other than the primary key of a partitioned table sometimes
resulted in excessive CPU load. (Bug #104576, Bug #33238010)
• Replication: A PURGE BINARY LOGS statement could be issued while the instance was locked
for backup, which contravened the rules of the backup lock by removing files from the server. The
statement now cannot be used while a LOCK INSTANCE FOR BACKUP statement is in effect. (Bug
#33437026)
• Replication: Replication stopped with an error when reading a table map event if the name of the
table or database was over 64 bytes – the limit is 64 characters, so the use of multi-byte characters
could cause this situation. The replica now no longer checks the size of the table and database
names, and supports the transmission of longer names. (Bug #33305975, Bug #104798)
• Replication: From MySQL 8.0.26, new versions of the plugins that implement semisynchronous
replication are supplied to replace the terms “master” and “slave” with “source” and “replica”.
Following this, the UNINSTALL PLUGIN statement incorrectly allowed the old versions of the
plugins, rpl_semi_sync_master and rpl_semi_sync_slave, to be uninstalled when replication
channels were currently using them. The issue has now been fixed. (Bug #33270401)
• Replication: If a replica was disconnecting while a SHOW REPLICAS statement was being issued,
the server was able to access deleted data. (Bug #33206343, Bug #104566)
90
MySQL 8.0 Release Notes
order sequence ticket generator now wraps around correctly. Thanks to Zhai Weixiang for the
contribution. (Bug #32891221, Bug #103636)
• Replication: The replication receiver thread stopped with an error if the replication source server
sent a heartbeat event containing a binary log file position that was above the 4GB offset, due to the
large size of the binary log file. A new heartbeat event (Heartbeat_log_event_v2, log event type 41)
that handles the larger value correctly has been added for use in this situation. (Bug #29913991)
• Group Replication: Group Replication could stop unexpectedly during the auto-rejoin procedure
while the Performance Schema replication group member statistics table was being checked. The
concurrency of the operations is now handled correctly. (Bug #33609089)
• Group Replication: Group Replication's selection process for a group member to be the donor
for distributed recovery involves the use of the standard random selector defined for the operating
system. If this random device was not available and an exception was thrown, the member's joining
process stopped. Group Replication now takes this possibility into account and uses a fallback
random selector if the one on the operating system returns an error. (Bug #33596124)
• Group Replication: An expelled group member using the Group Replication auto-rejoin procedure
reported its state as RECOVERING too early on, while it was still collecting information from other
group members and before the compatibility checks were complete. The state change is now carried
out while the view is being installed, which is the point where the rejoining member is actually
accepted as a group member. (Bug #33380840)
• Group Replication: Disabling the Group Replication plugin in a MySQL source distribution using
the CMake option DWITH_GROUP_REPLICATION=0 did not disable applications and tests related to
Group Replication, which caused them to build incorrectly. (Bug #33308513)
• Group Replication: The group communication engine for Group Replication (XCom, a Paxos
variant) now logs more information in the situation where the existing group members have difficulty
in communicating with a joining member, for example due to network issues. This can result in the
group remembering an old incarnation of the joining member and not allowing it to attempt to join
again. (Bug #32873315)
• Group Replication: Group Replication's Group Communication System (GCS) now differentiates
in its records of expelled members between those that had successfully joined the group, and those
that never did manage to join the group. (Bug #32630484)
91
MySQL 8.0 Release Notes
• Group Replication: A race condition occurred if the Group Replication group member statistics in
the Performance Schema were queried when Group Replication was being started or stopped. (Bug
#32392468)
• Microsoft Windows: On Windows, added missing debug and test suite binaries for MySQL Server
(commercial) and MySQL NDB Cluster (commercial and community). (Bug #32713189)
• JSON: When the first argument passed to JSON_TABLE() was a row instead of a single JSON
value, an assertion was raised while trying to evaluate the row expression. We fix this by raising an
error during function resolution if the first argument is a row, so that the row expression itself is never
evaluated. (Bug #33414235)
• Using LPAD() or RPAD() in the expression for a generated column led to corrupted indexes on the
parent table. (Bug #33661337)
• In some cases where warnings were issued, rows were missing from the results of aggregation using
a temporary table. (Bug #33603911)
• For openSUSE 15, added the libtirpc rpcgen build requirement in mysql.spec to now use TI-RPC.
(Bug #33582982)
• An UPDATE statement acting on multiple tables sometimes adds elements to a list each time it is
executed. Elements were never removed from this list, which increased the memory footprint for
each execution of the statement. We fix this by clearing the element list following execution. (Bug
#33574408)
• The size of the HOST column of the Performance Schema processlist table is increased from
VARCHAR(255) to VARCHAR(261). (Bug #33570218)
• A keyring migration failure due to an OpenSSL error raised an assertion. The SSL error state was
not flushed from the thread's OpenSSL error queue. (Bug #33546207)
• For Fedora, increased the release package version number from 1 to 10; this to help eliminate
potential installation related problems with native Fedora dnf/yum packages of the same version.
(Bug #33504443)
• Increased compat level to 11 for Debian-based packages as the previous level of 9 is deprecated;
and replaced calls to dh_systemd_enable + dh_systemd_start with dh_installsystemd to satisfy
requirements for compatibility level 10+. (Bug #33458752)
• A delete operation involving a full-text search query caused a failure. (Bug #33455243)
• An improperly handled error caused a startup failure when using the keyring_okv plugin. (Bug
#33449117)
• For virtual generated columns of type DECIMAL, we now always store some data, so that we avoid
undefined behavior when trying to convert the field buffer to a decimal value. (Bug #33424846)
• MySQL now supports pushing a condition down to a derived table when an expression from the
underlying derived table contains a variable set by a stored procedure. (Bug #33423394)
92
MySQL 8.0 Release Notes
• tls_version and admin_tls_version settings are now validated server startup. (Bug
#33390209)
• If two or more deprecated system variables were persisted using a SET PERSIST statement, when
the server was restarted, a deprecation warning was only logged for the first of the deprecated
system variables. (Bug #33388488)
• For an index range scan whose key parts are equal, the range is now shown as an equality.
For example, a = 3 is now displayed, instead of 3 <= a <= 3 previous to this change. (Bug
#33351123)
• Replaced /var/run references with /run as /var/run usage is deprecated for tmpfiles.d
configuration files. The symlink from /var/run to /run remains to keep current setups functional.
(Bug #33351110, Bug #33588618)
• Added a mapping from ICU error code U_FILE_ACCESS_ERROR to the new MySQL error code
ER_REGEXP_MISSING_FILE. (Bug #33326003)
• A failed keyring function argument validation check caused a failure. (Bug #33319782)
• The index range scan iterator did not always increment the number of rows examined as expected.
(Bug #33305632)
• The SUBSTR() function did not always correctly handle errors raised when trying to evaluate its
arguments. (Bug #33290160)
• International Components for Unicode version 67 introduced a new implementation for \X (match a
grapheme cluster), which requires locale data not currently included with MySQL.
This means that, when using the version of ICU bundled with MySQL, a query using \X raises
the error ER_REGEXP_MISSING_RESOURCE; when using ICU supplied by the system, we report
ER_WARN_REGEXP_USING_DEFAULT as a Note. (Bug #33290090)
• A full-text search query on a table stored in the BLACKHOLE storage engine where the chosen
query plan used a full-text index scan caused an error instead of returning an empty result set. (Bug
#33250020)
• The LOCK_TIME returned by the performance schema was under evaluated, missing time spent in
rows locks, and time spent when locking multiple tables. As of this release, LOCK_TIME accounts for:
• A new option \T for the mysql client prompt prints an asterisk (*) if the current session is inside a
transaction block. You can use the option with the --prompt command-line option, in a MySQL
option file, or with the MYSQL_PS1 environment variable. Thanks to Murakami Kohei for the
contribution. (Bug #33214862, Bug #104598)
• Constant subqueries in RANGE INTERVAL expressions were not always handled correctly. (Bug
#33197418)
• Decimal expressions which evaluated as NULL were not always handled correctly. (Bug #33169048)
93
MySQL 8.0 Release Notes
• A user account that was granted a MySQL role with a global SELECT privilege was denied access
to the mysql database. The user account's global privileges were not checked when the role was
granted. (Bug #33159353, Bug #104423)
• When setting up an Item_ref to a SELECT alias, its cached properties are copied (including
whether it is part of a ROLLUP expression or not). However, these might not yet be correctly
computed, so the computation should to be done first or the values could be wrong. Having the
wrong value could cause certain expressions to be materialized in an intermediate step when they
should not (because they contain ROLLUP expressions that are not ready for computation, but
having the wrong value is unknown at this point). The issue is fixed by forcing cached values to be
recomputed when an item is designated as a rollup item. (Bug #33149402, Bug #104394)
• An invalid comment string detected while upgrading a table from MySQL 5.7 to MySQL 8.0 caused
the upgrade to fail with errors that did not provide sufficient contextual information. (Bug #33148961)
• It was possible in some cases to create a generated column of type SERIAL, which is not allowed.
See Numeric Data Type Syntax, and CREATE TABLE and Generated Columns, for more information
(Bug #33141966)
• Statements which commit a transaction implicitly or explicitly are not allowed inside a trigger
or a stored function. Both CREATE TRIGGER and CREATE FUNCTION should report an error
(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG) in this case, but did not correctly handle DROP
TABLESPACE. (Bug #33141958)
• A SHOW TABLE STATUS operation raised an assertion failure when run on a table defined with a
very large AVG_ROW_LENGTH value. (Bug #33114368)
• When calculating the maximum number of rows likely to be read from a scan, the intermediate result
was a double that could become greater than the maximum allowed value for a 64-bit unsigned
integer. This triggered undefined behavior when converting the intermediate double value to an
integer, which in some cases could lead to assert failures.
We fix this by clamping the result in the range [1, UINT64_MAX]. (Bug #33066458)
• Queries using both UNION and LIMIT 0 triggered an assert failure in debug builds. (Bug
#33066455)
• Renaming an event using ALTER EVENT ... RENAME TO did not delete the Performance Schema
instrumentation for the original event. (Bug #33059358)
• An SSL handshake assertion was raised on debug builds when using the thread pool plugin. (Bug
#33012398)
• Some prepared statements using either GROUP BY WITH ROLLUP or one or more window functions
could be executed successfully only once. (Bug #33007266)
• An error occurred for statements of the form INSERT INTO view VALUE(tuple) AS
row_alias(id_list). When executing such statements, the server calls the internal function
Sql_cmd_insert_base::prepare_values_table() in order to prepare the derived table
created as a VALUES alias; this function populates Sql_cmd_insert_base.values_field_list
with Item_field objects pointing to the columns of the underlying table. When inserting into a view
rather than a table, an expected real_item() transform, needed to map from an Item_view_ref
referencing the view column to an Item_field representing the corresponding column in the
underlying table, was not performed. (Bug #32858783)
• Some multiply-nested subselects were not handled correctly, and could lead to an unplanned
shutdown of the server. (Bug #32547812)
94
MySQL 8.0 Release Notes
• Inspection of a session thread object during a SHOW PROCESSLIST operation and a concurrent
change to the thread's security context resulted in a race condition. (Bug #32320541, Bug #102052)
• In cases where there are no operations to be performed on the result of a UNION, the rows are
streamed without storing them in a temporary table, although a placeholder for the temporary table
still exists in the query block. Since this table is not instantiated, a check for estimates of the cost
of reading the rows from the table while calculating the access cost and optimizing for range based
access had unpredictable results.
We fix this by skipping retrieval of such row estimates in the case of an uninstantiated temporary
table. (Bug #32255904)
• A multi-table DELETE statement using common table expressions was not always handled correctly.
(Bug #32238558)
• SSL-related code was revised to avoid a potential memory leak. (Bug #31933295)
• In some cases, multiple-table UPDATE statements could block concurrent access. (Bug #31731752)
• Keyring system variables that use an internal slot for complex settings no longer accept a setting of
DEFAULT. (Bug #30879700)
• The Timestamp column in the mysql.tables_priv and myql.columns_priv grant tables was
set to a zero timestamp value ("0000-00-00 00:00:00") for GRANT and REVOKE operations,
preventing a logical restore of the grant tables. As of MySQL 8.0.28, a valid start time value is written
to the Timestamp column.
If you have existing grant table records with zero timestamp values that are preventing a logical
restore of the grant tables, a workaround is to update records in the grant tables or in the dump files,
replacing zero timestamp values with CURRENT_TIMESTAMP.
Thanks to Venkatesh Prasad Venugopal for the contribution. (Bug #30863899, Bug #98495)
• Producing a per-table dump using mysqldump in MySQL 5.7 and 8.0 requires a longer execution
time compared to MySQL 5.6. This is because the information_schema.files table, which is
queried for information on log file groups by mysqldump, contains information about InnoDB data
files as well as NDB data files from MySQL 5.7. In MySQL 8.0, the issue has been fixed by rewriting
the query to select only the appropriate data files. In MySQL 5.7, Information Schema tables do not
have indexes, so a full table scan is still required. (Bug #29210990, Bug #93875)
• Incorrect values for FORCE INDEX FOR GROUP BY could be set while saving and restoring the
presence of FORCE INDEX hints within tables. (Bug #105694, Bug #33604416)
• If a query with the sql_buffer_result system variable enabled returned just one row, and
an attempt was made to insert the result into a table, then an error in setting the output from the
temporary table could produce a data exception. (Bug #105351, Bug #33515752)
• Resetting of the active slice was not performed in WindowIterator::Read() at the end the end of
the input result set for windowing. This led to reading wrong values on reaching the ORDER BY sort,
since the number of the active slice was still set to 1—that is, to the items being read from the input
95
MySQL 8.0 Release Notes
table—while the ORDER BY sorting stage needs to read the values after computation of any window
functions. For this, it needs the active slice to be that of the last window's output table.
We fix this by moving the resetting of the slice to the output slice immediately following the read,
so that it is already set correctly when returning at the end of the input set and moving on to the
ordering.
Our thanks to Casa Zhang and the Tencent team for the contribution. (Bug #105045, Bug
#33399696)
• When executing prepared statements that activated a trigger created with the DEFINER clause (or a
stored function), invoker privileges were used for checking table access instead of definer privileges.
This, in turn, could cause privilege checks on tables used by the trigger or stored function to fail.
(Bug #104168, Bug #33064461)
This fix accumulates the frequency with an integer type instead, to avoid intermediate floating-point
errors.
Our thanks to Casa Zhang and the Tencent team for the contribution. (Bug #104108, Bug
#33045336)
• Multi-valued indexes were not used for queries executed from within stored functions. (Bug #102359,
Bug #32427727)
• An error occurred for an SQL statement having the form shown here:
INSERT INTO target_table
SELECT aggregate_expression, non_aggregate_expression
FROM empty_table;
This happened when the query plan used aggregation from a temporary table, and when
non_aggregate_expression was constant during one execution of the query, but could vary
between executions. Such an expression might, for example, include a function such as NOW() or
USER(). This resulted in the temporary table getting a column for non_aggregate_expression,
which is unnecessary, since all rows have the same value. In addition, if there were no rows, there
was no legal value to insert into target_table, which is what actually triggered the error.
We fix this by not using a temporary table column when non_aggregate_expression is const
for the current execution. (Bug #102252, Bug #32384355, Bug #33546083)
• When executing a prepared statement that included values passed in as strings, MySQL attempted
to parse them as integers and could return an error unrelated to the input value.
After a recent change, dynamic parameter handling was refactored so that the derived data type
for parameters was determined based on context. For example, in a comparison such as int_col
= ?, the parameter was given the same type as the (integer) column it was compared to. To
96
MySQL 8.0 Release Notes
preserve compatibility with existing MySQL applications, if a decimal or float value was supplied as
parameter, the statement was automatically reprepared with new type assigned to the parameter
based on the actual value. This handling preserved compatibility for numeric parameters.
However, if a string parameter was supplied, it was still interpreted as an integer (the resolved data
type) and this behavior was not compatible with older MySQL versions that detected the actual type
of the value. The consequences being that if int_col = ? is executed with the parameter value
'1.7', only the integer part of the string was used, making the effective comparison int_col = 1.
To fix the issue, now when a string parameter is supplied, the parameter is analyzed to determine
if it is an integer, a decimal, or a float value and the actual data type of the parameter is updated
accordingly. Later, the actual type is compared to the resolved type and if it is incompatible, the
statement is reprepared with the new actual type. So, the previous statement now evaluates as
int_col = 1.7 and the comparison evaluates using decimal numbers. (Bug #101806, Bug
#32213576, Bug #103364, Bug #32787037)
• Authentication Notes
• Compilation Notes
• Firewall Notes
• Keyring Notes
• Optimizer Notes
• Pluggable Authentication
• Security Notes
• Server Administration
• Bugs Fixed
97
MySQL 8.0 Release Notes
Authentication Notes
• Previously, MySQL user accounts authenticated to the server using a single authentication method.
MySQL now supports multifactor authentication (MFA), which makes it possible to create accounts
that have up to three authentication methods. MFA support entails these changes:
• CREATE USER and ALTER USER syntax has been extended to permit specification of multiple
authentication methods.
In addition, MySQL Enterprise Edition now supports authentication to MySQL Server using devices
such as smart cards, security keys, and biometric readers. This authentication method is based on
the Fast Identity Online (FIDO) standard, and uses a pair of plugins, authentication_fido on
the server side and authentication_fido_client on the client side. The server-side FIDO
authentication plugin is included only in MySQL Enterprise Edition distributions.
Multifactor authentication can use existing MySQL authentication methods, the new FIDO
authentication method, or a combination of both. For more information, see Multifactor
Authentication, and FIDO Pluggable Authentication. (Bug #33159968, WL #14183)
• In cases where an authentication plugin performed no hashing of the authentication string, CREATE
USER statements with a BY 'auth_string' clause failed with an error. (Bug #33125289)
In addition, error checking in several geometry functions has been improved. (Bug #33290245)
• The gen_dictionary() function now takes latin1 as the character set of its argument, and
returns the same character set. (Bug #30389649)
• Otherwise identical strings, using, respectively, the ASCII (collation ascii_general_ci) and UCS2
(collation ucs2_general_ci) character sets did not match as expected in join conditions. (Bug
#104571, Bug #33204161)
References: See also: Bug #24847620, Bug #30746908, Bug #32244631, Bug #32501472.
• Given the default collation c1 of a character set cs, and a different collation c2 (that is, not equal to
c1), then the statement CREATE DATABASE d COLLATE c2 CHARACTER SET cs created a new
database with the default collation set to c1 instead of c2. (Bug #104504, Bug #33183590)
Compilation Notes
• InnoDB: A workaround was implemented for a Clang issue that causes a build failure on Windows
(Bugzilla – Bug 51538). (Bug #33217633)
• MySQL now can be compiled using C++17. The following minimum version requirements apply for
compiler support:
98
MySQL 8.0 Release Notes
• XCode 10 (macOS)
• GCC 10 (Solaris)
In particular, on Solaris, GCC is now the only supported compiler. The code has been cleaned up to
remove adaptations and workarounds for Sun Studio, Oracle Studio, and SunPro. (Bug #32907274,
Bug #103757, Bug #32907475, Bug #32992125, Bug #32992242, Bug #33004840, Bug #33086882)
• Important Change: The BINARY operator is now deprecated, and subject to removal in a future
release of MySQL. Use of BINARY now causes a warning. Use CAST(... AS BINARY) instead.
(WL #13619)
Firewall Notes
• The new FIREWALL_EXEMPT privilege exempts a user from firewall restrictions. This is useful, for
example, for any database administrator who configures the firewall, to avoid the possibility of a
misconfiguration causing even the administrator to be locked out and unable to execute statements.
See MySQL Enterprise Firewall. (WL #14517)
• Function arguments were not always evaluated correctly during resolution of functions defined within
views. (Bug #33142010)
• Bit functions in window expressions assert that the runtime size of a bit mask is not bigger than its
resolve time size. We found several violations of this rule, listed here:
99
MySQL 8.0 Release Notes
• During resolution of REPLACE(str, from_str, to_str) we assumed that the entire length
of from_str would be replaced for each match in str, but since from_str may be only 1
character long, it is possible for str to be replaced with multiple copies of to_str.
• COMPRESS() computed the maximum result length in an arbitrary fashion. Now we use
compressBound from the zlib library instead.
Keyring Notes
• Diagnostics for keyring_hashicorp plugin configuration issues have been improved. (Bug
#32075854)
Optimizer Notes
• EXPLAIN FORMAT=TREE now shows more precise information than displayed previously about
scans generated by the range optimizer. In particular, sub-iterators are now displayed explicitly,
and are properly timed with EXPLAIN ANALYZE; index range scans now show the actual ranges
being scanned. Descriptions in the output are also more user-friendly than before; for example,
index_for_group_by shown for a query using DISTINCT is replaced by index skip scan
for deduplication.
In addition, a roundoff error causing inaccuracies in row count estimation for read over range
intersection scans has been corrected, and optimizer traces for index range scans now correctly
displays implicit key parts from InnoDB primary keys when they are used. (Bug #33037007, Bug
#33062448)
• When transforming EXISTS to a semijoin, and when the query contained a view reference, the query
was not processed correctly. (Bug #32813550)
• In the case of a lateral derived table, if the creation of the cache invalidator was delayed, the table
materialization was emitted without the invalidator, which kept rematerialization from occurring during
execution and led to wrong results.
The pending cache invalidator was emitted only when the index of the lateral table was less than that
of the last table in the table list being considered. When the table index of the pending invalidator
was equal to the last table of the join slice, the cache invalidator was skipped and the materialization
was emitted without the invalidator.
We fix this by creating the pending cache invalidator if the table index of the pending invalidator is
less than or equal to that of the last table in the table list of the current join slice. (Bug #32407774)
100
MySQL 8.0 Release Notes
Pluggable Authentication
• Microsoft Windows: The Kerberos authentication method added in MySQL 8.0.26 for MySQL
server and client hosts running Linux is now supported on the client side for Windows. This enables
MySQL client applications running on Windows to connect to MySQL accounts on Linux server hosts
that authenticate using Kerberos. For details, see Kerberos Pluggable Authentication. (WL #14605)
Security Notes
• For platforms on which OpenSSL libraries are bundled, the linked OpenSSL library for MySQL
Server has been updated to version 1.1.1l. Issues fixed in the new OpenSSL version are described
at https://www.openssl.org/news/cl111.txt and at http://www.openssl.org/news/vulnerabilities.html.
(Bug #33273138, Bug #33309871)
Server Administration
• Setting the session value of the following system variables is now a restricted operation and the
session user must have privileges sufficient to set restricted session variables:
• low_priority_updates
• max_delayed_threads
• max_error_count
• min_examined_row_limit
• preload_buffer_size
• select_into_buffer_size
• select_into_disk_sync_delay
• show_old_temporals
For information about the privileges required to set restricted session variables, see System Variable
Privileges. (WL #14695)
101
MySQL 8.0 Release Notes
Previously, the timeout value defaulted to 31536000 seconds (365 days), which did not help in
situations such as those just described. The new default value is 300 seconds, so that Group
Replication components are stopped after 5 minutes if the situation is not resolved before that time,
allowing the member to be restarted and to rejoin. (WL #14245)
• Replication: When GTID-based replication is in use on a replica server, the replication applier and
receiver threads still track and have some dependencies on binary log file names and file positions,
as used for the alternative binary log file position based replication. A new option for the CHANGE
REPLICATION SOURCE TO statement, GTID_ONLY, removes the persistence of file names and file
positions from the replication metadata repositories. For replication channels with this setting, in-
memory file positions are still tracked, and file positions can still be observed for debugging purposes
in error messages and through interfaces such as SHOW REPLICA STATUS statements (where they
are shown as being invalid if they are out of date). However, the writes and reads required to persist
and check the file positions are avoided in situations where GTID-based replication does not actually
require them, including the transaction queuing and application process. The GTID_ONLY setting
also means that the replication metadata is flushed less frequently.
The GTID_ONLY option is disabled by default for asynchronous replication channels, but it is
enabled by default for group replication channels, and it cannot be disabled for them. To set
GTID_ONLY = 1 for a replication channel, GTIDs must be in use on the server (gtid_mode =
ON), and row-based binary logging must be in use on the source (statement-based replication is
not supported). The CHANGE REPLICATION SOURCE TO options REQUIRE_ROW_FORMAT and
SOURCE_AUTO_POSITION must each be set to 1 for the replication channel. When GTID_ONLY is
set to 1, the replica uses replica_parallel_workers=1 if that system variable is set to zero
for the server, so it is always technically a multi-threaded applier. This is because a multi-threaded
applier uses saved positions rather than the replication metadata repositories to locate the start of a
transaction that it needs to reapply.
Thanks to Facebook for offering a contribution related to this issue. (Bug #94360, Bug #29364334,
WL #7491)
• Replication: Multithreading is now enabled by default for replica servers. A multithreaded applier
has a number of applier threads that execute transactions in parallel. This behavior can avoid many
cases of unwanted replication lag that can cause temporary divergence between the source and
replicas.
The following default server settings are used to produce the multithreading behavior:
To override the new defaults and disable multithreading for a replica server, specify
replica_parallel_workers=0. This setting disables parallel execution and gives the
replica a single applier thread and no coordinator thread. When you apply this setting, the
replica_parallel_type and replica_preserve_commit_order options have no effect and
are ignored. (WL #10475)
102
MySQL 8.0 Release Notes
• Group Replication: The asynchronous connection failover mechanism for MySQL replication
now enables a replica that is part of a managed replication group to automatically reconnect to
the sender if the current receiver (the primary of the group) fails. The new feature works with
Group Replication, on a group configured in single-primary mode, where the group’s primary is a
replica that has a replication channel with SOURCE_CONNECTION_AUTO_FAILOVER set to ON. The
feature operates by default on a group in this situation, although you can disable it for the group
by disabling the new member action mysql_start_failover_channels_if_primary, using
the group_replication_disable_member_action() function. The feature is designed for a
group of senders and a group of receivers to keep synchronized with each other even when some
members are temporarily unavailable. It also synchronizes a group of receivers with one or more
senders that are not part of a managed group. A replica that is not part of a replication group cannot
use this feature.
To configure this feature, the replication channel and the replication user account and password
for the channel must be set up on all the member servers in the replication group, and on any new
joining members. You can do this using the CHANGE REPLICATION SOURCE TO statement, or if
the new servers are provisioned using MySQL’s clone functionality, this all happens automatically.
The SOURCE_CONNECTION_AUTO_FAILOVER setting for the channel is broadcast to group
members from the primary when they join, and also if it is changed. The source list is broadcast to all
members when they join or when it is updated. If the primary goes offline or into an error state, the
new primary that is selected for the group has the source list and the channel configuration already in
place, and establishes a replacement asynchronous replication connection with the source.
• Group Replication: The group communication engine for Group Replication (XCom, a Paxos
variant) defaults to using every member of the group as a leader. When the Group Replication
communication protocol version is set to 8.0.27 or later, the group communication engine can now
use a single leader to drive consensus when the group is in single-primary mode. Operating with a
single consensus leader improves performance and resilience in single-primary mode, particularly
when some of the group’s secondary members are currently unreachable.
The single consensus leader is colocated with the group’s primary, and
changes when a new primary is elected. The Performance Schema table
replication_group_communication_information shows the preferred and actual
consensus leader, or leaders if all members are used as a leader, the communication protocol
version, and the write concurrency.
Note that when you manually upgrade the members of a replication group to a new MySQL
Server release, the group's communication protocol version is not automatically upgraded
to match. If you no longer need to support members at earlier releases, you can use the
group_replication_set_communication_protocol() function to set the communication
protocol version to the new MySQL Server version to which you have upgraded the members.
MySQL InnoDB Cluster manages the communication protocol version automatically for replication
groups created using that function. (WL #9149)
103
MySQL 8.0 Release Notes
protocol means that standard methods of user authentication can be used for granting (or revoking)
access to the group in place of the allowlist, and that the latest functionality of the server's protocol
is always available on release. Network namespaces are supported for Group Replication when the
MySQL communication stack is used.
Authentication is carried out using the existing replication user account that Group Replication uses
for distributed recovery, as set using CHANGE REPLICATION SOURCE TO, and this user must
be given the new GROUP_REPLICATION_STREAM privilege. The TLS/SSL configuration for the
connection is taken from Group Replication's existing settings for securing distributed recovery, plus
the group_replication_ssl_mode system variable that specifies whether TLS/ SSL is enabled
or disabled for group communications. These settings must be configured if they are not already in
place. All these settings must be the same on all group members to avoid communication issues.
As part of this work, the default value for the performance_schema_max_cond_classes system
variable is increased from 100 to 150.
See Group Replication Requirements For The MySQL Communication Stack for more details. (WL
#9852)
• Programs that encounter issues while processing include or includedir directives in option
files now produce error messages that are more informative about the cause of the errors. (Bug
#32798288, Bug #103397)
• The default value for the thread_stack system variable has been increased to 1048576 on all
supported platforms. (Bug #103912, Bug #32965326)
• A default time zone can now be set for a server by using the server option --default-time-zone
while starting a MySQL Server Docker container. Before, the container failed to start if the option was
used. (WL #14703)
• For online DDL operations, storage is usually the bottleneck. To address this issue, CPU utilization
and index building has been improved. Indexes can now be built simultaneously instead of serially.
Memory management has also been tightened to respect memory configuration limits set by the
user. See Configuring Parallel Threads for Online DDL Operations.
The new innodb_ddl_threads variable defines the maximum number of parallel threads for the
sort and build phases of index creation.
The new innodb_ddl_buffer_size variable defines the maximum buffer size for DDL operations.
The default setting is 1048576 bytes (approximately 1 MB). Defining a buffer size limit avoids
potential out of memory errors for online DDL operations that create or rebuild secondary indexes.
See Online DDL Memory Management. (WL #14283)
• The clone plugin now permits concurrent DDL operations on the donor MySQL Server instance while
a cloning operation is in progress. Previously, a backup lock was held during the cloning operation,
preventing concurrent DDL on the donor. To revert to the previous behavior of blocking concurrent
DDL on the donor during a clone operation, enable the clone_block_ddl variable. See Cloning
and Concurrent DDL. (WL #9683)
• Setting a session value for the internal_tmp_mem_storage_engine variable now requires the
SESSION_VARIABLES_ADMIN or SYSTEM_VARIABLES_ADMIN privilege. (WL #14728)
104
MySQL 8.0 Release Notes
Bugs Fixed
• Incompatible Change: For all SELECT statements on a view, the query digest was based on the
view definition. As a result, different queries had the same digest and aggregated together in the
Performance Schema table events_statements_summary_by_digest, so statistics in that table
were not usable for distinguishing distinct SELECT statements.
The query digest for each SELECT statement on a view now is based on the SELECT,
not the view definition. This enables distinguishing distinct SELECT statements in the
events_statements_summary_by_digest table. However, tools that use query digests may
need some adjustment to account for this change. For example, MySQL Enterprise Firewall and
query rewrite plugins rely on query digests and existing rules for them that are associated with views
may need to be updated. (Bug #27540213, Bug #89559, Bug #31761802)
• Important Change: EXPLAIN FORMAT=TREE now shows whether an index scan uses a covering
index, and thus does not need to look up other columns from the table/clustered index. For example,
if idx1 is a covering index, the old output Index scan on t1 using idx1 is now shown as
Covering index scan on t1 using idx1. Previously, this information was shown only for
FORMAT=TRADITIONAL and FORMAT=JSON.
This fix also improves the wording used for full-text search to align with this change. For example,
the old output Indexed full text search on t1 (which was the same in both the covering
and non-covering cases) is now Full-text index search on t1 when there is no covering
index, and Full-text covering index search on t1 when a covering index is used. (Bug
#32825235)
• InnoDB: An excessive number of notes were written to the error log when the
innodb_open_files limit was temporarily exceeded. (Bug #33343690)
• InnoDB: An in-place DDL operation failed to flush all modified pages. (Bug #33290335, Bug
#33238133)
• InnoDB: A parallel scan returned an incorrect partition ID when loading data into HeatWave from a
subpartitioned InnoDB table. (Bug #33276021)
• InnoDB: The unused os_event::event_iter field in the InnoDB sources was removed to
reduce memory use in the os_event structure.
• InnoDB: Truncation of an undo tablespace during use by an active transaction raised an assertion
failure. The transaction was prematurely marked as complete, permitting the truncation operation.
(Bug #33162828)
• InnoDB: When loading data into HeatWave from a partitioned table with concurrent DML modifying
the primary key, the partition ID reported in the load callback was found to be incorrect for some
records. (Bug #33139692)
• InnoDB: Each buffer pool block includes a block->lock_hash_val field. Caching of this value
was determined to be unnecessary, as it introduced unnecessary coupling of the buffer and lock
system and unnecessary memory usage. (Bug #33072415)
105
MySQL 8.0 Release Notes
• InnoDB: A query that performed an index merge with retrieval ordered by row ID raised an assertion
failure. The record buffer set up for the index merge could not be used due to the scanned table
containing a primary key with a BLOB component. A record buffer cannot be used for reading
BLOBs, which are stored outside of the record. The BLOB primary key was not detected when the
record buffer was set up, as the primary key column was not yet in the read set. Retrievals ordered
by row ID temporarily add the primary key at a later stage when needed. To address this issue,
a record buffer is no longer requested for row-ordered retrievals if the primary key has a BLOB
component. (Bug #33067554)
• InnoDB: Deleting or updating a row from a parent table initiated a cascading SET NULL operation
on the child table that set a virtual column value to NULL. The virtual column value should have been
derived from the base column value.
• InnoDB: On a system that was nearing disk capacity, an InnoDB recovery operation involving
application of file extension redo log records (MLOG_FILE_EXTEND) could cause a failure. (Bug
#33002492)
• InnoDB: Conflicting explicit locks granted on the same record raised an assertion failure. (Bug
#33000142)
• InnoDB: Freeing the first page of LOB at the end of purge batch raised an assertion failure. The
failure was due an invalid root page number. (Bug #32958624)
• InnoDB: To facilitate failure reporting and resolution, the ib::fatal() function in the InnoDB
sources was revised to include the caller's location. (Bug #32957311)
• InnoDB: Recovery on the clone recipient server failed with the following error: Error reading
encryption for innodb_undo_007. The encryption key was not written to encrypted spaces
created during the page copy phase of the clone operation. (Bug #32950216)
• InnoDB: InnoDB CRC32 checksum algorithm implementations have now been optimized for use
with ARM and x86/x64 architectures. (Bug #32887066)
• InnoDB: Startup on an instance with thousands of tables took an excessive amount of time due a
large amount of traffic on the error logging subsystem. (Bug #32846656)
• InnoDB: The INFORMATION_SCHEMA.FILES view did not show the current path of the
temporary tablespace file, and the file name shown was different from the one defined by the
innodb_temp_data_file_path variable. (Bug #32840635, Bug #103553)
• InnoDB: On Windows, keeping a file open without a shared write lock while attempting to acquire the
fil_shard mutex caused a deadlock with another thread that had acquired the fil_shard mutex
and was attempting to access the same file. (Bug #32808809)
• InnoDB: Starting a MySQL Server instance using the same InnoDB data files as an another running
MySQL Server instance resulted in an initialization failure. (Bug #32777654, Bug #103338)
• InnoDB: The InnoDB recovery process did not recognize that page compression had been applied
to data that was being recovered, causing the tablespace data file to increase in size during the redo
log apply phase, which could lead to a recovery failure for systems approaching a disk-full state.
(Bug #32771259)
• InnoDB: An assert that traversed a list of file segments which were not full to calculate the number
of used pages for comparison with the number of used pages tracked by a field in the file segment
inode failed sporadically. (Bug #31685095)
106
MySQL 8.0 Release Notes
• InnoDB: A transaction failed to roll back when the server was restarted after failure occurred during
an online DDL operation. Table locks could not be resurrected for the uncommitted transaction and
the data dictionary table object could not be loaded for the affected table.
Thanks to Shaohua Wang for the contribution. (Bug #31131530, Bug #99174)
• InnoDB: A query that used a temporary table for aggregation exhausted the memory available to
the TempTable storage engine, causing an update operation to fail with a table is full error. (Bug
#31117893, Bug #99100)
• Replication: The replication applier (SQL) thread overrode retryable errors (such as deadlocks
and wait timeouts) from storage engines with a key not found error, causing replication to stop
without retrying the transaction. These errors are no longer overridden. (Bug #33107663)
• Replication: An assertion was raised if a replica MySQL Server instance with unpopulated time
zones attempted to replicate a statement that set a time zone value that was unknown to the replica.
Replicas now handle this situation correctly. (Bug #32986721)
• Replication: The error messages issued by MySQL Replication when GTIDs required for auto-
positioning have been purged could be incorrectly assigned or scrambled in some situations. (Bug
#32965864)
• Replication: If a group member was elected as the primary right before or while it was shutting
down, the shutdown process hung while waiting on the primary election process, which was
attempting to make the server leave the group since the election had failed due to the shutdown.
The error handling process for primary elections now takes this into account, and does not take any
further actions if the member is already leaving the group. (Bug #32884709)
• Replication: In some situations, a replica that used connection compression was not able to re-
establish a lost connection to the source server. The issue has now been fixed. (Bug #32494609)
• Group Replication: During the Group Replication auto-rejoin procedure, a group member sets its
status to RECOVERING. If the group member does not manage to rejoin, it should change the status
to ERROR, but if a view change occurred in the meantime, it was possible for the status to remain in
RECOVERING. The member status is now set to ERROR after an unsuccessful auto-rejoin procedure,
regardless of any ongoing or stuck view changes. (Bug #33276418)
• Group Replication: Garbage collection for certification information has been moved from the Group
Replication Group Communication System (GCS) thread to a background thread, so that sending
and receiving of messages are not blocked while garbage collection is in progress. (Bug #33190276)
107
MySQL 8.0 Release Notes
Previously, DO statements had a blanket exemption from this hold, but now only DO statements
that do not use tables or loadable functions are exempt; this is the same as for SELECT. (Bug
#33130768)
• Group Replication: MySQL Server incorrectly permitted reads from Performance Schema tables
relating to Group Replication while Group Replication was stopping or restarting, and the data
concerned should not have been used. The server now checks whether Group Replication is in
OFFLINE status or uninitialized before executing the query. (Bug #33085494)
• Group Replication: A deadlock could occur when a statement referencing Access Control Lists
(ACLs), such as CREATE USER, was executed on the primary of a Group Replication group, and
a member joined the group immediately afterwards before the transaction commit was confirmed
by the other group members. The distributed recovery process needs a read lock on the ACL
cache which is locked by the ACL statement. This situation blocked Group Replication's Group
Communication System (GCS) thread until the ACL statement timed out, making the primary
unreachable and possibly preventing the new member from joining. The ACL cache lock is now no
longer required for the distributed recovery process, although the lock in the situation described
is only released after the view change is complete and the ACL statement is committed. Any new
connections or statements that require the ACL cache lock, including a member join when Group
Replication uses the MySQL communication stack, must therefore wait on this or fail and retry. (Bug
#33025231)
• Group Replication: If the thread that runs the Group Replication applier module is stopped, the
group cannot function properly because it cannot exchange group transactions and messages.
Previously, a member in this situation remained in ONLINE status and ignored the internal errors.
The member now changes to ERROR status if the thread is stopped, and takes the action specified by
group_replication_exit_state_action. (Bug #32934479)
• Group Replication: In MySQL 8.0.22 and later, a replication source server writes a TRUNCATE
TABLE statement to the binary log to notify replicas to empty a MEMORY table the first time it is used
after a server restart. Previously, the thread where the statement was logged was not registered with
the global thread manager, so Group Replication was not able to acknowledge it. The issue has now
been corrected. (Bug #32355801)
• JSON: Made additional improvements in JSON function error handling to those made in MySQL
8.0.23. (Bug #32864910)
• JSON: JSON_TABLE() allowed duplicate column names when the names differed in case only,
although column names are case-insensitive in MySQL.
Now this function compares column names in case-insensitive fashion. (Bug #102824, Bug
#32591074)
108
MySQL 8.0 Release Notes
• The MySQL client library could contribute to a memory leak if MySQL was linked against OpenSSL
1.0.1, as is the case for builds on EL6. (Bug #33335046)
• Implicitly grouped queries sometimes calculate aggregates during optimization when their values can
be easily retrieved from indexes. When a predicate referenced a column that was declared with a NO
PAD collation, that predicate might be evaluated using PAD SPACE semantics, and so return wrong
results. This was because an internal function that checked for insignificant trailing spaces made
the assumption that all nonbinary collations had PAD SPACE semantics, which was true of MySQL
5.7, but is not the case for MySQL 8.0, which has added many collations having NO PAD semantics,
including the default collation (utf8mb4_0900_ai_ci).
We fix this by explicitly checking the padding attribute of the collation in such cases. (Bug
#33282123)
• A query containing a common table expression with a MATCH() AGAINST() clause executed on a
table defined without a full-text index raised an assertion failure. (Bug #33264864)
• Several Performance Schema tables contained default timestamp values of 0 (zero) which conflicted
with the default sql_mode values NO_ZERO_IN_DATE and NO_ZERO_DATE.
For example, attempting to create a new table based on such a Performance Schema table resulted
in an error similar to the following: ERROR 1067 (42000): Invalid default value for
'FIRST_SEEN'
Default timestamp values have been removed from the following tables:
• performance_schema.events_errors_summary_by_account_by_error
• performance_schema.events_errors_summary_by_host_by_error
• performance_schema.events_errors_summary_by_thread_by_error
• performance_schema.events_errors_summary_by_user_by_error
• performance_schema.events_errors_summary_global_by_error
• performance_schema.events_statements_summary_by_digest
• performance_schema.host_cache
• performance_schema.replication_applier_filters
• performance_schema.replication_applier_global_filters
• An incorrectly type-casted variable was used when setting the --ssl-fips-mode option. (Bug
#33223230)
109
MySQL 8.0 Release Notes
• buf_resize_thread
• fts_optimize_thread
Thanks to Kaige Ye for the contribution. (Bug #33214130, Bug #104582, Bug #33214136, Bug
#104583)
• A recursive call to an internal save function led to an unexpected error. (Bug #33198164)
• The code to produce minimal TAR packages added debug symbols to the packages, which caused
larger (roughly by 10x) builds. Now DEB/RPM compiler flags are on by default for debug symbol
builds, and off by default for minimal sized release builds. (Bug #33151629, Bug #104402)
• Some multi-table DELETE statements were found to leak memory. (Bug #33151275)
• The return value for a copy function internal to the server was not handled as expected. (Bug
#33142669)
• Empty range frames were not always handled correctly. (Bug #33142418)
• In debug builds, the ALTER TABLE statement could produce an error if it added a new virtual column
with the same name as one of the columns later referred to by a foreign key. This fix now ignores
a virtual column if the name is duplicated and instead uses existing, non-virtual column names to
check conditions. (Bug #33114045)
• An assert condition to ensure that execution of a stored program instruction is started when there are
no errors did not work properly for a CASE statement in a loop. (Bug #33079184)
• In debug builds, ANALYZE TABLE with the UPDATE HISTOGRAM clause could return a non-success
value to the caller, instead of a success value, after successfully clearing the diagnostics area. (Bug
#33079073)
• The mecab_charset system status variable now reports its value as utf8mb4 rather than utf8,
which is deprecated. (Bug #33078623)
• In debug builds, MySQL Enterprise Encryption UDFs did not set the nullable flag when returning
NULL. (Bug #33077931)
• The range optimizer was sometimes called when a plan lock was in force. This caused issues since
the range optimizer can call itself, but a plan lock does not allow for recursion. (Bug #33076462)
• CAST() and DEFAULT(), when used inside stored routines, were not always handled correctly. (Bug
#33075828)
• String functions that use temporary string buffers during evaluation could lead to unexpected
shutdowns. (Bug #33073951)
110
MySQL 8.0 Release Notes
• The error message emitted after a host name failed to resolve to an IP address did not include a
meaningful errno value. Now, (-2) indicating EAI_NONAME is returned in the message instead of
(0). (Bug #33064143)
• A statement such as CREATE TABLE t SELECT 1 created an InnoDB table that was written
incorrectly to the binary log if the value of binlog_format was set to ROW and sql_mode was in
ANSI mode. As a result, replication of the statement failed with an error on the replica. Applying the
mysqlbinlog utility to such a binary log could also fail.
The atomic CREATE...SELECT was implemented by adding a new clause to CREATE TABLE called
START TRANSACTION. However, this clause was not added when ANSI mode was enabled. This
in turn caused the execution of an ordinary implicitly committed CREATE TABLE in the middle of
the transaction and produced an error in GTID mode if the transaction had an assigned GTID. The
issue is fixed by removing the SQL mode dependency from the new clause. (Bug #33064062, Bug
#104153)
• A log file containing a malformed ISO8601 timestamp was processed incorrectly. (Bug #33060440)
• String conversion warnings that previously referred to utf8 now reference utf8mb3 instead. (Bug
#33059330)
• When building MySQL from source on Unix platforms, .bz2 files are now used for Boost archive
downloads rather than .tar.gz files. (Bug #33052171)
• For Enterprise Linux 8 (and Fedora), fixed the debuginfo RPMS packages by disabling
REPRODUCIBLE_BUILD in fprofile.cmake. (Bug #33037380)
• For a query with rollup, when setting an expression as nullable because it had a grouping column,
we missed setting all expressions within that expression as nullable, doing so only for the topmost
expression. This meant that, during evaluation, a NULL generated by rollup was not always
propagated correctly. To fix this, we now set all the expressions having a grouping column as
nullable when the query uses rollup. (Bug #33036184)
• During execution of EXPLAIN, when crossing into a different query block through a streaming or
materialization node, this node was counted as the root, rather than the actual root node. (Bug
#33030136)
• The internal function find_in_group_list() did not match up match up all items correctly during
ROLLUP processing. We fix this by adding casts to GROUP BY expressions. (Bug #33022742, Bug
#33123934)
• A missing test for success of a memory allocation in the MySQL client library could lead to a client
exit. (Bug #33019026)
• An audit log function call from a prepared statement caused an error. (Bug #33016004)
• Avoid adding column names prefixed with !hidden! to ensure that new names do not collide with
names used by existing hidden columns for functional indexes. Generated hidden column names
now have the following new form that extends the use of functional indexes into environments that do
not support names generated by MD5():
!hidden!index_name!key_part_number!counter
The counter value of a generated name is zero unless a column with that name already exists in
the table. In this case, the value is incremented until the name becomes unique. (Bug #32983024)
111
MySQL 8.0 Release Notes
• Insufficient buffer space allocation during window function execution could cause an assertion to be
raised. (Bug #32975889)
• When finding the list of tables under a hash join, we did not take into account those that were also
hidden under ZERO_ROWS iterators. This could lead to NULL row flags not being set correctly,
which also caused problems when weedout wanted to save row IDs for them. (Bug #32975168)
• The gen_dictionary(), gen_range(), and gen_rnd_pan() data masking functions each could
generate the same value if executed in close temporal proximity multiple times. (Bug #32970772)
• Creation and deletion of temporary tables used in resolution of common table expressions and
having table references created within subqueries were not always managed correctly. (Bug
#32962511)
• When the -–binary-as-hex option is enabled for the mysql client, empty strings are now printed
as 0x instead of NULL. (Bug #32961656, Bug #103906)
• The resolver usually terminates the analysis and exits after encountering an error in a statement. In
the case of duplicate column analysis, the resolver continued to the end of the column list, possibly
adding multiple error messages to the diagnostics object. (Bug #32960158)
• When a scalar subquery returned multiple rows, the resulting error was not always handled correctly.
(Bug #32956779)
• Changing the server SQL mode after creating a table containing generated columns could cause
spurious messages to be written to the error log. (Bug #32954466)
• Evaluation of the values in an IN() list did not stop immediately on error, which led to assert
failures. We fix this by stopping evaluation in such cases as soon as an error has been raised. (Bug
#32942328)
• If an error was raised while evaluating a comparison of two non-nullable values as strings, the
result of the comparison was set to NULL, even though the result was non-nullable according to the
comparison operator metadata. The error was correctly returned to the user, but an assertion was
raised by this inconsistency when running in debug mode.
This is fixed by causing Arg_comparator not to set its owner to NULL when the owner is not
nullable. (Bug #32942327)
• An unset variable referenced in an SQL script executed during an upgrade operation caused a
failure. (Bug #32939819)
• Improper error propagation in filesort operations could raise an assertion. (Bug #32932969)
• In the internal WalkAndReplace() function, errors from set_cmp_func() were not correctly
propagated. (Bug #32918927, Bug #33007298)
• A deadlock could occur if a RESET REPLICA ALL statement was used while the channel
configuration was being read. (Bug #32906709)
• A potential race condition in accessing the persisted variables cache has been eliminated. (Bug
#32901419)
• The constant propagation performed by the MySQL optimizer could in some cases replace
references to a column that was not nullable with a nullable expression. When this occurred, the
112
MySQL 8.0 Release Notes
parent item of the replaced column reference could sometimes have the wrong nullability, leading
assert failures later, during execution, when a non-nullable item unexpectedly returned NULL.
We fix this by skipping constant propagation in cases where a non-nullable column reference is
replaced by a nullable expression. (Bug #32895824)
• A column name provided in a query could differ in collation details, or because the name was
provided as an expression alias in the query, and still match a column name in the dictionary. The
query output contained the column name specified in the query (for example, aaa) rather than the
column name from the dictionary (for example, AAA). (Bug #32892045)
• When the server SQL mode is other than strict mode, certain string functions return NULL to indicate
that the result is too large for the result buffer, which could lead to in inconsistent behaviour such as
incorrectly sorted output. In addition, the functions LAST_INSERT_ID() and CAST(... AS CHAR)
did not maintain nullability properly for all cases. (Bug #32864958)
• Hidden items added as part of an ORDER BY, windowing function, or a reference to a view were not
always handled correctly in implicitly grouped queries. (Bug #32863279, Bug #33079592)
• Type resolution for negation did not set the proper precision when converting the type from integer to
decimal. This is fixed by assigning the same precision as the argument. (Bug #32863037)
• Improper error propagation for failed CREATE TABLE ... SELECT statements caused rollback not
to occur. (Bug #32855882)
• When used in a subquery, a VALUES having more than one ROW() was not always handled
correctly. (Bug #32851684)
• The error packet that MySQL Server sends to a client program when the wait timeout expires
(ER_CLIENT_INTERACTION_TIMEOUT) used an incorrect sequence number of 2 instead of 0 in the
packet header when protocol compression was used. (Bug #32835205, Bug #103412)
• Concurrent insert operations on multiple tables with full-text indexes caused a large number of full-
text index synchronization requests, resulting in an out of memory condition. (Bug #32831765, Bug
#103523)
• The fix for a previous issue, following subsequent work which made it redundant and which led to
invalid results from expressions used in window functions, has been reverted. (Bug #32820802)
• In prepared statements, NULLIF() result type determination could be incorrect. (Bug #32816305,
Bug #103458)
• Creating and dropping of views within stored routines were not always handled correctly. (Bug
#32807430)
• The fix for a previous issue included a minor refactoring of how the precision and scale of a decimal
expression were determined. It later emerged that, for the TRUNCATE() function, we might end up
with a precision of zero, which is invalid.
• For legacy reasons, we can have composite access paths including Filter and Sort inside
table_path. For ease of analysis and better formatting, we move the EXPLAIN output for these
previous to the Materialize access path.
113
MySQL 8.0 Release Notes
We show here examples of an EXPLAIN statement run both prior to and following this change:
# Table created as follows:
mysql> DROP TABLE IF EXISTS t1;
Query OK, 0 rows affected (0.02 sec)
# Previous to change:
mysql> EXPLAIN FORMAT=TREE
-> SELECT * FROM ( SELECT * FROM t1 LIMIT 2 OFFSET 1 ) AS alias1
-> WHERE f1 <= ANY ( SELECT f1 FROM t1 ) ORDER BY f1\G
*************************** 1. row ***************************
EXPLAIN: -> Sort: alias1.f1
-> Filter: <nop>((alias1.f1 <= (select #3))) (cost=2.62 rows=2) [other sub-iterators not shown]
-> Table scan on alias1 (cost=2.62 rows=2)
-> Materialize (cost=0.35..0.35 rows=0)
-> Limit/Offset: 2/1 row(s) (cost=0.35 rows=0)
-> Table scan on t1 (cost=0.35 rows=1)
# Following change:
mysql> EXPLAIN FORMAT=TREE
-> SELECT * FROM ( SELECT * FROM t1 LIMIT 2 OFFSET 1 ) AS alias1
-> WHERE f1 <= ANY ( SELECT f1 FROM t1 ) ORDER BY f1\G
*************************** 1. row ***************************
EXPLAIN:
-> Sort: alias1.f1 (cost=0.35..0.35 rows=0)
-> Filter: <nop>((alias1.f1 <= (select #3))) (cost=2.62 rows=2)
-> Table scan on alias1 (cost=2.62 rows=2)
-> Materialize (cost=0.35..0.35 rows=0)
-> Limit/Offset: 2/1 row(s) (cost=0.35 rows=0)
-> Table scan on t1 (cost=0.35 rows=1)
-> Select #3 (subquery in condition; run only once)
-> Aggregate: max(t1.f1) (cost=0.45 rows=1)
-> Table scan on t1 (cost=0.35 rows=1)
After this change, the only legal access paths within table_path are TABLE_SCAN, REF,
REF_OR_NULL, EQ_REF, and ALTERNATIVE. (Bug #32788576, Bug #32915233)
• Constant folding did not always handle errors correctly when evaluating decimal expressions. (Bug
#32785804)
We fix this issue by performing setup_order() earlier, and, if the column is not found, resolution is
aborted. (Bug #32783943)
• When a query uses a temporary table for aggregation, the group by item is used as a unique
constraint on the temporary table: If the item value is already present, the row is updated; otherwise,
a new row is inserted into the temporary table. If the item has a result field or reference item, it
evaluated twice, once to check whether the result exists in the temporary table and, if not, again
while constructing the row to be inserted. When the group by item was nondeterministic, the result
114
MySQL 8.0 Release Notes
value used to check for existence differed from that with which an insert was attempted, causing the
insert to be rejected if the value already existed in the table.
We fix this by using the hash of any nondeterministic items as the unique constraint, so that the hash
is evaluated once only. (Bug #32552332)
• Privilege-checking for table-specific roles was in some contexts not restrictive enough. (Bug
#32400788)
• Inconsistencies in how certain comparison predicates were evaluated (for example, when part of
a WHERE clause) could return different results if a function was used instead of a string literal. (Bug
#32345941, Bug #102151)
• Columns of type ENUM or SET are ordered based on numeric comparison, but the comparison
function for range expressions (that is, expressions used for ordering in case of a range frame
specification) of a window function is set based on the result type of the column, which for ENUM and
SET is String. As a result, processing of rows for a window frame (to see whether a row is before
or after the frame) did not work correctly; for example, a string comparison might determine that a
row occurs before a frame, while a numeric comparison would have placed the row after.
To fix this problem, we implement integer cache items for ENUM and SET, as well as integer
comparison functions for use when ENUM or SET types are involved in range expressions. (Bug
#32328576)
• A DML statement, when accessing a subquery which had been optimized away and cleaned up, led
to an unplanned shutdown of the server. (Bug #32244822)
• When resolving columns, their names are compared in case-insensitive fashion using
utf8_general_ci, which does not always follow the same comparison rules as those for the
collation actually used for the table. Previously, when a table had in excess of 32 columns, name
lookup was performed using a hash table. Hashing is collation-aware, and so follows the collation's
comparison rules; this caused name lookup and duplication detection to be done in an inconsistent
fashion. We solve this problem by removing the hash, and performing column name resolution in the
same way in all cases regardless of the number of columns. (Bug #32169656)
• For a nullable column, when adjacent ranges were rounded off to the same value by range optimizer,
wrong results were returned. (Bug #31870920)
• Quote handling was improved for the SHOW GRANTS statement. (Bug #31716706)
• An attempt could be made to write a JSON_TABLE() expression to the optimizer trace before the
temporary table backing the table function had been created, causing an assertion to be raised. Now
when the column type is not yet available, <column type not resolved yet> is written. (Bug
#31578783)
• Validity checks for mandatory_roles system variable settings are now synchronized with validity
checks performed for GRANT role statements. (Bug #31218040)
• The query rewrite plugin failed when refreshing the rewrite rules and the table holding the rewrite
rules contained rows that had been marked as deleted, but not physically removed.
We fix this by causing the query rewrite plugin to skip the deleted rows instead of failing when it sees
them. (Bug #22654105)
• Refactoring done as part of implementing window functions in MySQL made it possible to refer to
aliases of aggregates in ORDER BY clauses but also allowed direct references to such aggregates,
115
MySQL 8.0 Release Notes
even though this should not be allowed. Now the server checks explicitly for such illegal references.
(Bug #13633829, Bug #30106081)
• In certain cases, the view reference cloned when pushing a condition down to a derived table was
not always resolved in the desired context. In addition, a check for a null condition was not performed
correctly. (Bug #104574, Bug #33209907, Bug #33197276)
• Some queries using HAVING COUNT(DISTINCT ...) did not return any rows when one was
expected. (Bug #104411, Bug #33152269)
• In views
• In prepared statements
In addition, MySQL wrongly reported impossible condition for a WHERE clause in the form f()
AND f(), where f() was any of MEMBER OF(), JSON_CONTAINS(), or JSON_OVERLAPS().
Our thanks to Yubao Liu for the contribution. (Bug #104325, Bug #104700, Bug #104721, Bug
#33123079, Bug #33268466, Bug #33275457)
References: See also: Bug #102359, Bug #32427727. This issue is a regression of: Bug #30838807.
• When NULL was passed to a user-created function that called REGEXP_INSTR(), the first invocation
of the function returned NULL as expected, but each subsequent invocation of the function also
returned NULL without regard to the value passed to it. (Bug #104239, Bug #33089668)
This is fixed by allocating the exception on the stack in such cases, instead. (Bug #104214, Bug
#33086286)
• Column names were not displayed correctly in the results of ROLLUP queries when the
subquery_to_derived optimization was enabled. (Bug #104139, Bug #33057397, Bug
#33104036)
• A stored procedure containing an IF statement using EXISTS, which acted on one or more tables
that were deleted and recreated between executions, did not execute correctly for subsequent
invocations following the first one. (Bug #103607, Bug #32855634)
• When executing a range query with multiple identical ranges joined by OR (for example, a query with
WHERE (a=1 AND b=2 AND c=3) OR (a=1 AND b=2 AND c=3)), the optimizer lost part of the
range, and so chose a query plan that was not optimal.
Our thanks to Facebook for the contribution. (Bug #102634, Bug #32523520)
• While evaluating a loose index scan as a possible option for performing grouping and finding the
minimum value, the cost calculation did not reflect the fact that the query looked at one group only,
due to the equality predicates on the grouping attributes. This resulted in examination of additional
rows since grouping is performed after reading the rows from the index.
We fix this by determining whether a query produces only one group by checking for the presence
of equality predicates on grouping attributes and using these for calculating the cost. This causes
the optimizer to pick loose index scan for such cases when doing so is found to be beneficial. (Bug
#101838, Bug #32266286)
116
MySQL 8.0 Release Notes
• When resolving integer division, the precision of the result is taken from the dividend. When the
divisor is a decimal number, it may be less than 1, which may cause the result to use more digits
than the dividend. This yielded incorrect values in some cases in which the result of integer division
was a decimal or float. (Bug #100259, Bug #31641064)
• Added an in-memory estimate to the optimizer trace to indicate how much of a given table is buffered
in the buffer pool.
Our thanks to Øystein Grøvlen for the contribution. (Bug #99993, Bug #31544522)
• The EXPLAIN output for a DML statement contains the table identifier, which normally includes the
database name, in the output of SHOW WARNINGS. For some statements such as CREATE VIEW, the
database name should be omitted, which is enforced by setting the alias_name_used flag to true
in the cached table object, but when the cached table was reused following CREATE VIEW, the flag
was not reset, which caused the database name to be omitted from the warnings following EXPLAIN
for statements run after a CREATE VIEW which access the same cached table as the view.
We fix this by ensuring that the alias_name_used flag is always set to an appropriate value during
table initialization.
Our thanks to Kaiwang Chen for the contribution. (Bug #98635, Bug #30909064)
• Authentication Notes
• Compilation Notes
• Component Notes
• Error Handling
• Firewall Notes
• Packaging Notes
• Pluggable Authentication
• Server Administration
• X Plugin Notes
• Bugs Fixed
117
MySQL 8.0 Release Notes
This is similar to what is already logged for prepared statements, for which parameter markers
appear rather than actual data values.
To perform digest logging, use audit filter definitions that replace the statement literal text by its
corresponding digest, as discussed in Replacement of Event Field Values.
Because text replacement occurs at an early auditing stage (during filtering), the choice of whether
to log statement literal text or digest values applies regardless of log format written later (that is,
whether the audit log plugin produces XML or JSON output). (Bug #31482609, WL #14267, WL
#14724)
• For MySQL Enterprise Audit, the new audit_log_max_size system variable enables audit log
file pruning based on combined log file size. To have an effect, audit_log_max_size requires
that audit_log_rotate_on_size be greater than 0. If that is true, the pruning algorithm uses
audit_log_max_size in conjunction with audit_log_prune_seconds, with nonzero values of
audit_log_max_size taking precedence over nonzero values of audit_log_prune_seconds.
For details, see Space Management of Audit Log Files. (WL #14525)
Authentication Notes
• Previously, as part of the “hello” packet sent by the server to clients, the server sent the name of the
server-side authentication plugin rather than the client-side plugin. The server now sends the client-
side name, which is more appropriate for the client's needs and may help to avoid extra protocol
round trips. (WL #14308)
Compilation Notes
• macOS: It is now possible to build MySQL for macOS 11 on ARM (that is, for Apple M1 systems).
(Bug #32386050, Bug #102259)
• Building on openSUSE 15 and SLES 15 now requires GCC 9, found in packages gcc-9 and gcc9-
c++.
Building on SLES 12 now requires GCC 10, found in packages gcc-10 and gcc10-c++.
It is also recommended to use the named GCC version when building third-party applications that
are based on the libmysqlclient C API library. (Bug #32886268, Bug #32886439)
• Building on Ubuntu 18.04 (bionic) now requires GCC 8, found in packages gcc-8 and g++-8. It
is also recommended to use GCC 8 when building third-party applications that are based on the
libmysqlclient C API library. (Bug #32877062)
• It is now possible to build MySQL on Solaris using GCC 10, which becomes the default and
recommended compiler. It is also recommended to use GCC 10 when building third-party
applications that are based on the libmysqlclient C API library. (Bug #32552988)
Component Notes
• A new component service enables server components to set system variable
values. For information about this service, see the MySQL Server Doxygen
118
MySQL 8.0 Release Notes
• If the assignment occurs during server startup, the warning appears in the error log.
• If the assignment occurs at runtime, the warning is added to the result of executing the ALTER
INSTANCE RELOAD TLS statement.
• If a client successfully connects using a deprecated TLS protocol, the server writes a warning to
the error log.
On the client side, the deprecation has no visible effect. Clients do not issue a warning if configured
to permit a deprecated TLS protocol. This includes:
• Client programs that support a --tls-version option for specifying TLS protocols for
connections to the MySQL server.
• Statements that enable replicas to specify TLS protocols for connections to the source server.
(CHANGE REPLICATION SOURCE TO has a SOURCE_TLS_VERSION option and CHANGE
MASTER TO has a MASTER_TLS_VERSION option.)
• The temptable_use_mmap variable is now deprecated and subject to removal in a future MySQL
version. (WL #14124)
• TLS support in MySQL has been moving toward a channel model using named sets of TLS
parameters that apply to different securable ports or protocols. For example, to query the state of a
particular TLS channel, use the Performance Schema tls_channel_status table:
119
MySQL 8.0 Release Notes
This makes monolithic parameters that apply to TLS support as a whole less applicable, so the
following options and system variables are now deprecated and subject to removal in a future
MySQL version:
The --ssl and --admin-ssl options are enabled by default, so it is normally unnecessary to
specify them. As an alternative to specifying those options in negated form, if it is desired to disable
encrypted connections for the main or administrative interface, set the corresponding TLS version
system variable to the empty value to indicate that no TLS versions are supported. For example,
these lines in the server my.cnf file disable encrypted connections for both interfaces:
[mysqld]
tls_version=''
admin_tls_version=''
(WL #14481)
Error Handling
• Information written to the server error log for client timeouts now includes (if available) the timeout
value, and client user and host. (Bug #31581289, Bug #100112)
Previously, if enabling super_read_only caused the Event Scheduler to stop, then after
subsequently disabling super_read_only, it was necessary to manually restart the Event
Scheduler by enabling it again. As a convenience, the server now automatically restarts the Event
Scheduler as needed when either read_only or super_read_only is disabled. (Bug #31633859)
Firewall Notes
• In MySQL 8.0.23, MySQL Enterprise Firewall implemented group profiles that each can apply to
multiple accounts, in addition to the previously implemented account profiles that each apply to a
single account. See Using MySQL Enterprise Firewall.
A group profile with a single member account is logically equivalent to an account profile for that
account, so it is possible to administer the firewall using group profiles exclusively, rather than a
mix of account and group profiles. For new firewall installations, that is accomplished by uniformly
creating new profiles as group profiles and avoiding account profiles. For upgrades from firewall
installations that already contain account profiles, MySQL Enterprise Firewall now includes a stored
procedure named sp_migrate_firewall_user_to_group() for converting account profiles to
group profiles.
Due to the greater flexibility offered by group profiles, all aspects of the firewall related to account
profiles are now deprecated and subject to removal in a future MySQL version:
120
MySQL 8.0 Release Notes
Additionally, if the server detects account profiles at startup, it writes a warning for every successfully
loaded account profile.
For information about converting account profiles to group profiles (which you should do at your
earliest convenience), see Migrating Account Profiles to Group Profiles. (WL #14174)
Packaging Notes
• Binary packages that include curl rather than linking to the system curl library have been
upgraded to use curl 7.77.0. (Bug #33077562)
• For Ubuntu packages, the AppArmor profile for mysqld was too restrictive regarding PID and socket
file names and failed for servers not using the exact names in the profile. Now the profile applies to
the directories in which the files live, enabling it to apply for different file names, and multiple servers.
(Bug #32857611)
• The dh-systemd package has been removed from Ubuntu 21.04, so the dependency on it has
been removed from MySQL packages built for that distribution. (Bug #32688072)
• For Debian packages, an EnvironmentFile directive was added to enable the systemd service to
read environmental variables from the /etc/default/mysql file if it is present. (Bug #32082863,
Bug #101363)
• Debian packages now use /run rather than /var/run for path names. (Bug #31955638)
• The bundled lz4 library was upgraded to version 1.9.3. (Bug #29747853)
• For Debian packages, the update-alternatives priority of the MySQL configuration file
was increased to ensure it replaces an existing file from a previously installed distribution. (Bug
#29606955)
Pluggable Authentication
• Linux: MySQL Enterprise Edition now supports an authentication method that enables users to
authenticate to MySQL Server using Kerberos, provided that appropriate Kerberos tickets are
available or can be obtained. It is available only on MySQL server and client hosts running Linux,
but can access Kerberos services running on non-Linux hosts. For details, see Kerberos Pluggable
Authentication.
Server Administration
• Setting the session value of the innodb_strict_mode system variable is now a restricted
operation and the session user must have privileges sufficient to set restricted session variables.
For information about the privileges required to set restricted session variables, see System Variable
Privileges. (Bug #32944980, WL #14610)
121
MySQL 8.0 Release Notes
X Plugin Notes
• When the X DevAPI Session.run_sql() method was used to execute a query that returned
multiple results, due to a caching issue, the result.columns property was not updated to reflect
the columns present in the active result, although the result.column_names property was. (Bug
#32887586)
• During an upgrade process, X Plugin logged a message stating that it was ready for connections
once the TCP port and UNIX socket had been allocated. However, connections could not actually be
accepted until after the upgrade process was complete. The message is now issued only after the
upgrade has finished. (Bug #32814997)
The following name replacements are visible in the Performance Schema tables, the process list,
and the replica status information. These changes are incompatible with earlier releases. Monitoring
tools that work with these instrumentation names might be impacted:
• Thread names, visible in the threads Performance Schema table with the prefix thread/sql/
• Thread stages, visible in the events_stages_* Performance Schema tables with the
prefix stage/sql/, and without the prefix in the threads and processlist Performance
Schema tables, the output from the SHOW PROCESSLIST statement, the Information Schema
processlist table, and the slow query log
If the incompatible changes do have an impact for you, you can set the new system variable
terminology_use_previous to BEFORE_8_0_26 to make MySQL Server use the old versions
of the names for the objects specified in the previous list. This enables monitoring tools that rely on
the old names to continue working until they can be updated to use the new names. The system
variable can be set with session scope to support individual functions, or global scope to be a default
for all new sessions. When global scope is used, the slow query log contains the old versions of the
names.
122
MySQL 8.0 Release Notes
For semisynchronous replication, you can choose whether to use the new or the old versions of the
system variables and status variables. New versions of the plugins that implement semisynchronous
replication, one for the source server and one for the replica, are supplied that replace the terms
master and slave with source and replica, and you can install these versions instead of the old ones:
• The rpl_semi_sync_master plugin (semisync_master.so library) for the source has a new
version rpl_semi_sync_source (semisync_source.so library)
• The rpl_semi_sync_slave plugin (semisync_slave.so library) for the replica has a new
version rpl_semi_sync_replica (semisync_replica.so library)
You cannot have both the new and the old version of the relevant plugin installed on an instance. If
you use the new version of the plugins, the new system variables and status variables are available
but the old ones are not. If you use the old version of the plugins, the old system variables and status
variables are available but the new ones are not.
The following internal-use items are converted to use the new terms but are not externalized to users
or monitoring tools, and MySQL Server handles any necessary resolution internally:
• Debug symbols
• User variables passed in the replication protocol handshake by the replica when it connects to a
replication source server (the replica sets both the old and the new name)
The following categories of identifiers have a new alias, and a deprecation warning is issued
when the old name is used, although the old name continues to work. Both names are
available in Performance Schema tables and status displays, and no deprecation warning
is issued when reading these. The new aliases are not affected by the new system variable
terminology_use_previous, and can still be used when it is set:
• System variables that contain the terms “master”, “slave”, or “mts”, with the exception of some that
have already been deprecated or are scheduled for deprecation, and those defined by NDB. If
these system variables are persisted using a SET PERSIST statement, both the old and the new
123
MySQL 8.0 Release Notes
name are persisted, regardless of which was specified in the statement. With a RESET PERSIST
statement, both are reset.
• Status variables that contain the terms “master”, “slave”, or “mts”, with the exception of those
defined by NDB.
• Command-line options for mysqld that contain the terms “master”, “slave”, or “mts”, with the
exception of some that have already been deprecated or are scheduled for deprecation, and those
defined by NDB.
• Command-line options for mysqladmin that contain the terms “master”, “slave”, or “mts”.
• Command-line options for mysqlbinlog that contain the terms “master”, “slave”, or “mts”.
• Command-line options for mysqldump that contain the terms “master”, “slave”, or “mts”.
The complete list of identifiers with new aliases (or in the case of semisynchronous replication,
replacements) is as follows:
• System variables:
124
MySQL 8.0 Release Notes
• rpl_semi_sync_slave_trace_level is replaced by
rpl_semi_sync_replica_trace_level
• rpl_semi_sync_master_wait_for_slave_count is replaced by
rpl_semi_sync_source_wait_for_replica_count
• rpl_semi_sync_master_trace_level is replaced by
rpl_semi_sync_source_trace_level
• rpl_semi_sync_master_wait_point is replaced by
rpl_semi_sync_source_wait_point
• Status variables:
125
MySQL 8.0 Release Notes
• Rpl_semi_sync_master_wait_sessions is replaced by
Rpl_semi_sync_source_wait_sessions
• Rpl_semi_sync_master_timefunc_failures is replaced by
Rpl_semi_sync_source_timefunc_failures
• Rpl_semi_sync_master_wait_pos_backtraverse is replaced by
Rpl_semi_sync_source_wait_pos_backtraverse
• Rpl_semi_sync_master_tx_wait_time is replaced by
Rpl_semi_sync_source_tx_wait_time
• Rpl_semi_sync_master_tx_avg_wait_time is replaced by
Rpl_semi_sync_source_tx_avg_wait_time
• Rpl_semi_sync_master_net_wait_time is replaced by
Rpl_semi_sync_source_net_wait_time
• Rpl_semi_sync_master_net_avg_wait_time is replaced by
Rpl_semi_sync_source_net_avg_wait_time
• For mysqld, the command-line versions of all the aliased and replaced system variables in the
lists above have equivalent command-line aliases or replacements, plus the following command-
line option that is not a system variable:
• For mysqladmin, the option start-slave now has the alias start-replica, and the option
stop-slave now has the alias stop-replica.
• For mysqlbinlog, the option read-from-remote-master now has the alias read-from-
remote-source.
126
MySQL 8.0 Release Notes
Thanks to Facebook for the contribution. (Bug #32312743, Bug #102044, WL #14521)
• Group Replication: For Group Replication, a group in single-primary mode can now be configured
to stay in super read-only mode, so that it only accepts replicated transactions and does not
accept any direct writes from clients. This setup means that when a group’s purpose is to provide a
secondary backup to another group for disaster tolerance, you can ensure that the secondary group
remains synchronized with the first. You can configure the group to remain in super read-only mode
when a new primary is elected, by disabling the action that normally takes place to remove that mode
on the primary.
Administrators can configure a group in this way using the new Group
Replication functions group_replication_enable_member_action() and
group_replication_disable_member_action(), which can enable and disable actions for
members of a group to take in specified situations. The functions can also be used on servers that
are not part of a group, as long as the Group Replication plugin is installed. Member actions are
configured on the primary and propagated to other group members and joining members using group
messages. Another function group_replication_reset_member_actions() is available to
reset the member actions configuration to the default setting for all member actions. (WL #13855)
• Group Replication: You can now select an alternative UUID to form part of the GTIDs that are
used when internally generated transactions for view changes (View_change_log_event)
are written to the binary log. The system variable group_replication_view_change_uuid
added in this release specifies a UUID that is used instead of the group name (the value of
group_replication_group_name). The alternative UUID makes it easier to distinguish view
change events from transactions received by the group from clients. This can be useful if your setup
allows for failover between groups, and you need to identify and discard transactions that were
specific to the backup group. Note that all members of the group must have the same alternative
UUID specified, so groups set up in this way cannot include members from releases prior to MySQL
8.0.26. (WL #14539)
• The URL for downloading Boost was updated. Thanks to Marcelo Altmann for the contribution. (Bug
#32856104, Bug #103611)
• The clone plugin now permits cloning from a donor MySQL server instance to a hotfix MySQL server
instance of the same version and release. Previously, the hotfix server instance was not recognized
as the same MySQL version and release. (Bug #32523635)
• These statements now report utf8mb3 rather than utf8 when writing character set names:
EXPLAIN, SHOW CREATE PROCEDURE, SHOW CREATE EVENT.
Stored program definitions retrieved from the data dictionary now report utf8mb3 rather than utf8
in character set references. This affects any output produced from those definitions, such as SHOW
CREATE statements.
This error message now reports utf8mb3 rather than utf8 when writing character set names:
ER_INVALID_CHARACTER_STRING. (Bug #32233614, Bug #32392077, Bug #32392209, Bug
#32428538, Bug #32428598)
• On platforms that support fdatasync() system calls, the new innodb_use_fdatasync variable
permits using fdatasync() instead of fsync() for operating system flushes. An fdatasync()
127
MySQL 8.0 Release Notes
system call does not flush changes to file metadata unless required for subsequent data retrieval,
providing a potential performance benefit. The innodb_use_fdatasync variable can be set
dynamically using a SET statement. (WL #14452)
Bugs Fixed
• Incompatible Change: Within trigger bodies, INSERT or UPDATE statements containing a SET
clause that used OLD or NEW values as assignment targets could raise an assertion or lead to a
server exit. Such assignments are no longer permitted. (Bug #32803211)
• Performance: Internal functions used to copy values between columns have been improved such
that computations not necessary when the values are of similar types are no longer performed.
Queries using temporary tables should be noticeably faster with this enhancement. Our internal
testing has shown such queries being executed up to 11% faster than previously; as always, your
results may differ from these depending on environment, configuration, and other factors. (Bug
#32742537)
• InnoDB: To reduce the number of unnecessary warning messages in the error log, instances
of the fil_space_acquire() function in the InnoDB sources were replaced by the
fil_space_acquire_silent() function where possible. (Bug #32944543)
• InnoDB: The TRX_FORCE_ROLLBACK_ASYNC flag in the InnoDB sources, which indicates whether
a transaction was rolled back asynchronously or by the owning thread, was found to be redundant
and has been removed. (Bug #32912595)
• InnoDB: Use of the ut_delete symbol instead of the UT_DELETE macro in the InnoDB
sources caused a failure in builds that disable Performance Schema memory tracing (-
DDISABLE_PSI_MEMORY=ON). (Bug #32910699)
• InnoDB: Dictionary system mutex_enter and mutex_exit calls in the InnoDB sources were
renamed to dict_sys_mutex_enter() and dict_sys_mutex_exit(), respectively. (Bug
#32907980)
• InnoDB: Legacy UNIV_INLINE and UNIV_MATERIALIZE artifacts were removed from InnoDB
sources. UNIV_HOTBACKUP was added to method declarations in some header files. (Bug
#32894165)
• InnoDB: The lock_sys sharded rw_lock index used random index values generated by the
ut_rnd_interval() function, which was not optimal for low-concurrency workloads. (Bug
#32880577)
• InnoDB: A string value setting for the innodb_redo_log_encrypt variable was not handled
properly. (Bug #32851525)
• InnoDB: Record buffer logic for the InnoDB memcached GET command was revised. (Bug
#32828352)
• InnoDB: The ut_list base member in the InnoDB sources now locates list nodes using
the element portion of the list type rather than storing a member pointer in the base node of a
list at runtime, which waisted resources. The patch also includes other ut_list related code
improvements. (Bug #32820458)
• InnoDB: After upgrading from MySQL 5.6 to MySQL 5.7 and starting the server with undo log
truncation enabled (innodb_undo_log_truncate=ON), a deadlock occurred when an undo
128
MySQL 8.0 Release Notes
tablespace truncate operation was initiated. The deadlock caused a long semaphore wait and an
eventual failure. A direct upgrade from MySQL 5.6 to MySQL 5.7.35 or later avoids this potential
issue. (Bug #32800020)
• InnoDB: The buf_get_LRU_mutex() function was optimized to avoid acquiring the LRU mutex
unnecessarily when flushing from the flush list. (Bug #32797451, Bug #103391)
Thanks to Adam Cable for the contribution. (Bug #32788772, Bug #103372)
• InnoDB: A failure occurred when truncating a partitioned table after an operation that added too
many columns to the table, exceeding the column limit. The number of columns added is now
evaluated before an ADD COLUMN operation is permitted. (Bug #32788564, Bug #103363)
• InnoDB: On platforms that support punch hole where the disk is near full, creating a tablespace with
a large AUTOEXTEND_SIZE setting could lead to a no space on device failure and a subsequent
InnoDB recovery failures. (Bug #32771235)
• InnoDB: A failure occurred during recovery with the disk being near full, leaving the data in an
inconsistent state. The failure occurred in the fil_tablespace_redo_extend() function, which
is used to redo a tablespace extension operation. (Bug #32749974, Bug #32748733)
• InnoDB: After relocating a file-per-table tablespace offline and making the new location known
to InnoDB using the innodb_directories option, an ALTER TABLE operation that used the
COPY algorithm failed with a storage engine error. The failure was due to a renaming check, which
searched the data directory instead of the new directory location. (Bug #32721533)
• InnoDB: ut_allocator() compliance issues with the C++ standard template library (STL) were
addressed. (Bug #32715698)
• InnoDB: The ut_list length member variable in the InnoDB sources was replaced by an atomic
field to permit lock free access without undefined behavior. The default ut_list constructor was
replaced by a new constructor that performs all list initialization. (Bug #32715371)
• InnoDB: The ut_allocator() out of memory reporting mechanism in the InnoDB sources was
not reliable and has been removed. (Bug #32715359)
129
MySQL 8.0 Release Notes
• InnoDB: Stalls were caused by concurrent SELECT COUNT(*) queries where the number of
parallel read threads exceeded the number of machine cores. A patch for this issue was provided
for Windows builds in MySQL 8.0.24. The MySQL 8.0.26 patch addresses the same issue on other
affected platforms. (Bug #32678019)
• InnoDB: To avoid costly calls to the rec_get_offsets() function, which determines the offsets
for each field in a record, caching of offsets is extended to indexes that meet certain requirements
such as having a fixed length, no virtual columns, instant columns, and so on. (Bug #32673649)
• InnoDB: When starting the server with a data directory that was restored by MySQL Enterprise
Backup, the doublewrite buffer (controlled by the innodb_doublewrite variable) remained
disabled until the next server restart. (Bug #32642866)
• InnoDB: “Too many open files” errors were encountered when creating a large number of tables.
(Bug #32634620)
• InnoDB: InnoDB recovery was unable to proceed due to a page tracking system recovery failure,
which should have been non-blocking. (Bug #32630875)
• InnoDB: An integer underflow issue was addressed in the InnoDB mecached plugin sources. (Bug
#32620378, Bug #32620398)
• InnoDB: When a transaction started waiting for lock, the InnoDB lock system provided information
to the server about the transaction currently holding the lock but failed to inform the server after
releasing the lock and grating it to another waiting transaction. As a result, the replication applier
thread coordinator was unable to detect potential deadlocks in the intended transaction commit order
that could occur if the third transaction in this scenario committed after the initial waiting transaction.
(Bug #32618301)
• InnoDB: When inserting a record into a unique secondary index, the index record locks taken to
prevent concurrent transactions from inserting a conflicting record into the affected range included an
unnecessary gap lock on the first record after the range. (Bug #32617942)
• InnoDB: InnoDB code that creates dynamically allocated over-aligned types was replaced by
ut::aligned_name library functions. (Bug #32601599)
• InnoDB: Memory allocation functions belonging to the API that handles dynamic storage of over-
aligned types (ut::aligned_name library functions) were extended to support memory tracing
using Performance Schema. The HAVE_PSI_MEMORY_INTERFACE source configuration option
enables the memory tracing module.
• InnoDB: Sampling of InnoDB data for the purpose of generating histogram statistics is now
supported with all transaction isolation levels supported by InnoDB. Previously, sampling was
performed using only the READ UNCOMMITTED isolation level. (Bug #32555575)
• InnoDB: An index with a key prefix length greater than 767 bytes was permitted on a table defined
with the REDUNDANT row format, exceeding the index key prefix length limit for that row format.
130
MySQL 8.0 Release Notes
The ALTER TABLE operation that added the index validated the index key prefix length for the row
format defined by the innodb_default_row_format variable instead of the actual row format of
the table. The fix ensures that index key prefix length is validated for the correct row format. (Bug
#32507117, Bug #102597)
• InnoDB: Adaptive hash index latches did not provide meaningful latch location information. (Bug
#32477773)
• InnoDB: A dependency related to redo and undo log encryption at server initialization time was
removed. (Bug #32476724)
• InnoDB: An online buffer pool resizing operation freed the previous buffer pool page hash,
conflicting with a concurrent buffer pool lookup that required the previous page hash. (Bug
#32460315)
• InnoDB: A workload stalled while executing a undo tablespace truncation operation on an instance
with a large buffer pool. The function that truncates marked undo tablespaces now takes a shared
latch instead of an exclusive latch, and the shared latch is taken for a shorter period of time. (Bug
#32353863, Bug #102143)
• InnoDB: A programming interface was added for handling dynamic storage of over-aligned types.
(Bug #32246200, Bug #32246061)
• InnoDB: Under certain circumstances, a failure during InnoDB recovery could have caused
a loss of committed changes. Checkpoints permitted during recovery did not handle page
flushing, flush list maintenance, or persisting changes to the data dictionary table buffer as
necessary for a proper checkpoint operations. Checkpoints and advancing the checkpoint LSN
are therefore no longer permitted until redo log recovery is complete and data dictionary dynamic
metadata (srv_dict_metadata) is transferred to data dictionary table (dict_table_t)
objects. Should the redo log run out of space during recovery or after recovery (but before
data dictionary dynamic metadata is transferred to data dictionary table objects) as a result of
this change, an innodb_force_recovery restart may be required, starting with at least the
SRV_FORCE_NO_IBUF_MERGE setting or, in case that fails, the SRV_FORCE_NO_LOG_REDO
setting. If an innodb_force_recovery restart fails in this scenario, recovery from backup may be
necessary. (Bug #32200595)
• InnoDB: Rollback segments are now initialized in parallel during startup. Previously, rollback
segments were initialized serially.
Thanks to Zheng Lai and the Tencent Cloud-Native Database team for submitting the contribution
this bug fix is based on. (Bug #32170127, Bug #101658)
• InnoDB: A race condition occurred between a purge thread that was truncating an undo tablespace
and a server thread that queried the INFORMATION_SCHEMA.FILES table. As a result, the
truncated undo tablespace did not appear in the INFORMATION_SCHEMA.FILES table when
queried, which in turn caused a MySQL Enterprise Backup failure due to a dependency on the
INFORMATION_SCHEMA.FILES table for undo tablespace file locations. (Bug #32104924, Bug
#32654667)
• InnoDB: When DML operations are concentrated on a single table, purge work was performed
by a single purge thread, which could result in slowed purge operations, increased purge lag, and
131
MySQL 8.0 Release Notes
increased tablespace file size if DML operations involve large object values. To address this issue,
purge work is now automatically redistributed among available purge threads when the purge lag
exceeds the innodb_max_purge_lag setting. (Bug #32089028)
• InnoDB: Code related to the trx_t::is_recovered flag in the InnoDB sources was revised
to address various complexity and correctness issues. One of the issues addressed caused an
XA transaction to be described incorrectly as “recovered”, which occurred when a client session
disconnected from an XA transaction after XA PREPARE. (Bug #31870582)
• InnoDB: Using the InnoDB memcached plugin, attempting to retrieve multiple values in a single get
command returned an incorrect value. (Bug #29675958, Bug #95032)
Thanks to Zhai Weixiang for the contribution. (Bug #27933068, Bug #90643)
• Partitioning: When a table was partitioned by TIMESTAMP and a timestamp literal with a time zone
offset was used in the WHERE clause of a SELECT statement, it was possible for a partition to be
omitted from the result set.
We fix this by making sure that a timestamp with a time zone offset is always converted as described
before comparing with values from the column. (Bug #101530, Bug #32134145)
• Replication: An incorrect default value in code meant that the allowlist of IP addresses permitted
for a replication group was implicitly reconfigured although no value had been supplied. (Bug
#32714911)
• Replication: A deadlock could occur if a STOP GROUP_REPLICATION statement was issued when
a replication channel on a group member was attempting to commit a transaction. The server now
rolls back the transaction immediately if it cannot acquire the relevant lock, rather than waiting for the
lock and the commit to complete and causing the deadlock. (Bug #32633176)
132
MySQL 8.0 Release Notes
• Replication: On a multithreaded replica, the reference to the active event was sometimes managed
incorrectly when retrying a transaction. (Bug #32590974)
• Replication: After a DML operation was performed on the last partition of a table with more than 128
partitions, MySQL Server and MySQL clients (such as mysqlbinlog) parsed the event information
from the binary log incorrectly, resulting in an inaccurate partition ID being stated. The information
is now read using an event reader function that is endianness independent. (Bug #32358736, Bug
#102191)
• Replication: In a new MySQL Server installation, the mysql.gtid_executed system table was
missing the property STATS_PERSISTENT=0 to disable persistent statistics, which is present for the
other replication-related tables. (Bug #32250735)
• Replication: When the same row in a table was updated multiple times by the same event, the
replication applier’s hash scan algorithm omitted to check for JSON partial updates, which are
logged when binlog_row_value_options=PARTIAL_JSON is set. This could result in replication
stopping with a “key not found” error. (Bug #32221703)
• Replication: Replica servers now check and validate the transaction ID part of a GTID before
applying and committing the transaction associated with it. (Bug #32103192)
• Replication: Replication could stop on a multithreaded replica if a unique secondary key was
omitted from the writeset hashes used to compute transaction dependencies, leading to errors when
executing the transactions on the multithreaded replica. Write set hashes now always include unique
secondary keys even if they are not included in the read set and write set. (Bug #31636339)
• Replication: MySQL semisynchronous replication did not clean up connection artifacts correctly
after sending a reply to the source, causing a mismatch that meant the connection had to be re-
established. The issue has now been fixed. (Bug #31363518, Bug #32441220, Bug #32759421)
As a result, on a multithreaded replica, when GTID_MODE = ON is set for the instance and
SOURCE_AUTO_POSITION is set for the channel using the CHANGE REPLICATION SOURCE TO
statement, the following behaviors now apply:
• A START REPLICA UNTIL SQL_AFTER_MTS_GAPS statement just stops the applier thread
when it finds the first event to execute, and does not attempt to check for gaps in the sequence of
transactions.
• A CHANGE REPLICATION SOURCE TO statement does not automatically fail if there are gaps in
the sequence of transactions.
These changed behaviors only apply on a multithreaded replica that uses GTIDs and GTID auto-
positioning, and not on a replica that uses binary log position-based replication. (Bug #30571587,
Bug #97694)
• Group Replication: When running Group Replication in single-primary mode, unnecessary copies
of the transaction data were created during data serialization. This is now done in a single step to
reduce the memory footprint. (Bug #32781945)
133
MySQL 8.0 Release Notes
member, so the timestamp appeared as zero in viewable output. For improved observability, group
members now set local timestamp values for transactions associated with view change events. (Bug
#32668567)
• Group Replication: Previously, a warning message was written to the error log if the original commit
timestamp on a replicated transaction was more recent than the immediate commit timestamp on
the replica applying it. The message could occur inappropriately if the fluctuation in the replication
lag had a similar value to the clock difference between the machines involved, which could be made
more likely by better quality connections between them. During Group Replication failover, it was
possible for a message to be returned for every transaction, flooding the log. To avoid this situation,
the warning message has been withdrawn. (Bug #32554807)
• Microsoft Windows: Writing to Windows event logs could be unsuccessful. (Bug #32890918)
• JSON: Reading JSON values from tables that used the CSV storage engine raised an error such as
Cannot create a JSON value from a string with CHARACTER SET 'binary'. This
happened because the CSV engine uses my_charset_bin as the character set for the record buffer
but creation of JSON values includes an explicit check for my_charset_bin, and raises an error if
this character set is given.
We handle this issue by passing the actual character set of the column instead of the character set of
the buffer holding the data, which is always binary. (Bug #102843, Bug #32597017)
• A query for which the derived condition pushdown optimization could be applied was not so
optimized when the query was part of INSERT ... SELECT. (Bug #32959186)
• Import operations for access privilege information became very slow for large numbers of accounts
and schemas. (Bug #32934351)
• Queries which needed to sort the results of a full-text index scan were in some circumstances not
handled correctly. (Bug #32924198)
• Queries containing GROUP BY, ORDER BY, and LIMIT in a subquery and accessed using a cursor
could cause a server exit. (Bug #32918240)
• When invoked with the --help and --verbose options, mysqld created an auto.cnf file in the
current directory. (Bug #32906164)
• Queries that involved pushing a condition with view references down to a materialized derived table
could cause a server exit. (Bug #32905044, Bug #32324234)
• A regression was found in the simplification of streaming aggregation (GROUP BY of data already
sorted) that was performed in MySQL 8.0.23.
We fix this issue as follows: When there is an implicit grouping on a single table which is the subject
of a fulltext search, we now force insertion of a temporary table to materialize MATCH() temporaries
before they are sent to the AggregateIterator, since it tries to save and restore the rows it
receives, but cannot properly include the fulltext search information, as it is hidden. (Bug #32889491)
• For conversion of -DBL_MAX to string and back to double, the new double value differed from the
original and was rejected as out of bounds. (Bug #32888982, Bug #103709)
134
MySQL 8.0 Release Notes
• Now, whenever the JSON_LENGTH() function includes the optional path argument, the server
rewrites it as JSON_LENGTH(JSON_EXTRACT(doc, path)). This means that JSON_LENGTH()
now supports wildcards (such as $, ., and *) and array ranges in the path, as shown here:
mysql> SELECT JSON_LENGTH('[1,2,3,4,5,6,7]', '$[2 to 4]') AS x;
+------+
| x |
+------+
| 3 |
+------+
(Bug #32877703)
• For flags typically used for RPM and Debian packages, the new WITH_PACKAGE_FLAGS
CMake option controls whether to add those flags to standalone builds on those platforms. The
default is ON for nondebug builds. This is used to “harden” the builds; for example, by adding -
D_FORTIFY_SOURCE=2. (Bug #32876974)
• The NULLIF() function did not perform all necessary checks for errors. (Bug #32865008)
• For views that depended on other views, output from the SHOW CREATE VIEW statement used
during production of dump files could cause an error at restore time. (Bug #32854203, Bug #103583)
• The query-attributes code did not properly handle large 64-bit numbers. (Bug #32847269)
• Information retrieved from the Performance Schema metadata_locks table could be incorrect for
foreign keys and CHECK constraints. (Bug #32832004, Bug #103532)
• When generating unique names for view columns, the server now considers only those objects
whose names are visible. (Bug #32821372)
• When a condition is pushed down to a materialized derived table, a clone of the derived table
expression replaces the column (from the outer query block) in the condition. When the cloned item
included a FULLTEXT function, it was added to the outer query block instead of the derived table
query block, which led to problems. To fix this, we now use the derived query block to clone such
items. (Bug #32820437)
• A common table expression which was used more than once in a statement, at least once within a
subquery that was subsequently removed during resolution due to being always true, or always false.
(Bug #32813547, Bug #32813554)
• If a statement is prepared against a table that is persistent at preparation time but temporary at the
time of first execution, an assertion could be raised. (Bug #32799797)
• An internal function used by spatial functions could reference memory after freeing it. (Bug
#32793104)
• The impossible filter optimization removed MRR access paths that were required by the
corresponding BKA access paths. (Bug #32787415)
• The MRR iterator normally filters out NULL keys by checking impossible_null_ref(), but when
a join condition either contained an IS NULL predicate, or used the NULL-safe equals operator
≪=>, the optimizer had to check whether the join condition used the predicate terms as part of its
join condition, and not set the internal flag HA_MRR_NO_NULL_ENDPOINTS in such cases. Now we
check, using a bitmask, whether the each column in the key rejects NULL, in which case we can set
HA_MRR_NO_NULL_ENDPOINTS without further checks. (Bug #32774281)
• For system variables with an enumeration type, SET PERSIST_ONLY var_name = DEFAULT
persisted the numeric value and not the symbolic name. (Bug #32761053)
135
MySQL 8.0 Release Notes
• For applications that use the C API to execute prepared statements, query attributes could not
be used for prepared statements with no parameters. (Bug #32753030, Bug #32790714, Bug
#32955044)
• The arguments to IN() were not always converted to the correct character set. (Bug #32746552)
• The LOCATE() function unconditionally returned NULL when an argument could not be evaluated.
Now, when used in an expression that is determined to be non-nullable, the function returns zero
instead. (Bug #32746536)
• The functions TRIM(), RTRIM(), and LTRIM() did not always perform proper error checking. (Bug
#32744772)
• A previous fix in an internal resolver function ensured that it raises an error when a generated
column cannot be resolved. This worked without any problem when the generated column is part
of a CREATE TABLE statement, but in the case where the table with the generated column was
generated on a MySQL 5.7 database and then upgraded to MySQL 8.0, an error was reported and
the upgrade terminated.
We fix this by using the correct pointer when reporting the table causing the error in the function
fix_generated_columns_for_upgrade(). (Bug #32738972)
• When looking inside rollup wrappers in the SELECT list, and trying to find the same item in the
GROUP BY list, the server did not take into account that a cache might have been added around the
expression. Now any such caches are unwrapped before looking for the item. (Bug #32729377, Bug
#32918400)
• A prepared statement that used MIN() or MAX() could return an incorrect result if it also included
dynamic parameters. (Bug #32713860, Bug #103170)
• Replication could fail if a DML statement was executed immediately after an XA transaction was
rejected or forced to rollback due to a deadlock. (Bug #32707060)
• Queries containing multiple instances of GROUPING() were not always handled correctly. (Bug
#32695103)
• When executing EXPLAIN ANALYZE, materialization iterators count every single init() call, even
those that only retain existing data, causes materializations to appear to cost too little compared to
the number of underlying calls. We fix this by allowing the materialization iterator to override the call
and row counts with its own data. (Bug #32688540)
• A race condition in the metadata locking code could result in a server exit. (Bug #32686116)
• An index-only scan on a covering full-text index could return incorrect results for queries with multiple
calls to MATCH() function depending on the order in which the MATCH() calls were evaluated. (Bug
#32685616)
• Including query attributes for a prepared statement could cause a statement execution failure. (Bug
#32676878)
• Executing DDL statements on a system table could cause a server exit. (Bug #32665990)
136
MySQL 8.0 Release Notes
• mysql_migrate_keyring failed to enforce the condition that the source and destination keystores
must differ. (Bug #32637784)
• System cache size checking could be inaccurate on Ubuntu. (Bug #32619199, Bug #102926)
• The server did not process correctly some queries that used MATCH ... AGAINST on a column
with a fulltext index in a HAVING clause. (Bug #32617181)
• The internal function Item_func_match::eq() raised an assert failure in debug builds when
it was called with an argument that was an Item_func_match_predicate. The assertion was
added with the expectation that an Item_func_match object would not be compared with an
Item_func_match_predicate object, but it was later found that this can happen during the
ONLY_FULL_GROUP_BY check when the predicate is in a HAVING clause.
We fix this by removing the assertion so that the function returns false, instead. (Bug #32611913)
• SELECT using DISTINCT with a GROUP BY ... WITH ROLLUP on a primary key column returned
a different result than when the column was not a primary key. (Bug #32565875)
• When an item in the SELECT list came from a table that was found to be constant, it was possible to
add caches around it before adding ROLLUP wrappers, causing it to be unfindable in the group list
(which had no such wrappers). This is addressed by unwrapping the caches. (Bug #32559356)
• The C client library could produce a Malformed communication packet error if a prepared
statement parameter was longer than 8KB and the next parameter represented a NULL value. (Bug
#32558782)
• When comparing arguments of different types, and the arguments are deemed constants, the server
may insert its own hidden item cache to save on repeated conversion (and possible warnings). This
is not visible in the output of any statements such as EXPLAIN.
An issue arose due to the fact that resolution of ROLLUP runs after the comparisons are set up, and
may replace the arguments, which could lead to incorrect results from comparisons. Now when this
happens, we signal that the comparison needs to reconsider its caches, and not possibly re-use stale
values. (Bug #32548377)
• Incorrect reference counting for a destructor in the implementation of a loadable function could raise
an assertion for debug builds or report that the function does not exist for nondebug builds. (Bug
#32528898, Bug #102649)
• MySQL source distributions now bundle the Google Test source code, which no longer need
be downloaded to run Google Test-based unit tests. Consequently, the WITH_GMOCK and
ENABLE_DOWNLOADS CMake options have been removed and are ignored if specified.
This change also corrects a couple of build issues whereby source distributions incorrectly included
an empty source_downloads directory, and CMake did not fail when WITH_UNIT_TESTS was
enabled but the Google Test source was not found. (For the latter issue, it can no longer occur
because the source is always present.) (Bug #32512077, Bug #27326599, Bug #29935278)
137
MySQL 8.0 Release Notes
• When outer batched key access and block-nested loop (or hash join) occurred together in a query,
both were reverted to nested loops in the plan interpretation to access paths. Problems arose in
some cases in which non-equality join conditions had been pushed to a special kind of BKA index
condition, and by converting to a regular index lookup (which does not check the BKA condition), it
was possible to drop conditions that should have been checked.
We fix this by removing the BKA index condition; since its use is very rare, potential gains in most
practical queries are very low, and removing it decreases complexity significantly. (Bug #32424884)
• SHOW CREATE USER could cause an unexpected server exit if the structure of the mysql.user
system table was manually altered. (Bug #32417780, Bug #31654586)
• For large values of the group_concat_max_len system variable, prepared statements that
used the GROUP_CONCAT() function could be unnecessarily re-prepared across executions. (Bug
#32413530, Bug #102344)
• Changes were not properly rolled back on re-execution of prepared statements or stored procedures
for which walk and replace was performed as part of optimization. (Bug #32384324, Bug #32573871)
• Client programs using the asynchronous C API functions could leak memory if a connection timeout
occurred. Thanks to Facebook for a contribution used in fixing this issue. (Bug #32372038, Bug
#102189, Bug #32800091, Bug #103409, Bug #33171164, Bug #104461)
• The dynamic statistics cache exposed by the INFORMATION_SCHEMA could be updated in the
middle of a transaction before it was known whether the transaction would commit, potentially
caching information corresponding to no committed state. (Bug #32338335)
• USING HASH was removed from the definitions of Performance Schema thread pool tables because
the Performance Schema does not support hash indexes. (Bug #32194617)
• Inserting a datetime literal with an explicit time zone offset into a TIMESTAMP column could produce
the wrong time if time_zone=SYSTEM and the system time zone has DST transitions. (Bug
#32173664, Bug #101670)
• While setting up ORDER BY for a window function, a window definition including a subquery was
removed along with the subquery in the ORDER BY. (Bug #32103260)
• The use of a SET PERSIST or SET PERSIST_ONLY statement is now disallowed for the
group_replication_force_members system variable. This system variable must be cleared
after use before you can issue a START GROUP_REPLICATION statement, so it should not be
persisted to the MySQL server instance’s option file. (Bug #31983203)
• Upgrades from MySQL 5.7 to 8.0 failed if the MySQL installation had FEDERATED tables. (Bug
#31973053)
• Persisting component-related system variables could result in unnecessary “unknown variable” error
messages. (Bug #31968366)
• An out-of-memory error occurred when loading large amounts of data into tables with full-text search
indexes. Not all of the memory allocated to the full-text search cache was accounted for when
inserting data into the full-text search auxiliary tables. (Bug #31576731)
• The precision for a UNION between integer and decimal values could be calculated incorrectly,
leading to truncation of the integer in the result. (Bug #31348202, Bug #99567)
• InnoDB wrote unnecessary warnings to the error log indicating that table statistics could not be
calculated. (Bug #30865032)
• A secondary index over a virtual column became corrupted when the index was built online.
138
MySQL 8.0 Release Notes
For UPDATE statements, we fix this as follows: If the virtual column value of the index record is set to
NULL, then we generate this value from the cluster index record. (Bug #30556595)
• DROP DATABASE for a database with a large number of tables (one million) could result in an out-of-
memory condition. (Bug #29634540)
• The system_time_zone system variable is initialized at server startup from the server host settings
and the mysqld environment, but if the server host time zone changed (for example, due to daylight
saving time), system_time_zone did not reflect the change. Now it does. (Bug #29330089, Bug
#94257)
• For upgrades on Ubuntu, if an existing my.cnf file is found, it is renamed to my.cnf.bak and a
warning is issued. (Bug #24486556, Bug #82639)
• Boolean system variables could be assigned a negative value. (Bug #11758439, Bug #50643)
• Prepared statements did not always make use of index extensions (see Use of Index Extensions).
(Bug #103711, Bug #32897525)
• When enabled, the prefer_ordering_index optimizer switch had a negative effect on the
performance of prepared statements. (Bug #103710, Bug #32897503)
• Successive INSERT() function calls could sometimes yield invalid NULL results. (Bug #103513, Bug
#32824978)
• Some NOT IN subqueries did not return correct results due to a regression in NULL handling. (Bug
#103331, Bug #32773801)
• Whenever a SELECT ... FOR UPDATE NOWAIT statement was unable to obtain a record lock, a
message Got error 203 when reading table ... was written to the error log, even though
though this is a relatively common occurrence, the logging of which led to excessive use of disk
space.
Our thanks to Brian Yue for this contribution. (Bug #103159, Bug #32705614)
• Bugs Fixed
Packaging Notes
• Binary packages that include curl rather than linking to the system curl library have been
upgraded to use curl 7.76.0.
Bugs Fixed
• On Fedora 34, builds from source failed due to an undefined reference to symbol
crc32_z@@ZLIB_1.2.9. (Bug #32702860)
139
MySQL 8.0 Release Notes
• Docker containers for MySQL Enterprise Edition no longer need to run with root privileges. (Bug
#32472242)
• For a prepared, implicitly grouped SELECT statement in which the WHERE clause was determined
always to be false, the result of some aggregate functions could sometimes be picked up from the
previous execution of the statement. (Bug #103192, Bug #32717969)
• Compilation Notes
• Error Handling
• Keyring Notes
• Optimizer Notes
• Packaging Notes
• Pluggable Authentication
• Security Notes
• Bugs Fixed
Compilation Notes
• GCC 10 is now a supported compiler for building MySQL on EL7 or EL8. This compiler is available
in the devtoolset-10 (EL7) or gcc-toolset-10 (EL8) package. It is also recommended to
use GCC 10 when building third-party applications that are based on the libmysqlclient C API
library. (Bug #32381003)
In such cases, the server now writes the reason to the connection before closing it, and client
receives a more informative error message, The client was disconnected by the server
because of inactivity. See wait_timeout and interactive_timeout for
configuring this behavior. (ER_CLIENT_INTERACTION_TIMEOUT).
The previous behavior still applies for client connections to older servers and connections to the
server by older clients. (WL #12999)
140
MySQL 8.0 Release Notes
Error Handling
• Client connection failure messages now include the port number. For example: Can't connect
to MySQL server on '127.0.0.1:63333'.. Thanks to Daniël van Eeden for the contribution.
(Bug #30787660, Bug #98311)
Keyring Notes
• MySQL Keyring previously implemented keystore capabilities using server plugins, but now is
transitioning to use the MySQL component infrastructure, beginning with these keyring components:
• component_keyring_file stores keyring data in a file local to the server host. This component
is available in MySQL Community Edition and MySQL Enterprise Edition distributions. See Using
the component_keyring_file File-Based Keyring Component.
The new keyring components have similarities to the existing keyring_file and
keyring_encrypted_file plugins, but are configured differently, use distinct on-disk storage
formats, and have fewer restrictions on key type and key size.
Keyring components are not loaded using the --early-plugin-load server option during startup
or configured during startup or at runtime using system variables:
• During startup, the server determines which keyring component to load using a manifest file,
and the loaded component consults its own configuration file when it initializes. See Keyring
Component Installation.
• At runtime, the new ALTER INSTANCE RELOAD KEYRING statement enables reconfiguring
an installed keyring component after changes to its configuration file. See ALTER INSTANCE
Statement.
Key migration capabilities have been expanded. Previously, key migration occurred only from one
keyring plugin to another. The new --keyring-migration-to-component server option enables
key migration from a keyring plugin to a keyring component; this facilitates transitioning a MySQL
installation from keyring plugins to keyring components. The new mysql_migrate_keyring utility
enables key migration from one keyring component to another. See Migrating Keys Between Keyring
Keystores. There is no provision for migrating keys from a keyring component to a keyring plugin.
Existing keyring plugins remain available with no change to user-visible characteristics, but their
implementation was revised to use the component infrastructure. This is facilitated using the built-
in plugin named daemon_keyring_proxy_plugin that acts as a bridge between the plugin and
component service APIs. See The Keyring Proxy Bridge Plugin. (WL #13446)
Optimizer Notes
• The MySQL query optimizer can now apply the derived table optimization to correlated scalar
subqueries, whenever the subquery_to_derived flag of the optimizer_switch variable is
enabled. This is done by applying an extra grouping and then an outer join on the lifted predicate.
For example, a query such as SELECT * FROM t1 WHERE (SELECT a FROM t2 WHERE
t2.a=t1.a) > 0 can be rewritten as SELECT t1.* FROM t1 LEFT OUTER JOIN (SELECT
a, COUNT(*) AS ct FROM t2 GROUP BY a) AS derived ON t1.a = derived.a WHERE
derived.a > 0.
141
MySQL 8.0 Release Notes
If the subquery already has an explicit grouping, MySQL adds the extra grouping to the end of the
existing grouping list.
MySQL performs a cardinality check to ensure that the subquery does not return more than one row,
and raises ER_SUBQUERY_NO_1_ROW if it does. The check is performed as part of evaluating any
WHERE or JOIN clause in the rewritten query, before evaluating the lifted predicate.
For more information, see Correlated Subqueries, as well as Derived Tables. (WL #13520)
Packaging Notes
• The bundled libedit library was upgraded to version 20190324-3.1. (Bug #32433089)
• Binary packages that include curl rather than linking to the system curl library have been
upgraded to use curl 7.74.0.
• There are new memory instruments to account for memory allocated to data dictionary
infrastructure and objects:
memory/sql/dd::infrastructure
memory/sql/dd::objects
• Some instruments were renamed for improved uniformity of instrument naming. Affected
instrument names are grouped using a key prefix in the same style as C++ namespaces. For
example, error-related instruments use a error:: prefix and partition-related instruments use a
Partition:: prefix. The following table displays the affected instruments.
In addition, the servers instrument is a duplicate of servers_cache and has been removed.
142
MySQL 8.0 Release Notes
Applications that use the old or removed instrument names should be adjusted to account for this
change.
• Several instruments were given a value in the DOCUMENTATION column (it is no longer NULL),
improving runtime instrumentation documentation availability.
(WL #14079)
Pluggable Authentication
• The new caching_sha2_password_digest_rounds system variable enables configuring the
number of hash rounds used by the caching_sha2_password authentication plugin for password
storage. (WL #14281)
Security Notes
• For platforms on which OpenSSL libraries are bundled, the linked OpenSSL library for MySQL
Server has been updated to version 1.1.1k. Issues fixed in the new OpenSSL version are described
at https://www.openssl.org/news/cl111.txt and https://www.openssl.org/news/vulnerabilities.html.
(Bug #32680637)
The new ST_Collect() aggregate function takes multiple geometry arguments and produces from
them a single geometry collection value. See Spatial Aggregate Functions
The CAST() and CONVERT() functions have been extended to support casting geometry values
from one spatial type to another. See Cast Functions and Operators. (WL #13454, WL #14160, WL
#14161, WL #14178, WL #14127)
• Group Replication: It is now possible to use START REPLICA SQL_THREAD and STOP REPLICA
SQL_THREAD statements for the group_replication_applier channel when Group Replication
is stopped. This enables an operator to apply any remaining unapplied transactions on a server that
left the group, without having to rejoin the server to the group. (Bug #32027612, Bug #32414767)
• Group Replication: Group Replication’s allowlist of hosts from which an incoming Group
Communication System connection can be accepted, can now be updated while Group
Replication is still running. You can therefore add new members to a group controlled by an
allowlist without needing to stop and restart Group Replication. The allowlist is specified by the
group_replication_ip_allowlist system variable on each group member. (WL #14563)
• Microsoft Windows: The /RTC1 compiler flag was removed from the debug compiler flags to
reduce the time needed to run all tests invoked by the mysql-test-run.pl script when using
MSVC on Windows. Initially, this compiler flag was introduced with the CMake program (by default
for debug builds) and it generated code to test for stack corruption around function calls and the use
of uninitialized variables at runtime. No loss of bug discovery is expected with the removal of the /
143
MySQL 8.0 Release Notes
RTC1 compiler flag. Memory errors, such as stack corruption, are more likely to be found by Address
Sanitizer (ASAN) testing and the use of uninitialized variables are detected by compiler warnings.
(Bug #32525732)
Thanks to Daniël van Eeden for the contribution. (Bug #32335434, Bug #102103)
• Client applications and test suite plugins now report utf8mb3 rather than utf8 when writing
character set names. (Bug #32164079, Bug #32164125)
• The --skip-slave-start command line parameter is used to prevent the replication I/O
thread and replication SQL thread from starting when a replica server restarts. However, using the
parameter on the command line or in a my.cnf option file might require login access to the server
host. The skip_slave_start system variable is now provided to give access to this feature using
MySQL Server’s privilege structure, so that database administrators do not need any privileged
access to the operating system. The new global system variable is read-only and can be set using a
SET PERSIST_ONLY statement. As a system variable, its value can also be queried from a MySQL
client and used by MySQL APIs. The --skip-slave-start command line parameter can still be
used as an alternative, and it sets the new global system variable. (WL #14450)
Bugs Fixed
• Important Note: When a utf8mb3 collation was specified in a CREATE TABLE statement, SHOW
CREATE TABLE, DEFAULT CHARSET, the values of system variables containing character set
names, and the binary log all subsequently displayed the character set as utf8 which is becoming
a synonym for utf8mb4. Now in such cases, utf8mb3 is shown instead, and CREATE TABLE
raises the warning 'collation_name' is a collation of the deprecated character
set UTF8MB3. Please consider using UTF8MB4 with an appropriate collation
instead. (Bug #27225287, Bug #32085357, Bug #32122844)
• InnoDB: Stale pages encountered by the buf_page_create() function were freed and then read
from disk again without being reinitialized. (Bug #32622548)
• InnoDB: C++ enum type values in buffer pool page and buffer pool block data structures in the
InnoDB source code were changed from int to uint8_t in MySQL 8.0.23, causing the data to
be printed as ascii characters instead of integers in different outputs including messages and
INFORMATION_SCHEMA tables.
The function that populates the INNODB_BUFFER_PAGE_LRU table did not print the IO_PIN state for
the IO_FIX field. (Bug #32575469)
• InnoDB: A function that checks for locks on a table tried to acquire an exclusive lock system
(lock_sys) latch, causing long semaphore waits. (Bug #32545030)
• InnoDB: Counting temporary tablespaces as open files caused the innodb_open_files limit to be
exceeded, preventing other files from being opened. Temporary tablespaces are now ignored when
counting open files. (Bug #32541241)
144
MySQL 8.0 Release Notes
• InnoDB: Rollback of a transaction that modified generated columns raised an assertion failure. The
failure occurred when attempting to free space occupied by externally stored columns. The update
vector containing the externally stored columns did not account for the generated columns. (Bug
#32529561)
• InnoDB: An unnecessary full flush list scan was removed, improving the speed with which session
temporary tablespaces are created. Previously, depending on the size of the buffer pool and the
number of dirty pages, creation of session temporary tablespaces could take a long time, affecting
write transaction performance. (Bug #32423860)
• InnoDB: A function that checks if a given page type is valid raised an assertion when testing valid
but undefined page type for an undo tablespace. (Bug #32366301)
• InnoDB: Sharded read-write lock function instrumentation was improved. (Bug #32333168)
• InnoDB: On Windows, when creating a table with the COMPRESSION option, InnoDB failed to check
the error status of a system call before checking the punch hole support flag set by the same system
call, which resulted in reading an uninitialized flag. (Bug #32322645)
• InnoDB: Geometry columns created in MySQL 5.6 caused failure when restarting the server after
upgrading from MySQL 5.7 to MySQL 8.0 due to a geometry type change introduced in MySQL 5.7.
(Bug #32299738)
• InnoDB: During recovery, log records for multiple record group mini transactions were parsed
twice. The log record from the first parsing operation is now saved to avoid the second pass, which
improves recovery performance.
Thanks to Zhai Weixiang for the contribution. (Bug #32293797, Bug #102010)
• InnoDB: In debug builds, an end range condition check for a secondary index raised an assertion
failure, and Valgrind testing uncovered an end range condition check for secondary index on a virtual
column that read an uninitialized value. (Bug #32291506)
• InnoDB: With the innodb_log_writer_threads variable disabled, extensive log writing by one
thread could block log flushing opportunities for other threads. (Bug #32255538)
• InnoDB: In SHOW ENGINE INNODB STATUS deadlock information, in cases where a single rw-
lock reader thread holds a shared latch, the reader thread id was not printed. (Bug #32252477)
• InnoDB: Running concurrent SHOW CREATE TABLE and ALTER TABLE operations on the same
table raised an assertion failure. The SHOW CREATE TABLE thread referenced a tablespace object
that had been made stale by the ALTER TABLE operation. (Bug #32235621)
• InnoDB: The introduction of sharded rw_lock_stats counters in MySQL 5.7 caused a regression
in CPU cache efficiency. To address this issue in MySQL 5.7, the sharding method was changed.
For optimal performance, the rw_lock_stats counter is removed in MySQL 8.0. (Bug #32225367)
• InnoDB: On Windows, stalls were caused by concurrent SELECT COUNT(*) queries where the
number of parallel read threads exceeded the number of machine cores. (Bug #32224707, Bug
#101789)
145
MySQL 8.0 Release Notes
• InnoDB: An IS_STALE column, which indicates whether a buffer pool page is stale, was added to
the INFORMATION_SCHEMA.INNODB_BUFFER_PAGE table. (Bug #32194434)
• InnoDB: In debug builds, the log_free_check() function in the redo log code, which ensures
that there is available space in the logs when holding latches on dirty pages, now uses a list of
mini-transactions opened by the current thread to search for potential constraint violations. (Bug
#32189367)
• InnoDB: During a slow shutdown on a system with a 64k InnoDB page size and
innodb_max_undo_log_size setting that was less than the initial undo tablespace size,
the two undo tablespaces were truncated in an endless loop. Undo tablespace truncation is
now restricted to undo tablespaces that are larger than the initial undo tablespace size and the
innodb_max_undo_log_size setting.
The function that retrieves the next redo rollback segment for an undo tablespace was modified
to ensure that undo logs are evenly split between two active undo tablespaces when an inactive
tablespace is found. (Bug #32173457)
• InnoDB: Starting the server in upgrade mode following an unexpected stoppage while the
undo_001 undo tablespace was being truncated caused failure. When upgrade processing was
completed and shutdown initiated, the function that determines if undo truncation is required could
not find the undo_001 undo tablespace. To address this issue, undo tablespace truncation is no
longer performed when starting the server in upgrade mode. (Bug #32127912)
• InnoDB: A delete operation on a parent table that initiated a cascading update on a child table
with an indexed virtual column and indexed foreign key constraint column caused a virtual column
corruption. (Bug #32124113)
• InnoDB: The open and close sequence for table share instances (m_share objects) and dictionary
table instances was modified to prevent accessing old m_share objects that could point to stale
dictionary indexes.
• InnoDB: An debug assertion failure occurred when issuing a TRUNCATE TABLE operation after a
successful server restart following a server initialization failure. (Bug #31763837)
• InnoDB: Undo tablespace truncation error handling was improved, and a Windows-specific InnoDB
file deletion procedure was made more POSIX-compatible. (Bug #31684783)
• InnoDB: An online ALTER TABLE operation failed with an Incorrect key file for table
error due to an unnecessary encryption status check that was performed when reading online DDL
row logs. (Bug #31529221, Bug #99938)
• InnoDB: Initializing the server with an with a 4K InnoDB page size caused “key too long” errors to
be written to the error log. (Bug #31496943, Bug #99892)
• InnoDB: A table created with a reserved name caused a failure. (Bug #31382599)
• InnoDB: Creating an index on virtual columns raised an invalid debug assertion failure. (Bug
#31279528, Bug #99421, Bug #27168185)
146
MySQL 8.0 Release Notes
specific functions that test the buf_page_t::io_fix field for particular values. A series of other
small, related code changes were also implemented. (Bug #31027553)
• InnoDB: The TempTable memory allocator did not track RAM consumption when allocating blocks
of memory shared by different queries for a given session, which could result in nonadherence to the
temptable_max_ram limit. (Bug #29890126)
• Partitioning: In some cases, invalid PARTITION clauses were not handled correctly in ALTER
TABLE statements. (Bug #32235085)
• Replication: Binary log transaction compression could not continue if a row event included a BLOB
column containing uncompressable data, and the compressed size of the row event was higher than
its uncompressed size. The function now handles the additional post-compression bytes correctly.
(Bug #32174715, Bug #101611)
• Replication: If all previous binary log files were purged at startup because their retention period had
expired, the new binary log file contained an empty Previous_gtids event, which could cause
errors in replication. The order of initialization has now been changed so that previous binary log files
are only purged after the previous GTID set has been written to the new binary log file that is created
at startup. (Bug #32134875, Bug #101533)
• Replication: When MySQL Server counted the number of GTIDs in a set, it was possible for the
return value to wrap, returning an incorrect result. This could lead to an incorrect decision to use
state transfer from the binary log for Group Replication distributed recovery, when a remote cloning
operation would have been more efficient. The logic has now been corrected. (Bug #32086209)
• Replication: An assertion was raised in debug builds relating to lost GTIDs if binary log files were
removed at startup because their retention period had expired. (Bug #32008512, Bug #101137)
• Replication: A deadlock could occur if the binary log file was rotated while system variables were
being updated and read by different clients. (Bug #31774422)
• Replication: The output of a SHOW PROCESSLIST statement for a replica’s SQL thread sometimes
showed the last query as currently being applied when the replica was actually caught up. (Bug
#30521198, Bug #97560)
• Group Replication: A race condition could occur if a STOP GROUP_REPLICATION statement was
used to stop a group member, while the Performance Schema statistics for Group Replication were
being queried by another client. Group Replication now prevents STOP GROUP_REPLICATION
statements and Performance Schema queries from running concurrently. (Bug #32100147)
• Microsoft Windows: Running MySQL Server (64-bit) on a Windows system with more than 32
logical processors and setting the VCPU attribute of a resource group to greater than 30 produced
an incorrect CPU mask value, which is used to set the thread affinity. Under these conditions,
the MSVC compiler reported warnings that the 32-bit shift was converted implicitly to 64-bit in the
thread_attrs_api_win.cc file. The conversion resulted in the wrong CPU mask calculation on
systems that have more than 32 logical processors. This fix ensures that a 64-bit shift is used when
calculating the CPU mask by replacing argument 1 of the shift with 1LL. (Bug #32079726)
147
MySQL 8.0 Release Notes
• JSON: The IF() function sometimes hit an assertion in debug builds when an error was raised from
its first argument; this also could occur under similar circumstances with the additional condition that
the function's return type was JSON. (Bug #32231393, Bug #32231620)
• JSON: A number of JSON functions did not propagate errors correctly, which could lead to assert
failures in debug builds. (Bug #32047630)
• JSON: JSON_TABLE() inside triggers was sometimes handled incorrectly when re-used in different
sessions. Fixed by ensuring that JSON_TABLE() and its temporary table are processed in the
context of the current session. (Bug #31644193)
• JSON: A multi-valued index defined on an expression that cast a column into a typed array was not
used for speeding up queries. This was because the server, when substituting an expression with
an equivalent indexed generated column, did not attempt to replace a reference to a column with a
reference to an equivalent generated column; for multi-valued indexes, it makes sense to replace
the column reference with a reference to a generated column backing a multi-valued index on an
expression that cast that column into a typed array.
This fix lifts the restriction that the server attempts to substitute only function expressions and
conditional expressions with indexed generated columns, by allowing substitution of column
references when they appear in a context where they can make use of a multi-valued index, that is,
when they are used as arguments to MEMBER OF(), JSON_CONTAINS(), or JSON_OVERLAPS().
The restriction remains in force for cases in which the column reference is used in a non-array
context. (Bug #30838807)
• JSON: The JSON_SEARCH() function interpreted all search string and path values as utf8mb4
strings, regardless of their actual encoding, which could lead to wrong results. (Bug #102443, Bug
#32443143)
• JSON: In some cases, when used in a left join, some MySQL JSON functions caused the optimizer
to transform it into an inner join, even though the inner join was not equivalent to the original left
join. This was due to the fact that they return a value which is not NULL, even though one of their
arguments is NULL, and the optimizer expected them to return NULL on NULL input.
• Community packages for generic Linux were not built with the necessary LDAP/SASL/Kerberos
dependencies, and did not bundle the associated required libraries. (Bug #32619858)
• The functions BIT_AND(), BIT_OR(), BIT_XOR(), and JSON_ARRAYAGG() did not always provide
proper error handling. (Bug #32594813)
• The server did not always provide proper error messages when IN was incorrectly used with UNION.
(Bug #32593846)
• It was possible for casting from DECIMAL to a signed integer type to hit an assertion when
the result had more digits than the metadata in Item_typecast_signed indicated it would
have. This happened because the decimal value is rounded when converted to an integer, and
Item_typecast_signed did not take into account that the rounding might increase the number of
digits in what was the integer part of the decimal value, such as when rounding 9.9 up to 10.
This is fixed by removing the logic that tried to compute a minimal maximum length for the result
of the cast, and instead using the default set by the parent class Item_int_func. That default
is the maximum width of a 64-bit integer, which should be safe regardless of the input value. (Bug
#32591589)
148
MySQL 8.0 Release Notes
• The name my_row_id was not permitted for invisible columns. This restriction has been lifted. (Bug
#32586231)
• On a system with many concurrent connections, execution of grant statements could take
excessively long waiting for metadata locks, causing the server to become unresponsive. (Bug
#32483597)
• Windows binaries and libraries were not being properly signed. (Bug #32458533)
• LIKE ... ESCAPE, where ESCAPE did not reference a constant value, was not handled correctly
within a prepared statement. (Bug #32446728)
• MySQL has traditionally interpreted an empty value in the ESCAPE clause (that is, ESCAPE '') for
LIKE as “no escape character”. Problems could arise when either of the first two arguments to LIKE
was a string using a multibyte character set, because the empty value in such cases was interpreted
as meaning that the backslash (\) should be used as the escape character, breaking the expected
behavior.
This fix causes LIKE to interpret ESCAPE '' as meaning that there is no escape character
regardless of character set, restoring the previous, expected behavior.
In addition, we now raise an error if the specified escape character cannot be converted to the target
character set. This supersedes the original behavior in such cases, which was to fall back silently to
using the backslash as the escape character. (Bug #32446508)
• Loadable function arguments containing window functions or subqueries could produce unexpected
results. (Bug #32424455)
• Improper handling of temporary tables used for cursors within stored procedures could result in
unexpected server behavior. (Bug #32416811)
• Use of the symbol TRUE in the source resulted in a build failure on some platforms. This was
replaced by true. (Bug #32406197, Bug #102308)
• The privilege check used to determine whether users can see view definitions in the
INFORMATION_SCHEMA.VIEWS table worked incorrectly. (Bug #32405811)
• For recursive common table expressions, an assertion could be raised if it became necessary to
convert an in-memory temporary table to on-disk. (Bug #32404597)
• A prepared statement employing a user-created function was not handled correctly when the function
took no arguments. (Bug #32404542)
• A clone plugin installation failure could cause subsequent installation attempts to fail. (Bug
#32402158, Bug #102240)
• Some internal functions used with temporal column types did not provide proper handling for YEAR
values. (Bug #32395335)
These long strings caused problems for some string conversion routines, since their actual lengths
could exceed the expected maximums. We fix this by explicitly telling my_gcvt the desired length
whenever we fetch a FLOAT or DOUBLE in a string context. (Bug #32385934)
149
MySQL 8.0 Release Notes
• Within triggers, use of RAND() with no arguments could lead to unexpected server behavior. (Bug
#32372805)
• When an Item_cache object was used in a prepared statement or stored procedure, it might
point to a Field object that was used in a previous execution. We solve this issue by replacing the
cached field member with an Item_field, which is persistent for the lifetime of the procedure. (Bug
#32367019)
• A missing tablespace error was reported on the recipient MySQL server instance
after a remote cloning operation. The tablespace was not cloned due to the
innodb_validate_tablespace_paths variable being disabled on the donor instance, which
resulted in the associated tablespace object not being loaded. A check is now performed before a
cloning operation to ensure that all tablespace objects are loaded. (Bug #32354908, Bug #102137)
• Some query blocks containing large numbers of EXISTS subqueries were not always handled
correctly. (Bug #32343143)
• mysqlpump could exit unexpectedly if a SHOW CREATE TABLE statement failed. (Bug #32340208)
• A long running remote cloning operation failed due to a low wait_timeout setting on the donor
MySQL Server instance. Donor threads use the MySQL Server wait_timeout setting when
listening for Clone protocol commands. To avoid timeout failures on donor instances with a low
wait_timeout setting, the Clone idle timeout is now set to the default wait_timeout setting,
which is 28800 seconds (8 hours). Clone network read and write timeout values were also increased.
(Bug #32340112, Bug #102097)
• Replication threads running in the server were visible in the Performance Schema threads table,
but failed to appear in the variables_by_thread or status_by_thread tables. Now they
appear in all three tables. Thanks to Facebook for the contribution. (Bug #32335496, Bug #102115)
• A query string was displayed before it had been rewritten. (Bug #32335263, Bug #32628376)
• For builds compiled using the libedit library, if the mysql client was invoked with the --
default-character-set=utf8 option, libedit rejected input of multibyte characters. (Bug
#32329078, Bug #32583436, Bug #102806)
• On Windows, large result sets could cause the mysql client to exit unexpectedly. (Bug #32316323,
Bug #102051)
• Preparing a query expression for repeated execution could raise an assertion if an error occurred
during preparation. (Bug #32291841)
• Functional index creation did not handle the column name as not case-sensitive. (Bug #32287186,
Bug #101994)
• Temporary tables bound to triggers during statement execution could cause an unexpected server
exit. (Bug #32267749, Bug #32288089, Bug #32299045)
• Improved NULL and error handling in calculations involving decimal values. (Bug #32258228, Bug
#32497850)
• An assertion was raised if there was an open handler to a table in a schema when the schema was
altered to be read only. (Bug #32248313)
150
MySQL 8.0 Release Notes
• MySQL produced invalid metadata for a number of temporal functions returning integer values.
These functions included TO_DAYS(), PERIOD_DIFF(), PERIOD_ADD(), TO_SECONDS(),
DAYOFMONTH(), DAYOFYEAR(), HOUR(), and MINUTE(), among others. (Bug #32239578)
• Table subqueries of a natural join which retrieved only invisible columns were not handled correctly.
(Bug #32235285)
• For debug builds, using ALTER TABLE to set a column to have a DEFAULT value of TRUE raised an
assertion. (Bug #32235058)
• When an error was raised while evaluating a condition that was pushed down to the storage engine
using index condition pushdown, the storage engine sometimes ignored the error and returned an
error code indicating success, which could lead to assertion failures later.
Now in such cases, we make sure that the executor detects that an error has been raised, and stop
execution at that point. (Bug #32234773)
• For debug builds with binary logging disabled, ALTER TABLE ... MODIFY COLUMN with an invalid
DEFAULT value raised an assertion. (Bug #32234194)
• Preparation of an aggregate function sometimes hit an assertion in debug builds when the function
took a constant scalar subquery as argument and the scalar subquery raised an error. (Bug
#32231698)
• For debug builds, improper character set handling for NULLIF() evaluated in aggregate context
raised an assertion. (Bug #32231557)
• Upgrading a MySQL instance with a very large number of tables consumed an excessive amount of
memory. Memory allocated to analyze data dictionary entities for possible upgrade was not released
until all entities were processed. (Bug #32226180, Bug #101818)
• ANALYZE TABLE executed on a table concurrently with a long-running query on the same table
caused subsequent queries on the table to wait for the long-running query to finish. This wait induced
by ANALYZE TABLE is now eliminated, thus allowing the subsequent queries to execute with no
wait. (Bug #32224917)
• Statements using a LIKE expression with an ESCAPE clause were not always handled correctly.
(Bug #32213959)
• On ARM platforms, an assertion could be raised in utilities used during the build process. (Bug
#32209415)
• InnoDB did not always handle some legal names for table partitions correctly. (Bug #32208630)
• SHOW CREATE VIEW produced invalid syntax for views created with a ROLLUP clause. This issue
also affected mysqldump, which uses SHOW CREATE VIEW. (Bug #32197353, Bug #101740)
• Connection establishment failure could cause the server to count the number of open connections
incorrectly. (Bug #32156518)
• Refactoring work done in MySQL 8.0.19 did not handle left joins correctly on columns using functions
such as IFNULL(). (Bug #32141711)
151
MySQL 8.0 Release Notes
• The optimizer could choose to use a Skip Scan even for backward index scans for which it is
inapplicable, resulting in unpredictable server behavior. (Bug #32127290)
• SHOW CREATE USER caused any pending transaction to commit. (Bug #32123671)
• Loadable function arguments containing window functions were evaluated at prepare time despite
the fact that window functions are set up quite late in the prepare process. Now evaluation of these
is delayed until execution time, similarly to how this is performed with respect to loadable function
arguments containing subqueries. (Bug #32122078, Bug #32393265)
• Creating a table containing a column with a nonconstant default expression caused subsequent
ALTER TABLE statements to fail. (Bug #32121425, Bug #101486)
• Updating a BLOB-like column with a value from a larger BLOB-like column could cause the updated
column to have the wrong size, even zero. (Bug #32112403)
• Improper locking on an internal queue could cause mysqlpump to exit unexpectedly. (Bug
#32067013)
• On MacOS, the preference pane now includes an option to load the configured my.cnf file during
initialization. (Bug #32057159)
• The server did not always prepare correctly a statement using GROUP_CONCAT() on a SELECT with
an ORDER BY clause. (Bug #32053547, Bug #31947466)
• Errors occurring in window functions were not always correctly propagated, which could lead to
assertion failures in debug builds. (Bug #32028154)
• Calling XA COMMIT on a transaction started by another thread could result in Address Sanitizer
warnings. (Bug #32025408)
• When the mysql client was used in batch mode, its parser could be confused by USE followed by
DROP DATABASE when the USE database name was quoted. (Bug #32015466, Bug #101124)
• A change in MySQL 8.0.17 caused comp_err to become much slower. Normal performance has
been restored. (Bug #32014733)
• Using CAST() on a DATE or DATETIME value in an INSERT statement raised a warning for
"0000-00-00" and "2000-02-31", but not for "2000-01-00" or "2000-00-01". Now a
warning is shown in each of these cases also. (Bug #32013612)
• The maximum length of the MASTER_COMPRESSION_ALGORITHMS value for the CHANGE MASTER
TO statement was checked incorrectly. (Bug #32008597)
• When casting a dynamic parameter to YEAR (such as in PREPARE s FROM "SELECT CAST(? AS
YEAR)"), type propagation was not preformed, causing execution of the prepared statement in which
the parameter was used to fail. (Bug #32002844)
• Definitions of some system tables for a MySQL 5.7 instance upgraded to MySQL 8.0 differed from
the definitions of the system tables in a new MySQL 8.0 installation. (Bug #31989290)
• Some SHOW statements using subqueries could result in unexpected server behavior. (Bug
#31853180)
• The SHOW ENGINE PERFORMANCE SCHEMA STATUS statement reported incorrect memory usage
for the Performance Schema. (Bug #31795132, Bug #100624)
152
MySQL 8.0 Release Notes
• When trying to generate an entity data model using Visual Studio 2019, some tables could not
be imported with the entity framework wizard. This was due to a change in MySQL 8.0.21 made
to orthogonal data type aggregation, which handles columns from UNION and from functions or
operators such as CASE and IF(). This makes it possible to return a value of type ENUM or SET,
which did not need to be handled previously in such cases. (Bug #31750645)
• While optimizing the ORDER BY clause of a subquery there was a possibility of cleaning up
a subquery tree referenced in the outer SELECT, which could lead to a premature exit. (Bug
#31721430)
• A malformed name in the mysql.func system table could cause unexpected server behavior. (Bug
#31674599)
• LOAD DATA performance degraded if many long rows were loaded. (Bug #31637142)
• Compiler options for using profile guided optimization with GCC were improved to include -
fprofile-partial-training and -fprofile-update=prefer-atomic when appropriate.
Thanks to Dmitriy Philimonov for the suggestion. (Bug #31450064, Bug #99781)
• A null pointer was incremented during recovery from the redo log, causing a runtime error in an
Undefined Behavior Sanitizer (UBSAN) build. (Bug #31173032, Bug #32428131, Bug #32483976)
• With the log_slow_extra system variable enabled to add the Errno field to slow query log output,
the error number was 0 even for failed statements. (Bug #30769965, Bug #98220)
• On debug builds, certain conversion operations using the utf32 character set could cause
unexpected server behavior. (Bug #30746908)
• SELECT ... FOR UPDATE from a nonexistent Performance Schema table produced
ER_TABLEACCESS_DENIED_ERROR rather than ER_NO_SUCH_TABLE. (Bug #30701047, Bug
#98068)
• Mishandling of stored program local variables could lead to unexpected server behavior. (Bug
#30366310)
• The Performance Schema metadata_locks table could show incorrect DURATION values, such as
when a metadata lock taken for a TRANSACTION duration was later modified to EXPLICIT duration
by a RENAME TABLE operation. (Bug #30065213, Bug #96237)
• The audit_log plugin could fail to store its encryption password if it generated one at startup. (Bug
#29559793)
• Uninstalling a plugin could affect subsequent execution of prepared statements. (Bug #29363867)
• Conversion of string-valued user-defined variables or function results to double (for example, using
CAST()) did not emit a warning when truncation occurred. (Bug #27969934, Bug #21943299)
• When a view definition used LIKE with an ESCAPE clause, the contents of the ESCAPE clause were
ignored, leading to wrong results. (Bug #26086751)
• It was possible to insert illegal ASCII values (outside 7-bit range) into character columns that used
the ascii character set. This is now prohibited. (Bug #24847620)
• To enable use of spaces and other special characters within configuration values,
mysql_config_editor now surrounds values it writes to the configuration file with double quote
153
MySQL 8.0 Release Notes
characters, and also escapes double quote characters used within values. (Bug #19953349, Bug
#74691)
• When the aggregate iterator finds no rows, it calls on each item in its SELECT list to inform them of
this (for example, so that COUNT(*) can set itself to zero, or SUM(foo) can set itself to NULL). After
internal work done in MySQL 8.0.22, it could also inadvertently call hidden items. In some queries
with doubly nested subqueries, one such hidden item could become its own parent subquery (and
scalar subqueries in MySQL have special legacy handling of this call, for queries which are not
ONLY_FULL_GROUP_BY), causing the entire subquery to return NULL when it should not have done
so.
This is fixed by making the call only on visible items, as in MySQL 8.0.21 and earlier. (Bug #102101,
Bug #32335256)
• When interpreting the old-style plan to access paths, cache invalidators for LATERAL were delayed
until all outer joins were completed, since outer joins could produce null-complemented rows that
should also invalidate caches. Problems arose when an outer join contained a LATERAL, and that
LATERAL referred only to tables from within the same outer join; in such cases the invalidator should
be applied immediately and not delayed, lest we miss emitted rows, and the cache be incorrectly
kept. In particular, this could happen when certain Information Schema tables were on the right side
of an outer join, as these are now views defined using LATERAL.
We fix this by delaying emission of the invalidator until we are inside the same (outer) join nest as the
materialization to be invalidated, but no further. This also deals correctly with the case where rows
from a table should invalidate two or more separate materializations, where some are within the join
and some are higher up. (Bug #101460, Bug #32113029, Bug #32311147)
• An optimizer trace printed floating-point numbers with a maximum six characters, which meant that
the precision could be very low for many values, given that sign, decimal point, and exponent could
use many of these characters. This was especially problematic for large numbers, whose precision
could thus be as small as 1, and which could be rounded to values whose absolute value exceeded
DBL_MAX and so could be rejected by JSON parsers.
Now such numbers are always printed in an optimizer trace with a precision of 6. (Bug #101457, Bug
#32113020)
• Filesort was used for a query having an ORDER BY ... DESC clause, even when an index on the
descending column was available and used. This happened because an ORDER BY sub-clause was
not removed due to matching a field in an equality predicate, even though it should have, so that the
optimizer did not match the query with the descending index, leading to suboptimal performance.
(Bug #101220, Bug #32038406)
• The debug server hit an assert when optimizer_search_depth was less than the number of
JOIN_TAB structures used for a join. (Bug #100288, Bug #31655483)
• Following the ALTER TABLE operations EXCHANGE PARTITION, IMPORT TABLESPACE, and
IMPORT PARTITION TABLESPACE, serialized digital information reflecting the previous role of
the tablespace was left behind. Now in such cases, the old SDI is explicitly removed from both
tablespaces involved in the exchange or import of a tablespace. (Bug #98501, Bug #30878065)
• Type resolution performed by the integer division operator (DIV) yielded a precision of one less than
expected in the result.
Our thanks to Kaiwang Chen for the contribution. (Bug #96459, Bug #30156563)
154
MySQL 8.0 Release Notes
• C API Notes
• Compilation Notes
• Firewall Notes
• Optimizer Notes
• Pluggable Authentication
• Security Notes
• X Plugin Notes
• Bugs Fixed
The new privileges apply only at the global level. For more information, see Privileges Provided by
MySQL, and FLUSH Statement.
The mysql_refresh() C API function performs operations similar to those of various FLUSH
statements, but is unaffected by this change. It still requires the RELOAD privilege regardless of the
operation for which it is invoked. (WL #14303)
C API Notes
• For some applications, it may be useful to define metadata on a per-query basis. Examples include
the URL of the page that produced a query, or extra processing information to be passed with a
query for use by a plugin such as an audit plugin or query rewrite plugin. MySQL now supports this
155
MySQL 8.0 Release Notes
capability without the use of workarounds such as specially formatted comments included in query
strings:
• On the client side, the mysql_bind_param() C API function enables defining query attributes.
These attributes apply to the next SQL statement sent to the server for execution. Additionally,
the mysql and mysqltest clients have a query_attributes command that enables defining
query attributes.
• On the server side, a component service provides access to query attributes. A component named
query_attributes uses this service to implement a mysql_query_attribute_string()
loadable function that enables obtaining attribute values within SQL statements. The
query_attributes component is optional but must be installed for the function to be available.
Thanks to Facebook for suggesting the idea (and for contributing code, although it was not used).
(Bug #27855905, Bug #28686334, WL #12542)
Compilation Notes
• Thanks to Tzachi Zidenberg, who contributed a patch for compiling MySQL on aarch64 (ARM64).
(Bug #31815236, Bug #100664)
A new status variable, Com_change_replication_source, has been added as an alias for the
Com_change_master status variable. Both the old and new version of the statement update both
the old and new version of the status variable.
The server rewrites all CHANGE MASTER TO statements as CHANGE REPLICATION SOURCE TO
statements in the query log. The same is done for the statements START SLAVE, STOP SLAVE,
SHOW SLAVE STATUS, SHOW SLAVE HOSTS and RESET SLAVE. The event name for the CHANGE
MASTER TO statement is set to statement/sql/change_replication_source in the
statement history table. (Bug #32145023, WL #14189)
156
MySQL 8.0 Release Notes
database, or to a file in the data directory. The FILE setting was already deprecated in a previous
release, and tables are the default for the replication metadata repositories in MySQL 8.0. (WL
#13958)
• Flushing the host cache can be done using any of these methods:
• Execute a TRUNCATE TABLE statement that truncates the Performance Schema host_cache
table. This requires the DROP privilege for the table.
Although those methods are equivalent in effect, granting the RELOAD privilege enables a number of
other operations in addition to host cache flushing, which is undesirable from a security standpoint.
Granting the DROP privilege for the host_cache table is preferable because it has a more limited
scope. Therefore, the FLUSH HOSTS statement is deprecated and will be removed in a future
MySQL version. Instead, truncate the host_cache table.
Firewall Notes
• Administrators perform MySQL Enterprise Firewall management by registering profiles that specify
sets of rules for permitted statements (allowlists). Previously, profiles could be associated only with
individual accounts, so that, to apply a given allowlist to multiple account profiles, it was necessary to
duplicate the rule set for each profile. For easier administration and greater flexibility, the firewall now
provides group profile capabilities:
• Named group profiles can be created. A group profile can include multiple accounts as members,
and an account can be a member of multiple group profiles.
• Each group profile has its own allowlist. The profile allowlist applies to all member accounts,
eliminating the need to duplicate it across multiple account profiles.
Optimizer Notes
• Switched the hash table used for hash joins from an unordered multimap to an unordered flat map
implemented with a multimap adapter. This change yields the following improvements:
• Less memory usage due to less hash table overhead, less space used for alignment and key/value
lengths, and better memory usage with many equal keys; this should also reduce the frequency at
which it is necessary to spill to disk
• Better memory control by approaching the allowed join buffer size more closely rather than being
effectively limited to approximately 2/3 of join_buffer_size, and by making it possible to free
old memory when the hash table grows
157
MySQL 8.0 Release Notes
• Performance overhead of timer code was reduced. This should be of most benefit to workloads with
high concurrency using the Performance Schema. Thanks to Georgy Kirichenko for the contribution.
(Bug #31960377, Bug #101018)
Pluggable Authentication
• The MySQL Enterprise Edition SASL LDAP authentication plugin now supports SCRAM-SHA-256
as an authentication method for MySQL clients and servers. SCRAM-SHA-256 is similar to SCRAM-
SHA-1 but is more secure. Use of SCRAM-SHA-256 requires an OpenLDAP server built using Cyrus
SASL 2.1.27 or higher. See LDAP Authentication Methods. (WL #14180)
Security Notes
• For platforms on which OpenSSL libraries are bundled, the linked OpenSSL library for MySQL
Server has been updated to version 1.1.1i. Issues fixed in the new OpenSSL version are described
at https://www.openssl.org/news/cl111.txt and https://www.openssl.org/news/vulnerabilities.html.
(Bug #32260610)
X Plugin Notes
• For X Protocol connections using the MYSQL41 authentication method, if the nonce sent by the
server was shorter than 20 bytes, the connection logic did not handle it correctly. (Bug #32036194)
• If a query that was building up a resultset was killed, X Plugin interpreted this as meaning the
server session had been killed, and dropped the connection. The status of a query is now checked
separately from the status of the server session. (Bug #31954296)
• A deadlock could occur if an X Protocol session attempted to display X Plugin status variables or
settings at the same time as another X Protocol session was being released and reset. The situation
is now handled appropriately. (Bug #31931873)
• If an X Protocol client with a connection to a server remains idle (not sending to the server) for
longer than the relevant X Plugin timeout setting (read, write, or wait timeout), X Plugin closes the
connection. In the case of a read timeout, the plugin returns a warning notice with the error code
ER_IO_READ_ERROR to the client application.
From MySQL 8.0.23, X Plugin now also sends a warning notice if a connection is actively closed
due to a server shutdown, or by the connection being killed from another client session. In the case
of a server shutdown, the warning notice is sent to all authenticated X Protocol clients with open
connections, with the ER_SERVER_SHUTDOWN error code. In the case of a killed connection, the
warning notice is sent to the relevant client with the ER_SESSION_WAS_KILLED error code, unless
the connection was killed during SQL execution, in which case a fatal error is returned with the
ER_QUERY_INTERRUPTED error code.
Client applications can use the warning notices to display to users, or to analyze the reason for
disconnection and decide whether to attempt reconnection to the same server, or to a different
server. (WL #14166)
158
MySQL 8.0 Release Notes
• For classic MySQL protocol, if an SQL query is using metadata locking or the sleep function, the
connection to the server is checked periodically to verify that it is still alive. If not, the query can be
stopped so that it does not continue to consume resources. Previously, X Protocol did not carry out
these checks, and assumed that the connection was still alive. The check has now been added for X
Protocol. (WL #14167)
• Dropping a large tablespace on a MySQL instance with a large buffer pool (>32GBs).
• Dropping a tablespace with a significant number of pages referenced from the adaptive hash
index.
The pages of dropped or truncated tablespaces and associated AHI entries are now removed from
the buffer pool passively as pages are encountered during normal operations. Previously, dropping
or truncating tablespaces initiated a full list scan to remove pages from the buffer pool immediately,
which negatively impacted performance. (Bug #31008942, Bug #98869, WL #14100)
• InnoDB: The new AUTOEXTEND_SIZE option defines the amount by which InnoDB extends the
size of a tablespace when it becomes full, making it possible to extend tablespace size in larger
increments. Allocating space in larger increments helps to avoid fragmentation and facilitates
ingestion of large amounts of data. The AUTOEXTEND_SIZE option is supported with the CREATE
TABLE, ALTER TABLE, CREATE TABLESPACE, and ALTER TABLESPACE statements. For more
information, see Tablespace AUTOEXTEND_SIZE Configuration.
• InnoDB: InnoDB now supports encryption of doublewrite file pages belonging to encrypted
tablespaces. The pages are encrypted using the encryption key of the associated tablespace. For
more information, see InnoDB Data-at-Rest Encryption. (WL #13775)
• InnoDB: InnoDB atomics code was revised to use C++ std::atomic. (WL #14235)
The connection is failed over to another group member in the following situations:
• The currently connected source does not have the highest weighted priority in the group.
159
MySQL 8.0 Release Notes
managed) servers, so the connection for a single server is also now failed over if another source
server is available that has a higher weighted priority. (WL #14019)
• When invoked with the --all-databases option, mysqldump now dumps the mysql database
first, so that when the dump file is reloaded, any accounts named in the DEFINER clause of other
objects will already have been created. (Bug #32141046)
• Some overhead for disabled Performance Schema and LOCK_ORDER tool instrumentation was
identified and eliminated. (Bug #32105698)
• For BLOB and TEXT columns that have a default value expression, the
INFORMATION_SCHEMA.COLUMNS table and SHOW COLUMNS statement now display the expression.
(Bug #31856459)
The replication applier on a multithreaded replica has always handled data access deadlocks
that were identified by the storage engines involved. However, some other types of lock were not
detected by the replication applier, such as locks involving access control lists (ACLs) or metadata
locking (for example, FLUSH TABLES WITH READ LOCK statements). This could lead to three-actor
deadlocks with the commit order locking, which could not be resolved by the replication applier, and
caused replication to hang indefinitely. From MySQL 8.0.23, deadlock handling on multithreaded
replicas that preserve the commit order has been enhanced to mitigate these types of deadlocks.
The deadlocks are not specifically resolved by the replication applier, but the applier is aware of them
and initiates automatic retries for the transaction, rather than hanging. If the retries are exhausted,
replication stops in a controlled manner so that the deadlock can be resolved manually. (Bug
#107574, Bug #34291887, WL #13574)
• CRC calculations for binlog checksums are faster on ARM platforms. Thanks to Krunal Bauskar for
the contribution. (Bug #99118, Bug #31101633, Bug #32163391)
• Replication channels can now be set to assign a GTID to replicated transactions that do not already
have one, using the ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS option of the CHANGE
REPLICATION SOURCE TO statement. This feature enables replication from a source that does not
use GTID-based replication, to a replica that does. For a multi-source replica, you can have a mix
of channels that use ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS, and channels that do not.
The GTID can include the replica’s own server UUID or a server UUID that you assign to identify
transactions from different sources.
• The new temptable_max_mmap variable defines the maximum amount of memory the TempTable
storage engine is permitted to allocate from memory-mapped temporary files before it starts storing
data to InnoDB internal temporary tables on disk. A setting of 0 disables allocation of memory
from memory-mapped temporary files. For more information, see Internal Temporary Table Use in
MySQL. (WL #14125)
160
MySQL 8.0 Release Notes
Bugs Fixed
• InnoDB: A CREATE TABLE operation that specified the COMPRESSION option was permitted with
a warning on a system that does not support hole punching. The operation now fails with an error
instead. (Bug #32174200)
• InnoDB: A MySQL DB system restart following an upgrade that was initiated while a data load
operation was in progress raised an assertion failure. (Bug #32173596)
• InnoDB: An error message regarding the number of truncate operations on the same undo
tablespace between checkpoints incorrectly indicated a limit of 64. The limit was raised from 64 to
50,000 in MySQL 8.0.22. (Bug #32151601, Bug #101601)
• InnoDB: rw_lock_t and buf_block_t source code structures were reduced in size. (Bug
#32084500)
• InnoDB: An InnoDB transaction became inconsistent after creating a table using a storage engine
other than InnoDB from a query expression that operated on InnoDB tables. (Bug #32079103)
• InnoDB: In some circumstances, such as when an existing gap lock inherits a lock from a deleted
record, the number of locks that appear in the INFORMATION_SCHEMA.INNODB_TRX table could
diverge from the actual number of record locks.
Thanks to Fungo Wang from Alibaba for the patch. (Bug #32068538, Bug #101305)
• InnoDB: An off-by-one error in Fil_system sharding code was corrected, and the maximum
number of shards (MAX_SHARDS) was changed to 69. (Bug #32052821, Bug #101260)
• InnoDB: The TempTable storage engine memory allocator allocated extra blocks of memory
unnecessarily. (Bug #32018553)
• InnoDB: A SELECT COUNT(*) operation on a table containing uncommitted data performed poorly
due to unnecessary I/O.
Thanks to Brian Yue for the contribution. (Bug #31997733, Bug #100966)
• InnoDB: A race condition when shutting down the log writer raised an assertion failure. (Bug
#31997362)
• InnoDB: Page cleaner threads were not utilized optimally in sync-flush mode, which could cause
page flush operations to slow down or stall in some cases. Sync-flush mode occurs when InnoDB
is close to running out of free space in the redo log, causing the page cleaner coordinator to initiate
aggressive page flushing. (Bug #31994031)
• InnoDB: A high frequency of updates while undo log truncation was enabled caused purge to lag.
The lag was due to the innodb_purge_rseg_truncate_frequency setting being changed
temporarily from 128 to 1 when an undo tablespace was selected for truncation. The code that
modified the setting has been removed. (Bug #31991688)
If the AUTOEXTEND_SIZE option is defined for an undo tablespace, the undo tablespace is extended
by the greater of the AUTOEXTEND_SIZE setting and the extension size determined by the logic
described above.
161
MySQL 8.0 Release Notes
When an undo tablespace is truncated, it is normally recreated at 16MB in size, but if the
current file extension size is larger than 16MB, and the previous file extension happened within
the last second, the new undo tablespace is created at a quarter of the size defined by the
innodb_max_undo_log_size variable.
Stale undo tablespace pages are no longer removed at the next checkpoint. Instead, the pages are
removed in the background by the InnoDB master thread. (Bug #31965404, Bug #32020900, Bug
#101194)
• InnoDB: An invalid pointer caused a shutdown failure on a MySQL Server compiled with the
DISABLE_PSI_MEMORY source configuration option enabled. (Bug #31963333)
• InnoDB: A long SX lock held by an internal function that calculates new statistics for a given index
caused a failure. (Bug #31889883)
• InnoDB: After dropping a FULLTEXT index and renaming the table to move it to a new schema, the
FULLTEXT auxiliary tables were not renamed accordingly and remained in the old schema directory.
(Bug #31773368, Bug #100570)
• InnoDB: After upgrading to MySQL 8.0, a failure occurred when attempting to perform a DML
operation on a table that was previously defined with a full-text search index. (Bug #31749490)
• InnoDB: Importing a tablespace with a page-compressed table did not report a schema mismatch
error for source and destination tables defined with a different COMPRESSION setting. The
COMPRESSION setting of the exported table is now saved to the .cfg metadata file during the
FLUSH TABLES ... FOR EXPORT operation, and that information is checked on import to ensure
that both tables are defined with the same COMPRESSION setting. (Bug #31744694)
• InnoDB: Dummy keys used to check if the MySQL Keyring plugin is functioning were left behind in
an inactive state, and the number of inactive dummy keys increased over time. The actual master
key is now used instead, if present. If no master key is available, a dummy master key is generated.
(Bug #31737924)
• InnoDB: Querying the INFORMATION_SCHEMA.FILES table after moving the InnoDB system
tablespace outside of the data directory raised a warning indicating that the innodb_system
filename is unknown. (Bug #31603047)
162
MySQL 8.0 Release Notes
Thanks to Venkatesh Prasad for the contribution. (Bug #31599938, Bug #100118)
• InnoDB: Persisting GTID values for XA transactions affected XA transaction performance. Two
GTID values are generated for XA transactions, one for the prepare stage and another for the
commit stage. The first GTID value is written to the undo log and later overwritten by the second
GTID value. Writing of the second GTID value could only occur after flushing the first GTID value
to the gtid_executed table. Space is now reserved in the undo log for both XA transaction GTID
values. (Bug #31467953, Bug #99638)
• InnoDB: InnoDB source files were updated to address warnings produced when building Doxygen
source code documentation. (Bug #31354760)
• InnoDB: The full-text search synchronization thread attempted to read a previously-freed word from
the index cache. (Bug #31310404)
• InnoDB: A 20µs sleep in the buf_wait_for_read() function introduced with parallel read
functionality in MySQL 8.0.17 took 1ms on Windows, causing an unexpected timeout when running
certain tests. Also, AIO threads were found to have uneven amounts of waiting operating system IO
requests. (Bug #31095274)
• InnoDB: Cleanup in certain replicated XA transactions failed to reattach transaction object (trx_t),
which raised an assertion failure. (Bug #31006095)
• InnoDB: The tablespace encryption type setting was not properly updated due to a failure during
the resumption of an ALTER TABLESPACE ENCRYPTION operation following a server failure. (Bug
#30883833, Bug #98537)
• InnoDB: An interrupted tablespace encryption operation did not update the encrypt_type table
option information in the data dictionary when the operation resumed processing after the server was
restarted. (Bug #30883833, Bug #98537, Bug #30888919, Bug #98564)
• InnoDB: Internal counter variables associated with thread sleep delay and threads entering an
leaving InnoDB were revised to use C++ std::atomic. Built-in atomic operations were removed.
Thanks to Yibo Cai from ARM for the contribution. (Bug #30567060, Bug #97704)
• InnoDB: A relaxed memory order was implemented for dictionary memory variable fetch-add
(dict_temp_file_num.fetch_add) and store (dict_temp_file_num.store) operations.
Thanks to Yibo Cai for the contribution. (Bug #30567054, Bug #97703)
• InnoDB: A background thread that resumed a tablespace encryption operation after the server
started failed to take an metadata lock on the tablespace, which permitted concurrent DDL
operations and led to a race condition with the startup thread. The startup thread now waits until the
tablespace metadata lock is taken. (Bug #28531637)
• Partitioning: ALTER TABLE t1 EXCHANGE PARTITION ... WITH TABLE t2 led to an assert
when t1 was not a partitioned table. (Bug #100971, Bug #31941543)
163
MySQL 8.0 Release Notes
the asynchronous connection failover mechanism. The network namespace for a replication channel
is managed using the CHANGE REPLICATION SOURCE statement, and has special requirements
for Group Replication source servers, so it should no longer be specified in the functions. (Bug
#32078189)
• Replication: When using network namespaces in a replication channel and the initial connection
from the replica to the master was interrupted, subsequent connection attempts failed to use the
correct namespace information. (Bug #31954087)
• Replication: If a group member was expelled and made an auto-rejoin attempt at a point when
some tables on the instance were locked (for example while a backup was running), the attempt
failed and no further attempts were made. This scenario is now handled correctly. (Bug #31460690)
• Replication: As the number of replicas replicating from a semisynchronous source server increased,
locking contention could result in a performance degradation. The locking mechanisms used
by the plugins have been changed to use shared locks where possible, avoid unnecessary lock
acquisitions, and limit callbacks. The new behaviors can be implemented by enabling the following
system variables:
Both system variables can be enabled before or after installing the semisynchronous replication
plugin, and can be enabled while replication is running. Semisynchronous replication source servers
can also get performance benefits from enabling these system variables, because they use the same
locking mechanisms as the replicas. (Bug #30519928)
• Replication: On a multi-threaded replica where the commit order is preserved, worker threads
must wait for all transactions that occur earlier in the relay log to commit before committing their
own transactions. If a deadlock occurs because a thread waiting to commit a transaction later in
the commit order has locked rows needed by a transaction earlier in the commit order, a deadlock
detection algorithm signals the waiting thread to roll back its transaction. Previously, if transaction
retries were not available, the worker thread that rolled back its transaction would exit immediately
without signalling other worker threads in the commit order, which could stall replication. A worker
thread in this situation now waits for its turn to call the rollback function, which means it signals the
other threads correctly. (Bug #26883680, Bug #87796)
• Replication: GTIDs are only available on a server instance up to the number of non-negative values
for a signed 64-bit integer (2 to the power of 63 minus 1). If you set the value of gtid_purged to
a number that approaches this limit, subsequent commits can cause the server to run out of GTIDs
and take the action specified by binlog_error_action. From MySQL 8.0.23, a warning message
is issued when the server instance is approaching the limit. (Bug #26035544)
164
MySQL 8.0 Release Notes
the write set information cannot be discarded if the transaction is to complete. The byte limit set by
group_replication_transaction_size_limit is applied instead of the numeric limit, and if
the limit is exceeded, the transaction fails to execute. (Bug #32019842)
• Microsoft Windows: On Windows, running the MySQL server as a service caused shared-memory
connections to fail. (Bug #32009251)
• JSON: JSON_ARRAYAGG() did not always perform proper error handling. (Bug #31856260, Bug
#32012559, Bug #32181438)
Now in such cases, an in-place update (that is, a partial update) is also performed when the target
table is an updatable view. (Bug #25840784)
• JSON: Work done in MySQL 8.0.22 to cause prepared statements to be prepared only once
introduced a regression in the handling of dynamic parameters to JSON functions. All JSON
arguments were classified as data type MYSQL_TYPE_JSON, which overlooked the fact that JSON
functions take two kinds of JSON parameters—JSON values and JSON documents—and this
distinction cannot be made with the data type only. For Bug #31667405, this problem was solved for
comparison operators and the IN() operator by making it possible to tag a JSON argument as being
a scalar value, while letting arguments to other JSON functions be treated as JSON documents.
The present fix restores for a number of JSON functions their treatment of certain arguments as
JSON values, as listed here:
The third, fifth, seventh, and subsequent odd-numbered arguments to the functions
JSON_INSERT(), JSON_REPLACE(), JSON_SET(), JSON_ARRAY_APPEND(), and
JSON_ARRAY_INSERT(). (Bug #101284, Bug #32063203)
• JSON: When mysqld was run with --debug, attempting to execute a query that made use of a
multi-valued index raised an error. (Bug #99833, Bug #31474182)
• Use of the thread_pool plugin could result in Address Sanitizer warnings. (Bug #32213294)
• While pushing a condition down to a materialized derived table, and a condition is partially pushed
down, the optimizer may, in some cases in which a query transformation has added new conditions
to the WHERE condition, call the internal fix_fields() function for the condition that remains in the
outer query block. A successful return from this function call was misinterpreted as an error, leading
to the silent failure of the original statement. (Bug #32150145)
• Multiple calls to a stored procedure containing an ALTER TABLE statement that included an ORDER
BY clause could cause a server exit. (Bug #32147402)
• Prepared statements involving stored programs could cause heap-use-after-free memory problems.
(Bug #32131022, Bug #32045681, Bug #32051928)
165
MySQL 8.0 Release Notes
• Queries on INFORMATION_SCHEMA tables that involved materialized derived tables could fail. (Bug
#32127562, Bug #101504)
• A potential buffer overflow was fixed. Thanks to Sifang Zhao for pointing out the issue, and for
suggesting a fix (although it was not used). (Bug #32113015, Bug #101448)
• Conversion of FLOAT values to values of type INT could generate Undefined Behavior Sanitizer
warnings. (Bug #32099994, Bug #32100033)
• In multiple-row queries, the LOAD_FILE() function evaluated to the same value for every row. (Bug
#32096341, Bug #101401)
• Generic Linux tar file distributions had too-restrictive file permissions after unpacking, requiring a
manual chmod to correct. (Bug #32080900)
• For debug builds, prepared SET statements containing subqueries in stored procedures could raise
an assertion. (Bug #32078387)
• For prepared statements, illegal mix of collations errors could occur for legal collation
mixes. (Bug #32077842, Bug #101346, Bug #32145078, Bug #101575)
The function REGEXP_SUBSTR() can always return NULL, so no such check is needed, and for this
function we make sure that one is not performed. (Bug #32053093)
• Testing an aggregate function for IS NULL or IS NOT NULL in a HAVING condition using WITH
ROLLUP led to wrong results. (Bug #32049313)
• When a new aggregate function was added to the current query block because an inner query block
had an aggregate function requiring evaluation in the current one, the server did not add rollup
wrappers to it as needed. (Bug #32034914)
• For debug builds, certain CREATE TABLE statements with CHECK constraints could raise an
assertion. (Bug #32018406, Bug #101180)
• Incorrect BLOB field values were passed from InnoDB during a secondary engine load operation.
(Bug #32014483)
• The LOCK_ORDER tool did not correctly represent InnoDB share exclusive locks. (Bug #31994052)
• The server did not handle properly an error raised when trying to use an aggregation function with an
invalid column type as part of a hash join. (Bug #31989333)
• The length of the WORD column of the INFORMATION_SCHEMA.KEYWORDS table could change
depending on table contents. (Bug #31982157)
• The Performance Schema host_cache table was empty and did not expose the contents of
the host cache if the Performance Schema was disabled. The table now shows cache contents
regardless of whether the Performance Schema is enabled. (Bug #31978763)
• A HANDLER READ statement sometimes hit an assert when a previous statement did not restore the
original value of THD::mark_used_columns after use. (Bug #31977414)
• Importing a compressed table could cause an unexpected server exit if the table contained values
that were very large when uncompressed. (Bug #31943021)
• Removed a memory leak that could occur when a subquery using a hash join and LIMIT was
executed repeatedly. (Bug #31940549)
166
MySQL 8.0 Release Notes
• Memory used for storing partial-revokes information could grow excessively for sessions that
executed a large number of statements. (Bug #31919448)
• The server did not handle all cases of the WHERE_CONDITION optimization correctly. (Bug
#31905199)
• FLUSH TABLES WITH READ LOCK could block other sessions from executing SHOW TABLE
STATUS. (Bug #31894662)
• In some cases, MIN() and MAX() incorrectly returned NULL when used as window functions with
temporal or JSON values as arguments. (Bug #31882291)
• GRANT ... GRANT OPTION ... TO and GRANT ... TO .. WITH GRANT OPTION sometimes
were not correctly written to the server logs. (Bug #31869146, Bug #100793)
• For debug builds, CREATE TABLE using a partition list of more than 256 entries raised an assertion.
(Bug #31867653)
• It was possible for queries in the file named by the init_file system variable to cause server
startup failure. (Bug #31835782)
• When performing a hash join, the optimizer could register a false match between a negative integer
value and a very large unsigned integer value. (Bug #31832001, Bug #31940639, Bug #100967)
• SHOW VARIABLES could report an incorrect value for the partial_revokes system variable. (Bug
#31819558, Bug #100677)
• The server automatic upgrade procedure failed to upgrade older help tables that used the latin1
character set. (Bug #31789964)
• Duplicate warnings could occur when executing an SQL statement that read the grant tables in
serializable or repeatable-read transaction isolation level. (Bug #31769242)
• In certain queries with DISTINCT aggregates (which in general are solved by sorting before
aggregation), the server used a temporary table instead of streaming due to the mistaken
assumption that the logic for handling the temporary table performed deduplication. Now the server
checks for the implied unique index instead, which is more robust and allows for the removal of
unnecessary logic. (Bug #31762806)
• Calling one stored function from within another could produce a conflict in field resolution, resulting in
a server exit. (Bug #31731334)
• Loadable functions defined without a udf_init() method could cause an unexpected server exit.
(Bug #31701219)
• Setting the secure_file_priv system variable to NULL should disable its action, but instead
caused the server to create a directory named NULL. (Bug #31700734, Bug #100384)
• mysqlpump could exit unexpectedly due to improper simultaneous accesses to shared structures.
(Bug #31696241)
• Uninstalling a component and deregistering loadable functions installed by the component was not
properly synchronized with whether the functions were currently in use. (Bug #31646698)
167
MySQL 8.0 Release Notes
• For the engines which support primary key extension, when the total key length exceeded
MAX_KEY_LENGTH or the number of key parts exceeded MAX_REF_PARTS, key parts of primary keys
which did not fit within these limits were not added to the secondary key, but key parts of primary
keys were unconditionally marked as part of secondary keys.
This led to a situation in which the secondary key was treated as a covering index, which meant
sometimes the wrong access method was chosen.
This is fixed by modifying the way in which key parts of primary keys are added to secondary keys so
that those which do not fit within which do not fit within the limits mentioned previously mentioned are
cleared. (Bug #31617858)
• When MySQL is configured with -DWITH_ICU=system, CMake now checks that the ICU library
version is sufficiently recent. (Bug #31600044)
• When invoked with the --binary-as-hex option, mysql displayed NULL values as empty binary
strings (0x).
Selecting an undefined variable returned the empty binary string (0x) rather than NULL. (Bug
#31549724, Bug #31638968, Bug #100251)
The root cause of this issue related to the fact that, when buffering rows for window functions, if the
size of the in-memory temporary table holding these buffered rows exceeds the limit specified, a new
temporary table is created on disk; the frame buffer partition offset is set at the beginning of a new
partition to the total number of rows that have been read so far, and is updated specifically for use
when the temporary table is moved to disk (this being used to calculate the hints required to process
window functions). The problem arose because the frame buffer partition offset was not updated
for the specific case when a new partition started while creating the temporary table on disk, which
caused the wrong rows to be read.
This issue is fixed by making sure to update the frame buffer partition offset correctly whenever a
new partition starts while a temporary table is moved to disk. (Bug #31546816)
• While buffering rows for window functions, if the size of the in-memory temporary table holding
these buffered rows exceeds the limit specified by temptable_max_ram, a new temporary table
is created on disk. After the creation of the temporary table, hints used to process window functions
need to be reset, since the temporary table is now moved to disk, making the existing hints unusable.
When the creation of the temporary table on disk occurred when the first row in the frame buffer
was being processed, the hints had not been initialized and trying to reset these uninitialized hints
resulted in an unplanned server exit.
This issue is fixed by adding a check to verify whether frame buffer hints have been initialized, prior
to resetting them. (Bug #31544404)
• The Performance Schema could produce incorrect results for joins on a CHANNEL_NAME column
when the index for CHANNEL_NAME was disabled with USE INDEX (). (Bug #31544023, Bug
#99989)
168
MySQL 8.0 Release Notes
• When removing unused window definitions, a subquery that was part of an ORDER BY was not
removed. (Bug #31518806)
• In certain cases, the server did not handle multiply-nested subqueries correctly. (Bug #31472704)
• The recognized syntax for a VALUES statement includes an ORDER BY clause, but this clause was
not resolved, so the execution engine could encounter invalid data. (Bug #31387510)
• The server attempted to access a non-existent temporary directory at startup, causing a failure.
Checks were added to ensure that temporary directories exist, and that files are successfully created
in the tmpdir directory. (Bug #31377118)
• While removing redundant sorting, a window's ordering was removed due to the fact that rows were
expected to come in order because of the ordering of another window. When the other window
was subsequently removed because it was unused, this resulted in unordered rows, which was not
expected during evaluation.
Now in such cases, removal of redundant sorts is not performed until after any unused windows have
been removed. In addition, resolution of any rollups has been moved to the preparation phase. (Bug
#31361393)
• Semisynchronous replication errors were incorrectly written to the error log with a subsystem tag
of Server. They are now written with a tag of Repl, the same as for other replication errors. (Bug
#31327337)
• The server did not always correctly handle cases in which multiple WHERE conditions, one of which
was always FALSE, referred to the same subquery. (Bug #31216115)
• Conversion of DOUBLE values to values of type BIT, ENUM, or SET could generate Undefined
Behavior Sanitizer warnings. (Bug #31019130)
• Certain accounts could cause server startup failure if the skip_name_resolve system variable was
enabled. (Bug #31018510)
• Client programs could unexpectedly exit if communication packets contained bad data. (Bug
#30890850)
• When creating a multi-valued or other functional index, a performance drop was seen when
executing a query against the table on which the index was defined, even though the index itself was
not actually used. This occurred because the hidden virtual column that backs such indexes was
evaluated unnecessarily for each row in the query. (Bug #30838749)
• In some cases, the optimizer attempted to compute the hash value for an empty string. Now a fixed
value is always used instead. (Bug #22588319)
169
MySQL 8.0 Release Notes
• The INSERT() and RPAD() functions did not correctly set the character set of the result. (Bug
#22523946, Bug #79909, Bug #31887870, Bug #100841)
• Some corner cases for val1 BETWEEEN val2 AND val3 were fixed, such as that -1 BETWEEN
9223372036854775808 AND 1 returned true. (Bug #22515857, Bug #79878)
• Several issues converting strings to numbers were fixed. (Bug #19186271, Bug #73248)
• Certain group by queries that performed correctly did not return the expected result when WITH
ROLLUP was added. This was due to the fact that decimal information was not always correctly piped
through rollup group items, causing functions returning decimal values such as TRUNCATE() to
receive data of the wrong type. (Bug #101684, Bug #32179240)
• When creating fields for materializing temporary tables (that is, when needing to sort a join), the
optimizer checks whether the item needs to be copied or is only a constant. This was not done
correctly in one specific case; when performing an outer join against a view or derived table
containing a constant, the item was not properly materialized into the table, which could yield
spurious occurrences of NULL in the result. (Bug #101622, Bug #32162862)
Our thanks to Hope Lee for the contribution. (Bug #101256, Bug #32050219)
• For a query having the following form, the column list sometimes assumed an inconsistent state after
temporary tables were created, causing out-of-bounds indexing later:
SELECT * FROM (
SELECT PI()
FROM t1 AS table1, t1 AS table2
ORDER BY PI(), table1.a
) AS d1;
• When aggregating data that was already sorted (known as performing streaming aggregation, due
to no temporary tables being used), it was not possible to determine when a group ended until
processing the first row in the next group, by which time the group expressions to be output were
often already overwritten.
This is fixed by replacing the complex logic previously used with the much simpler method of saving
a representative row for the group when encountering it the first time, so that its columns can easily
be retrieved for the output row when needed. (Bug #100791, Bug #27272052, Bug #31073167, Bug
#31790217, Bug #31868610)
• Subqueries making use of fulltext matching might not perform properly when
subquery_to_derived was enabled, and could lead to an assert in debug builds. (Bug #100749,
Bug #31851600)
• When an ALTER TABLE ... CONVERT TO CHARACTER SET statement is executed, the
character set of every CHAR, VARCHAR, and TEXT column in the table is updated to the new
CHARACTER SET value. This change was also applied to the hidden CHAR column used by an
170
MySQL 8.0 Release Notes
ARRAY column for a multi-valued index; since the character set of the hidden column must be one of
my_charset_utf8mb4_0900_bin or binary, this led to an assert in debug builds of the server.
This issue is resolved by no longer setting the character set of the hidden column to that of the table
when executing the ALTER TABLE statement referenced previously; this is similar to what is done for
BLOB columns in similar circumstances. (Bug #99403, Bug #31301101)
• In some cases, the server's internal string-conversion routines had problems handling floating-
point values which used length specifiers and triggered use of scientific notation. (Bug #92537, Bug
#101570, Bug #28691605, Bug #32144265)
• C API Notes
• Compilation Notes
• Configuration Notes
• Keyring Notes
• Optimizer Notes
• Packaging Notes
• Pluggable Authentication
• X Plugin Notes
• Bugs Fixed
• Modifying the mysql.infoschema and mysql.sys reserved accounts now requires the
SYSTEM_USER privilege. (Bug #31255458)
• For the CREATE USER, DROP USER, and RENAME USER account-management statements, the
server now performs additional security checks designed to prevent operations that (perhaps
inadvertently) cause stored objects to become orphaned or that cause adoption of stored objects
that are currently orphaned. Such operations now fail with an error. If you have the SET_USER_ID
privilege, it overrides the checks and those operations produce a warning rather than an error; this
171
MySQL 8.0 Release Notes
enables administrators to perform the operations when they are deliberately intended. See Orphan
Stored Objects. (WL #14073)
C API Notes
• The MySQL client library now includes a mysql_real_connect_dns_srv() C API function that
is similar to mysql_real_connect() but uses a DNS SRV record to determine the candidate
hosts for establishing a connection to a MySQL server, rather than explicit host, port, and socket
arguments.
Applications that use the C API can call the new function directly. In addition, the mysql client
program is modified to use DNS SRV capability; it now supports a --dns-srv-name option that
takes precedence over --host and causes the connection to be based on a DNS SRV record. See
mysql_real_connect_dns_srv().
Compilation Notes
• On Windows, Visual Studio 2019 Update 4 is now the minimum version for MySQL compilation. (Bug
#31655401)
• The minimum version of the Boost library for server builds is now 1.73.0. (Bug #31309800)
Configuration Notes
• The new WITH_TCMALLOC CMake option indicates whether to link with -ltcmalloc. If enabled,
built-in malloc(), calloc(), realloc(), and free() routines are disabled. The default is OFF.
WITH_TCMALLOC and WITH_JEMALLOC are mutually exclusive. (Bug #31785166)
• The new COMPRESS_DEBUG_SECTIONS CMake option indicates whether to compress the debug
sections of binary executables (Linux only). Compressing executable debug sections saves space
at the cost of extra CPU time during the build process. The default is OFF. If this option is not set
explicitly but the COMPRESS_DEBUG_SECTIONS environment variable is set, the option takes its
value from that variable. (Bug #31498296)
• On platforms that implement network namespace support (such as Linux), MySQL now enables
configuring the network namespace for TCP/IP connections from client programs to the MySQL
server or X Plugin:
• For client connections, the mysql client and the mysqlxtest test suite client support a --
network-namespace option for specifying the network namespace.
• For replication connections from replica servers to source servers, the CHANGE MASTER TO
statement supports a NETWORK_NAMESPACE option for specifying the network namespace.
172
MySQL 8.0 Release Notes
For more information, including the host system prerequisites that must be satisfied to use this
feature, see Network Namespace Support. (WL #12720)
For both system variables, the default value is AUTOMATIC. If either one of the system
variables has been set to a user-defined value and the other has not, the changed value
is used. If both of the system variables have been set to a user-defined value, the value of
group_replication_ip_allowlist is used. (WL #14175)
• From MySQL 8.0.22, the statements START SLAVE, STOP SLAVE, SHOW SLAVE STATUS, SHOW
SLAVE HOSTS and RESET SLAVE are deprecated. The following aliases should be used instead:
The statements work in the same way as before, only the terminology used for each statement and
its output has changed.
New status variables have been added as aliases for the related status variables. Both the old and
new versions of the statements update both the old and new versions of these status variables:
(WL #14171)
• The InnoDB memcached plugin is deprecated and support for it will be removed in a future MySQL
version. (WL #14131)
Keyring Notes
• MySQL Enterprise Edition now includes a keyring_oci plugin that uses Oracle Cloud
Infrastructure Vault as a back end for keyring storage. No key information is permanently stored in
MySQL server local storage. All keys are stored in Oracle Cloud Infrastructure Vault, making this
173
MySQL 8.0 Release Notes
plugin well suited for Oracle Cloud Infrastructure MySQL customers for management of their MySQL
Enterprise Edition keys. For more information, see The MySQL Keyring. (WL #9770)
Optimizer Notes
• Important Change: A prepared statement is now prepared only once, when executing PREPARE,
rather than once each time it is executed. In addition, a statement inside a stored procedure is
also now prepared only once, when the stored procedure is first executed. This change enhances
performance of such statements, since it avoids the added cost of repeated preparation and rollback
of preparation structures, the latter being the source of several bugs.
As part of this work, the manner in which dynamic parameters used in prepared statements are
resolved is changed, with the resulting changes in prepared statement use cases listed here:
• A parameter used in a prepared statement has its data type determined when the statement
is prepared, and the type persists for each subsequent execution of the statement, unless the
statement is reprepared (see PREPARE Statement, for information about when this may occur).
• For a prepared statement of the form SELECT expr1, expr2, ... FROM table ORDER
BY ?, passing an integer value N for the parameter no longer causes ordering of the results by the
th
N expression in the select list; the results are no longer ordered, as is expected with ORDER BY
constant.
• It was possible (although unsupported) to insert a floating point value into a LIMIT or OFFSET
clause by means of a parameter (and possibly a user variable). This is now explicitly disallowed;
such values must be integers.
• A user variable that is read by a prepared statement now has its type determined when the
statement is prepared; the type persists for each subsequent execution of the statement.
• A user variable that is read by a statement within a stored procedure now has its type determined
the first time the statement is executed; the type persists for all subsequent invocations of the
containing stored procedure.
• For parameters for which no contextual information is available to determine the parameter type,
the server assumes the parameter is a character string with the default character set, not a binary
string. Parameters for which this is incorrect may be placed within a CAST() expression.
See PREPARE Statement, for the rules governing how the effectiue data types of parameters and
user variables used within prepared statements are determined.
In addition, the rows (N) argument to the window functions LAG(), LEAD(), and NTILE() must now
be an integer in the range 0 to 263, inclusive, in any of the following forms:
• a user-defined variable
In addition, this argument is no longer permitted to be NULL. See the descriptions of the functions
just referenced for more information. (Bug #48612, Bug #99601, Bug #100150, Bug #105166, Bug
#11756670, Bug #23599127, Bug #31119132, Bug #31365678, Bug #31393719, Bug #31592822,
Bug #31810577, Bug #33448735, WL #9384)
174
MySQL 8.0 Release Notes
• The filesort algorithm now supports sorting a join on multiple tables, and not just a single table.
(Bug #31310238, Bug #31559978, Bug #31563876)
• When using a RIGHT JOIN, some internal objects, were not converted to those suitable for use with
a LEFT JOIN as intended. These included some lists of tables built at parse time, but which did not
have their order reversed. This required maintaining code to handle instances in which a LEFT JOIN
was originally a RIGHT JOIN as special cases, and was the source of several bugs. Now the server
performs any necessary reversals at parse time, so that after parsing, a RIGHT JOIN is in fact, in all
respects, a LEFT JOIN. (Bug #30887665, Bug #30964002, WL #6509)
• Added support for periodic synchronization when writing to files with SELECT INTO DUMPFILE
and SELECT INTO OUTFILE statements. This feature can be enabled by setting the
select_into_disk_sync system variable to ON; the size of the write buffer cn be set using
the server system variable select_into_buffer_size; the default buffer size is 131072
17
(2 ) bytes. An optional delay following synchronization to disk can also be set using the
select_into_disk_sync_delay system variable; the default behaviour is not to allow any delay
(that is, a delay time of 0 milliseconds).
For more information, see the descriptions of the system variables referenced previously.
Our thanks to Facebook for this contribution to MySQL 8.0. (Bug #30284861, WL #13926)
• MySQL now implements derived condition pushdown for eligible queries. What this means is that, for
a query such as SELECT * FROM (SELECT i, j FROM t1) AS dt WHERE i > constant,
it is now possible in many cases to push the outer WHERE condition down to the derived table, in this
case resulting in SELECT * FROM (SELECT i, j FROM t1 WHERE i > constant) AS dt.
Previously, if the derived table was materialized and not merged, MySQL materialized the entire
table—in this case t1—then qualified the rows with the WHERE condition.
When the derived table cannot be merged into the outer query (for example, if the derived table uses
aggregation), pushing the outer WHERE condition down to the derived table can reduce the number of
rows that need to be processed, which should improve the query's performance.
An outer WHERE condition can be pushed down directly to a materialized derived table when the
derived table uses no aggregate or window functions. In addition, when the derived table has a
GROUP BY and uses no window functions, the outer WHERE condition can be pushed down to the
derived table as a HAVING condition. If the derived table uses a window function and the outer
WHERE references columns used in the window function's PARTITION clause, the WHERE condition
can also be pushed down.
This optimization cannot be employed for a derived table that contains a UNION or LIMIT clause.
For further information and examples, see Derived Condition Pushdown Optimization. (Bug #59870,
Bug #88381, Bug #11766303, Bug #27590273, WL #8084)
Packaging Notes
• For RPM and Debian packages, client-side plugins were moved to their own client-plugins package.
(Bug #31584093)
• The VERSION file in MySQL source distributions is now named MYSQL_VERSION due to a naming
conflict with Boost. (Bug #31466846)
175
MySQL 8.0 Release Notes
• For platforms on which systemd is used to run MySQL, packages no longer include legacy System
V files: the mysqld_multi.server and mysql.server scripts, and the mysql.server.1,
mysqld_multi.1, and mysqld_safe.1 man pages. (Bug #31450888)
An alternative SHOW PROCESSLIST implementation is now available based on the new Performance
Schema processlist table. This implementation queries active thread data from the Performance
Schema rather than the thread manager and does not require a mutex:
• The alternative implementation does not apply to the INFORMATION_SCHEMA PROCESSLIST table
or the COM_PROCESS_INFO command of the MySQL client/server protocol.
• To ensure that the default and alternative implementations yield the same information, certain
configuration requirements must be met; see The processlist Table.
(WL #9090)
• An SQL interface to the most recent events written to the MySQL server error log is now available
by means of queries on the new Performance Schema error_log table. This table has a fixed
size, with old events automatically discarded as necessary to make room for new ones. The table
is populated if error log configuration includes a log sink component that supports this capability
(currently the traditional-format log_sink_internal and JSON-format log_sink_json sinks).
Several new status variables provide information about error_log table operation. See The
error_log Table. (WL #13681)
Pluggable Authentication
• These changes were made for the LDAP authentication plugins:
• For the SASL LDAP authentication plugin, the SCRAM-SHA-1 authentication method is not
supported on On SLES 12 and 15 and EL6 systems. The default method on those systems is now
GSSAPI.
• If the LDAP host is not set, the LDAP connection pool will not be initialized, which enables
successful authentication plugin installation in cases when previously it would fail. (This might be
the case when a site installs a plugin first, then configures it later.)
• If an LDAP connection parameter is changed at runtime, the LDAP connection pool is reinitialized
for the first subsequent authentication attempt.
• If the LDAP server is restarted, existing connections in the connection pool become invalid. The
LDAP authentication plugin detects this case and reinitializes the connection pool and (for the
SASL LDAP plugin) the SASL challenge is resent.
176
MySQL 8.0 Release Notes
( query_expression )
[order_by_clause]
[limit_clause]
[into_clause]
Other variations are possible; see Parenthesized Query Expressions (Bug #30592703)
• It is now possible to cast values of other types to YEAR, using either the CAST() function or the
CONVERT() function. These functions now support YEAR values of one or two digits in the range
0-99, and four-digit values in the range 1901-2155. Integer 0 is converted to Year 0; a string
consisting of one or more zeroes (following possible truncation) is converted to the year 2000.
Casting adds 2000 to values in the range 1-69 inclusive, and 1900 to values in the range 70-99
inclusive.
Strings beginning with one, two, or four digits followed by at least one non-digit character (and
possibly other digit or non-digit characters) are truncated prior to conversion to YEAR; in such
cases, the server emits a truncation warning. Floating-point values are rounded prior to conversion;
CAST(1944.5 AS YEAR) returns 1945 due to rounding, and CAST("1944.5" AS YEAR) returns
1944 (with a warning) due to truncation.
DATE, DATETIME, and TIMESTAMP are cast to the YEAR portion of the value. A TIME value is cast to
the current year. Not specifying the value to be cast as a TIME value may yield a different result from
what is expected; CAST("13:47" AS YEAR) returns 2013 due to truncation of the string value, and
CAST(TIME "13:47" AS YEAR) returns 2020 as of the year of this release.
Casting of GEOMETRY values to YEAR is not supported. A cast of an incompatible type or an out-of-
range or illegal value returns NULL.
YEAR can also be used as the return type for the JSON_VALUE() function. This function supports
four-digit years only, and otherwise follows the same rules as apply to CAST() and CONVERT()
when performing casts to YEAR.
For more information, see the description of the CONVERT() function. (WL #14015)
• When selecting a TIMESTAMP column value, it is now possible to convert it from the system
time zone to a UTC DATETIME when retrieving it, using the AT TIME ZONE operator which is
implemented for the CAST() function in this release.
Values that were inserted into the table using a timezone offset are also supported.
AT TIME ZONE cannot be used with CONVERT(), or in any other context other than as part of
a CAST() function call. The ARRAY keyword and creation of multi-valued indexes are also not
supported when using AT TIME ZONE.
177
MySQL 8.0 Release Notes
mysql> SELECT ts, CAST(ts AT TIME ZONE 'UTC' AS DATETIME) AS ut FROM ex;
+---------------------+---------------------+
| ts | ut |
+---------------------+---------------------+
| 2020-07-28 21:39:31 | 2020-07-29 01:39:31 |
| 2020-08-01 01:44:30 | 2020-08-01 05:44:30 |
+---------------------+---------------------+
2 rows in set (0.00 sec)
For more information and examples, see the description of the CAST() function in the MySQL
Manual. (WL #12535)
X Plugin Notes
• In specific conditions, terminating an X Protocol connection could cause MySQL Server to stop
unexpectedly. (Bug #31671503)
• You can use MySQL Server's new asynchronous connection failover mechanism to automatically
establish an asynchronous (source to replica) replication connection to a new source after
the existing connection from a replica to its source fails. The connection fails over if the
replication I/O thread stops due to the source stopping or due to a network failure. The
asynchronous connection failover mechanism can be used to keep a replica synchronized
with multiple MySQL servers or groups of servers that share data. To activate asynchronous
connection failover for a replication channel set SOURCE_CONNECTION_AUTO_FAILOVER=1
on the CHANGE MASTER TO statement for the channel, and set up a source list for
the channel using the asynchronous_connection_failover_add_source and
asynchronous_connection_failover_delete_source functions. (WL #12649)
A posix_fallocate() operation is not atomic, which makes it possible for a failure to occur
between allocating space to a tablespace file and updating the file metadata. Such a failure can
leave newly allocated pages in an uninitialized state, resulting in a failure when InnoDB attempts to
access those pages. To prevent this scenario, InnoDB writes a redo log record before allocating a
new tablespace page. If a page allocation operation is interrupted, the operation is replayed from the
redo log record during recovery. (WL #13782)
178
MySQL 8.0 Release Notes
• To permit concurrent DML and DDL operations on MySQL grant tables, read operations that
previously acquired row locks on MySQL grant tables are now executed as non-locking reads. The
operations that are now performed as non-locking reads on MySQL grant tables include:
• SELECT statements and other read-only statements that read data from grant tables through join
lists and subqueries, including SELECT ... FOR SHARE statements, using any transaction
isolation level.
• DML operations that read data from grant tables (through join lists or subqueries) but do not
modify them, using any transaction isolation level.
Statements that no longer acquire row locks when reading data from grant tables report a warning if
executed while using statement-based replication.
When using -binlog_format=mixed, DML operations that read data from grant tables are now
written to the binary log as row events to make the operations safe for mixed-mode replication.
SELECT ... FOR SHARE statements that read data from grant tables now report a warning. With
the FOR SHARE clause, read locks are not supported on grant tables.
DML operations that read data from grant tables and are executed using the SERIALIZABLE
isolation level now report a warning. Read locks that would normally be acquired when using the
SERIALIZABLE isolation level are not supported on grant tables. (WL #14087)
• The ALTER DATABASE statement now supports a READ ONLY option that controls whether to
permit modification of a database and objects within it. This option is useful for database migration
because a database for which READ ONLY is enabled can be migrated to another MySQL instance
without concern that the database might be changed during the operation. See ALTER DATABASE
Statement.
Bugs Fixed
• InnoDB: Code related to transaction support for histogram sampling was removed, including related
assertion code that caused test failures. Transaction support is not required for histogram sampling.
(Bug #31787736)
• InnoDB: Encryption information was not set for redo log archive log writer thread write operations.
(Bug #31690196)
• InnoDB: The TTASEventMutex::exit function was optimized for ARM64. Thanks to Krunal
Bauskar for the contribution. (Bug #31589019, Bug #100132)
• InnoDB: InnoDB failed to compile with the DISABLE_PSI_RWLOCK CMake option enabled. (Bug
#31578289)
• InnoDB: The transaction isolation level, which is set to READ UNCOMMITTED for histogram sampling
to avoid unnecessary lookups of old record versions, was not reset after the sampling operation
completed. (Bug #31564407)
• InnoDB: A query that updated the clustered index of an internal temporary table returned an
incorrect result. The modified pages of the clustered index were not added to the flush list resulting in
lost changes when the modified pages were evicted from the buffer pool. (Bug #31560679)
• InnoDB: A build dependency on the Boost library defined for the TempTable storage engine was
removed. (Bug #31505048)
179
MySQL 8.0 Release Notes
• InnoDB: A workaround was implemented to handle a Clang compiler issue in 32-bit builds that
causes the ATOMIC_LLONG_LOCK_FREE value to be defined as “sometimes lock-free” while
__atomic_always_lock_free returns true for the same type on the same platform. (Bug
#31504609)
• InnoDB: A REDUNDANT row format table created in an earlier version of MySQL, where the row
format was not defined explicitly, permitted the addition of an index that exceeded the REDUNDANT
row format index column size limit. (Bug #31479542, Bug #99791)
• InnoDB: A DML operation on a column defined with a multi-valued index caused a failure. (Bug
#31479282)
• InnoDB: A failure occurred during master key rotation. An undo tablespace in-memory object was
freed prematurely. (Bug #31467626)
• InnoDB: Unused physical read ahead code was removed from the parallel read interface. (Bug
#31429385)
• InnoDB: A master key rotation operation failed to skip an undo tablespace that was already
truncated, which lead to an assertion failure when shutting down the server. (Bug #31400195)
• InnoDB: After importing a tablespace for a page-compressed table, pages were no longer
compressed, and INFORMATION_SCHEMA.INNODB_TABLESPACES metadata incorrectly indicated
that pages were compressed. The table's compression information was unavailable during the import
operation. (Bug #31396947)
• InnoDB: A rollback and update operation after performing an instant DDL operation raised an
assertion. (Bug #31391126)
• InnoDB: The log system (log_sys) sharded read-write lock caused a performance regression in
CPU-bound workloads. (Bug #31389135)
• InnoDB: Compiling with the UNIV_ENCRYPT_DEBUG option enabled caused compilation errors. (Bug
#31369540)
• InnoDB: DDL operations on a partitioned table could cause a failure. TABLE_SHARE and table
instance objects were opened for all partitions unnecessarily. (Bug #31365127)
• InnoDB: After changing a VARCHAR column collation from utf8mb4 to utf8mb4_bin in an in-
place ALTER TABLE operation and adding an index on the same column, a case-sensitive query
on the VARCHAR column returned an incorrect result. The VARCHAR column collation was changed
in the data dictionary but not in the in-memory table object. Consequently, the index created on the
VARCHAR column used stale column information causing comparisons to use the previously defined
collation. (Bug #31361838)
• InnoDB: An ALTER TABLE ... IMPORT TABLESPACE operation on a large encrypted and
compressed table failed with a Page decompress failed after reading from disk error.
The decryption operation did not use the encryption block size used during encryption. Also, the
encryption process did not consider compressed length, while the decryption process decrypts data
by compressed length only. (Bug #31313533)
• InnoDB: A failure occurred during a concurrent update operation. The failure was due to an invalid
previous record value. (Bug #31205266, Bug #99286)
• InnoDB: Upgrade from MySQL 5.7 to MySQL 8.0 failed on an instance with a table created in a
general tablespace and defined with a FULLTEXT index. The correct data dictionary space ID for
table could not determined. (Bug #31154128, Bug #99211)
• InnoDB: The function used to process the SHOW ENGINE INNODB MUTEX statement was
insufficiently isolated from other threads adding new mutexes concurrently. (Bug #31105262)
• InnoDB: Failure to call a buffer pool page I/O completion routine resulted in orphan buffer pool I/O
write pages. (Bug #31073853)
180
MySQL 8.0 Release Notes
• InnoDB: Numerous system temporary table pages at the tail of the buffer pool flush list caused a
performance degradation. The flush_list_mutex was held while the flush list scan traversed over
system temporary table pages. The flush list scan now excludes system temporary table pages. (Bug
#31060470, Bug #98974)
• InnoDB: The buffer control block structure (buf_block_t) was freed while reducing the size of the
buffer pool, causing an assertion failure. The fix for this bug also backports important aspects of the
fix for Bug #20735882 / Bug #76343, and replaces the internal buf_block_is_uncompressed()
function with the buf_pointer_is_block_field_instance() function. The
buf_block_is_uncompressed() function returned false in too many cases, affecting OLTP query
throughput. (Bug #31036301, Bug #31389823)
• InnoDB: Parallel read threads failed to respond to an explicit transaction interruption. (Bug
#31016076)
• InnoDB: In session started with START TRANSACTION WITH CONSISTENT SNAPSHOT, a range
query returned a truncated result. The end range flag was not reset at the beginning of the index
read resulting in an aborted read and missing rows. (Bug #30950714, Bug #98642)
• InnoDB: A full-text phrase search raised an assertion failure. Thanks to TXSQL (Tencent MySQL)
for the contribution. (Bug #30933728, Bug #31228694)
• InnoDB: A failure occurred while attempting to initialize the system tablespace on a raw disk
partition. Additionally, a INPLACE DDL operation on the raw-disk partition tablespace failed with an
error instead of switching to the COPY algorithm. (Bug #30867065, Bug #98091)
• InnoDB: LOB purge code (lob::purge()) did not properly handle latches taken during B-tree mini-
transaction (btr_mtr) commit and restore operations, which could lead to conflicts between B-tree
and LOB mini-transactions. (Bug #30620011)
• InnoDB: A long running statistics calculation operation on a large table blocked other operations
requiring access to the table's statistics, causing those operations to fail. A new statistics calculation
mutex was introduced, which permits concurrent access table statistics. Thanks to Kamil Holubicki
for the contribution. (Bug #30607708)
• InnoDB: Two connections attempted to use the same transaction handler object resulting in a stalled
query. (Bug #30594501)
• InnoDB: Shutting down the server with innodb_fast_shutdown setting greater than 0 raised an
assertion failure. The assertion was caused by the presence of recovered transactions that were not
yet rolled back. Assertion code was revised to ignore recovered transactions during a fast shutdown.
Messages are now written to the error log when recovered transactions that are not rolled back are
left behind by a fast shutdown. Slow shutdown now waits for recovered transactions to be rolled
back. Various other shutdown logic improvements were implemented. (Bug #30226841)
• InnoDB: Dedicated log writer threads, introduced in MySQL 8.0.11, caused a CPU-bound
performance regression on low-concurrency systems. To address this issue, the new
innodb_log_writer_threads variable permits disabling dedicated log writer threads so that redo
log records are written from the log buffer to the system buffers and flushed from the system buffers
to the redo log files by each user thread, which is the behavior prior to the introduction of dedicated
log writer threads. Other redo logging optimizations were implemented, including the removal of an
unnecessary log closer thread that wasted CPU time, and optimizations to remedy too-aggressive
checkpoint activity and excessive flush calls. The issues addressed by this fix also manifested in a
LOAD DATA performance regression. (Bug #30088404, Bug #30003849)
181
MySQL 8.0 Release Notes
the rollback thread was not initiated due to a startup validation failure caused by the incorrect
lower_case_table_names setting. (Bug #29833945)
• Packaging; Group Replication: MySQL Server Docker images did not expose the Group
Replication recommended port (33061). (Bug #31627536)
• Packaging: Added a client-plugins RPM that was separated from the client package. It
contains shared plugins for MySQL client applications. (Bug #35162346)
• Replication: You can now set the value of the gtid_purged system variable in a stored procedure,
which was not previously permitted. You cannot set gtid_purged in a stored function. (Bug
#31571427)
• Replication: When a replication source server shuts down and restarts, its MEMORY tables become
empty. To replicate this effect to replicas, the first time that the source uses a given MEMORY table
after startup, it logs an event that notifies replicas that the table must be emptied by writing a
statement to the binary log to that effect. Previously, this was a DELETE statement, but it is now a
TRUNCATE TABLE statement. A replica server also writes this statement to its own binary log when
it shuts down and restarts. The statement is always logged in statement format, even if the binary
logging format is set to ROW, and it is written even if read_only or super_read_only mode is set
on the server. (Bug #29848785, Bug #95496)
• Replication: When using row-based replication, the replica was allowed to use an invisible index
when searching for rows to synchronize. (Bug #96148, Bug #30072179)
• Group Replication: X Plugin could stop unexpectedly if a Group Replication notification was issued
after a new X Protocol connection was made but before the session was created. The dispatcher
thread that handles Group Replication notifications now checks that the session pointer is valid. (Bug
#31742798)
• Group Replication: Group Replication handling of memory allocation issues when adding
transaction write sets has been improved. (Bug #31586243)
• Group Replication: While a remote cloning procedure was taking place on a joining member
during distributed recovery, Group Replication considered the pre-cloning gtid_executed value
on the joining member when identifying the common set of transactions that had been applied on
all members. This meant that garbage collection for applied transactions from the group's set of
certification information (shown as the count_transactions_rows_validating field in the
Performance Schema table replication_group_member_stats) did not take place during
the remote cloning procedure. If the remote cloning procedure took a long time, the certification
information could therefore get too large to transmit to the joining member when it restarted after the
remote cloning procedure, in which case an error was raised and the member was not able to join
the group.
To avoid this issue, Group Replication now considers only group members with ONLINE status
when identifying the common set of transactions that have been applied on all members. When a
joining member enters ONLINE state after distributed recovery, its certification information is updated
with the certification information from the donor at the time when the member joined, and garbage
collection takes place for this on future rounds.
As a workaround for this issue in earlier releases, after the remote cloning operation completes, wait
two minutes to allow a round of garbage collection to take place to reduce the size of the group's
certification information. Then issue the following statement on the joining member, so that it stops
trying to apply the previous set of certification information:
182
MySQL 8.0 Release Notes
• Group Replication: It was possible for a group member that left the group due to a communication
error to reconnect between auto-rejoin attempts while the auto-rejoin procedure was still ongoing,
which left Group Replication unable to function on the member. Group Replication error management
and member status handling has now been corrected to prevent this situation. (Bug #31401797)
• Microsoft Windows: On Windows, build targets could fail if the build was on a file system root, such
as R:/. (Bug #31315467)
• JSON: JSON_OBJECT() did not always perform proper checking for NULL values. (Bug #31393934)
• The new WITH_SYSTEMD_DEBUG CMake option, if enabled, produces additional systemd debugging
information, for platforms on which systemd is used to run MySQL. The default is OFF. (Bug
#31788834)
• For RPM and Debian packages, client-side plugins were moved from the server package to the client
package in MySQL 8.0.21. This could cause failures relating to LDAP authentication plugins when
upgrading from 5.7 packages to 8.0 packages. Packaging adjustments were made to avoid this
problem. (Bug #31782612)
• The timestamp written for the ts key by the log_sink_json JSON-format error log sink did not
have the same value as other timestamps in the same log message. (Bug #31749103)
• Kerberos authentication for the SASL LDAP authentication plugin incorrectly handled failure to
acquire a ticket-granting ticket. (Bug #31727195)
• For some third-party libraries, enabling link-time optimization caused build failures. (Bug #31701553,
Bug #100410)
• Printing an excessively long diagnostic message could cause the server to exit unexpectedly. (Bug
#31686926)
• Certain cases of successful LDAP authentication could cause the server to hang. (Bug #31661437)
• During transformation of a grouped query into a derived table, when the WHERE clause and the
HAVING clause became part of the derived table, the condition count was not updated for the
derived table. This resulted in reduced memory allocation while creating keys for ref access. (Bug
#31661309)
• When a value was compared using LIKE with a table column not defined as one of the MySQL string
types, the server sometimes did not raise the expected error. (Bug #31659015)
• The acquire_related() service function returned the default service in some cases when it
should have returned an error. (Bug #31655906)
• A remote cloning operation checked for the availability of a plugin on the recipient that was removed
from the donor instance previously. References to the uninstalled plugin had not been released.
Error reporting issues related to plugin mismatches and availability were also addressed. (Bug
#31639732, Bug #100244)
• In debug builds, the server attempted to evaluate subqueries while creating a view. (Bug #31590301)
183
MySQL 8.0 Release Notes
• A condition using RAND() was not pushed down even in cases where it was safe to do so, that is
when no windowing function or GROUP BY is in use. (Bug #31587575)
• While pushing conditions down to a derived table, a constant condition such as WHERE FALSE or
WHERE TRUE was pushed down to the first table in the derived table, which is not necessary as the
condition has nothing to do with the derived table. MySQL now avoids pushing constant conditions
down to derived tables in such cases.
In addition used tables are now updated for the condition that needs to be pushed down to the
derived table, following code inspection revealing that this was not done after replacing the columns
in the condition with the derived table expressions. (Bug #31587493)
• A query using WHERE column > (... IN (SELECT ...)) could sometimes trigger an assertion
in the range optimizer. (Bug #31586906)
• It was possible for ANALYZE TABLE to fail with Duplicate key error if a row was inserted in
the interval between the check for the existence of the row and the execution of the insert, and the
statistics table was updated concurrently. ANALYZE TABLE now ignores the error in this situation.
(Bug #31582758)
• The range optimizer does not use the correct lock type after cloning the handler needed to perform
merged scans, and instead used a read lock unconditionally. This resulted in various different side
effects for different scenarios.
For example, a SELECT with FOR UPDATE requests a write lock, but after cloning the handler for an
index merge scan, the range optimizer requested a read lock which resulted in a mismatch. Similarly,
for data dictionary tables, the lock type was set to LOCK_NONE due to the special handling required
for such tables.
To prevent this problem from occurring, we now ensure that the original lock type of the handler is
always used in the cloned handler as well. (Bug #31582383)
• In some cases, a query using an ANY subquery gave an incorrect result when the
subquery_to_derived optimizer switch was enabled. (Bug #31566339)
• When FALSE AND condition was simplified as FALSE, temporary table resources allocated for
the condition were not always released afterwards. (Bug #31565009)
• A value equal to ULLONG_MAX could be inserted into a BIT(64) column, but not retrieved. (Bug
#31564742, Bug #100053)
• While removing an unused window definition, a subquery that was part of an ORDER BY was not
removed. The optimizer then tried to optimize the subquery without locking the tables. Now, when
removing an unused window definition, the server cleans up any subqueries present as part of the
definition. (Bug #31518806)
• A coding problem introduced in MySQL 8.0.20 could cause client applications to exit unexpectedly
during shutdown. (Bug #31515752)
• Merging during filesort operations could fail to remove duplicates for queries that used
DISTINCT. (Bug #31498664, Bug #99900)
184
MySQL 8.0 Release Notes
• MySQL's internal DYNAMIC_STRING class formerly allocated memory in a linear fashion, that is, by
a predetermined number of bytes. The class has been revised such that it now allocates memory
exponentially, which should make operations such as repeated string appends more efficient. (Bug
#31491799)
• A newly added collation was not added and could cause an unexpected exit on shutdown. (Bug
#31470422)
• On Windows, file name reuse by the GetTempFileName() function could cause an assertion to be
raised. (Bug #31468590)
• NATURAL JOIN evaluation could inadvertently match hidden virtual columns created by functional
indexes. (Bug #31463511, Bug #99807)
• Sort keys for string hash join keys using more than 1024 bytes were not handled correctly by the
server. (Bug #31437753)
• The server attempted to delete from a view whose definition included HAVING when the HAVING
clause was constant and evaluated as true even though a view with HAVING as part of its definition
should not be updatable. (Bug #31429865)
• When the internal function replace_index_subquery() failed, the server still attempted to create
iterators for the affected subquery. Now the function raises a clear error instead. (Bug #31427072)
• A query using WHERE NOT EXISTS (SELECT const FROM table WHERE
column=FROM_UNIXTIME(value) was not handled correctly. (Bug #31425664)
• In some cases, key_hint handling was improperly applied to derived and internal temporary tables.
(Bug #31424455)
• Re-execution of prepared INSERT statements could fail for inserts through a view. (Bug #31417951)
• The user_attributes column in mysql.user table rows could be affected incorrectly by partial
revokes. (Bug #31405985)
• Improper window function initialization could cause a server exit. (Bug #31389573, Bug #31437834)
• Sensitive LDAP authentication plugin system variables now display as asterisks when retrieved in
SQL statements. (Bug #31388444, Bug #31391864)
• mysql-test-run.pl tests under no-threads connection handling failed with ASAN builds due
to improper resource group initialization. This has been fixed. Thanks to Xiaoyu Wang, Tencent
Technology for the contribution. (Bug #31378900, Bug #99609)
• Killing a query could raise spurious assertions in the hash join iterator. (Bug #31361354)
• In some cases, an outer reference that was not LATERAL was not marked as read-only as expected.
(Bug #31359965)
• A failure occurred when upgrading from MySQL 5.7 to MySQL 8.0 due to invalid references
to orphaned events (events for which a database no longer exists). The server now fails with
185
MySQL 8.0 Release Notes
an appropriate error messages when orphaned events are encountered during upgrade. Error
messages for orphaned stored routines were also revised. (Bug #31335554)
• Enabling the create_admin_listener_thread system variable could cause a server exit during
startup. (Bug #31335279)
• After ALTER TABLE to add an expression default to a column, the first insert inserted a value as if
the expression had been evaluated at alter time and not insert time. (Bug #31330789, Bug #99513)
• The LDAP authentication plugins did not properly compare the user-supplied authentication method
against the permitted methods. (Bug #31320532)
• Certain views could cause a following USE statement to result in an unexpected server exit. (Bug
#31311312)
• When a filesort sorted a buffer and LIMIT was active, it first sorted all rows and then discarded
those that did not fit within the limit, which required sorting many rows that were certain to be
discarded later. Now the optimizer sorts only the rows actually needed. Internal testing shows that
this change can speed up the sort phase for a simple string sorting benchmark (as measured by
EXPLAIN ANALYZE) by up to 15%. (Bug #31303537)
• A dynamic range scan runs the range optimizer for each row fetched from the first table in a join to
determine whether a range scan can be picked for the second table using the value available from
that row. If the row contains no usable indexes, a table scan may be chosen instead. For the query
giving rise to this issue, a table scan is chosen once, followed by a range scan on a non-covering
index, and the dynamic range iterator has two read sets which are used for both these cases. One
of these, used for the table scan, includes the base columns of generated columns required for
processing the query; the other read set does not include the base columns in the read set used for
range scans. This is because, for covering indexes, the read set should not include base columns to
avoid adding unneeded columns by hash join or batched key access. The issue arose because the
second read set was also used for a non-covering index, which resulted in an assert.
To prevent this from happening, when initializing a table read set in the dynamic range iterator, we
now make sure that it includes the base columns when the range optimizer picks a non-covering
index. (Bug #31280526)
• It was possible to insert an out-of-range value for a TIMESTAMP if it included a timezone offset. (Bug
#31239157)
• The keyring_hashicorp keyring plugin did not limit the size of keys for key operations. (Bug
#31205715)
• Configuring with -DWITH_ZSTD=system failed for older versions of the zstd library. CMake now
checks the zstd version and requires at least 1.0.0 for compilation, 1.2.0 to run compression
checks. (Bug #31174920, Bug #99241)
• In some cases, a SELECT that obtained status variable information from Performance Schema tables
and that included a sort by a column containing temporal values was not handled correctly. (Bug
#31168097)
• In some cases, ROUND() and TRUNCATE() did not return the data type of their first arguments as
expected. This fix insures that return types from these functions follow these rules, where the first
argument is of the type shown:
• For any floating-point type or any non-numeric type, the return type is DOUBLE.
186
MySQL 8.0 Release Notes
• The type attributes for the return value are also copied from the first argument, except in the case
of DECIMAL, when the second argument is a constant value.
• When the desired number of decimal places is less than the scale of the argument, the scale
and the precision of the result are adjusted accordingly. In addition, for the ROUND() function,
the precision is extended by one place to accomodate rounding that increases the number of
significant digits. If the second argument is negative, the return type is adjusted such that its scale
is 0, with a corresponding precision.
For more information, see the description of the ROUND() function. (Bug #31128028)
• A SELECT ... FOR SHARE statement now only requires the SELECT privilege. Previously,
the SELECT privilege was required with at least one of the DELETE, LOCK TABLES, or UPDATE
privileges. (Bug #31096384, Bug #99101)
• A semijoin strategy was chosen for the join of a correlated subquery having a LIMIT clause and
requiring a row other than the first, which caused the LIMIT clause to be ignored and invalid rows to
be returned. Now, when LIMIT used with this type of join specifies a row other than the first row, or
more than one row, the semijoin strategy is no longer employed. (Bug #31096309)
• After the fix for Bug #81009, privilege checks for truncating Performance Schema tables were too
restrictive when read_only or super_read_only were enabled, causing truncation to fail even for
users with appropriate table privileges. (Bug #31080309, Bug #99072)
• ORDER BY did not work as expected for queries with ROLLUP in which window functions were also
used. (Bug #31073133)
• Date interval calculations checked for overflow but not underflow. Now they check for both. (Bug
#31054071)
• If an XA prepared transaction rollback XID was incorrectly formatted, the transaction remained in
recovered state for XA COMMIT and XA ROLLBACK statements (or raised an assertion for debug
builds) rather that reporting an error. (Bug #31030205)
• Database-level privileges inherited through a role were not handled properly for database names that
contained wildcard characters. (Bug #31013538, Bug #98876)
• Certain prepared statements could cause an unexpected server exit. (Bug #30943963)
• OPTIMIZE TABLE for MyISAM tables could cause table size to increase and query performance to
decrease. REPAIR TABLE for MyISAM tables could cause the Table is already up to date
status produced by a previous OPTIMIZE TABLE to be lost. (Bug #30869674, Bug #98511, Bug
#29755517)
• Inserting a TIMESTAMP value having a timezone offset which also had a zero for the month, day,
or both, led to an assert. Such a value should be and is now rejected, regardless of the sql_mode
setting. (Bug #30786762)
• Privileges granted using roles could be mishandled at the column-privilege level. (Bug #30660403,
Bug #97971)
187
MySQL 8.0 Release Notes
• Comparison of a TIME value with NULL in some cases raised an assertion. (Bug #30324587)
• LDAP authentication plugins enforced CA verification incorrectly, which could result in use of an
incorrect CA. (Bug #30220357)
• ORDER BY queries were not executed correctly when sort_buffer_size and max_sort_length
were set to values which caused the internal limit on the maximum number of keys allowed per sort
buffer to be set to 0. (Bug #30175483)
• A large number of nested arguments in full-text search query caused an error. (Bug #29929684)
• A potential misreporting of memory use by the Performance Schema has been corrected. (Bug
#29912403)
• The SET_VAR hint did not accept a floating point value specified as a system variable setting. (Bug
#29349748)
• Previously, when NULL was used as the format argument to STR_TO_DATE(), irrelevant warnings
were printed. Now, when NULL is passed to it, the function returns NULL. (Bug #27265863)
• In some cases, incorrect use of IS NULL generated multiple warnings about invalid arguments. (Bug
#27264652)
• Resolving an ORDER BY column that referred to a SELECT list column from a derived table was not
performed correctly when executing certain prepared statements. (Bug #26808862)
• When using EXPLAIN on a multi-table UPDATE statement in which a generated column was
referenced in a condition, the output always showed the table containing this column as being
updated, whether the table was actually updated or not. (Bug #22671310)
• An assertion could be raised when the SQL layer passed incorrect information to InnoDB about the
type of operation to be performed on a temporary table. (Bug #22503696)
• This construct works for base tables to insert a row using all default values but failed for views:
INSERT INTO name () VALUES ();
• In some cases, the server issued an error when an invisible index was used in an index hint even
when the use_invisible_indexes optimizer switch was not set to OFF. (Bug #100024, Bug
#31550839)
• Regular expression functions such as REGEXP_LIKE() yielded inconsistent results with binary string
arguments. These functions now reject binary strings with an error. (Bug #98950, Bug #98951, Bug
#31031886, Bug #31031888)
• When range values specified in a predicate are not compatible with the data type of the column with
which the values are compared, the range optimizer rounds off the range values and assigns certain
flags so that it does not exclude rows that qualify for the range because of rounding. In the specific
query that triggered the reported issue, a column named id of type INT was tested using id NOT
IN (-0.1, 0.1), and the values being tested are rounded to integers, with the predicate thus
being treated as NOT IN (0,0). The optimizer then treats this as the intervals id < 0 and 0 <
id < 0, but in this case it also set a flag to a value that indicated that reads should begin following
rows containing 0 for the value to be compared. Now in such cases, the flag is set in such a way that
the values which have been rounded are treated correctly. (Bug #98826, Bug #30988735)
188
MySQL 8.0 Release Notes
• For a view based on a join having an updatable part and one that was not, the error message
generated when attempting to update a column of this view that was not updatable referenced the
source table or view instead of the view actually named in the offending UPDATE statement. (Bug
#80655, Bug #22891840)
In the documentation for MySQL 8.0.21, we have started changing the term “master” to “source”, the
term “slave” to “replica”, the term “whitelist” to “allowlist”, and the term “blacklist” to “blocklist”. There
are currently no changes to the product's syntax, so these terms are still present in the documentation
where the current code requires their use. See the blog post MySQL Terminology Updates for more
information.
• C API Notes
• Compilation Notes
• Configuration Notes
• JSON Notes
• Optimizer Notes
• Packaging Notes
• Pluggable Authentication
• Security Notes
• X Plugin Notes
• Bugs Fixed
For example, the first of the following two statements creates a user account bill@localhost with
the comment text This is Bill's user account. The second statement adds a user attribute
to this account, using the key email, with the value [email protected].
CREATE USER 'bill'@'localhost' COMMENT 'This is Bill\'s user account';
189
MySQL 8.0 Release Notes
Only one of COMMENT or ATTRIBUTE can be used in the same CREATE USER or ALTER USER
statement.
User comments and user attributes are stored together internally as a JSON object,
with the comment text as the value of an element with the key comment. You can
information retrieve user comments and user attributes from the ATTRIBUTE column of the
INFORMATION_SCHEMA.USER_ATTRIBUTES table; since this data is in JSON format, you can work
with it using MySQL's JSON function and operators (see JSON Functions). Changes to an existing
user attribute are merged with its current value, as you had used JSON_MERGE_PATCH(); new key-
value pairs are appended to the attribute, and new values for existing keys overwrite their previous
values.
To remove a given key-value pair from a user attribute, use ALTER USER user ATTRIBUTE
'{"key":null}'.
For more information and examples, see CREATE USER Statement, ALTER USER Statement, and
The INFORMATION_SCHEMA USER_ATTRIBUTES Table. (WL #13562)
C API Notes
• Per OpenSSL recommendation, x509_check_host() and X509_check_ip_asc() calls in
the C client library were replaced, respectively, with X509_VERIFY_PARAM_set1_host() and
X509_VERIFY_PARAM_set1_ip_asc() calls. (Bug #29684791)
• The MySQL C API now supports compression for asynchronous functions. This means that the
MYSQL_OPT_COMPRESSION_ALGORITHMS and MYSQL_OPT_ZSTD_COMPRESSION_LEVEL options
for the mysql_options() function now affect asynchronous operations, not just synchronous
operations. See mysql_options().
Our thanks to Facebook for the contribution. (Bug #96802, Bug #30284871, WL #13510)
Compilation Notes
• The minimum version of the Boost library for server builds is now 1.72.0. (Bug #30963985)
Configuration Notes
• tcmalloc is no longer a permitted value for the mysqld_safe --malloc-lib option. (Bug
#31372027)
• There are new configuration parameters that apply specifically to the administrative interface.
• The ALTER INSTANCE RELOAD TLS statement is extended with a FOR CHANNEL clause that
enables specifying the channel (interface) for which to reload the TLS context.
• The new Performance Schema tls_channel_status table exposes TLS context properties for
the main and administrative interfaces.
190
MySQL 8.0 Release Notes
• For backward compatibility, the administrative interface uses the same TLS context as the main
interface unless some nondefault TLS parameter value is configured for the administrative
interface.
For more information, see Administrative Interface Support for Encrypted Connections, ALTER
INSTANCE Statement, and The tls_channel_status Table. (WL #13850)
When one or more columns using index prefixes are specified as part of the partitioning key, a
warning is now generated for each such column. In addition, when a CREATE TABLE or ALTER
TABLE statement is rejected because all columns specified in the proposed partitioning key employ
index prefixes, the error message returned now makes clear the reason the statement did not
succeed. This includes cases in which the columns proposed the partitioning function are defined
implicitly as those in the table's primary key by employing an empty PARTITION BY KEY() clause.
For more information and examples, see Column index prefixes not supported for key partitioning,
and KEY Partitioning. (Bug #29941932, Bug #29941959, Bug #31100205, WL #13588)
JSON Notes
• Added the JSON_VALUE() function, which simplifies creating indexes on JSON columns. A
call to JSON_VALUE(json_doc, path RETURNING type) is equivalent to calling CAST(
JSON_UNQUOTE( JSON_EXTRACT(json_doc, path) ) AS type), where json_doc is a
JSON document, path is a JSON path expression pointing to a single value within the document,
and type is a data type compatible with CAST(). RETURNING type is optional; if no return type is
specified, JSON_VALUE() returns VARCHAR(512).
JSON_VALUE() also supports ON EMPTY and ON ERROR clauses similar to those used with
JSON_TABLE().
You can create indexes on a JSON column using JSON_VALUE() as shown here:
CREATE TABLE inventory(
items JSON,
INDEX i1 ( (JSON_VALUE(items, '$.name' RETURNING CHAR(50))) ),
INDEX i2 ( (JSON_VALUE(items, '$.price' RETURNING DECIMAL(5,2))) ),
INDEX i3 ( (JSON_VALUE(items, '$.quantity' RETURNING UNSIGNED)) )
);
Assuming the items column contains values such as '{"name": "hat", "price": "22.95",
"quantity": "17"}', you can issue queries, such as the following, that are able to use these
indexes:
SELECT items->"$.price" FROM inventory
WHERE JSON_VALUE(items, '$.name' RETURNING CHAR(50)) = "hat";
191
MySQL 8.0 Release Notes
For more information and examples, see the description of the JSON_VALUE() function. (WL
#12228)
Optimizer Notes
• MySQL attempts to use an ordered index for any ORDER BY or GROUP BY query that has a LIMIT
clause, overriding any other choices made by the optimizer, whenever it determines that this would
result in faster execution. Because the algorithm for making this determination makes certain
assumptions about data distribution and other conditions, it may not always be completely correct,
and it is possible in some cases that choosing a different optimization for such queries can provide
better performance. To handle such occurrences, it is now possible to disable this optimization by
setting the optimizer_switch system variable's prefer_ordering_index flag to off.
For more information about this flag and examples of its use, see Switchable Optimizations, and
LIMIT Query Optimization.
Our thanks to Jeremy Cole for the contribution. (Bug #97001, Bug #30348211, WL #13929)
• A single-table UPDATE or DELETE statement that uses a subquery having a [NOT] IN or [NOT]
EXISTS predicate can now in many cases make use of a semijoin transformation or subquery
materialization. This can be done when the statement does not use LIMIT or ORDER BY, and when
semijoin or subquery materialization is allowed by any optimizer hints used in the subquery, or by the
value of the optimizer_switch server system variable.
You can see when the semijoin optimization or subquery materialization is used for an eligible single-
table DELETE or UPDATE due to the presence of a join_optimization object in the optimizer
trace. You can also see that the conversion is performed by checking the output of EXPLAIN
FORMAT=TREE; if the optimization is not performed, this shows <not executable by iterator
executor>, while a multi-table statement reports a full plan.
As part of this work, semi-consistent reads are now supported by multi-table UPDATE of InnoDB
tables, when the transaction isolation level is weaker than REPEATABLE READ. (Bug #35794, Bug
#96423, Bug #11748293, Bug #30139244, WL #6507)
• Added the optimizer_switch flag subquery_to_derived. When this flag is set to on, the
optimizer transforms eligible scalar subqueries into left outer joins (and in some cases, inner
joins) on derived tables. This optimization can be applied to a subquery which meets the following
conditions:
ANY and ALL subqueries which can be rewritten to use MIN() or MAX() are also not affected.
With subquery_to_derived=on, the optimization can also be applied to a table subquery which
is the argument to IN, NOT IN, EXISTS, or NOT EXISTS, and which does not contain a GROUP BY
clause.
The subquery_to_derived flag is set to off by default, since it generally does not improve
performance, and its intended use for the most part is for testing purposes.
192
MySQL 8.0 Release Notes
For more information, see Switchable Optimizations, for more information and examples. See also
Optimizing Derived Tables, View References, and Common Table Expressions with Merging or
Materialization, and LIMIT Query Optimization. (WL #13851)
• Building on work done in MySQL 8.0.18, the server now performs injection of casts into queries to
avoid mismatches when comparing string data types with those of numeric or temporal types; as
when comparing numeric and temporal types, the optimizer now adds casting operations in the item
tree inside expressions and conditions in which the data type of the argument and the expected data
type do not match. This makes queries in which string types are compared with numeric or temporal
types equivalent to queries which are compliant with the SQL standard, while maintaining backwards
compatibility with previous releases of MySQL. Such casts are now performed whenever string
values are compared to numeric or temporal values using any of the standard numeric comparison
operators (=, >=, >, <, <=, <>/!=, and <=>).
Such implicit casts are now performed between a string type (CHAR, VARCHAR, BINARY,
VARBINARY, BLOB, TEXT, ENUM, or SET) and a numeric type (SMALLINT, TINYINT, MEDIUMINT,
INT/INTEGER, BIGINT; DECIMAL/NUMERIC; FLOAT, DOUBLE, REAL; and BIT) by casting the string
value to DOUBLE; if the numeric value is not already of type DOUBLE, FLOAT, or REAL, it is also
cast to DOUBLE. A YEAR value is also cast to DOUBLE when compared with a string value (as is the
string value). For such comparisons between string types and TIMESTAMP or DATETIME values, the
arguments are cast as DATETIME; when a string type is compared with a DATE value, the string is
cast to DATE.
You can see when casts are injected into a given query by viewing the output of
EXPLAIN ANALYZE, EXPLAIN FORMAT=JSON, or EXPLAIN FORMAT=TREE. EXPLAIN
[FORMAT=TRADITIONAL] can also be used, but in this case it is necessary, following execution of
the EXPLAIN statement, to issue SHOW WARNINGS to view the rewritten query.
This change is not expected to cause any difference in query results or performance. (WL #13456)
Packaging Notes
• For RPM and Debian packages, client-side plugins were moved from the server package to the client
package. Additionally, debug versions of client-side plugins were moved to the test package. (Bug
#31123564, Bug #31336340)
• MSI packages for Windows no longer include the legacy server data component. (Bug #31060177)
• The bundled Protobuf library was upgraded from version 3.6.1 to version 3.11. (Bug #31000511, Bug
#98852)
• The libevent library bundled with MySQL was upgraded to version 2.1.11. In addition, for the
WITH_LIBEVENT CMake option, the following two changes were made:
2. If system is specified but no system libevent is found, the bundled version is no longer used
in place of the missing system library, and an error occurs instead.
(Bug #30926742)
• The ICU (International Components for Unicode) library bundled with MySQL has been upgraded to
version 65.1.
193
MySQL 8.0 Release Notes
Pluggable Authentication
• The MySQL Enterprise Edition authentication_ldap_sasl plugin that
implements SASL LDAP authentication supports multiple authentication methods,
but depending on host system configuration, they might not all be available. The new
Authentication_ldap_sasl_supported_methods status variable provides discoverability for
the supported methods. Its value is a string consisting of supported method names separated by
spaces. Example: "SCRAM-SHA1 GSSAPI" (WL #13876)
Security Notes
• Incompatible Change: Access to the INFORMATION_SCHEMA.FILES table now requires the
PROCESS privilege.
This change affects users of the mysqldump command, which accesses tablespace information in
the FILES table, and thus now requires the PROCESS privilege as well. Users who do not need to
dump tablespace information can work around this requirement by invoking mysqldump with the --
no-tablespaces option. (Bug #30350829)
• For platforms on which OpenSSL libraries are bundled, the linked OpenSSL library for MySQL
Server has been updated to version 1.1.1g. Issues fixed in the new OpenSSL version are described
at https://www.openssl.org/news/cl111.txt and https://www.openssl.org/news/vulnerabilities.html.
(Bug #31296697)
• Previously, LOCAL data loading capability for the LOAD DATA statement could be controlled on
the client side only by enabling it for all files accessible to the client, or by disabling it altogether.
The new MYSQL_OPT_LOAD_DATA_LOCAL_DIR option for the mysql_options() C API function
enables clients to restrict LOCAL data loading to files located in a designated directory. See Security
Considerations for LOAD DATA LOCAL. (WL #13168)
• The innodb.innodb_mysql test case was updated to avoid nondeterminism of output row order.
Thanks to Facebook for the contribution. (Bug #30810572, Bug #98377)
X Plugin Notes
• Where a dollar sign ($) was used to reference an entire document, X Plugin handled the reference
differently depending on the context in which it was used. This has now been standardized. (Bug
#31374713)
• With certain settings for the global SQL mode, X Plugin's authentication process failed to accept a
correct user password. The authentication process now operates independently from the global SQL
mode's setting to ensure consistency. (Bug #31086109)
194
MySQL 8.0 Release Notes
Note that Group Replication does not use checksums to verify incoming events on the
group_replication_applier channel, because events are written to that relay log from
multiple sources and before they are actually written to the originating server's binary log, which
is when a checksum is generated. Checksums are used to verify the integrity of events on the
group_replication_recovery channel and on any other replication channels on group
members. (WL #9038)
• Performance: Improved the implementation of the UNHEX() function by introducing a lookup table
for mapping a hexadecimal digit string to its binary representation. This change speeds up execution
of the function by a factor of 8 or more in testing. (Bug #31173103)
• InnoDB: Redo logging can now be enabled and disabled using ALTER INSTANCE {ENABLE|
DISABLE} INNODB REDO_LOG syntax. This functionality is intended for loading data into a new
MySQL instance. Disabling redo logging helps speed up data loading by avoiding redo log writes.
The new INNODB_REDO_LOG_ENABLE privilege permits enabling and disabling redo logging.
The new Innodb_redo_log_enabled status variable permits monitoring redo logging status.
• InnoDB: Truncating an undo tablespace on a busy system could affect performance due to
associated flushing operations that remove old undo tablespace pages from the buffer pool and flush
the initial pages of the new undo tablespace to disk. To address this issue, the flushing operations
were removed.
Old undo tablespace pages are now released passively as they become least recently used, or are
removed at the next full checkpoint. The initial pages of the new undo tablespace are now redo
logged instead of flushed to disk during the truncate operation, which also improves durability of the
undo tablespace truncate operation.
To prevent potential issues caused by an excessive number of undo tablespace truncate operations,
truncate operations on the same undo tablespace between checkpoints are now limited to 64. If the
limit is exceeded, an undo tablespace can still be made inactive, but it is not truncated until after the
next checkpoint.
• InnoDB: At startup, InnoDB validates the paths of known tablespace files against tablespace
file paths stored in the data dictionary in case tablespace files have been moved to a different
location. The new innodb_validate_tablespace_paths variable permits disabling tablespace
path validation. This feature is intended for environments where tablespaces files are not moved.
195
MySQL 8.0 Release Notes
Disabling tablespace path validation improves startup time on systems with a large number of
tablespace files.
For more information, see Disabling Tablespace Path Validation. (WL #14008)
• InnoDB: Table and table partition data files created outside of the data directory using the DATA
DIRECTORY clause are now restricted to directories known to InnoDB. This change permits
database administrators to control where tablespace data files are created and ensures that the data
files can be found during recovery.
General and file-per-table tablespaces data files (.ibd files) can no longer be created in the undo
tablespace directory (innodb_undo_directory) unless that directly is known to InnoDB.
Truncating an InnoDB table that resides in a file-per-table tablespace drops the existing tablespace
and creates a new one. As of MySQL 8.0.21, InnoDB creates the new tablespace in the default
location and writes a warning to the error log if the tablespace was created with an earlier version
and the current tablespace directory is unknown. To have TRUNCATE TABLE create the tablespace
in its current location, add the directory to the innodb_directories setting before running
TRUNCATE TABLE. (WL #13065)
• InnoDB: To improve concurrency for operations that require access to lock queues for table and
row resources, the lock system mutex (lock_sys->mutex) was replaced by sharded latches, and
lock queues were grouped into table and page lock queue shards, with each shard protected by a
dedicated mutex. Previously, the single lock system mutex protected all lock queues, which was a
point of contention on high-concurrency systems. The new sharded implementation permits more
granular access to lock queues.
The lock system mutex (lock_sys->mutex) was replaced by the following sharded latches:
• wait/synch/sxlock/innodb/lock_sys_global_rw_lock
• wait/synch/mutex/innodb/lock_sys_table_mutex
• wait/synch/mutex/innodb/lock_sys_page_mutex
(WL #10314)
• Group Replication: Group Replication group members can now advertise a list of IP addresses that
joining members can use to make connections to them for state transfer during distributed recovery.
Previously, the existing member's standard SQL client connection was used for this purpose as well
as for client traffic. Advertising distributed recovery endpoints instead gives you improved control
of distributed recovery traffic (comprising remote cloning operations and state transfer from the
binary log) in your network infrastructure. The list of distributed recovery endpoints for a member
196
MySQL 8.0 Release Notes
• Group Replication: You can now specify user credentials for distributed recovery on the START
GROUP_REPLICATION statement using the USER, PASSWORD, and DEFAULT_AUTH options. These
credentials are used for distributed recovery on the group_replication_recovery channel.
When you specify user credentials on START GROUP_REPLICATION, the credentials are saved in
memory only, and are removed by a STOP GROUP_REPLICATION statement or server shutdown.
These credentials can replace user credentials set using a CHANGE MASTER TO statement, which
are stored in the replication metadata repositories, and can therefore help to secure the Group
Replication servers against unauthorized access.
The new method of providing user credentials is not compatible with starting Group Replication
automatically on server start. If user credentials have previously been set using a CHANGE MASTER
TO statement, credentials that you specify on START GROUP_REPLICATION take precedence
over these. However, the credentials from the replication metadata repositories are used if START
GROUP_REPLICATION is specified without user credentials, which happens on automatic starts if
the group_replication_start_on_boot system variable is set to ON (including after a remote
cloning operation for distributed recovery). To gain the security benefits of specifying user credentials
on START GROUP_REPLICATION, ensure that group_replication_start_on_boot is set
to OFF (the default is ON), and use a CHANGE MASTER TO statement to clear any user credentials
previously set for the group_replication_recovery channel. (WL #13768)
• Group Replication: The minimum setting for the maximum size for the XCom message cache
in Group Replication, specified by the group_replication_message_cache_size system
variable, has been reduced from approximately 1 GB to 134217728 bytes, or approximately 128 MB.
Note that this size limit applies only to the data stored in the cache, and the cache structures require
an additional 50 MB of memory. The same cache size limit should be set on all group members.
The default XCom message cache size of 1 GB, which was formerly also the minimum setting, is
unchanged.
The smaller message cache size is provided to enable deployment on a host that has a
restricted amount of available memory and good network connectivity. Having a very low
group_replication_message_cache_size setting is not recommended if the host is on
an unstable network, because a smaller message cache makes it harder for group members to
reconnect after a transient loss of connectivity. If some messages that were exchanged during a
member's temporary absence have been deleted from the other members' XCom message caches
because their maximum size limit was reached, the member cannot reconnect using the message
cache. It must leave the group and rejoin in order to retrieve the transactions through distributed
recovery, which is a slower process than using the message cache, although the member still can
rejoin in this way without operator intervention.
Note that from MySQL 8.0.21, by default an expel timeout of 5 seconds is added before a member is
expelled from the group (specified by the group_replication_member_expel_timeout system
variable). With this default setting the XCom message cache therefore now needs to store the
messages exchanged by the group in a 10-second period (the expel timeout plus the initial 5-second
detection period), rather than in a 5-second period as previously (the initial 5-second detection period
only). (WL #13979)
197
MySQL 8.0 Release Notes
to the group. If the member does reconnect in this time, it can recover missed messages from the
XCom message cache and return to ONLINE state automatically, rather than being expelled from the
group and needing the auto-rejoin procedure or manual operator intervention to rejoin.
If you previously tuned the size of the XCom message cache with reference to the expected volume
of messages in the previous default time before a member was expelled (the 5-second detection
period only), increase your group_replication_message_cache_size setting to account for
the new expel timeout, which doubles the default time to 10 seconds. With the new default expel
timeout you might start to see warning messages from GCS on active group members, stating that a
message that is likely to be needed for recovery by a member that is currently unreachable has been
removed from the message cache. This message shows that a member has had a need to use the
message cache to reconnect, and that the cache size might not be sufficient to support the current
waiting period before a member is expelled. (WL #13773)
• Group Replication: The Group Replication auto-rejoin feature is now activated by default. The
group_replication_autorejoin_tries system variable, which is available from MySQL
8.0.16, makes a member that has been expelled or reached its unreachable majority timeout try
to rejoin the group automatically. This system variable, which originally defaulted to 0 so auto-
rejoin was not activated, now defaults to 3, meaning that a member makes three attempts to
rejoin the group in the event of its expulsion or unreachable majority timeout. Between each
attempt the member waits for 5 minutes. If the specified number of tries is exhausted without
the member rejoining or being stopped, the member proceeds to the action specified by the
group_replication_exit_state_action system variable.
The auto-rejoin feature minimizes the need for manual intervention to bring a member back into the
group, especially where transient network issues are fairly common. During and between auto-rejoin
attempts, a member remains in super read only mode and does not accept writes. However, reads
can still be made on the member, with an increasing likelihood of stale reads over time. If you want
to intervene to take the member offline, the member can be stopped manually at any time by using
a STOP GROUP_REPLICATION statement or shutting down the server. If you cannot tolerate the
possibility of stale reads for any period of time, set the group_replication_autorejoin_tries
system variable to 0, in which case operator intervention is required whenever a member is expelled
from the group or reaches its unreachable majority timeout. (WL #13706)
• Previously, the --disabled-storage-engines option did not ignore spaces around storage
engines listed in the option value. Spaces around engine names are now ignored. (Bug #31373361,
Bug #99632)
• The new HANDLE_FATAL_SIGNALS CMake option enables configuring whether Address Sanitizer
and Undefined Behavior Sanitizer builds use the sanitizer runtime library to handle fatal signals
rather than a MySQL-internal function. The option default is ON for non-sanitizer builds, OFF for
sanitizer builds. If the option is OFF, the default action is used for SIGBUS, SIGILL and SIGSEGV,
rather than the internal function. (Bug #31068443)
• Using a column that is repeated twice or more in GROUP BY (through an alias), combined with
ROLLUP, had behavior differing from MySQL 5.7. Example:
SELECT a, b AS a, COUNT(*) FROM t1 GROUP BY a, b WITH ROLLUP;
Behavior of such queries has been changed to better match MySQL 5.7. They should be avoided,
however, because behavior may change again in the future or such queries may become illegal.
(Bug #30921780, Bug #98663)
• comp_err provides better error messages for certain input file issues. Thanks to Facebook for the
contribution. (Bug #30810629, Bug #98390)
• MySQL Server Docker containers now support server restart within a client session (which happens,
for example, when the RESTART statement is executed by a client or during the configuration of
an InnoDB Cluster instance). To enable this important feature, containers should be started with
the docker run option --restart set to the value on-failure. See Starting a MySQL Server
Instance for details. (Bug #30750730)
198
MySQL 8.0 Release Notes
• EXPLAIN ANALYZE now supports the FORMAT option. Currently, TREE is the only supported format.
(Bug #30315224)
• ALTER INSTANCE ROTATE INNODB MASTER KEY is no longer permitted when read_only or
super_read_only are enabled. (Bug #30274240)
• On storage engines that support atomic DDL, the CREATE TABLE ... SELECT statement is now
logged as one transaction in the binary log when row-based replication is in use. Previously, it was
logged as two transactions, one to create the table, and the other to insert data. With this change,
CREATE TABLE ... SELECT statements are now safe for row-based replication and permitted
for use with GTID-based replication. For more information, see Atomic Data Definition Statement
Support. (Bug #11756034, Bug #47899, WL #13355)
• LOAD XML now supports CDATA sections in the XML file to be imported. (Bug #98199, Bug
#30753708)
• X Plugin's mysqlx_bind_address system variable now accepts multiple IP addresses like MySQL
Server's bind_address system variable does, enabling X Plugin to listen for TCP/IP connections
on multiple network sockets.
An important difference in behavior is that for MySQL Server, any error in the list of addresses
prevents the server from starting, but X Plugin (which is not a mandatory plugin) does not do this.
With X Plugin, if one of the listed addresses cannot be parsed or if X Plugin cannot bind to it, the
address is skipped, an error message is logged, and X Plugin attempts to bind to each of the
remaining addresses. X Plugin's Mysqlx_address status variable displays only those addresses
from the list for which the bind succeeded. If none of the listed addresses results in a successful
bind, X Plugin logs an error message stating that X Protocol cannot be used. (WL #12715)
The following INFORMATION_SCHEMA tables were added for querying storage engine attributes for
tables, columns, indexes, and tablespaces. Values are stored in the data dictionary. The tables are
reserved for future use.
• INFORMATION_SCHEMA.TABLES_EXTENSIONS
• INFORMATION_SCHEMA.COLUMNS_EXTENSIONS
• INFORMATION_SCHEMA.TABLE_CONSTRAINTS_EXTENSIONS
• INFORMATION_SCHEMA.TABLESPACES_EXTENSIONS
(WL #13341)
• The default logging level for MySQL Server omits informational log messages, which previously
included some significant lifecycle events for Group Replication that were non-error situations, such
as a group membership change. Messages about significant events for a replication group have now
been reclassified as system messages, so they always appear in the server error log regardless
of the server logging level. Operators can therefore review a complete history of the server's
membership in a replication group. In addition, socket bind errors on the group communication layer
have been reclassified from information to error messages. (WL #13769)
Bugs Fixed
• InnoDB: A GROUP BY operation on a JSON array column caused failures in an UBSan build of
MySQL due to incorrect type casting. (Bug #31451475)
199
MySQL 8.0 Release Notes
• InnoDB: Several InnoDB error log messages were defined without symbolic values. (Bug
#31401028)
• InnoDB: The file segment for a single page write was not released after a data file write failure
associated with a doublewrite flush and sync operation. (Bug #31370227)
• InnoDB: Code that was accessed when undo tablespace truncation used the same space ID before
and after a truncate operation was removed. That scenario no longer occurs. The truncated undo
tablespace is replaced by a new undo tablespace datafile with a different space ID. (Bug #31354435)
• InnoDB: The range of reserved space IDs for undo tablespaces was increased from 512 per undo
tablespace to 400000. (Bug #31340834)
• InnoDB: An error that occurred while inserting a log into the ddl_log table was not returned
making it appear as though the operation was successful, and a transaction was not registered while
performing a tablespace encryption operation. (Bug #31236217)
• InnoDB: The lob::purge() function did not free LOBs correctly for an undo log record type
(TRX_UNDO_UPD_DEL_REC) that is generated when an insert operation modifies a delete-marked
record. (Bug #31222046, Bug #99339)
• InnoDB: A shutdown error occurred following an attempt to rebuild a discarded partition. (Bug
#31215415)
• InnoDB: The internal get_real_path() function, responsible for retrieving directory or a file path,
was modified to strip trailing separators before determining if a path is a file or directory. Additionally,
if a path does not exist or cannot be identified as a file or subdirectory, the function now assumes the
path is a file if the basename has a three letter suffix. (Bug #31215160)
• InnoDB: Tablespace-related error messages were revised. (Bug #31205520, Bug #31205441)
• InnoDB: The parallel read thread limit was not observed when spawning read threads for histogram
sampling, causing an assertion failure. (Bug #31151218)
• InnoDB: The transaction read view was not checked when sampling records for generation of
histogram statistics. (Bug #31151077)
• InnoDB: An I/O completion routine was not able acquire an LRU list mutex due to a latch held by
another thread. (Bug #31128739)
• InnoDB: An attachable transaction thread requested an InnoDB ticket that was already reserved by
the main thread, causing a deadlock. Additionally, the server failed to respond to KILL statements in
this deadlock scenario. (Bug #31090777)
• InnoDB: The INNODB_METRICS table AVG_COUNT_RESET value for a counter defined as a module
owner reported NULL. The METRIC_AVG_VALUE_RESET field was incorrectly marked as NULL.
Thanks to Fungo Wang for the contribution. (Bug #31084706, Bug #98990)
• InnoDB: Various aspects of the lock system (lock_sys) code were refactored, and issues with
lock_sys lock_rec_block_validate() and lock_test_prdt_pacge_lock() functions
were fixed. The lock_rec_block_validate() function called another function repeatedly, which
could result in locks not being validated under certain circumstances. The implementation also had a
200
MySQL 8.0 Release Notes
potential quadratic time complexity. The lock_test_prdt_page_lock() function did not iterate
over all locks as intended. (Bug #31001732)
• InnoDB: Use of memory-mapped files after exceeding the temptable_max_ram threshold caused
a performance degradation. (Bug #30952983, Bug #98739)
• InnoDB: In debug mode, a DROP TABLE operation on a table with an incorrectly defined
COMPRESSION clause caused a failure. InnoDB did not return an error to the caller for proper
handling. (Bug #30899683, Bug #98593)
• InnoDB: Purge thread activity was excessive when the history list length approached zero, wasting
CPU resource and causing mutex contention. (Bug #30875956)
• InnoDB: An ALTER TABLE ... IMPORT TABLESPACE operation with a .cfg file failed with an
“Incorrect key file for table” error. The row_import::m_flags member was not initialized. (Bug
#30830441)
• InnoDB: A DROP TABLE operation performed after discarding a partition did not remove the
associated data files, and DROP DATABASE failed with an error indicating that the database directory
could not be removed. Upgrade from MySQL 5.7 to MySQL 8.0 also failed if a partitioned table with a
discarded partition was present. The DISCARD attribute was applied to the table object instead of the
partition object in the data dictionary, which made it appear that all partitions were discarded. (Bug
#30818917)
• InnoDB: The server failed intermittently with an “ibuf cursor restoration fails” error. (Bug #30770380,
Bug #91033)
• InnoDB: An ALTER TABLE operation that copied data from one table to another returned an “Out
of range value for column” error. The counter that tracks the number of AUTO_INCREMENT rows
required for a multi-row insert operation was not always set back to zero after a bulk insert operation.
(Bug #30765952, Bug #98211)
• InnoDB: A type conversion failure during a DELETE IGNORE operation caused an assertion failure.
A JSON value was not converted to the expected value. (Bug #30664660)
• InnoDB: A purge operation encountered a null LOB reference, causing an assertion failure. (Bug
#30658887)
• InnoDB: Chunk size was not calculated correctly when deallocating memory from the TempTable
storage engine, causing a regression in SELECT DISTINCT query performance. (Bug #30562964)
• InnoDB: A segmentation fault occurred in the TempTable storage engine while using the thread pool
plugin. TempTable thread-local variables were not compatible with the use of different threads for
statements issued by a single client connection. Use of thread local variables also lead to excessive
memory consumption due to the memory used by thread-local variables remaining allocated for
the life of the thread. To address these issues, thread-local variables were replaced by a caching
mechanism. (Bug #30050452, Bug #31116036, Bug #99136)
201
MySQL 8.0 Release Notes
• InnoDB: A fatal “page still fixed or dirty” error occurred during shutdown. (Bug #29759555, Bug
#95285)
• Partitioning: A query against a partitioned table, which used an ORDER BY, returned unordered
results under the following conditions:
• The table had a composite index with a prefix on one of the columns.
• The query's WHERE clause contained an equality condition on the prefixed column.
• The column with the prefix was the leftmost column in the index.
• The column used in the ORDER BY was the rightmost column in the index.
Our thanks to Quanan Han for the suggestion. (Bug #84070, Bug #25207522)
• Replication: When a replication source server shuts down and restarts, its MEMORY tables become
empty. To replicate this effect to replicas, the first time that the source uses a given MEMORY table
after startup, it notifies replicas that the table must be emptied by writing a DELETE statement for
that table to the binary log. Previously, the generated DELETE statement was written to the binary
log statement cache for the current session, which could result in it being logged together with other
statements under the same GTID, or logged without BEGIN and COMMIT statements. Also, in some
situations, the generated DELETE statement could consume the GTID intended for the transaction
that triggered it. The generated DELETE statement is now logged with accompanying BEGIN and
COMMIT statements, and the resulting transaction is flushed to the binary log immediately after it is
written to the statement cache, so that it always receives its own GTID and is kept separate from
other transactions. (Bug #30527929, Bug #25681518, Bug #77729)
• Replication: Following a patch in MySQL 8.0.14, if a function call contained operations on temporary
tables, it could be written to the binary log in statement format when binlog_format = MIXED
was set. This led to CREATE TEMPORARY TABLE statements being incorrectly written to the binary
log if they contained a function call. Following further analysis, operations on temporary tables in
stored functions and triggers are now marked as unsafe for binary logging in statement format, as
they have a strong chance of causing issues with replication. When binlog_format = MIXED is
set, these operations are now logged in row format. (Bug #30395151, Bug #30320009)
• Replication: A fix made in MySQL 8.0.14 and MySQL 5.7.25 for a deadlock scenario
involving the system variables binlog_transaction_dependency_tracking and
binlog_transaction_dependency_history_size had the side effect of leaving the writeset
history used for transaction dependency tracking unprotected from concurrent update. The writeset
history and tracking mode are now locked correctly whenever they are accessed. (Bug #29719364,
Bug #95181)
202
MySQL 8.0 Release Notes
starts the replication channel. This approach means that the replication channel always needs
operator intervention to restart, but the user credentials are not recorded in the replication metadata
repositories.
The documentation for the CHANGE MASTER TO statement has also been corrected to clarify that it
is possible to specify MASTER_USER='', and the resulting error occurs only if you attempt to start
the replication channel with the empty credentials. (Bug #27357189)
• Group Replication: On Windows, Group Replication's use of the Windows API function
SleepConditionVariableCS to wait for new write events caused noticeably high CPU usage
by this function after Group Replication had been running for two days or more, which could
be corrected by restarting the MySQL server instance, but then increased again over time as
before. This was caused by the use of two clock functions to calculate the timeout after which the
SleepConditionVariableCS function was called, which drifted relative to each other over time, making
the timeout progressively shorter and the calls to the function more frequent. The issue has been
corrected on Windows by using the current time from a single clock to calculate the timeout. (Bug
#31117930)
• Group Replication: If Group Replication was stopped while distributed recovery was in progress,
memory issues could result from an attempt to access the record of the member that was selected
as the donor. This record is now kept locally with the distributed recovery state. (Bug #31069563)
• Group Replication: When distributed recovery for Group Replication involves a remote cloning
operation, the flag set on the server to indicate this remains set until the server instance is restarted.
Previously, if Group Replication was stopped and restarted on the server, that flag caused Group
Replication to purge the relay log files for the group_replication_applier channel, as is
required on starting after a remote cloning operation to ensure that there is no mismatch with the
cloned data tables. If there were any unapplied transactions in the purged relay log files, the member
could not subsequently be used to bootstrap a group, although it could successfully join a group
by retrieving the transactions from another member. Group Replication now ignores the flag on its
second or subsequent starts, and only purges the relay log files the first time it is started after a
remote cloning operation. (Bug #31059680)
• Group Replication: To avoid the possibility of data inconsistency, Group Replication blocks a
new incarnation of the same server (with the same address but a new identifier) from joining the
group while its old incarnation is still listed as a member. Previously, the Group Replication Group
Communication System (GCS) treated the connection to the old incarnation of a server as active
while it was attempting to send messages to the server, and only recognized that the connection was
inactive when the socket returned an error, which might take a significant amount of time. During that
period, the new incarnation of the server was unable to join the group because the existing members
did not connect to it, as they were still waiting on the connection to the old incarnation. Now, GCS
only treats a connection to a server as active while messages can be sent to it successfully. If the
socket is no longer writeable, the server connection is treated as inactive and is proactively closed.
The connection close triggers the group member to attempt reconnection to that server address,
upon which a connection is established to the new incarnation of the server, enabling the new
incarnation to join the group. (Bug #30770577)
• Group Replication: Group Replication did not broadcast a notification when switching from single-
primary mode to multi-primary mode. The change is now notified for use in routing. (Bug #30738896)
203
MySQL 8.0 Release Notes
• Group Replication: Group Replication tracking of connections to other group members only took
into account the incoming connections, not the outgoing connections. This meant if the outgoing
connection from member A to member B was broken, for example by a firewall configuration issue,
but the incoming connection from member B to member A was intact, member A would display
member B's status as ONLINE, although member A's messages were not reaching member B.
Member B would display member A's status as UNREACHABLE. Now, if a group member starts
to receive pings from another group member to which it has an active connection (in this case,
if member A received pings from member B), this is treated as an indicator of an issue with the
connection. If sufficient pings are received, the connection is shut down by the recipient of the pings
(in this case, member A), so that the status of the connection is consistent for both members. (Bug
#25660161, Bug #84796)
• JSON: When the expression and path passed to JSON_TABLE() yielded a JSON null, the function
raised an error instead of returning SQL NULL as required. (Bug #31345503)
• JSON: In MySQL 5.7, and in MySQL 8.0 prior to 8.0.17, the server attempted to convert JSON
boolean values to their SQL counterparts when testing them directly with IS TRUE, as shown here:
mysql> CREATE TABLE test (id INT, col JSON);
mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
+------+---------------+--------------+
| id | col | col->"$.val" |
+------+---------------+--------------+
| 1 | {"val": true} | true |
+------+---------------+--------------+
As the result of work done in MySQL 8.0.17 to ensure that all predicates in SQL conditions are
complete (that is, a condition of the form WHERE value is rewritten as WHERE value <> 0),
and that a NOT IN or NOT EXISTS condition in a WHERE or ON clause is converted to an antijoin,
evaluation of a JSON value in an SQL boolean context performs an implicit comparison against
JSON integer 0. This means that the query shown previously returns the following result in MySQL
8.0.17 and later:
mysql> SELECT id, col, col->"$.val" FROM test WHERE col->"$.val" IS TRUE;
+------+----------------+--------------+
| id | col | col->"$.val" |
+------+----------------+--------------+
| 1 | {"val": true} | true |
| 2 | {"val": false} | false |
+------+----------------+--------------+
In such cases, the server also now provides a warning: Evaluating a JSON value in SQL
boolean context does an implicit comparison against JSON integer 0; if
this is not what you want, consider converting JSON to a SQL numeric type
with JSON_VALUE RETURNING. Thus, the query can now be rewritten using JSON_VALUE() as
shown here:
mysql> SELECT id, col, col->"$.val" FROM test
-> WHERE JSON_VALUE(col, "$.val" RETURNING UNSIGNED) IS TRUE;
+------+---------------+--------------+
204
MySQL 8.0 Release Notes
| id | col | col->"$.val" |
+------+---------------+--------------+
| 1 | {"val": true} | true |
+------+---------------+--------------+
(Bug #31168181)
• JSON: A GROUP BY query against a table having a multi-valued index was not always handled
correctly by the server. (Bug #31152942)
• If log_error_services was persisted, in some cases it could take effect at the wrong time during
startup. (Bug #31464539)
• SHOW CREATE USER after certain manual grant table modifications could cause a server exit. (Bug
#31462844)
• Some in-memory updates of partial revokes could produce incorrect privileges. (Bug #31430086)
• If log_error_verbosity was set using SET PERSIST, it did not take effect early enough during
server startup to affect InnoDB initialization. (Bug #31410674)
• The parser incorrectly raised an assertion before rejecting subqueries in generated column
expressions. (Bug #31396191)
• This release makes the following two micro-optimizations for degenerate hash joins (that is, those
with no join conditions):
1. For a degenerate hash antijoin or semijoin, add LIMIT 1 when building the hash table, since
having more rows than this cannot change the result.
2. For a degenerate hash antijoin with a nonempty hash table, avoid scanning the outer side.
Together, these changes handle a performance regression whereby a rewrite to a hash antijoin
caused a NOT EXISTS query which was not rewritten to be executed by the optimizer and be
replaced with “zero rows found”. To handle the case in which a nested loop is used instead, a non-
correlated subquery inside NOT EXISTS is no longer transformed to an antijoin.
• The upgrade of the bundled libedit library in the previous MySQL distribution caused a problem
for builds using that library such that CTRL+C (SIGINT) in the mysql client required a following
Enter to take effect in some circumstances. (Bug #31360025)
• Columns declared with both AUTO_INCREMENT and DEFAULT value expressions are a nonpermitted
combination, but ALTER TABLE failed to produce an error for SET DEFAULT (expr) operations on
AUTO_INCREMENT columns. (Bug #31331454)
• A lookup function used internally in the MySQL server returns integer -1 when the argument is
ambiguous; this resulted in undefined behavior when this value was converted to an unsigned value
prior to use as an argument in subsequent calculations. Now when the function returns -1, this is
handled as an error and the value is not used further. (Bug #31326120)
• Negation of a signed value in certain cases led to undefined behavior; to prevent this from occurring,
the value to be negated is now treated as unsigned. (Bug #31325602)
• The WEIGHT_STRING() function did not always return the correct result for an integer argument.
(Bug #31321257)
205
MySQL 8.0 Release Notes
• Assigning CONCAT('') or CONCAT_WS('') to a variable set the variable to NULL, not the empty
string. (Bug #31320716, Bug #99485, Bug #31413167, Bug #99722)
• Corrected problems where under some circumstances privilege restrictions could be ignored. (Bug
#31306814, Bug #31315692)
• Certain SELECT statement privileges to lock rows were not checked properly and could block other
users incorrectly. (Bug #31293065)
• When performing a filesort, an internal function could sometimes return NULL on failure, even if the
subselect being sorted was not nullable. (Bug #31281602)
• Statement rewriting for the binary log was inefficient on Windows. (Bug #31260698)
• An inconsistency in representing anonymous users in memory could cause issues while performing
privilege-granting operations. (Bug #31246179)
• If the administrative connection interface was enabled, a race condition could lead to problems
accepting Unix socket file connections on the main connection interface. (Bug #31241872)
• When a role was granted with WITH ADMIN OPTION, the grantee was able to manage the role only
after activating it. (Bug #31237368)
• Invalid rows in the default_roles or role_edges system tables could cause server misbehavior.
(Bug #31217385)
• Component deinitialization failure at runtime could lead to repeated messages written to the error log
at shutdown. (Bug #31217037)
• The prohibition on granting roles to anonymous users was incompletely enforced. (Bug #31215017)
• The keyring_hashicorp keyring plugin did not perform sufficient validity checking on the values
of its configuration parameters. (Bug #31205363)
• The keyring_hashicorp keyring plugin did not permit binary log encryption to be enabled (by
setting the binlog_encryption system variable). (Bug #31204841)
• The keyring_hashicorp keyring plugin did not permit an encryption password to be set by the
audit_log plugin. (Bug #31197670)
• Some queries using REGEXP_SUBSTR() with an ORDER BY clause were not handled correctly by
the server. (Bug #31184858)
• Some instances where pointer arithmetic was applied to nullptr were corrected. (Bug #31172750)
• If the available file descriptors were exhausted, mysql_real_connect() caused the client to exit.
(Bug #31151052)
• Using the killall command to initiate a mysqld shutdown resulted in no message being logged to
indicate the start of shutdown. This has been corrected. (Bug #31121907)
• Calling mysql_real_connect_nonblocking() with an invalid host could cause the client to exit
upon calling mysql_close(). (Bug #31104389, Bug #99112)
• For Debian packages, Python 2 dependencies that could cause installation failures were removed.
(Bug #31099324)
• A potential memory leak in lf_hash_insert() was fixed. (Bug #31090258, Bug #99078)
206
MySQL 8.0 Release Notes
• Within the LDAP SASL authentication plugins, multiple calls to sasl_client_done() could cause
undefined behavior in some cases. (Bug #31088206)
• With the thread pool plugin enabled, high concurrency conditions could cause loss of client context
resulting in a server exit. (Bug #31085322)
• Removed an unneeded optimization for EXISTS() that was never actually evaluated. (Bug
#31069510)
• For a server started with the --skip-grant-tables option, enabling the partial_revokes
system variable caused a server exit. (Bug #31066069, Bug #31202963)
• Queries that used a recursive common table expression with an outer reference could return
incorrect results. (Bug #31066001, Bug #99025)
• The parser could fail for multibyte character sets with a minimum character length greater than 1
byte. (Bug #31063981)
• In some cases, the LEAST() function could return NULL for non-nullable input. (Bug #31054254)
• The last call to the mysql_fetch_row_nonblocking() C API function to return the null row was
setting an error when it should not have. (Bug #31048553, Bug #98947)
• On Windows, the default connection type uses a named pipe. The nonblocking C API, which is
intended for TCP/SSL connections, did not take that into account and caused the client to exit. It now
produces an error message indicating the problem. (Bug #31047717)
• X Plugin connections that failed to authenticate due to nonexistence of the user modified the global
audit_log_filter_id system variable. (Bug #31025461)
• LOAD DATA did not ignore hidden generated columns when parsing input file rows. (Bug #31024266,
Bug #98925)
• Pinbox exhaustion in the metadata locking subsystem could produce a misleading error message.
(Bug #31019269, Bug #98911)
• CREATE TABLE ... SELECT failed if it included a functional index. (Bug #31017765, Bug #98896)
• For X Protocol connections, checking the global session mutex was improved to eliminate a minor
performance degradation as the number of threads increased. (Bug #31000043)
• In certain cases, executing a query containing multiple subqueries could lead to an unplanned
shutdown of the server. (Bug #30975826)
• SHOW CREATE TRIGGER failed if FLUSH TABLES WITH READ LOCK was in effect. (Bug
#30964944)
• Excessive access checks were performed on certain of the data dictionary tables that underlie
INFORMATION_SCHEMA views, resulting in slow SHOW COLUMNS performance. These checks were
reduced to improve performance.
207
MySQL 8.0 Release Notes
SHOW SCHEMAS
SHOW TABLES
SHOW TABLE STATUS
SHOW COLUMNS
SHOW KEYS
SHOW EVENTS
SHOW TRIGGERS
SHOW PROCEDURE STATUS
SHOW FUNCTION STATUS
SHOW CHARACTER SET
SHOW COLLATION
• Two otherwise identical queries executed separately returned one row when using a case-sensitive
collation and two rows with a case-insensitive collation. When the same two predicates were
combined in a single query using AND, two rows were returned when only one row should have been.
(Bug #30961924)
• ALTER TABLE on a SET column that had a display width greater than 255 was not done in place,
even if otherwise possible. (Bug #30943642, Bug #98523)
• The server checked whether a number in yottabytes was too large to print by comparing the value as
a double to ULLONG_MAX, which cannot be represented as a double. This caused the double value
immediately above ULLONG_MAX yottabytes to be printed as 0Y, the erroneous conversion being
reported by Clang 10. (Bug #30927590)
• Resource group SQL statements such as CREATE RESOURCE GROUP did not work over connections
that use X Protocol. (Bug #30900411)
• SHOW GRANTS could display function privileges as procedure privileges. (Bug #30896461, Bug
#98570)
• The audit_log plugin mishandled connection events when multiple clients connected
simultaneously. (Bug #30893593)
• The LOCK_ORDER tool reported a syntax error for empty dependency graphs. Empty graphs are now
permitted.
The LOCK_ORDER tool could exhibit unexpected behavior due to mishandling thread list
maintenance. (Bug #30889192)
• Upgrades from MySQL 5.7 did not grant the REPLICATION_APPLIER privilege to root. (Bug
#30783149)
• The gen_range() user-defined function could mishandle its arguments, causing a server exit. (Bug
#30763294)
• During UPDATE processing, conversion of an internal in-memory table to InnoDB could result in a
key-length error. (Bug #30674616)
• Attempts to grant dynamic privileges (which are always global) at the procedure or function level did
not produce an error. (Bug #30628160)
• Table value constructors ignored the LIMIT clause. The clause is now taken into account. For
example: VALUES ROW(1), ROW(2), ROW(3) LIMIT 2 outputs 1 and 2. (Bug #30602659)
• It is possible to define a column named * (single asterisk character), but SELECT `*` was treated
identically to SELECT *, making it impossible to select only this column in a query; in other words,
the asterisk character was expanded to a list of all table columns even when it was surrounded by
backticks. (Bug #30528450)
• The FROM_DAYS() function could produce results that were out of range (with the year > 9999).
(Bug #30455845, Bug #97340)
208
MySQL 8.0 Release Notes
• For debug builds, altering the mysql.func table to MyISAM (not a recommended operation in any
case) caused a server exit. Now this operation is prohibited. (Bug #30248138, Bug #96692)
• In certain cases, a LIMIT clause incorrectly caused the optimizer to estimate that zero rows needed
to be read from a table. (Bug #30204811)
• An internal packet-length function returned values of the wrong integer type. (Bug #30139031)
• Calculations by mysqldump for the length of INSERT statements did not take into account the
_binary character set introducer used for VARBINARY strings. (Bug #29998457, Bug #96053)
• The messages printed to the error log during upgrade of partitioned tables defined with prefix keys
did not provide sufficient details. Detailed warnings that indicate the schema, table, column, and
prefix length are now printed. (Bug #29942014)
• An assertion was raised if creating a child table in a foreign key relation caused an engine
substitution. (Bug #29899151, Bug #95743)
• The server permitted connections for hosts with names longer than the maximum permitted length
(255 characters). (Bug #29704941)
• In a multiple-table UPDATE that updated the key of the first table, if a temporary table strategy was
used, duplicate entries could be written to the temporary table, followed by occurrence of a Can't
find record error. (Bug #28716103)
• The server sometimes mistakenly removed a subquery with a GROUP BY when optimizing a query,
even in some cases when this subquery was used by an outer select. This could occur when the
subquery also used an aggregate function. (Bug #28240054)
• When reading rows from a storage engine, errors other than “no more records” could be ignored,
leading to problems later. (Bug #20162055)
• When a multi-table update used a temporary table, this was not shown in the output of EXPLAIN
FORMAT=TREE, even though such use could have an impact on the performance of the UPDATE
statement for which this was done. (Bug #17978975)
• When performing a filesort for removing duplicates, such as when executing SELECT DISTINCT, it
may be necessary to perform another sort afterwards to satisfy an ORDER BY. In cases where such
an ORDER BY had been pushed down into the first table of a join, as opposed to the join as a whole,
this final sort was not actually performed. (Bug #99687, Bug #31397840)
• Refactoring work done in MySQL 8.0.20 caused single-row buffering for GROUP BY of non-nullable
columns not to function correctly, not taking into account that such a column could be the inner table
for an outer join, and thus would have a NULL flag that would need to be copied. In a GROUP BY
without a temporary table, this would cause the NULL flag to come from the next output row instead
of the previous one, and the data returned to be inconsistent. (Bug #99398, Bug #31252625)
209
MySQL 8.0 Release Notes
• A logical error in the constant folding code for the case in which a constant of type DECIMAL or
FLOAT was the left-hand operand and an integer column value was the right-hand operand yielded
an incorrect result. (Bug #99145, Bug #31110614)
• A query whose predicate compared 0 with -0 where at least one of these was a floating-point value
returned incorrect results. (Bug #99122, Bug #31102789)
• Reimplemented rollups without using slices. This fixes the following known issues:
• A repeating column in a GROUP BY ... WITH ROLLUP yielded the wrong result; that is, a GROUP
BY of the form GROUP BY a, b, a WITH ROLLUP erroneously produced NULL for some of the
column names in the result.
• A GROUP BY ... WITH ROLLUP that did not require a temporary table to print the result also
produced an erroneous NULL in place of at least one of the expected column names in the output.
(Bug #98768, Bug #99141, Bug #26227613, Bug #29134467, Bug #30967158, Bug #30969045, Bug
#31110494)
• Problems with error handling in queries with MAX(), MIN(), or both, combined with a GROUP BY
clause, meant that such a query continued executing until it went through all possible iterations even
when an error should have caused it to terminate immediately. (Bug #98242, Bug #30769515)
• After refactoring the type propagation code for LEAST(), GREATEST(), and other functions, as well
as UNION, an adjustment of the result type for data types like ENUM also replaced the calculated
integer data type with a type that could not accommodate both signed and unsigned values. (Bug
#95148, Bug #29698617)
• Compilation Notes
• JSON Notes
• Logging Notes
• Optimizer Notes
• Packaging Notes
• Pluggable Authentication
• X Plugin Notes
210
MySQL 8.0 Release Notes
• Bugs Fixed
For upgrades from an older version of MySQL, any user who has the global SELECT privilege is
granted SHOW_ROUTINE, if there is not already some user who has SHOW_ROUTINE. (WL #9049)
Compilation Notes
• Solaris: Clang and GCC now can be used for compiling MySQL on Solaris, although both are
experimental and cannot currently be used for production code. (Bug #30562248)
• On EL7 and EL8, CMake configuration was adjusted to look for GCC 9 before GCC 8.
Because libmysqlclient ships with MySQL distributions, client applications built against
libmysqlclient on those platforms are affected and may need to be recompiled. (Bug
#30722756)
• On Windows, the CMake compiler-version check for Visual Studio was updated to indicate that Visual
Studio 2019 is the currently supported version. (The version check can be bypassed by running
CMake with -DFORCE_UNSUPPORTED_COMPILER=1.) (Bug #30688403)
• The use of VALUES() to access new row values in INSERT ... ON DUPLICATE KEY UPDATE
statements is now deprecated, and is subject to removal in a future MySQL release. Instead, you
should use aliases for the new row and its columns as implemented in MySQL 8.0.19 and later.
For example, the statement shown here uses VALUES() to access new row values:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
211
MySQL 8.0 Release Notes
Henceforth, you should instead use a statement similar to the following, which uses an alias for the
new row:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new
ON DUPLICATE KEY UPDATE c = new.a+new.b;
Alternatively, you can employ aliases for both the new row and each of its columns, as shown here:
INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6) AS new(m,n,p)
ON DUPLICATE KEY UPDATE c = m+n;
For more information and examples, see INSERT ... ON DUPLICATE KEY UPDATE Statement. (WL
#13325)
JSON Notes
• The rapidjson library included with MySQL has been upgraded to the GitHub snapshot of 16
January 2020. A fix for a compiler error encountered when building from the snapshot on Mac OS X
has been added. (Bug #30898701)
Logging Notes
• Sending a SIGHUP signal to the server no longer causes it to write a status report to the error log.
Other actions performed by the server in response to SIGHUP continue to be done. See Unix Signal
Handling in MySQL.
Similarly, mysqladmin debug no longer causes the status report to be written. (Bug #30578923)
• The log_sink_json JSON-format error log sink now includes a ts (timestamp) in log messages.
The value is an integer indicating milliseconds since the epoch ('1970-01-01 00:00:00' UTC).
See Error Log Output Format. (WL #13786)
Optimizer Notes
• Hash joins are now used any time a nested block loop would be employed. This means that hash
joins can be used for the following types of queries:
• Inner non-equi-joins
• Semijoins
• Antijoins
This builds on work done for MySQL 8.0.18, and removes a limitation in the implementation such
that a hash join could be used only with a query having at least one equi-join condition. In addition,
both inner and outer joins (including semijoins and antijoins) can now employ batched key access
(BKA), which allocates join buffer memory incrementally so that individual queries need not use up
large amounts of resources that they do not actually require for resolution. For more information, see
Batched Key Access Joins.
This fix completes the task of replacing the executor used in previous versions of MySQL with the
iterator executor, including replacement of the old index subquery engines that governed queries of
the form WHERE value IN (SELECT column FROM table WHERE condition) for those IN
queries which have not been converted into semijoins, as well as queries materialized into the same
form, which depended on internals from the old executor.
212
MySQL 8.0 Release Notes
For more information and examples, see Hash Join Optimization. (Bug #30528604, Bug #30473261,
Bug #30912972, WL #13377, WL #13476)
• This release implements several new index-level optimizer hints, which function much like existing
index hints that employ SQL keywords such as FORCE INDEX and IGNORE INDEX. These are
intended to replace the equivalent index hints, which will be deprecated in a future MySQL release
(and eventually removed). The new hints are listed here, along with a brief description of each:
• JOIN_INDEX: Forces MySQL to use the specified index or indexes for any available access
method, such as ref, range, index_merge, and so on. This is equivalent to the FORCE INDEX
FOR JOIN index hint.
NO_JOIN_INDEX: Causes the server to ignore the specified index or indexes for any access
method. The equivalent index hint is IGNORE INDEX FOR JOIN.
• GROUP_INDEX: Makes the server use the specified index or indexes for index scans for GROUP BY
operations. Equivalent to FORCE INDEX FOR GROUP BY.
NO_GROUP_INDEX: Forces MySQL to ignore the specified index or indexes for index scans for
GROUP BY operations. The equivalent index hint is IGNORE INDEX FOR GROUP BY.
• ORDER_INDEX: Causes MySQL to use the specified index or indexes for sorting rows. It is
equivalent to FORCE INDEX FOR ORDER BY.
NO_ORDER_INDEX: Keeps the server from using the specified index or indexes for performing row
sorts. Equivalent to IGNORE INDEX FOR ORDER BY.
• INDEX: Acts as the combination of JOIN_INDEX, GROUP_INDEX, and ORDER_INDEX, forcing the
server to use the specified index or indexes for any and all scopes. Equivalent to FORCE INDEX.
Consider the following query using index hints on a table having the indicated columns and index:
Using the index-level optimizer hints introduced in this release, this query can be rewritten as shown
here:
The new index-level optimizer hints can be used with SELECT, UPDATE, and DELETE statements.
(This is unlike index hints using FORCE INDEX or IGNORE INDEX, which can be used only with
SELECT and UPDATE.) Thus, statements like the following are possible:
Multiple hints can be specified within the same comment, like this:
213
MySQL 8.0 Release Notes
Index-level optimizer hints can be used concurrently with other optimizer hints. When you do so, the
index-level hints apply first; the effects of any other optimizer hints are limited to the set of indexes
permitted by the index-level hints.
Index-level hints can also be used when creating views, as shown here:
CREATE VIEW v1 AS
SELECT /*+ NO_INDEX(t1 i_a,i_b) */ a FROM t1
WHERE b IN
(SELECT /*+ NO_INDEX(t1 i_ab,i_b) */ a FROM t1 WHERE a > 3)
ORDER BY a;
If these index-level optimizer hints are used in the same statement as index hints, the index hints are
ignored.
The new index-level optimizer hints are equivalent to FORCE INDEX rather than USE INDEX; in
other words, using one or more of the index-level optimizer hints means that a table scan is used
only if there is no way to use one of the named indexes to find rows in the table. To cause MySQL
to use the same index or set of indexes as with a given instance of USE INDEX, you can use
NO_INDEX, NO_JOIN_INDEX, NO_GROUP_INDEX, NO_ORDER_INDEX, or some combination of
these.
For more information and examples, see Index-Level Optimizer Hints. (WL #13538)
Packaging Notes
• Binary packages that include curl rather than linking to the system curl library have been
upgraded to use curl 7.69.0. (Bug #30866333)
• For RPM packages, the comp_err utility has been moved to the -test subpackage and marked as
a test component. (Bug #30716034)
• The bundled libedit library was upgraded to version 3.1. (Bug #28939380, Bug #20770875, Bug
#22930525, Bug #22332089, Bug #27433491, Bug #27285445, WL #13534)
• The bundled LZ4 library was upgraded to version 1.9.2. This fixes certain issues such as Bug
#30369643 producing a mysqlpump runtime error. (WL #13690)
Pluggable Authentication
• An LDAP server can be configured to delegate LDAP searches to another LDAP server,
a functionality known as LDAP referral. However, enabling LDAP referral can cause
searches to fail with LDAP operation errors under certain conditions. To enable the
MySQL Enterprise Edition LDAP authentication plugins to avoid referral errors, the new
authentication_ldap_simple_referral and authentication_ldap_sasl_referral
system variables are available. These variables enable each plugin to control whether the LDAP
server should use referral during MySQL authentication. See LDAP Search Referral. (WL #12888)
• The MySQL Enterprise Edition SASL LDAP authentication plugin now supports GSSAPI/Kerberos
as an authentication method for MySQL clients and servers on Linux. This is useful in Linux
214
MySQL 8.0 Release Notes
environments where applications access LDAP using Microsoft Active Directory, which has Kerberos
enabled by default. See LDAP Authentication Methods.
This feature is available for all RPM and DEB packages for Linux, but not for the TAR archive
packages. (WL #12888)
• Before FROM:
SELECT * INTO OUTFILE 'file_name' FROM table_name;
INTO now can appear in a third position, at the end of SELECT statements:
SELECT * FROM table_name FOR UPDATE INTO OUTFILE 'file_name';
Placing INTO at the end is the preferred position. The position before a locking clause is now
deprecated and support for it will be removed in a future MySQL version. In other words, INTO after
FROM but not at the end of the SELECT produces a warning.
Additionally, some changes have been made for UNION with respect to INTO. These UNION variants
containing INTO are syntactically correct and produce the same result:
... UNION SELECT * FROM table_name INTO OUTFILE 'file_name';
... UNION (SELECT * FROM table_name) INTO OUTFILE 'file_name';
... UNION SELECT * INTO OUTFILE 'file_name' FROM table_name;
... UNION (SELECT * INTO OUTFILE 'file_name' FROM table_name);
However, the last two variants are confusing, as if they collect information from the named table
rather than the entire query expression (the UNION). Those two UNION variants containing INTO now
are deprecated and support for them will be removed in a future MySQL version. Thus:
• In the trailing query block of a query expression, use of INTO before FROM produces a warning.
• In a parenthesized trailing block of a query expression, use of INTO (regardless of its position
relative to FROM) produces a warning.
The deprecations apply to all INTO forms: INTO OUTFILE, INTO DUMPFILE, and INTO
var_list. (WL #13559)
X Plugin Notes
• If the MySQL Server instance's client connections limit, as specified by the max_connections
server system variable, was reached while X Plugin was starting up, X Plugin was unable to create
a session to get the server configuration, so failed to start. X Plugin now creates an administrative
session (using the mysql_admin_session service) during startup, which is not subject to the client
connections limit. (Bug #30894981)
• When an X Protocol session could not be initialized because there were too many X Protocol
connections already, the error code 5011 Could not open session was returned. The
215
MySQL 8.0 Release Notes
more relevant error code 1040 Too many connections is now returned in this situation. (Bug
#30753637)
• An issue with validating JSON references caused an error when creating a collection with a
validation schema. (Bug #30733330)
• During shutdown of a MySQL Server instance with X Protocol connections to clients, a race condition
in X Plugin could cause invalid client connections to be accepted for processing. Because invalid
clients were ignored for client timeout verification during shutdown, these clients blocked shutdown
until the timeout set by the mysqlx_wait_timeout system variable was reached, which defaults
to 8 hours. To prevent this issue, client timeout verification now includes clients that are in an invalid
state. (Bug #30702685)
• When connecting to a MySQL 8.0 server, X Plugin set a different collation for the session to that
used by the mysql client, which could cause issues with queries that depended on the collation.
X Plugin now uses the utf8mb4_0900_ai_ci collation, which is the default for the utf8mb4
characterset. (Bug #30516849)
• The worker threads for X Protocol connections were identified as system threads on creation, and
assigned to the SYS_default resource group. This identification meant they could not be assigned
to user resource groups for resource management purposes. They are now identified as user
threads and assigned to the USR_default resource group. Note that X Protocol does not currently
support CREATE, ALTER, DROP, and SET RESOURCE GROUP statements, but these statements
can operate on X Protocol connection threads using classic MySQL protocol connections. (Bug
#30059288)
• X Plugin can now access the MySQL system variables as soon as initialization starts, so the plugin
install thread can set up the required connectivity itself rather than starting a separate thread. (Bug
#29127302)
One effect of this enhancement is that it is now possible for Out of memory errors to occur when
trying to sort rows containing very large (multi-megabtye) JSON or GEOMETRY column values if the
sort buffers are of insufficient size; this can be compensated for in the usual fashion by increasing
the value of the sort_buffer_size system variable. (Bug #30400985, Bug #30804356)
The First In First Out (FIFO) algorithm, which had also been used for transaction scheduling,
was removed. The FIFO algorithm was rendered redundant by CATS algorithm enhancements.
Transaction scheduling previously performed by the FIFO algorithm is now performed by the CATS
algorithm.
The following INNODB_METRICS counters were added for monitoring code-level transaction
scheduling events:
216
MySQL 8.0 Release Notes
• lock_rec_release_attempts
• lock_rec_grant_attempts
• lock_schedule_refreshes
The number of times the wait-for graph was analyzed to update transaction schedule weights.
(WL #13486)
• InnoDB: The storage area for the doublewrite buffer was moved from the system tablespace to
doublewrite files. Moving the doublewrite buffer storage area out of the system tablespace reduces
write latency, increases throughput, and provides flexibility with respect to placement of doublewrite
buffer pages. The following system variables were introduced for advanced doublewrite buffer
configuration:
• innodb_doublewrite_dir
• innodb_doublewrite_files
• innodb_doublewrite_pages
Defines the maximum number of doublewrite pages per thread for a batch write.
• innodb_doublewrite_batch_size
• EXPLAIN ANALYZE can now be stopped during execution using KILL QUERY or CTRL-C. (Bug
#30787515)
• EXPLAIN FORMAT=TREE now displays inversion information for windowing functions. (Bug
#30770631)
• EXPLAIN FORMAT=TREE output has been improved to provide more information about evaluated
window functions, and to match that supplied for regular aggregates. (Bug #30573446, Bug
#30582782)
• Configuring with the -DWITH_LTO=1 CMake option now works on macOS. (Bug #30125902)
• You can now enable binary log transaction compression on a MySQL server instance.
When binary log transaction compression is enabled, transaction payloads are compressed
using the zstd algorithm, and then written to the server's binary log file as a single event (a
Transaction_payload_event). Compressed transaction payloads remain in a compressed state
while they are sent in the replication stream to replicas, other Group Replication group members,
or clients such as mysqlbinlog. They are not decompressed by receiver threads, and are written
to the relay log still in their compressed state. Binary log transaction compression therefore saves
217
MySQL 8.0 Release Notes
storage space both on the originator of the transaction and on the recipient (and for their backups),
and saves network bandwidth when the transactions are sent between server instances.
You can enable binary log transaction compression on a MySQL server instance using the
binlog_transaction_compression system variable, which defaults to OFF. You can also use
the binlog_transaction_compression_level_zstd system variable to set the level for the
zstd algorithm that is used for compression. This value determines the compression effort, from 1
(the lowest effort) to 22 (the highest effort). (WL #3549)
(WL #13239)
• Since MySQL 8.0.19, compression has been supported for messages sent over X Protocol
connections. Connections can be compressed if the server and the client agree on a compression
algorithm to use. By default, the server permits the Deflate, LZ4, and zstd compression algorithms, or
you can set the mysqlx_compression_algorithms system variable to include only the ones you
permit. In MySQL 8.0.19, X Protocol uses the library default compression level for each algorithm,
and the client cannot negotiate this.
From MySQL 8.0.20, the client can request a specific compression level during capability
negotiations for an X Protocol connection. X Protocol sets a maximum compression level for
each algorithm, which prevents the server from agreeing to high compression levels that are
requested by clients if that would consume too much resource on the server. The maximum
compression levels are initially set to 5 for Deflate, 8 for LZ4, and 11 for zstd. You can adjust
these settings using the new mysqlx_deflate_max_client_compression_level,
mysqlx_lz4_max_client_compression_level, and
mysqlx_zstd_max_client_compression_level system variables.
New default compression levels for X Protocol have also been selected through performance
testing as being a good trade-off between compression time and network transit time. These
defaults are not necessarily the same as the library default for each algorithm. They are
applied if the client does not request a compression level for the algorithm. The default
compression levels are initially set to 3 for Deflate, 2 for LZ4, and 3 for zstd. You can
adjust these settings using the new mysqlx_deflate_default_compression_level,
mysqlx_lz4_default_compression_level, and
mysqlx_zstd_default_compression_level system variables. (WL #13034)
218
MySQL 8.0 Release Notes
Bugs Fixed
• Incompatible Change: Some queries that used ST_Contains() did not return any results unless >
0 was added.
Note
For upgrades from earlier versions of MySQL, you should recreate spatial
indexes in tables that have them.
• Performance: Certain queries against tables with spatial indexes were not performed as efficiently
following an upgrade from MySQL 5.7 to MySQL 8.0. (Bug #94655, Bug #29488350)
• NDB Cluster: NDB defines one SPJ worker per node owning a primary partition of the root table.
If this table used read from any fragment replica, DBTC put all SPJ workers in the same DBSPJ
instance, which effectively removed the use of some SPJ workers. (Bug #30639165)
• NDB Cluster: Executing the SHOW command using an ndb_mgm client binary from NDB 8.0.16 or
earlier to access a management node running NDB 8.0.17 or later produced the error message
Unknown field: is_single_user. (Bug #30599413)
• InnoDB: A CREATE UNDO TABLESPACE operation that specified an undo data file name without
specifying a path removed an existing undo data file of the same name from the directory specified
by innodb_undo_directory variable. The file name conflict check was performed on the data
directory instead of the directory specified by the innodb_undo_directory variable. (Bug
#30908328, Bug #98628)
• InnoDB: In debug builds, a regression introduced in MySQL 8.0.19 slowed down mutex and rw-lock
deadlock debug checks. (Bug #30886393)
• InnoDB: Valgrind testing raised an error indicating that a conditional jump or move depends on an
uninitialized value. The error was a false-positive due to invalid validation logic. (Bug #30837136)
• InnoDB: A data dictionary table open function was implemented with incorrect lock ordering. (Bug
#30782103, Bug #97825)
• InnoDB: Changes to parallel read threads functionality introduced in MySQL 8.0.17 caused a
degradation in SELECT COUNT(*) performance. Pages were read from disk unnecessarily. (Bug
#30766089)
• InnoDB: DDL logging was not performed for SQL operations executed by the bootstrap thread using
the init_file startup variable, causing files to be left behind that should have been removed
during a post-DDL stage. (Bug #30721214, Bug #98131)
• InnoDB: Adding an index on a column cast as a JSON array on a table with a specific number of
records failed with an “Incorrect key file for table” error. (Bug #30709525, Bug #98098)
• InnoDB: A Valgrind error reported that an uninitialized lock->writer_thread value was used in
a conditional jump. (Bug #30694177)
219
MySQL 8.0 Release Notes
• InnoDB: An internal buffer pool statistics counter (n_page_gets) was partitioned by page number
to avoid contention when accessed by multiple threads. (Bug #30604841, Bug #97822)
• InnoDB: A tablespace import operation failed with a schema mismatch error due to the .cfg
file and the data dictionary both containing default values for a column that was added using
ALGORITHM=INSTANT. An error should only occur if default values differ. (Bug #30561144)
• InnoDB: A slow shutdown failed to flush some GTIDs, requiring recovery of unflushed GTIDs from
the undo log. (Bug #30548229)
• InnoDB: A broken alignment requirement in the code that allocates a prefix in memory for
Performance Schema memory allocations caused a failure on MySQL builds optimized for macOS
and FreeBSD. (Bug #30530857)
• InnoDB: Adding a virtual column raised an assertion failure due to data that was missing from the
new data dictionary object created for the table. (Bug #30524263)
• InnoDB: A required latch was not taken when checking the mode of an undo tablespace. A required
latch was also not taken when checking whether an undo tablespace is empty. (Bug #30509134)
• InnoDB: Allocating an update undo log segment to an XA transaction for persisting a GTID value
before the transaction performed any data modifications caused a failure. (Bug #30456328)
• InnoDB: A query executed on a partitioned table with a discarded tablespace raised an assertion
failure. (Bug #30437407, Bug #97271)
• InnoDB: During a cloning operation, writes to the data dictionary buffer table at shutdown were too
late, causing a failure. Newly generated dirty pages were not being flushed. (Bug #30427369, Bug
#30405535, Bug #30405535)
• InnoDB: Read-write lock code (rw_lock_t) that controls ordering of access to the boolean
recursive flag and the writer thread ID using GCC builtins or os_mutex when the builtins are not
available, was revised to use C++ std::atomic in some instances. Thanks to Yibo Cai from ARM
for the contribution. (Bug #30401416, Bug #97150)
• InnoDB: A failure occurred while upgrading from MySQL 5.7 to MySQL 8.0. A server data dictionary
object was missing information about the FTS_DOC_ID column and FTS_DOC_ID_INDEX that
remain after dropping a FULLTEXT index. (Bug #30357954)
• InnoDB: Unnecessary messages about parallel scans were printed to the error log. (Bug
#30330448)
• InnoDB: During upgrade from MySQL 5.7 to MySQL 8.0, clustered indexes named
GEN_CLUST_INDEX are renamed to PRIMARY, which resulted in duplicate entries for the clustered
indexes being added to the mysql.innodb_index_stats table. (Bug #30330448)
• InnoDB: Various internal functions computed write event slots in an inconsistent manner. (Bug
#30228108, Bug #96519)
• InnoDB: Under specific circumstances, it was possible that tablespace encryption key information
would not be applied during the redo log apply phase of crash recovery. (Bug #30209760)
• InnoDB: A file operation failure caused the page tracking archiver to fail, which in turn caused the
main thread to hang, resulting in an assertion failure. Also, incorrectly, the page tracking archiver
remained enabled in innodb_read_only mode. (Bug #30202643)
220
MySQL 8.0 Release Notes
• InnoDB: An index corruption error was reported when attempting to import a tablespace containing
a table column that was added using ALGORITHM=INSTANT. The error was due to missing metadata
associated with the instantly added column. (Bug #30191523, Bug #96477)
• InnoDB: A transaction attempting to fetch an LOB record encountered a null LOB reference, causing
an assertion failure. However, the null LOB reference was valid in this particular scenario because
the LOB value was not yet fully written. (Bug #30144303)
• InnoDB: During a parallel read operation, the rollback of a table load operation while autocommit
was disabled resulted in a server to exit due to assertion code that did not account for the possibility
of tree structure changes during a parallel read. (Bug #30060690)
• InnoDB: The current size value maintained in a rollback segment memory object was found to
be invalid, causing an assertion failure in function trx_purge_free_segment(). A validation
routine (trx_rseg_t::validateCurrSize()) was added to verify the current size value. (Bug
#29947027)
• InnoDB: A prepared statement executed with invalid parameter values raised an assertion failure.
(Bug #29880907)
• InnoDB: An add column operation caused an assertion failure. The failure was due to a dangling
pointer. (Bug #29866408)
• InnoDB: Updating certain InnoDB system variables that take string values raised invalid read errors
during Valgrind testing. (Bug #29717909, Bug #95215)
• InnoDB: Redo log records for modifications to undo tablespaces increased in size in MySQL 8.0
due to a change in undo tablespace ID values, which required additional bytes. The change in redo
log record size caused a performance regression in workloads with heavy write I/O. To address this
issue, the redo log format was modified to reduce redo log record size for modifications to undo
tablespaces. (Bug #29536710)
• InnoDB: Additional information about InnoDB file writes, including progress data, is now printed to
the error log. (Bug #29472295, Bug #94634)
• InnoDB: An insert statement on a table with a spatial index raised a record type mismatch assertion
due to a tuple corruption. (Bug #29465567)
• InnoDB: A function that calculates undo log record size could calculate an incorrect length value in
the case of a corrupted undo log record, resulting in a malloc failure. Assertion code was added to
detect incorrect calculations. (Bug #29448406, Bug #82734)
• Replication: While an SQL statement was in the process of being rewritten for the binary log so that
sensitive information did not appear in plain text, if a SHOW PROCESSLIST statement was used to
inspect the query, the query could become corrupted when it was written to the binary log, causing
replication to stop. The process of rewriting the query is now kept private, and the query thread is
updated only when rewriting is complete. (Bug #30569003, Bug #97531, Bug #30654405)
• Replication: When a GRANT or REVOKE statement is only partially executed, an incident event is
logged in the binary log, which makes the replication slave's applier thread stop so that the slave
can be reconciled manually with the master. Previously, if a failed GRANT or REVOKE statement was
the first statement executed in the session, no GTID was applied to the incident event (because the
cache manager did not yet exist for the session), causing an error on the replication slave. Also, no
incident event was logged in the situation where a GRANT statement created a user but then failed
because the privileges had been specified incorrectly, again causing an error on the replication
slave. Both these issues have now been fixed. (Bug #30566518, Bug #30324661)
• Replication: Compression is now triggered for the mysql.gtid_executed table when the
thread/sql/compress_gtid_table thread is launched after the server start, and the effects are
visible when the compression process is complete. (Bug #30541799)
221
MySQL 8.0 Release Notes
• Replication: In the event of an unplanned disconnection of a replication slave from the master, the
reference to the master's dump thread might not be removed from the list of registered slaves, in
which case statements that accessed the list of slaves would fail. The issue has now been fixed.
(Bug #29915479)
• Replication: When a partitioned table was involved, the server did not correctly handle the situation
where a row event could not be written to the binary log due to a lack of cache space. An appropriate
error is now returned in this situation. (Bug #29848931)
• Replication: Under certain conditions, replication of conditional comments could fail. (Bug
#28388217)
• Group Replication: The thread used by the Group Replication message service was not correctly
registered by the Performance Schema instrumentation, so the thread actions were not visible in
Performance Schema tables. (Bug #30824676)
• Group Replication: Group Replication initiates and manages cloning operations for distributed
recovery, but group members that have been set up to support cloning may also participate in
cloning operations that a user initiates manually. In releases before MySQL 8.0.20, you could not
initiate a cloning operation manually if the operation involved a group member on which Group
Replication was running. From MySQL 8.0.20, you can do this, provided that the cloning operation
does not remove and replace the data on the recipient. The statement to initiate the cloning
operation must therefore include the DATA DIRECTORY clause if Group Replication is running. (Bug
#30798640)
• Group Replication: For Group Replication channels, issuing the CHANGE MASTER TO statement
with the PRIVILEGE_CHECKS_USER option while Group Replication was running caused the
channel's relay log files to be deleted. Transactions that had been received and queued in the relay
log, but not yet applied, could be lost in this situation. The CHANGE MASTER TO statement can now
only be issued when Group Replication is not running. (Bug #30655369)
• Group Replication: The Group Replication failure detection mechanism raises a suspicion if a
server stops sending messages, and the member is eventually expelled provided that a majority
of the group members are still communicating. However, the failure detection mechanism did
not take into account the situation where one or more of the group members in the majority had
actually already been marked for expulsion, but had not yet been removed from the group. Where
the network was unstable and members frequently lost and regained connection to each other in
different combinations, it was possible for a group to end up marking all its members for expulsion,
after which the group would cease to exist and have to be set up again.
The Group Replication Group Communication System (GCS) now tracks the group members that
have been marked for expulsion, and treats them as if they were in the group of suspect members
when deciding if there is a majority. This ensures at least one member remains in the group and the
group can continue to exist. When an expelled member has actually been removed from the group,
GCS removes its record of having marked the member for expulsion, so that the member can rejoin
the group if it is able to. (Bug #30640544)
• Group Replication: Performance Schema tables could not be accessed on a MySQL server with
Group Replication that was running under high load conditions. (Bug #30112711, Bug #30675790)
• Group Replication: Internal queries from Group Replication to the Performance Schema for
statistics on local group members failed if they occurred simultaneously with changes to the group's
membership. Locking for the internal queries has been improved to fix the issue. (Bug #30049349,
Bug #30791583, Bug #30963553)
222
MySQL 8.0 Release Notes
• Group Replication: During the Group Replication distributed recovery process, if a joining
member is unable to complete a remote cloning operation with any donor from the group, it uses
state transfer from a donor's binary log to retrieve all of the required data. However, if the last
attempted remote cloning operation was interrupted and left the joining member with incomplete
or no data, an attempt at state transfer immediately afterwards could also fail. Before attempting
state transfer following a failed remote cloning operation, Group Replication now checks that the
remote cloning operation did not reach the stage of removing local data from the joining member.
If data was removed, the joining member leaves the group and takes the action specified by the
group_replication_exit_state_action system variable. (Bug #29669099, Bug #29944828)
• Group Replication: Before taking certain actions, Group Replication checks what transactions are
running on the server. Previously, the service used for this check did not count transactions that were
in the commit phase, which could result in the action timing out. Now, transactions that are in the
commit phase are included in the set of currently ongoing transactions. (Bug #28327838)
• JSON: When JSON_TABLE() was used as part of an INSERT statement in strict mode, conversion
errors handled by any ON ERROR clause could cause the INSERT to be rejected. Since errors are
handled by an ON ERROR clause, the statement should not be rejected unless ERROR ON ERROR is
actually specified.
This issue is fixed by ignoring warnings when converting values to the target type if NULL ON ERROR
or DEFAULT ... ON ERROR has been specified or is implied. (Bug #30628330)
• JSON: The output from JSON_TABLE() was not always correct when used in views. This fix
corrects the following issues:
• Column names were not quoted, causing syntax errors when quoting was needed for these.
(Bug #30263373)
• Privilege requirements were checked incorrectly for stored objects with a DEFINER that has the
SYSTEM_USER privilege. (Bug #31077699)
• A number of errors reported by Clang in the documentation generated from the MySQL sources have
been corrected. (Bug #30956093)
• If a query contained multiple references to the same common table expression (CTE) and a pseudo-
comment crossed borders of the CTE definition, the parser failed with confusing syntax error
messages. (Bug #30871301)
• For installation using Debian packages, the /var/run/mysqld directory was not created. (Bug
#30855015, Bug #98484)
223
MySQL 8.0 Release Notes
• mysqlslap did not shut down its threads properly when SQL statements returned an error. This
could result in attempts to free already freed memory. (Bug #30850310)
• When X Plugin was attempting to add a document to a collection as either an insertion or an update
in the case of a duplicate key, in the case where the document failed a unique key constraint in a
field other than the primary key, the error returned by X Plugin did not state that this was the cause of
the issue. The appropriate error is now returned. (Bug #30843865)
• An integer value generated by transformations in the resolver was supplied to a test which expected
a boolean. (Bug #30837240)
• A query using an IN expression that accessed one or more columns holding large string values
could lead to a memory leak. (Bug #30814171)
• Statements did not work properly when the target of a DELETE was a common table expression.
(Bug #30796015, Bug #98330)
• When a table had both a primary key and a secondary key on the same column, but for different
lengths, the range optimizer chose the wrong key part in the secondary index for comparing range
values. (Bug #30783011)
• In some cases, errors caused when DISTINCT was used with an aggregate function whose
argument was of an incorrect type were not propagated correctly. (Bug #30782687)
• For replication using compression, the slave could raise an assertion if the master was restarted.
(Bug #30774692)
• For debug builds, the server could exit trying to print an optimizer trace. (Bug #30773218, Bug
#98258)
• With LOCK TABLES active, while processing INFORMATION_SCHEMA queries, the server could
attempt to lock internal temporary tables (which need no locks), causing an assertion to be raised.
(Bug #30764651, Bug #98221)
• The mysqldump internal network timeout was increased from 700 to 86400 seconds to
accommodate connecting to busy or unresponsive servers. (Bug #30755992, Bug #98203)
• After deleting the temporary table associated with a window function's frame buffer, the temporary
table parameter for the frame buffer was not cleaned up, causing string buffers associated with copy
fields not to be freed properly. (Bug #30752366)
• The -libs-compat RPM package is now built with system zlib to avoid problems with
unrestricted export of symbols in libmysqlclient.so.18. (Bug #30722389, Bug #98130)
• The server exited histogram sampling prematurely, causing an assertion failure. An unnecessary
boolean variable that marked the completion of a sampling operation was removed. (Bug
#30717778)
• When removing a WHERE condition because one of the participating conditions was always false, a
materialized derived table was not cleaned up properly, resulting in a memory leak. (Bug #30712243)
• Multiple comparisons with the same GEOMETRY value were not always handled correctly. (Bug
#30697042)
224
MySQL 8.0 Release Notes
• MIN() and MAX() could return an incorrect value for some queries if a WHERE clause containing an
IN () subquery was added. (Bug #30691682, Bug #98047)
• Server startup failed if MySQL Enterprise Firewall was enabled at startup but the whitelist and user
tables were missing. (Bug #30690181)
• For prepared statements, re-execution could cause a server exit if a cleaned-up materialized
temporary table was still being referred to. (Bug #30674598)
• Some joins within subqueries where an outer query used EXISTS or NOT EXISTS were not always
handled correctly. (Bug #30671329)
• Queries using ORDER BY constant are permitted but an ORDER BY clause of this sort should not
have any effect on the result; such queries were not always handled correctly. (Bug #30669493)
• The strconvert() function was not safe for conversions between filename and
utf8_general_ci strings. (Bug #30668847)
• Some filesorts using keys of fixed length were not always handled correctly. (Bug #30665034)
• When performing a hash join on two string columns that were potentially very large (in particular,
BLOB columns with PAD SPACE collations), MySQL stored the entire sort key in the row, which
impacted performance by requiring large amounts of memory. Now only a collation-aware hash is
stored, with an added equality comparison prevent a wrong answer, even in the event of a 64-bit
hash collision. (Bug #30664831)
• When at least two tables were joined to at least two other tables using a semijoin, and the join
optimizer chose to use a loose scan, it was possible to place both of the left tables below the
deduplicating nested loop iterator, leading to excessive deduplication. We fix this by treating a loose
scan across multiple tables as a separate internal structure. (Bug #30659810)
• In unions of a const table and zero or more known-zero expressions, derived tables of exactly one
row could be read incorrectly as having zero rows. (Bug #30655712, Bug #97967)
• A MySQL 8.0.19 patch set an invalid INFORMATION_SCHEMA and data dictionary version number.
Assertion code was added to prevent future version information errors. (Bug #30645158, Bug
#97948)
• When setting up the iterator tree, the optimizer now filters away and subsequently ignores conditions
which are known to be trivially true. (Bug #30644591)
• Under some conditions, SHOW COLUMNS on a temporary MERGE table could raise an assertion or
cause a server exit. (Bug #30640463)
225
MySQL 8.0 Release Notes
• Using the asynchronous C API functions could result in freeing already freed memory. (Bug
#30596999, Bug #97805)
• On tables containing a CHECK constraint, certain simple queries were inefficient due to excessive
memory allocation and Performance Schema calls. (Bug #30594613)
• A race condition could occur between InnoDB issuing requests for schema and table metadata while
filling INFORMATION_SCHEMA.INNODB_TABLES, and the schema being dropped, leading to user
queries on INNODB_TABLES reporting an error. (Bug #30591967)
• The client library could be induced into an infinite loop by a malicious server. (Bug #30581726)
• Using ALTER USER to reset an account MAX_USER_CONNECTIONS value did not take effect until all
current account connections terminated, if there were any. (Bug #30578217, Bug #97735)
• When the optimizer sets up a weedout, it notifies all tables that are part of the weedout that they
should provide row IDs. For confluent weedouts (weedouts returning at most one row), the optimizer
expects that the executor handles the weedout without row IDs. In the iterator executor, confluent
weedouts are implemented using LIMIT 1; the normal weedout iterator does not handle confluent
weedouts, and thus always expects row IDs. In the case of a confluent weedout on the right side
of an outer join, the confluent weedout was processed as a normal weedout, causing the iterator
executor to ask for row IDs where the tables did not supply them. Now in such cases, the LIMIT 1
optimization is also applied. (Bug #30566549, Bug #30282693)
• SET PERSIST could fail due to attempting to persist variables to the wrong directory. (Bug
#30561982)
• Within a stored program with an error handler defined for the error condition of accessing a
nonexistent table, the handler was not invoked if the table was nonexistent because it was named in
a nonexistent database. (Bug #30561920, Bug #97682)
• The duplicate weedout optimization strategy employed by MySQL (see Optimizing IN and EXISTS
Subquery Predicates with Semijoin Transformations) uses an internal table of row IDs which it
has already seen, with a unique index on the column containing these IDs. When the key for the
unique index became too large, which could happen with very large row IDs, the server reverted to
deduplication by hash key instead, with a separate index (not unique) over the hash field only, as
with other temporary tables. Because the latter index was not properly initialized, affected queries
were not executed properly and could lead to a premature exit. (Bug #30556257)
• For debug builds, under LOCK TABLES, the server could mishandle materialized temporary tables
and raise an assertion. (Bug #30476213, Bug #97404)
• Altering column collations did not affect unique indexes until a server restart. (Bug #30386119, Bug
#97103)
• When using roles, the EXECUTE privilege for stored functions was treated as a privilege for stored
procedures. As a result, it was not possible to use EXECUTE as a role privilege for functions. (Bug
#30376231)
• A materialized subquery including a condition in which a column value was used as input to a
nondeterministic function produced incorrect results. (Bug #30368937)
• Several fixes were applied to the InnoDB memcached plugin. The fixes addressed potential
deadlock issues, issues related to connection list latches, and removal of an obsolete flush mutex.
(Bug #30354225)
226
MySQL 8.0 Release Notes
• Strings that used the utf8mb4_0900_bin collation could not be compared with utf8mb4 strings
that used a different collation. Now the comparison is done by using utf8mb4_0900_bin for both
strings. (Bug #30350111)
• During optimization, MySQL removes conditions in which all arguments are considered equal;
for example, 1 <> 1 is removed and replaced with false. In doing so, conditions containing
non-deterministic arguments were also removed, which caused a condition such as RAND() <
RAND() to be considered an impossible condition. Now, the optimizer no longer removes conditions
containing nondeterministic arguments. (Bug #30311271)
• Scheduling of events could be disturbed by removing events. (Bug #30301356, Bug #96849)
• The Event Scheduler reported warnings for Valgrind builds. (Bug #30301340)
• Shutting down the server while using the clone plugin raised a Valgrind error. (Bug #30248419)
• If the mysqld-auto.cnf file was malformed, the server did not start (expected), but did not report
any error (unexpected). (Bug #30169731, Bug #96501)
• UPDATE statements could give an inconsistent number of rows matched (found rows) in cases
where not all matched rows were updated, depending on the reason for rows not being updated.
For example, rows not updated due to being updated through a view with a WITH CHECK OPTION
clause were not counted as matching rows, whereas rows not updated due to a failing CHECK
CONSTRAINT were counted. For consistency, rows that fail a WITH CHECK OPTION clause now are
counted as matching rows. (Bug #30158954)
• When restarting the MySQL server on a cloned directory, InnoDB reported an error indicating that it
could not find a tablespace file for a statistics table that was dropped by the server previously. (Bug
#30093799)
• The server did not handle correctly a UNION in which one of the queries contained a subquery that
used ORDER BY. (Bug #29952565)
• For INFORMATION_SCHEMA queries, a race condition could result in multiple attempts to insert a key
when updating the dynamic statistics tables, producing a duplicate-key error. (Bug #29948755, Bug
#95929)
• SHOW CREATE VIEW could fail with an illegal mix of collations for views defined on a function that
returns a string. (Bug #29904087)
• The Performance Schema could fail to remove thread instrumentation when a thread was deleted.
(Bug #29859605)
• A query with a WHERE clause whose predicate contained a numeric value in scientific notation was
not handled correctly.
In addition, attempting to insert a particular integer specified as a string caused a server exit when
the string-to-integer conversion was not successful. (Bug #29723340, Bug #30441969)
• An internal interface was added for retrieving and parsing errors that occur on the donor MySQL
server instance (ER_CLONE_DONOR errors) and for checking if data on the recipient has been
dropped. (Bug #29682642)
• It was not possible to drop any columns from a table when the DEFAULT value. (Bug #29661106)
• For the CONNECTION_CONTROL plugin, the Performance Schema instrumentation used keys that
were not discoverable to the Performance Schema unless the associated code actually executed.
(Bug #29539976)
• For a nullable column c, the optimizer now recognizes when the conditions c < c, c > c, and
c <> c are always false and need not be evaluated for every row. Thanks to Daniel Black for the
contribution. (For nonnullable columns, the optimizer already recognized always-false conditions.)
(Bug #29115386, Bug #93642)
227
MySQL 8.0 Release Notes
• Reinitialization of character sets from Index.xml could cause a use-after-free error. (Bug
#28956360, Bug #93276)
• The sys schema ps_setup_reset_to_default() procedure used MySQL 5.7 defaults, not
MySQL 8.0 defaults. (Bug #27636611)
•
Previously, mysqlpump read the [mysql_dump] and [client] groups from option files.
mysqlpump now additionally reads the [mysqlpump] group. The [mysql_dump] group is still
accepted but is deprecated. (Bug #24733245, Bug #83144)
• For a query of the form SELECT DISTINCT ... ORDER BY ..., when the ORDER BY was
pushed down onto the first table in the join, the result was not always sorted in the correct order.
(Bug #98217, Bug #30760534)
• The NULL indicator was not properly written for items used as variable-length keys, such that all
such items were assumed to be not NULL, which was considered equal to the empty string when
using certain collations. One visible effect of this issue was that ordering by an expression using a
nullable string was sometimes not performed correctly. An example of such a query, where column
c1 contains both NULL and empty string values, is shown here:
SELECT c1, SUBSTR(c1, 1) AS c2 FROM t ORDER BY c2;
• A query returned inaccurate results when an expression in a GROUP BY clause used a column name
differing in case from that used for the name of the column when the table containing this column
was created. An example of this would be when the query used GROUP BY id although the column
name as shown in the original CREATE TABLE statement was ID.
This occurred because, the server performed case-sensitive comparisons of column names in
expressions with names of columns in tables. This issue is fixed by ensuring that such comparisons
are performed in a case-insensitive fashion as expected. (Bug #97628, Bug #98222, Bug
#30541701, Bug #30761372)
• A multi-table UPDATE statement which updated a table joined to a derived table that joined two
other tables was not optimized properly as it had been in MySQL 5.6, instead being treated as if
STRAIGHT_JOIN had been used with the subquery creating the derived table. (Bug #97418, Bug
#30488700)
• EXPLAIN now uses hash join instead of block nested loop, since the latter no longer exists
and is replaced by a hash join in nearly all cases. (Bug #97299, Bug #30444550)
• The execution plan for a query that filtered on the first column of a composite hash index wrongly
used this index, producing erroneous results. (Bug #94737, Bug #29527115)
• References to columns from tables of outer query blocks in an ON condition of a JOIN did not work,
and could be used only in a WHERE. The fix for this problem means that a query such as this one now
works correctly:
SELECT o.order_date FROM orders o
WHERE o.order_date IN ( SELECT c.contact_name FROM customers c
INNER JOIN order_details od
ON o.order_id = od.discount );
228
MySQL 8.0 Release Notes
References to other tables of the same FROM clause as the JOIN, as in the query SELECT * FROM
t1 CROSS JOIN (t2 LEFT JOIN t3 ON t1.c=3), are not outer references and remain
forbidden. In this case, a lateral join is required, like this: SELECT * FROM t1 JOIN LATERAL
(SELECT * FROM t2 LEFT JOIN t3 ON t1.c=3). (Bug #35242, Bug #96946, Bug #11748138,
Bug #30350696)
• There could be a mismatch between the version of OpenSSL used to build the server and the
version used for other parts of MySQL such as libraries or plugins. This could cause certain features
not to work, such as the LDAP authentication plugins. Now the same version of OpenSSL is used for
building everything. (WL #13759)
• Previous work in MySQL 8.0 to optimize impossible expressions such as a=b AND FALSE as
FALSE could make for less efficient execution when such expressions appeared as outer join
conditions, due to the fact that the join was interpreted as a Cartesian product followed by a filter.
(Bug #8202, Bug #89739, Bug #97552, Bug #11745046, Bug #27581277, Bug #30520749)
Important
There is an issue for MySQL 8.0.19 installed using MySQL Installer that
prevents the server from starting if MySQL Enterprise Firewall is selected
during the server configuration steps. If the server startup operation fails, click
Cancel to end the configuration process and return to the dashboard. You must
uninstall the server.
• Compilation Notes
• Configuration Notes
• Error Handling
• INFORMATION_SCHEMA Notes
• Keyring Notes
• Logging Notes
• Packaging Notes
229
MySQL 8.0 Release Notes
• X Plugin Notes
• Bugs Fixed
• Audit log connect events now include any connection attributes passed by the client. Connection
attribute logging is supported for new-style XML log file format and JSON format, but not old-style
XML format. See Audit Log File Formats. (WL #11378)
Compilation Notes
• Microsoft Windows: On Windows, the minimum version of CMake for builds from the command line
is now 3.15. (Bug #30332632, Bug #96954)
Configuration Notes
• New FPROFILE_GENERATE and FPROFILE_USE CMake options are available for experimenting with
profile guided optimization (PGO) with GCC. See the cmake/fprofile.cmake in a MySQL source
distribution for information about using them. These options have been tested with GCC 8 and 9, and
with Clang.
Enabling FPROFILE_USE also enables WITH_LTO (link time optimization). (Bug #30089834, Bug
#96314, Bug #30133324, Bug #96410, Bug #30164113, Bug #96486)
• Innodb_system_rows_read, Innodb_system_rows_inserted,
Innodb_system_rows_deleted status variables were added for counting row operations on
InnoDB tables that belong to system-created schemas. The new status variables are similar to
the existing Innodb_rows_read, Innodb_rows_inserted, Innodb_rows_deleted status
variables, which count operations on InnoDB tables that belong to both user-created and system-
created schemas.
230
MySQL 8.0 Release Notes
• Display width specification for integer data types was deprecated in MySQL 8.0.17, and now
statements that include data type definitions in their output no longer show the display width for
integer types, with these exceptions:
• The type is TINYINT(1). MySQL Connectors make the assumption that TINYINT(1)
columns originated as BOOLEAN columns; this exception enables them to continue to make that
assumption.
This change applies to tables, views, and stored routines, and affects the output from SHOW CREATE
and DESCRIBE statements, and from INFORMATION_SCHEMA tables.
For DESCRIBE statements and INFORMATION_SCHEMA queries, output is unaffected for objects
created in previous MySQL 8.0 versions because information already stored in the data dictionary
remains unchanged. This exception does not apply for upgrades from MySQL 5.7 to 8.0, for which all
data dictionary information is re-created such that data type definitions do not include display width.
(Bug #30556657, Bug #97680, WL #13528)
• Setting the hash_join optimizer switch (see optimizer_switch system variable) no longer has
any effect. The same applies with respect to the HASH_JOIN and NO_HASH_JOIN optimizer hints.
Both the optimizer switch and the optimizer hint are now deprecated, and subject to removal in a
future release of MySQL.
This also fixes an issue whereby SELECT DISTINCT ... WITH ROLLUP did not always return all
distinct rows. (Bug #27549694, Bug #30471809)
• In MySQL 5.7.14, the mysqlx namespace parameter was introduced for X Protocol's StmtExecute
request, replacing the xplugin parameter, which was therefore deprecated. X Plugin continued
to support the deprecated xplugin namespace for backward compatibility. In MySQL 8.0.19,
the xplugin namespace has now been removed. If the xplugin namespace is used from
this release on, an error message is returned as for an unknown namespace. X Plugin's
Mysqlx_stmt_execute_xplugin status variable, which counted the number of StmtExecute
requests received for the xplugin namespace, is no longer used from MySQL 8.0.19. (WL #13057)
• Support for the YEAR(2) data type was removed in MySQL 5.7.5, leaving only YEAR and YEAR(4)
as valid specifications for year-valued data. Because YEAR and YEAR(4) are semantically identical,
specifying a display width is unnecessary, so YEAR(4) is now deprecated and support for it will
be removed in a future MySQL version. Statements that include data type definitions in their
output no longer show the display width for YEAR. This change applies to tables, views, and
stored routines, and affects the output from SHOW CREATE and DESCRIBE statements, and from
INFORMATION_SCHEMA tables.
For DESCRIBE statements and INFORMATION_SCHEMA queries, output is unaffected for objects
created in previous MySQL 8.0 versions because information already stored in the data dictionary
remains unchanged. This exception does not apply for upgrades from MySQL 5.7 to 8.0, for which all
data dictionary information is re-created such that data type definitions do not include display width.
The (undocumented) UNSIGNED attribute for YEAR is also now deprecated and support for it will be
removed in a future MySQL version. (WL #13537)
Error Handling
• Error messages regarding crash recovery for XA were revised to indicate XA context to distinguish
them from non-XA crash recovery messages. (Bug #30578290, Bug #97743)
• Previously, the server returned this error message for attempts to use LOAD DATA LOCAL with
LOCAL capability disabled: The used command is not allowed with this MySQL
version. This was misleading because the error condition is not related to the MySQL version.
The server now returns an error code of ER_CLIENT_LOCAL_FILES_DISABLED and this message:
231
MySQL 8.0 Release Notes
Loading local data is disabled; this must be enabled on both the client
and server side. (Bug #30375698, Bug #29377985, Bug #94396)
Loadable function behavior is still the same by default, but the interface for writing loadable functions
has been extended to enable them to determine the character set and collation of string arguments,
and to return strings that have a particular character set and collation. These capabilities are optional
for loadable function writers, who may take advantage of them as desired. See Loadable Function
Character Set Handling
Of the loadable functions distributed with MySQL, those associated with the following features and
extensions have been modified to take advantage of the new capabilities: MySQL Enterprise Audit,
MySQL Enterprise Firewall, MySQL Enterprise Data Masking and De-Identification, MySQL Keyring
(the general-purpose keyring functions only), and Group Replication. The modification applies only
where it make sense. For example, a function that returns encrypted data is intended to return a
binary string, not a character string.
Character-set capabilities for loadable functions are implemented using the mysql_udf_metadata
component service. For information about this service, see the MySQL Server Doxygen
documentation, available at https://dev.mysql.com/doc/index-other.html (search for
s_mysql_mysql_udf_metadata and udf_metadata_imp). Source code for the MySQL Keyring
functions is available in Community source distributions and may be examined as examples for third-
party loadable function writers who wish to modify their own functions to be character set-aware. (WL
#12370)
INFORMATION_SCHEMA Notes
• The INFORMATION_SCHEMA contains several new tables that expose role information:
• APPLICABLE_ROLES: Roles applicable for the current user; see The INFORMATION_SCHEMA
APPLICABLE_ROLES Table.
• ENABLED_ROLES: Roles enabled within the current session; see The INFORMATION_SCHEMA
ENABLED_ROLES Table.
• ROLE_COLUMN_GRANTS: Column privileges for roles for the current user; see The
INFORMATION_SCHEMA ROLE_COLUMN_GRANTS Table.
• ROLE_ROUTINE_GRANTS: Routine privileges for roles for the current user; see The
INFORMATION_SCHEMA ROLE_ROUTINE_GRANTS Table.
• ROLE_TABLE_GRANTS: Table privileges for roles for the current user; see The
INFORMATION_SCHEMA ROLE_TABLE_GRANTS Table.
(WL #10895)
Keyring Notes
• A new SECRET key type is available that is intended for general-purpose storage of sensitive data
using the MySQL keyring. The keyring encrypts and decrypts SECRET data as a byte stream upon
storage and retrieval. The SECRET key type is supported by all keyring plugins. See Supported
Keyring Key Types and Lengths. (WL #12859)
232
MySQL 8.0 Release Notes
Logging Notes
• The SIGUSR1 signal now causes the server to flush the error log, general query log, and slow query
log. One use for SIGUSR1 is to implement log rotation without having to connect to the server (which
to flush logs requires an account that has the RELOAD privilege). The server response to SIGUSR1
is a subset of the response to SIGHUP, enabling SIGUSR1 to be used as a more “lightweight” signal
that flushes certain logs without the other SIGHUP effects such as flushing the thread and host
caches and writing a status report to the error log. See Unix Signal Handling in MySQL. (WL #13689)
Packaging Notes
• Binary packages that include curl rather than linking to the system curl library have been
upgraded to use curl 7.66.0. (Bug #30356844)
• The zstd library bundled with MySQL has been upgraded from version 1.3.3 to 1.4.3. MySQL uses
the zstd library to support connection compression. (Bug #30236685)
• For package types for which OpenSSL shared libraries are included, they are now also included
under lib/private if the package has private-to-MySQL libraries located there that need
OpenSSL. (Bug #29966296)
You can use ORDER BY with TABLE, which also supports LIMIT with optional OFFSET; these
clauses function in the same way in a TABLE statement as they do with SELECT. The following two
statements produce the same result:
TABLE t ORDER BY c LIMIT 10 OFFSET 3;
• VALUES consists of the VALUES keyword followed by a series of row constructors (ROW()),
separated by commas. It can be used to supply row values in an SQL-compliant fashion to
an INSERT statement or REPLACE statement. For example, the following two statements are
equivalent:
INSERT INTO t1 VALUES ROW(1,2,3), ROW(4,5,6), ROW(7,8,9);
You can also select from a VALUES table value constructor just as you would a table, bearing in
mind that you must supply a table alias when doing so. Using column aliases, you can also select
individual columns, like this:
mysql> SELECT a,c FROM (VALUES ROW(1,2,3), ROW(4,5,6)) AS t(a,b,c);
+---+---+
| a | c |
+---+---+
| 1 | 3 |
| 4 | 6 |
+---+---+
You can employ such SELECT statements in joins, unions, subqueries, and other constructs in
which you normally expect to be able to use such statements.
233
MySQL 8.0 Release Notes
For more information and examples, see TABLE Statement, and VALUES Statement, as well as
INSERT ... SELECT Statement, CREATE TABLE ... SELECT Statement, JOIN Clause, UNION
Clause, and Subqueries. (Bug #77639, WL #10358)
• Previously, it was not possible to use LIMIT in the recursive SELECT part of a recursive common
table expression (CTE). LIMIT is now supported in such cases, along with an optional OFFSET
clause. An example of such a recursive CTE is shown here:
+-------+
| a |
+-------+
| xxx |
| xxxx |
| xxxxx |
+-------+
Specifying LIMIT in this fashion can make execution of the CTE more efficient than doing so in the
outermost SELECT, since only the requested number of rows is generated.
For more information, see Recursive Common Table Expressions. (Bug #92857, Bug #28816906,
WL #12534)
• When CHECK constraints were implemented in MySQL 8.0.16, ALTER TABLE supported DROP
CHECK and ALTER CHECK syntax as MySQL extensions to standard SQL for modifying check
constraints, but did not support the more general (and SQL standard) DROP CONSTRAINT and
ALTER CONSTRAINT syntax for modifying existing constraints of any type. That syntax is now
supported; the constraint type is determined from the constraint name. (WL #12787)
• MySQL now supports aliases in the VALUES and SET clauses of INSERT INTO ... ON
DUPLICATE KEY UPDATE statement for the row to be inserted and its columns. Consider a
statement such as this one:
INSERT INTO t
VALUES (9,5), (7,7), (11,-1)
ON DUPLICATE KEY UPDATE a = a + VALUES(a) - VALUES(b);
Using the alias new for the inserted row, you can now rewrite the statement, referring back to the row
alias in the ON DUPLICATE KEY UPDATE clause, like this:
INSERT INTO t
VALUES (9,5), (7,7), (11,-1) AS new
ON DUPLICATE KEY UPDATE a = a + new.a - new.b;
Using the same row alias, and, additionally, the column aliases m and n for the columns of the
inserted row, you can omit the row alias and use only the column aliases, as shown here:
INSERT INTO t
VALUES (9,5), (7,7), (11,-1) AS new(m,n)
234
MySQL 8.0 Release Notes
The row alias must be distinct from the table name; column aliases must be distinct from one
another.
See INSERT ... ON DUPLICATE KEY UPDATE Statement, for more information and examples. (WL
#6312)
X Plugin Notes
• X Plugin could not be compiled on Debian with GCC 9. The --no-as-needed linker option was
added to provide a workaround for the issue. (Bug #30445201)
• Using X Protocol to query the Information Schema table TRIGGERS could result in errors being
returned or some rows not being returned. (Bug #30318917)
235
MySQL 8.0 Release Notes