Oracle has published the second MySQL 9.7.0 early access release!
Previously I wrote about building and testing the first one under macOS. This time I won't do that, because I cannot, because of a showstopper bug #120246 (XCode 26.4 fails to build 9.7.0-er2). Using a different compiler does not help this time because some of the errors appear libc-related.
So, this time I'll be looking into a different thing: what exactly has changed from the first to the second early access release? When the 1st ER came out, the community noted that there are no release notes. Oracle has now published them, and they cover what has changed from 9.6.0, but not between the ER releases, and this is precisely the gap I wanted to cover.
I got the source diff, excluding the generated files:
diff -ruN -x 'sql_yacc.cc' -x 'sql_hints.yy.*' mysql-9.7.0-er mysql-9.7.0-er2
Diffstat shows 466 files changed, 17835 insertions(+), 2971 deletions(-)
Then I fed it, together with URLs of the release notes and WLs to Claude Opus 4.6, which produced the following, which I then iterated to remove obvious mistakes and lightly edited to remove some irrelevant ("test result files have been updated") stuff and re-ordered to list most user-visible changes first:
New feature: Fire child triggers during FK cascade (WL#17024)
- New session variable
enable_cascade_triggers, defaultOFF,SESSION_VAR+IN_BINLOG+CMD_LINE. WhenON, BEFORE/AFTER triggers on a child table fire duringON DELETE CASCADE,ON UPDATE CASCADE,ON DELETE SET NULLandON UPDATE SET NULLactions (SET NULL fires the child's UPDATE triggers in both cases, since the child row is not deleted). WhenOFF, the historical behaviour (no child triggers during cascade) is kept. - Introduced as already deprecated. The variable emits a deprecation
warning regardless of value, and the command-line option
--enable_cascade_triggersdoes the same:- set to
OFF: warns "triggers on child table will not fire". - set to
ONwhileinnodb_native_foreign_keys=ON: warns that it is only supported with SQL foreign-key handling. - otherwise: generic deprecation warning.
- set to
- Limits and safety rails:
- Max depth of a cascade-trigger chain is 30 tables
(
FK_MAX_TABLES_IN_CASCADE_CHAIN). - Triggers that would modify the FK columns are rejected.
- Generated columns and CHECK constraints are re-evaluated after BEFORE triggers.
- Self-referencing FKs correctly prelock for UPDATE triggers on the cascade path.
- Max depth of a cascade-trigger chain is 30 tables
(
- Replication behaviour:
- The applied value is recorded in each DML binlog event (new
Q_ENABLE_CASCADE_TRIGGERSstatus variable) so replay is deterministic.mysqlbinlogprints the flag. - Row-based replication workers force
enable_cascade_triggers=OFF— triggers are never re-fired from replica-side row events. - Statement-based applier honours the flag only if the source is
9.7.0 or newer, gated by
replica_allow_higher_version_source(the gate is new; the sysvar itself already shipped in-er).
- The applied value is recorded in each DML binlog event (new
- New tests: source × replica matrix
(
rpl_fk_enable_triggers_{off_off,off_on,on_off,on_on}), child-trigger tests, binlog tests that echo "WL#17024", refreshes ofall_persisted_variables/mysqld--help-*/ replica compatibility-rules results.
New feature: MySQL Router host-cache
A brand-new Router subsystem that caches DNS resolution results so routing connections do not re-query the resolver on every hop. (not called out in the draft release notes, but installed by packaging)
- Three new Router plugins:
host_cache— the cache itself, configurable with:enabled,max_entries,ttl_success,ttl_negative,ttl_jitter_ratio.rest_host_cache— lists / invalidates entries via the existing Router REST framework.mock_host_resolver— test-only resolver used by component tests.
- Routing integration: classic routing connections resolve
hostnames via a new harness-level resolver framework that consults
the cache (
CachePolicy::UseIfPresent). - Packaging:
host_cache.soandrest_host_cache.soship in the Router package; defaultconfiguration_defaults_cluster{,set}.jsonfiles now include a[host_cache]section.
Optimizer / hint bug fixes
- Bug#116084 "Uniform syntax of join order and table hints" —
JOIN_PREFIX/JOIN_SUFFIX/JOIN_ORDERnow accept the same table-list syntax as the other table hints.sql_hints.yycollapses the*_empty_qbrules;opt_hints_join_order.testadds the covering cases. - Bug#38191248 — NULL detection for DATE-type columns in derived
tables after derived merge. New cases in
derived.test. - Bug#39062785 — hypergraph assertion
`tl->join_cond_optim() !nullptr'= failed. New case inhypergraph_bugs.test. - Bug#37804715 INTERSECT wrong result (release notes pair this with Bug#117911).
When INTERSECT/EXCEPT produce a non-nullable result type but an operand is
nullable, a
NOT NULLfilter is injected into HAVING/QUALIFY (for aggregates/window) or WHERE (for plain columns).make_join_hypergraph.ccpreserves an explicitItem_func_true()sentinel so the fix survives hypergraph planning. - Correlated-subquery plan fix —
test_quick_select()now receives the correctprev_tables/read_tablescontext instead of empty maps.
Prepared-statement bug fixes
- Bug#39071552 —
Rollback_item_tree_changes()stack use-after-free. Thecondsstack item insql_delete.cc/sql_update.ccis moved off-stack (ArrayAlloc<Item *>(1)) so it survives prepared-statement re-execution while triggers mutate the item tree. Regression test inps.test. - Bug#38600714 — SQL reprepare bug causing 100% CPU. Reprepare
gives up with an error in release builds when it keeps hitting a
parameter-type mismatch, instead of looping forever. Regression
test covers
KILL/PURGE/CREATE TABLE … DEFAULT(?)variants. - Digest split:
Prepared_statementnow carries separatem_execute_digestandm_deallocate_digest(and corresponding PSI instrumentation), fixing double-accounting of theDEALLOCATE PREPAREdigest via the new PSIdigest_setentry point.
Histogram fixes
- Bug#38983545 — stale diagnostic-area conditions were being
re-logged on every background histogram update. Each background
update now resets the diagnostics area first, and repeated
background-update errors are downgraded to warnings in the error
log.
histogram_background_error.testadds the regression case and flips the wait condition fromErrortoWarning. - Bug#37269033 — user-defined histogram import failed for BIGINT
data containing unsigned values.
Histogram::extract_json_dom_value<longlong>now also acceptsJ_UINT(range-checked againstLLONG_MAX).histogram_update_using_data.testextended.
Performance Schema — binary_log_transaction_compression_stats thread-safety
- Concurrent access to the P_S
binary_log_transaction_compression_statstable could race with binlog stats updates. binlog/monitoring/contextnow takes a snapshot under astd::mutexbefore rows are emitted, and the backing store usesstd::unique_ptr<Compression_stats>(also plugs a leak). (not in release notes)
Clone plugin — protocol V4 (WL#16520 code delta)
The parent cross-LTS feature was already in -er (the four
remote_basic_replace_across_lts_* tests ship there). What's new
in -er2:
- Protocol bump to V4: new
COM_RES_CONFIG_V4response command. - Version-and-maturity handshake: donor sends its version and
maturity (
LTS/INNOVATION); recipient caches and validates via new service methodmysql_clone_validate_version(). The check moves out ofmysql_clone_validate_configs()into its own service entry point. - One new test:
remote_basic_replace_one_lts_to_next.{test,result,cnf}.
New component service: audit-log prune adapt
Two new header-only component-service declarations:
include/mysql/components/services/bits/audit_log_prune_adapt_bits.h—typedef void (*audit_log_prune_adapt_v1_t)(size_t external_rotate_cycle);include/mysql/components/services/mysql_audit_log_prune_adapt_service.h
These let an audit-log plugin adjust its pruning cycle to be slower than rotation, whether rotation is time-based or external. The audit-log plugin itself is enterprise and not in this source tree, so only the service headers ship here. (release notes advertise the consumer features WL#17213/WL#17179, but those land in the enterprise plugin, not in this diff.)
InnoDB
- Parallel FTS index build refactor:
ddl0fts.cc/ddl0impl-buffer.h/ddl0impl-builder.hreorganised.copy_fts_column()becomesenqueue_parsing();Doc_item::m_fieldowns itsdfield_tinstead of pointing at parser state; newpop_unfinished_tuple()+will_fit()guarantee forward progress. No SQL-level semantics change. New regression testinnodb_fts/articles_fts_words. - Symlinked datadir tablespaces: new static
fil_ibd_same_as_default_path()infil0fil.cc. When discovering tablespaces at startup, a.ibdsymlinked into the datadir tree is recognised as "default location" (by inode comparison). Fixes the rewritteninnodb_recovery_with_upper_case_names. (not in release notes) - Parallel scan:
row0pread.ccrecord copy now accounts for the extra-bytes prefix (rec_offs_extra_size) so the saved pointer stays valid. (not in release notes)
Group Replication — GCS input-length hardening
Defensive hardening of the XCom state-exchange decoder:
Xcom_member_state::decode_header()now takes a buffer length and validates it before reading.decode_snapshot()enforces element-count sanity against the size required by the node array.decode()does an overall size check; return values changed from rawbooltoERROR/OKconstants.pipeline_interfaces.h:event_len <packet->len= check before deserialising a binlog event; logsER_GRP_RPL_UNABLE_TO_CONVERT_PACKET_TO_EVENTon mismatch.
(not in release notes)
JSON schema — recursion / stack-overflow guard
sql-common/json_schema.cc:
- New
JSON_SCHEMA_MAX_EXPANSION_DEPTH = 100. - Helpers
is_local_json_pointer_ref(),resolve_local_json_pointer_ref(),json_schema_exceeds_expansion_depth()walk a schema and abort with a proper error before rapidjson's recursive compile blows the stack.
Security adjacent — not in the release notes.
Smaller SQL-layer fixes
- ALTER TABLE INPLACE — separate trackers
old_field_index_without_vgc(stored) andold_field_index_vgc(virtual) so VGC reorder is detected correctly; reorder-flag comparison now usesnew_field_index_vgc. - LOAD DATA — Bug#39045673: field-list setup rewritten to build
set_fields/set_varsdeques and feed a unifiedsetup_fields(). New test data filestd_data/bug39045673.csv. - sys-schema
revoke_schema_privileges_from_all_accounts_exceptcorrectness fix (string-literal quoting); new assertions inpr_revoke_schema_privileges_from_all_accounts_except. events_bugs.test—--sorted_resulton alast_executed-sensitive SELECT (non-determinism fix).
Build / toolchain
- C++23 is now the project-wide default (was C++20). The top-level
CMakeLists.txtaddsSET(CMAKE_CXX_STANDARD 23); per-compiler-std=c++23//std:c++latestflags are dropped. (not in release notes)
Performance Schema — PSI statement service v6
- New
PSI_STATEMENT_VERSION_6interface;PSI_STATEMENT_VERSION_5remains resolvable (tagged obsolete) so older plugins still load. - New
digest_set_v6_tcallback lets the server hand a fully-computed statement digest to P_S in one call — used by the prepared-statement digest split above.
X plugin allocator rewrite
plugin/x/src/ngs/memory.h — PFS_allocator<T> rewritten as a
proper C++17 allocator: explicit value_type / size_type /
difference_type / is_always_equal, operator==, noexcept,
[[nodiscard]], throws std::bad_array_new_length /
std::bad_alloc on overflow / my_malloc failure instead of
silent UB inside standard containers. (not in release notes)
For completeness: NDB Cluster
(not in release notes)
- New NDBINFO table
TRANSPORTER_ACTIVITY(TABLEID 53) — histogram of activity on heartbeated transporters, for diagnosing link starvation / flapping. TRANSPORTER_DETAILSgrows two columns (19 → 21):heartbeat_intervalandlast_recv(time since last receive).- New "Late heartbeat" event in the cluster log; docs clarify that four missed heartbeats mark a node dead.
- Node-ID hardening: API client connect / subscribe paths validate
the node ID against
MAX_NODES_ID(2048) before using it. New testndb_high_api_node_id. - Transporter plumbing:
Transportergainsget_last_recv()/set_last_recv()+m_last_recv; signal structs (EnableCom,CloseComReqConf,ApiRegSignalData) carry the new activity info; QMGR/trpman handshake updated; new unit-test drivertrpman-t.cpp. - Portlib:
NdbTick_AddMillisecondssignature changesUint64→Int64with a range assertion. - Associated tests:
ndb_trp_activity, refreshes ofndbinfo/ndbinfo_plansresults.
1 comment:
Do the build issues persist if the missing headers are added?
Post a Comment