MySQL 26.10 Release Notes  /  Changes in MySQL 26.10.0 (2026-09-18 (Early Access Release))

Changes in MySQL 26.10.0 (2026-09-18 (Early Access Release))

Compilation Notes

  • RapidYAML 0.16.0 is now bundled for use as an optional dependency of opentelemetry-cpp when built with -DWITH_CONFIGURATION=ON. (Bug #39894165)

  • MySQL Server could fail to compile with GCC 16.1 due to warnings treated as errors. (Bug #39688855, Bug #39671507, Bug #39670670, Bug #39670901)

  • MySQL source builds can now be configured with OpenSSL 4.0. Compatibility updates were also made for curl, libfido2, and gRPC. (Bug #39102340)

Component Notes

  • MySQL command services did not return stored-procedure output parameters from prepared CALL statements. Prepared-statement multi-result support now returns those parameters as a result set to component consumers. (Bug #39836178)

  • The public mysql_command_services API now supports password-authenticated local Classic Protocol connections through the write-only MYSQL_COMMAND_PASSWORD option. Any non-null value, including an empty string, selects normal authentication to the local server; null retains embedded behavior. Connections remain server-local and one-shot, and option-file settings are rejected. (Bug #39817209)

  • Components using mysql_account_database_security_context_lookup can now query an account's lock state through the read-only Boolean account_locked option exposed by mysql_security_context_options. (Bug #39702733)

  • The default command-service DOM consumer could return incomplete MYSQL_FIELD metadata, including a null catalog and zero metadata-name lengths. It now returns catalog def with length 3 and supplies the byte lengths of the remaining metadata names, matching libmysql and Classic Protocol results. (Bug #39667008)

  • MySQL REST Service (MRS) is now available as a MySQL Server component, component_mysql_rest_service, enabling HTTPS endpoints without a separate MySQL Router process.

    To install, and confirm it is running, run the following:

            INSTALL COMPONENT 'file://component_mysql_rest_service';
            SELECT mysql_rest_service_restart();
            SHOW GLOBAL STATUS LIKE 'mysql_rest_service.state';

    Dynamic global system variables configure the service:

    • mysql_rest_service.http_port: sets the HTTPS port; the default is 33443.

    • mysql_rest_service.ssl_cert: defines the TLS certificate

    • mysql_rest_service.ssl_key: the name of the SSL key file

    • mysql_rest_service.ssl_cipher: the TLS 1.2 cipher list.

    • mysql_rest_service.io_worker_threads: the I/O worker count; zero enables automatic sizing.

    • mysql_rest_service.http_max_connections: the HTTP connection limit; the default is 1024.

    • mysql_rest_service.http_max_request_body_size: the request body size limit. Default is 16MiB.

    • mysql_rest_service.http_max_response_body_size: the response body size limit. Default is 16MiB.

    The following status variables provide observability:

    • mysql_rest_service.current_http_port: the active port number.

    • mysql_rest_service.current_tls_cert: current value of mysql_rest_service.ssl_cert system variable

    • mysql_rest_service.current_tls_key: current value of mysql_rest_service.ssl_key system variable

    • mysql_rest_service.current_tls_cipher: current value of mysql_rest_service.ssl_cipher system variable

    • mysql_rest_service.current_io_worker_threads: the number of active IO worker threads

    • mysql_rest_service.state: one of the following values:

      • STOPPED: The component is loaded and the MRS backend is not running.

      • STARTING: Backend startup is in progress.

      • WAITING_FOR_METADATA: Startup is waiting for required MRS metadata and will retry.

      • READY: The embedded MRS backend and HTTP listener are running.

      • STOPPING: Backend startup cancellation or runtime shutdown is in progress.

      • ERROR: Backend startup failed irrecoverably or a running backend terminated unexpectedly. See the MySQL Server error log.

    The following UDFs enable you to manage the MRS:

    • mysql_rest_service_start(): Starts the REST Service backend, asynchronously.

    • mysql_rest_service_stop(): Stops the REST Service backend, synchronously.

    • mysql_rest_service_restart(): Restarts the REST Service backend, asynchronously.

    Note

    Each UDF requires the MYSQL_REST_SERVICE_ADMIN privilege.

    (WL #17018, WL #17019)

Deprecation and Removal Notes

  • Important Change: MySQL no longer supports OpenSSL versions older than 1.1.1. Build checks, packaging requirements, help text, and version guards now enforce the new minimum. (Bug #39546984)

InnoDB Notes

  • InnoDB: A previous InnoDB deadlock fix made row-size estimates more accurate for B-tree operations, but also made CREATE TABLE and ALTER TABLE validation stricter. As a result, some table definitions accepted by earlier MySQL LTS releases were unexpectedly rejected or produced warnings, disrupting existing applications.

    As of this release, the legacy validation behavior is preserved for most DDL operations while retaining the accurate estimate where it is needed to prevent B-tree deadlocks. ALTER TABLE ... ALGORITHM=INSTANT continues to use the stricter calculation to safely handle large default values.

    Our thanks to Paweł Olchawa and the team at Percona, and Meng-Hsiu Chiang and the team at Amazon for their contribution. (Bug #120323, Bug #39249507)

    References: See also: Bug #39129182.

  • After an exported table was modified, its tablespace discarded, and an older exported image imported, point lookups could return rows or values from the discarded tablespace generation. Stale Adaptive Hash Index entries are now treated as misses so lookups fall back to normal B-tree traversal. (Bug #39661793)

  • After ALTER TABLE ... IMPORT TABLESPACE failed, stale pages from the discarded tablespace could later trigger an assertion during eviction. Failed-import cleanup now preserves the index space identifier required to remove stale Adaptive Hash Index entries. Errors were returned similar to the following:

    [ERROR] [MY-013183] [InnoDB] Assertion failure: btr0sea.cc:1082:block->page.id.space() == index->space

    (Bug #39661792)

  • Fixed an issue relating to concurrent COPY ALTER operations.

    Our thanks to George Ma and the team at Alibaba for the contribution. (Bug #39134921)

  • If InnoDB page reorganization produced a size mismatch, InnoDB could continue using the reorganized page without recording the corresponding redo. A later insert followed by a server crash could consequently cause recovery failure or page corruption. The mismatch is now treated as fatal rather than allowing inconsistent redo state to continue. (Bug #116574, Bug #37258813)

  • The uncompressed externally stored InnoDB LOB prefix-copy path could read beyond the remaining destination-buffer capacity after an inline prefix had already been copied. The external read now accounts for the copied prefix length. (Bug #104884, Bug #33340548)

Logging Notes

  • Microsoft Windows: Failure to open a new error log could close the descriptor owned by an existing stream; retrying with that stream could trigger a CRT assertion and prevent error-log recreation. Delete-pending handles are now redirected to NUL without invalidating the stream, allowing a later retry to recreate the error log. (Bug #32901809)

MySQL Programs Notes

  • The mysql client's interactive -p input could truncate or mishandle passwords longer than 79 bytes, including token-style credentials, causing authentication failures. Interactive input now accepts longer credentials without requiring them on the command line. Errors were returned similar to the following:

            ERROR 9125 (HY000): An error occurred while validating the access token. 
            Please acquire a new token and retry.

    Using the command-line workaround could also produce:

            mysql: [Warning] Using a password on the command line interface can be insecure.

    Our thanks to Hanchun Liu for the contribution. (Bug #120663, Bug #39621454)

Optimizer Notes

  • If explain_json_format_version=2, JSON EXPLAIN output for a WEEDOUT AccessPath did not include an access_type attribute. (Bug #37925474)

  • With the hypergraph optimizer, an ORDER BY on a trailing part of a multi-valued index could add an unnecessary sort even when a single-point range fixed the array key part. Ordered range scans can now use trailing key parts to provide the requested ordering. (Bug #37543247)

  • The hypergraph optimizer could undercount the one-time cost of materializing an IN subquery and select materialization when per-row IN-to-EXISTS lookups were cheaper. Materialized temporary-table costs and sizes are now calculated from the appropriate access path. (Bug #36834773)

  • EXPLAIN FORMAT=TREE now provides the Note 1003 warning containing the transformed query, including for INSERT and REPLACE statements using VALUES. This exposes transformations such as subquery-to-semijoin conversion. (Bug #36784038)

  • optimizer_switch and optimizer_trace accepted values such as o and of as valid flag values. Exact matches are now required. Invalid values return ER_WRONG_VALUE_FOR_VAR and leave the variable unchanged. (Bug #36596561)

  • EXPLAIN FORMAT=JSON could omit used_key_parts for an index_merge access path. Key parts are now collected recursively from index-merge, row-ID intersection, and row-ID union child scans. (Bug #35206957)

  • With the hypergraph optimizer enabled, single-table UPDATE or DELETE statements using ORDER BY and a subquery converted to a hash semijoin or antijoin could modify the wrong rows. An update through a view with CHECK OPTION could also use incorrect rows or fail when required row identifiers were not preserved. (Bug #121038, Bug #39822725)

  • Grouped aggregate queries using GROUP_INDEX_SKIP_SCAN for distinct aggregates followed by a window function could return null or zero aggregate values, duplicate groups, or incorrect row counts. (Bug #119323, Bug #38627346)

  • Queries exposing the same derived-table expression under different output aliases could report both result columns with the later alias even though their values were correct. This affected populated results ordered by RAND() and empty results using the optimizer. The hypergraph optimizer was not affected. (Bug #118729, Bug #38249983, Bug #39734461)

  • Equality index ranges containing an IS NULL key part could lose the NULL_RANGE flag, causing unsuitable records_per_key() statistics to be used when eq_range_index_dive_limit was reached. The flag is now propagated for every applicable equality range so records_in_range() is used.

    Our thanks to Kaiwang Chen and the team at Tencent for the contribution. (Bug #117776, Bug #37743879)

  • Optimizer trace output now includes a test_if_cheaper_ordering object describing how candidate indexes for ORDER BY or GROUP BY were evaluated. Per-index values include is_covering, select_limit, index_scan_cost, rows, chosen, and the rejection cause.

    Our thanks to Tianfeng Li and the team at Tencent for the contribution. (Bug #116355, Bug #37171976)

  • With optimizer_switch set to index_merge_union=off, an index-merge plan for disjunctive conditions could omit a disjunct and return incomplete results. For example, a query expected to return four rows instead returned: Empty set (0.00 sec).

    Our thanks to Kun Qin for the contribution. (Bug #114885, Bug #36584358)

  • On Linux, a RESOURCE_GROUP optimizer hint in a prepared statement was not applied by EXECUTE or subsequent executions. The hint now remains effective across executions without leaking to later statements on the connection.

    Our thanks to Dmitry Lenev and the team from Percona for the contribution. (Bug #112011, Bug #35696738)

Packaging Notes

  • The bundled TIRPC library was upgraded to version 1.3.7. (Bug #39703871)

  • Rebuilding MySQL source RPMs on minimal EL8 or EL9 systems could fail because required dependencies were omitted from mysql.spec.in.

    Our thanks to Simon Mudd for the contribution. (Bug #120895, Bug #39894524)

Performance Schema Notes

  • The component-facing psi_thread.h header now uses psi_thread_v7. PSI_THREAD_VERSION values 4 through 6 are deprecated for plugins. (Bug #39802197)

Replication Notes

  • With Change Stream Applier enabled, performance_schema.threads could report a PROCESSLIST_ID for the replica SQL thread that differed from INFORMATION_SCHEMA.PROCESSLIST. The identifier now remains stable during CSA session creation. (Bug #39933596)

  • Under certain circumstances, after recovery from a network partition, a group could lose quorum and remain in a reconnection loop that blocked writes after networking stabilized. Connection delegation now uses a single nonblocking publication attempt, allowing normal reconnection handling to retry. Errors were returned similar to the following:

            MY-013781: "Error sending connection delegation command"

    (Bug #39767762)

  • The GTID for an XA COMMIT or XA ROLLBACK could become visible before XA RECOVER stopped listing the completed XID. XA RECOVER now hides the finalized transaction before the GTID is externalized. (Bug #36505659)

  • After XA PREPARE made its GTID visible in gtid_executed, XA RECOVER could still omit the prepared XID. The XID is now made visible before the GTID state is updated, so waiting for the GTID guarantees that another session can observe the prepared transaction. (Bug #35872823)

  • Replaying a CTAS binary log through mysqlbinlog into a server with binary logging disabled could fail instead of restoring the logged tables and rows because an additional transaction produced an invalid transaction boundary. Parser-started CTAS transactions are now suppressed for binlog-applier threads.

    Our thanks to Venkatesh Duggirala and the team at Google for the contribution. (Bug #120757, Bug #39743645)

  • On a binlogless replica using relay-log recovery, parallel replication, and commit-order preservation, replicated FLUSH PRIVILEGES statements could leave gaps in mysql.gtid_executed. After restart, the replica could request already-applied transactions, resulting in duplicate errors or failure when the source had purged the required binary logs. Errors were returned similar to the following:

    Cannot replicate because the source purged required binary logs. 
    Replicate the missing transactions from elsewhere, or provision a new replica from backup

    (Bug #115613, Bug #36849620)

  • With the MySQL communication stack, multiple members on one multihomed host could fail to join when they used different IP addresses but the same SQL port. Local members are now identified by their configured endpoint rather than all local interfaces. The XCom stack still requires distinct localAddress ports. Errors were returned similar to the following:

    [ERROR] [MY-011735] [Repl] Plugin group_replication reported: 
    '[GCS] Error connecting to all peers. Member join failed. Local port: 3306'
    [ERROR] [MY-011735] [Repl] Plugin group_replication reported: 
    '[GCS] The member was unable to join the group. Local port: 3306'

    (Bug #110773, Bug #36055146)

  • After a replica worker applied a rewritten statement, SHOW PROCESSLIST and performance_schema.threads could continue displaying the completed statement while the worker was idle. Query-event cleanup now clears the displayed state.

    Our thanks to Marcelo Altmann for the contribution. (Bug #99200, Bug #31140932)

SQL Syntax Notes

  • ALTER TABLE ... EXCHANGE PARTITION could move rows that violated the destination table's CHECK constraints or exchange tables whose generated columns used different expressions. Rows are now checked in both directions, including when WITHOUT VALIDATION skips partition-bound checks, and mismatched generated-column definitions are rejected. Errors were returned similar to the following:

            ERROR 3819 (HY000): Check constraint 't_swap_chk_1' is violated.

    (Bug #120206, Bug #39634208)

Bugs Fixed

  • For encrypted X Protocol connections, the Tls_key_exchange_algorithm and Tls_sign_algorithm session status variables could remain empty despite an active TLS session. (Bug #39980717)

  • GROUP_CONCAT() with ORDER BY could trigger a debug assertion when later input rows contained NULL argument values. Errors were returned similar to the following:

    mysqld-debug: ./sql/field.cc:5428: virtual String* Field_time::val_str(String*, String*) 
    const: Assertion `!is_null()' failed.

    (Bug #39280089)

  • After a global privilege was granted and partially revoked for a schema, a subsequent GRANT for the same account could fail with ERROR 3901. Errors were returned similar to the following:

            ERROR 3901 (HY000): 'GRANT' privilege for database 'sys' exists both 
            as partial revoke and mysql.db simultaneously. It could mean that the 
            'mysql' schema is corrupted.

    (Bug #38921524)