[MCOL-4152] Run test005 twice and get mysqld crash Created: 2020-07-07  Updated: 2020-09-21  Resolved: 2020-08-11

Status: Closed
Project: MariaDB ColumnStore
Component/s: MDB Plugin
Affects Version/s: 1.4.3, 1.5.2
Fix Version/s: 5.4.1

Type: Bug Priority: Blocker
Reporter: David Hall (Inactive) Assignee: Daniel Lee (Inactive)
Resolution: Fixed Votes: 0
Labels: None

Sprint: 2020-8

 Description   

If you run test005.sh, it completes fine.
Run it again and you get segv.

The problem appears that ha_mcs::condStack ends up with a garbage entry.

The server reuses handlers, which are created for each table. If a query has a subquery that uses cond_push, it doesn't call cond_pop, leaving the cond on the stack. The next query that uses that handler, has a (now possibly deleted) pointer to a previous query's cond on the condStack.



 Comments   
Comment by David Hall (Inactive) [ 2020-07-08 ]

This query may cause a crash after the first run:
update nation set n_regionkey = (select o_custkey from orders where o_orderkey = n_nationkey and o_orderkey <= 40);
Unfortunately, on my machine, it seems to get the same exact address from malloc each time it calls make_cond_for_table() (sql_select.cc:11582), so while it keeps building the condStack, all the entries are pointing to the same cond and it won't always break. Sometimes it gets a different address and it crashes.

I have verified that the handlers are created once and re-used by breakpoint at ha_mcs.cpp:241

In sqlUpdate.cc: 741, we find:

      if (!table->file->cond_push(select->cond))
        table->file->pushed_cond= select->cond;

and at sqlUpdate.cc:1287 we have:

  if (table->file->pushed_cond)
  {
    table->file->pushed_cond= 0;
    table->file->cond_pop();
  }

But in this query, we get a cond_push for the orders subquery at sql_select.cpp:11581

             COND *push_cond= 
              make_cond_for_table(thd, tmp_cond, current_map, current_map,
                                  -1, FALSE, FALSE);
              if (push_cond)
              {
                /* Push condition to handler */
                if (!tab->table->file->cond_push(push_cond))
                  tab->table->file->pushed_cond= push_cond;
              }

There is no corresponding cond_pop() call. The condition pointer stays in our condStack which is used again for the next query using the "orders" table and condition pushdown.

Comment by David Hall (Inactive) [ 2020-07-09 ]

I added cleanup code in ha_mcs::extra() for operation HA_EXTRA_DETACH_CHILDREN.

Comment by Roman [ 2020-07-13 ]

This doesn't look like appropriate place so we need to check whether handler::reset() got called before we reuse the handler.

Comment by Roman [ 2020-07-13 ]

As I can see our plugin lacks ::reset() method that must reset the cond stack. I'm 99% sure this is why we fail in the first place.

Comment by Gregory Dorman (Inactive) [ 2020-07-14 ]

It did not make it into 1.5.3.

Comment by Daniel Lee (Inactive) [ 2020-08-11 ]

Build verified: 1.5.4-1 (Drone b414)

Repeated test005 three times without mariadbd crashing.

Generated at Thu Feb 08 02:48:12 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.