Skip to content

ssl.cmake: fix version regex for OpenSSL 1.0.2. #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

ssl.cmake: fix version regex for OpenSSL 1.0.2. #3

wants to merge 1 commit into from

Conversation

MikeMcQuaid
Copy link

OpenSSL 1.0.2 has whitespace between the # and define so make the regex more liberal to match it accordingly.

Should be backported to 5.6, 5.5 branches too.

Thanks!

CC Homebrew/legacy-homebrew#36205 @DomT4

OpenSSL 1.0.2 has whitespace between the # and define so make the regex more
liberal to match it accordingly.
@MikeMcQuaid
Copy link
Author

Oh, closing this as I see you're not accepting pull requests here (yet 😉).

@DomT4
Copy link

DomT4 commented Jan 25, 2015

@MikeMcQuaid MikeMcQuaid deleted the openssl-102-regex branch January 25, 2015 12:28
bkandasa pushed a commit that referenced this pull request Aug 4, 2015
…201 -> CRASH

BUG#20191813: MSR + MTS: IF WE HAVE ANY INACTIVE CHANNEL, POST RESTART START SLAVE HITS ER1794

(Patch and commit messages addapted from Rith's cset draft.)

Observations:
  1. Till 5.6, an active_mi always existed unless the server was started
     in bootstrap mode.
  2. Multisource introduces new mi<->rli for each channel.
  3. Combining above 2 points, MSR code was written in such a way that
     following shall hold for backward compatibility:
       a) create a default channel always (exept for bootstrap mode)
       b) Create all other channels.
  4. Bullet #3 above was accomplished like this:
       a) Read the repositories and create channels
       b) If default channel not created, create one.
  5. Initialiation of default channel failed when 4.i) failed.
  6. When 4.a) failed, we deleted the master_info for that channel

Notes about bug#19021091:
  - If proper postions are not given, --relay-log-recovery fails and
    hence initialization fails, after the behavioir introduced in
    bug#19021091
  - Hence 4.a) above failed.

The bug exists because the default channel was never created, thence
START SLAVE crashes as it expects a default channel and that is not
found.

The solution for this bug two-fold: (i) make sure that default channel
is always created in rpl_info_factory.cc; (ii) when the init of
repositories into master_info failed, don't delete the master info for
that channel.

Note:
- Seems that there is room for refactoring this part of the code, but
  this should be done outside of the scope of this bug.
- Fixed minor things in a couple of tests.
bjornmu pushed a commit that referenced this pull request Feb 5, 2016
Problem:

The binary log group commit sync is failing when committing a group of
transactions into a non-transactional storage engine while other thread
is rotating the binary log.

Analysis:

The binary log group commit procedure (ordered_commit) acquires LOCK_log
during the #1 stage (flush). As it holds the LOCK_log, a binary log
rotation will have to wait until this flush stage to finish before
actually rotating the binary log.

For the #2 stage (sync), the binary log group commit only holds the
LOCK_log if sync_binlog=1. In this case, the rotation has to wait also
for the sync stage to finish.

When sync_binlog>1, the sync stage releases the LOCK_log (to let other
groups to enter the flush stage), holding only the LOCK_sync. In this
case, the rotation can acquire the LOCK_log in parallel with the sync
stage.

For commits into transactional storage engine, the binary log rotation
checks a counter of "flushed but not yet committed" transactions,
waiting until this counter to be zeroed before closing the current
binary log file.  As the commit of the transactions happen in the #3
stage of the binary log group commit, the sync of the binary log in
stage #2 always succeed.

For commits into non-transactional storage engine, the binary log
rotation is checking the "flushed but not yet committed" transactions
counter, but it is zero because it only counts transactions that
contains XIDs. So, the rotation is allowed to take place in parallel
with the #2 stage of the binary log group commit. When the sync is
called at the same time that the rotation has closed the old binary log
file but didn't open the new file yet, the sync is failing with the
following error: 'Can't sync file 'UNOPENED' to disk (Errcode: 9 - Bad
file descriptor)'.

Fix:

For non-transactional only workload, binary log group commit will keep
the LOCK_log when entering #2 stage (sync) if the current group is
supposed to be synced to the binary log file.
bjornmu pushed a commit that referenced this pull request Apr 10, 2017
Author: Andrei Elkin <[email protected]>
Date:   Fri Nov 25 15:17:17 2016 +0200

    WL#9175 Correct recovery of DDL statements/transactions by binary log

    The patch consists of two parts implementing the WL agenda which is
    is to provide crash-safety for DDL.
    That is a server (a general one, master or slave) must be able to recover
    from crash to commit or rollback every DDL command that was in progress
    on the eve of crash.

    The Commit decision is done to commands that had reached
    Engine-prepared status and got successfully logged into binary log.
    Otherwise they are rolled back.

    In order to achieve the goal some refinements are done to the binlogging
    mechanism, minor addition is done to the server recovery module and some changes
    applied to the slave side.

    The binary log part includes Query-log-event which is made to contain xid
    that is a key item at server recovery. The recovery now is concern with it along
    with its standard location in Xid_log_event.

    The first part deals with the ACL DDL sub-class and
    TRIGGER related queries are fully 2pc-capable. It constructs
    the WL's framework which is proved on these subclasses.
    It also specifies how to cover the rest of DDLs by the WL's framework.
    For those not 2pc-ready DDL cases, sometimes "stub" tests are prepared
    to be refined by responsible worklogs.

    Take a few notes to the low-level details of implementation.

    Note #1.

    Tagging by xid number is done to the exact 2pc-capable DDL subclass.
    For DDL:s that will be ready for xiding in future, there is a tech specification
    how to do so.

    Note #2.

    By virtue of existing mechanisms, the slave applier augments the DDL
    transaction incorporating the slave info table update and the
    Gtid-executed table (either one optionally) at time of the DDL is
    ready for the final commit.
    When for filtering reason the DDL skips committing at its regular
    time, the augmented transaction would still be not empty consisting of
    only the added statements, and it would have to be committed by
    top-level slave specific functions through Log_event::do_update_pos().

    To aid this process Query_log_event::has_committed is introduced.

    Note #3 (QA, please read this.)

    Replication System_table interface that is employed by handler of TABLE type slave info
    had to be refined in few places.

    Note #4 (runtime code).

    While trying to lessen the footprint to the runtime server code few
    concessions had to be conceded. These include changes to
    ha_commit_trans()
    to invoke new pre_commit() and post_commit(), and post_rollback() hooks
    due to the slave extra statement.

    -------------------------------------------------------------------

    The 2nd part patch extends the basic framework,
    xidifies the rest of DDL commands that are
    (at least) committable at recovery. At the moment those include
    all Data Definition Statements except ones related to
    VIEWs, STORED Functions and Procedures.

    DDL Query is recoverable for these subclasses when it has been
    recorded into the binary log and was discovered there at the server
    restart, quite compatible with the DML algorithm.
    However a clean automatic rollback can't be provided for some
    of the commands and the user would have to complete recovery
    manually.
pobrzut pushed a commit that referenced this pull request May 8, 2017
akopytov pushed a commit to akopytov/mysql-server that referenced this pull request Aug 25, 2017
In WL-included builds ASAN run witnessed missed ~Query_log_event invocation.
The destruct-or was not called due to the WL's changes in the error propagation
that specifically affect LC MTS.
The failure is exposed in particular by rpl_trigger as the following
stack:

  #0 0x9ecd98 in __interceptor_malloc (/export/home/pb2/test/sb_2-22611026-1489061390.32/mysql-commercial-8.0.1-dmr-linux-x86_64-asan/bin/mysqld+0x9ecd98)
  mysql#1 0x2b1a245 in my_raw_malloc(unsigned long, int) obj/mysys/../../mysqlcom-pro-8.0.1-dmr/mysys/my_malloc.cc:209:12
  mysql#2 0x2b1a245 in my_malloc obj/mysys/../../mysqlcom-pro-8.0.1-dmr/mysys/my_malloc.cc:72
  mysql#3 0x2940590 in Query_log_event::Query_log_event(char const*, unsigned int, binary_log::Format_description_event const*, binary_log::Log_event_type) obj/sql/../../mysqlcom-pro-8.0.1-dmr/sql/log_event.cc:4343:46
  mysql#4 0x293d235 in Log_event::read_log_event(char const*, unsigned int, char const**, Format_description_log_event const*, bool) obj/sql/../../mysqlcom-pro-8.0.1-dmr/sql/log_event.cc:1686:17
  mysql#5 0x293b96f in Log_event::read_log_event()
  mysql#6 0x2a2a1c9 in next_event(Relay_log_info*)

Previously before the WL
Mts_submode_logical_clock::wait_for_workers_to_finish() had not
returned any error even when Coordinator thread is killed.

The WL patch needed to refine such behavior, but at doing so
it also had to attend log_event.cc::schedule_next_event() to register
an error to follow an existing pattern.
While my_error() does not take place the killed Coordinator continued
scheduling, ineffectively though - no Worker gets engaged (legal case
of deferred scheduling), and without noticing its killed status up to
a point when it resets the event pointer in
apply_event_and_update_pos():

  *ptr_ev= NULL; // announcing the event is passed to w-worker

The reset was intended for an assigned Worker to perform the event
destruction or by Coordinator itself when the event is deferred.
As neither is the current case the event gets unattended for its termination.

In contrast in the pre-WL sources the killed Coordinator does find a Worker.
However such Worker could be already down (errored out and exited), in
which case apply_event_and_update_pos() reasonably returns an error and executes

  delete ev

in exec_relay_log_event() error branch.

**Fixed** with deploying my_error() call in log_event.cc::schedule_next_event()
error branch which fits to the existing pattern.
THD::is_error() has been always checked by Coordinator before any attempt to
reset *ptr_ev= NULL. In the errored case Coordinator does not reset and
destroys the event itself in the exec_relay_log_event() error branch pretty similarly to
how the pre-WL sources do.

Tested against rpl_trigger and rpl suites to pass.

Approved on rb#15667.
akopytov pushed a commit to akopytov/mysql-server that referenced this pull request Aug 25, 2017
Some character sets are designated as MY_CS_STRNXFRM, meaning that sorting
needs to go through my_strnxfrm() (implemented by the charset), and some are
not, meaning that a client can do the strnxfrm itself based on
cs->sort_order. However, most of the logic related to the latter has been
removed already (e.g. filesort always uses my_strnxfrm() since 2003), and now
it's mostly in the way. The three main uses left are:

 1. A microoptimization for constructing sort keys in filesort.
 2. A home-grown implementation of Boyer-Moore for accelerating certain
    LIKE patterns that should probably be handled through FTS.
 3. Some optimizations to MyISAM prefix keys.

Given that our default collation (utf8mb4_0900_ai_ci) now is a strnxfrm-based
collation, the benefits of keeping these around for a narrow range of
single-byte locales (like latin1_swedish_ci, cp850 and a bunch of more
obscure locales) seems dubious. We seemingly can't remove the flag entirely
due to mysql#3 seemingly affecting the on-disk MyISAM structure, but we can remove
the code for mysql#1 and mysql#2.

Change-Id: If974e490d451b7278355e33ab1fca993f446b792
bjornmu pushed a commit that referenced this pull request Sep 21, 2017
Patch #3:

find_child_doms() has two kinds of duplicate elimination. One for
removing duplicates that occur due to multiple ellipses, and one for
removing duplicates that occur due to auto-wrapping on results
returned by an ellipsis.

The first kind of duplicate elimination is performed by maintaining a
sorted set of results. The second kind performs a linear search of the
results to see if the value is already in the result vector.

This patch consolidates this code so that they both use the first kind
of duplicate elimination. It also makes sure that duplicate
elimination for auto-wrapping only happens for paths that could
produce duplicates (only if the auto-wrapping path leg comes after an
ellipsis path leg).

This is just a code cleanup. The microbenchmark results are
indistinguishable from noise.

Microbenchmarks (64-bit, Intel Core i7-4770 3.4 GHz, GCC 6.3):

BM_JsonDomSearchEllipsis              25443 ns/iter [+1.0%]
BM_JsonDomSearchEllipsis_OnlyOne      17757 ns/iter [+0.7%]
BM_JsonDomSearchKey                     128 ns/iter [ 0.0%]
BM_JsonBinarySearchEllipsis          233469 ns/iter [-0.9%]
BM_JsonBinarySearchEllipsis_OnlyOne  226089 ns/iter [-1.5%]
BM_JsonBinarySearchKey                   86 ns/iter [ 0.0%]

Change-Id: Ia62916098096032adf9f2ecc70a42c845f625c1c
bjornmu pushed a commit that referenced this pull request Jan 23, 2018
…TABLE_UPGRADE_GUARD

To repeat: cmake -DWITH_ASAN=1 -DWITH_ASAN_SCOPE=1
./mtr --mem --sanitize main.dd_upgrade_error

A few dd tests fail with:
==26861==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7000063bf5e8 at pc 0x00010d4dbe8b bp 0x7000063bda40 sp 0x7000063bda38
READ of size 8 at 0x7000063bf5e8 thread T2
    #0 0x10d4dbe8a in Prealloced_array<st_plugin_int**, 16ul>::empty() const prealloced_array.h:186
    #1 0x10d406a8b in lex_end(LEX*) sql_lex.cc:560
    #2 0x10dae4b6d in dd::upgrade::Table_upgrade_guard::~Table_upgrade_guard() (mysqld:x86_64+0x100f87b6d)
    #3 0x10dadc557 in dd::upgrade::migrate_table_to_dd(THD*, std::__1::basic_string<char, std::__1::char_traits<char>, Stateless_allocator<char, dd::String_type_alloc, My_free_functor> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, Stateless_allocator<char, dd::String_type_alloc, My_free_functor> > const&, bool) (mysqld:x86_64+0x100f7f557)
    #4 0x10dad7e85 in dd::upgrade::migrate_plugin_table_to_dd(THD*) (mysqld:x86_64+0x100f7ae85)
    #5 0x10daec6a1 in dd::upgrade::do_pre_checks_and_initialize_dd(THD*) upgrade.cc:1216
    #6 0x10cd0a5c0 in bootstrap::handle_bootstrap(void*) bootstrap.cc:336

Change-Id: I265ec6dd97ee8076aaf03763840c0cdf9e20325b
Fix: increase lifetime of 'LEX lex;' which is used by 'table_guard'
bjornmu pushed a commit that referenced this pull request Oct 22, 2018
Post push fix

sql/opt_range.cc:14196:22: runtime error: -256 is outside the range of representable values of type 'unsigned int'
    #0 0x4248a9d in cost_skip_scan(TABLE*, unsigned int, unsigned int, unsigned long long, Cost_estimate*, unsigned long long*, Item*, Opt_trace_object*) sql/opt_range.cc:14196:22
    #1 0x41c524c in get_best_skip_scan(PARAM*, SEL_TREE*, bool) sql/opt_range.cc:14086:5
    #2 0x41b7b65 in test_quick_select(THD*, Bitmap<64u>, unsigned long long, unsigned long long, bool, enum_order, QEP_shared_owner const*, Item*, Bitmap<64u>*, QUICK_SELECT_I**) sql/opt_range.cc:3352:23
    #3 0x458fc08 in get_quick_record_count(THD*, JOIN_TAB*, unsigned long long) sql/sql_optimizer.cc:5542:17
    #4 0x458a0cd in JOIN::estimate_rowcount() sql/sql_optimizer.cc:5290:25

The fix is to handle REC_PER_KEY_UNKNOWN explicitly, to avoid using
-1.0 in computations later.

Change-Id: Ie8a81bdf7323e4f66abcad0a9aca776de8acd945
surbhat1595 pushed a commit that referenced this pull request Apr 25, 2019
…E TO A SERVER

Problem
========================================================================
Running the GCS tests with ASAN seldomly reports a user-after-free of
the server reference that the acceptor_learner_task uses.

Here is an excerpt of ASAN's output:

==43936==ERROR: AddressSanitizer: heap-use-after-free on address 0x63100021c840 at pc 0x000000530ff8 bp 0x7fc0427e8530 sp 0x7fc0427e8520
WRITE of size 8 at 0x63100021c840 thread T3
    #0 0x530ff7 in server_detected /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:962
    #1 0x533814 in buffered_read_bytes /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:1249
    #2 0x5481af in buffered_read_msg /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:1399
    #3 0x51e171 in acceptor_learner_task /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:4690
    #4 0x562357 in task_loop /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c:1140
    #5 0x5003b2 in xcom_taskmain2 /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:1324
    #6 0x6a278a in Gcs_xcom_proxy_impl::xcom_init(unsigned short, node_address*) /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_proxy.cc:164
    #7 0x59b3c1 in xcom_taskmain_startup /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc:107
    #8 0x7fc04a2e4dd4 in start_thread (/lib64/libpthread.so.0+0x7dd4)
    #9 0x7fc047ff2bfc in __clone (/lib64/libc.so.6+0xfebfc)

0x63100021c840 is located 64 bytes inside of 65688-byte region [0x63100021c800,0x63100022c898)
freed by thread T3 here:
    #0 0x7fc04a5d7508 in __interceptor_free (/lib64/libasan.so.4+0xde508)
    #1 0x52cf86 in freesrv /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:836
    #2 0x52ea78 in srv_unref /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:868
    #3 0x524c30 in reply_handler_task /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:4914
    #4 0x562357 in task_loop /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c:1140
    #5 0x5003b2 in xcom_taskmain2 /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:1324
    #6 0x6a278a in Gcs_xcom_proxy_impl::xcom_init(unsigned short, node_address*) /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_proxy.cc:164
    #7 0x59b3c1 in xcom_taskmain_startup /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc:107
    #8 0x7fc04a2e4dd4 in start_thread (/lib64/libpthread.so.0+0x7dd4)

previously allocated by thread T3 here:
    #0 0x7fc04a5d7a88 in __interceptor_calloc (/lib64/libasan.so.4+0xdea88)
    #1 0x543604 in mksrv /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:721
    #2 0x543b4c in addsrv /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:755
    #3 0x54af61 in update_servers /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_transport.c:1747
    #4 0x501082 in site_install_action /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:1572
    #5 0x55447c in import_config /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/site_def.c:486
    #6 0x506dfc in handle_x_snapshot /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:5257
    #7 0x50c444 in xcom_fsm /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:5325
    #8 0x516c36 in dispatch_op /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:4510
    #9 0x521997 in acceptor_learner_task /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:4772
    #10 0x562357 in task_loop /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/task.c:1140
    #11 0x5003b2 in xcom_taskmain2 /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_base.c:1324
    #12 0x6a278a in Gcs_xcom_proxy_impl::xcom_init(unsigned short, node_address*) /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_proxy.cc:164
    #13 0x59b3c1 in xcom_taskmain_startup /home/tvale/mysql/plugin/group_replication/libmysqlgcs/src/bindings/xcom/gcs_xcom_control_interface.cc:107
    #14 0x7fc04a2e4dd4 in start_thread (/lib64/libpthread.so.0+0x7dd4)

Analysis
========================================================================
The server structure is reference counted by the associated sender_task
and reply_handler_task.
When they finish, they unreference the server, which leads to its memory
being freed.

However, the acceptor_learner_task keeps a "naked" reference to the
server structure.
Under the right ordering of operations, i.e. the sender_task and
reply_handler_task terminating after the acceptor_learner_task acquires,
but before it uses, the reference to the server structure, leads to the
acceptor_learner_task accessing the server structure after it has been
freed.

Solution
========================================================================
Let the acceptor_learner_task also reference count the server structure
so it is not freed while still in use.

Reviewed-by: André Negrão <[email protected]>
Reviewed-by: Venkatesh Venugopal <[email protected]>
RB: 21209
mycastiel pushed a commit to mycastiel/mysql-server that referenced this pull request Jun 11, 2019
# 这是第一个提交说明:

Bug#29637712: WINDOWS 2016 AD-LDS AUTHENTICATION_LDAP_SIMPLE PLUGIN ALLOWS UNAUTHENTICATED CONNECTIONS

Windows AD allows LDAP authentication with empty password.
After this fix AUTHENTICATION_LDAP_SIMPLE plugin will not try to perform LDAP bind when empty password is given.
Authentication will be considered as failed.

rb: 21910
Approved by: Georgi Kodinov <[email protected]>
Approved by: Harin Vadodaria <[email protected]>
Change-Id: Ie74d6b89f84670d5cd8a12f32fbe0030b91af3ea

# 这是提交说明 mysql#2:

test

test1

# 这是提交说明 mysql#3:

test2
bjornmu pushed a commit that referenced this pull request Jan 13, 2020
When shutting down a mysql server, the test must wait not just for
clients to be disconnected, but for the server to shut down fully.

Change-Id: Ieed9fa201d420cae4cae10a47ff4a42b0d19f09e
strandlie pushed a commit to strandlie/mysql-server that referenced this pull request Jan 11, 2021
             DB_TYPE_INNODB || CNT <= 1 || (W->LAST_ROW_OUTPUT() == 0
              && W->FRAME()->M_FROM->M_BORDER_TYPE == WBT_VALUE_FOLLOWING)
             || FOR_NTH_VALUE' FAILED.

Problem:
Only seen in debug mode with RANGE frame. While evaluating the
previous row, we had a frame containing no rows. While evaluating the
current row (mysql#3 in the minimal repro given in added test), we find
that all possible rows falls *before* the frame boundaries, so we
still have a frame containing no rows. In this case, we could move the
possible boundaries

   [first_rowno_in_range_frame, last_rowno_in_range_frame]

one row forward for the set of rows that will fit in the frame when
evaluating the next (last) row, but we didn't update them to reflect
this. In production code, this will lead to reading more rows than
strictly necessary when evaluating the frame rows for the next current
row, which is not optimal, but will work. In the debug code, we assert
when we need to read more than one row to position correctly in the
frame buffer, hence the issue.

Solution:
Update m_first_rowno_in_range_frame and m_last_rowno_in_range_frame
also in this case.

Reviewed by: Chaithra Gopalareddy <[email protected]>
bjornmu pushed a commit that referenced this pull request Jan 18, 2021
To call a service implementation one needs to:
1. query the registry to get a reference to the service needed
2. call the service via the reference
3. call the registry to release the reference

While #2 is very fast (just a function pointer call) #1 and #3 can be
expensive since they'd need to interact with the registry's global
structure in a read/write fashion.

Hence if the above sequence is to be repeated in a quick succession it'd
be beneficial to do steps #1 and #3 just once and aggregate as many #2
steps in a single sequence.

This will usually mean to cache the service reference received in #1 and
delay 3 for as much as possible.

But since there's an active reference held to the service implementation
until 3 is taken special handling is needed to make sure that:

The references are released at regular intervals so changes in the
registry
can become effective. There is a way to mark a service implementation
as "inactive" ("dying") so that until all of the active references to it
are released no new ones are possible.

All of the above is part of the current audit API machinery, but needs
to be isolated into a separate service suite and made generally
available to
all services.

This is what this worklog aims to implement.

RB#24806
bjornmu pushed a commit that referenced this pull request Jan 18, 2021
TABLESPACE STATE DOES NOT CHANGE THE SPACE TO EMPTY

After the commit for Bug#31991688, it was found that an idle system may
not ever get around to truncating an undo tablespace when it is SET INACTIVE.
Actually, it takes about 128 seconds before the undo tablespace is finally
truncated.

There are three main tasks for the function trx_purge().
1) Process the undo logs and apply changes to the data files.
   (May be multiple threads)
2) Clean up the history list by freeing old undo logs and rollback
   segments.
3) Truncate undo tablespaces that have grown too big or are SET INACTIVE
   explicitly.

Bug#31991688 made sure that steps 2 & 3 are not done too often.
Concentrating this effort keeps the purge lag from growing too large.
By default, trx_purge() does step#1 128 times before attempting steps
#2 & #3 which are called 'truncate' steps.  This is set by the setting
innodb_purge_rseg_truncate_frequency.

On an idle system, trx_purge() is called once per second if it has nothing
to do in step 1.  After 128 seconds, it will finally do steps 2 (truncating
the undo logs and rollback segments which reduces the history list to zero)
and step 3 (truncating any undo tablespaces that need it).

The function that the purge coordinator thread uses to make these repeated
calls to trx_purge() is called srv_do_purge(). When trx_purge() returns
having done nothing, srv_do_purge() returns to srv_purge_coordinator_thread()
which will put the purge thread to sleep.  It is woke up again once per
second by the master thread in srv_master_do_idle_tasks() if not sooner
by any of several of other threads and activities.

This is how an idle system can wait 128 seconds before the truncate steps
are done and an undo tablespace that was SET INACTIVE can finally become
'empty'.

The solution in this patch is to modify srv_do_purge() so that if trx_purge()
did nothing and there is an undo space that was explicitly set to inactive,
it will immediately call trx_purge again with do_truncate=true so that steps
#2 and #3 will be done.

This does not affect the effort by Bug#31991688 to keep the purge lag from
growing too big on sysbench UPDATE NO_KEY. With this change, the purge lag
has to be zero and there must be a pending explicit undo space truncate
before this extra call to trx_purge is done.

Approved by Sunny in RB#25311
bjornmu pushed a commit that referenced this pull request Jan 18, 2021
…TH VS 2019 [#3] [noclose]

storage\ndb\src\common\portlib\NdbThread.cpp(1240,3): warning C4805: '==': unsafe mix of type 'int' and type 'bool' in operation

Change-Id: I33e3ff9845f3d3e496f64401d30eaa9b992da594
bjornmu pushed a commit that referenced this pull request Oct 19, 2021
Patch #3: Multi-value indexes are not used for MEMBER OF combined with OR.

If we have a MEMBER OF predicate that is combined with other predicates
with an OR operator, the range optimizer will not consider MEMBER OF
as a candidate for using an index.

Fixed by adding a case construct for Item_func::MEMBER_OF_FUNC in
get_func_mm_tree().

json_overlaps() and json_contains() already has this type of support.

This is a contribution by Yubao Liu.

Change-Id: I1fd7a78091998437310973b3c24099ad554a58a6
piki pushed a commit to planetscale/mysql-server that referenced this pull request Apr 27, 2022
Move install process into Dockerfile
rahulmalik87 pushed a commit to rahulmalik87/mysql-server that referenced this pull request Jun 16, 2022
… COMPILER WARNINGS

Remove stringop-truncation warning in ndb_config.cpp by refactoring.

Change-Id: I1eea7fe190926a85502e73ca7ebf07d984af9a09
nawazn pushed a commit that referenced this pull request Jul 26, 2022
Remove duplicated NdbEventOperationImpl::m_eventId which is only used in
some printouts.

Change-Id: Id494e17e3a483a8d049e9aaeb9f41bd6d4ccd847
nawazn pushed a commit that referenced this pull request Jul 26, 2022
-- Patch #1: Persist secondary load information --

Problem:
We need a way of knowing which tables were loaded to HeatWave after
MySQL restarts due to a crash or a planned shutdown.

Solution:
Add a new "secondary_load" flag to the `options` column of mysql.tables.
This flag is toggled after a successful secondary load or unload. The
information about this flag is also reflected in
INFORMATION_SCHEMA.TABLES.CREATE_OPTIONS.

-- Patch #2 --

The second patch in this worklog triggers the table reload from InnoDB
after MySQL restart.

The recovery framework recognizes that the system restarted by checking
whether tables are present in the Global State. If there are no tables
present, the framework will access the Data Dictionary and find which
tables were loaded before the restart.

This patch introduces the "Data Dictionary Worker" - a MySQL service
recovery worker whose task is to query the INFORMATION_SCHEMA.TABLES
table from a separate thread and find all tables whose secondary_load
flag is set to 1.

All tables that were found in the Data Dictionary will be appended to
the list of tables that have to be reloaded by the framework from
InnoDB.

If an error occurs during restart recovery we will not mark the recovery
as failed. This is done because the types of failures that can occur
when the tables are reloaded after a restart are less critical compared
to previously existing recovery situations. Additionally, this code will
soon have to be adapted for the next worklog in this area so we are
proceeding with the simplest solution that makes sense.

A Global Context variable m_globalStateEmpty is added which indicates
whether the Global State should be recovered from an external source.

-- Patch #3 --

This patch adds the "rapid_reload_on_restart" system variable. This
variable is used to control whether tables should be reloaded after a
restart of mysqld or the HeatWave plugin. This variable is persistable
(i.e., SET PERSIST RAPID_RELOAD_ON_RESTART = TRUE/FALSE).

The default value of this variable is set to false.

The variable can be modified in OFF, IDLE, and SUSPENDED states.

-- Patch #4 --

This patch refactors the recovery code by removing all recovery-related
code from ha_rpd.cc and moving it to separate files:

  - ha_rpd_session_factory.h/cc:
  These files contain the MySQLAdminSessionFactory class, which is used
to create admin sessions in separate threads that can be used to issue
SQL queries.

  - ha_rpd_recovery.h/cc:
  These files contain the MySQLServiceRecoveryWorker,
MySQLServiceRecoveryJob and ObjectStoreRecoveryJob classes which were
previously defined in ha_rpd.cc. This file also contains a function that
creates the RecoveryWorkerFactory object. This object is passed to the
constructor of the Recovery Framework and is used to communicate with
the other section of the code located in rpdrecoveryfwk.h/cc.

This patch also renames rpdrecvryfwk to rpdrecoveryfwk for better
readability.

The include relationship between the files is shown on the following
diagram:

        rpdrecoveryfwk.h◄──────────────rpdrecoveryfwk.cc
            ▲    ▲
            │    │
            │    │
            │    └──────────────────────────┐
            │                               │
        ha_rpd_recovery.h◄─────────────ha_rpd_recovery.cc──┐
            ▲                               │           │
            │                               │           │
            │                               │           │
            │                               ▼           │
        ha_rpd.cc───────────────────────►ha_rpd.h       │
                                            ▲           │
                                            │           │
            ┌───────────────────────────────┘           │
            │                                           ▼
    ha_rpd_session_factory.cc──────►ha_rpd_session_factory.h

Other changes:
  - In agreement with Control Plane, the external Global State is now
  invalidated during recovery framework startup if:
    1) Recovery framework recognizes that it should load the Global
    State from an external source AND,
    2) rapid_reload_on_restart is set to OFF.

  - Addressed review comments for Patch #3, rapid_reload_on_restart is
  now also settable while plugin is ON.

  - Provide a single entry point for processing external Global State
  before starting the recovery framework loop.

  - Change when the Data Dictionary is read. Now we will no longer wait
  for the HeatWave nodes to connect before querying the Data Dictionary.
  We will query it when the recovery framework starts, before accepting
  any actions in the recovery loop.

  - Change the reload flow by inserting fake global state entries for
  tables that need to be reloaded instead of manually adding them to a
  list of tables scheduled for reload. This method will be used for the
  next phase where we will recover from Object Storage so both recovery
  methods will now follow the same flow.

  - Update secondary_load_dd_flag added in Patch #1.

  - Increase timeout in wait_for_server_bootup to 300s to account for
  long MySQL version upgrades.

  - Add reload_on_restart and reload_on_restart_dbg tests to the rapid
  suite.

  - Add PLUGIN_VAR_PERSIST_AS_READ_ONLY flag to "rapid_net_orma_port"
  and "rapid_reload_on_restart" definitions, enabling their
  initialization from persisted values along with "rapid_bootstrap" when
  it is persisted as ON.

  - Fix numerous clang-tidy warnings in recovery code.

  - Prevent suspended_basic and secondary_load_dd_flag tests to run on
  ASAN builds due to an existing issue when reinstalling the RAPID
  plugin.

-- Bug#33752387 --

Problem:
A shutdown of MySQL causes a crash in queries fired by DD worker.

Solution:
Prevent MySQL from killing DD worker's queries by instantiating a
DD_kill_immunizer before the queries are fired.

-- Patch #5 --

Problem:
A table can be loaded before the DD Worker queries the Data Dictionary.
This means that table will be wrongly processed as part of the external
global state.

Solution:
If the table is present in the current in-memory global state we will
not consider it as part of the external global state and we will not
process it by the recovery framework.

-- Bug#34197659 --

Problem:
If a table reload after restart causes OOM the cluster will go into
RECOVERYFAILED state.

Solution:
Recognize when the tables are being reloaded after restart and do not
move the cluster into RECOVERYFAILED. In that case only the current
reload will fail and the reload for other tables will be attempted.

Change-Id: Ic0c2a763bc338ea1ae6a7121ff3d55b456271bf0
bjornmu pushed a commit that referenced this pull request Oct 11, 2022
Bug#34486254 - WL#14449: Mysqld crash - sig11 at rpd::ConstructQkrnExprCond
Bug#34381109 - Hypergraph offload Issue : LEFT JOIN test cases failing in i_subquery tests
Bug#34432230: Enabling testcase along with BM failures in order_by_limit_extended_mixed_varlen and scgts
Bug#34408615 - Assertion failure `args->ctx->m_lirid != kInvalidRelId' in ha_rpd_qkrn_expr.cc
Bug#34471424 - HYPERGRAPH HeatWave Visible fields not populated
Bug#34472083 - WL#14449: Mysqld crash - Assertion `extract_ctx.cmn_expr_or == nullptr' failed
Bug#34395166 - HYPERGRAPH BUG: QUERIES not offloading on heatwave in MTR SUITE
Bug#34056849 - WL#14449: Offload issue with dictionary encoding
Bug#34381126 - Hypergraph offload Issue : QCOMP test file non offload bug
Bug#34450394 - Hypergraph result mismatch
Bug#34472373 WL#14449: Mysqld crash - Assertion `args->ctx->m_lirid != kInvalidRelId' failed
Bug#34472354 WL#14449: Mysqld crash - sig11 at rpdrqce_check_const_cols_rpdopn
Bug#34472069 WL#14449: Mysqld crash - Assertion `n < size()' failed
Bug#34472058 WL#14449: Mysqld crash - sig11 at rpdrqc_construct_phyopt_bvfltr
Bug#34143535 - WL#14449: task formation error
Bug#34356273 - HYPERGRAPH BUG: CAST binary having issues with DICTIONARY ENCODING
Bug#34381303 - Hypergraph offload Issue : LIMIT DUAL not offloading
Bug#34356238 - HYPERGRAPH BUG: CAST DATE WITH DOUBLE_PRECISION
Bug#34448736 - Hypergraph Result mismatch:Result mismatch with user variables
BUG#34388727: Enabling testcases
Bug#34413698 - Hypergraph Union issues
Bug#34432241 - Hypergraph out of stack memory issue in rapid.qcomp_bugs_debug_notubsan_notasan
Bug#34369934 - Hypergraph Performance : TPCDS q93 qcomp issue -2
Bug#34399991 - HYPERGRAPH BUG: crash in cp_i_subquery_dict MTR file
Bug#34057893 - Fixing MTR timeout by reducing the partial JOIN search space
Bug#33321588 Hypergraph Result Mismatch : Cannot process QEXEC JSON document expected for each HeatWave node in query [no-close]
Bug#34395166 - HYPERGRAPH BUG: QUERIES not offloading on heatwave in MTR SUITE
Bug#34086457 - Hypergraph offload Issue : constant not marked correctly
Bug#34380519 BUG#33294870 BUG#34114292: Enabling testcases after these bug fixes.
BUG#34079278 : Partially enabling testcases for fixes cases.
BUG#33321588 : Fixing 'Cannot process QEXEC JSON document expected for each HeatWave node in query' Error
Bug#34360222 - HYPERGRAPH BUG: QUERIES WITH RANGE LIKE 1+1 NOT OFFLOADING WITH DICT ENCODING
Bug#34412319 - HyperGraph: sig 11 on bm mtr cp_blob_dict
Bug#34403562 - HyperGraph: Signal 6 while running rapid.cp_blob_dict testcase
Bug#34360341 - HYPERGRAPH BUG: QUERIES not offloading on heatwave with VARLEN ENCODING
Bug#34012291 - Hypergraph Offload Issue : Subquery is OOM instead of error ER_SUBQUERY_NO_1_ROW
Bug#34399868 - HYPERGRAPH BUG: Output mismatch in cp_i_index_merge
Bug#34289251 - WL#14449: post-join filters set as inner joins' extra predicates are not handled
Bug#34381354 - Hypergraph offload Issue : DATE COUNT not offloading
Bug#34119506 - Hypergraph Result Mismatch : Decimal precision issue
Bug#34399722 - HYPERGRAPH BUG: Output mismatch with mysql
Bug#34360278 - HYPERGRAPH BUG: QUERIES not offloading on heatwave
Bug#34369223 - HyperGraph: Offload failure when hypergraph is ON
Bug#34361863 - Impossible Condition Cases Failing with HyperGraph
Bug#34289797 - Hypergraph Optimizer: query projecting expression from inner side of outer join does not offload
Bug#34128728 - Hypergraph Crash : Due to ZERO ROWS
Bug#34066930 - Hypergraph Result Mismatch : Wrong result with Zero Rows
Bug#34078549 - Hypergraph Result Mismatch : Wrong result with ZERO ROWS Select_varlen test
Bug#33426211 - Hypergraph Offload issue : Due to the absence of few corner case optimizations
Bug#34086457 - Hypergraph offload Issue : constant not marked correctly
Bug#34299494 - Hypergraph : Disable commutative INNER JOIN
Bug#34299823 - Hypergraph Optimizer: Issue with projection set for partial plan
Bug#33380501 - WL#14449: expected error ER_SUBQUERY_NO_1_ROW but query succeeds
Bug#33811377 - WL#14449: SUBQUERY item in JOIN's extra predicates is not detected in partial plan
Bug#33410257 - Hypergraph Offload Issue :  Rapidside ENUM issue

* Add new file ha_rpd_estimate_ap.cc for costing AccessPath trees
  using the new Hypergraph Optimizer.

* Rework function CollectAllBaseTables() to not return any size
  information -- instead it can simply be computed by iterating
  over the map passed to it.

* Add member to Qkrn_context to store a pointer to the Hypergraph
  Optimizer object. When that is set we have a partial plan,
  otherwise it's the final plan.

* Add a couple of new timers for Hypergraph-based costing

* Replace all occurences of JOIN::having_for_explain with
  JOIN::having_cond, because the former one is not always populated
  correctly anymore.

* Ignore SQL SELECT_BIG_RESULT hint as it does not have any meaning
  for  RAPID.

* Set flags for handlerton::secondary_engine_flags

* Add new function Rapid_execution_context::IsQueryPushable() for
  partial plans.

* Currently, the patch contains a fix in the costing code which
  enables costing of any temporary table. This is ported forwards
  from the change for bug 34162247.

* Allow dumping partial plans by appending the overal partial
  plan ID  for item dump and QKRN dumps.

* Some const-ness fixes / improvements.

* Add code in ha_rpd_qkrn_ap.cc to extract the projection list
  for the root translate state of a partial plan.

* More fixes to partial plan projection set computation:
  In function ExtractGroupByHypergraph(), reuse function
  ExtractProjectionItemHypergraph() to extract sub-expressions correctly
  such that they math the current state_map.
  In function ExtractWindowHypergraph() take into account the current
  state_map, which was missing before and then for a base TABLE_SCAN we
  could pick up expressions from another base TABLE_SCAN, which led to
  offload errors.

* In HashJoinPullJoinConditionFromExtraPredicate(), remove a superfluous
  check whether Item_func::type() == Item::FUNC_ITEM.

* In TranslateHashJoin(), where we check the extra predicates also for
  inner joins, since those represent post join filters, initially we
  used UpdateItemListHashJoin(), which would project whole expressions
  from the post join filter, which leads to larger projection lists of
  the join and its children.
  For instance, for a query like
    SELECT t1.a, t2.b FROM t1 JOIN t2 ON ... WHERE t1.a > 5 OR t2.b > 10
  the WHERE condition ends up as post-join filter. Then, with the
  previous approach, t1 would project "t1.a" and "t1.a > 5" and t2 would
  project "t2.b" and "t2.b > 10" and then the post join filter would
  degrade into "qkrcol(t1.a > 5) != 0 OR qkrcol(t2.b > 10) != 0".
  Change to use UpdateItemList() which extracts only Item_fields, i.e.
  base columns, to match the behavior from the old optimizer.

* In ExtractProjectionItemHypergraph(), project all expressions for the
  final partial plan of a query block. This is necessary when e.g. a
  child query block is of the form
    SELECT 1, 2, 3, t1.a FROM t1 LIMIT 5
  Then, if we always ignore all constants in the TABLE_SCAN then when
  creating the TOPK node for the LIMIT we'll try to project the
  constants from there, which is not supported.

* Add TPC-H/DS perf job queries without STRAIGHT JOIN hints.

* Dump hypergraph performance profile timers to QEXEC_pp JSON dump.

* In Mtoq_table::GetCell() an earlier patch introduced a small
  optimization which was intended to skip an mrow_item in the case of
  aggregation Items (ITEM_SUM_FUNCs). The idea is that when one is
  <aggregate>(DISTINCT) and the other is just <aggregate>(), then
  they cannot be the same. Also, when the number of arguments differ,
  or when they are just different aggregates, then we don't need
  to call AreItemsEqual() after the special ITEM_SUM_FUNC code path.
  However, the "optimization" was wrong and skipped too many Items
  such that some were not found at all in the MtoQ table anymore.

* Add more state to the hypergraph optimizer to remove code from
   HeatWave side. In particular:
  * To decide whether ORDER BY LIMIT OFFSET can be handled we only
     need to check a new flag.
  * Whether there are multiple base tables in a query block is also
    tracked through a hypergraph optimizer flag.
  * Add handling for hypergraph filters on top of derived tables and
    joins.

Improve speed of Mtoq_table::GetCell
========================================
 Before, we called Qkrn_context::GetQueryBlock() in each loop
 iteration over the cells for the given query block. That is,
 however, already done before the loop once and we can re-use
 that retrieved query block.

 For DISTINCT aggregation Items (SUM_FUNC_ITEM) we have a special
 code path to compare them as equal when e.g.

 Also, improve code of AreDistinctItemListEqual():
 * Use only prefix incrementor.
 * Use copy operator to populate vector "it", which will reserve
   space to avoid multiple re-allocations.
 * Rename "it" to "first_copy" and "it1" to "iter".

Bug 34289251
============
Since the Hypergraph optimizer, post-join filters can be encoded
as join extra predicates, which was not yet considered in
HeatWave's AccessPath translation. This may result in wrong
results, as in the bug's case, where the query is quite simple:

  SELECT * FROM t1 NATURAL JOIN t2 WHERE t1.b > t2.b;

Here, the post-join filter "t1.b > t2.b" is encoded as a join extra
predicate.

The fix is to "simply" also consider those for inner joins, not
only for outer joins and semi joins and ensure that an intermediate
qkrnts is created for the post-join filter. Care had to be taken
to also ensure that all of the predicates' sub-expressions are
added to both projected and required items for the join itself.

Additionally added a few comments to function calls for constants
and added checks for return value of calls to
UpdateItemListHashJoin().

Bugs 33380501, 33811377:
========================
* Reset Qkrn_context::m_leaf_table_count before counting the leaf
  tables

* In CountLeafTables(): The hypergraph optimizer counts derived
  tables and common table expressions as leaf tables in their
  parent query blocks, so do not traverse any further.

* Bug 33380501: patch by Kajori Banerjee. Adds function
  rpdrqcj_rejects_multiple_rows() which recursively checks
  JOIN key expressions whether they contain a qkrcol which has
  reject_multiple_rows_qkrcol == true.

* Bug 33811377:
  Root cause: through IsQueryPushable we don't identify all cases
  where a subquery item is involved. In this case it is a join's
  extra predicate whose string representation is
    <in_optimizer>(8,<exists>(select #3))
  When we try to translate the expression it is inside an
  Item_cond_and
  and since it is const_for_exection(), we call Item::is_null(),
  which then executes the subquery and then leads to a mysqld
  crash. The fix is to also check evaluate_during_optimization()
  which identifies such a case. This is added in several places
  where we call a function which potentially evaluates the
  Item (like is_null()). By that, we avoid interpreting the
  subquery item as a constant and we will try to fully translate
  this subquery item, which will then hit the default
  (unsupported) case in ConstructQkrnExprTreeSwitch() by
  which we bail out of query translation.

* Avoid assertions in rapidjson due to calling IsQueryPushable()
  for every subplan. All calls to PrintOffloadTrace passed
    abort_query = true
  which however is wrong for partial plans, because we may get a
  supported one later.

* Split cp_join_prepart into dict and varlen tests.

* Make the Extract***Hypergraph functions for partial plans only
  return bool (false=success, true=error).

* Fix extraction of required items of GROUP BY keys and aggregation
  expressions for partial plans. This must be done similar to
  AccessPath style extraction using CompileItem. Therefore,
  refactored function ExtractRequiredItemsForGroupBy() to use
  the same functionality for partial plan extraction, too.

* In RapidEstimateQueryCostsAP() when we catch a RapidException,
  for now always print and offload trace and dump to screen the
  type and string message.

* Pick up more test changes from the original branch.

* Extract projection expressions from all WINDOWs' partition by
  and order by lists.

* Re-introduce handling aggregate items in UpdateItemList, which was
  removed during code coverage-related clean-up for worklog 14344
  (AP uptake).

* We were not aware that for semi joins we need to always project
  anexpression from the inner side due to some QCOMP issue.
  Filed bug 34252350 to track this issue.

* Fix issue with correlated semi joins where an OR condition was
  attached to the semi join as an additional condition
  (extra predicate) but was ignored because any non-Item::FUNC_ITEM
  was ignored when inspecting the extra predicates. Fix is to add
  Item::COND_ITEMs, too.

* In the AP cost estimation code, print the QCOMP exception if one
  occurs to console (for debugging, will be removed later).

* In TranslateDerivedTable(): When a derived table MATERIALIZE
  AccessPath is the root node and we're translating a partial plan,
  then when re-initializing the Qkrn_context for the parent query block
  (which contains the derived table's MATERIALIZE) we need to call
    InitializeQkrnContextPartialPlan()
  instead of
    InitializeQkrnContext().

* Fix issues when WITH ROLLUP modifier is present and when extracting
 expressions for the root AccessPath for partial plans.

* The Qkrn_context flags m_has_gby, m_has_ftag, m_has_windowfunc,
  and m_has_oby were used wrongly: they only indicate whether the
  current query block has one of those, but they don't indicate
  whether corresponding qkrn nodes were created.
* One issue with ENUM columns and WITH ROLLUP: when the ENUM column
  is inside an Item_rollup_group_item then do
* Remove argument "is_outer_query_block" from TransformQkrn().
  It is not needed as we can be sure that transformation is only
  done once perpartial plan or query fragment.

Bug 33410257 - Hypergraph Offload Issue :  Rapidside ENUM issue
===============================================================
The algorithm for detecting whether there are string operations on an
enum column in ContainsEnumOpn() was incomplete. It needs to keep
track of the parent operations, similar to how
ContainsUnsupportedCastEnumToChar() works.

Bug 34471424 - HYPERGRAPH HeatWave Visible fields not populated
===============================================================
For few partial plans in the bug's query, which contain a common
table expression, the hidden bitmap is not populated properly which
leads to an empty initial projection set for the first AccessPath
inside the CTE.

Fix is to ensure for partial plans that the projection items of the
CTE are all marked as not hidden in the hidden bitmap.

Note that there *may* be a different root cause which is specific
to some rewrite where we have a CTE inside another derived table.

Bug 34472083:
=============
The code for extracting potential join predicates from parent
FILTER AccessPaths was very strict by asserting that OR
conditionals are not nested. This can be, however, the case and
we should be more graceful. Especially for directly-nested ORs we
can simply pretend as if those ORs had been merged already by the
resolver/optimizer and proceed. For more complex nested OR/AND
filter or join predicates now just completely skip trying to
extract any predicates.

Added test wl14449_bugs with dict and varlen variants.

Bug 34395166:
=============
* scgts: The query had multiple partial plans failing because the
  hidden_map for HeatWaveVisibleFields adapter was not correct for
  some Common Table Expressions. As a quick fix, this is now
  corrected on the HeatWave side and in the meantime will be
  discussed with the MySQL optimizer team whether this is actually
  a bug on their side. The issue seems to be the following: The
  affected SCGTS query has a quite deep nesting of CTEs and derived
  tables and UNIONs and one of the CTE ismactually merged into
  another one.
  In the query, CTE
    snapshot_inventory_item_sub3
  is merged into CTE
    snapshot_inventory_item_sub4.
  while more CTEs may have been merged, we use only this example
  for illustration. Then, for computing the hidden_map, we check
  for each CTE instance its parent query block and search for all
  occurrences of Item_fields from that CTE. For that search, we use
  amongst others Query_block::top_join_list.
  Now in this case, the top_join_list however only contains the
  tables from the query block BEFORE the other CTE (and its tables
  and joins) was merged into that query block. In this case, the
  list only contains tables
    * po_octg_line
    * sub3b
  while it should contain tables
    * po_octg_line
    * snapshot_inventory_item_sub2 AS sub2
    * state_prov
    * invtry_item
    * pt_bol_date
  Those tables can be found in Query_block::leaf_tables, but not in
  Query_block::top_join_list.
  The (temporary?) fix is to check both Query_block::leaf_tables
  and Query_block::top_join_list.
* astro: The query is successfully offloaded again, re-enabled the
  test case and re-recorded the result file.

Other Changes:
==============
* ha_rpd_estimate_ap.cc: Correctly set qcomp_ret upon errors during
                         QCOMP.
* cloud_variables.result: Update due to latest bm pre-merge job.
* qcomp_bugs_debug_notubsan_notasan.result: Update due to latest bm
                                            pre-merge job.

Bug 34056849 - WL#14449: Offload issue with dictionary encoding
 ================================================================
1. The test cases in bug_poc_dict are rigtfully not offloaded given
   MYSQL's type input. On mysql-8.0 there are implicit casts
   (e.g. string to double) which enable these test cases to offload
   on that branch, but MySQL behavior is not consistent across all
   comparison functions and BETWEEN.
   Limitations on the HyperGraph branch are consistent (see the newly
   added test cases) and are in agreement with known HeatWave
   limitations with dictionary encoding.

2. Marked test cases in bushy_replaylog_dict are offloaded on the latest
   branch.

3. Test cases in join_outer_dict are rightfully not offloaded given
   the AP plan: the join condition requires comparison of different
   dictionary encoded columns (coming from a different base column).
   With natural join the plan is different: the join condition is
   pushed into both tables and the join is a cartesian product - hence
   there's no issue with comparing dict-encoded columns.
   On 8.0 both plans contain a cartesian product with two pushed-down
   filters - hence the offload issue does not exist.

Bug 34381126 :
================
Recording the testcases since bug not reproducible anymore

Bug 34450394 :
==================
Mismatch was due to insert into + select.
Changing test case to use order by in select
ensures the output is deterministic.

Bug#34472373
===================
Partial plan 4:
======================

-> Inner hash join prefix over( SUBQUERY2_t1_SUBQUERY2_t2):
   * Projection set = []
 -> FILTER prefix:
       * table_map = 0x0001
       * Original filter =
            (unhex('') = concat_ws('0',SUBQUERY2_t1.col_varchar_key
       * Projection set = [unhex('')]
       * Required items =
            [unhex(''), concat_ws('0',SUBQUERY2_t1.col_varchar_key)
       * DummyFields = [(none)(=0), (none)(=0)]
        -> TABLE_SCAN prefix on SUBQUERY2_t1:
           * Actual filter =
          (unhex('') = concat_ws('0',SUBQUERY2_t1.col_varchar_key)
           * Projection set =
          [unhex(''), SUBQUERY2_t1.col_int_key]

Problem :
===================
ExtractRequiredItemsForFilter adds the constant to the
required items.

Bug#34472354
===================
Same fix as above resolved the issue.

Bug#34472069 and Bug#34472058  : fixed in the latest branch

sum_distinct-big is timing out Job 1094368

Bug#34143535 - WL#14449: task formation error
 ==============================================
1) The distinct inside an inner query block of a partial plan was
notapplied. Updated the function ReadyToHandleDistinctAndOrderBy.

2) Problem :
Earlier all the partial plans were dumped irrespective of any
system variable or flag.

Solution :
Dump hypergraph partial plan only when system variable
qkrn_print_translate_states is set to true.

Bug 34356238
==============
Closed since diff was because we only match MySQL upto 5
decimal places.

Bug 34448736 :
===============
Closed since the diff matches with MySQL output.

Bug 34413698 - Hypergraph Union issues
======================================
Problem: Union with hypergraph cases failed due to
proper projection with special case of derived tables.

Solution: Update Projection Populate such that with this
special case of derived table + union, we appropriately
populate projection set.

Bug#34432241:
==============
Unnecessary call to ItemToString in IsConstValueItem causing the
issue. Removing the redundant call to ItemToString.

Bug#34369934
============
Join pattern changed due to the change in the order of the join
keys with the hypergraph.

Bug 34399991 - HYPERGRAPH BUG: crash in cp_i_subquery_dict MTR file
===================================================================
Ensure filter items do not have subquery in them

Bug#34395166 -P6
==================
Query :
SELECT * FROM t1 WHERE c_id=@min_cid OR c_id=@max_cid;

Has ZERO rows. But it was not getting offloaded from
IsQueryPushable.

Solution :
Do not check for IsQueryPushable for ZERO_ROWS, FAKE_SINGLE_ROW and
ZERO_ROWS_AGGREGATED.

Bug#34395166 - P5
===================
Query :

SELECT *
FROM t3
WHERE col_varchar_10_latin1_key IN (
   SELECT alias1.col_varchar_10_latin1_key
   FROM t1 AS alias1
   LEFT JOIN t1 AS alias2
   JOIN t2 AS alias3
   ON alias2.col_varchar_10_latin1_key
   ON alias1.col_varchar_1024_utf8_key
   WHERE alias1.pk AND alias1.pk < 3 OR alias1.pk AND alias3.pk);

The BV filter has the condition alias1.pk<>0 AND alias1.pk < 3.

The hash join node projects the expression (alias1.pk < 3) instead
of the individual columns. This later creates a problem during
qkrn transformation of the BV filter as one child of the condition
(AND) is a column instead of an expression.

Bug#34395166 - P2
====================
Query:
SELECT          RANK() OVER (ORDER BY AVG(id)) FROM t1;

The item_map of (RANK() OVER (ORDER BY AVG(id))) = 0
Hence it was not projected from the window function of the
partial plan 4. As a result the window node projected the dummy
column leading to an offload issue.

BUG#33321588 :
==============
- Root cause for this issue is, the ordering of the query result is
  not in expected format.
- Heatwave doesn't ensure ordering without explicit ORDER BY clause.
- ORDER BY clause is added at required place.

Bug 34086457 - Hypergraph offload Issue : constant not marked correctly
=======================================================================
Problem: coalesce(col1, col2) is not marked as Item type ITEM_CACHE
which leads to false value returned from isConstValue

Solution: check for function with string constants in isConstValue

Bug#34399868 - HYPERGRAPH BUG: Output mismatch in cp_i_index_merge
=================================================================
This is actually *NOT* a HyperGraph bug!

There are 2 test cases which are resulting in result mismatch on
mysql-8.0 as well. A bug has been open for them.

This did not show up before because cp_i_index_merge.test relies
only on randomized data. That is also risking unstable mtr.

A temporary solution here is to just put explain for all test cases
that might be unstable - which is what this patch is doing.

In the meantime the underlying bug 34423734 needs to be fixed on
8.0 and those concrete test cases (without randomness) will be
appended to this test file.

Bug#34399722 - HYPERGRAPH BUG: Output mismatch with mysql
==============================================================
The ROW_NUMBER() is a window function or analytic function
that assigns a sequential number to each row in the result set.
The first number begins with one. Since there is no ordering
metioned in the window function, the row numbers
might be assigned in a different order.

Bug#34361863 - Impossible Condition Cases Failing with HyperGraph
==================================================================
for hypergraph Rapid_execution_context fields like m_subquery_type
and m_best_outer_plan_num are not updated during join order
enumeration. Hence checking them in HasOnlyInvalidPlans is not
relevant.

BUG#34289797 :
========================
Not reproducible, thus enabling the relevant testcase
and re-recording the test file. Additionally, more queries offload
with hypergraph, changing offload correspondingly for
bushy_bugs_varlen and bushy_bugs_dict test files.

BUG 34128728, Bug 34066930 Bug 34078549
Fix for Zero rows induced problems with Hypergraph Optimizer
==================================================================
Problem: Hypergraph Optimizer (may) sometime propose JOIN plans
with Zero Row in Inner/Outer Child. In this case, we handle by
inserting Filter and ZeroRowAggregate replacing the ZeroRow AP.
However, the PopulateProjectionSet does not pick up the correct
state map of tables under the new Filter AP. TranslateHash join
now does special handling for OuterJOIN and ZeroRows, but this was
now being done for inner join as well, which is incorrect.

Solution: We introduce m_zero_row_state_map member in
Translate_State::filter struct, which is used to resolve the state
map when we replace the Zero Row AP with Filter AP. In subsequent
calls to GetUsedTables() from PopulateProjectionSet() for
new Filter() AP, we are able to resolve the correct state_map,
thus handling the projection correctly.
Secondly, in TranslateHashJoin(), the special processing of zero
rows in outer join case has additional check to ensure it's invoked
 only when outerjoin is present.

Bug#34299494 - Hypergraph : Disable commutative INNER JOIN
============================================================
Say Query is
SELECT * FROM t1, t2 WHERE t1.a=t2.a;

At present the hypergraph optimizer explores both join orders
(t1 t2) and (t2 t1). Since both are same with respect to
HeatWave perspective, it does not makes sense to explore
(t2 t1) when ( t1 t2) is already explored.

Bug#34299823 - Hypergraph Optimizer:
Issue with projection set for partial plan
==============================================================
* In ExtractProjectionItemHypergraph(), also project expressions
which do not reference any tables. This fixes queries where
partial plans would otherwise have no SELECT list at all, for
instance
    SELECT isnull(gen_rnd_ssn()) FROM ...
* In TranslateHashJoin(), for extra predicates which are used as
  post-join filters, use UpdateItemListHashJoin() instead of
  UpdateItemList, because it updates local variables
  "has_from_inner" and "has_from_outer" which may be important for
  dummy projection.
  Example query is e.g. from data_masking.test:267:
    SELECT isnull(gen_rnd_ssn()), gen_rnd_pan(gen_range(1,1))
    FROM t1 JOIN t1 AS t2 ON t1.e > t2.e
    GROUP BY gen_rnd_ssn();
  For that query the GROUP BY key and the SELECT list do not
  contain any expressions over base table columns. Hence, when
  reaching a plan with the AGGREGATE AccessPath, we don't have
  any required items for it, but it needs at least one required
  item for dummy projection (see TranslateGroupBy() for
  step case 1).

Further fixes:
* Correctly handle the post-join filter retrieved through
  GetHyperGraphFilterCond(). First, all sub-expressions must be
  projected from the join node itself and then the post-join filter
  must be added to the intermediate qkrnts' filter, too.
* Add function DumpItemToString() which simply prints the result of
  ItemToString() for the given Item to the console. This is just a
  small debug utility function because my gdb does not print that
  output anymore.

Bug#34490127 - Always enforce Hypergraph Optimizer for HeatWave
Bug#34303379 - mysqld got signal 6 in rpd::ExtractCommonExpression at ha_rpd_qkrn_ap.cc
Bug#34242831 - [Sonny] Cost estimation: AttachToCommonParent: Expected a join node
Bug#34151831 - Query offload fails at ExtractItemFromDerivedTable
Bug#33659812 - LEFT JOIN OFFLOAD ISSUE: AttachToCommonParent: Expected a join node

Bug 34490127:
=============
* Set optimizer switch for using the hypergraph optimizer in the
  constructor of Rapid_execution_context to use always it for HeatWave
  going forward.
* Added an offload Check in RapidOptimize() that indeed the Hypergraph
  Optimizer is used.
* To take effect we had to move the code in sql_select.cc (function
  Sql_cmd_dml::prepare) which updates lex->using_hypergraph_optimizer to
  after the call to open_tables_for_query() such that the secondary
  engine's prepare hook is called before checking the optimizer switch,
  otherwise the first change above would stay ineffective.
* Removed adding the cmake flag WITH_HYPERGRAPH_OPTIMIZER from file
  _helper.sh again such that we can test the current behavior that the
  hypergraph optimizer is disabled by default for other engines than
  HeatWave in PERF builds. We circumvent this behavior for HeatWave by
  setting the optimizer switch programmatically.
* Remove the `--hypergraph` flag again from r_mtr.json.
* Update test files to not source files not_hypergraph.inc or
  have_hypergraph.inc, because they test for hypergraph being enabled or
  not by setting the optimizer_switch, which is now not possible on PERF
  builds anymore and we don't need that behavior anymore with the above
  changes.
* partition_dict.test and partition_varlen.test : Added missing
  enforcement of secondary engine.
* Revert result for test autodb_hcs_console_queries
* Re-enable tests from disabled.def : rapid.autodb_hcs_console_queries
  and rapid.qcomp_cost_model_evaluation_tpch.
  Re-record result for qcomp_cost_model_evaluation_tpch.result.
* Re-record affected test results.

Bugs 34303379, 34242831, 34151831, 33659812:
============================================
* Added test cases
* Added a separate sonnys test file for all bugs which use the respective schema.

WL#14449 - Query_term support

* Implement remaining changes for proper Query_term support.
* In the qkropn dumping code which tracks the use of tables and base
  table columns, checks were missing whether RapidSchema is nullptr.
  This led to crashes in some DEBUG MTR tests.
* Stabilize and improve several tests

WL#14449 - Handle FILTER AccessPaths with FALSE predicate

Until Bug 34494609 is properly fixed, add functionality to replace
FILTER AccessPaths with only FALSE-predicate by ZERO_ROWS or
ZERO_ROWS_AGGREGATED as appropriate. The latter is used when ZERO_ROWS
can be propagated all the way up to an aggregation AccessPath in the
current Query_block.
The ZERO_ROWS will be propagated as far up the current query block as
possible. When the patch for this bug is fixed from MySQL side, this
functionality can be removed again.

Change-Id: I77e6b7a75bb9071d4ad4fbc22b445c4bd51a82c7
pull bot pushed a commit to zhuizhu-95/mysql-server that referenced this pull request Apr 28, 2023
Missing initializers for m_verbosity and m_util_latest_gci

storage/ndb/test/src/UtilTransactions.cpp:35:24: warning: 2
uninitialized fields at the end of the constructor call [clang-analyzer-
optin.cplusplus.UninitializedObject]

Removed unused member m_defaultClearMethod

Change-Id: I46617df4a1ea3c3c56a8d82e999dcc01019232a7
pull bot pushed a commit to zhuizhu-95/mysql-server that referenced this pull request Apr 28, 2023
  # This is the 1st commit message:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA

  Problem Statement
  -----------------
  Currently customers cannot enable heatwave analytics service to their
  HA DBSystem or enable HA if they are using Heatwave enabled DBSystem.
  In this change, we attempt to remove this limitation and provide
  failover support of heatwave in an HA enabled DBSystem.

  High Level Overview
  -------------------
  To support heatwave with HA, we extended the existing feature of auto-
  reloading of tables to heatwave on MySQL server restart (WL-14396). To
  provide seamless failover functionality to tables loaded to heatwave,
  each node in the HA cluster (group replication) must have the latest
  view of tables which are currently loaded to heatwave cluster attached
  to the primary, i.e., the secondary_load flag should be in-sync always.

  To achieve this, we made following changes -
    1. replicate secondary load/unload DDL statements to all the active
       secondary nodes by writing the DDL into the binlog, and
    2. Control how secondary load/unload is executed when heatwave cluster
       is not attached to node executing the command

  Implementation Details
  ----------------------
  Current implementation depends on two key assumptions -
   1. All MDS DBSystems will have RAPID plugin installed.
   2. No non-MDS system will have the RAPID plugin installed.

  Based on these assumptions, we made certain changes w.r.t. how server
  handles execution of secondary load/unload statements.
   1. If secondary load/unload command is executed from a mysql client
      session on a system without RAPID plugin installed (i.e., non-MDS),
      instead of an error, a warning message will be shown to the user,
      and the DDL is allowed to commit.
   2. If secondary load/unload command is executed from a replication
      connection on an MDS system without heatwave cluster attached,
      instead of throwing an error, the DDL is allowed to commit.
   3. If no error is thrown from secondary engine, then the DDL will
      update the secondary_load metadata and write a binlog entry.

  Writing to binlog implies that all the consumer of binlog now need to
  handle this DDL gracefully. This has an adverse effect on Point-in-time
  Recovery. If the PITR backup is taken from a DBSystem with heatwave, it
  may contain traces of secondary load/unload statements in its binlog.
  If such a backup is used to restore a new DBSystem, it will cause failure
  while trying to execute statements from its binlog because
   a) DBSystem will not heatwave cluster attached at this time, and
   b) Statements from binlog are executed from standard mysql client
      connection, thus making them indistinguishable from user executed
      command.
  Customers will be prevented (by control plane) from using PITR functionality
  on a heatwave enabled DBSystem until there is a solution for this.

  Testing
  -------
  This commit changes the behavior of secondary load/unload statements, so it
   - adjusts existing tests' expectations, and
   - adds a new test validating new DDL behavior under different scenarios

  Change-Id: Ief7e9b3d4878748b832c366da02892917dc47d83

  # This is the commit message #2:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA (PITR SUPPORT)

  Problem
  -------
  A PITR backup taken from a heatwave enabled system could have traces
  of secondary load or unload statements in binlog. When such a backup
  is used to restore another system, it can cause failure because of
  following two reasons:

  1. Currently, even if the target system is heatwave enabled, heatwave
  cluster is attached only after PITR restore phase completes.
  2. When entries from binlogs are applied, a standard mysql client
  connection is used. This makes it indistinguishable from other user
  session.

  Since secondary load (or unload) statements are meant to throw error
  when they are executed by user in the absence of a healthy heatwave
  cluster, PITR restore workflow will fail if binlogs from the backup
  have any secondary load (or unload) statements in them.

  Solution
  --------
  To avoid PITR failure, we are introducing a new system variable
  rapid_enable_delayed_secondary_ops. It controls how load or unload
  commands are to be processed by rapid plugin.

    - When turned ON, the plugin silently skips the secondary engine
      operation (load/unload) and returns success to the caller. This
      allows secondary load (or unload) statements to be executed by the
      server in the absence of any heatwave cluster.
    - When turned OFF, it follows the existing behavior.
    - The default value is OFF.
    - The value can only be changed when rapid_bootstrap is IDLE or OFF.
    - This variable cannot be persisted.

  In PITR workflow, Control Plane would set the variable at the start of
  PITR restore and then reset it at the end of workflow. This allows the
  workflow to complete without failure even when heatwave cluster is not
  attached. Since metadata is always updated when secondary load/unload
  DDLs are executed, when heatwave cluster is attached at a later point
  in time, the respective tables get reloaded to heatwave automatically.

  Change-Id: I42e984910da23a0e416edb09d3949989159ef707

  # This is the commit message mysql#3:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA (TEST CHANGES)

  This commit adds new functional tests for the MDS HA + HW integration.

  Change-Id: Ic818331a4ca04b16998155efd77ac95da08deaa1

  # This is the commit message mysql#4:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA
  BUG#34776485: RESTRICT DEFAULT VALUE FOR rapid_enable_delayed_secondary_ops

  This commit does two things:
  1. Add a basic test for newly introduced system variable
  rapid_enable_delayed_secondary_ops, which controls the behavior of
  alter table secondary load/unload ddl statements when rapid cluster
  is not available.

  2. It also restricts the DEFAULT value setting for the system variable
  So, following is not allowed:
  SET GLOBAL rapid_enable_delayed_secondary_ops = default
  This variable is to be used in restricted scenarios and control plane
  only sets it to ON/OFF before and after PITR apply. Allowing set to
  default has no practical use.

  Change-Id: I85c84dfaa0f868dbfc7b1a88792a89ffd2e81da2

  # This is the commit message mysql#5:

  Bug#34726490: ADD DIAGNOSTICS FOR SECONDARY LOAD / UNLOAD DDL

  Problem:
  --------
  If secondary load or unload DDL gets rolled back due to some error after
  it had loaded / unloaded the table in heatwave cluster, there is no undo
  of the secondary engine action. Only secondary_load flag update is
  reverted and binlog is not written. From User's perspective, the table
  is loaded and can be seen on performance_schema. There are also no
  error messages printed to notify that the ddl didn't commit. This
  creates a problem to debug any issue in this area.

  Solution:
  ---------
  The partial undo of secondary load/unload ddl will be handled in
  bug#34592922. In this commit, we add diagnostics to reveal if the ddl
  failed to commit, and from what stage.

  Change-Id: I46c04dd5dbc07fc17beb8aa2a8d0b15ddfa171af

  # This is the commit message mysql#6:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA (TEST FIX)

  Since ALTER TABLE SECONDARY LOAD / UNLOAD DDL statements now write
  to binlog, from Heatwave's perspective, SCN is bumped up.

  In this commit, we are adjusting expected SCN values in certain
  tests which does secondary load/unload and expects SCN to match.

  Change-Id: I9635b3cd588d01148d763d703c72cf50a0c0bb98

  # This is the commit message mysql#7:

  Adding MTR tests for ML in rapid group_replication suite

  Added MTR tests with Heatwave ML queries with in
  an HA setup.

  Change-Id: I386a3530b5bbe6aea551610b6e739ab1cf366439

  # This is the commit message mysql#8:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA (MTR TEST ADJUSTMENT)

  In this commit we have adjusted the existing test to work with the
  new MTR test infrastructure which extends the functionalities to
  HA landscape. With this change, a lot of mannual settings have now
  become redundant and thus removed in this commit.

  Change-Id: Ie1f4fcfdf047bfe8638feaa9f54313d509cbad7e

  # This is the commit message mysql#9:

  WL#15280: HEATWAVE SUPPORT FOR MDS HA (CLANG-TIDY FIX)

  Fix clang-tidy warnings found in previous change#16530, patch#20

  Change-Id: I15d25df135694c2f6a3a9146feebe2b981637662

Change-Id: I3f3223a85bb52343a4619b0c2387856b09438265
dveeden pushed a commit to dveeden/mysql-server that referenced this pull request May 5, 2023
In ndb_socket_poller, check read sockets for SSL pending data.

Change-Id: If3aa3897a5decaeaf2309031590f89bc27d4685c
nawazn pushed a commit that referenced this pull request Jul 18, 2023
Some minor refactoring of function find_item_in_list() before the fix.

- Code is generally aligned with coding standard.

- Error handling is separated out, now is is false for success and
  true for error.

- The found item is now an output argument, and a null pointer means
  the item was not found (along with the other two out arguments).

- The report_error argument is removed since it was always used as
  REPORT_EXCEPT_NOT_FOUND.

- A local variable "find_ident" is introduced, since it better
  represents that we are searching for a column reference than having
  separate field_name, table_name and db_name variables.

Item_field::replace_with_derived_expr_ref()

- Redundant tests were removed.

Function resolve_ref_in_select_and_group() has also been changed so
that success/error is now returned as false/true, and the found item
is an out argument.

Function Item_field::fix_fields()

- The value of thd->lex->current_query_block() is cached in a local
  variable.

- Since single resolving was introduced, a test for "field" equal to
  nullptr was redundant and could be eliminated, along with the indented
  code block that followed.

- A code block for checking bitmaps if the above test was false could
  also be removed.

Change-Id: I3cd4bd6a23dd07faff773bdf11940bcfd847c903
nawazn pushed a commit that referenced this pull request Jul 18, 2023
Two problems were identified for this bug. The first is seen by looking
at the reduced query:

select subq_1.c1 as c1
from (select subq_0.c0 as c0,
             subq_0.c0 as c1,
             90 as c2,
             subq_0.c1 as c3
      from (select (select v2 from table1) as c0,
                   ref_0.v4 as c1
            from table1 as ref_0
           ) as subq_0
      ) as subq_1
where EXISTS (select subq_1.c0 as c2,
                     case
                     when EXISTS (select (select v0 from table1) as c1
                                          from table1 as ref_8
                                          where EXISTS (select subq_1.c2 as c7
                                                        from table1 as ref_9
                                                       )
                                         )
                     then subq_1.c3
                     end as c5
              from table1 as ref_7);

In the innermost EXISTS predicate, a column subq_1.c2 is looked up.
It is erroneously found as the column subq_1.c0 with alias c2 in the
query block of the outermost EXISTS predicate. But this resolving is not
according to SQL standard: A table name cannot be part of a column alias,
it has to be a simple identifier, and any referencing column must also
be a simple identifier. By changing item_ref->item_name to
item_ref->field_name in a test in find_item_in_list, we ensure that the
match is against a table (view) name and column name and not an alias.

But there is also another problem. The EXISTS predicate contains a few
selected columns that are resolved and then immediately deleted since
they are redundant in EXISTS processing. But if these columns are
outer references and defined in a derived table, we may actually
de-reference them before the initial reference increment. Thus, those
columns are removed before they are possibly used later. This happens
to subq_1.c2 which is resolved in the outer-most query block and
coming from a derived table. We prevent this problem by incrementing
the reference count of selected expressions from derived tables earlier,
and we try to prevent this problem from re-occuring by adding an
"m_abandoned" field in class Item, which is set to true when the
reference count is decremented to zero and prevents the reference count
from ever be incremented after that.

Change-Id: Idda48ae726a580c1abdc000371b49a753e197bc6
bjornmu pushed a commit that referenced this pull request Jul 18, 2023
Some minor refactoring of function find_item_in_list() before the fix.

- Code is generally aligned with coding standard.

- Error handling is separated out, now is is false for success and
  true for error.

- The found item is now an output argument, and a null pointer means
  the item was not found (along with the other two out arguments).

- The report_error argument is removed since it was always used as
  REPORT_EXCEPT_NOT_FOUND.

- A local variable "find_ident" is introduced, since it better
  represents that we are searching for a column reference than having
  separate field_name, table_name and db_name variables.

Item_field::replace_with_derived_expr_ref()

- Redundant tests were removed.

Function resolve_ref_in_select_and_group() has also been changed so
that success/error is now returned as false/true, and the found item
is an out argument.

Function Item_field::fix_fields()

- The value of thd->lex->current_query_block() is cached in a local
  variable.

- Since single resolving was introduced, a test for "field" equal to
  nullptr was redundant and could be eliminated, along with the indented
  code block that followed.

- A code block for checking bitmaps if the above test was false could
  also be removed.

Change-Id: I3cd4bd6a23dd07faff773bdf11940bcfd847c903
bjornmu pushed a commit that referenced this pull request Jul 18, 2023
Two problems were identified for this bug. The first is seen by looking
at the reduced query:

select subq_1.c1 as c1
from (select subq_0.c0 as c0,
             subq_0.c0 as c1,
             90 as c2,
             subq_0.c1 as c3
      from (select (select v2 from table1) as c0,
                   ref_0.v4 as c1
            from table1 as ref_0
           ) as subq_0
      ) as subq_1
where EXISTS (select subq_1.c0 as c2,
                     case
                     when EXISTS (select (select v0 from table1) as c1
                                          from table1 as ref_8
                                          where EXISTS (select subq_1.c2 as c7
                                                        from table1 as ref_9
                                                       )
                                         )
                     then subq_1.c3
                     end as c5
              from table1 as ref_7);

In the innermost EXISTS predicate, a column subq_1.c2 is looked up.
It is erroneously found as the column subq_1.c0 with alias c2 in the
query block of the outermost EXISTS predicate. But this resolving is not
according to SQL standard: A table name cannot be part of a column alias,
it has to be a simple identifier, and any referencing column must also
be a simple identifier. By changing item_ref->item_name to
item_ref->field_name in a test in find_item_in_list, we ensure that the
match is against a table (view) name and column name and not an alias.

But there is also another problem. The EXISTS predicate contains a few
selected columns that are resolved and then immediately deleted since
they are redundant in EXISTS processing. But if these columns are
outer references and defined in a derived table, we may actually
de-reference them before the initial reference increment. Thus, those
columns are removed before they are possibly used later. This happens
to subq_1.c2 which is resolved in the outer-most query block and
coming from a derived table. We prevent this problem by incrementing
the reference count of selected expressions from derived tables earlier,
and we try to prevent this problem from re-occuring by adding an
"m_abandoned" field in class Item, which is set to true when the
reference count is decremented to zero and prevents the reference count
from ever be incremented after that.

Change-Id: Idda48ae726a580c1abdc000371b49a753e197bc6
venkatesh-prasad-v pushed a commit to venkatesh-prasad-v/mysql-server that referenced this pull request Aug 3, 2023
…etwork

https://bugs.mysql.com/bug.php?id=109668

Description
-----------
GR suffered from problems caused by the security probes and network scanner
processes connecting to the group replication communication port. This usually
is not a problem, but poses a serious threat when another member tries to join
the cluster by initialting a connection to the member which is affected by
external processes using the port dedicated for group communication for longer
durations.

On such activites by external processes, the SSL enabled server stalled forever
on the SSL_accept() call waiting for handshake data. Below is the stacktrace:

    Thread 55 (Thread 0x7f7bb77ff700 (LWP 2198598)):
    #0 in read ()
    mysql#1 in sock_read ()
    mysql#2 in BIO_read ()
    mysql#3 in ssl23_read_bytes ()
    mysql#4 in ssl23_get_client_hello ()
    mysql#5 in ssl23_accept ()
    mysql#6 in xcom_tcp_server_startup(Xcom_network_provider*) ()

When the server stalled in the above path forever, it prohibited other members
to join the cluster resulting in the following messages on the joiner server's
logs.

    [ERROR] [MY-011640] [Repl] Plugin group_replication reported: 'Timeout on wait for view after joining group'
    [ERROR] [MY-011735] [Repl] Plugin group_replication reported: '[GCS] The member is already leaving or joining a group.'

Solution
--------
This patch adds two new variables

1. group_replication_xcom_ssl_socket_timeout

   It is a file-descriptor level timeout in seconds for both accept() and
   SSL_accept() calls when group replication is listening on the xcom port.
   When set to a valid value, say for example 5 seconds, both accept() and
   SSL_accept() return after 5 seconds. The default value has been set to 0
   (waits infinitely) for backward compatibility. This variable is effective
   only when GR is configred with SSL.

2. group_replication_xcom_ssl_accept_retries

   It defines the number of retries to be performed before closing the socket.
   For each retry the server thread calls SSL_accept()  with timeout defined by
   the group_replication_xcom_ssl_socket_timeout for the SSL handshake process
   once the connection has been accepted by the first accept() call. The
   default value has been set to 10. This variable is effective only when GR is
   configred with SSL.

Note:
- Both of the above variables are dynamically configurable, but will become
  effective only on START GROUP_REPLICATION.
- This patch is only for the Linux systems.
bjornmu pushed a commit that referenced this pull request Oct 25, 2023
Part of WL#15135 Certificate Architecture

This patch adds an instance of TlsKeyManager to class
TransporterRegistry. This TlsKeyManager will handle certificate
authentication in all node types.

A new method TransporterRegistry::init_tls() configures TLS at
node startup time.

Change-Id: I1f9d3fff21ea7f2d9f009cce48823304c2baead7
bjornmu pushed a commit that referenced this pull request Oct 25, 2023
Add a unit test, an NdbApi test, and an MTR test.

The unit test is testNdbProcess-t
The NdbApi test is testMgmd -n SshKeySigning
The MTR test is sign_keys in suite ndb_tls

Create the ndb_tls test suite.
Create the ndb-tls subdirectory in std_data.
Create a CA key and certificate in std_data/ndb-tls/.

Change-Id: Icec0fa4a9031be11facbd346d09debe8bc8bfe68
bjornmu pushed a commit that referenced this pull request Oct 25, 2023
Negotiate TLS in SocketAuthTls SocketAuthenticator.

On the server side, TransporterRegistry always instantiates
a SocketAuthTls authenticator.

Change-Id: I826390b545ef96ec4224ff25bc66d9fdb7a5cf7a
bjornmu pushed a commit that referenced this pull request Oct 25, 2023
Add the final bit of code into TransporterRegsitry to start TLS
before transporter upgrade, and update the MTR test results.

The tls_required and tls_off_certs tests will show TLS in use
for transporter connections to MGMD.

Change-Id: I2683447c02b27e498873fee77e0382c609a477cd
venkatesh-prasad-v pushed a commit to venkatesh-prasad-v/mysql-server that referenced this pull request Jan 26, 2024
…and a local

             DDL executed

https://bugs.mysql.com/bug.php?id=113727

Problem
-------
In high concurrency scenarios, MySQL replica can enter into a deadlock due to a
race condition between the replica applier thread and the client thread
performing a binlog group commit.

Analysis
--------
It needs at least 3 threads for this deadlock to happen

1. One client thread
2. Two replica applier threads

How this deadlock happens?
--------------------------
0. Binlog is enabled on replica, but log_replica_updates is disabled.

1. Initially, both "Commit Order" and "Binlog Flush" queues are empty.

2. Replica applier thread 1 enters the group commit pipeline to register in the
   "Commit Order" queue since `log-replica-updates` is disabled on the replica
   node.

3. Since both "Commit Order" and "Binlog Flush" queues are empty, the applier
   thread 1

   3.1. Becomes leader (In Commit_stage_manager::enroll_for()).

   3.2. Registers in the commit order queue.

   3.3. Acquires the lock MYSQL_BIN_LOG::LOCK_log.

   3.4. Commit Order queue is emptied, but the lock MYSQL_BIN_LOG::LOCK_log is
        not yet released.

   NOTE: SE commit for applier thread is already done by the time it reaches
         here.

4. Replica applier thread 2 enters the group commit pipeline to register in the
   "Commit Order" queue since `log-replica-updates` is disabled on the replica
   node.

5. Since the "Commit Order" queue is empty (emptied by applier thread 1 in 3.4), the
   applier thread 2

   5.1. Becomes leader (In Commit_stage_manager::enroll_for())

   5.2. Registers in the commit order queue.

   5.3. Tries to acquire the lock MYSQL_BIN_LOG::LOCK_log. Since it is held by applier
        thread 1 it will wait until the lock is released.

6. Client thread enters the group commit pipeline to register in the
   "Binlog Flush" queue.

7. Since "Commit Order" queue is not empty (there is applier thread 2 in the
   queue), it enters the conditional wait `m_stage_cond_leader` with an
   intention to become the leader for both the "Binlog Flush" and
   "Commit Order" queues.

8. Applier thread 1 releases the lock MYSQL_BIN_LOG::LOCK_log and proceeds to update
   the GTID by calling gtid_state->update_commit_group() from
   Commit_order_manager::flush_engine_and_signal_threads().

9. Applier thread 2 acquires the lock MYSQL_BIN_LOG::LOCK_log.

   9.1. It checks if there is any thread waiting in the "Binlog Flush" queue
        to become the leader. Here it finds the client thread waiting to be
        the leader.

   9.2. It releases the lock MYSQL_BIN_LOG::LOCK_log and signals on the
        cond_var `m_stage_cond_leader` and enters a conditional wait until the
        thread's `tx_commit_pending` is set to false by the client thread
       (will be done in the
       Commit_stage_manager::process_final_stage_for_ordered_commit_group()
       called by client thread from fetch_and_process_flush_stage_queue()).

10. The client thread wakes up from the cond_var `m_stage_cond_leader`.  The
    thread has now become a leader and it is its responsibility to update GTID
    of applier thread 2.

    10.1. It acquires the lock MYSQL_BIN_LOG::LOCK_log.

    10.2. Returns from `enroll_for()` and proceeds to process the
          "Commit Order" and "Binlog Flush" queues.

    10.3. Fetches the "Commit Order" and "Binlog Flush" queues.

    10.4. Performs the storage engine flush by calling ha_flush_logs() from
          fetch_and_process_flush_stage_queue().

    10.5. Proceeds to update the GTID of threads in "Commit Order" queue by
          calling gtid_state->update_commit_group() from
          Commit_stage_manager::process_final_stage_for_ordered_commit_group().

11. At this point, we will have

    - Client thread performing GTID update on behalf if applier thread 2 (from step 10.5), and
    - Applier thread 1 performing GTID update for itself (from step 8).

    Due to the lack of proper synchronization between the above two threads,
    there exists a time window where both threads can call
    gtid_state->update_commit_group() concurrently.

    In subsequent steps, both threads simultaneously try to modify the contents
    of the array `commit_group_sidnos` which is used to track the lock status of
    sidnos. This concurrent access to `update_commit_group()` can cause a
    lock-leak resulting in one thread acquiring the sidno lock and not
    releasing at all.

-----------------------------------------------------------------------------------------------------------
Client thread                                           Applier Thread 1
-----------------------------------------------------------------------------------------------------------
update_commit_group() => global_sid_lock->rdlock();     update_commit_group() => global_sid_lock->rdlock();

calls update_gtids_impl_lock_sidnos()                   calls update_gtids_impl_lock_sidnos()

set commit_group_sidno[2] = true                        set commit_group_sidno[2] = true

                                                        lock_sidno(2) -> successful

lock_sidno(2) -> waits

                                                        update_gtids_impl_own_gtid() -> Add the thd->owned_gtid in `executed_gtids()`

                                                        if (commit_group_sidnos[2]) {
                                                          unlock_sidno(2);
                                                          commit_group_sidnos[2] = false;
                                                        }

                                                        Applier thread continues..

lock_sidno(2) -> successful

update_gtids_impl_own_gtid() -> Add the thd->owned_gtid in `executed_gtids()`

if (commit_group_sidnos[2]) { <=== this check fails and lock is not released.
  unlock_sidno(2);
  commit_group_sidnos[2] = false;
}

Client thread continues without releasing the lock
-----------------------------------------------------------------------------------------------------------

12. As the above lock-leak can also happen the other way i.e, the applier
    thread fails to unlock, there can be different consequences hereafter.

13. If the client thread continues without releasing the lock, then at a later
    stage, it can enter into a deadlock with the applier thread performing a
    GTID update with stack trace.

    Client_thread
    -------------
    mysql#1  __GI___lll_lock_wait
    mysql#2  ___pthread_mutex_lock
    mysql#3  native_mutex_lock                                       <= waits for commit lock while holding sidno lock
    mysql#4  Commit_stage_manager::enroll_for
    mysql#5  MYSQL_BIN_LOG::change_stage
    mysql#6  MYSQL_BIN_LOG::ordered_commit
    mysql#7  MYSQL_BIN_LOG::commit
    mysql#8  ha_commit_trans
    mysql#9  trans_commit_implicit
    mysql#10 mysql_create_like_table
    mysql#11 Sql_cmd_create_table::execute
    mysql#12 mysql_execute_command
    mysql#13 dispatch_sql_command

    Applier thread
    --------------
    mysql#1  ___pthread_mutex_lock
    mysql#2  native_mutex_lock
    mysql#3  safe_mutex_lock
    mysql#4  Gtid_state::update_gtids_impl_lock_sidnos               <= waits for sidno lock
    mysql#5  Gtid_state::update_commit_group
    mysql#6  Commit_order_manager::flush_engine_and_signal_threads   <= acquires commit lock here
    mysql#7  Commit_order_manager::finish
    mysql#8  Commit_order_manager::wait_and_finish
    mysql#9  ha_commit_low
    mysql#10 trx_coordinator::commit_in_engines
    mysql#11 MYSQL_BIN_LOG::commit
    mysql#12 ha_commit_trans
    mysql#13 trans_commit
    mysql#14 Xid_log_event::do_commit
    mysql#15 Xid_apply_log_event::do_apply_event_worker
    mysql#16 Slave_worker::slave_worker_exec_event
    mysql#17 slave_worker_exec_job_group
    mysql#18 handle_slave_worker

14. If the applier thread continues without releasing the lock, then at a later
    stage, it can perform recursive locking while setting the GTID for the next
    transaction (in set_gtid_next()).

    In debug builds the above case hits the assertion
    `safe_mutex_assert_not_owner()` meaning the lock is already acquired by the
    replica applier thread when it tries to re-acquire the lock.

Solution
--------
In the above problematic example, when seen from each thread
individually, we can conclude that there is no problem in the order of lock
acquisition, thus there is no need to change the lock order.

However, the root cause for this problem is that multiple threads can
concurrently access to the array `Gtid_state::commit_group_sidnos`.

In its initial implementation, it was expected that threads should
hold the `MYSQL_BIN_LOG::LOCK_commit` before modifying its contents. But it
was not considered when upstream implemented WL#7846 (MTS:
slave-preserve-commit-order when log-slave-updates/binlog is disabled).

With this patch, we now ensure that `MYSQL_BIN_LOG::LOCK_commit` is acquired
when the client thread (binlog flush leader) when it tries to perform GTID
update on behalf of threads waiting in "Commit Order" queue, thus providing a
guarantee that `Gtid_state::commit_group_sidnos` array is never accessed
without the protection of `MYSQL_BIN_LOG::LOCK_commit`.
bjornmu pushed a commit that referenced this pull request Apr 30, 2024
…nt on Windows and posix [#3]

Adding a new method NdbProcess::create_via_ssh to be used when invoking
programs over ssh.

Currently no extra quoting of arguments will be done due to the ssh
indirection.  To properly provide that one would need to know about
what shell will ssh use to execute command on remote host, and on
Windows one also need to know what quoting the program expects.

Change-Id: Iff588581c2afa6f599e6055f916dafb5d3cff602
bjornmu pushed a commit that referenced this pull request Apr 30, 2024
Problem:
Starting ´ndb_mgmd --bind-address´ may potentially cause abnormal
program termination in MgmtSrvr destructor when ndb_mgmd restart itself.

  Core was generated by `ndb_mgmd --defa'.
  Program terminated with signal SIGABRT,   Aborted.
  #0  0x00007f8ce4066b8f in raise () from /lib64/libc.so.6
  #1  0x00007f8ce4039ea5 in abort () from /lib64/libc.so.6
  #2  0x00007f8ce40a7d97 in __libc_message () from /lib64/libc.so.6
  #3  0x00007f8ce40af08c in malloc_printerr () from /lib64/libc.so.6
  #4  0x00007f8ce40b132d in _int_free () from /lib64/libc.so.6
  #5  0x00000000006e9ffe in MgmtSrvr::~MgmtSrvr (this=0x28de4b0) at
mysql/8.0/storage/ndb/src/mgmsrv/MgmtSrvr.cpp:
890
  #6  0x00000000006ea09e in MgmtSrvr::~MgmtSrvr (this=0x2) at mysql/8.0/
storage/ndb/src/mgmsrv/MgmtSrvr.cpp:849
  #7  0x0000000000700d94 in mgmd_run () at
mysql/8.0/storage/ndb/src/mgmsrv/main.cpp:260
  #8  0x0000000000700775 in mgmd_main (argc=<optimized out>,
argv=0x28041d0) at mysql/8.0/storage/ndb/src/
mgmsrv/main.cpp:479

Analysis:
While starting up, the ndb_mgmd will allocate memory for bind_address in
order to potentially rewrite the parameter. When ndb_mgmd restart itself
the memory will be released and dangling pointer causing double free.

Fix:
Drop support for bind_address=[::], it is not documented anywhere, is
not useful and doesn't work.
This means the need to rewrite bind_address is gone and bind_address
argument need neither alloc or free.

Change-Id: I7797109b9d8391394587188d64d4b1f398887e94
bjornmu pushed a commit that referenced this pull request Jul 1, 2024
… for connection xxx'.

The new iterator based explains are not impacted.

The issue here is a race condition. More than one thread is using the
query term iterator at the same time (whoch is neithe threas safe nor
reantrant), and part of its state is in the query terms being visited
which leads to interference/race conditions.

a) the explain thread

uses an iterator here:

   Sql_cmd_explain_other_thread::execute

is inspecting the Query_expression of the running query
calling master_query_expression()->find_blocks_query_term which uses
an iterator over the query terms in the query expression:

   for (auto qt : query_terms<>()) {
       if (qt->query_block() == qb) {
           return qt;
       }
   }

the above search fails to find qb due to the interference of the
thread b), see below, and then tries to access a nullpointer:

    * thread #36, name = ‘connection’, stop reason = EXC_BAD_ACCESS (code=1, address=0x0)
  frame #0: 0x000000010bb3cf0d mysqld`Query_block::type(this=0x00007f8f82719088) const at sql_lex.cc:4441:11
  frame #1: 0x000000010b83763e mysqld`(anonymous namespace)::Explain::explain_select_type(this=0x00007000020611b8) at opt_explain.cc:792:50
  frame #2: 0x000000010b83cc4d mysqld`(anonymous namespace)::Explain_join::explain_select_type(this=0x00007000020611b8) at opt_explain.cc:1487:21
  frame #3: 0x000000010b837c34 mysqld`(anonymous namespace)::Explain::prepare_columns(this=0x00007000020611b8) at opt_explain.cc:744:26
  frame #4: 0x000000010b83ea0e mysqld`(anonymous namespace)::Explain_join::explain_qep_tab(this=0x00007000020611b8, tabnum=0) at opt_explain.cc:1415:32
  frame #5: 0x000000010b83ca0a mysqld`(anonymous namespace)::Explain_join::shallow_explain(this=0x00007000020611b8) at opt_explain.cc:1364:9
  frame #6: 0x000000010b83379b mysqld`(anonymous namespace)::Explain::send(this=0x00007000020611b8) at opt_explain.cc:770:14
  frame #7: 0x000000010b834147 mysqld`explain_query_specification(explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00, query_term=0x00007f8f82719088, ctx=CTX_JOIN) at opt_explain.cc:2088:20
  frame #8: 0x000000010bd36b91 mysqld`Query_expression::explain_query_term(this=0x00007f8f7a090360, explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00, qt=0x00007f8f82719088) at sql_union.cc:1519:11
  frame #9: 0x000000010bd36c68 mysqld`Query_expression::explain_query_term(this=0x00007f8f7a090360, explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00, qt=0x00007f8f8271d748) at sql_union.cc:1526:13
  frame #10: 0x000000010bd373f7 mysqld`Query_expression::explain(this=0x00007f8f7a090360, explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00) at sql_union.cc:1591:7
  frame #11: 0x000000010b835820 mysqld`mysql_explain_query_expression(explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00, unit=0x00007f8f7a090360) at opt_explain.cc:2392:17
  frame #12: 0x000000010b835400 mysqld`explain_query(explain_thd=0x00007f8fbb111e00, query_thd=0x00007f8fbb919c00, unit=0x00007f8f7a090360) at opt_explain.cc:2353:13
 * frame #13: 0x000000010b8363e4 mysqld`Sql_cmd_explain_other_thread::execute(this=0x00007f8fba585b68, thd=0x00007f8fbb111e00) at opt_explain.cc:2531:11
  frame #14: 0x000000010bba7d8b mysqld`mysql_execute_command(thd=0x00007f8fbb111e00, first_level=true) at sql_parse.cc:4648:29
  frame #15: 0x000000010bb9e230 mysqld`dispatch_sql_command(thd=0x00007f8fbb111e00, parser_state=0x0000700002065de8) at sql_parse.cc:5303:19
  frame #16: 0x000000010bb9a4cb mysqld`dispatch_command(thd=0x00007f8fbb111e00, com_data=0x0000700002066e38, command=COM_QUERY) at sql_parse.cc:2135:7
  frame #17: 0x000000010bb9c846 mysqld`do_command(thd=0x00007f8fbb111e00) at sql_parse.cc:1464:18
  frame #18: 0x000000010b2f2574 mysqld`handle_connection(arg=0x0000600000e34200) at connection_handler_per_thread.cc:304:13
  frame #19: 0x000000010e072fc4 mysqld`pfs_spawn_thread(arg=0x00007f8fba8160b0) at pfs.cc:3051:3
  frame #20: 0x00007ff806c2b202 libsystem_pthread.dylib`_pthread_start + 99
  frame #21: 0x00007ff806c26bab libsystem_pthread.dylib`thread_start + 15

b) the query thread being explained is itself performing LEX::cleanup
and as part of the iterates over the query terms, but still allows
EXPLAIN of the query plan since

   thd->query_plan.set_query_plan(SQLCOM_END, ...)

hasn't been called yet.

     20:frame: Query_terms<(Visit_order)1, (Visit_leaves)0>::Query_term_iterator::operator++() (in mysqld) (query_term.h:613)
     21:frame: Query_expression::cleanup(bool) (in mysqld) (sql_union.cc:1861)
     22:frame: LEX::cleanup(bool) (in mysqld) (sql_lex.h:4286)
     30:frame: Sql_cmd_dml::execute(THD*) (in mysqld) (sql_select.cc:799)
     31:frame: mysql_execute_command(THD*, bool) (in mysqld) (sql_parse.cc:4648)
     32:frame: dispatch_sql_command(THD*, Parser_state*) (in mysqld) (sql_parse.cc:5303)
     33:frame: dispatch_command(THD*, COM_DATA const*, enum_server_command) (in mysqld) (sql_parse.cc:2135)
     34:frame: do_command(THD*) (in mysqld) (sql_parse.cc:1464)
     57:frame: handle_connection(void*) (in mysqld) (connection_handler_per_thread.cc:304)
     58:frame: pfs_spawn_thread(void*) (in mysqld) (pfs.cc:3053)
     65:frame: _pthread_start (in libsystem_pthread.dylib) + 99
     66:frame: thread_start (in libsystem_pthread.dylib) + 15

Solution:

This patch solves the issue by removing iterator state from
Query_term, making the query_term iterators thread safe. This solution
labels every child query_term with its index in its parent's
m_children vector.  The iterator can therefore easily compute the next
child to visit based on Query_term::m_sibling_idx.

A unit test case is added to check reentrancy.

One can also manually verify that we have no remaining race condition
by running two client connections files (with \. <file>) with a big
number of copies of the repro query in one connection and a big number
of EXPLAIN format=json FOR <connection>, e.g.

    EXPLAIN FORMAT=json FOR CONNECTION 8\G

in the other. The actual connection number would need to verified
in connection one, of course.

Change-Id: Ie7d56610914738ccbbecf399ccc4f465f7d26ea7
bjornmu pushed a commit that referenced this pull request Jul 1, 2024
This is a combination of 5 commits.

This is the 1st commit message:

WL#15746: TLS Enhancements for HeatWave-AutoML & Dask Comm. Upgrade

Problem:
--------
- HeatWave-AutoML communication was unauthenticated, unauthorized,
  and unencrypted.
- Dask communication utilized TCP, not aligning with FedRamp
  guidelines.

Solution:
---------
- Introduced TLS and mTLS in HeatWave-AutoML's plugin and driver for
  authentication, authorization, and encryption.
- Applied TLS to Dask to ensure authentication, encryption, and
  authorization.

Dask Authorization (OCID-based):
--------------------------------
1. For each DBsystem:
    - MySQL node sends OCIDs of authorized nodes to the head driver
      via:
        a. rapid_net_nodes
        b. rapid_net_allowed_ocids (older API, mainly for MTR tests)
    - Scenarios:
        a. All OCIDs provided: Dask authorizes.
        b. Any OCID absent: ML call fails with message.
2. During Dask worker registration to the Dask scheduler, a script is
    dispatched to the Dask worker for execution, retrieving the worker's
    OCID for authorization purposes.
    - If the OCID isn't approved, the connection is denied, terminating
      the worker and causing the ML query to fail.
3. For every Dask worker (both as listener and connector), an OCID-
    based authorization is performed post SSL/TLS connection handshake.
    The process compares the OCID from the peer's certificate against
    the allowed_ocids received from the HeatWave-AutoML MySQL plugin.

HWAML Plugin Changes:
---------------------
- Sourced certificate data and SSL setup from disk, incorporating
  SSL/TLS for HWAML.
- Reused "keystore" variable to specify disk location for
  certificate retrieval.
- Certificates and keys expected in PKCS12 format.
- Introduced "have_ml_encryption" variable (default=0).
    > Acts as a switch to explicitly deactivate HWAML network
      encryption, akin to "disable_net_encryption" affecting
      network encryption for HeatWave. Set to 1 to enable.
- Introduced a customized verifier function for verify_callback to
  be set in SSL_CTX_set_verify and used in the handshake process
  of SSL/TLS. The customized verifier function will perform
  instance id (OCID) based authorization on the plugin side during
  standard SSL/TLS handshake process.
- CRL (Certificate Revocation List) checks are also conducted if CRL
  Distribution Points are present and accessible in the provided
  certificate.

HWAML Driver Changes & OCID-based Authorization:
------------------------------------------------
- Introduced "enable_encryption" (default=0).
    > Set to 1 to enable encryption.
- When receiving a new connection request and encryption is on, the
  driver performs OCID-based self-checking, comparing OCID retrieved
  from its own instance principal with the OCID in the
  provided certificate on disk.
- The driver compares OCID from "mysql_compute_id" and extracted OCID
  from mTLS certificate during connection.
- Introduced "cert_dir" argument for certificate directory
  specification.
- Expected files: cert_chain.pem, certificate.pem, private_key.pem.
    > OCID should be in the userID (UID) or CN field of the
      certificate.pem subject.
- CRL (Certificate Revocation List) checks are also conducted post
  handshake, if CRL Distribution Points are present and accessible in
  the provided certificate, alongside OCID authorization.

Encryption Behavior:
--------------------
- If encryption is deactivated on both plugin and driver side, HWAML
  will work without encryption as it was before this commit.

Enabling Encryption:
--------------------
- By default, "have_ml_encryption" and "enable_encryption" are set to 0
    > Encryption is disabled by default.
- For the HWAML plugin:
    > "have_ml_encryption" set to 1 (default is 0).
    > Specify the .pfx file's path using the "keystore".
- For the HWAML Driver:
    > "enable_encryption" set to 1 (default is 0)
    > Specify "mysql_instance_id" and "cert_dir".

Testing:
--------
- MTR has been modified for the encryption setup.
    > Runs with encryption if "OCI_INSTANCE_ID" is set to a valid
      value.
- On OCI (when "OLRAPID_KEYSTORE" is not set):
    > Certificates and keys are generated; PEMs for driver and PKCS12
      for plugin.
- On AWS (when "OLRAPID_KEYSTORE" is set as the path to PKCS12
  keystore files):
    > PEM files are extracted from the provided PKCS12 and used for
      the driver. The plugin uses the provided PKCS12 keystore file.

Change-Id: I553ca135241e03484db6debbe186e6d34d582bf4

This is the commit message #2:

WL#15746 - Adding ML encryption support to BM

Enabling ML encryption on Baumeister:
- Certificates are generated on MySQLd during initialization
- Needed certicates for workers are packaged and sent to worker nodes
- Workers use packaged files to generate their certificates
- Arguments are added to driver.py invoke
- Keystore path is added to mysql config

Change-Id: I11a5cc5926488ff4fbf91bb6c10a091358db7dc9

This is the commit message #3:

WL#15746: Enhanced CRL Daemon Checker

Issue
=====
The previous design assumed a plain HTTPS link for the CRL distribution
point, accessible to all. This assumption no longer holds, as public
accessibility for CRL distribution contradicts OCI guidelines. Now, the
CRL distribution point in certificates provided by the control plane is
expected to be protected by OCI Instance Principal Authentication.
However, using this authentication method introduces a delay of several
seconds, which is impractical for HeatWave-AutoML.

Solution
========
The CRL fetching code now uses OCI Instance Principal Authentication.
To mitigate performance issues, the CRL checking process has been
redesigned. Instead of enforcing CRL checks per connection in MySQL
Plugin and HeatWave-AutoML Driver communications, a daemon thread in
HeatWave-AutoML Driver, Dask scheduler, and Dask Worker now periodically
fetches and verifies the CRL against all active connections. This
separation minimizes performance impacts. Consequently, MySQL Plugin's
CRL checks have been removed, as checks in the Driver, Scheduler, and
Worker sufficiently cover all cluster nodes.

Changes
=======
- Implemented CRL checker as a daemon thread in Driver, Scheduler, and
  Worker.
- Each connection/socket has an associated CRL checker.
- CRL checks occur periodically at set intervals.
- Skips CRL check if the CRL is temporarily unavailable.
- Failing a CRL check results in the associated connection/socket being
  closed. On the Driver, a stop event is triggered (akin to CTRL-C).

Change-Id: Id998cfe9e15d9236291b0ae420d65c2197837966

This is the commit message #4:

WL#15746: Fix Dask workers being shutdown without releasing address

Issue
=====
Dask workers getting shutting but not releasing the address used
properly sometimes.

Solution
========
Reverted some changes in heatwave_cluster.py in dask worker shutdown
function. Hopefully this will fix the address issue

Change-Id: I5a6749b5a25b0ccb73ba7369e545bc010da1b84f

This is the commit message #5:

WL#15746: Implement Dask Worker Join Timeout for Head Node

Issue:
======
In the cluster_shutdown method, the join operation on the head node's
worker process lacked a timeout. This led to potential indefinite
waiting and eventual hanging of the head node.

Solution:
=========
A timeout has been introduced for the worker process join on the head
node. Unlike non-head nodes, which rely on worker join to complete Dask
tasks and cannot have a timeout, the head node can safely implement
this. Now, if the worker process on the head node fails to shut down
post-join, indicating a timeout, it will be manually terminated. This
ensures proper release of associated resources and prevents hanging of
the head node.

Additional Change:
==================
Added Cert Rotation Guard for DASK clusters. This feature initiates on
the first plugin-driver connection when the DASK cluster is off,
recording the certificate's expiry date. During driver idle times,
it checks the current cert's expiry against this date. If it detects a
change, indicating a certificate rotation, it shuts down the DASK
cluster. The cluster restarts on the next connection request, ensuring
the use of the latest certificate.

Change-Id: Ie63a2e2b7664e05e1622d8bd6503663e13fa73cb
laurynas-biveinis pushed a commit to laurynas-biveinis/mysql-server that referenced this pull request Oct 22, 2024
This is a combination of 5 commits.

This is the 1st commit message:

WL#15746: TLS Enhancements for HeatWave-AutoML & Dask Comm. Upgrade

Problem:
--------
- HeatWave-AutoML communication was unauthenticated, unauthorized,
  and unencrypted.
- Dask communication utilized TCP, not aligning with FedRamp
  guidelines.

Solution:
---------
- Introduced TLS and mTLS in HeatWave-AutoML's plugin and driver for
  authentication, authorization, and encryption.
- Applied TLS to Dask to ensure authentication, encryption, and
  authorization.

Dask Authorization (OCID-based):
--------------------------------
1. For each DBsystem:
    - MySQL node sends OCIDs of authorized nodes to the head driver
      via:
        a. rapid_net_nodes
        b. rapid_net_allowed_ocids (older API, mainly for MTR tests)
    - Scenarios:
        a. All OCIDs provided: Dask authorizes.
        b. Any OCID absent: ML call fails with message.
2. During Dask worker registration to the Dask scheduler, a script is
    dispatched to the Dask worker for execution, retrieving the worker's
    OCID for authorization purposes.
    - If the OCID isn't approved, the connection is denied, terminating
      the worker and causing the ML query to fail.
3. For every Dask worker (both as listener and connector), an OCID-
    based authorization is performed post SSL/TLS connection handshake.
    The process compares the OCID from the peer's certificate against
    the allowed_ocids received from the HeatWave-AutoML MySQL plugin.

HWAML Plugin Changes:
---------------------
- Sourced certificate data and SSL setup from disk, incorporating
  SSL/TLS for HWAML.
- Reused "keystore" variable to specify disk location for
  certificate retrieval.
- Certificates and keys expected in PKCS12 format.
- Introduced "have_ml_encryption" variable (default=0).
    > Acts as a switch to explicitly deactivate HWAML network
      encryption, akin to "disable_net_encryption" affecting
      network encryption for HeatWave. Set to 1 to enable.
- Introduced a customized verifier function for verify_callback to
  be set in SSL_CTX_set_verify and used in the handshake process
  of SSL/TLS. The customized verifier function will perform
  instance id (OCID) based authorization on the plugin side during
  standard SSL/TLS handshake process.
- CRL (Certificate Revocation List) checks are also conducted if CRL
  Distribution Points are present and accessible in the provided
  certificate.

HWAML Driver Changes & OCID-based Authorization:
------------------------------------------------
- Introduced "enable_encryption" (default=0).
    > Set to 1 to enable encryption.
- When receiving a new connection request and encryption is on, the
  driver performs OCID-based self-checking, comparing OCID retrieved
  from its own instance principal with the OCID in the
  provided certificate on disk.
- The driver compares OCID from "mysql_compute_id" and extracted OCID
  from mTLS certificate during connection.
- Introduced "cert_dir" argument for certificate directory
  specification.
- Expected files: cert_chain.pem, certificate.pem, private_key.pem.
    > OCID should be in the userID (UID) or CN field of the
      certificate.pem subject.
- CRL (Certificate Revocation List) checks are also conducted post
  handshake, if CRL Distribution Points are present and accessible in
  the provided certificate, alongside OCID authorization.

Encryption Behavior:
--------------------
- If encryption is deactivated on both plugin and driver side, HWAML
  will work without encryption as it was before this commit.

Enabling Encryption:
--------------------
- By default, "have_ml_encryption" and "enable_encryption" are set to 0
    > Encryption is disabled by default.
- For the HWAML plugin:
    > "have_ml_encryption" set to 1 (default is 0).
    > Specify the .pfx file's path using the "keystore".
- For the HWAML Driver:
    > "enable_encryption" set to 1 (default is 0)
    > Specify "mysql_instance_id" and "cert_dir".

Testing:
--------
- MTR has been modified for the encryption setup.
    > Runs with encryption if "OCI_INSTANCE_ID" is set to a valid
      value.
- On OCI (when "OLRAPID_KEYSTORE" is not set):
    > Certificates and keys are generated; PEMs for driver and PKCS12
      for plugin.
- On AWS (when "OLRAPID_KEYSTORE" is set as the path to PKCS12
  keystore files):
    > PEM files are extracted from the provided PKCS12 and used for
      the driver. The plugin uses the provided PKCS12 keystore file.

Change-Id: I553ca135241e03484db6debbe186e6d34d582bf4

This is the commit message mysql#2:

WL#15746 - Adding ML encryption support to BM

Enabling ML encryption on Baumeister:
- Certificates are generated on MySQLd during initialization
- Needed certicates for workers are packaged and sent to worker nodes
- Workers use packaged files to generate their certificates
- Arguments are added to driver.py invoke
- Keystore path is added to mysql config

Change-Id: I11a5cc5926488ff4fbf91bb6c10a091358db7dc9

This is the commit message mysql#3:

WL#15746: Enhanced CRL Daemon Checker

Issue
=====
The previous design assumed a plain HTTPS link for the CRL distribution
point, accessible to all. This assumption no longer holds, as public
accessibility for CRL distribution contradicts OCI guidelines. Now, the
CRL distribution point in certificates provided by the control plane is
expected to be protected by OCI Instance Principal Authentication.
However, using this authentication method introduces a delay of several
seconds, which is impractical for HeatWave-AutoML.

Solution
========
The CRL fetching code now uses OCI Instance Principal Authentication.
To mitigate performance issues, the CRL checking process has been
redesigned. Instead of enforcing CRL checks per connection in MySQL
Plugin and HeatWave-AutoML Driver communications, a daemon thread in
HeatWave-AutoML Driver, Dask scheduler, and Dask Worker now periodically
fetches and verifies the CRL against all active connections. This
separation minimizes performance impacts. Consequently, MySQL Plugin's
CRL checks have been removed, as checks in the Driver, Scheduler, and
Worker sufficiently cover all cluster nodes.

Changes
=======
- Implemented CRL checker as a daemon thread in Driver, Scheduler, and
  Worker.
- Each connection/socket has an associated CRL checker.
- CRL checks occur periodically at set intervals.
- Skips CRL check if the CRL is temporarily unavailable.
- Failing a CRL check results in the associated connection/socket being
  closed. On the Driver, a stop event is triggered (akin to CTRL-C).

Change-Id: Id998cfe9e15d9236291b0ae420d65c2197837966

This is the commit message mysql#4:

WL#15746: Fix Dask workers being shutdown without releasing address

Issue
=====
Dask workers getting shutting but not releasing the address used
properly sometimes.

Solution
========
Reverted some changes in heatwave_cluster.py in dask worker shutdown
function. Hopefully this will fix the address issue

Change-Id: I5a6749b5a25b0ccb73ba7369e545bc010da1b84f

This is the commit message mysql#5:

WL#15746: Implement Dask Worker Join Timeout for Head Node

Issue:
======
In the cluster_shutdown method, the join operation on the head node's
worker process lacked a timeout. This led to potential indefinite
waiting and eventual hanging of the head node.

Solution:
=========
A timeout has been introduced for the worker process join on the head
node. Unlike non-head nodes, which rely on worker join to complete Dask
tasks and cannot have a timeout, the head node can safely implement
this. Now, if the worker process on the head node fails to shut down
post-join, indicating a timeout, it will be manually terminated. This
ensures proper release of associated resources and prevents hanging of
the head node.

Additional Change:
==================
Added Cert Rotation Guard for DASK clusters. This feature initiates on
the first plugin-driver connection when the DASK cluster is off,
recording the certificate's expiry date. During driver idle times,
it checks the current cert's expiry against this date. If it detects a
change, indicating a certificate rotation, it shuts down the DASK
cluster. The cluster restarts on the next connection request, ensuring
the use of the latest certificate.

Change-Id: Ie63a2e2b7664e05e1622d8bd6503663e13fa73cb
dbussink added a commit to planetscale/mysql-server that referenced this pull request Nov 21, 2024
In case `with_ndb_home` is set, `buf` is allocated with `PATH_MAX` and
the home is already written into the buffer.

The additional path is written using `snprintf` and it starts off at
`len`. It still can write up to `PATH_MAX` though which is wrong, since
if we already have a home written into it, we only have `PATH_MAX - len`
available in the buffer.

On Ubuntu 24.04 with debug builds this is caught and it crashes:

```
*** buffer overflow detected ***: terminated
Signal 6 thrown, attempting backtrace.
stack_bottom = 0 thread_stack 0x0
 #0 0x604895341cb6 <unknown>
 mysql#1 0x7ff22524531f <unknown> at sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
 mysql#2 0x7ff22529eb1c __pthread_kill_implementation at ./nptl/pthread_kill.c:44
 mysql#3 0x7ff22529eb1c __pthread_kill_internal at ./nptl/pthread_kill.c:78
 mysql#4 0x7ff22529eb1c __GI___pthread_kill at ./nptl/pthread_kill.c:89
 mysql#5 0x7ff22524526d __GI_raise at sysdeps/posix/raise.c:26
 mysql#6 0x7ff2252288fe __GI_abort at ./stdlib/abort.c:79
 mysql#7 0x7ff2252297b5 __libc_message_impl at sysdeps/posix/libc_fatal.c:132
 mysql#8 0x7ff225336c18 __GI___fortify_fail at ./debug/fortify_fail.c:24
 mysql#9 0x7ff2253365d3 __GI___chk_fail at ./debug/chk_fail.c:28
 mysql#10 0x7ff225337db4 ___snprintf_chk at ./debug/snprintf_chk.c:29
 mysql#11 0x6048953593ba <unknown>
 mysql#12 0x604895331a3d <unknown>
 mysql#13 0x6048953206e7 <unknown>
 mysql#14 0x60489531f4b1 <unknown>
 mysql#15 0x60489531e8e6 <unknown>
 mysql#16 0x7ff22522a1c9 __libc_start_call_main at sysdeps/nptl/libc_start_call_main.h:58
 mysql#17 0x7ff22522a28a __libc_start_main_impl at csu/libc-start.c:360
 mysql#18 0x60489531ed54 <unknown>
 mysql#19 0xffffffffffffffff <unknown>
```

In practice this buffer overflow only would happen with very long paths.

Signed-off-by: Dirkjan Bussink <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants