Wednesday, April 15, 2026

What changed between MySQL 9.7.0-er and 9.7.0-er2

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, default OFF, SESSION_VAR + IN_BINLOG + CMD_LINE. When ON, BEFORE/AFTER triggers on a child table fire during ON DELETE CASCADE, ON UPDATE CASCADE, ON DELETE SET NULL and ON UPDATE SET NULL actions (SET NULL fires the child's UPDATE triggers in both cases, since the child row is not deleted). When OFF, 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_triggers does the same:
    • set to OFF: warns "triggers on child table will not fire".
    • set to ON while innodb_native_foreign_keys=ON: warns that it is only supported with SQL foreign-key handling.
    • otherwise: generic deprecation warning.
  • 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.
  • Replication behaviour:
    • The applied value is recorded in each DML binlog event (new Q_ENABLE_CASCADE_TRIGGERS status variable) so replay is deterministic. mysqlbinlog prints 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).
  • 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 of all_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.so and rest_host_cache.so ship in the Router package; default configuration_defaults_cluster{,set}.json files 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_ORDER now accept the same table-list syntax as the other table hints. sql_hints.yy collapses the *_empty_qb rules; opt_hints_join_order.test adds 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 in hypergraph_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 NULL filter is injected into HAVING/QUALIFY (for aggregates/window) or WHERE (for plain columns). make_join_hypergraph.cc preserves an explicit Item_func_true() sentinel so the fix survives hypergraph planning.
  • Correlated-subquery plan fixtest_quick_select() now receives the correct prev_tables / read_tables context instead of empty maps.

Prepared-statement bug fixes

  • Bug#39071552Rollback_item_tree_changes() stack use-after-free. The conds stack item in sql_delete.cc / sql_update.cc is moved off-stack (ArrayAlloc<Item *>(1)) so it survives prepared-statement re-execution while triggers mutate the item tree. Regression test in ps.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_statement now carries separate m_execute_digest and m_deallocate_digest (and corresponding PSI instrumentation), fixing double-accounting of the DEALLOCATE PREPARE digest via the new PSI digest_set entry 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.test adds the regression case and flips the wait condition from Error to Warning.
  • Bug#37269033 — user-defined histogram import failed for BIGINT data containing unsigned values. Histogram::extract_json_dom_value<longlong> now also accepts J_UINT (range-checked against LLONG_MAX). histogram_update_using_data.test extended.

Performance Schema — binary_log_transaction_compression_stats thread-safety

  • Concurrent access to the P_S binary_log_transaction_compression_stats table could race with binlog stats updates.
  • binlog/monitoring/context now takes a snapshot under a std::mutex before rows are emitted, and the backing store uses std::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_V4 response command.
  • Version-and-maturity handshake: donor sends its version and maturity (LTS / INNOVATION); recipient caches and validates via new service method mysql_clone_validate_version(). The check moves out of mysql_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.htypedef 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.h reorganised. copy_fts_column() becomes enqueue_parsing(); Doc_item::m_field owns its dfield_t instead of pointing at parser state; new pop_unfinished_tuple() + will_fit() guarantee forward progress. No SQL-level semantics change. New regression test innodb_fts/articles_fts_words.
  • Symlinked datadir tablespaces: new static fil_ibd_same_as_default_path() in fil0fil.cc. When discovering tablespaces at startup, a .ibd symlinked into the datadir tree is recognised as "default location" (by inode comparison). Fixes the rewritten innodb_recovery_with_upper_case_names. (not in release notes)
  • Parallel scan: row0pread.cc record 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 raw bool to ERROR / OK constants.
  • pipeline_interfaces.h: event_len < packet->len= check before deserialising a binlog event; logs ER_GRP_RPL_UNABLE_TO_CONVERT_PACKET_TO_EVENT on 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) and old_field_index_vgc (virtual) so VGC reorder is detected correctly; reorder-flag comparison now uses new_field_index_vgc.
  • LOAD DATA — Bug#39045673: field-list setup rewritten to build set_fields / set_vars deques and feed a unified setup_fields(). New test data file std_data/bug39045673.csv.
  • sys-schema revoke_schema_privileges_from_all_accounts_except correctness fix (string-literal quoting); new assertions in pr_revoke_schema_privileges_from_all_accounts_except.
  • events_bugs.test--sorted_result on a last_executed-sensitive SELECT (non-determinism fix).

Build / toolchain

  • C++23 is now the project-wide default (was C++20). The top-level CMakeLists.txt adds SET(CMAKE_CXX_STANDARD 23); per-compiler -std=c++23 / /std:c++latest flags are dropped. (not in release notes)

Performance Schema — PSI statement service v6

  • New PSI_STATEMENT_VERSION_6 interface; PSI_STATEMENT_VERSION_5 remains resolvable (tagged obsolete) so older plugins still load.
  • New digest_set_v6_t callback 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.hPFS_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_DETAILS grows two columns (19 → 21): heartbeat_interval and last_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 test ndb_high_api_node_id.
  • Transporter plumbing: Transporter gains get_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 driver trpman-t.cpp.
  • Portlib: NdbTick_AddMilliseconds signature changes Uint64Int64 with a range assertion.
  • Associated tests: ndb_trp_activity, refreshes of ndbinfo / ndbinfo_plans results.

Tuesday, March 24, 2026

Building and testing MySQL 9.7.0 early access build on macOS

Oracle released 9.7.0 community early access build, which is a part of their work towards fulfilling their new promises to the community. This is great news for community testing and I did my part in my usual way (previously: 8.0.45 / 8.4.8 / 9.6.0).

Build

No changes from 9.6.0: the current Xcode (26.3) builds the 9.7.0 early access build fine, LLVM 21 still fails (bug #119246).

Tests

Bad news

Good news

One-off issues

  • component_keyring_file.tablespace_encrypt_10 failed once under debug build
  • Likewise main.func_in_mrr
  • Likewise perfschema.idx_compare_metadata_locks
  • main.mysqltest failed testcase check one under debug build
  • rpl_gtid.rpl_semisync_gtid_tag crashed once under debug + sanitizers build
  • perfschema.system_events_component failed once under debug + sanitizers build
  • Likewise perfschema.stage_mdl_global
  • Likewise innodb_undo.truncate

Tuesday, February 10, 2026

Boring but useful: making large-scale changes on MySQL codebase with LLMs

I used Claude Code to do a simple mass refactoring on MySQL 9.6 over two weeks, resulting in a 25K line diff that passes the testsuite. That was something I wanted to experiment with for some time now: making boring but useful large-scale changes to MySQL while spending as little human effort as possible. Claude Code with Opus 4.5 (and 4.6 for the last few days) was used for everything.

Why boring but useful large-scale?

  • Pushing LLMs to the limit–like building a browser or a compiler, I guess I'd be building a database from scratch for a comparable project–is fun, it shows us what's possible and what needs one more frontier model release, but the result artifact itself is throwaway code, thus not usable in the general sense, nor do I have time (or money for tokens) for this.
  • Making algorithmically challenging changes is still firmly in the domain of humans. No "Add LSM tree to InnoDB. Be thorough. Do not make any mistakes." prompting here. Although, as I'm writing this, I just saw Zongzhi Chen doing exactly that and patching PostgreSQL with an InnoDB-like doublewrite buffer. Things move quickly.
  • Making too simple changes is a waste of LLM capabilities where sed would do the same faster and cheaper.

For a boring but useful large-scale change I picked replacing THD * with const THD & or THD & in method parameters and class fields. This might require some background. MySQL started in mid-90s, and its current source code, after 30 years, has features of three strata: modern C++ (C++11 to C++20), early standard C++ (C++98, C++03), and even earlier "C with classes" style. One thing still surviving from the earliest days is that pointers are used instead of references, including the contexts when the pointer can never be nullptr. I'll try not to digress on why it's not the right thing, C++ Core Guidelines has that (F.16, F.17, F.18, F.19, and finally F.60 for when the pointers are the right choice).

I settled on this after a few false starts, which made promising progress but eventually imploded. That was because of my mistake of not letting the agent make intermediate commits, resulting in unmanageable working directory diff every time. Now I believe I could have completed most of them too:

  • "Convert THD * to THD &": yep I tried it twice, the first time it broke the server and then couldn't debug its way out of the hole.
  • "Replace LEX_CSTRING with std::string_view" - the partial conversion was successful, but my mistake was not considering that lex strings are both owning and non-owning whereas string views are always strictly non-owning. The project failed in trying to replace the owning lex strings with something different altogether.
  • "Replace printf-style formatting with std::format" - this one imploded because of no intermediate commit rule, but not before scoring some strong wins, such as converting the MySQL error log and client error machinery and messages more or less correctly.

It was also my goal to spend as little of my time as possible on this, consciously ignoring some of the current best practices of this type of work, such as not setting up CLAUDE.md, not doing it in a dedicated container where the agent has full permissions, and not implementing any kind of Ralph Wiggum loop. All of these saved me some advance planning time, but then I had to go to a terminal and tell "continue" when it stopped mid-task or inexplicably started doing edits with some shell trickery instead of its standard tools. Thus by trying to save time I wasted some time, but definitely saved some thinking and could rubber-stamp agent questions while doing other, more useful, work.

I launched Claude Code and prompted

Convert pointers to THD to (optionally const) references to THD throughout the
codebase. The safe instances to convert are the ones where the pointer is dereferenced
unconditionally, there is an assert(thd != nullptr) check, or any thd == nullptr
branches are dead code (because e.g. the function is never called with pointer ==
nullptr). Not safe instances are the ones where null pointers are passed and C API.
In the touched code (and only in the touched code!) follow Almost Always Auto while
keeping references and pointers pulled out and const as much as possible (unless it
forces other code changes), except for trivial function parameters. Examples of AAA
and const: "const auto bar = ... ", "const auto *bar = ... ", "auto &baz = ...",
"const auto &x = ...", "const auto *const y = ...", "auto *const z = ..."

and letting it plan until we both were happy with the plan, and go. As I said above, every few tens of minutes to few hours it just stopped asking permission to continue, directly against original instructions. At those points I cleared its context and pointed to the plan file again.

Finally, some two weeks later (I did not orchestrate any parallelization, it sometimes parallelized itself a bit with subagents, also I needed room in the usage limits for other work on my account), it declared it's done. Then I ran debug + sanitizers testsuite, pasted any failures to the agent asking to fix, but, very importantly, always git bisect to the failing commit first. There were over a thousand commits. It debugged everything rather easily once it always had a relatively small regressing commit identified. Nice.

I succeeded in staying below usage limits of my Claude Max plan all the time. In the failed attempts above the agent parallelized much more aggressively and burned through the week's allowance in three days. I tried to preserve my sanity and did not go the route of stacked Max accounts.

With a clean testsuite run I asked it to create a second branch with all commits squashed. This produced a +25304, -25402 line diff. I looked at random points in the diff and everywhere I was satisfied with the result. The straightforward conversion bits went fine, but it also removed some provably-redundant nullptr checks, declared non-moveable classes as such, simplified constructors. The resulting release build binary is some 12K smaller on macOS, BTW. If this were real work, I'd still have to read the whole diff for any obvious issues, but in any case this is significantly faster than doing the work myself.

"If this were real work" - or is it? The nature of this patch is such that no tracking fork could take it, only Oracle MySQL. I have signed the contributor's agreement with them, then sent them some patches and have been waiting for years but they are still not merged, thus I will not submit this one unless asked to.

I pushed the code to GitHub:

To conclude, with LLMs, everyone has an opinion. A vocal part of the community does things like OpenClaw and Gas Town. I am way, way more conservative than that: so far I successfully avoided buying a Mac Mini for OpenClaw and giving my email and bank login details to it, and I also get uncomfortable quickly due to cognitive load if running too many coding agents in parallel. But, we live in exciting times, software engineering is changing and I am very optimistic.

Friday, January 23, 2026

Building and testing MySQL 8.0.45, 8.4.8, and 9.6.0 on macOS

Oracle has just released MySQL 8.0.45, 8.4.8, and 9.6.0 and here are the results of my usual testing of building them and running the testsuite on macOS, Apple Silicon hardware.

Build

All three versions compile with the current XCode (26.2) OK. With Homebrew-packaged LLVM, versions 14 to 17 inclusive are getting a strange CMake error that might have more to do with macOS than MySQL. LLVM 19 still fails to build 8.0.45 (bug #119238), but not 8.4.8, and so does LLVM 20 (bug #119239). Both these issues are pre-existing. But, 8.4.8 regressed in that it started being affected by bug #119246 too. LLVM 21 still fails to build 9.6.0 (preexisting bug #119246).

Test

Bad news:

  1. Bug #119735 Unhandled error log warning in main.initialize-sha256
  2. Bug #119738 global-buffer-overflow on INSTALL PLUGIN
  3. Bug #119739 Test rpl_gtid.rpl_gtids_table_disable_binlog_on_slave result difference
  4. Bug #119746 innodb.table_encrypt_4 failing with a result difference

No news aka old bad news:

  1. Bug #113189 ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails
  2. Bug #113190 Several tests in routertest_integration_routing_sharing_constrained_pools fail
  3. Bug #113260 Client error in error log: MY-004031 - The client was disconnected …
  4. Bug #113665 perfschema.relaylog fails with a result difference
  5. Bug #113709 StrXfrmTest.ChineseUTF8MB4 failing with an AddressSanitizer error
  6. Bug #113722 Test main.index_merge_innodb failing with a result difference
  7. Bug #114892 Test XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails
  8. Bug #115480 Test innodb.log_first_rec_group failing
  9. Bug #116369 rpl.rpl_semi_sync_alias crashes under AddressSanitizer
  10. Bug #116373 auth_sec.acl_tables_row_locking failing with result diff
  11. Bug #116378 routertest_integration_routing_splitting crashing under AddressSanitizer
  12. Bug #116385 Test main.mysql_upgrade_grant timing out on debug build
  13. Bug #116394 Test binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an assert
  14. Bug #118171 Test main.mysqldump-tablespace-escape failing
  15. Bug #118185 Non-specific ASan error on TestLoaderGood/LoaderReadTest.load_wrong_version/0
  16. Bug #118213 Test perfschema.idx_compare_mutex_instances fails under debug + sanitizers
  17. Bug #119247 Test main.log_buffered-big failure
  18. Bug #119249 Router unit test setup failures
  19. Bug #119251 Test rpl.rpl_seconds_behind_master failure
  20. Bug #119252 Test router.response_cache failure
  21. Bug #119253 innodb.tablespace_encrypt_9 crashing the server with assertion failure
  22. Bug #119258 router integration tests failing to login

Good news:

  1. none! Every single bug I am tracking is present

Conclusion

With 4 new, 22 unchanged bugs, and not a single fix, the testsuite quality is continuing to slowly decay. I hope this will change for the better.

Addendum

A note for my future self. Issues I couldn't reliably reproduce:

  • main.mysqltest failing testcase check on 8.0.45, 8.0.45 debug build
  • innodb_zip.16k, main.mysqlpump_bugs failing with a result difference, 8.0.45 debug+sanitizers build
  • main.subquery_sj_firstmatch failing with a result difference, 8.0.45 release build
  • main.lowercase_table4 timeout, 8.0.45 debug+sanitizers build
  • x.mysqlxtest_mode_ssl test command failure, 8.4.8 release build
  • connection_control.performance_schema_processlist test result difference, 8.4.8 release build
  • merge_innodb_tests-t failed once, 8.4.8 debug+sanitizers build
  • routertest_harness_net_ts_timer failed once, 8.4.8 debug build
  • rpl_nogtid.rpl_semi_sync_optimize_for_static_plugin_config failing with global-buffer-overflow under 9.6.0 debug+sanitizers build, serious, but I couldn't reproduce.
  • routertest_integration_routing_direct, routertest_integration_routing_router_require, routertest_integration_routing_sharing, and routertest_integration_routing_sharing_constrained_pools failed once under 9.6.0 debug+sanitizers build and once under 9.6.0 debug build
  • perfschema.system_events_plugin, test_service_sql_api.test_sql_stmt, main.group_by, main.index_merge_innodb, perfschema.idx_compare_metadata_locks failed once, 9.6.0 debug build
  • router.authentication_mysql_accounts, router.app_specific_metadata_v_latest, and main.ps failed once, 9.6.0 release build

Monday, December 01, 2025

Look at me, I'm an (LLM-assisted) Emacs Lisp developer now

Claude Code came out in February and I was hooked immediately. Luckily for me Anthropic introduced flat rate pricing plans very soon afterwards, or I'd have been bankrupted by pay-per-token prices by summer. I tried to channel all that newly-developed addiction to something productive, and decided to write, greenfield, some Emacs Lisp packages. I think such projects are perfectly-sized for working with Claude Code: for smaller tasks the regular chat interface worked fine (although now Claude Code handles those for me too), and for larger tasks one needs to start paying more attention to context management.

So I wrote three Emacs Lisp packages, all related to LLMs (yeah there is some infinite recursion going on here. I guess it all stops at the singularity):

All three packages have been published on MELPA (which is like npm registry, but for Elisp), and the first package (the library one) is surprisingly popular, with about 1,700 installs as of today.

Obviously I learned a lot about LLM-assisted development too but so far I am not planning to blog about that specifically, as things move faster than my ability to draft and publish and there are some very good guides out there.

Tuesday, October 28, 2025

Building and testing MySQL 8.0.44 / 8.4.7 / 9.5.0 releases on macOS

Oracle MySQL 8.0.44 / 8.4.7 / 9.5.0 are out and it's time for me to build and run their tests on macOS, Apple Silicon hardware. I have skipped the review of the previous set of releases this summer due to personal reasons, so this covers the delta from 8.0.42 / 8.4.5 / 9.3.0, out in spring.

Build

No need to use any of the bundled 3rd party libraries, and the current XCode (26.0.1) compiles all the releases. As usual, things get more interesting with Homebrew-packaged LLVM. All releases fail to build with LLVM 17 and lower versions with a bizarre CMake error, which may have to do more with the newer macOS version 26 than MySQL. LLVM 18 and 19 build fine.

8.0.44: does not build with 20 & 21:

8.4.7: builds with LLVM 20, and 21 has a different error than 8.0.44: Bug #119242 8.4.7 fails to build with clang 21.

9.5.0: builds with LLVM 20, and 21 has a different error from both 8.0.44 and 8.4.7: Bug #119246 9.5.0 compilation error with LLVM 21

The newest compiler errors are, unfortunately, expected. So, all in all, things are looking good here.

Tests

A lot of churn here over the past two releases.

Bad news:

No news, aka previously reported bugs with no to little changes:

Good news:

One-off issues:

  • merge_innodb-t on 8.0.44 and 8.4.7, debug + sanitizers build
  • gcs_xcom_control_interface on 8.0.44 and 9.5.0 release builds
  • routertest_integration_routing_direct on 8.0.44 release build
  • binlog_gtid.binlog_check_gtid_persistor_compatibility crashed on 8.4.7 debug build
  • rpl_gtid.rpl_gtids_table_disable_binlog_on_slave result difference on 8.4.7 debug build
  • innodb.trigger_function_lock_compare timeout on 8.4.7 debug build
  • routertest_integration_routing_splitting on 8.4.7 debug w/ sanitizers builds, maybe Bug #116378 routertest_integration_routing_splitting crashing under AddressSanitizer, but was not able to confirm
  • perfschema.keyring_keys result difference on 8.4.7 release build
  • json.array_index result difference on 9.5.0 debug w/ sanitizers build
  • perfschema.error_log result difference on 9.5.0 debug w/ sanitizers build
  • main.slow_log result difference on 9.5.0 debug w/ sanitizers build
  • router.app_specific_metadata_v_latest result difference on 9.5.0 release build
  • innodb_undo.truncate test assertion failure on 9.5.0 debug build

Conclusion

Without the one-offs I have 9 new, 15 unchanged, and 12 fixed bugs. At last the fixed ones outnumber the new ones, hopefully this trend will continue.

Friday, May 16, 2025

Building and testing MySQL 8.0.42 / 8.4.5 / 9.3.0 on macOS

Previously: 8.0.41 / 8.4.4 / 9.2.0

MySQL 8.0.42 / 8.4.5 / 9.3.0 are out, and as usual, I have built and tested the new releases on macOS, due to its popularity as the server OS, of course.

Build

The 8.0 series don't build with the current XCode clang because of bug 118026 (Build failed with apple clang 17). That's inconvenient, but Homebrew-packaged LLVM clang versions 14 to 18 build it fine.

Another pre-existing build bug 117299 (ddl0bulk.h:236:15: error: parameter 'prebuilt' not found in the function declaration [-Werror,-Wdocumentation]) previously only affected 8.0, but now hits 8.4. Of course, the workarounds are simple enough.

I have also reported bug 118161 (Having Homebrew-installed googletest breaks build). I suspect this is not a 8.0.42 regression, thus will not be counting towards the running bug totals.

So, for build, we have one bug with no change, and one slightly worsened. Meh, but not too bad either.

Test

Here the things are not looking as good.

Bad news first. New bugs and existing bugs with substantial regressions. The number is substantial:

Bugs with no news:

Closed bugs or bugs that have improved in some ways:

Did not test:

One-off issues that I wasn't able to repeat properly for bug reporting.

  • rpl_gtid.rpl_gtids_table_disable_binlog_on_slave on 8.0.42
  • rpl_gtid.rpl_gtid_create_select on 8.0.42
  • test_services.test_table_access on 8.0.42
  • main.system_variable_source on 8.0.42
  • innodb.trigger_function_lock_compare on 8.0.42
  • gcs_xcom_control_interface-t on 8.0.42 and 9.3.0
  • router.authentication_mysql_accounts on 9.3.0
  • routertest_integration_routing_sharing on 9.3.0
  • routertest_integration_routing_sharing_constrained_pools on 9.3.0
  • rpl_nogtid.rpl_semi_sync_uninstall_plugin on 9.3.0
  • perfschema.idx_compare_events_waits_history on 9.3.0
  • sys_vars.log_slow_admin_statements_func on 9.3.0
  • main.subquery_mat_all on 9.3.0

Conclusion

Without the one-off issues I have 13 (!) new, 15 unchanged, 2 fixed, and 1 untested bug. The positive trend of the previous set of releases is no more, and the set of open issues almost doubles in size. I hope that the next quarterly release will look better.