<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-36536015</id><updated>2026-03-24T16:25:18.133+02:00</updated><category term="mysql"/><category term="gsoc"/><category term="art"/><category term="unodb"/><category term="c++"/><category term="emacs"/><category term="llm"/><category term="rust"/><category term="arm"/><category term="dotfiles"/><category term="linux"/><category term="neon"/><category term="qsbr"/><category term="simd"/><category term="spindle-search"/><category term="spindle-search gds-dot-net"/><category term="x86_64"/><title type='text'>Laurynas Biveinis</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-36536015.post-7131151645135612381</id><published>2026-03-24T16:25:00.000+02:00</published><updated>2026-03-24T16:25:18.121+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 9.7.0 early access build on macOS</title><content type='html'>&lt;p&gt;
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: &lt;a href=&quot;https://of-code.blogspot.com/2026/01/building-and-testing-mysql-8045-848-and.html&quot;&gt;8.0.45 / 8.4.8 / 9.6.0&lt;/a&gt;).
&lt;/p&gt;
&lt;div id=&quot;outline-container-org5f2153c&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org5f2153c&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org5f2153c&quot;&gt;
&lt;p&gt;
No changes from 9.6.0: the current Xcode (26.3) builds the 9.7.0 early access build
fine, LLVM 21 still fails (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119246&quot;&gt;bug #119246&lt;/a&gt;).
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-orgd1bee83&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgd1bee83&quot;&gt;Tests&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgd1bee83&quot;&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-orgbcdcb2d&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgbcdcb2d&quot;&gt;Bad news&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgbcdcb2d&quot;&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=120088&quot;&gt;Bug #120088 Hypergraph MTR tests failing&lt;/a&gt;, although I&#39;m happy to see hypergraph in the community builds.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org59f5d40&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org59f5d40&quot;&gt;No news&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org59f5d40&quot;&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;Bug #113665 perfschema.relaylog fails with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;Bug #116394 Test binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an assert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118213&quot;&gt;Bug #118213 Test perfschema.idx_compare_mutex_instances fails under debug + sanitizers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119249&quot;&gt;Bug #119249 Router unit test setup failures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119250&quot;&gt;Bug #119250 routertest_integration_routing_sharing_constrained_pools missing connection_pool.so&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119251&quot;&gt;Bug #119251 Test rpl.rpl_seconds_behind_master failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119253&quot;&gt;Bug #119253 innodb.tablespace_encrypt_9 crashing the server with assertion failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119258&quot;&gt;Bug #119258 router integration tests failing to login&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119739&quot;&gt;Bug #119739 Test rpl_gtid.rpl_gtids_table_disable_binlog_on_slave result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119746&quot;&gt;Bug #119746 innodb.table_encrypt_4 failing with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org016db09&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org016db09&quot;&gt;Good news&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org016db09&quot;&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119252&quot;&gt;Bug #119252 Test router.response_cache failure&lt;/a&gt; no longer reproduces with 9.7.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org08e4371&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org08e4371&quot;&gt;One-off issues&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org08e4371&quot;&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;component_keyring_file.tablespace_encrypt_10&lt;/code&gt; failed once under debug build&lt;/li&gt;
&lt;li&gt;Likewise &lt;code&gt;main.func_in_mrr&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Likewise &lt;code&gt;perfschema.idx_compare_metadata_locks&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.mysqltest&lt;/code&gt; failed testcase check one under debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_semisync_gtid_tag&lt;/code&gt; crashed once under debug + sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perfschema.system_events_component&lt;/code&gt; failed once under debug + sanitizers build&lt;/li&gt;
&lt;li&gt;Likewise &lt;code&gt;perfschema.stage_mdl_global&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Likewise &lt;code&gt;innodb_undo.truncate&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/7131151645135612381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/7131151645135612381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/7131151645135612381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/7131151645135612381'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2026/03/building-and-testing-mysql-970-early.html' title='Building and testing MySQL 9.7.0 early access build on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-4857379366761747804</id><published>2026-02-10T14:13:00.000+02:00</published><updated>2026-02-10T14:13:13.096+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="llm"/><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Boring but useful: making large-scale changes on MySQL codebase with LLMs</title><content type='html'>&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
Why boring but useful large-scale?
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Pushing LLMs to the limit&amp;#x2013;like building a browser or a compiler, I guess I&#39;d be
building a database from scratch for a comparable project&amp;#x2013;is fun, it shows us
what&#39;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.&lt;/li&gt;
&lt;li&gt;Making algorithmically challenging changes is still firmly in the domain of humans.
No &quot;Add LSM tree to InnoDB. Be thorough. Do not make any mistakes.&quot; prompting here.
Although, as I&#39;m writing this, I just saw Zongzhi Chen doing exactly that and
&lt;a href=&quot;https://medium.com/@baotiao/in-2026-can-ai-modify-database-kernel-code-c7c88cb43389&quot;&gt;patching PostgreSQL with an InnoDB-like doublewrite buffer&lt;/a&gt;. Things move quickly.&lt;/li&gt;
&lt;li&gt;Making too simple changes is a waste of LLM capabilities where &lt;code&gt;sed&lt;/code&gt; would do the
same faster and cheaper.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
For a boring but useful large-scale change I picked replacing &lt;code&gt;THD *&lt;/code&gt; with &lt;code&gt;const THD
&amp;amp;&lt;/code&gt; or &lt;code&gt;THD &amp;amp;&lt;/code&gt; 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 &quot;C with classes&quot; 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 &lt;code&gt;nullptr&lt;/code&gt;. I&#39;ll try not to digress on why it&#39;s not the
right thing, C++ Core Guidelines has that (&lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-in&quot;&gt;F.16&lt;/a&gt;, &lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-inout&quot;&gt;F.17&lt;/a&gt;, &lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-consume&quot;&gt;F.18&lt;/a&gt;, &lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-forward&quot;&gt;F.19&lt;/a&gt;, and finally &lt;a href=&quot;https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#rf-ptr-ref&quot;&gt;F.60&lt;/a&gt;
for when the pointers are the right choice).
&lt;/p&gt;

&lt;p&gt;
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:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&quot;Convert &lt;code&gt;THD *&lt;/code&gt; to &lt;code&gt;THD &amp;amp;&lt;/code&gt;&quot;: yep I tried it twice, the first time it broke the
server and then couldn&#39;t debug its way out of the hole.&lt;/li&gt;
&lt;li&gt;&quot;Replace &lt;code&gt;LEX_CSTRING&lt;/code&gt; with &lt;code&gt;std::string_view&lt;/code&gt;&quot; - 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.&lt;/li&gt;
&lt;li&gt;&quot;Replace &lt;code&gt;printf&lt;/code&gt;-style formatting with &lt;code&gt;std::format&lt;/code&gt;&quot; - 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.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
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 &quot;continue&quot;
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.
&lt;/p&gt;

&lt;p&gt;
I launched Claude Code and prompted
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;orgcabb368&quot;&gt;
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: &quot;const auto bar = ... &quot;, &quot;const auto *bar = ... &quot;, &quot;auto &amp;amp;baz = ...&quot;,
&quot;const auto &amp;amp;x = ...&quot;, &quot;const auto *const y = ...&quot;, &quot;auto *const z = ...&quot;
&lt;/pre&gt;
&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
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&#39;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.
&lt;/p&gt;

&lt;p&gt;
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&#39;s allowance in three days. I tried to preserve my sanity and did not
go the route of stacked Max accounts.
&lt;/p&gt;

&lt;p&gt;
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 &lt;code&gt;nullptr&lt;/code&gt; 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&#39;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.
&lt;/p&gt;

&lt;p&gt;
&quot;If this &lt;i&gt;were&lt;/i&gt; real work&quot; - 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&#39;s
agreement with them, then sent them some &lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/commits/patched-mysql-9.1.0/&quot;&gt;patches&lt;/a&gt; and have been waiting for years but
they are still not merged, thus I will not submit this one unless asked to.
&lt;/p&gt;

&lt;p&gt;
I pushed the code to GitHub:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/commits/thd-ref/&quot;&gt;thousand commits&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/commit/365faa260e8d10fd1f95efe385dfdde56528b07d&quot;&gt;one commit&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
To conclude, with LLMs, everyone has an opinion. A vocal part of the community does
things like &lt;a href=&quot;https://openclaw.ai&quot;&gt;OpenClaw&lt;/a&gt; and &lt;a href=&quot;https://github.com/steveyegge/gastown&quot;&gt;Gas Town&lt;/a&gt;. 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.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/4857379366761747804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/4857379366761747804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4857379366761747804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4857379366761747804'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2026/02/boring-but-useful-making-large-scale.html' title='Boring but useful: making large-scale changes on MySQL codebase with LLMs'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-371505056492193895</id><published>2026-01-23T14:39:00.000+02:00</published><updated>2026-01-23T14:39:07.994+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.45, 8.4.8, and 9.6.0 on macOS</title><content type='html'>&lt;p&gt;
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.
&lt;/p&gt;
&lt;div id=&quot;outline-container-org615feeb&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org615feeb&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org615feeb&quot;&gt;
&lt;p&gt;
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 (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119238&quot;&gt;bug #119238&lt;/a&gt;),
but not 8.4.8, and so does LLVM 20 (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119239&quot;&gt;bug #119239&lt;/a&gt;). Both these issues are pre-existing.
But, 8.4.8 regressed in that it started being affected by &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119246&quot;&gt;bug #119246&lt;/a&gt; too. LLVM 21
still fails to build 9.6.0 (preexisting &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119246&quot;&gt;bug #119246&lt;/a&gt;).
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org39aab37&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org39aab37&quot;&gt;Test&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org39aab37&quot;&gt;
&lt;p&gt;
Bad news:
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119735&quot;&gt;Bug #119735 Unhandled error log warning in main.initialize-sha256&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119738&quot;&gt;Bug #119738 global-buffer-overflow on INSTALL PLUGIN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119739&quot;&gt;Bug #119739 Test rpl_gtid.rpl_gtids_table_disable_binlog_on_slave result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119746&quot;&gt;Bug #119746 innodb.table_encrypt_4 failing with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
No news aka old bad news:
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;Bug #113189 ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;Bug #113190 Several tests in routertest_integration_routing_sharing_constrained_pools fail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;Bug #113260 Client error in error log: MY-004031 - The client was disconnected &amp;#x2026;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;Bug #113665 perfschema.relaylog fails with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;Bug #113709 StrXfrmTest.ChineseUTF8MB4 failing with an AddressSanitizer error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;Bug #113722 Test main.index_merge_innodb failing with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;Bug #114892 Test XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;Bug #115480 Test innodb.log_first_rec_group failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116369&quot;&gt;Bug #116369 rpl.rpl_semi_sync_alias crashes under AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116373&quot;&gt;Bug #116373 auth_sec.acl_tables_row_locking failing with result diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;Bug #116378 routertest_integration_routing_splitting crashing under AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116385&quot;&gt;Bug #116385 Test main.mysql_upgrade_grant timing out on debug build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;Bug #116394 Test binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an assert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118171&quot;&gt;Bug #118171 Test main.mysqldump-tablespace-escape failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118185&quot;&gt;Bug #118185 Non-specific ASan error on TestLoaderGood/LoaderReadTest.load_wrong_version/0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118213&quot;&gt;Bug #118213 Test perfschema.idx_compare_mutex_instances fails under debug + sanitizers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119247&quot;&gt;Bug #119247 Test main.log_buffered-big failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119249&quot;&gt;Bug #119249 Router unit test setup failures&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119251&quot;&gt;Bug #119251 Test rpl.rpl_seconds_behind_master failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119252&quot;&gt;Bug #119252 Test router.response_cache failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119253&quot;&gt;Bug #119253 innodb.tablespace_encrypt_9 crashing the server with assertion failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119258&quot;&gt;Bug #119258 router integration tests failing to login&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Good news:
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;none! Every single bug I am tracking is present&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org5cf5172&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org5cf5172&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org5cf5172&quot;&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div id=&quot;outline-container-org7f1c289&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org7f1c289&quot;&gt;Addendum&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org7f1c289&quot;&gt;
&lt;p&gt;
A note for my future self. Issues I couldn&#39;t reliably reproduce:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;main.mysqltest&lt;/code&gt; failing testcase check on 8.0.45, 8.0.45 debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb_zip.16k&lt;/code&gt;, &lt;code&gt;main.mysqlpump_bugs&lt;/code&gt; failing with a result difference, 8.0.45
debug+sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.subquery_sj_firstmatch&lt;/code&gt; failing with a result difference, 8.0.45 release
build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.lowercase_table4&lt;/code&gt; timeout, 8.0.45 debug+sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;x.mysqlxtest_mode_ssl&lt;/code&gt; test command failure, 8.4.8 release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;connection_control.performance_schema_processlist&lt;/code&gt; test result difference, 8.4.8
release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;merge_innodb_tests-t&lt;/code&gt; failed once, 8.4.8 debug+sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_harness_net_ts_timer&lt;/code&gt; failed once, 8.4.8 debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_nogtid.rpl_semi_sync_optimize_for_static_plugin_config&lt;/code&gt; failing with
global-buffer-overflow under 9.6.0 debug+sanitizers build, serious, but I couldn&#39;t
reproduce.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_direct&lt;/code&gt;,
&lt;code&gt;routertest_integration_routing_router_require&lt;/code&gt;,
&lt;code&gt;routertest_integration_routing_sharing&lt;/code&gt;, and
&lt;code&gt;routertest_integration_routing_sharing_constrained_pools&lt;/code&gt; failed once under 9.6.0
debug+sanitizers build and once under 9.6.0 debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perfschema.system_events_plugin&lt;/code&gt;, &lt;code&gt;test_service_sql_api.test_sql_stmt&lt;/code&gt;,
&lt;code&gt;main.group_by&lt;/code&gt;, &lt;code&gt;main.index_merge_innodb&lt;/code&gt;, &lt;code&gt;perfschema.idx_compare_metadata_locks&lt;/code&gt;
failed once, 9.6.0 debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;router.authentication_mysql_accounts&lt;/code&gt;, &lt;code&gt;router.app_specific_metadata_v_latest&lt;/code&gt;,
and &lt;code&gt;main.ps&lt;/code&gt; failed once, 9.6.0 release build&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/371505056492193895/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/371505056492193895' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/371505056492193895'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/371505056492193895'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2026/01/building-and-testing-mysql-8045-848-and.html' title='Building and testing MySQL 8.0.45, 8.4.8, and 9.6.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-3315819160722945269</id><published>2025-12-01T17:12:00.000+02:00</published><updated>2026-02-10T14:25:48.732+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><category scheme="http://www.blogger.com/atom/ns#" term="llm"/><title type='text'>Look at me, I&#39;m an (LLM-assisted) Emacs Lisp developer now</title><content type='html'>&lt;p&gt;&lt;a href=&quot;https://www.claude.com/product/claude-code&quot;&gt;Claude Code&lt;/a&gt; came out in February and I was hooked immediately. Luckily for me Anthropic introduced flat rate pricing plans very soon afterwards, or I&#39;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.&lt;/p&gt;&lt;p&gt;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):&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/mcp-server-lib.el&quot;&gt;mcp-server-lib.el&lt;/a&gt;: an Emacs Lisp library for writing &lt;a href=&quot;https://en.wikipedia.org/wiki/Model_Context_Protocol&quot;&gt;Model Context Protocol (MCP)&lt;/a&gt; servers, running in Emacs. MCP is a protocol allowing LLMs to call tools and read things in a structured way.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/elisp-dev-mcp&quot;&gt;elisp-dev-mcp&lt;/a&gt;: an MCP server for developing Emacs Lisp.&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/org-mcp&quot;&gt;org-mcp&lt;/a&gt;: an MCP server for reading and updating Emacs &lt;a href=&quot;https://orgmode.org&quot;&gt;Org&lt;/a&gt; tasks.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;All three packages have been published on &lt;a href=&quot;https://melpa.org&quot;&gt;MELPA&lt;/a&gt; (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.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;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.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/3315819160722945269/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/3315819160722945269' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3315819160722945269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3315819160722945269'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2025/12/look-at-me-im-llm-assisted-emacs-lisp.html' title='Look at me, I&#39;m an (LLM-assisted) Emacs Lisp developer now'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-349974736714287734</id><published>2025-10-28T16:21:00.001+02:00</published><updated>2025-10-28T16:21:45.587+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.44 / 8.4.7 / 9.5.0 releases on macOS </title><content type='html'>&lt;p&gt;
Oracle MySQL 8.0.44 / 8.4.7 / 9.5.0 are out and it&#39;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 &lt;a href=&quot;https://of-code.blogspot.com/2025/05/building-and-testing-mysql-8042-845-930.html&quot;&gt;8.0.42 / 8.4.5 / 9.3.0&lt;/a&gt;, out in spring.
&lt;/p&gt;

&lt;div id=&quot;outline-container-org33e74d5&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org33e74d5&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org33e74d5&quot;&gt;
&lt;p&gt;
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.
&lt;/p&gt;

&lt;p&gt;
8.0.44: does not build with 20 &amp;amp; 21:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119238&quot;&gt;Bug #119238	Compilation error with clang 20&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119239&quot;&gt;Bug #119239	Compilation error with clang 21&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
8.4.7: builds with LLVM 20, and 21 has a different error than 8.0.44: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119242&quot;&gt;Bug #119242
8.4.7 fails to build with clang 21&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
9.5.0: builds with LLVM 20, and 21 has a different error from both 8.0.44 and 8.4.7:
&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119246&quot;&gt;Bug #119246	9.5.0 compilation error with LLVM 21&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
The newest compiler errors are, unfortunately, expected. So, all in all, things are
looking good here.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org3a5093b&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org3a5093b&quot;&gt;Tests&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org3a5093b&quot;&gt;
&lt;p&gt;
A lot of churn here over the past two releases.
&lt;/p&gt;

&lt;p&gt;
Bad news:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=99063&quot;&gt;Bug #99063	perfschema.idx_compare_ees_by_thread_by_error is unstable&lt;/a&gt; - open
since 8.0.19, but I only encountered it now&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119247&quot;&gt;Bug #119247	Test main.log_buffered-big failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119249&quot;&gt;Bug #119249	routertest_integration_routing_direct test failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119250&quot;&gt;Bug #119250	routertest_integration_routing_sharing_constrained_pools missing
connection_pool.so&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119251&quot;&gt;Bug #119251	Test rpl.rpl_seconds_behind_master failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119252&quot;&gt;Bug #119252	Test router.response_cache failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119253&quot;&gt;Bug #119253	innodb.tablespace_encrypt_9 crashing the server with assertion failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119254&quot;&gt;Bug #119254	Clone, x, innodb, and component_keyring tests fail on copy_file command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119258&quot;&gt;Bug #119258	routertest_integration_routing_direct tests failing to login&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
No news, aka previously reported bugs with no to little changes:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;Bug #113189	ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test
fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;Bug #113190	Several tests in
routertest_integration_routing_sharing_constrained_pools fail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;Bug #113260	Client error in error log: MY-004031 - The client was disconnected
&amp;#x2026;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;Bug #113665	perfschema.relaylog fails with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;Bug #113709	StrXfrmTest.ChineseUTF8MB4 failing with an AddressSanitizer error&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;Bug #113722	Test main.index_merge_innodb failing with a result difference&lt;/a&gt;, fixed
in 9.2.0, still happens on 8.0.44.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;Bug #115480	Test innodb.log_first_rec_group failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116369&quot;&gt;Bug #116369	rpl.rpl_semi_sync_alias crashes under AddressSanitizer&lt;/a&gt;, but only on
8.0.44, does not fail on 8.4.7, and the test looks gone in 9.5.0.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116373&quot;&gt;Bug #116373	auth_sec.acl_tables_row_locking failing with result diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;Bug #116378	routertest_integration_routing_splitting crashing under
AddressSanitizer&lt;/a&gt; - not sure whether it&#39;s fixed or became an intermittent issue.
Filing under &quot;no news&quot; for now&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;Bug #116394	Test binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an
assert&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118169&quot;&gt;Bug #118169	Test innodb.partition_upgrade_8019_mac_lctn_2_debug failing&lt;/a&gt; - might
have been downgraded from a reliable failure to an intermittent one&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118171&quot;&gt;Bug #118171	Test main.mysqldump-tablespace-escape failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118185&quot;&gt;Bug #118185	Non-specific ASan error on
TestLoaderGood/LoaderReadTest.load_wrong_version/0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118213&quot;&gt;Bug #118213	Test perfschema.idx_compare_mutex_instances fails under debug +
sanitizers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Good news:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=103338&quot;&gt;Bug #103338	Starting mysqld on same data files sometimes errors out due to
doublewrite buf&lt;/a&gt; - could not reproduce it anymore, but now there is &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119247&quot;&gt;bug 119247&lt;/a&gt; on
the same testcase&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116372&quot;&gt;Bug #116372	ODR violation reported by AddressSanitizer for plugin variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116375&quot;&gt;Bug #116375	UBSan error on Rpl_commit_order_queue_test.Simulate_mts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117297&quot;&gt;Bug #117297	Test rpl.rpl_json failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117314&quot;&gt;Bug #117314	Test innodb.tablespace_encrypt_9 failing&lt;/a&gt; - but see &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=119253&quot;&gt;bug 119253&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118170&quot;&gt;Bug #118170	Test innodb.partition_upgrade_8019_win_lctn_2_debug failing instead
of skipping on macos&lt;/a&gt; - the test actually passes (!) on 8.0.44 and 8.4.7, and is
disabled on 9.5.0.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118175&quot;&gt;Bug #118175	UBSan error at x/protocol/stream/decompression_input_stream.h&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118185&quot;&gt;Bug #118185	Non-specific ASan error on
TestLoaderGood/LoaderReadTest.load_wrong_version/0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118193&quot;&gt;Bug #118193	Test innodb.partition_upgrade_5727_mac_lctn_2 failing with a result
difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118211&quot;&gt;Bug #118211
Spec/ShareConnectionReconnectTest.change_user/ssl_modes_REQUIRED__PREFERRED_socket
test fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118212&quot;&gt;Bug #118212	Some router tests crash under AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118214&quot;&gt;Bug #118214	LifecycleTest.Simple_AllFunctions crashes under AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
One-off issues:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;merge_innodb-t&lt;/code&gt; on 8.0.44 and 8.4.7, debug + sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gcs_xcom_control_interface&lt;/code&gt; on 8.0.44 and 9.5.0 release builds&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_direct&lt;/code&gt; on 8.0.44 release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;binlog_gtid.binlog_check_gtid_persistor_compatibility&lt;/code&gt; crashed on 8.4.7 debug
build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtids_table_disable_binlog_on_slave&lt;/code&gt; result difference on 8.4.7 debug
build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb.trigger_function_lock_compare&lt;/code&gt; timeout on 8.4.7 debug build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_splitting&lt;/code&gt; on 8.4.7 debug w/ sanitizers builds,
maybe &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;Bug #116378	routertest_integration_routing_splitting crashing under
AddressSanitizer&lt;/a&gt;, but was not able to confirm&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perfschema.keyring_keys&lt;/code&gt; result difference on 8.4.7 release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;json.array_index&lt;/code&gt; result difference on 9.5.0 debug w/ sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perfschema.error_log&lt;/code&gt; result difference on 9.5.0 debug w/ sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.slow_log&lt;/code&gt; result difference on 9.5.0 debug w/ sanitizers build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;router.app_specific_metadata_v_latest&lt;/code&gt; result difference on 9.5.0 release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb_undo.truncate&lt;/code&gt; test assertion failure on 9.5.0 debug build&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org2f4e1ea&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org2f4e1ea&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org2f4e1ea&quot;&gt;
&lt;p&gt;
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.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/349974736714287734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/349974736714287734' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/349974736714287734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/349974736714287734'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2025/10/building-and-testing-mysql-8044-847-950.html' title='Building and testing MySQL 8.0.44 / 8.4.7 / 9.5.0 releases on macOS '/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-4866059926469805280</id><published>2025-05-16T15:46:00.000+03:00</published><updated>2025-05-16T15:46:53.115+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.42 / 8.4.5 / 9.3.0 on macOS</title><content type='html'>&lt;p&gt;
&lt;a href=&quot;https://of-code.blogspot.com/2025/01/building-and-testing-mysql-8041-844-920.html&quot;&gt;Previously: 8.0.41 / 8.4.4 / 9.2.0&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
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.
&lt;/p&gt;

&lt;div id=&quot;outline-container-orgc4592d8&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgc4592d8&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgc4592d8&quot;&gt;
&lt;p&gt;
The 8.0 series don&#39;t build with the current XCode clang because of &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118026&quot;&gt;bug 118026 (Build
failed with apple clang 17)&lt;/a&gt;. That&#39;s inconvenient, but Homebrew-packaged LLVM clang
versions 14 to 18 build it fine.
&lt;/p&gt;

&lt;p&gt;
Another pre-existing build &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117299&quot;&gt;bug 117299 (ddl0bulk.h:236:15: error: parameter &#39;prebuilt&#39;
not found in the function declaration [-Werror,-Wdocumentation])&lt;/a&gt; previously only
affected 8.0, but now hits 8.4. Of course, the workarounds are simple enough.
&lt;/p&gt;

&lt;p&gt;
I have also reported &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118161&quot;&gt;bug 118161 (Having Homebrew-installed googletest breaks build)&lt;/a&gt;.
I suspect this is not a 8.0.42 regression, thus will not be counting towards the
running bug totals.
&lt;/p&gt;

&lt;p&gt;
So, for build, we have one bug with no change, and one slightly worsened. Meh, but
not too bad either.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org2bf6269&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org2bf6269&quot;&gt;Test&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org2bf6269&quot;&gt;
&lt;p&gt;
Here the things are not looking as good.
&lt;/p&gt;

&lt;p&gt;
Bad news first. New bugs and existing bugs with substantial regressions. The number
is substantial:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116369&quot;&gt;https://bugs.mysql.com/bug.php?id=116369&lt;/a&gt; (rpl.rpl_semi_sync_alias crashes under
AddressSanitizer) - was 8.0-only, now 9.3.0 crashes too at a different point.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118169&quot;&gt;https://bugs.mysql.com/bug.php?id=118169&lt;/a&gt; (Test
innodb.partition_upgrade_8019_mac_lctn_2_debug failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118170&quot;&gt;https://bugs.mysql.com/bug.php?id=118170&lt;/a&gt; (Test
innodb.partition_upgrade_8019_win_lctn_2_debug failing instead of skipping on
macos)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118171&quot;&gt;https://bugs.mysql.com/bug.php?id=118171&lt;/a&gt; (Test main.mysqldump-tablespace-escape
failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118175&quot;&gt;https://bugs.mysql.com/bug.php?id=118175&lt;/a&gt; (UBSan error at
x/protocol/stream/decompression_input_stream.h)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118184&quot;&gt;https://bugs.mysql.com/bug.php?id=118184&lt;/a&gt; (UBSan errors on router tests)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118185&quot;&gt;https://bugs.mysql.com/bug.php?id=118185&lt;/a&gt; (Non-specific ASan error on
TestLoaderGood/LoaderReadTest.load_wrong_version/0)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118193&quot;&gt;https://bugs.mysql.com/bug.php?id=118193&lt;/a&gt; (Test
innodb.partition_upgrade_5727_mac_lctn_2 failing with a result difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118211&quot;&gt;https://bugs.mysql.com/bug.php?id=118211&lt;/a&gt;
(Spec/ShareConnectionReconnectTest.change_user/ssl_modes_REQUIRED__PREFERRED_socket
test fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118212&quot;&gt;https://bugs.mysql.com/bug.php?id=118212&lt;/a&gt; (Some router tests crash under
AddressSanitizer)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118213&quot;&gt;https://bugs.mysql.com/bug.php?id=118213&lt;/a&gt; (Test
perfschema.idx_compare_mutex_instances fails under debug + sanitizers)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=118214&quot;&gt;https://bugs.mysql.com/bug.php?id=118214&lt;/a&gt; (LifecycleTest.Simple_AllFunctions crashes
under AddressSanitizer)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Bugs with no news:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=103338&quot;&gt;https://bugs.mysql.com/bug.php?id=103338&lt;/a&gt; (Starting mysqld on same data files
sometimes errors out due to doublewrite buf)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;https://bugs.mysql.com/bug.php?id=113189&lt;/a&gt;
(ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;https://bugs.mysql.com/bug.php?id=113190&lt;/a&gt; (Several tests in
routertest_integration_routing_sharing_constrained_pools fail)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;https://bugs.mysql.com/bug.php?id=113260&lt;/a&gt; (Client error in error log: MY-004031 -
The client was disconnected …)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;https://bugs.mysql.com/bug.php?id=113665&lt;/a&gt; (perfschema.relaylog fails with a result
difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;https://bugs.mysql.com/bug.php?id=113709&lt;/a&gt; (StrXfrmTest.ChineseUTF8MB4 failing with
an AddressSanitizer error)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;https://bugs.mysql.com/bug.php?id=113722&lt;/a&gt; (Test main.index_merge_innodb failing with
a result difference) - was closed for 9.2.0, still happens on 8.4.5.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;https://bugs.mysql.com/bug.php?id=115480&lt;/a&gt; (Test innodb.log_first_rec_group failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116373&quot;&gt;https://bugs.mysql.com/bug.php?id=116373&lt;/a&gt; (auth_sec.acl_tables_row_locking failing
with result diff)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116375&quot;&gt;https://bugs.mysql.com/bug.php?id=116375&lt;/a&gt; (UBSan error on
Rpl_commit_order_queue_test.Simulate_mts) - no change in the current release but
already closed for the next ones, looking forward to confirming.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;https://bugs.mysql.com/bug.php?id=116378&lt;/a&gt; (routertest_integration_routing_splitting
crashing under AddressSanitizer)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;https://bugs.mysql.com/bug.php?id=116394&lt;/a&gt; (Test
binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an assert)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117297&quot;&gt;https://bugs.mysql.com/bug.php?id=117297&lt;/a&gt; (Test rpl.rpl_json failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117314&quot;&gt;https://bugs.mysql.com/bug.php?id=117314&lt;/a&gt; (Test innodb.tablespace_encrypt_9 failing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Closed bugs or bugs that have improved in some ways:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;https://bugs.mysql.com/bug.php?id=114892&lt;/a&gt; (Test
XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails) - this one is
intermittent with low enough frequency that I cannot tell whether it was fixed.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116385&quot;&gt;https://bugs.mysql.com/bug.php?id=116385&lt;/a&gt; (Test main.mysql_upgrade_grant timing out
on debug build)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Did not test:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116372&quot;&gt;https://bugs.mysql.com/bug.php?id=116372&lt;/a&gt; (ODR violation reported by
AddressSanitizer for plugin variables)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
One-off issues that I wasn&#39;t able to repeat properly for bug reporting.
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtids_table_disable_binlog_on_slave&lt;/code&gt; on 8.0.42&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtid_create_select&lt;/code&gt; on 8.0.42&lt;/li&gt;
&lt;li&gt;&lt;code&gt;test_services.test_table_access&lt;/code&gt; on 8.0.42&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.system_variable_source&lt;/code&gt; on 8.0.42&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb.trigger_function_lock_compare&lt;/code&gt; on 8.0.42&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gcs_xcom_control_interface-t&lt;/code&gt; on 8.0.42 and 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;router.authentication_mysql_accounts&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_sharing&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_sharing_constrained_pools&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_nogtid.rpl_semi_sync_uninstall_plugin&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;perfschema.idx_compare_events_waits_history&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sys_vars.log_slow_admin_statements_func&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.subquery_mat_all&lt;/code&gt; on 9.3.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgd2da68d&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgd2da68d&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgd2da68d&quot;&gt;
&lt;p&gt;
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.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/4866059926469805280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/4866059926469805280' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4866059926469805280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4866059926469805280'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2025/05/building-and-testing-mysql-8042-845-930.html' title='Building and testing MySQL 8.0.42 / 8.4.5 / 9.3.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-8231548616857795358</id><published>2025-01-29T15:16:00.000+02:00</published><updated>2025-01-29T15:16:35.310+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.41 / 8.4.4 / 9.2.0 on macOS</title><content type='html'>&lt;p&gt;
&lt;a href=&quot;https://of-code.blogspot.com/2024/10/building-and-testing-mysql-8040-843-910.html&quot;&gt;Previously: 8.0.40 / 8.4.3 / 9.1.0&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Oracle released MySQL 8.0.41 / 8.4.4 / 9.2.0, and it&#39;s time for me to build and test
it under macOS, of all things!
&lt;/p&gt;

&lt;p&gt;
But first, a detour to the last set of releases Valgrind results, because its run
took a few weeks on 9.1.0, and that&#39;s without &lt;code&gt;--big-test&lt;/code&gt;. A big part of tests timed
out, or failed randomly. There appear no errors that are diagnosed during server
operation, and the shutdown logs are way too verbose for me to try to find any memory
leaks. Perhaps 9.2.0 will fare better, and I will reduce &lt;code&gt;--parallel&lt;/code&gt; further. Will
it take two months to run? We will see!
&lt;/p&gt;

&lt;div id=&quot;outline-container-org0d53dbd&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org0d53dbd&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org0d53dbd&quot;&gt;
&lt;p&gt;
Mostly good news here, again. &lt;code&gt;-DWITH_ZLIB=bundled&lt;/code&gt; is no longer required, that&#39;s
probably due to newer XCode toolchain finally updating its zlib.
&lt;/p&gt;

&lt;p&gt;
A new build bug:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117299&quot;&gt;https://bugs.mysql.com/bug.php?id=117299&lt;/a&gt; (ddl0bulk.h:236:15: error: parameter
&#39;prebuilt&#39; not found in the function declaration [-Werror,-Wdocumentation]) - the
workaround is trivial.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
A fixed build bug:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113113&quot;&gt;https://bugs.mysql.com/bug.php?id=113113&lt;/a&gt; (Build failure with Homebrew LLVM 14-19 on
macOS) no longer happens with 8.4.4 and 9.2.0, but 8.0.41 is still affected.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
MySQL 8.0.41 does not build with LLVM 19. It could probably be fixed by backporting a
fix for MySQL 8.4.4 which is documented as &quot;Implemented the standards-compliant
&lt;code&gt;my_char_traits&amp;lt;unsigned char&amp;gt;&lt;/code&gt; for use as a drop-in replacement for
&lt;code&gt;std::char_traits&amp;lt;unsigned char&amp;gt;&lt;/code&gt;, which was deprecated in Clang 18 and removed in
Clang 19. (Bug #37273525)&quot;
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org22c0cf4&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org22c0cf4&quot;&gt;Test&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org22c0cf4&quot;&gt;
&lt;p&gt;
New bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117297&quot;&gt;https://bugs.mysql.com/bug.php?id=117297&lt;/a&gt; (Test rpl.rpl_json failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=117314&quot;&gt;https://bugs.mysql.com/bug.php?id=117314&lt;/a&gt; (Test innodb.tablespace_encrypt_9 failing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
No changes:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;https://bugs.mysql.com/bug.php?id=113260&lt;/a&gt; (Client error in error log: MY-004031 -
The client was disconnected &amp;#x2026;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116373&quot;&gt;https://bugs.mysql.com/bug.php?id=116373&lt;/a&gt; (auth_sec.acl_tables_row_locking failing
with result diff)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;https://bugs.mysql.com/bug.php?id=115480&lt;/a&gt; (Test innodb.log_first_rec_group failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;https://bugs.mysql.com/bug.php?id=113189&lt;/a&gt;
(ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;https://bugs.mysql.com/bug.php?id=113190&lt;/a&gt; (Several tests in
routertest_integration_routing_sharing_constrained_pools fail)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;https://bugs.mysql.com/bug.php?id=113709&lt;/a&gt; (StrXfrmTest.ChineseUTF8MB4 failing with
an AddressSanitizer error)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116375&quot;&gt;https://bugs.mysql.com/bug.php?id=116375&lt;/a&gt; (UBSan error on
Rpl_commit_order_queue_test.Simulate_mts)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;https://bugs.mysql.com/bug.php?id=113665&lt;/a&gt; (perfschema.relaylog fails with a result
difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116385&quot;&gt;https://bugs.mysql.com/bug.php?id=116385&lt;/a&gt; (Test main.mysql_upgrade_grant timing out
on debug build)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;https://bugs.mysql.com/bug.php?id=116378&lt;/a&gt; (routertest_integration_routing_splitting
crashing under AddressSanitizer)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;https://bugs.mysql.com/bug.php?id=113722&lt;/a&gt; (Test main.index_merge_innodb failing with
a result difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;https://bugs.mysql.com/bug.php?id=114892&lt;/a&gt; (Test
XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails) - this one I
haven&#39;t seen in a while, but it&#39;s back&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;https://bugs.mysql.com/bug.php?id=116394&lt;/a&gt; (Test
binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an assert)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Fixed bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115495&quot;&gt;https://bugs.mysql.com/bug.php?id=115495&lt;/a&gt; (&quot;Unable to read page&quot; crash on
innodb.dblwr_encrypt_recover)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116390&quot;&gt;https://bugs.mysql.com/bug.php?id=116390&lt;/a&gt; (Test
main.opt_hint_resource_group_hypergraph failing testcase check)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116391&quot;&gt;https://bugs.mysql.com/bug.php?id=116391&lt;/a&gt; (Test main.opt_hints_join_order_hypergraph
failing with a result diff)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115498&quot;&gt;https://bugs.mysql.com/bug.php?id=115498&lt;/a&gt; (Test main.opt_hints_hypergraph always
failing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Did not test:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116372&quot;&gt;https://bugs.mysql.com/bug.php?id=116372&lt;/a&gt; (ODR violation reported by
AddressSanitizer for plugin variables)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
One-off issues:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;main.join_cache_nojb&lt;/code&gt; failed once with query execution plan difference on 8.0.41
debug build.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtids_table_disable_binlog_on_slave&lt;/code&gt; failed intermittently on 8.0.41
Debug with sanitizers, 8.4.4 Debug, &amp;amp; 8.4.4 Debug with sanitizers builds. The same
happened in the previous set of releases too.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;binlog_gtid.binlog_gtid_bgc_ticket_manager&lt;/code&gt; failed once on 8.4.4 Debug build.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routertest_integration_routing_sharing_constrained_pools&lt;/code&gt; failed once in a way
that is not bug #113190 above.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_heartbeat_log_pos_4gb&lt;/code&gt; timed out once on 8.4.4 Debug with sanitizers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;binlog_gtid.binlog_check_gtid_persistor_compatibility&lt;/code&gt; failed once on 9.2.0
Debug with sanitizers.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb.trigger_function_lock_compare&lt;/code&gt; timed out once on 9.2.0 Debug with
sanitizers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org59ce43e&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org59ce43e&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org59ce43e&quot;&gt;
&lt;p&gt;
Without the one-off issues I have 2 new, 13 unchanged, 4 fixed, 1 untested bug. Much
less churn than the last time, and finally the trend is positive.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/8231548616857795358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/8231548616857795358' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/8231548616857795358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/8231548616857795358'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2025/01/building-and-testing-mysql-8041-844-920.html' title='Building and testing MySQL 8.0.41 / 8.4.4 / 9.2.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-9074091151176473220</id><published>2024-11-08T16:12:00.000+02:00</published><updated>2024-11-08T16:12:26.234+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Storing the MySQL Data Dictionary in a 3rd-Party Storage Engine</title><content type='html'>&lt;p&gt;MySQL 8.0 replaced legacy &lt;code&gt;FRM&lt;/code&gt; files with a transactional data dictionary, stored in
InnoDB. Here I&#39;ll describe how any other storage engine could become the DDSE, that
is, serve as the backend for the data dictionary, replacing InnoDB. This is purely an
internals post, and will not look into user-facing motivations and implications of
the change (which can be found &lt;a href=&quot;https://dev.mysql.com/blog-archive/mysql-8-0-data-dictionary-background-and-motivation/&quot;&gt;here&lt;/a&gt;), now will it discuss storing any internal
SE-specific data dictionary-like information in the server DD, nor should the DD
tables be confused with system tables, a distinct category.
&lt;/p&gt;

&lt;p&gt;
This is based on the experience of implementation this feature in MyRocks.
&lt;/p&gt;

&lt;p&gt;
The needed changes broadly fall into three areas:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Changes to the SE to make it able work as the DDSE&lt;/li&gt;
&lt;li&gt;Changes to the core server layer which no longer can assume InnoDB being the DDSE&lt;/li&gt;
&lt;li&gt;Changes to InnoDB so it can keep on working while not being the DDSE&lt;/li&gt;
&lt;/ul&gt;

&lt;div id=&quot;outline-container-org0909176&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org0909176&quot;&gt;Changes to the SE to make it DDSE&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org0909176&quot;&gt;
&lt;p&gt;
The DDSE must:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;be transactional&lt;/li&gt;
&lt;li&gt;be linked statically into the server&lt;/li&gt;
&lt;li&gt;know how to assign any internal IDs to DD tables&lt;/li&gt;
&lt;li&gt;implement the handlerton API for DDSEs&lt;/li&gt;
&lt;li&gt;make DD transactions durable&lt;/li&gt;
&lt;li&gt;be able to do non-locking reads&lt;/li&gt;
&lt;li&gt;support attachable transactions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The first two items are straightforward, in the motivation if not in the
implementation. The storage engine must be transactional to maintain the
transactional data dictionary. It also must be linked statically into the server, as
dynamic plugins are registered in a &lt;code&gt;mysql.plugin&lt;/code&gt; table, which is hard to access
without data dictionary. This can be done by adding &lt;code&gt;MANDATORY&lt;/code&gt; as an argument to
&lt;code&gt;MYSQL_ADD_PLUGIN&lt;/code&gt; in the &lt;code&gt;CMakeLists.txt&lt;/code&gt; for the SE.
&lt;/p&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgf759771&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgf759771&quot;&gt;Internal ID assignment&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgf759771&quot;&gt;
&lt;p&gt;
The main task for the DDSE is to know how to access the DD tables without needing to
refer to the DD. That is achieved by the DDSE hardcoding its internal IDs and any
other needed data for the DD schema metadata. To get an ID,
&lt;code&gt;handler::get_se_private_id&lt;/code&gt; is called for each DD table, allowing the DDSE to update
the passed &lt;code&gt;dd::Table&lt;/code&gt; object to set the private IDs. &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L20646C1-L20678C2&quot;&gt;For example&lt;/a&gt;:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;dd_table-&amp;gt;set_se_private_id(next_dd_index_id++);
for (auto *index : *dd_table-&amp;gt;indexes()) {
  auto &amp;amp;properties = index-&amp;gt;se_private_data();
  properties.set(&quot;index_id&quot;, next_dd_index_id++);
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
The create table implementation can then &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L10378-L10398&quot;&gt;access this metadata&lt;/a&gt; to use the allocated
IDs.
&lt;/p&gt;

&lt;p&gt;
One question may arise, why bother going through &lt;code&gt;get_se_private_id&lt;/code&gt; at all? Can&#39;t
the &lt;code&gt;CREATE TABLE&lt;/code&gt; code recognize that it&#39;s being called for a DD table, allocate the
ID itself, and store it in the passed &lt;code&gt;dd::Table&lt;/code&gt; object there? In principle, yes, it
could, but: 1) there are asserts in the server layer that the DD tables have their SE
private data set; 2) modifying passed &lt;code&gt;dd::Table&lt;/code&gt; objects for handler CREATE TABLE is
only allowed for &lt;code&gt;HTON_SUPPORTS_ATOMIC_DDL&lt;/code&gt; engines, while there is no requirement
for a DDSE to be one.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org36e34e1&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org36e34e1&quot;&gt;Handlerton API for DDSEs&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org36e34e1&quot;&gt;
&lt;p&gt;
There are several handlerton APIs that a DDSE must implement:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L62-L66&quot;&gt;dict_get_server_version&lt;/a&gt;, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L68-L72&quot;&gt;dict_set_server_version&lt;/a&gt;: read and write the server of the
DD schema in a SE-specific way. Called by the server layer during upgrades.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L74-L87&quot;&gt;ddse_dict_init&lt;/a&gt;: the name suggests that it performs any DD initialization as needed
in the DDSE. But it is also tasked with returning any extra SE-specific DD tables
and tablespaces (in the InnoDB sense) back to the server DD layer. It also has a
mode argument, with four possible values. While it may appear daunting needing to
implement DDSE initialization in four different ways, in MyRocks this function does
nothing. Not having SE-specific tables and tablespaces helps.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L95-L104&quot;&gt;dict_recover&lt;/a&gt;: also perform any DD initialization in the DD, governed by the mode
argument. The name and docs suggest that these are recovery-related actions. In
MyRocks this function does nothing.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L58-L60&quot;&gt;dict_register_dd_table_id&lt;/a&gt;: allows the DDSE to note which DD object IDs belong to
DD tables. It is up to the engine to decide how to use this information. For
instance, MyRocks checks whether a &lt;code&gt;DROP TABLE&lt;/code&gt; and similar operations. are not
executed against a DD table, for defense in depth.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L89&quot;&gt;is_dict_read_only&lt;/a&gt;: if the SE has a read only mode (InnoDB does), this allows
telling the server layer when the DD can be read but not updated. Otherwise,
&lt;code&gt;return false;&lt;/code&gt; is a great implementation.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L91-L93&quot;&gt;dict_cache_reset_tables_and_tablespaces&lt;/a&gt;: tells the DDSE to invalidate any cached
metadata about tables and tablespaces, because it is going to be reloaded anew.
This call happens in the server startup sequence right after binlog crash recovery.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/rdb_native_dd.cc#L106-L110&quot;&gt;dict_cache_reset&lt;/a&gt;: remove metadata for a single table from any internal SE caches.
Called in upgrades. No-op in MyRocks, because there is no need to do any DDSE
upgrades in MyRocks yet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgfe74ec8&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgfe74ec8&quot;&gt;Durability for DD transactions&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgfe74ec8&quot;&gt;
&lt;p&gt;
I have previously discussed &lt;a href=&quot;https://of-code.blogspot.com/2023/09/implementing-durability-in-mysql.html&quot;&gt;SE durability implementation&lt;/a&gt;, and it touches upon DD
transactions: if a transaction involves DD, it should be persisted regardless of any
reduced durability settings (&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L6791-L6792&quot;&gt;MyRocks implementation&lt;/a&gt;). While reduced durability for
user transactions may result in lost data for the last transactions before a crash,
in the case of DD it may result in desynced DD, making the whole instance nonviable,
which I strongly suspect was the cause for this requirement.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgf70800e&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgf70800e&quot;&gt;Non-locking reads for user transactions for the DD tables&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgf70800e&quot;&gt;
&lt;p&gt;
&lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; views provide read-only access to the underlying DD tables for
users. Now this access must be non-blocking, both ways: a DDL statement in progress
such as &lt;code&gt;ALTER TABLE&lt;/code&gt; must not block any &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; queries and conversely
an &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; query, if done in a session with a high transaction isolation
level, must not block any DDL statements from proceeding.
&lt;/p&gt;

&lt;p&gt;
That is implemented by a new parameter for &lt;code&gt;handler::extra&lt;/code&gt; method:
&lt;code&gt;HA_EXTRA_NO_READ_LOCKING&lt;/code&gt;. Having received this, the SE should skipping acquiring
read locks, if any, for the handler&#39;s table. MyRocks implementation: &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L15792-L15794&quot;&gt;setting&lt;/a&gt;,
&lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L15117-L15118&quot;&gt;reading&lt;/a&gt;. For InnoDB implementation, you can take a look at &lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=7464&quot;&gt;WL#7446&lt;/a&gt; (InnoDB: provide a
way to do non-locking reads), note that the parameter was named differently there.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgb2e6765&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgb2e6765&quot;&gt;Attachable transactions&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgb2e6765&quot;&gt;
&lt;p&gt;
All the DD accesses are wrapped by DD transactions. These DD transactions differ from
the regular user transactions in that they can and will happen in the middle of those
regular transactions. The server layer takes care of starting and stopping them, and
of swapping the transaction context in the thread handle. The storage engine must be
prepared to handle this swapped context correctly, that is, if it observes
&lt;code&gt;THD::ha_data == nullptr&lt;/code&gt; in the middle of a transaction, it should allocate a new
object to this field, and invalidate any cached assumptions about its contents. Once
that is ensured, add &lt;code&gt;HA_ATTACHABLE_TRX_COMPATIBLE&lt;/code&gt; to handler &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.h#L502&quot;&gt;table_flags&lt;/a&gt; return
value bitset. The server implementation design is &lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=8003&quot;&gt;WL#8003&lt;/a&gt; (Server support for
attachable transactions) and the InnoDB implementation is &lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=7828&quot;&gt;WL#7828&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org413bd87&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org413bd87&quot;&gt;Changes to the core server&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org413bd87&quot;&gt;
&lt;p&gt;
The server assumes several things about the DDSE, and also that there is exactly one
engine involved.
&lt;/p&gt;

&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;What the DDSE is&lt;/li&gt;
&lt;li&gt;Early initialization of static plugins&lt;/li&gt;
&lt;li&gt;&lt;code&gt;READ COMMITTED&lt;/code&gt; and &lt;code&gt;READ UNCOMMITTED&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Foreign keys&lt;/li&gt;
&lt;li&gt;Implicit primary keys&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TABLESPACE&lt;/code&gt; support&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handler::delete_row&lt;/code&gt; is bug-for-bug compatible with InnoDB implementation&lt;/li&gt;
&lt;li&gt;Duplicate entry or lock wait timeout?&lt;/li&gt;
&lt;li&gt;Supporting DD tables in multiple SEs&lt;/li&gt;
&lt;li&gt;Changing the DDSE of an existing instance&lt;/li&gt;
&lt;li&gt;Clone plugin compatibility&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgd78f134&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgd78f134&quot;&gt;What the DDSE is&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgd78f134&quot;&gt;
&lt;p&gt;
The DD layer is full of &lt;code&gt;ha_resolve_by_legacy_type(thd, DB_TYPE_INNODB)&lt;/code&gt; calls for
every time it needs to get the DDSE handlerton. Naturally, you&#39;ll have to grep all of
&lt;code&gt;sql&lt;/code&gt; for &lt;code&gt;DB_TYPE_INNODB&lt;/code&gt; and &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/6cd2d60a51a0967ecb81b709a857ba600a13df3b&quot;&gt;refactor out some helper function&lt;/a&gt; to return the right
handlerton for you. I wish grepping only &lt;code&gt;sql/dd&lt;/code&gt; were enough, but there is
&lt;code&gt;sql/resourcegroups&lt;/code&gt; too.
&lt;/p&gt;

&lt;p&gt;
That&#39;s not all. SQL definitions assume the engine too, the default constructor of
&lt;code&gt;Object_table_impl&lt;/code&gt; adds a hardcoded &lt;code&gt;&quot;ENGINE=InnoDB&quot;&lt;/code&gt; string, which will need
&lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/991cb6ac00ec14bb13a22e0d7046a3eb3ad1eaef&quot;&gt;patching&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgb9b4a62&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgb9b4a62&quot;&gt;Early initialization of static plugins&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgb9b4a62&quot;&gt;
&lt;p&gt;
Linking the DDSE statically into the server binary is not enough to ensure it is
initialized early enough. The initialization of early plugins is handled by
&lt;code&gt;plugin_register_builtin_and_init_core_se&lt;/code&gt; in &lt;code&gt;sql/plugin.cc&lt;/code&gt;. It has a loop where it
iterates over all known at this stage plugins and initializes some of them. You&#39;ll
have to &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/149a5a229dc67eb8e442ee07be14ecc5359c5bcf&quot;&gt;add logic to initialize your SE&lt;/a&gt; as well.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org0c4f196&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org0c4f196&quot;&gt;Transaction isolation level requirements&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org0c4f196&quot;&gt;
&lt;p&gt;
The main level used in DD operations is &lt;code&gt;READ COMMITTED&lt;/code&gt;. Luckily, this is sort of a
&quot;default&quot; isolation level for transactional engines, and even if the SE implements
something else, like snapshot isolation, it still has to map that to the levels MySQL
understands, likely to &lt;code&gt;READ COMMITTED&lt;/code&gt; again.
&lt;/p&gt;

&lt;p&gt;
But, the server data dictionary also expects the DDSE to support &lt;code&gt;READ UNCOMMITTED&lt;/code&gt;.
Even though I spent better part of the year working on this, I still don&#39;t fully
understand the reason behind it (any transaction can read its own uncommitted
changes in any isolation level in every storage engine I know about, and reading
uncommitted changes from other transactions for correctness looks suspicious). I have
tried an experiment where I patched the server to always use &lt;code&gt;READ COMMITTED&lt;/code&gt; with
InnoDB still being the DDSE, to see what breaks. And what broke was the foreign key
operations but only when there was more than one of them in a single &lt;code&gt;ALTER TABLE&lt;/code&gt;.
You have to evaluate how much of a showstopper that is for you, and whether go back
to the SE and implement &lt;code&gt;READ UNCOMMITTED&lt;/code&gt;, or patch the server to always use &lt;code&gt;READ
COMMITTED&lt;/code&gt; with DDSE.
&lt;/p&gt;

&lt;p&gt;
A further complication here is that a SE may or may not support atomic DDL
(&lt;a href=&quot;https://of-code.blogspot.com/2022/12/the-zoo-of-mysql-storage-engine-flags.html&quot;&gt;handlerton flag &lt;code&gt;HTON_SUPPORTS_ATOMIC_DDL&lt;/code&gt;&lt;/a&gt;), and the DDSE could go either way. If it
does not, then there are interim DD transaction commits in the middle of a DDL
statement, complicating this picture. I only worked on the case where the DDSE does
not support atomic DDL.
&lt;/p&gt;

&lt;p&gt;
Last but not least, if the unsupported isolation levels are strictly rejected, users
may find it surprising that their DDL statements fail if their session uses one of
the unsupported levels, for instance, if there is another engine for user tables that
does support them. Consider &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/rocksdb/ha_rocksdb.cc#L15098-L15108&quot;&gt;accepting an unsupported level&lt;/a&gt; for the scope of any DDL
statements. I am not fully certain why issue this happens at all – the attachable
transactions should run in one of the accepted levels in the DDSE – but maybe the
DDSE gets to see the DDL statement in an outer transaction first.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgd707b2b&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgd707b2b&quot;&gt;Foreign keys&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgd707b2b&quot;&gt;
&lt;p&gt;
The DD table definitions in &lt;code&gt;.cc&lt;/code&gt; files under &lt;code&gt;sql/dd/impl/tables&lt;/code&gt; feature many
foreign keys. If your SE does not support them, you&#39;ll glad to learn that the DD
schema has no referential actions, so the keys effectively serve as defense-in-depth
against incorrect operations, but their presence is optional, and omitting their
definitions &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/991cb6ac00ec14bb13a22e0d7046a3eb3ad1eaef&quot;&gt;works just fine&lt;/a&gt;. This commit also handles the hardcoded &quot;ENGINE=InnoDB&quot;
discussed above and the next two items.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org7cbdcac&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org7cbdcac&quot;&gt;Implicit primary keys&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org7cbdcac&quot;&gt;
&lt;p&gt;
Some of the DD tables, for example &lt;code&gt;mysql.index_column_usage&lt;/code&gt;, have no explicit
primary keys declared. But, they do have several unique non-NULL indexes, one of
which is promoted to a primary key. As an implementation detail, it might be hard
(and brittle) to track this promotion logic to repeat this decision correctly in the
SE. If that&#39;s the case, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/991cb6ac00ec14bb13a22e0d7046a3eb3ad1eaef&quot;&gt;patch the SQL definitions&lt;/a&gt; to make one of those unique keys a
primary key explicitly.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org4ac5dd7&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org4ac5dd7&quot;&gt;&lt;code&gt;TABLESPACE&lt;/code&gt; support&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org4ac5dd7&quot;&gt;
&lt;p&gt;
All the DD tables are created in the &lt;code&gt;mysql&lt;/code&gt; tablespace. If your SE has no notion of
tablespaces, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/991cb6ac00ec14bb13a22e0d7046a3eb3ad1eaef&quot;&gt;patch the SQL definitions&lt;/a&gt; to remove this.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgfdcfe59&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgfdcfe59&quot;&gt;&lt;code&gt;delete_row&lt;/code&gt; bug-for-bug compatibility with the DD-InnoDB interface&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgfdcfe59&quot;&gt;
&lt;p&gt;
This was a fun one. MySQL deletes rows through &lt;code&gt;handler::delete_row(const uchar
*buf)&lt;/code&gt;, where &lt;code&gt;buf&lt;/code&gt; points to either &lt;code&gt;record[0]&lt;/code&gt; or &lt;code&gt;record[1]&lt;/code&gt;. But, the reference
implementation &lt;i&gt;InnoDB does not even look at what the buf is&lt;/i&gt; and relies on a
pre-positioned cursor to delete the row. And the DD layer added a new call to
&lt;code&gt;delete_row&lt;/code&gt; that always passes &lt;code&gt;buf == record[1]&lt;/code&gt;, pointing to a memory block of
zeros. Benign with InnoDB, anything can happen with another engine. Check
&lt;code&gt;sql/dd/impl/raw/raw_record.cc&lt;/code&gt;, so that your &lt;code&gt;Raw_record::update&lt;/code&gt; &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/c018a9a3da8b8b21e5ceb6fd7a92b981c84fa918&quot;&gt;passes&lt;/a&gt;
&lt;code&gt;m_table-&amp;gt;record[0]&lt;/code&gt; instead of &lt;code&gt;m_table-&amp;gt;record[1]&lt;/code&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org3a68d75&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org3a68d75&quot;&gt;Duplicate entry or lock wait timeout&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org3a68d75&quot;&gt;
&lt;p&gt;
The data dictionary holds the statistics tables, which usually have higher volume of
writes than the rest of DD tables. They are not typical DD tables also in that it is
possible, and legal, to write statistics data for the same object from two different
threads, concurrently. One of them will win the race and the other may get
&lt;code&gt;ER_DUP_ENTRY&lt;/code&gt; error, which is then silently discarded.
&lt;/p&gt;

&lt;p&gt;
The above is true if InnoDB is the DDSE. Other engines may handle duplicate index
entries by returning a different error, for example, MyRocks returns
&lt;code&gt;ER_LOCK_WAIT_TIMEOUT&lt;/code&gt; instead and cannot be easily made to return &lt;code&gt;ER_DUP_ENTRY&lt;/code&gt;.
Thus the server has to accommodate by &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/6c58f4f18adebd15e379275b01a53d86d2bbb6d1&quot;&gt;silently discarding either error&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org7e0f473&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org7e0f473&quot;&gt;Supporting DD tables in multiple SEs&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org7e0f473&quot;&gt;
&lt;p&gt;
While only one storage engine can host the data dictionary, it still makes sense for
other storage engines to be able to have their own additional private tables in the
DD, as discussed below in the context of InnoDB. This requires some changes in the
server layer:
&lt;/p&gt;

&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Handlerton method &lt;code&gt;dict_register_dd_table_id&lt;/code&gt; needs to be &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/e1c467df45e21f181cd5df8d4c59d74d63c534cf&quot;&gt;called for the correct&lt;/a&gt;
SE. The DD layer can no longer assume the engine of a DD table, and must get the
handlerton for the &lt;code&gt;dict_register_dd_table_id&lt;/code&gt; call from the table object.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dict_init&lt;/code&gt;, &lt;code&gt;dict_recover&lt;/code&gt;, and &lt;code&gt;dict_cache_reset_tables_and_tablespaces&lt;/code&gt;, need to
be called for all participating SEs. Their implementations, especially for the
first two, must handle both cases of the SE being the DDSE and not being one. But
note that this code will have to be further adjusted if the DDSE change needs to be
supported on existing instances.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org98d7d9f&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org98d7d9f&quot;&gt;Changing the DDSE of an existing instance&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org98d7d9f&quot;&gt;
&lt;p&gt;
If you want to change the DDSE on existing instances, you&#39;ll have to design and write
the code to perform this change. I was not the main author of this part of the
project, thus I&#39;ll skip discussing it.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgf609196&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgf609196&quot;&gt;Clone&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgf609196&quot;&gt;
&lt;p&gt;
Technically not the core server, but a plugin. Clone is an InnoDB-centric plugin, but
if your storage engine already supports clone, then almost everything will work. One
thing that will not, without a larger patch for clone than I thought was worth
developing, is clone rollbacks on startup. This does not happen on successful clones,
and a failed clone instance with a non-InnoDB DDSE will just fail in a different way.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgc196526&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgc196526&quot;&gt;Changes to InnoDB&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgc196526&quot;&gt;
&lt;p&gt;
It is hard to blame InnoDB for not working straight out of the box when it does not
store the data dictionary. Several changes need to be made there:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Rewrite InnoDB-specific &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; DD view implementations&lt;/li&gt;
&lt;li&gt;Allow InnoDB to register its DD tables even when it&#39;s not the DDSE&lt;/li&gt;
&lt;li&gt;Mark DDL transactions as read-write&lt;/li&gt;
&lt;li&gt;Register DDL transactions with server 2PC coordinator&lt;/li&gt;
&lt;li&gt;Allowing UNDO tablespace truncation to run without RW workload&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org3230b52&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org3230b52&quot;&gt;Reimplementing InnoDB-specific &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; DD views.&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org3230b52&quot;&gt;
&lt;p&gt;
There are several &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; views that are specific to InnoDB, that is,
they are not server DD-layer views over DD tables: &lt;code&gt;INNODB_TABLES&lt;/code&gt;,
&lt;code&gt;INNODB_TABLESPACES&lt;/code&gt;, &lt;code&gt;INNODB_DATAFILES&lt;/code&gt;, &lt;code&gt;INNODB_COLUMNS&lt;/code&gt;, &lt;code&gt;INNODB_VIRTUAL&lt;/code&gt;. InnoDB
implements those views by opening the underlying DD tables using low-level InnoDB
APIs. Since those tables are in a different engine now, the views have to be
reimplemented (&lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/5907566c74b0e77ba6c7a21f3b0281470829b682&quot;&gt;main commit&lt;/a&gt;, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/b3552f8d8baefb3f42aac6adb46b7e7b20826f4b&quot;&gt;fix 1&lt;/a&gt;, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/34d350bbde01fa0c3c342c83fea0228ceddeeba1&quot;&gt;fix 2&lt;/a&gt;) using server layer APIs, luckily they are
rather straightforward to use:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;template &amp;lt;typename O, typename F&amp;gt;
int for_all_innodb_objects_in_dd(THD *thd, F f) {
  auto *const dc = dd::get_dd_client(thd);
  const dd::cache::Dictionary_client::Auto_releaser releaser(dc);
  std::vector&amp;lt;const O *&amp;gt; dd_objs;
  if (dc-&amp;gt;fetch_global_components(&amp;amp;dd_objs)) {
    return 1;
  }

  for (const auto *obj : dd_objs) {
    if (obj-&amp;gt;engine() != innobase_hton_name) continue;

    const auto ret = f(thd, *obj);
    if (ret) return ret;
  }

  return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
where the first template argument is &lt;code&gt;dd::Table&lt;/code&gt; or &lt;code&gt;dd::Tablespace&lt;/code&gt; and &lt;code&gt;f&lt;/code&gt; reads
the needed information and fill out the result row, possibly also looking into
partitions, if needed:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;[&amp;amp;tables](THD *thd, const dd::Table &amp;amp;table) {
  const auto table_id = table.se_private_id();
  if (dict_sys_t::is_dd_table_id(table_id)) return 0;

  if (table_id != dd::INVALID_OBJECT_ID) {
    fill_i_s_innodb_tables_row(thd, *tables, table_id);
  } else {
    assert(!table.leaf_partitions().empty());
    for (const auto *partition : table.leaf_partitions()) {
      assert(partition-&amp;gt;engine() == innobase_hton_name);
      const auto table_id = partition-&amp;gt;se_private_id();
      if (table_id != dd::INVALID_OBJECT_ID)
        fill_i_s_innodb_tables_row(thd, *tables, table_id);
    }
  }
  return 0;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orge146b2e&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orge146b2e&quot;&gt;InnoDB-specific DD tables&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orge146b2e&quot;&gt;
&lt;p&gt;
A storage engine should be allowed to have its private DD tables even if it is not
the DDSE of the instance. InnoDB in particular needs its own tables in &lt;code&gt;mysql&lt;/code&gt;
schema: &lt;code&gt;innodb_dynamic_metadata&lt;/code&gt;, &lt;code&gt;innodb_table_stats&lt;/code&gt;, &lt;code&gt;innodb_index_stats&lt;/code&gt;, and
&lt;code&gt;innodb_ddl_log&lt;/code&gt;. They get created and registered in &lt;code&gt;ddse_dict_init&lt;/code&gt; handlerton
method implementation and the handler method &lt;code&gt;get_se_private_data&lt;/code&gt; will be called for
them too.
&lt;/p&gt;

&lt;p&gt;
There&#39;s more to it if DDSE changes need to be considered. The private data for DD
tables in InnoDB is table ID, index ID, B-tree root page ID, etc. The first two are
assigned sequentially. If InnoDB is not the DDSE, a naive implementation would give
out the IDs that belong to different tables when InnoDB is the DDSE. To avoid this
can of worms, it is prudent to play it safe and make sure that in both cases the same
IDs are assigned to the private InnoDB DD tables. Last but not least, one of the
InnoDB private data pieces assigned in advance is the B-tree root page ID, which must
be in sync to what the underlying code actually will do at a later point. And that
varies with &lt;code&gt;innodb_page_size&lt;/code&gt;, so make sure to test and handle all possible settings
for this system variable. Everything discussed in this paragraphs is handled &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/fb-mysql-8.0.32/storage/innobase/handler/ha_innodb.cc#L15179-L15226&quot;&gt;here&lt;/a&gt; and
also in &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/fb-mysql-8.0.32/storage/innobase/dict/dict0crea.cc#L75-L100&quot;&gt;dict_table_build_def&lt;/a&gt; with a &lt;code&gt;btr_create&lt;/code&gt; &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/innobase/btr/btr0btr.cc#L875-L918&quot;&gt;debugging counterpart&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org25b2f54&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org25b2f54&quot;&gt;Mark DDL transactions as read-write&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org25b2f54&quot;&gt;
&lt;p&gt;
For some DDL operations, InnoDB did not bother marking their transactions as
read-write in the DDL implementation proper, because the operation involved a write
to a DD table in InnoDB anyway, taking care of that RW bit. With the DD table being
in another SE, the DDL transaction incorrectly becomes RO in InnoDB, which had the
effect of skipping the &lt;code&gt;prepare&lt;/code&gt; call in the 2PC, breaking crash recovery. The
existing &lt;code&gt;handler::mark_trx_read_write&lt;/code&gt; fails to work here, being a private method. I
ended up a copy-paste-shortening it to a new helper &lt;code&gt;ha_innodb::mark_trx_rw&lt;/code&gt;, which
is called from the various InnoDB DDL entry points (&lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/caf6a09373874a2706076a505178ef35bd1ea48e#diff-2b46b0d944b235431b9269c4e8b717524fccc2119c171fd3d01fd193198bf03b&quot;&gt;commit&lt;/a&gt;):
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;/** Mark transaction as read-write in the server layer.
Normally this is handled by handler::mark_trx_read_write, but when InnoDB is not
the DDSE (and transactions do not call that method many times), the few
remaining calls happen too early, when the transaction is not started yet, or
with an incompatible table_share value.
@param  thd     thread handle */
void mark_trx_rw(THD &amp;amp;thd) {
  auto &amp;amp;ha_info = thd.get_ha_data(innodb_hton_ptr-&amp;gt;slot)-&amp;gt;ha_info[0];
  if (ha_info.is_started())
    ha_info.set_trx_read_write();
}
// ...
if (!innobase_is_ddse()) {
  mark_trx_rw(*thd);
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org8cff937&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org8cff937&quot;&gt;Register DDL transactions with server 2PC coordinator&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org8cff937&quot;&gt;
&lt;p&gt;
With binlog disabled, when InnoDB is the DDSE, and it is, for example, creating an
InnoDB table, it correctly assumes that it is the sole engine in this transaction and
does not bother to register itself with the server 2PC coordinator. This assumption
does not hold when InnoDB is asked to create its own table when it&#39;s not InnoDB.
&lt;/p&gt;

&lt;p&gt;
Fixing this consists of adding numerous instances of
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;if (!innobase_is_ddse()) {
  innobase_register_trx(hton, thd, trx);
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
to the InnoDB DDL entry points (&lt;a href=&quot;https://github.com/facebook/mysql-5.6/commit/caf6a09373874a2706076a505178ef35bd1ea48e#diff-2b46b0d944b235431b9269c4e8b717524fccc2119c171fd3d01fd193198bf03b&quot;&gt;same commit as for the previous item&lt;/a&gt;).
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgf3445dc&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;orgf3445dc&quot;&gt;GTID persistence with binlog disabled&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-orgf3445dc&quot;&gt;
&lt;p&gt;
If binlog is disabled, InnoDB persists the transaction GTID info itself. This logic
needed some &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/innobase/handler/ha_innodb.cc#L20267-L20271&quot;&gt;tweaking&lt;/a&gt;.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org0bf2cad&quot; class=&quot;outline-3&quot;&gt;
&lt;h3 id=&quot;org0bf2cad&quot;&gt;Allowing UNDO tablespace truncation to run without RW workload&lt;/h3&gt;
&lt;div class=&quot;outline-text-3&quot; id=&quot;text-org0bf2cad&quot;&gt;
&lt;p&gt;
With DDSE being another engine, InnoDB purge may get stuck and leave undo tablespaces
untruncated. After I recovered from the initial &quot;huh? Why is there a relationship
between purge and DD?&quot;, I found that undo tablespace truncation runs only if there is
something to purge (makes sense, doesn&#39;t it?). In the case of executing &lt;code&gt;DROP UNDO
TABLESPACE&lt;/code&gt;, InnoDB the DDSE would execute some read-write DD transactions,
potentially creating something to purge. If it&#39;s not the DDSE, no actual writes to
InnoDB happen, it has nothing to purge, consequently never getting to the undo
tablespace truncation and the final drop.
&lt;/p&gt;

&lt;p&gt;
One way to address this is to &lt;a href=&quot;https://github.com/facebook/mysql-5.6/blob/8d824c2ed8762c5d4d27abf9e5e456795cb34621/storage/innobase/srv/srv0srv.cc#L3079-L3083&quot;&gt;call&lt;/a&gt; &lt;code&gt;trx_purge_truncate_undo_spaces&lt;/code&gt; from
&lt;code&gt;srv_do_purge&lt;/code&gt;. Doing that unconditionally if InnoDB is not the DDSE works, but might
be less than optimal.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org44a90cd&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org44a90cd&quot;&gt;Testing&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org44a90cd&quot;&gt;
&lt;p&gt;
If your branch of MySQL needs to support both InnoDB and your SE as DDSEs, one way to
do MTR testing for DDSE regressions is to have a server variable to choose the DDSE
(which is likely what you&#39;ll already have if you need two support both DDSEs), and
some MTR include files to skip some tests with one or the other choice. Then adding
&lt;code&gt;--mysqld​=--ddse-var​=non-default-one&lt;/code&gt; to MTR invocations will do the trick. Any
failing tests then can be saved separately with &lt;code&gt;--initialize --mysqld​=--ddse-var&lt;/code&gt; in
their option files and added as regression tests to the main testsuite runs.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orge03e467&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orge03e467&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orge03e467&quot;&gt;
&lt;p&gt;
A checklist for everything discussed above:
&lt;/p&gt;

&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Changes to the SE to make it able work as the DDSE
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;be transactional&lt;/li&gt;
&lt;li&gt;be linked statically into the server&lt;/li&gt;
&lt;li&gt;know how to assign any internal IDs to DD tables&lt;/li&gt;
&lt;li&gt;implement the handlerton API for DDSEs&lt;/li&gt;
&lt;li&gt;make DD transactions durable&lt;/li&gt;
&lt;li&gt;be able to do non-locking reads&lt;/li&gt;
&lt;li&gt;support attachable transactions&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Changes to the core server layer which no longer can assume InnoDB being the DDSE
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;What the DDSE is&lt;/li&gt;
&lt;li&gt;Early initialization of static plugins&lt;/li&gt;
&lt;li&gt;&lt;code&gt;READ COMMITTED&lt;/code&gt; and &lt;code&gt;READ UNCOMMITTED&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Foreign keys&lt;/li&gt;
&lt;li&gt;Implicit primary keys&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TABLESPACE&lt;/code&gt; support&lt;/li&gt;
&lt;li&gt;&lt;code&gt;handler::delete_row&lt;/code&gt; is bug-for-bug compatible with InnoDB implementation&lt;/li&gt;
&lt;li&gt;Duplicate entry or lock wait timeout?&lt;/li&gt;
&lt;li&gt;Supporting DD tables in multiple SEs&lt;/li&gt;
&lt;li&gt;Changing the DDSE of an existing instance&lt;/li&gt;
&lt;li&gt;Clone plugin compatibility&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Changes to InnoDB so it can keep on working while not being the DDSE
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Rewrite InnoDB-specific &lt;code&gt;INFORMATION_SCHEMA&lt;/code&gt; DD view implementations&lt;/li&gt;
&lt;li&gt;Allow InnoDB to register its DD tables even when it&#39;s not the DDSE&lt;/li&gt;
&lt;li&gt;Mark DDL transactions as read-write&lt;/li&gt;
&lt;li&gt;Register DDL transactions with server 2PC coordinator&lt;/li&gt;
&lt;li&gt;Allowing UNDO tablespace truncation to run without RW workload&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;

&lt;li&gt;Testing&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org5799b97&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org5799b97&quot;&gt;Reference&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org5799b97&quot;&gt;
&lt;p&gt;
Oracle design documents:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=6380&quot;&gt;WL#6380&lt;/a&gt; (Formulate framework for API for DD)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=6394&quot;&gt;WL#6394&lt;/a&gt; (Bootstrap code for new DD)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=6599&quot;&gt;WL#6599&lt;/a&gt; (New Data Dictionary and I_S integration)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=7464&quot;&gt;WL#7464&lt;/a&gt; (InnoDB: provide a way to do non-locking reads)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=7828&quot;&gt;WL#7828&lt;/a&gt; (InnoDB: attachable transaction support)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=8003&quot;&gt;WL#8003&lt;/a&gt; (Server support for attachable transactions)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Blog posts:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://dev.mysql.com/blog-archive/bootstrapping-the-transactional-data-dictionary/&quot;&gt;https://dev.mysql.com/blog-archive/bootstrapping-the-transactional-data-dictionary/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/9074091151176473220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/9074091151176473220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/9074091151176473220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/9074091151176473220'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/11/storing-mysql-data-dictionary-in-3rd.html' title='Storing the MySQL Data Dictionary in a 3rd-Party Storage Engine'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-7369408778281508730</id><published>2024-10-22T16:18:00.000+03:00</published><updated>2024-10-22T16:18:38.083+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>A MySQL 9.1.0 branch with patches</title><content type='html'>&lt;p&gt;
Following-up on the previous &lt;a href=&quot;https://of-code.blogspot.com/2024/07/a-mysql-900-branch-with-patches.html&quot;&gt;MySQL 9.0.0 branch with patches&lt;/a&gt;, I have rebased them on
9.1.0: &lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/tree/patched-mysql-9.1.0&quot;&gt;patched-mysql-9.1.0&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
The set of the patches is the same as for 9.0.0: it improves AddressSanitizer support
and fixes/improves clone plugin to support a second transactional storage engine:
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115120&quot;&gt;Bug 115120&lt;/a&gt;: Provide memory debugging macro implementations for
AddressSanitizer.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109922&quot;&gt;Bug 109922&lt;/a&gt;: SEs do not coordinate clone rollbacks on instance startup.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109920&quot;&gt;Bug 109920&lt;/a&gt;: SEs cannot add to clone data size estimates.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109919&quot;&gt;Bug 109919&lt;/a&gt;: Clone plugin does not support arbitrary length &lt;code&gt;O_DIRECT&lt;/code&gt;
files.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=107715&quot;&gt;Bug 107715&lt;/a&gt;: Multiple SE clone not calling &lt;code&gt;clone_end&lt;/code&gt; after mixed
&lt;code&gt;clone_begin&lt;/code&gt; failure/success.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106750&quot;&gt;Bug 106750&lt;/a&gt;: Some clone tests needlessly marked as Linux-only.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106737&quot;&gt;Bug 106737&lt;/a&gt;: Wrong SE called to ack clone application if &amp;gt;1 SE.&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/7369408778281508730/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/7369408778281508730' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/7369408778281508730'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/7369408778281508730'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/10/a-mysql-910-branch-with-patches.html' title='A MySQL 9.1.0 branch with patches'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-4935775961316816291</id><published>2024-10-18T17:03:00.000+03:00</published><updated>2024-10-18T17:03:58.664+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.40 / 8.4.3 / 9.1.0 on macOS</title><content type='html'>&lt;p&gt;
Congrats to Oracle friends with MySQL 8.0.40 / 8.4.3 / 9.1.0 releases! Let&#39;s continue
my blog post series on builds and tests on macOS (the previous post for MySQL 8.0.38 /
8.4.1 / 9.0.0 is &lt;a href=&quot;https://of-code.blogspot.com/2024/07/building-and-testing-mysql-8038-841-900.html&quot;&gt;here&lt;/a&gt;. I skipped the emergency hotfixes 8.0.39 / 8.4.2 / 9.0.1).
&lt;/p&gt;

&lt;div id=&quot;outline-container-orgc6e95bf&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgc6e95bf&quot;&gt;Build&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgc6e95bf&quot;&gt;
&lt;p&gt;
Mostly good news here. XCode 16 works (8.4.3 &amp;amp; 9.10 need
&lt;code&gt;-Wno-unused-const-variable&lt;/code&gt;), and so does LLVM 18. The very recent LLVM 19 release
will need fixes for the new errors (and not only warnings which could be disabled),
but that&#39;s expected. Homebrew LLVM still needs the workaround to avoid mixing system
and Homebrew LLVM static linker utilities (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113113&quot;&gt;Bug #113113 Build failure with Homebrew
LLVM 14-19 on macOS&lt;/a&gt;). All releases build with maximum system libraries, good.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgf68abb2&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgf68abb2&quot;&gt;Test&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgf68abb2&quot;&gt;
&lt;p&gt;
Many changes here. Several existing bugs have been fixed, but there are also new
regressions. As usual, I tested Release, Debug, and Debug+ASan+UBSan configurations.
&lt;/p&gt;

&lt;p&gt;
New bugs
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116369&quot;&gt;Bug #116369 rpl.rpl_semi_sync_alias crashes under AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116371&quot;&gt;Bug #116371 global-buffer-overflow AddressSanitizer error on
clone.remote_basic_replace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116373&quot;&gt;Bug #116373 auth_sec.acl_tables_row_locking failing with result diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116375&quot;&gt;Bug #116375 UBSan error on Rpl_commit_order_queue_test.Simulate_mts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116378&quot;&gt;Bug #116378 routertest_integration_routing_splitting crashing under
AddressSanitizer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116385&quot;&gt;Bug #116385 Test main.mysql_upgrade_grant timing out on debug build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116389&quot;&gt;Bug #116389 innodb.sdi failing with a result diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116390&quot;&gt;Bug #116390 Test main.opt_hint_resource_group_hypergraph failing testcase check&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116391&quot;&gt;Bug #116391 Test main.opt_hints_join_order_hypergraph failing with a result diff&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116394&quot;&gt;Bug #116394 Test binlog_gtid.binlog_gtid_binlog_recovery_errors crashes with an
assert&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Little or no changes
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;Bug #113260 Client error in error log: MY-004031 - The client was disconnected &amp;#x2026;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;Bug #113665 perfschema.relaylog fails with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;Bug #115480 Test innodb.log_first_rec_group failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;Bug #113709 StrXfrmTest.ChineseUTF8MB4 failing with an AddressSanitizer error&lt;/a&gt; still
present in 8.0.40.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;Bug #113190 Several tests in
routertest_integration_routing_sharing_constrained_pools fail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=103338&quot;&gt;Bug #103338 Starting mysqld on same data files sometimes errors out due to
doublewrite buf&lt;/a&gt;, presenting as flaky &lt;code&gt;main.log_buffered-big&lt;/code&gt; test.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;Bug #113189 ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test
fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115495&quot;&gt;Bug #115495 &quot;Unable to read page&quot; crash on innodb.dblwr_encrypt_recover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;Bug #113722 Test main.index_merge_innodb failing with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115497&quot;&gt;Bug #115497 Test main.alter_table-big_myisam failure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Fixed and no longer reproducing bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113703&quot;&gt;Bug #113703 Test innodb.ddl_kill fails under Sanitizer build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115482&quot;&gt;Bug #115482: Test main.window_jsonaggs failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;Bug #113023 mysql-test/include/wait_for_pattern_in_file.inc incompatible with
Homebrew Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115479&quot;&gt;Bug #115479 main.partition_innodb_tablespace not masking temp directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115481&quot;&gt;Bug #115481 Test main.window_functions failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114888&quot;&gt;Bug #114888 Test innodb.parallel_read_kill always fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;Bug #114892 Test XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113710&quot;&gt;Bug #113710 Spec/HttpClientSecureTest.ensure/default_client_cipher_succeeds ASan
error&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orge7f580e&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orge7f580e&quot;&gt;Totals&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orge7f580e&quot;&gt;
&lt;p&gt;
To sum up the existing build &amp;amp; test bugs, we have 10 new, 11 unchanged, and 8 fixed bugs.
A lot of churn, and still plus two regressions total.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org38ac5d5&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org38ac5d5&quot;&gt;Newer tooling&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org38ac5d5&quot;&gt;
&lt;p&gt;
I have also logged two bugs which seem to be new classes of errors from newer tooling
instead of being MySQL regressions, i.e. they are very likely present in older
versions too. These I don&#39;t count in the above, but will start doing so from the next
releases:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;XCode 16 AddressSanitizer started catching &lt;a href=&quot;https://en.cppreference.com/w/cpp/language/definition&quot;&gt;ODR&lt;/a&gt; violations, resulting in &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116372&quot;&gt;Bug #116372
ODR violation reported by AddressSanitizer for plugin variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;LLVM 18 UndefinedBehaviorSanitizer also started diagnosing something that was not
caught by earlier versions: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=116396&quot;&gt;Bug #116396 LLVM 18 UBSan errors on server bootstrap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgab3f381&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgab3f381&quot;&gt;Valgrind&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgab3f381&quot;&gt;
&lt;p&gt;
I have been complaining that running Valgrind is excessively slow, and that there was
an error present on every test (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115229&quot;&gt;Bug #115229 pwrite(buf) points to uninitialised
byte(s) in os_fusionio_get_sector_size()&lt;/a&gt;). The good news is that this bug has been
fixed, making the Valgrind runs actually usable now. I have started one for 9.1.0,
will see how far along it goes.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org6737f71&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org6737f71&quot;&gt;One-off issues that I couldn&#39;t handle better&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org6737f71&quot;&gt;
&lt;p&gt;
Stuff I couldn&#39;t repeat reliably or at all, just dumping it here in case I have to
reference it next time.
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;rpl_nogtid.rpl_semi_sync_non_group_commit_deadlock&lt;/code&gt; 8.0.40 Debug+San reports
&lt;code&gt;odr-violation&lt;/code&gt; on &lt;code&gt;ReplSemiSyncBase::kPacketMagicNum&lt;/code&gt;, does not reproduce running
individually&lt;/li&gt;
&lt;li&gt;&lt;code&gt;binlog.binlog_mysqlbinlog_raw&lt;/code&gt; failed once on 8.0.40 Debug+San (L77 &lt;code&gt;copy_file&lt;/code&gt;
error)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtids_table_disable_binlog_on_slave&lt;/code&gt; failed once on 8.4.3 Debug+San
build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.index_merge_innodb_hypergraph&lt;/code&gt; failed once on 8.4.3 Debug+San build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb.trigger_function_lock_compare&lt;/code&gt; timed out once there&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auth_sec.grant_as_ddl&lt;/code&gt; failed once 8.4.3 Release build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rpl_gtid.rpl_gtids_table_disable_binlog_on_slave&lt;/code&gt; failed once on 9.1.0 Debug+San
build&lt;/li&gt;
&lt;li&gt;&lt;code&gt;merge_innodb_tests-t&lt;/code&gt; failed once on 9.1.0 Debug+San&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.lock_backup&lt;/code&gt; failed once 9.1.0 with MTR thread id masking clobbering error
number&lt;/li&gt;
&lt;li&gt;&lt;code&gt;innodb.trigger_function_lock_compare&lt;/code&gt; failed once on 9.1.0 Debug&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgd7ac7b3&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgd7ac7b3&quot;&gt;Conclusion&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgd7ac7b3&quot;&gt;
&lt;p&gt;
I am happy to see that some of the bugs are getting fixed, but the trend is still going the wrong way, and I miss the
fully-clean mid-8.0 releases.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/4935775961316816291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/4935775961316816291' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4935775961316816291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4935775961316816291'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/10/building-and-testing-mysql-8040-843-910.html' title='Building and testing MySQL 8.0.40 / 8.4.3 / 9.1.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-2137899140217760839</id><published>2024-10-10T16:06:00.000+03:00</published><updated>2024-10-10T16:06:24.309+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="emacs"/><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Emacs Projectile Tweaks for MySQL Development </title><content type='html'>&lt;p&gt;
I am using Emacs with &lt;a href=&quot;https://projectile.mx&quot;&gt;Projectile&lt;/a&gt; (besides other packages) for MySQL development.
Here&#39;s a couple of little tweaks to save a few keystrokes here and there:
&lt;/p&gt;

&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Visit (which in Emacs parlance means open) the MTR test file, by its MTR name
instead of file path:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-emacs-lisp&quot;&gt;;; This is a not a MySQL-specific implementation of `projectile-find-test-file&#39;.
;; That function is meant for jumping from a source file to its test file.
;; TODO(laurynas): this is not an exhaustive implementation for all locations
;; test files can reside. Add them as the need arises.
(defun my-visit-mtr-test ()
  &quot;Input MySQL MTR test name and visit it.&quot;
  (interactive)
  (let* ((input (read-string &quot;MySQL MTR test name: &quot;))
         ;; TODO(laurynas): error checking
         (parts (split-string input &quot;\\.&quot;))
         (suite-name (car parts))
         (test-in-suite (concat &quot;t/&quot; (cadr parts) &quot;.test&quot;))
         (test-root (concat (projectile-project-root) &quot;mysql-test/&quot;))
         (file-path (if (string= suite-name &quot;main&quot;)
                        (concat test-root test-in-suite)
                      (concat test-root &quot;suite/&quot; suite-name &quot;/&quot;
                              test-in-suite))))
    (find-file file-path)))

(define-key projectile-command-map &quot;M&quot; #&#39;my-visit-mtr-test)
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
The last line binds this command to M in the Projectile command map, so if your
Projectile keybinding prefix is &lt;code&gt;C-c p&lt;/code&gt; (&lt;code&gt;C&lt;/code&gt; is Ctrl in case non-Emacs users are
still reading), you can do &lt;code&gt;C-c p M&lt;/code&gt; to invoke it.
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Register .test and .result files as &quot;other file types&quot; for each other. This way
&lt;code&gt;projectile-find-other-file&lt;/code&gt; (at e.g. &lt;code&gt;C-c p a&lt;/code&gt;) can be used for quick jumping
between tests and their results:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-emacs-lisp&quot;&gt;(add-to-list &#39;projectile-other-file-alist &#39;(&quot;test&quot; &quot;result&quot;))
(add-to-list &#39;projectile-other-file-alist &#39;(&quot;result&quot; &quot;test&quot;))
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
If I think of more utilities, I&#39;ll try not to forget to update this post.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/2137899140217760839/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/2137899140217760839' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/2137899140217760839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/2137899140217760839'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/10/emacs-projectile-tweaks-for-mysql.html' title='Emacs Projectile Tweaks for MySQL Development '/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-2358534392792013918</id><published>2024-09-06T17:09:00.001+03:00</published><updated>2024-09-06T17:09:14.185+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Running Perl-using MTR tests for fb-mysql under macOS</title><content type='html'>The headline is slightly misleading. Oracle MySQL has several Perl-using MTR tests,
the whole MTR framework is Perl-based, and those tests run fine out of the box (with
an occasional &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;bug&lt;/a&gt;). However, &lt;a href=&quot;https://github.com/facebook/mysql-5.6/&quot;&gt;fb-mysql&lt;/a&gt; has additional tests that call the Random Query
Generator under the hood, and these tests don&#39;t work out of the box under macOS.
&lt;/p&gt;

&lt;p&gt;
Here&#39;s what I had to do to get them working:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;orgb80678c&quot;&gt;
# mysql-client default version is 9.0 now, and you&#39;ll get the wrong auth plugin error
brew install perl mysql-client@8.0

# TODO: does not survive upgrades, do what the Perl Homebrew formula advises with
# local::lib

/opt/homebrew/opt/perl/bin/cpan DBI
/opt/homebrew/opt/perl/bin/cpan JSON
/opt/homebrew/opt/perl/bin/cpan Expect

# Adjust path only for compilation below. For now I don&#39;t need it globally
export PATH=&quot;/opt/homebrew/opt/mysql-client/bin:$PATH&quot;

# Run the following command and expect it to fail with the error as in
# https://stackoverflow.com/questions/53277884/installation-of-dbdmysql-fails-with-symbol-not-found-on-osx-mojave
/opt/homebrew/opt/perl/bin/cpan DBD::mysql

# Now go to ~/.cpan/build/DBD-mysql-&amp;lt;latest&amp;gt; and do:
perl Makefile.PL \
     --libs=&quot;-L/opt/homebrew/opt/mysql-client/lib -L/opt/homebrew/lib -lmysqlclient -lz -lzstd -lssl -lcrypto -lresolv&quot;
sudo make install
&lt;/pre&gt;

&lt;p&gt;
And now:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;orgd23adba&quot;&gt;
[  5%] rocksdb.rqg_runtime &#39;rocksdb_ddse&#39;       w4  [ pass ]  41533
&lt;/pre&gt;

&lt;p&gt;
Success! Stay tuned for getting Python tests running too.
&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/2358534392792013918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/2358534392792013918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/2358534392792013918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/2358534392792013918'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/09/running-perl-using-mtr-tests-for-fb.html' title='Running Perl-using MTR tests for fb-mysql under macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-1790441687217818747</id><published>2024-08-23T16:01:00.000+03:00</published><updated>2024-08-23T16:01:17.311+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>A README for my MySQL development tooling</title><content type='html'>&lt;p&gt;Over the years I have written and borrowed various bits of scripts and configuration files to make MySQL development easier by configuring and automating things. Having written &lt;a href=&quot;https://of-code.blogspot.com/2024/01/introducing-patch2testlist-for-mysql.html&quot;&gt;patch2testlist&lt;/a&gt; a few months ago, I figured that now I have at least one thing that should work not only on my machine. Thus I put together a &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/README.md&quot;&gt;README&lt;/a&gt; for MySQL-related stuff in my dotfiles, also included below.&lt;/p&gt;
&lt;h1&gt;My MySQL Development Tools&lt;/h1&gt;

&lt;h2&gt;Tool configuration&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/vilniusdb/.clangd&quot;&gt;clangd&lt;/a&gt;:
I am so glad C++ finally got universal IDE tooling and
&lt;a href=&quot;https://clangd.llvm.org&quot;&gt;clangd&lt;/a&gt; is very useful for MySQL development.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/vilniusdb/.dir-locals.el&quot;&gt;Emacs&lt;/a&gt;:
my primary Emacs config is
&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/tree/master/emacs/.emacs.d&quot;&gt;elsewhere&lt;/a&gt;,
while this is a directory-local config that takes effect in the source trees.
It prevents creating spurious &lt;code&gt;.ispell.dict&lt;/code&gt; files, sets the C++ style to
Google, and makes &lt;a href=&quot;https://magit.vc&quot;&gt;Magit&lt;/a&gt;
(&lt;a href=&quot;https://github.com/alphapapa/magit-todos&quot;&gt;magit-todos&lt;/a&gt; actually) exclude 3rd
party TODO comments.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/vilniusdb/CPPLINT.cfg&quot;&gt;cpplint&lt;/a&gt;:
&lt;a href=&quot;https://github.com/cpplint/cpplint&quot;&gt;cpplint&lt;/a&gt; is still marginally useful with
MySQL sources.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I symlink these into the parent directory of all the source trees.&lt;/p&gt;

&lt;h2&gt;Could be useful to you&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/usr/bin/patch2testlist&quot;&gt;patch2testlist&lt;/a&gt;:
for a given patch, print a list of MTR tests to run to cover the test changes
in the patch. Introduced in its &lt;a href=&quot;https://of-code.blogspot.com/2024/01/introducing-patch2testlist-for-mysql.html&quot;&gt;own blog
post&lt;/a&gt;.
Unlike the scripts below, &lt;code&gt;patch2testlist&lt;/code&gt; is standalone and works without the
zsh utility functions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Useful to me&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/.zsh.d/rc/mysql-work.sh&quot;&gt;mysql-work.sh&lt;/a&gt;:
a shell initialization script that sets up environment variables and helper
functions to configure, build, &amp;amp; test various MySQL versions on macOS and
Linux. For example, &lt;code&gt;$MY8037D&lt;/code&gt; will expand to CMake options for a debug build
of MySQL 8.0.37. As for the functions, among others, &lt;code&gt;mysql_build&lt;/code&gt; will
configure and build a given tree, and &lt;code&gt;rmtr&lt;/code&gt; will incrementally build and run
MTR tests with libeatmydata. This script adds various warning disable flags so
that older unpatched trees can be built with newer compilers within reason. It
also absorbs bug workarounds and complications related to build environments,
for example, different MySQL versions need both OpenSSL 1.1 and 3 installed,
which then in turn results in build issues if both versions are present
simultaneously. This script is not usable without its &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/tree/master/mysql-work/.zsh.d/functions&quot;&gt;zsh utility
functions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/usr/bin/fetchworksrc&quot;&gt;fetchworksrc&lt;/a&gt;:
fetch all remotes for Git repos in &lt;code&gt;WORK_REPOS_TO_PULL&lt;/code&gt; environment variable;
pull all the worktrees in &lt;code&gt;WORK_TREES_TO_UPDATE&lt;/code&gt; one and do incremental
builds. This script runs at midnight on my work machine. There are some
quality of life embellishments such as skipping the the build if the machine
is a laptop on battery and managing Homebrew OpenSSL version incompatibilities
in builds. Again, this script is not usable without its &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/tree/master/mysql-work/.zsh.d/functions&quot;&gt;zsh utility
functions&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;zsh function library&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/tree/master/mysql-work/.zsh.d/functions&quot;&gt;This
directory&lt;/a&gt;.
One file per function as zsh requires. Currently they fall into two sets of
responsibilities: querying the source tree for version information and managing
&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/.zsh.d/functions/mysql_need_openssl3_workaround&quot;&gt;OpenSSL 3 build workarounds&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;No longer maintained (patches welcome)&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/usr/bin/gca&quot;&gt;gca&lt;/a&gt;,
the workhorse script from my time at Percona. Used when the same patch has to
be developed for more than one major MySQL series (e.g. the patch is needed
for 8.0, 8.4, &amp;amp; 9.0, using an example that is current at the time of the
writing). There is a constraint that the lower series version of the patch has
to be &lt;code&gt;git merge&lt;/code&gt;d to the next higher series, but the latest commits of these
series are not fully merged to each other due to how Oracle pushes their
source trees. So, a lower series feature branch has to be created not from the
tip but from some older commit which had been fully merged. This script
manages finding such commits and creating the worktrees. Luckily I only deal
with single series these days.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/usr/bin/reupmerge&quot;&gt;reupmerge&lt;/a&gt;,
used in that same multiple-series workflow. It handles the scenario where,
i.e. a code review change needs to be applied to a lower branch commit in a
feature branch. Changing that commit requires re-merging it to the higher
series. For the case where the higher series commit needs not to change, this
script automates saving its diff, and re-merging the lower series with that
exact saved diff.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/.emacs.d/dotfiles/mysql-work.el&quot;&gt;mysql-work.el&lt;/a&gt;:
mostly outdated Emacs configuration bits, mostly copied from colleagues at
Percona. They set up MySQL (and InnoDB) indentation styles that were used up
to 5.7, and provide a bit of syntax support for MTR &lt;code&gt;.test&lt;/code&gt; files.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/1790441687217818747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/1790441687217818747' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/1790441687217818747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/1790441687217818747'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/08/a-readme-for-my-mysql-development.html' title='A README for my MySQL development tooling'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-5047299569114659302</id><published>2024-07-09T16:11:00.000+03:00</published><updated>2024-07-09T16:11:36.276+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>A MySQL 9.0.0 branch with patches</title><content type='html'>&lt;p&gt;
Recently I made public a branch of &lt;a href=&quot;https://of-code.blogspot.com/2024/05/a-mysql-840-branch-with-patches.html&quot;&gt;MySQL 8.4.0 with patches&lt;/a&gt;. Now that newer upstream
versions have been released, I have rebased the branch on 9.0.0: &lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/tree/patched-mysql-9.0.0&quot;&gt;patched-mysql-9.0.0&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
I did not add any new patches, and dropped the LLVM compilation fix &lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/commit/1f897ded35ea67a79487e68945a1a52e70bba63f&quot;&gt;patch&lt;/a&gt;. Thus the
current patch set improves AddressSanitizer support and includes several
fixes/improvements for the clone plugin to support a second transactional storage
engine:
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115120&quot;&gt;Bug 115120&lt;/a&gt;: Provide memory debugging macro implementations for
AddressSanitizer.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109922&quot;&gt;Bug 109922&lt;/a&gt;: SEs do not coordinate clone rollbacks on instance startup.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109920&quot;&gt;Bug 109920&lt;/a&gt;: SEs cannot add to clone data size estimates.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109919&quot;&gt;Bug 109919&lt;/a&gt;: Clone plugin does not support arbitrary length O_DIRECT files.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=107715&quot;&gt;Bug 107715&lt;/a&gt;: Multiple SE clone not calling clone_end after mixed
clone_begin failure/success.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106750&quot;&gt;Bug 106750&lt;/a&gt;: Some clone tests needlessly marked as Linux-only.&lt;/li&gt;
&lt;li&gt;Fix for &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106737&quot;&gt;Bug 106737&lt;/a&gt;: Wrong SE called to ack clone application if &amp;gt;1 SE.&lt;/li&gt;
&lt;/ol&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/5047299569114659302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/5047299569114659302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/5047299569114659302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/5047299569114659302'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/07/a-mysql-900-branch-with-patches.html' title='A MySQL 9.0.0 branch with patches'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-3069945077084809581</id><published>2024-07-04T16:52:00.000+03:00</published><updated>2024-07-04T16:52:48.268+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.38 / 8.4.1 / 9.0.0 on macOS</title><content type='html'>&lt;p&gt;
Oracle has just released MySQL 8.0.38/8.4.1/9.0.0, so let&#39;s see how the Valgrind
&lt;a href=&quot;https://of-code.blogspot.com/2024/05/building-and-testing-mysql-8037-840-on.html&quot;&gt;testing of the previous set of releases&lt;/a&gt; is going:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org7e35c78&quot;&gt;[ 65%] innodb.bug33788578_rec_IV_set            w2  [ fail ]  Found warnings/errors in error log file!
&lt;/pre&gt;

&lt;p&gt;
It only managed two thirds of a run (a &lt;code&gt;--big-test&lt;/code&gt; one) in a few
weeks, which means that I either need a faster machine, or that Valgrind testing does
not take even remotely reasonable amount of time. Despite the run being incomplete,
it resulted in couple of bug reports because &lt;i&gt;every single test&lt;/i&gt; gives an error:
&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115229&quot;&gt;#115229: pwrite(buf) points to uninitialised byte(s) in
os_fusionio_get_sector_size()&lt;/a&gt;. I also noticed that one test always times out:
&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114998&quot;&gt;#114998: Test rpl_gtid.rpl_gtid_parallel times out under Valgrind&lt;/a&gt;. I need to rethink
Valgrind testing going forward, maybe by trying dropping &lt;code&gt;--big-test&lt;/code&gt; first.
&lt;/p&gt;

&lt;p&gt;
Back to the new releases. A nice surprise is that the they build with XCode 15.3 even
though the associated bug (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;#113123: Compilation fails with LLVM 17 and XCode 15.3&lt;/a&gt;) is
still open. However, an LLVM 18 build fails in the bundled zlib, and this time I
refrained from reporting a bug. GCC 11–14 also fail, but they are officially
unsupported for macOS, so I won&#39;t be reporting that, unless I encounter issues on
Linux.
&lt;/p&gt;

&lt;p&gt;
Fixed and no longer reproducing bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;#113123: Compilation fails with LLVM 17 and XCode 15.3&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114894&quot;&gt;#114894: Test rpl.rpl_log_info_repository_persistence_require_row failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114896&quot;&gt;#114896: Several tablespace encryption tests failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113702&quot;&gt;#113702: Test binlog.binlog_error_action fails under Sanitizer build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113704&quot;&gt;#113704: Tests main.log_backtrace &amp;amp; main.log_backtrace_debug fail under Sanitizer
build&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
New bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115479&quot;&gt;#115479: main.partition_innodb_tablespace not masking temp directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115480&quot;&gt;#115480: Test innodb.log_first_rec_group failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115481&quot;&gt;#115481: Test main.window_functions failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115482&quot;&gt;#115482: Test main.window_jsonaggs failing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115495&quot;&gt;#115495: &quot;Unable to read page&quot; crash on innodb.dblwr_encrypt_recover&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115497&quot;&gt;#115497: Test main.alter_table-big_myisam failure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115498&quot;&gt;#115498: Test main.opt_hints_hypergraph always failing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Little to no changes
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;#113260: Client error in error log: MY-004031 - The client was disconnected …&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;#113023: mysql-test/include/wait_for_pattern_in_file.inc incompatible with Homebrew
Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;#113189: ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;#113190: Several tests in routertest_integration_routing_sharing_constrained_pools
fail&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114888&quot;&gt;#114888: Test innodb.parallel_read_kill always fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;#113709: StrXfrmTest.ChineseUTF8MB4 failing with an AddressSanitizer error&lt;/a&gt;, which
is a duplicate of #109540, fixed in 8.1.0 only.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;#113722: Test main.index_merge_innodb failing with a result difference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;#114892: Test XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;#113665: perfschema.relaylog fails with a result difference&lt;/a&gt; - reproduced only on
8.4.1. I guess the test is still flaky.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113703&quot;&gt;#113703: Test innodb.ddl_kill fails under Sanitizer build&lt;/a&gt; - reproduced on 8.4.1 and
9.0.0 but not 8.0.38.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113710&quot;&gt;#113710: Spec/HttpClientSecureTest.ensure/default_client_cipher_succeeds ASan error&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Finally, I did not retest &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113113&quot;&gt;#113113: Build failure with Homebrew LLVM 14-17 on macOS&lt;/a&gt;,
where I keep using the workaround of setting CMAKE_AR to Homebrew ar.
&lt;/p&gt;

&lt;p&gt;
To sum up, 5 bugs fixed or no longer reproducing, 7 new, 11 with no changes, 1 not
tested, and 2 new Valgrind ones. I don&#39;t like this trend and I miss the middle-8.0
releases that were fully clean under macOS.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/3069945077084809581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/3069945077084809581' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3069945077084809581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3069945077084809581'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/07/building-and-testing-mysql-8038-841-900.html' title='Building and testing MySQL 8.0.38 / 8.4.1 / 9.0.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-1096294141580982801</id><published>2024-06-14T16:20:00.001+03:00</published><updated>2024-06-17T07:09:33.188+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Implementing a Table-Returning MySQL Function</title><content type='html'>&lt;p&gt;Edit: links to Percona &lt;a href=&quot;https://docs.percona.com/percona-server/8.0/sequence-table.html&quot;&gt;SEQUENCE_TABLE&lt;/a&gt; implementation added to the end&lt;/p&gt;&lt;p&gt;
MySQL has many native functions and it&#39;s relatively straightforward to write new
ones. While the official internals manual has a &lt;a href=&quot;https://dev.mysql.com/doc/extending-mysql/8.4/en/adding-native-function.html&quot;&gt;chapter&lt;/a&gt; on adding native functions,
some aspects aren&#39;t immediately obvious, such as the possible return types for
functions. The linked docs suggest that functions can return a double, an integer, or
a string, but doesn&#39;t mention that they can also return JSON documents (i.e.
&lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/json-creation-functions.html#function_json-array&quot;&gt;JSON_ARRAY&lt;/a&gt;) and relational tables (i.e. &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.4/en/json-table-functions.html#function_json-table&quot;&gt;JSON_TABLE&lt;/a&gt;). I have filed a &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=115329&quot;&gt;bug&lt;/a&gt; for this
omission, meanwhile this post will be my attempt at documenting the implementation of
table-returning functions.
&lt;/p&gt;

&lt;p&gt;
We will implement a table-returning function called &lt;code&gt;LAST_INSERT_IDS&lt;/code&gt;, We will focus
on the server infrastructure to support that, not on the function&#39;s purpose or the
actual data it returns. Let&#39;s do the simplest possible thing: return a table with one
column and one row.
&lt;/p&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org6f26084&quot;&gt;
&lt;h2 id=&quot;org6f26084&quot;&gt;Exploring the Codebase&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org6f26084&quot;&gt;
&lt;p&gt;
Grepping the source tree for &lt;code&gt;JSON_TABLE&lt;/code&gt; points to &lt;code&gt;Table_function&lt;/code&gt; class declared
in &lt;a href=&quot;https://github.com/mysql/mysql-server/blob/trunk/sql/table_function.h&quot;&gt;sql/table_function.h&lt;/a&gt;. Source code history then points to this &lt;a href=&quot;https://github.com/mysql/mysql-server/commit/f1131e4d4f8c3f474a523758c0ae7a23059683a5&quot;&gt;commit&lt;/a&gt;, which in
turn mentions &lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=8867&quot;&gt;Worklog #8867 (Add JSON table functions)&lt;/a&gt;. Luckily for us it&#39;s a
relatively old worklog, thus available publicly! From the worklog we can learn that
any result tables will start as in-memory temporary tables which will spill to disk
as needed. Good. The worklog also touches upon a lot of stuff elsewhere in the server
so that the query optimizer will know how to deal with table-returning functions. We
won&#39;t need to deal with that while implementing a new function, but it may provide
debugging starters should anything go wrong.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org0f8f6df&quot;&gt;
&lt;h2 id=&quot;org0f8f6df&quot;&gt;Function class&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org0f8f6df&quot;&gt;
&lt;p&gt;
To start writing code, we have to derive a new concrete class from &lt;code&gt;Table_function&lt;/code&gt;
and let the compiler tell us what methods must be implemented:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;class Table_function_last_insert_ids final : public Table_function {
 public:
  bool init() override;
  bool fill_result_table() override;
  const char *func_name() const override;
  bool print(const THD *thd, String *str,
             enum_query_type query_type) const override;
  bool walk(Item_processor processor, enum_walk walk, uchar *arg) override;

 private:
  List&amp;lt;Create_field&amp;gt; *get_field_list() override;
  bool do_init_args() override;
};
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
But let&#39;s not implement them just yet (stub them out with &lt;code&gt;assert(0)&lt;/code&gt; bodies to learn
what gets called when), and let&#39;s look into instantiating the class
object first. The regular functions get registered with MySQL in &lt;code&gt;func_array&lt;/code&gt;
variable in &lt;a href=&quot;https://github.com/mysql/mysql-server/blob/trunk/sql/item_func.cc&quot;&gt;sql/item_create.cc&lt;/a&gt;, and the surrounding code knows how to create their
objects. But &lt;code&gt;JSON_TABLE&lt;/code&gt; is not there! Grepping shows that it is wired directly to
the parser, probably because its arguments are non-trivial. Our function is much
simpler in that regard, can we get away with putting it there instead of patching
parser? It turns out that no, we cannot, because the simpler functions derive from
&lt;code&gt;Item_func&lt;/code&gt; class, which derives from &lt;code&gt;Item&lt;/code&gt;, which is what this infrastructure
expects. And our table-returning function derives from &lt;code&gt;Table_function&lt;/code&gt;, which has no
further ancestors.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-orgd90ec69&quot;&gt;
&lt;h2 id=&quot;orgd90ec69&quot;&gt;Patching the parser&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgd90ec69&quot;&gt;
&lt;p&gt;
OK, off to the parser we go. To find a starting point, let&#39;s check what &lt;code&gt;JSON_TABLE&lt;/code&gt;
does. Grepping for &lt;code&gt;Table_function_json&lt;/code&gt; in the parser (the worklog is not too
specific in this area), we get a match for &lt;code&gt;PT_table_factor_function&lt;/code&gt; class in
&lt;a href=&quot;https://github.com/mysql/mysql-server/blob/trunk/sql/parse_tree_nodes.cc&quot;&gt;sql/parse_tree_nodes.cc&lt;/a&gt;. Then we grep for that class in the parser grammar and we get
a hint why the table-returning functions are harder to implement than other kinds of
functions:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-bison&quot;&gt;table_function:
        JSON_TABLE_SYM &#39;(&#39; expr &#39;,&#39; text_literal columns_clause &#39;)&#39;
        opt_table_alias
        {
          // Alias isn&#39;t optional, follow derived&#39;s behavior
          if ($8 == NULL_CSTR)
          {
            my_message(ER_TF_MUST_HAVE_ALIAS,
                       ER_THD(YYTHD, ER_TF_MUST_HAVE_ALIAS), MYF(0));
            MYSQL_YYABORT;
          }

          $$= NEW_PTN PT_table_factor_function($3, $5, $6, to_lex_string($8));
        }
      ;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
We can see that the parser knows how to work with exactly one table-returning
function that is named &lt;code&gt;JSON_TABLE&lt;/code&gt;, thus we have to patch the parser. Let&#39;s
keep everything under the non-terminal symbol &lt;code&gt;table_function&lt;/code&gt;:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-bison&quot;&gt;table_function:
          json_table_function
        | last_insert_ids_function
        ;

last_insert_ids_function:
          LAST_INSERT_IDS_SYM &#39;(&#39; &#39;)&#39;
          opt_table_alias
          {
            // Alias isn&#39;t optional, follow derived&#39;s behavior
            if ($4 == NULL_CSTR)
            {
                my_message(ER_TF_MUST_HAVE_ALIAS,
                           ER_THD(YYTHD, ER_TF_MUST_HAVE_ALIAS), MYF(0));
                MYSQL_YYABORT;
            }

            $$= NEW_PTN PT_last_insert_ids_function(to_lex_string($4));
          }
        ;

json_table_function:
        // As before
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Unfortunately the &lt;code&gt;opt_table_alias&lt;/code&gt; block must be duplicated. But, no increase in the
parser shift/reduce conflicts! There is more not particularly interesting stuff to do
in the lexer and the parser:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Add the function name to the lexer, &lt;code&gt;{SYM(&quot;LAST_INSERT_IDS&quot;,
  LAST_INSERT_IDS_SYM)},&lt;/code&gt; to &lt;code&gt;sql/lex.h&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Declare this lexer symbol as a token for the parser. I did not make it a keyword
because &lt;code&gt;JSON_TABLE&lt;/code&gt; wasn&#39;t one neither: &lt;code&gt;%token  LAST_INSERT_IDS_SYM 10024&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Finally, declare &lt;code&gt;last_insert_ids_function&lt;/code&gt; symbol to be of &lt;code&gt;table_reference&lt;/code&gt; type,
same as &lt;code&gt;table_function&lt;/code&gt; was before.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org10f2566&quot;&gt;
&lt;h2 id=&quot;org10f2566&quot;&gt;Parse Tree Node class&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org10f2566&quot;&gt;
&lt;p&gt;
That&#39;s enough for the lexer and the parser, next we need to implement
&lt;code&gt;PT_last_insert_ids_function&lt;/code&gt; class:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;class PT_last_insert_ids_function : public PT_table_reference {
 public:
  PT_last_insert_ids_function(const LEX_STRING &amp;amp;table_alias)
      : m_table_alias{table_alias} {}

 private:
  const LEX_STRING m_table_alias;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Without a &lt;code&gt;PT_last_insert_ids_function::contextualize&lt;/code&gt; method, which would actually
create the &lt;code&gt;Table_function_last_insert_ids&lt;/code&gt; object, the above implementation fails
rather non-obviously:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org4cee9c5&quot;&gt;mysqltest: At line 24: Query &#39;SELECT * FROM LAST_INSERT_IDS() as ids&#39; failed.
ERROR 1096 (HY000): No tables used
&lt;/pre&gt;

&lt;p&gt;
Let&#39;s add that method by copying, pasting, and deleting the non-applicable bits of
&lt;code&gt;PT_table_factor_function::contextualize&lt;/code&gt;. The job of this method will be to create
the function object and to assign a name and a table for the query optimizer for the
result.
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;bool PT_last_insert_ids_function::contextualize(Parse_context *pc) {
  if (super::contextualize(pc)) return true;
  auto *const fn = new (pc-&amp;gt;mem_root) Table_function_last_insert_ids{};
  if (unlikely(fn == nullptr)) return true;

  LEX_CSTRING alias;
  alias.length = strlen(fn-&amp;gt;func_name());
  alias.str = sql_strmake(fn-&amp;gt;func_name(), alias.length);
  if (unlikely(alias.str == nullptr)) return true;

  auto *const ti = new (pc-&amp;gt;mem_root) Table_ident(alias, fn);
  if (ti == nullptr) return true;

  m_table_ref = pc-&amp;gt;select-&amp;gt;add_table_to_list(pc-&amp;gt;thd, ti, m_table_alias.str, 0,
                                              TL_READ, MDL_SHARED_READ);
  if (m_table_ref == nullptr || pc-&amp;gt;select-&amp;gt;add_joined_table(m_table_ref))
    return true;

  return false;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-orgebbb77b&quot;&gt;
&lt;h2 id=&quot;orgebbb77b&quot;&gt;Filling out the function class implementation&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgebbb77b&quot;&gt;
&lt;p&gt;
This implementation forces us to define the first method in
&lt;code&gt;Table_function_last_insert_ids&lt;/code&gt;, a very simple one:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;const char *func_name() const override { return &quot;last_insert_ids&quot;; }
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Let&#39;s run it!
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;orgaed1fbe&quot;&gt;SELECT * FROM LAST_INSERT_IDS() as ids;
...
Assertion failed: (0), function init, file table_function.h, line 440.
&lt;/pre&gt;
&lt;p&gt;
…which points to the stub &lt;code&gt;Table_function_last_insert_ids::init()&lt;/code&gt;. Let&#39;s say we
have no meaningful initialization at this point, so remove the assert from the stub:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org34c47ec&quot;&gt;Assertion failed: (false), function get_field_list, file table_function.h, line 464.
&lt;/pre&gt;

&lt;p&gt;
This is &lt;code&gt;get_field_list&lt;/code&gt; method, and we have to implement it to describe the schema
of the table we will be returning:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;List&amp;lt;Create_field&amp;gt; *Table_function_last_insert_ids::get_field_list() {
  assert(fields.is_empty());

  auto *const field = new Create_field;
  field-&amp;gt;init_for_tmp_table(MYSQL_TYPE_LONGLONG, MAX_BIGINT_WIDTH,
                            DECIMAL_NOT_SPECIFIED, /* is_nullable */ false,
                            /* is_unsigned */ true, 0, &quot;insert_id&quot;);
  fields.push_back(field);

  return &amp;amp;fields;
}
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
This implementation assumes it is not a simple getter and thus is called exactly
once. If the assumption will shown to be incorrect by the &lt;code&gt;assert&lt;/code&gt;, I&#39;ll move the
code to &lt;code&gt;init&lt;/code&gt; and will reduce this one to a simple getter. Also, something will have
to free the memory we are allocating for the field, that&#39;s for later.
&lt;/p&gt;

&lt;p&gt;
Run again…
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org753a28c&quot;&gt;Assertion failed: (false), function do_init_args, file table_function.h, line 467.
&lt;/pre&gt;

&lt;p&gt;
For &lt;code&gt;JSON_TABLE&lt;/code&gt;, this method is documented to &quot;check whether given default values
can be saved to fields.&quot; Let&#39;s assume that we have no meaningful actions here, remove
the assert, return success, run again:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org798189a&quot;&gt;Assertion failed: (0), function fill_result_table, file table_function.h, line 442.
&lt;/pre&gt;
&lt;p&gt;
Finally we get to the second serious method that should provide the payload for the
result table:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;bool Table_function_last_insert_ids::fill_result_table() {
  assert(!fields.is_empty());
  assert(!table-&amp;gt;materialized);
  assert(table-&amp;gt;s-&amp;gt;fields == 1);

  empty_table();

  auto *const field = get_field(0);
  assert(field-&amp;gt;field_index() == 0);
  field-&amp;gt;store(current_thd-&amp;gt;first_successful_insert_id_in_prev_stmt);
  field-&amp;gt;set_notnull();
  write_row();

  return false;
}
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
And…
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;orgd413358&quot;&gt;SELECT * FROM LAST_INSERT_IDS() as ids;
insert_id
0
&lt;/pre&gt;

&lt;p&gt;
Success!
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org5ee6890&quot;&gt;
&lt;h2 id=&quot;org5ee6890&quot;&gt;Implementing the remaining stubs&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org5ee6890&quot;&gt;
&lt;p&gt;
We still have two stub methods with asserts in them: &lt;code&gt;print&lt;/code&gt; and &lt;code&gt;walk&lt;/code&gt;.
Let&#39;s try figuring out under what conditions they get called, again, by looking at
&lt;code&gt;JSON_TABLE&lt;/code&gt; implementation.
&lt;/p&gt;

&lt;p&gt;
Let&#39;s start with &lt;code&gt;print&lt;/code&gt;. It gets called by &lt;code&gt;sql_lex.cc&lt;/code&gt; &lt;code&gt;Table_ref::print&lt;/code&gt;. There
are references to optimizer trace and something else around that. Let&#39;s see if that
&quot;something else&quot; refers to the good old &lt;code&gt;EXPLAIN&lt;/code&gt;:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org322eb8e&quot;&gt;EXPLAIN SELECT * FROM LAST_INSERT_IDS() as ids;
Assertion failed: (false), function print, file table_function.h, line 450.
7   mysqld                              0x000000010385ffb8 Table_function_last_insert_ids::walk(bool (Item::*)(unsigned char*), enum_walk, unsigned char*) + 0
&lt;/pre&gt;

&lt;p&gt;
Interesting! We tried to find what calls &lt;code&gt;print&lt;/code&gt;, but we found what calls &lt;code&gt;walk&lt;/code&gt;
instead. Since our function is atomic with regard to the query optimizer and has no
internal structure, there is nothing to walk, let&#39;s remove the &lt;code&gt;assert&lt;/code&gt;:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org9d3f487&quot;&gt;EXPLAIN SELECT * FROM LAST_INSERT_IDS() as ids;
Assertion failed: (false), function print, file table_function.h, line 450.
&lt;/pre&gt;

&lt;p&gt;
Great, so the same &lt;code&gt;EXPLAIN&lt;/code&gt; statement exercises both &lt;code&gt;walk&lt;/code&gt; and  &lt;code&gt;print&lt;/code&gt;. Let&#39;s add
a simple implementation for the latter:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;bool print(const THD *, String *str, enum_query_type) const override {
  return !str-&amp;gt;append(STRING_WITH_LEN(&quot;last_insert_ids()&quot;));
}
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
And now the &lt;code&gt;EXPLAIN&lt;/code&gt;!
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org28444f1&quot;&gt;EXPLAIN SELECT * FROM LAST_INSERT_IDS() as ids;
id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	SIMPLE	ids	NULL	ALL	NULL	NULL	NULL	NULL	2	100.00	Table function: last_insert_ids; Using temporary
Warnings:
Note	1003	/* select#1 */ select `ids`.`insert_id` AS `insert_id` from last_insert_ids() `ids`
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org5355277&quot;&gt;
&lt;h2 id=&quot;org5355277&quot;&gt;Memory management&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org5355277&quot;&gt;
&lt;p&gt;
One last thing is that &lt;code&gt;Field&lt;/code&gt; object which was allocated in
&lt;code&gt;Table_function_last_insert_ids::get_field_list&lt;/code&gt; and never freed. Let&#39;s see if the
standard tooling catches this error. AddressSanitizer under Linux includes
LeakSanitizer, let&#39;s try it:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org13fd266&quot;&gt;==31384==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 1440 byte(s) in 6 object(s) allocated from:
    #0 0xab9c0d1a99ac in operator new(unsigned long) (/home/laurynas/vilniusdb/last_insert_ids/_build-debug-llvm-14-san/runtime_output_directory/mysqld+0xb0599ac) (BuildId: 611e155cd8dc43455bd5d5e0ddbdfe53ae205fa4)
    #1 0xab9c0e6bb8bc in Table_function_last_insert_ids::get_field_list() /home/laurynas/vilniusdb/last_insert_ids/sql/table_function.cc:778:23
    #2 0xab9c0e6b5514 in Table_function::create_result_table(THD*, unsigned long long, char const*) /home/laurynas/vilniusdb/last_insert_ids/sql/table_function.cc:64:46
    #3 0xab9c0e0024fc in Table_ref::setup_table_function(THD*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_derived.cc:933:23
    #4 0xab9c0e388bfc in Query_block::resolve_placeholder_tables(THD*, bool) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_resolver.cc:1310:15
    #5 0xab9c0e3854a4 in Query_block::prepare(THD*, mem_root_deque&amp;lt;Item*&amp;gt;*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_resolver.cc:247:7
    #6 0xab9c0e3e3da4 in Sql_cmd_select::prepare_inner(THD*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_select.cc:484:17
    #7 0xab9c0e3e2d74 in Sql_cmd_dml::prepare(THD*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_select.cc:399:11
    #8 0xab9c0e3e4360 in Sql_cmd_dml::execute(THD*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_select.cc:539:9
    #9 0xab9c0e263934 in mysql_execute_command(THD*, bool, unsigned long long*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_parse.cc:5489:29
    #10 0xab9c0e25c8c8 in dispatch_sql_command(THD*, Parser_state*, unsigned long long*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_parse.cc:6276:21
    #11 0xab9c0e253894 in dispatch_command(THD*, COM_DATA const*, enum_server_command) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_parse.cc:2565:7
    #12 0xab9c0e259124 in do_command(THD*) /home/laurynas/vilniusdb/last_insert_ids/sql/sql_parse.cc:1745:18
    #13 0xab9c0e7f6f10 in handle_connection(void*) /home/laurynas/vilniusdb/last_insert_ids/sql/conn_handler/connection_handler_per_thread.cc:307:13
    #14 0xab9c12076ee8 in pfs_spawn_thread(void*) /home/laurynas/vilniusdb/last_insert_ids/storage/perfschema/pfs.cc:3022:3
    #15 0xfbb124cc5978 in start_thread nptl/./nptl/pthread_create.c:447:8
    #16 0xfbb124d2ba48 in thread_start misc/../sysdeps/unix/sysv/linux/aarch64/clone3.S:76
&lt;/pre&gt;

&lt;p&gt;
Yep, a leak. Let&#39;s try freeing that memory in the destructor:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;Table_function_last_insert_ids::~Table_function_last_insert_ids() {
  assert(fields.elements == 1);
  delete fields.head();
}
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Run again, no leak or any other Sanitizer error.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org47c2e7d&quot;&gt;
&lt;h2 id=&quot;org47c2e7d&quot;&gt;Summary checklist&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org47c2e7d&quot;&gt;
&lt;p&gt;
So, to summarize, the checklist for adding a new table-returning function to MySQL:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Add the function name as a lexer symbol in &lt;code&gt;sql/lex.h&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add the function name symbol as a token in the parser (&lt;code&gt;sql/sql_yacc.yy&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;In the parser, rename &lt;code&gt;table_function&lt;/code&gt; to &lt;code&gt;json_table_function&lt;/code&gt; and add new
&lt;code&gt;table_function&lt;/code&gt; with &lt;code&gt;json_table_function&lt;/code&gt; and new function alternatives. All
these symbols must be typed as &lt;code&gt;table_reference&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create a new parse tree node class, for example:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;class PT_last_insert_ids_function : public PT_table_reference {
  using super = PT_table_reference;

 public:
  PT_last_insert_ids_function(const LEX_STRING &amp;amp;table_alias)
      : m_table_alias{table_alias} {}

  bool contextualize(Parse_context *pc) override;

 private:
  const LEX_STRING m_table_alias;
};

bool PT_last_insert_ids_function::contextualize(Parse_context *pc) {
  if (super::contextualize(pc)) return true;
  auto *const fn = new (pc-&amp;gt;mem_root) Table_function_last_insert_ids{};
  if (unlikely(fn == nullptr)) return true;

  LEX_CSTRING alias;
  alias.length = strlen(fn-&amp;gt;func_name());
  alias.str = sql_strmake(fn-&amp;gt;func_name(), alias.length);
  if (unlikely(alias.str == nullptr)) return true;

  auto *const ti = new (pc-&amp;gt;mem_root) Table_ident(alias, fn);
  if (ti == nullptr) return true;

  m_table_ref = pc-&amp;gt;select-&amp;gt;add_table_to_list(pc-&amp;gt;thd, ti, m_table_alias.str, 0,
                                              TL_READ, MDL_SHARED_READ);
  if (m_table_ref == nullptr || pc-&amp;gt;select-&amp;gt;add_joined_table(m_table_ref))
    return true;

  return false;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;Create a new table function class:&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot; style=&quot;text-align: left;&quot;&gt;class Table_function_last_insert_ids final : public Table_function {
 public:
  ~Table_function_last_insert_ids() override;

  bool init() override { return false; }

  bool fill_result_table() override;

  const char *func_name() const override { return &quot;last_insert_ids&quot;; }

  bool print(const THD *, String *str, enum_query_type) const override {
    return !str-&amp;gt;append(STRING_WITH_LEN(&quot;last_insert_ids()&quot;));
  }

  bool walk(Item_processor, enum_walk, uchar *) override {
    return false;
  }

 private:
  List&amp;lt;Create_field&amp;gt; *get_field_list() override;

  bool do_init_args() override { return false; }

  List&amp;lt;Create_field&amp;gt; fields;
};

Table_function_last_insert_ids::~Table_function_last_insert_ids() {
  assert(fields.elements == 1);
  delete fields.head();
}

List&amp;lt;Create_field&amp;gt; *Table_function_last_insert_ids::get_field_list() {
  assert(fields.is_empty());

  auto *const field = new Create_field;
  field-&amp;gt;init_for_tmp_table(MYSQL_TYPE_LONGLONG, MAX_BIGINT_WIDTH,
                            DECIMAL_NOT_SPECIFIED, /* is_nullable */ false,
                            /* is_unsigned */ true, 0, &quot;insert_id&quot;);
  fields.push_back(field);

  return &amp;amp;fields;
}

bool Table_function_last_insert_ids::fill_result_table() {
  assert(!fields.is_empty());
  assert(!table-&amp;gt;materialized);
  assert(table-&amp;gt;s-&amp;gt;fields == 1);

  empty_table();

  auto *const field = get_field(0);
  assert(field-&amp;gt;field_index() == 0);
  field-&amp;gt;store(current_thd-&amp;gt;first_successful_insert_id_in_prev_stmt);
  field-&amp;gt;set_notnull();
  write_row();

  return false;
}
&lt;/pre&gt;&lt;h2&gt;Percona SEQUENCE_TABLE&lt;/h2&gt;&lt;div&gt;After I have posted this, Percona&#39;s Yura Soroking &lt;a href=&quot;https://www.linkedin.com/feed/update/urn:li:activity:7207372890076258306?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7207372890076258306%2C7208060045794635776%29&amp;amp;dashCommentUrn=urn%3Ali%3Afsd_comment%3A%287208060045794635776%2Curn%3Ali%3Aactivity%3A7207372890076258306%29&quot;&gt;pointed out&lt;/a&gt; on LinkedIn their implementation of &lt;a href=&quot;https://docs.percona.com/percona-server/8.0/sequence-table.html&quot;&gt;SEQUENCE_TABLE&lt;/a&gt;&amp;nbsp;function: &lt;a href=&quot;https://www.percona.com/blog/generating-numeric-sequences-in-mysql/&quot;&gt;blog post&lt;/a&gt;, the &lt;a href=&quot;https://github.com/percona/percona-server/pull/3760&quot;&gt;initial implementation source code&lt;/a&gt;. This implementation follows similar framework as the toy implementation above.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/1096294141580982801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/1096294141580982801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/1096294141580982801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/1096294141580982801'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/06/implementing-table-returning-mysql.html' title='Implementing a Table-Returning MySQL Function'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-3365081518034219653</id><published>2024-05-28T18:16:00.003+03:00</published><updated>2024-07-09T13:46:49.387+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>A MySQL 8.4.0 branch with patches</title><content type='html'>&lt;p&gt;While writing the &lt;a href=&quot;https://of-code.blogspot.com/2024/05/building-and-testing-mysql-8037-840-on.html&quot;&gt;previous post&lt;/a&gt;, I noticed that I didn&#39;t have a central location for the patches that I submitted to Oracle. Some were in local branches, some were .patch files lying around. So now I pushed a tree that has all those patches applied in a single place: &lt;a href=&quot;https://github.com/laurynas-biveinis/mysql-server/tree/patched-mysql-8.4.0&quot;&gt;patched-mysql-8.4.0&lt;/a&gt;, and I even added a README. This tree hopefully will make it easier to rebase on future Oracle releases. I had maintained similar branches before while pushing some of the Percona patches to Oracle around early 8.0 times.&lt;/p&gt;&lt;p&gt;As for the patches themselves, the majority of them add various missing features for the clone plugin to be able to support more than one transactional storage engine. There is also a compilation fix and a slightly improved AddressSanitizer support patch.&lt;/p&gt;&lt;p&gt;All MySQL 8.4.0 users are advised to migrate ASAP! /s&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/3365081518034219653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/3365081518034219653' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3365081518034219653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/3365081518034219653'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/05/a-mysql-840-branch-with-patches.html' title='A MySQL 8.4.0 branch with patches'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-4021022840410259667</id><published>2024-05-08T16:52:00.001+03:00</published><updated>2024-05-08T17:37:51.551+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.37 &amp; 8.4.0 on macOS</title><content type='html'>&lt;p&gt;
The first MySQL LTS release, 8.4.0, is out, together with 8.0.37! Which means it&#39;s
time for me to build and test them in my main work environment, continuing the series
(&lt;a href=&quot;https://of-code.blogspot.com/2024/01/building-and-testing-mysql-8036-and-830.html&quot;&gt;8.3.0/8.0.36&lt;/a&gt;, &lt;a href=&quot;https://of-code.blogspot.com/2023/12/mysql-8035-and-820-are-out-here-are-my.html&quot;&gt;8.2.0/8.0.35&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;
The first surprise is that both these releases do not build with the current XCode
(15.3 at the time of writing), because the LLVM 17 compilation failure I previously
reported (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;#113123: Compilation fails with LLVM 17 and XCode 15.3&lt;/a&gt;) is not fixed yet
and started affected Apple toolchain too. I am using Homebrew-packaged LLVM 16 for
all the builds of these versions. I didn&#39;t do any LLVM 18 nor GCC testing neither.
&lt;/p&gt;

&lt;p&gt;
For the good news, I no longer get a build-breaking warning in NDB, even though its
bug (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113662&quot;&gt;#113662&lt;/a&gt;) is still open. Finally, for the build-related no-news, nothing has
changed with regard to system vs bundled libraries: both versions continue to build
with all the system libraries, except for zlib.
&lt;/p&gt;

&lt;p&gt;
On to the testsuite. It seems that 8.4.0 release build testsuite takes some 20% less
time than the 8.0.37 one. It must be the payoff from the deprecated feature removal
removing their tests too, although I did not try to confirm that.
&lt;/p&gt;

&lt;p&gt;
Fixed bugs and no longer reproducing test failures on open bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113257&quot;&gt;https://bugs.mysql.com/bug.php?id=113257&lt;/a&gt; (Assertion on
rpl.rpl_replication_observers_example_plugin_ongoing_transaction)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113258&quot;&gt;https://bugs.mysql.com/bug.php?id=113258&lt;/a&gt; (TLS 1.3 tests fail)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113420&quot;&gt;https://bugs.mysql.com/bug.php?id=113420&lt;/a&gt; (testNdbProcess fails under ASan+UBSan)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113736&quot;&gt;https://bugs.mysql.com/bug.php?id=113736&lt;/a&gt; (Test main.qualify_hypergraph failing with
a result difference)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
New test failures:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114888&quot;&gt;https://bugs.mysql.com/bug.php?id=114888&lt;/a&gt; (Test innodb.parallel_read_kill always
fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114892&quot;&gt;https://bugs.mysql.com/bug.php?id=114892&lt;/a&gt; (Test
XComControlTest.SuspectMemberFailedRemovalDueToMajorityLoss fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114894&quot;&gt;https://bugs.mysql.com/bug.php?id=114894&lt;/a&gt; (Test
rpl.rpl_log_info_repository_persistence_require_row failing)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=114896&quot;&gt;https://bugs.mysql.com/bug.php?id=114896&lt;/a&gt; (Several tablespace encryption tests
failing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
I wanted to call the following the list of bugs with no changes, but I can&#39;t. While
some of the bugs indeed have no changes, there is also a small but definite creep
there: a test that only failed in one configuration before now fails in two. A second
sibling test started failing with same symptoms. That&#39;s definitely not &quot;no changes&quot;,
but not new independent bugs neither. It&#39;s worrying.
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;https://bugs.mysql.com/bug.php?id=113189&lt;/a&gt;
(ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;https://bugs.mysql.com/bug.php?id=113190&lt;/a&gt; (Several tests in
routertest_integration_routing_sharing_constrained_pools fail)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;https://bugs.mysql.com/bug.php?id=113260&lt;/a&gt; (Client error in error log: MY-004031 -
The client was disconnected &amp;#x2026;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;https://bugs.mysql.com/bug.php?id=113665&lt;/a&gt; (perfschema.relaylog fails with a result
difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113702&quot;&gt;https://bugs.mysql.com/bug.php?id=113702&lt;/a&gt; (Test binlog.binlog_error_action fails
under Sanitizer build)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113703&quot;&gt;https://bugs.mysql.com/bug.php?id=113703&lt;/a&gt; (Test innodb.ddl_kill fails under
Sanitizer build) - the test now fails under debug build without sanitizer too.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113704&quot;&gt;https://bugs.mysql.com/bug.php?id=113704&lt;/a&gt; (Test main.log_backtrace fails under
Sanitizer build), but now main.log_backtrace_debug fails too, added it under the
same bug.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;https://bugs.mysql.com/bug.php?id=113709&lt;/a&gt; (StrXfrmTest.ChineseUTF8MB4 failing with
an AddressSanitizer error), which is a duplicate of &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109540&quot;&gt;#109540&lt;/a&gt;, which is fixed in
8.1.0 only. There is a comment that unit tests ASan errors are not a high priority
error, it&#39;s just a tiny harmless heap-buffer-overflow /s.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113710&quot;&gt;https://bugs.mysql.com/bug.php?id=113710&lt;/a&gt; (
Spec/HttpClientSecureTest.ensure/default_client_cipher_succeeds ASan error) - still
fails on 8.0.37 but not 8.4.0. The latter shows an UBSan error though.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;https://bugs.mysql.com/bug.php?id=113722&lt;/a&gt; (Test main.index_merge_innodb failing with
a result difference)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
I did not re-test two bugs:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;https://bugs.mysql.com/bug.php?id=113023&lt;/a&gt;
(mysql-test/include/wait_for_pattern_in_file.inc incompatible with Homebrew Perl)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113113&quot;&gt;https://bugs.mysql.com/bug.php?id=113113&lt;/a&gt; (Build failure with Homebrew LLVM 14-17 on
macOS), where I keep using the workaround of setting &lt;code&gt;CMAKE_AR&lt;/code&gt; to Homebrew &lt;code&gt;ar&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Thus, the numbers are: 4 new bugs reported, 5 fixed or no longer reproducing, 10 bugs
with no changes or with a bit of creep, 2 non-tested.
&lt;/p&gt;

&lt;p&gt;
But wait, there&#39;s more! I have also sent some patches to Oracle by OCA! I am only
counting the recent patches I developed at VilniusDB and not the ones I submitted at
Percona. So how many have they applied since 8.3.0?
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106737&quot;&gt;https://bugs.mysql.com/bug.php?id=106737&lt;/a&gt; (Wrong SE called to ack clone application
if &amp;gt;1 SE) - nope.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=106750&quot;&gt;https://bugs.mysql.com/bug.php?id=106750&lt;/a&gt; (Some clone tests needlessly marked as
Linux-only) - nope.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=107715&quot;&gt;https://bugs.mysql.com/bug.php?id=107715&lt;/a&gt; (Multiple SE clone not calling clone_end
after mixed clone_begin failure/success) - nope.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;https://bugs.mysql.com/bug.php?id=113123&lt;/a&gt; (Compilation fails with LLVM 17 and XCode 15.3) - nope.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
So, zero. Of course two out of four patches are for &lt;a href=&quot;https://of-code.blogspot.com/2024/01/mysql-clone-plugin-internals-and.html&quot;&gt;clone with a 2nd transactional
storage engine&lt;/a&gt;, thus the excuse of Oracle MySQL not having such engine sounds
plausible.
&lt;/p&gt;

&lt;p&gt;
That&#39;s about it. I am still running Valgrind tests, and they should complete any week
now, unless I have to kill them to take their machine for something else. I will not
be updating this post or writing a new one unless their results are very, very
unexpected. Otherwise here&#39;s to the new MySQL releases and hopefully I will continue
the series in three months.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/4021022840410259667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/4021022840410259667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4021022840410259667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4021022840410259667'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/05/building-and-testing-mysql-8037-840-on.html' title='Building and testing MySQL 8.0.37 &amp; 8.4.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-5630060434048230513</id><published>2024-01-30T16:51:00.001+02:00</published><updated>2024-01-30T16:51:08.692+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Introducing patch2testlist for MySQL development</title><content type='html'>&lt;p&gt;
I wrote a small shell utility &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/usr/bin/patch2testlist&quot;&gt;patch2testlist&lt;/a&gt; that might be useful for fellow MySQL
developers. It reads a diff and outputs the list of tests touched in this diff to run
in a format suitable for &lt;code&gt;mysql-test-run.pl&lt;/code&gt; consumption. Furthermore, when provided
with a path to the source tree of the diff, it handles included files.
&lt;/p&gt;

&lt;p&gt;
There are two ways to invoke it.
&lt;/p&gt;
&lt;ol class=&quot;org-ol&quot;&gt;
&lt;li&gt;&lt;p&gt;
Quick-and-dirty mode that does not handle included files:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org69ba467&quot;&gt;
$ ./mtr `git diff | patch2testlist` ...
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;
Thorough mode that considers included files, if the source tree path is given:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org5ba6f44&quot;&gt;
$ ./mtr `git diff | patch2testlist ../..` ...
&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
What does it do? Let&#39;s consider an example:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org22aaff9&quot;&gt;
$ git diff | diffstat
 mysql-test/extra/rpl_tests/rpl_replica_start_after_clone.inc                                    |    2 
 mysql-test/include/keyring_tests/binlog/rpl_encryption_master_key_rotation_at_startup.inc       |    5 -
 mysql-test/include/keyring_tests/mats/rpl_encryption.inc                                        |    2 
 mysql-test/include/keyring_tests/mats/rpl_encryption_master_key_generation_recovery.inc         |    2 
 mysql-test/suite/auth_sec/include/acl_tables_row_locking_test.inc                               |    4 
 mysql-test/suite/binlog/t/binlog_restart_server_with_exhausted_index_value.test                 |    1 
 mysql-test/suite/component_keyring_file/inc/rpl_setup_component.inc                             |    1 
 mysql-test/suite/innodb/t/log_8_0_11_case1.test                                                 |    1 
 mysql-test/suite/rocksdb/r/sys_tables.result                                                    |    2 
 mysql-test/suite/rocksdb/r/sys_tables_acl_tables_row_locking.result                             |  384 +++++++++++++++++++---------------------------------------------------------------
 mysql-test/suite/rocksdb/r/sys_tables_is_statistics_mysql.result                                |    4 
 mysql-test/suite/rocksdb/r/sys_tables_mysqlcheck.result                                         |    8 -
 mysql-test/suite/rpl/t/rpl_cloned_slave_relay_log_info.test                                     |    4 
 mysql-test/suite/rpl/t/rpl_encryption.test                                                      |    3 
 mysql-test/suite/rpl/t/rpl_encryption_master_key_generation_recovery.test                       |    3 
 mysql-test/suite/rpl/t/rpl_encryption_master_key_rotation_at_startup.test                       |    5 -
 mysql-test/suite/rpl/t/rpl_gtid_innodb_sys_header.test                                          |    2 
 mysql-test/suite/rpl_gtid/t/rpl_gtid_xa_commit_failure_before_gtid_externalization.test         |    1 
 mysql-test/suite/rpl_gtid/t/rpl_gtid_xa_commit_one_phase_failure_before_prepare_in_engines.test |    1 
 mysql-test/suite/rpl_gtid/t/rpl_gtid_xa_prepare_failure_before_prepare_in_engines.test          |    1 
 mysql-test/suite/rpl_gtid/t/rpl_gtid_xa_rollback_failure_before_gtid_externalization.test       |    1 
 mysql-test/suite/rpl_nogtid/t/rpl_assign_gtids_to_anonymous_transactions_clone.test             |    4 
 mysql-test/suite/rpl_nogtid/t/rpl_gtid_mode.test                                                |    5 -
 mysql-test/suite/rpl_nogtid/t/rpl_nogtid_encryption_read.test                                   |    3 
 mysql-test/suite/test_services/t/test_host_application_signal_plugin.test                       |    3 
 mysql-test/t/basedir.test                                                                       |    5 -
 mysql-test/t/mysqld_daemon.test                                                                 |    3 
 mysql-test/t/mysqld_safe.test                                                                   |   27 ++---
 mysql-test/t/restart_server.test                                                                |    3 
 mysql-test/t/restart_server_no_acl.test                                                         |    3 
...
$ git diff | patch2testlist
binlog.binlog_restart_server_with_exhausted_index_value innodb.log_8_0_11_case1 main.basedir
main.mysqld_daemon main.mysqld_safe main.restart_server main.restart_server_no_acl
rocksdb.sys_tables rocksdb.sys_tables_acl_tables_row_locking
rocksdb.sys_tables_is_statistics_mysql rocksdb.sys_tables_mysqlcheck
rpl.rpl_cloned_slave_relay_log_info rpl.rpl_encryption
rpl.rpl_encryption_master_key_generation_recovery
rpl.rpl_encryption_master_key_rotation_at_startup rpl.rpl_gtid_innodb_sys_header
rpl_gtid.rpl_gtid_xa_commit_failure_before_gtid_externalization
rpl_gtid.rpl_gtid_xa_commit_one_phase_failure_before_prepare_in_engines
rpl_gtid.rpl_gtid_xa_prepare_failure_before_prepare_in_engines
rpl_gtid.rpl_gtid_xa_rollback_failure_before_gtid_externalization
rpl_nogtid.rpl_assign_gtids_to_anonymous_transactions_clone rpl_nogtid.rpl_gtid_mode
rpl_nogtid.rpl_nogtid_encryption_read test_services.test_host_application_signal_plugin
&lt;/pre&gt;

&lt;p&gt;
The quick-and-dirty mode above does not require a hundred line script, a &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/b25eddc4c9ac7b916a9d2af83d8690e0c1f58c87/mysql-work/usr/bin/patch2testlist&quot;&gt;ten-line one
will do&lt;/a&gt;. But notice that several of the changed files in the &lt;code&gt;diffstat&lt;/code&gt; output are
test include files (i.e. &lt;code&gt;rpl_replica_start_after_clone.inc&lt;/code&gt;). Ideally we&#39;d want to
run any tests that include (directly and indirectly) such files, and the ten-line
script does not handle this case.
&lt;/p&gt;

&lt;p&gt;
That&#39;s what the other ninety lines of the script do. If the optional source tree path
argument is given, then it greps for any included files under &lt;code&gt;mysql-test/&lt;/code&gt;, then
greps for newly-found files and so on until it finds no more:
&lt;/p&gt;
&lt;pre class=&quot;example&quot; id=&quot;org8b5aea5&quot;&gt;
$ git diff | patch2testlist ../..
auth_sec.acl_tables_row_locking binlog.binlog_restart_server_with_exhausted_index_value
component_keyring_file.rpl_binlog_cache_encryption
component_keyring_file.rpl_binlog_cache_temp_file_encryption
component_keyring_file.rpl_default_table_encryption component_keyring_file.rpl_encryption
component_keyring_file.rpl_encryption_master_key_generation_recovery
component_keyring_file.rpl_encryption_master_key_rotation_at_startup innodb.log_8_0_11_case1
main.basedir main.mysqld_daemon main.mysqld_safe main.restart_server main.restart_server_no_acl
rocksdb.sys_tables rocksdb.sys_tables_acl_tables_row_locking rocksdb.sys_tables_is_statistics_mysql
rocksdb.sys_tables_mysqlcheck rpl.rpl_cloned_slave_relay_log_info rpl.rpl_encryption
rpl.rpl_encryption_master_key_generation_recovery rpl.rpl_encryption_master_key_rotation_at_startup
rpl.rpl_gtid_innodb_sys_header rpl.rpl_slave_start_after_clone
rpl_gtid.rpl_gtid_only_start_replica_after_clone
rpl_gtid.rpl_gtid_xa_commit_failure_before_gtid_externalization rpl_gtid.rpl_gtid_xa_commit_one_phase_failure_before_prepare_in_engines
rpl_gtid.rpl_gtid_xa_prepare_failure_before_prepare_in_engines
rpl_gtid.rpl_gtid_xa_rollback_failure_before_gtid_externalization
rpl_nogtid.rpl_assign_gtids_to_anonymous_transactions_clone rpl_nogtid.rpl_gtid_mode
rpl_nogtid.rpl_nogtid_encryption_read test_services.test_host_application_signal_plugin
&lt;/pre&gt;

&lt;p&gt;
As you can see the list is now significantly longer, indicating a more thorough test
run coverage of the diff. All this extra grepping takes about 90 seconds on my
machine, if some popular include files are touched. I have no idea whether that&#39;s
with hot or cold FS cache. I also don&#39;t know whether replacing &lt;code&gt;grep&lt;/code&gt; with &lt;code&gt;rg&lt;/code&gt; would
it make it faster.
&lt;/p&gt;

&lt;p&gt;
To minimize the false positives in included file search, grep considers the lines
that don&#39;t start with the MTR language comment character &lt;code&gt;#&lt;/code&gt;, and are like
&lt;code&gt;...source...basename-of-included-file&lt;/code&gt;. This allows false positives in indented
comments and inside string literals (that one should be rare) and it cannot tell
apart files with the same name in different directories. In theory it also allows
false negatives if an include file is referenced using a string variable to store its
name. Any suggestions for better
regexps are welcome.
&lt;/p&gt;

&lt;p&gt;
It goes without saying that it is best applied on test-only patches. If you touch the
source code, then you should be looking at whole MTR runs, or, if possible, MTR runs
of selected suites. But if you are indeed working on a test-only patch, this script
reduces the required test time effectively.
&lt;/p&gt;

&lt;p&gt;
Should be portable but currently tested on macOS only. Feedback is welcome!
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/5630060434048230513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/5630060434048230513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/5630060434048230513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/5630060434048230513'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/01/introducing-patch2testlist-for-mysql.html' title='Introducing patch2testlist for MySQL development'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-6125297438311057883</id><published>2024-01-24T16:04:00.001+02:00</published><updated>2024-01-24T16:04:17.345+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Building and testing MySQL 8.0.36 and 8.3.0 on macOS</title><content type='html'>&lt;p&gt;
The previous releases (8.0.35 and 8.2.0) resulted in me &lt;a href=&quot;https://of-code.blogspot.com/2023/12/mysql-8035-and-820-are-out-here-are-my.html&quot;&gt;reporting fifteen bugs&lt;/a&gt;. Let&#39;s
find out whether 8.0.36 and 8.3.0 will fare better on an M1 Mac.
&lt;/p&gt;

&lt;p&gt;
Let&#39;s start with the build. Boost goes away as an external dependency in 8.3.0,
removing the need to specify Boost-related CMake options, good. The server continues
to build successfully with &lt;code&gt;-DWITH_SYSTEM_LIBS=ON&lt;/code&gt; but now started requiring
&lt;code&gt;-DWITH_ZLIB=bundled&lt;/code&gt;, because 8.3.0 made the system libraries option govern zlib
too, and the one in XCode is one patch level version too old. The Homebrew-installed
version is ignored.
&lt;/p&gt;

&lt;p&gt;
8.0.36 Release configuration builds with a single potentially-fatal warning: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113662&quot;&gt;bug
#113662&lt;/a&gt; (NDB compilation error on macOS Release build). Finding this made me look,
why is NDB built at all, if I did not add &lt;code&gt;-DWITH_NDB=ON&lt;/code&gt;? This resulted in &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113661&quot;&gt;bug
#113661&lt;/a&gt; (NDB storage engine built ignoring -DWITH_NDB=OFF (which is OFF by default
too)).
&lt;/p&gt;

&lt;p&gt;
The most serious build-related issue I saw previously was incorrect query results if
compiled with LLVM 15 and newer, reported as &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113049&quot;&gt;bug #113049&lt;/a&gt; (MTR test json.array_index
fails with a result difference) and &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113046&quot;&gt;bug #113046&lt;/a&gt; (MTR tests for SELECT fail with ICP,
MRR, possibly other flags). This issue has been fixed, although the bugs are still
open (thus no release notes entries neither). As Tor Didriksen explained, they are
open due to still remaining issues with recent MSVC compilers. But, LLVM works fine
for me now and that&#39;s great.
&lt;/p&gt;

&lt;p&gt;
The previous releases also required &lt;code&gt;-ffp-contract=off&lt;/code&gt; compilation flag workaround
to take care of some failures: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113047&quot;&gt;bug #113047&lt;/a&gt; (MTR test main.derived_limit fails with
small cost differences), &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113048&quot;&gt;bug #113048&lt;/a&gt; (MTR test gis.gis_bugs_crashes fails with a
result difference). This has been mostly addressed, except that #113047 is fixed in
8.0.36 and 8.4.0 but not 8.3.0, so that failure still remains if the workaround is
dropped.
&lt;/p&gt;

&lt;p&gt;
The previous releases could not be compiled with LLVM 17, and no changes occurred
here, &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;bug #113123&lt;/a&gt; (Compilation fails with LLVM 17) still applies.
&lt;/p&gt;

&lt;p&gt;
Moving on to tests in Release, Debug, and Debug+ASan+UBsan configurations. Looking
better than the last time, this is what I had to report:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113665&quot;&gt;https://bugs.mysql.com/bug.php?id=113665&lt;/a&gt; (perfschema.relaylog fails with a result
difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113702&quot;&gt;https://bugs.mysql.com/bug.php?id=113702&lt;/a&gt; (Test binlog.binlog_error_action fails
under Sanitizer build)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113703&quot;&gt;https://bugs.mysql.com/bug.php?id=113703&lt;/a&gt; (Test innodb.ddl_kill fails under
Sanitizer build)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113704&quot;&gt;https://bugs.mysql.com/bug.php?id=113704&lt;/a&gt; (Test main.log_backtrace fails under
Sanitizer build)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113709&quot;&gt;https://bugs.mysql.com/bug.php?id=113709&lt;/a&gt; (StrXfrmTest.ChineseUTF8MB4 failing with
an AddressSanitizer error)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113710&quot;&gt;https://bugs.mysql.com/bug.php?id=113710&lt;/a&gt;
(Spec/HttpClientSecureTest.ensure/default_client_cipher_succeeds ASan error)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113722&quot;&gt;https://bugs.mysql.com/bug.php?id=113722&lt;/a&gt; (Test main.index_merge_innodb failing with
a result difference)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113736&quot;&gt;https://bugs.mysql.com/bug.php?id=113736&lt;/a&gt; (Test main.qualify_hypergraph failing with
a result difference)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
So, to sum up, 10 bugs reported, 4 bugs confirmed fixed, 5 bugs (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;#113123&lt;/a&gt;, &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;#113260&lt;/a&gt;,
&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;#113189&lt;/a&gt;, &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;#113190&lt;/a&gt;, &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113258&quot;&gt;#113258&lt;/a&gt;) have no changes, and 1 bug (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;#113023&lt;/a&gt;) I did not test.
&lt;/p&gt;

&lt;p&gt;
All in all, this looks OK. While no perfect clean testsuite results I was used to in
some older releases, no miscompilation-like bugs neither, and that&#39;s fine.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/6125297438311057883/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/6125297438311057883' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/6125297438311057883'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/6125297438311057883'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/01/building-and-testing-mysql-8036-and-830.html' title='Building and testing MySQL 8.0.36 and 8.3.0 on macOS'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-687089038911854743</id><published>2024-01-11T17:16:00.003+02:00</published><updated>2024-01-11T17:16:58.797+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>MySQL clone plugin internals and MyRocks clone design</title><content type='html'>&lt;p&gt;I just realized that about MySQL and MyRocks clone I never actually published anything more serious &lt;a href=&quot;https://www.facebook.com/kastauyra/posts/pfbid036Efs1CoQuYqRNKxNNxxdCjhCrd9EgEGPE2zANyVXYwGiSEqtmVrAmcngtxAJ4whil&quot;&gt;than a single-emoji post on Facebook&lt;/a&gt;, a link to an &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109926&quot;&gt;Oracle umbrella bug&lt;/a&gt;, and this&amp;nbsp;&lt;a href=&quot;https://twitter.com/kastauyra/status/1689155611638800384&quot;&gt;tweet&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So, let&#39;s talk about clone. MySQL has a &lt;a href=&quot;https://dev.mysql.com/doc/refman/8.0/en/clone-plugin.html&quot;&gt;clone plugin&lt;/a&gt; which can be used to copy new instances from existing ones, and it&#39;s also integrated into group replication for the same purpose. In Oracle releases this plugin copies only InnoDB tables, making the feature unsuitable for MyRocks instances.&lt;/p&gt;&lt;p&gt;Now MyRocks is the first storage engine, besides InnoDB, to get the clone support, and it works on mixed MyRocks/InnoDB instances while ensuring that the cloned instances are consistent across engines too. The code is in &lt;a href=&quot;https://github.com/facebook/mysql-5.6/&quot;&gt;Meta&#39;s branch&lt;/a&gt;, I don&#39;t believe there are any user docs (but MyRocks support is so seamless that Oracle docs suffice! Only half-joking here), but there are IMHO extensive internals docs at Meta&#39;s wiki:&amp;nbsp;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/wiki/MyRocks-Clone-Plugin&quot;&gt;MyRocks Clone Plugin&lt;/a&gt;.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Their scope is broader than the title might suggest. Not only the MyRocks clone design is discussed, but there is also a clone background section, which discusses how clone works internally and fully applies to the Oracle branches too.&lt;/p&gt;&lt;p&gt;Like with all things 3rd party storage engines, it is rare to develop a feature without having to patch the server (or in this case server, clone, &amp;amp; InnoDB plugins). The details of this patch are also discussed in the Wiki, and also in the aforementioned &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=109926&quot;&gt;Oracle umbrella bug&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Last but not least, with background and patches elsewhere out of the way, the Wiki has the design of MyRocks clone proper.&lt;/p&gt;&lt;p&gt;I hope the feature will reach MyRocks downstreams one day. Since MariaDB currently has no clone plugin, that leaves Percona Server. Maybe these docs will help with the porting, and also for advanced end-user troubleshooting. Clone away!&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/687089038911854743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/687089038911854743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/687089038911854743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/687089038911854743'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2024/01/mysql-clone-plugin-internals-and.html' title='MySQL clone plugin internals and MyRocks clone design'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-6944022519859966042</id><published>2023-12-14T17:45:00.003+02:00</published><updated>2023-12-14T17:45:52.695+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>MySQL 8.0.35 and 8.2.0 are out, here are my 15 compilation/test bug reports</title><content type='html'>&lt;p&gt;I&#39;m only a month and a half late to the party. That&#39;s, unfortunately, because I tried to build it and run its tests, on macOS, of all things. First the good news: it builds, and does so with the maximum set of 3rd party libraries possible.&lt;/p&gt;&lt;p&gt;Next I tried running the testsuite. I am used to clean test results in Oracle releases, under good conditions at least (not too heavy a load on the system, not too high a &lt;span style=&quot;font-family: courier;&quot;&gt;--parallel&lt;/span&gt; setting), with only occasional issues. This time I saw dozens of failures under debug, debug+sanitizers, release configurations, and tried to convert them to bug reports, best-effort.&lt;/p&gt;&lt;p&gt;First I identified a Homebrew-packaged Perl incompatibility with a test script: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113023&quot;&gt;https://bugs.mysql.com/bug.php?id=113023&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Then I had a couple of test output differences where the difference was in floating point values: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113047&quot;&gt;https://bugs.mysql.com/bug.php?id=113047&lt;/a&gt; (MTR test main.derived_limit fails with small cost differences) and &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113048&quot;&gt;https://bugs.mysql.com/bug.php?id=113048&lt;/a&gt; (MTR test gis.gis_bugs_crashes fails with a result difference). I am not a floating point programming expert, but somewhat luckily I remembered that there is a GCC option &lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-ffp-contract&quot;&gt;-ffp-contract=off&lt;/a&gt;, and that MySQL CMake script checks whether to add it. On a hunch that maybe the CMake test is incomplete (it is Linux-only and I was on macOS) I tried adding it as a workaround and it worked!&lt;/p&gt;&lt;p&gt;The next set of bugs was nastier. A bunch of query optimizer tests were failing with incorrect query results (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113046&quot;&gt;https://bugs.mysql.com/bug.php?id=113046&lt;/a&gt;), and so did a JSON array test (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113049&quot;&gt;https://bugs.mysql.com/bug.php?id=113049&lt;/a&gt;). To find the triggering conditions I tried different compilers, and, found that the tests pass if compiled with LLVM 14 and fail with LLVM 15, 16, 17, and XCode 15. I had no idea whether this is a compiler bug, MySQL undefined behavior, or something else, but Tor Didriksen posted on &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113049&quot;&gt;#113049&lt;/a&gt; that &quot;Recent versions of Clang have changed their implementation of std::sort(), and our own &#39;varlen_sort()&#39; function returns wrong results.&quot;, one less mystery then.&lt;/p&gt;&lt;p&gt;Checking those different compiler versions was not trivial, because Homebrew-packaged LLVM 14 to 17 fail to build MySQL: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113113&quot;&gt;https://bugs.mysql.com/bug.php?id=113113&lt;/a&gt;. Something about some incompatibility between system &lt;span style=&quot;font-family: courier;&quot;&gt;ar&lt;/span&gt; and LLVM &lt;span style=&quot;font-family: courier;&quot;&gt;ranlib&lt;/span&gt; utilities, with a workaround to use the&amp;nbsp;&lt;span style=&quot;font-family: courier;&quot;&gt;ar&lt;/span&gt; coming from LLVM, i.e. &lt;span style=&quot;font-family: courier;&quot;&gt;-DCMAKE_AR=/opt/homebrew/opt/llvm@16/bin/llvm-ar&lt;/span&gt;. My &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/blob/master/mysql-work/.zsh.d/rc/mysql-work.sh&quot;&gt;build script&lt;/a&gt;&amp;nbsp;is at 700 lines now, and that&#39;s already with some parts factored out.&lt;/p&gt;&lt;p&gt;On the top of the previous bug, LLVM 17, being new, had its regular and expected share of new warnings/errors: &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113123&quot;&gt;https://bugs.mysql.com/bug.php?id=113123&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Back from the build-with-different-compilers detour, there were still some test failures unaccounted: a debug assertion in group replication (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113257&quot;&gt;https://bugs.mysql.com/bug.php?id=113257&lt;/a&gt;), all the TLS 1.3-using tests failing (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113258&quot;&gt;https://bugs.mysql.com/bug.php?id=113258&lt;/a&gt;), spam in the replicating server error log (&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113260&quot;&gt;https://bugs.mysql.com/bug.php?id=113260&lt;/a&gt;).&lt;/p&gt;&lt;p&gt;At this point I stopped processing MTR tests, as I had already logged many bugs, and it became harder to avoid duplicates, so thought I could look at the unit tests. Here I&#39;ll just give a list of partial findings:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113189&quot;&gt;https://bugs.mysql.com/bug.php?id=113189&lt;/a&gt; (ColumnStatisticsTest.StoreAndRestoreAttributesEquiHeight unit test fails)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113190&quot;&gt;https://bugs.mysql.com/bug.php?id=113190&lt;/a&gt; (Several tests in routertest_integration_routing_sharing_constrained_pools fail)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113420&quot;&gt;https://bugs.mysql.com/bug.php?id=113420&lt;/a&gt; (testNdbProcess fails under ASan+UBSan)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113421&quot;&gt;https://bugs.mysql.com/bug.php?id=113421&lt;/a&gt; (HistogramsTest.DecimalSingletonToJSON fails under sanitizer build)&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=113422&quot;&gt;https://bugs.mysql.com/bug.php?id=113422&lt;/a&gt;&amp;nbsp;(Handler_test.TableCreateReturnsRecordFileFullWhenTempTableAllocatorThrowsRecordF) - the test name is longer than the bug title length limit.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;That&#39;s why it took me ~six weeks (and fifteen bug reports) to celebrate the new MySQL releases. That&#39;s halfway to the next expected release date on the quarterly schedule, and I hope I will be able to write a much shorter blog post much sooner after that release, as usual!&lt;/p&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/6944022519859966042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/6944022519859966042' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/6944022519859966042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/6944022519859966042'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2023/12/mysql-8035-and-820-are-out-here-are-my.html' title='MySQL 8.0.35 and 8.2.0 are out, here are my 15 compilation/test bug reports'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-830659631465065142</id><published>2023-10-23T18:14:00.000+03:00</published><updated>2023-10-23T18:14:29.473+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c++"/><category scheme="http://www.blogger.com/atom/ns#" term="rust"/><title type='text'>Strong typing: comparing Rust newtype to C++</title><content type='html'>&lt;p&gt;
Rust source code often makes heavy use of the newtype idiom, where a new type is
created for an underlying primitive type to differentiate it from other uses of the
same underlying type. The term &quot;newtype&quot; comes from Haskell where it&#39;s not an idiom,
but a keyword, thus a built-in language feature.
&lt;/p&gt;

&lt;p&gt;
I was wondering why I never heard of newtype as a C++ developer, because C++ is
obviously a strongly-typed language, where the same issue exists. There are different
ways to approach it and this is my attempt to get the thoughts on the topic in order,
there will be no earth-shattering insights.
&lt;/p&gt;

&lt;div id=&quot;outline-container-org8bdbe6d&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org8bdbe6d&quot;&gt;Rust: newtype&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org8bdbe6d&quot;&gt;
&lt;p&gt;
Suppose you are developing a database and have transaction IDs and log sequence
numbers. Both are &lt;code&gt;u64&lt;/code&gt; but are not interoperable in any way. So in Rust, a natural
implementation would be to apply newtype idiom twice:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-rust&quot;&gt;pub struct TransactionId(u64);

impl TransactionId {
    fn new(id: u64) -&amp;gt; Self {
        Self(id)
    }

    fn get(&amp;amp;self) -&amp;gt; u64 {
      self.0
    }
    ...
}

impl fmt::Display for TransactionId { ... }

pub struct LogSequenceNumber(u64);

impl LogSequenceNumber { ... }
...
&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;
Let&#39;s enumerate the options in C++.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orge7f507c&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orge7f507c&quot;&gt;C++: do nothing&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orge7f507c&quot;&gt;
&lt;p&gt;
Do nothing, and use &lt;code&gt;std::uint64_t&lt;/code&gt; for both types. No compiler protection, no
documentation at the type name, thus the most bug-prone option. Obviously there is
nothing to stop us from using this same option in Rust too.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-orgb6f9461&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;orgb6f9461&quot;&gt;C++: use type aliases&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgb6f9461&quot;&gt;
&lt;p&gt;
Introduce type aliases:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;// Can also be done with typedef, but let&#39;s stick to modern C++:
using transaction_id = std::uint64_t;
using log_sequence_number = std::uint64_t;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
This expresses the intent, documents things whenever the type name appears, and is
not too verbose. The downside is that it does not introduce new types, only aliases
for existing ones, meaning that transaction IDs assign to LSNs and back freely.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div id=&quot;outline-container-org93bb165&quot; class=&quot;outline-2&quot;&gt;
&lt;h2 id=&quot;org93bb165&quot;&gt;C++: introduce new types&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org93bb165&quot;&gt;
&lt;p&gt;
Introduce new types. Like in Rust, differently-named structs with identical fields can
be used.
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;struct transaction_id {
  std::uint64_t val;
}

struct log_sequence_id {
  std::uint64_t val;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Now type safety is increased and the type mix-up is prevented by the compiler. But so
are most operations with type variables, requiring writing extra code to have the
desired functionality, compared to the first two options. Writing this extra code
will be more verbose than the same in Rust because the latter has support for traits,
which can have default implementations.
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;struct log_sequence_id {
  ...
  // explicit is important, we don&#39;t want to make the incompatible types
  // implicitly-covertable again inadvertently
  explicit log_sequence_id(std::uint64_t v) : val{v} {}

  log_sequence_id&amp;amp; operator += (std::size_t log_delta) {
    val += log_delta;
    return *this;
  }
  ...
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Naturally, limiting available operations is advantageous too, in both languages. For
example, it makes no sense to add two transaction IDs together.
&lt;/p&gt;

&lt;p&gt;
Since this is C++, meaning that we have the template-hammer, making all the problems
look like template-nails for better or worse, we could try avoiding spelling out
structs every time:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;// Written this way only to show a point. The actual implementation would be more
// complex to be able to handle move-only types and wrap large objects efficiently.
template&amp;lt;typename T, typename Tag&amp;gt;
class newtype {
 public:
  explicit newtype(T v) : val{v} {}
  void set(T v) { val = v; }
  T get() const { return val; }
 private:
  T val;
};

struct log_sequence_id_tag{};
using log_sequence_id = newtype&amp;lt;std::uint64_t, log_sequence_id_tag&amp;gt;;

struct transaction_id_tag{};
using transaction_id = newtype&amp;lt;std::uint64_t, transaction_id_tag&amp;gt;;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Now introducing a newtype is reduced to two lines of code. Again, C++ developers do
not usually discuss newtype but they do discuss &lt;a href=&quot;https://stackoverflow.com/questions/34287842/strongly-typed-using-and-typedef&quot;&gt;strongly-typed using and typedefs&lt;/a&gt;,
which is the same thing, called differently.
&lt;/p&gt;

&lt;p&gt;
In most cases we are wrapping a single value of a primitive or string type. Those
wrapped values are then operated using free functions or methods of some other
classes. Thus, in this setting, this is a great option and we are done. But suppose
we want to add some methods to the newly-introduced type instead of using free
functions. The &lt;code&gt;newtype&lt;/code&gt; template will not allow this, not unless we introduce
inheritance:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;using log_sequence_id_base = newtype&amp;lt;std::uint64_t, log_sequence_id_tag&amp;gt;;

class log_sequence_id : public log_sequence_id_base {
   ...
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
At which point the use of the &lt;code&gt;newtype&lt;/code&gt; template becomes questionable and the code
simplifies by folding the value into the class:
&lt;/p&gt;
&lt;div class=&quot;org-src-container&quot;&gt;
&lt;pre class=&quot;src src-c++&quot;&gt;class log_sequence_id {
 public:
  ...
 private:
  std::uint64_t value;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
Here we are back to creating a new type manually, just like before, without
templates. This seems to be different from Rust, where a single-field struct will
clearly show its newtype origins in the declaration, regardless of how much
functionality it acquired later on.
&lt;/p&gt;

&lt;p&gt;
So, there you have it. Both languages are strongly typed and have means to introduce
new distinct types built on the existing ones, with Rust calling this newtype, and
developers having a choice in C++ between type aliases, which don&#39;t actually increase
type safety, to succinct templates and verbose types with some trade-offs.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/830659631465065142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/830659631465065142' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/830659631465065142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/830659631465065142'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2023/10/strong-typing-comparing-rust-newtype-to.html' title='Strong typing: comparing Rust newtype to C++'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-695924504281948775</id><published>2023-09-25T15:31:00.005+03:00</published><updated>2023-09-28T16:56:02.687+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>Implementing durability in a MySQL storage engine</title><content type='html'>&lt;p&gt;&lt;b&gt;update 2023-09-28&lt;/b&gt;: edited for non-durable SE commits under group commit, and fixed the &lt;code&gt;trx-&amp;gt;flush_log_later&lt;/code&gt; discussion.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;update 2023-09-27&lt;/b&gt;: Binlog group commits asks the storage engines to commit non-durably, will edit the post even more.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;update 2023-09-26&lt;/b&gt;: &lt;code&gt;trx-&amp;gt;flush_log_later&lt;/code&gt; is actually used. Will edit the post.&lt;/p&gt;

&lt;p&gt;
Let&#39;s review how a MySQL storage engine should implement transaction durability by
flushing / syncing WAL writes to disk. For performance reasons (group 2PC), let&#39;s
also review when it specifically should &lt;i&gt;not&lt;/i&gt; sync writes to disk. The reference
durability implementation is, of course, InnoDB.
&lt;/p&gt;

&lt;p&gt;
The main storage engine entry point is &lt;code&gt;handlerton::commit&lt;/code&gt;. Since in general the
storage engines participate in two-phase commit protocol with the binary log, there
is also &lt;code&gt;handlerton::prepare&lt;/code&gt;, and &lt;code&gt;handlerton::flush_logs&lt;/code&gt; participates too. Let&#39;s
ignore rollbacks, savepoints, explicit XA transactions, read only transactions,
transactions on temporary tables only, crash recovery, and transaction coordinators
other than the binlog.
&lt;/p&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-orge916e8a&quot;&gt;
&lt;h2 id=&quot;orge916e8a&quot;&gt;Background: Group Commit&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orge916e8a&quot;&gt;
&lt;p&gt;
It was implemented (&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=5223&quot;&gt;WL#5223&lt;/a&gt;) in its current form in MySQL 5.6, and its internals are
described in this &lt;a href=&quot;http://mysqlmusings.blogspot.com/2012/06/binary-log-group-commit-in-mysql-56.html&quot;&gt;Mats Kindahl&#39;s blog post&lt;/a&gt;. I will not repeat everything here (and
I&#39;m sure I&#39;d miss a lot of details), but for durability discussion, from the storage
engine side, the group commit looks as follows:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;prepare(t1)&lt;/code&gt; with reduced durability;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prepare(t2)&lt;/code&gt; with reduced durability;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;prepare(tn)&lt;/code&gt; with reduced durability;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;flush_logs()&lt;/code&gt;, making all the prepares above durable;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;commit(t1)&lt;/code&gt; with reduced durability;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;commit(t2)&lt;/code&gt; with reduced durability;&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;li&gt;&lt;code&gt;commit(tn)&lt;/code&gt; with reduced durability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A surprise here is that the commits are performed with reduced durability too. How do reduced-durability commits implement full durability for the committed transactions, then? Turns out, the design of binlog group commit is only the commit of binlog itself is durable, and for the storage engines, prepares are made durable in batches and that&#39;s it. If their commits are lost, binlog crash recovery will roll forward the prepared transactions.&lt;/p&gt;
  
&lt;p&gt;This design is counterintuitive if one thinks that &lt;code&gt;innodb-flush-log-at-trx-commit=1&lt;/code&gt;, as documented, makes InnoDB commits durable in this setup, which it does not, and it is possible to see binlog crash recovery in action. Davi Arnaut reported this as &lt;a href=&quot;https://bugs.mysql.com/bug.php?id=75519&quot;&gt;bug #75519&lt;/a&gt; in 2015, and IMHO few users are aware of this behavior.&lt;/p&gt;
  
&lt;p&gt;
Anyway, back to the implementation. Apparently the server developers did not want to change the prepare/commit handlerton
interface, so the server durability request (full or reduced) is not passed in as an
argument, but must be queried by &lt;code&gt;thd_get_durability_property&lt;/code&gt; returning an &lt;code&gt;enum&lt;/code&gt;
with two possible values &lt;code&gt;HA_REGULAR_DURABILITY&lt;/code&gt; and &lt;code&gt;HA_IGNORE_DURABILITY&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Later, in 8.0, this durability property was reused to implement correct &amp;amp; performant
commit order on multithreaded replicas, when binlog is disabled (&lt;a href=&quot;https://dev.mysql.com/worklog/task/?id=7846&quot;&gt;WL#7846&lt;/a&gt;).
&lt;/p&gt;

&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-orgb9ced08&quot;&gt;
&lt;h2 id=&quot;orgb9ced08&quot;&gt;InnoDB: &lt;code&gt;handlerton::commit&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgb9ced08&quot;&gt;
&lt;p&gt;
Implemented by &lt;code&gt;innobase_commit&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Comes last in the group commit, but let&#39;s review it first. In other setups it might
be the only entry point.
&lt;/p&gt;


&lt;p&gt;
Wherever I say &quot;write [to the disk] and sync|flush&quot;, the mental model is that of a
buffered write with a separate flush/sync afterwards. If &lt;code&gt;O_SYNC&lt;/code&gt; or &lt;code&gt;O_DSYNC&lt;/code&gt; is
used to write the log instead, then the write and the sync are a single operation.
&lt;/p&gt;

&lt;p&gt;Let&#39;s ignore non-default &lt;code&gt;innobase_commit_concurrency&lt;/code&gt; setups.&lt;/p&gt;

&lt;p&gt;
First the code sets &lt;code&gt;trx-&amp;gt;flush_log_later&lt;/code&gt; and then goes through the call stack &lt;code&gt;innobase_commit&lt;/code&gt; -&amp;gt; &lt;code&gt;innobase_commit_low&lt;/code&gt; -&amp;gt;
&lt;code&gt;trx_commit_for_mysql&lt;/code&gt; -&amp;gt; &lt;code&gt;trx_commit&lt;/code&gt; -&amp;gt; &lt;code&gt;trx_commit_low&lt;/code&gt;. The last one calls
&lt;code&gt;trx_write_serialisation_history&lt;/code&gt;, which makes the necessary commit writes to a
mini-transaction, then &lt;code&gt;trx_commit_low&lt;/code&gt; commits the mini-transaction by creating the
redo log records. Nothing is done for durability yet at this point. Finally
&lt;code&gt;trx_commit_low&lt;/code&gt; calls &lt;code&gt;trx_commit_in_memory&lt;/code&gt;, which sees that &lt;code&gt;trx-&amp;gt;flush_log_later&lt;/code&gt; is set and sets &lt;code&gt;trx-&amp;gt;must_flush_log_later&lt;/code&gt;. (if &lt;code&gt;trx_commit&lt;/code&gt; is called from other API than SE commit, then &lt;code&gt;flush_log_later&lt;/code&gt; will not be set and the durability will be ensured in this function).
&lt;/p&gt;

&lt;p&gt;
At this point the callstack returns all the way back to &lt;code&gt;innobase_commit&lt;/code&gt;, which calls
&lt;code&gt;trx_complete_for_mysql&lt;/code&gt;, which now checks &lt;code&gt;trx-&amp;gt;must_flush_log_later&lt;/code&gt; (set), durability request (reduced), and whether this is a DDL transaction. If it is not, then nothing is done, and InnoDB reports the commit as successful. If it is a DDL transaction, then log is flushed ignoring the reduced durability request and &lt;code&gt;innodb_flush_log_at_trx_commit&lt;/code&gt; setting..
&lt;/p&gt;

&lt;p&gt;
The above mentioned that DDL transactions are flushed more than regular ones,
regardless of &lt;code&gt;innodb_flush_log_at_trx_commit&lt;/code&gt; setting. This is a deliberate design
decision, which has to do with the data dictionary, I believe. To understand why, consider the relevant parts of server startup sequence:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;InnoDB comes up, and performs its own recovery from its redo log.&lt;/li&gt;&lt;li&gt;Server data dictionary is initialized.&lt;/li&gt;&lt;li&gt;Binlog crash recovery runs.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;If any DD transactions are trapped in prepared state by the time of the data dictionary initialization, they will be invisible, while their disk changes (e.g. a tablespace renamed on disk) will be present on disk. This inconsistency is likely to be fatal for the DD, and binlog crash recovery runs too late to recover from that.&lt;/div&gt;&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-org36a3361&quot;&gt;
&lt;h2 id=&quot;org36a3361&quot;&gt;InnoDB: &lt;code&gt;handlerton::prepare&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-org36a3361&quot;&gt;
&lt;p&gt;
Implemented by &lt;code&gt;innobase_xa_prepare&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
It calls &lt;code&gt;trx_prepare_for_mysql&lt;/code&gt; -&amp;gt; &lt;code&gt;trx_prepare&lt;/code&gt; -&amp;gt; &lt;code&gt;trx_prepare_low&lt;/code&gt;, which updates
the undo log state for the transaction a mini-transaction, committing which makes the
top-level transaction prepared. Then &lt;code&gt;trx_prepare&lt;/code&gt; calls &lt;code&gt;trx_flush_logs&lt;/code&gt;, which will
either do nothing or write and flush the redo log up to the mini-transaction&#39;s commit
LSN, depending on the server durability request.
&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;

&lt;div class=&quot;outline-2&quot; id=&quot;outline-container-orgf07b179&quot;&gt;
&lt;h2 id=&quot;orgf07b179&quot;&gt;InnoDB: &lt;code&gt;handlerton::flush_logs&lt;/code&gt;&lt;/h2&gt;
&lt;div class=&quot;outline-text-2&quot; id=&quot;text-orgf07b179&quot;&gt;
&lt;p&gt;
Implemented by &lt;code&gt;innobase_flush_logs&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
It has a bool argument telling whether it was invoked as a part of binlog group
commit, which is the interesting case here, ignoring the other option of it being
invoked by &lt;code&gt;FLUSH LOGS&lt;/code&gt; SQL statement. It writes the redo log buffer to disk and
flushes it according it to &lt;code&gt;innodb_flush_log_at_trx_commit&lt;/code&gt; value.
&lt;/p&gt;

&lt;p&gt;
Bugs reported while writing this:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=112456&quot;&gt;https://bugs.mysql.com/bug.php?id=112456&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div&gt;Bugs found while writting this:&lt;/div&gt;&lt;div&gt;&lt;ul style=&quot;text-align: left;&quot;&gt;&lt;li&gt;&lt;a href=&quot;https://bugs.mysql.com/bug.php?id=75519&quot;&gt;https://bugs.mysql.com/bug.php?id=75519&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;

&lt;p&gt;
Bugs that made me write this:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/facebook/mysql-5.6/issues/1370&quot;&gt;https://github.com/facebook/mysql-5.6/issues/1370&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;

</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/695924504281948775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/695924504281948775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/695924504281948775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/695924504281948775'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2023/09/implementing-durability-in-mysql.html' title='Implementing durability in a MySQL storage engine'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-36536015.post-4766550374594144098</id><published>2023-08-25T16:02:00.000+03:00</published><updated>2023-08-25T16:21:45.535+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c++"/><category scheme="http://www.blogger.com/atom/ns#" term="mysql"/><title type='text'>MySQL Build Times: Use Ninja</title><content type='html'>&lt;p&gt;
I had noticed &lt;a href=&quot;https://ninja-build.org&quot;&gt;Ninja&lt;/a&gt; as one of the possible CMake generators long time ago, but never
paid attention to it, as I could not imagine it being better than Make so much that
it&#39;d be worth switching. Then, when I posted my &lt;a href=&quot;https://of-code.blogspot.com/2023/04/mysql-clang-ftime-trace.html&quot;&gt;MySQL -ftime-trace results&lt;/a&gt;, I got a
&lt;a href=&quot;https://www.linkedin.com/feed/update/urn:li:activity:7057357977371959296?commentUrn=urn%3Ali%3Acomment%3A%28activity%3A7057357977371959296%2C7057581403776921600%29&quot;&gt;comment on LinkedIn&lt;/a&gt; that Ninja visualizes build time nicely. I tried that, and it
did, and I went back to Make builds.
&lt;/p&gt;

&lt;p&gt;
A few months later, I am looking at &lt;a href=&quot;https://vittorioromeo.info&quot;&gt;Vittorio Romeo&#39;s&lt;/a&gt; &quot;Improving Compilation Times&quot;
presentation &lt;a href=&quot;https://github.com/italiancpp/itcppcon23/blob/main/Improving%20compilation%20times%20-%20Vittorio%20Romeo.pdf&quot;&gt;slides&lt;/a&gt; (download them, do not read inline on GitHub; there is also the
talk video &lt;a href=&quot;https://www.youtube.com/watch?v=PfHD3BsVsAM&quot;&gt;itself&lt;/a&gt;), and the very first low-hanging fruit advice is &quot;use Ninja&quot;.
&lt;/p&gt;

&lt;p&gt;
OK, so let&#39;s actually try, say, Debug build on Facebook MySQL 8.0.28:
&lt;/p&gt;
&lt;ul class=&quot;org-ul&quot;&gt;
&lt;li&gt;&lt;code&gt;make -j13&lt;/code&gt;: 4m43s&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ninja&lt;/code&gt;: 4m17s&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
A 10% improvement with roughly zero effort is nice. There are other niceties too: you
don&#39;t have to figure out the right make parallelism argument for &lt;code&gt;-j&lt;/code&gt;, as Ninja
handles that automatically, and the terminal is not spammed with the build log of all
the source files that have been built uneventfully. Only compiler warnings and any
irregular build output is there.
&lt;/p&gt;

&lt;p&gt;
To use it, add &lt;code&gt;-G Ninja&lt;/code&gt; to CMake invocation, and then use &lt;code&gt;ninja&lt;/code&gt; instead of &lt;code&gt;make&lt;/code&gt;
to build. I have &lt;a href=&quot;https://github.com/laurynas-biveinis/dotfiles/commit/777dc9889524af7e4bf8f95e225a70341c8333dd&quot;&gt;patched my scripts&lt;/a&gt;.
&lt;/p&gt;
</content><link rel='replies' type='application/atom+xml' href='http://of-code.blogspot.com/feeds/4766550374594144098/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/36536015/4766550374594144098' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4766550374594144098'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/36536015/posts/default/4766550374594144098'/><link rel='alternate' type='text/html' href='http://of-code.blogspot.com/2023/08/mysql-build-times-use-ninja.html' title='MySQL Build Times: Use Ninja'/><author><name>Laurynas</name><uri>http://www.blogger.com/profile/09696674827789424795</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>