MySQL 9.7 Release Notes  /  Changes in MySQL 9.7.2 (2026-07-28)

Changes in MySQL 9.7.2 (2026-07-28)

Audit Log Notes

  • The server could close unexpectedly if audit_log_encryption_password_get(keyring ID) was called. (Bug #33296125)

Compilation Notes

  • The version of libfido2 used with MySQL was upgraded to 1.17.0. (Bug #39478664)

  • Fixed a potential memory leak in the comp_err utility. (Bug #36532183)

Deprecation and Removal Notes

InnoDB Notes

  • InnoDB: Fixed a debug assertion in row_upd_rec_in_place() for non-versioned ROW_FORMAT=REDUNDANT rows. (Bug #39165747)

  • InnoDB: During a buffer-pool resize, Adaptive Hash Index could be disabled in mysqld-auto.cnf even though innodb_adaptive_hash_index=ON. (Bug #39157211)

  • InnoDB: Fixed an issue relating to table maintenance and clean-up. (Bug #39091376)

  • InnoDB: Fixed an issue relating to unique indexes. (Bug #38501299)

  • InnoDB: Under certain circumstances, when adding an AUTO_INCREMENT column to an existing table, some records in that table could be skipped, resulting in inaccurate values in the AUTO_INCREMENT column.

    Our thanks to Huaxiong Song and the team at Alibaba for the contribution. (Bug #115136, Bug #37105825)

JSON Notes

  • Updating a JSON relational duality view that deleted rows from a nested child base table could violate foreign-key constraints. JSON Duality View update processing now performs deletes first, in reverse binding order, before inserts and updates are executed. (Bug #39566804)

  • Fixed an issue relating to JSON Schema validation. (Bug #39489024)

  • Fixed an issue relating to processing JSON date values. (Bug #39361343)

  • Fixed an issue relating to processing of nested arrays. (Bug #39255759)

  • Fixed an issue relating to metadata validation. (Bug #39255734)

  • JSON_VALUE() with RETURNING DATETIME and a DEFAULT value could return an invalid constant date when the expression was used in a DATE context, silently affecting predicates and joins. The datetime value is now extracted before narrowing to a date. (Bug #120788, Bug #39649893)

MySQL Programs Notes

  • mysql_tzinfo_to_sql generated unnecessary warnings. For example:

    Warning: Unable to load '/usr/share/zoneinfo//iso3166.tab' as time zone. Skipping it.
    Warning: Unable to load '/usr/share/zoneinfo//leap-seconds.list' as time zone. Skipping it.
    Warning: Unable to load '/usr/share/zoneinfo//leapseconds' as time zone. Skipping it.
    Warning: Unable to load '/usr/share/zoneinfo//tzdata.zi' as time zone. Skipping it.
    Warning: Unable to load '/usr/share/zoneinfo//zone.tab' as time zone. Skipping it.
    Warning: Unable to load '/usr/share/zoneinfo//zone1970.tab' as time zone. Skipping it.

    As of this release, those warnings are suppressed.

    Our thanks to Daniël van Eeden for the contribution. (Bug #115021, Bug #36624161)

Optimizer Notes

  • Fixed an issue relating to subquery_to_derived. (Bug #39525738)

  • A query using the hypergraph optimizer with GROUP BY ... WITH ROLLUP on a constant expression and an empty USE INDEX FOR GROUP BY() hint could cause an assertion failure during optimization.

    As of this release, the optimizer recognizes that constant grouping requires no index ordering, allowing a valid streaming aggregate plan to be selected. (Bug #39505077)

  • Fixed an issue relating to ROLLUP queries. (Bug #39501528)

  • Fixed an issue related to error handling in aggregation of decimal data. (Bug #39474810)

  • Some temporal and geospatial expressions could trigger assertion failures. (Bug #39279682, Bug #39280411)

  • Fixed an issue relating to error-handling. (Bug #39272322)

  • Fixed an issue relating to user-variable handling. (Bug #39243027)

  • Under certain circumstances, predicate-heavy queries using the hypergraph optimizer could trigger an assertion failure. (Bug #39181175)

  • Fixed an issue relating to Common Table Expressions with subquery_to_derived enabled. (Bug #39179197)

  • Fixed an issue in ExtractValue(). (Bug #39138426)

  • Complex queries using the hypergraph optimizer could spend unnecessary planning time repeatedly checking for a secondary-engine row-count hook, even when no secondary engine was installed.

    The optimizer now caches this hook lookup once per query, reducing planning overhead. (Bug #39015463)

  • Opening a table after updating its histogram could trigger an assertion failure because metadata locks for histograms were released incorrectly.

    Histogram metadata locks are now released only for the table currently being opened. (Bug #38940484)

  • Fixed an issue relating to dynamic scan execution.

    Our thanks to Mengchu Shi and the team from Alibaba for the contribution. (Bug #38657550)

  • Queries which used BETWEEN with constant bounds could show an unnecessary filter operation above an otherwise exact index range scan when using the hypergraph optimizer.

    As of this release, the optimizer recognizes these range conditions as exact and removes the redundant filter step. (Bug #37152269)

  • Queries involving materialized derived tables could choose an index-lookup plan even when the cost of building the temporary index outweighed its benefit.

    As of this release, the hypergraph optimizer includes temporary-index build cost when evaluating these plans, improving plan selection for derived-table queries. (Bug #36957877)

  • SELECT DISTINCT ... LIMIT queries, which used materialization-based duplicate removal, could process all distinct rows before applying the limit, causing performance degradation when only a small number of unique rows was requested.

    The hypergraph optimizer now passes the query limit to duplicate removal, allowing it to stop once it has found the required number of unique rows. Sort-based DISTINCT plans forced by SQL_BIG_RESULT are unchanged. (Bug #36720017)

  • Hash joins could perform unnecessary disk spill I/O for queries with a low LIMIT, even when only a small number of result rows was needed.

    As of this release, the hypergraph optimizer considers both spill-to-disk and in-memory hash join plans, allowing cost-based optimization to favor the faster in-memory option when appropriate. (Bug #36684053)

  • ORDER BY expressions using stored functions with side effects or non-deterministic functions such as RAND() could be evaluated more than once per row by the hypergraph optimizer, resulting in unexpected repeated side effects.

    As of this release, rows are materialized before sorting in affected queries so these expressions are evaluated only once per row. Top-level UPDATE and DELETE statements, and queries optimized for secondary engines, are unaffected. (Bug #36578540)

  • Under certain circumstances, filters using IFNULL returned incorrect results. (Bug #36448705)

  • A negated IS TRUE condition involving a BETWEEN predicate could return incorrect results for DECIMAL values because NULL-state handling was not initialized correctly. (Bug #120540, Bug #39444505)

  • AVG() of functions such as ASCII() could return a truncated value when used with SQL_BUFFER_RESULT, because the calculated decimal precision did not reserve space for a sign.

    As of this release, decimal precision calculations correctly account for signed values, preventing truncation of valid results such as 255.0000. (Bug #120465, Bug #39392429)

  • Due to a fix in a previous version, IFNULL() did not handle NULL correctly. (Bug #120429, Bug #39347654)

    References: This issue is a regression of: Bug #37285902.

  • A fix in a previous version caused an issue where a WHERE equality condition could fail to match an existing row when a scalar subquery and its outer query referenced the same CTE.

    This fix prevents cleanup of derived-table temporary keys from a query block that does not own them, preserving correct key metadata during outer-query optimization and ensuring correct result matching. (Bug #120403, Bug #39321676)

    References: This issue is a regression of: Bug #35912840.

  • UNION and UNION ALL queries with pushed-down WHERE conditions involving AND and IS NULL could return incorrect rows.

    Condition pushdown now preserves WHERE predicate semantics in set-operation branches. (Bug #119780, Bug #38888307)

  • Queries involving nested merged views and outer joins could return incorrect results when a view column containing a constant expression was evaluated before outer-join null completion.

    The optimizer retains the correct inner-table dependency for merged view columns, ensuring outer-join expressions and related WHERE conditions are evaluated at the proper stage. (Bug #119499, Bug #38729126)

    References: This issue is a regression of: Bug #35854686.

  • Queries that filtered an indexed column with IS NULL could perform an unnecessary filesort when the same column appeared in ORDER BY.

    As of this release, the optimizer recognizes IS NULL as a constant condition for order-by simplification, allowing index order to be used when applicable.

    Our thanks to Kishore Kumar for the contribution. (Bug #119442, Bug #38700622)

  • Queries with ORDER BY, a low LIMIT, and a reverse range scan on a composite index could return incorrect results if the optimizer removed the sort operation prematurely.

    As of this release, the optimizer accounts for all key parts required for ordering before selecting a reverse index range scan.

    Our thanks to Somrak Monpengpinij for the contribution. (Bug #119198, Bug #38564020)

  • CAST(NULLIF(...) AS DATETIME) could return an incorrect result because temporal values produced by NULLIF() were not evaluated with the appropriate temporal type handling.

    Temporal evaluation is now handled correctly for IF() and NULLIF() expressions. As a result, NULLIF() applied to a YEAR expression now preserves the YEAR data type; related aggregate expressions may therefore return DECIMAL rather than DOUBLE.

    Our thanks to Ximin Liang for the contribution. (Bug #118053, Bug #37875484)

  • FORCE INDEX on a unique index could still perform an index dive for IS NULL predicates, contrary to the expected behavior of forcing a single index.

    The optimizer now skips the index dive in this case while continuing to use index statistics only when they are valid for the selected range.

    Our thanks to Kaiwang Chen and the team from Tencent for the contribution. (Bug #117791, Bug #37751691)

  • Temporal results returned by GREATEST(), LEAST(), or COALESCE() could report an incorrect collation through the client protocol and the COLLATION() function. Temporal values use the binary collation, but these multi-purpose functions did not apply the required translation. Temporal results from these functions now correctly report the binary collation.

    Our thanks to Dirkjan Bussink for the contribution. (Bug #117543, Bug #37626671)

  • Queries using CONST access on a materialized temporary table could return incorrect results after an in-memory temporary table was converted to an on-disk table.

    As of this release, the temporary table's read state is reset after conversion, ensuring the expected rows remain accessible.

    Our thanks to Jingqi Tian for the contribution. (Bug #116741, Bug #37308710)

  • Some LEFT JOIN queries with OR conditions displayed dynamic range access in EXPLAIN, but still performed full scans of the inner table at execution time. This occurred because the optimizer did not recognize eligible outer-join predicates when evaluating range access.

    The optimizer now considers these predicates for dynamic range analysis, allowing eligible LEFT JOIN queries to use an index range scan re-planned for each outer row instead of repeatedly scanning the full inner table.

    Our thanks to Hope Lee for the contribution. (Bug #113288, Bug #36061036)

  • For some LEFT JOIN queries, an optimizer rewrite could prevent a non-equality condition from being applied while building a hash join. As a result, more rows than necessary could be added to the hash table before filtering.

    The optimizer now remaps eligible predicates to the build-side table when possible, allowing earlier filtering and more efficient hash join execution without changing inner-join filtering behavior.

    Our thanks to Wen He and Yicheng Wei for their contribution. (Bug #112198, Bug #35749693)

  • Queries that assigned names to derived-table columns produced by GROUP BY ... WITH ROLLUP could report an “Unknown column” error when a window function ordered by one of those names.

    Materialized rollup fields now retain their derived-table column names, allowing these references to resolve correctly.

    Our thanks to Hope Lee and the team at AliBaba for the contribution. (Bug #112112, Bug #35722845)

  • Using a view created with one or more CTE definitions could result in a syntax error.

    Our thanks to Vitali Vinahradski for the contribution. (Bug #111559, Bug #35536775)

  • A cached table could retain temporary-NULL state after a multi-table UPDATE involving a trigger, causing later valid statements to warn or fail under strict SQL mode. Errors were returned similar to the following:

    ERROR 1048 (23000): Column 'columnName' cannot be null

    Our thanks to Shun Yi and the team from Alibaba for the contribution. (Bug #110962, Bug #35373634)

  • TIMESTAMPDIFF() returned unexpected results when used with a WHERE clause. (Bug #108143, Bug #34499767)

Packaging Notes

  • As of this release, MySQL no longer supports Enterprise Linux 7 (and associated glibc 2.17 generic).

Performance Schema Notes

  • Fixed an issue relating to OBJECT_INSTANCE_BEGIN columns. (Bug #39449066)

  • A fix in a previous version caused a performance overhead in prepared statement digests. (Bug #38809758)

    References: This issue is a regression of: Bug #36445818.

Replication Notes

  • Replication: Fixed an issue relating to client BINLOG execution with REPLICATION_APPLIER. (Bug #39474825)

  • Replication: Fixed an issue relating to heartbeat handling. (Bug #39377010)

  • Replication: On writable replicas with log_replica_updates disabled, concurrent local commits and applier work could cause a race condition. (Bug #39259437)

  • Replication: Fixed an issue relating to event rotate handling. (Bug #39253359)

  • Replication: A replication receiver configured with SOURCE_RETRY_COUNT=0 could stop after a later transient connection loss, despite SOURCE_RETRY_COUNT=0 allowing unlimited reconnect attempts. The inconsistency could also cause the receiver to exit without logging an additional reconnect error.

    Replication now consistently treats SOURCE_RETRY_COUNT=0 as unlimited across reconnect paths, allowing the receiver to continue retrying and catch up after repeated transient failures. (Bug #39086875)

  • Replication: Fixed an issue relating to error handling. (Bug #38924622)

  • Replication: ALTER USER statements with explicit empty authentication data were rewritten for the binary log without preserving the empty authentication string. This resulted in password_expired errors. (Bug #38478657)

  • Replication: If a replication channel was configured using an applier user, the privilege check for CREATE and DROP statements failed if those privileges are granted only at the database-specific level for that user. (Bug #37587555)

  • Replication: Under certain circumstances, multiple simultaneous queries on the binary_log_transaction_compression_stats table could cause the server to stop with an error. (Bug #36196212)

  • Replication: If explicit_defaults_for_timestamp was disabled, row-based replica apply or mysqlbinlog replay could stop when recomputing a stored, generated TIMESTAMP NOT NULL column from NULL input. Errors were returned similar to the following:

    Could not execute Write_rows event on table tablename; Column 'timestamp_col2' 
    cannot be null, Error_code: 1048; handler error No Error!

    The row is now applied using the field default and a warning is emitted. (Bug #120128, Bug #39182574)

  • Fixed several issues relating to validations. (Bug #39234600, Bug #38673268, Bug #38673285, Bug #38712932, Bug #39253416, Bug #39282368, Bug #39253383, Bug #39253491, Bug #39254867, Bug #39254885, Bug #39254896, Bug #39254914, Bug #39282350, Bug #39319907)

Thread Pool Notes

X Plugin Notes

  • Fixed several issues in the X Plugin. (Bug #39268692, Bug #39268863)

Bugs Fixed

  • Fixed several issues in the Clone plugin. (Bug #39252316, Bug #39245805, Bug #39245844, Bug #39253040, Bug #39253103)

  • It was not possible to start the server on Oracle Linux or Red Hat Linux 9 if innodb_redo_log_encrypt=ON was defined in the configuration file. (Bug #39181231)

  • Fixed an issue relating to connection-attribute parsing. (Bug #39116965)

  • Some Polish characters were replaced by question marks (?) in client messages. (Bug #38036138)

  • Fixed an issue relating to table maintenance statement error handling after table and metadata-lock cleanup.

    Our thanks to Yin Peng and the team from Tencent for the contribution. (Bug #37797437)

  • Deleting a row from a table with a self-referencing foreign key caused replication to fail. (Bug #119996, Bug #39091367)

  • During LOAD DATA, fields can be marked temporarily nullable while input rows are parsed. If a row supplies NULL for a NOT NULL column, LOAD DATA could leave temporary NULL state on the table fields before returning to the same thread. A later INSERT in that same session can then treat valid non-NULL values as NULL and return ER_BAD_NULL_ERROR.

    Our thanks to Feng Chuanheng for the contribution. (Bug #118060, Bug #38939847)

  • Upgrading from older 8.x releases with thousands of tables, views, routines, and events caused the memory consumed by server to grow continuously, leading to significant memory spikes.

    Memory management is improved for these scenarios. (Bug #117983, Bug #37832455, Bug #38031020)

  • The following were not properly defined as reserved keywords:

    • CUBE

    • EXTERNAL

    • QUALIFY

    • TABLESAMPLE

    The following were not properly defined as non-reserved keywords:

    • MANUAL

    • PARALLEL

    (Bug #114874, Bug #36584265)

  • The behavior of INSERT() was incorrect for multibyte characters. It inserted characters even if the given position was beyond the input string.

    Our thanks to Dirkjan Bussink for the contribution. (Bug #113962, Bug #36289412)

  • Under certain circumstances, LEAST() and GREATEST() could return unexpected results.

    Our thanks to Jinsheng Ba for the contribution. (Bug #113304, Bug #36065440)

  • Fixed a memory leak in statement_digest() and statement_digest_text(). (Bug #104115, Bug #33073320)