1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00
Commit Graph

8416 Commits

Author SHA1 Message Date
Sergei Petrunia
691e964d23 MDEV-31764: ASAN use-after-poison in trace_engine_stats in ANALYZE JSON
Do not attempt to produce "r_engine_stats" on the temporary (=work) tables.
These tables may be
- re-created during the query execution
- freed during the query execution (This is done e.g. in JOIN::cleanup(),
  before we produce ANALYZE FORMAT=JSON output).

- (Also, make save_explain_data() functions not set handler_for_stats
  to point to handler objects that do not have handler->handler_stats set.
  If the storage engine is not collecting handler_stats, it will not have
  them when we're producing ANALYZE FORMAT=JSON output, either).
2023-08-01 22:32:54 +03:00
Oleksandr Byelkin
6bf8483cac Merge branch '10.5' into 10.6 2023-08-01 15:08:52 +02:00
Marko Mäkelä
bce3ee704f Merge 10.10 into 10.11 2023-07-26 14:44:43 +03:00
Marko Mäkelä
b1b47264d2 Merge 10.9 into 10.10 2023-07-26 14:17:36 +03:00
Marko Mäkelä
864bbd4d09 Merge 10.6 into 10.9 2023-07-26 13:42:23 +03:00
Sergei Petrunia
6e484c3bd9 MDEV-31577: Make ANALYZE FORMAT=JSON print innodb stats
ANALYZE FORMAT=JSON output now includes table.r_engine_stats which
has the engine statistics. Only non-zero members are printed.

Internally: EXPLAIN data structures Explain_table_acccess and
Explain_update now have handler* handler_for_stats pointer.
It is used to read statistics from handler_for_stats->handler_stats.

The following applies only to 10.9+, backport doesn't use it:

Explain data structures exist after the tables are closed. We avoid
walking invalid pointers using this:
- SQL layer calls Explain_query::notify_tables_are_closed() before
  closing tables.
- After that call, printing of JSON output is disabled. Non-JSON output
  can be printed but we don't access handler_for_stats when doing that.
2023-07-21 16:50:11 +03:00
Oleksandr Byelkin
f52954ef42 Merge commit '10.4' into 10.5 2023-07-20 11:54:52 +02:00
Marko Mäkelä
7cde5c539b Merge 10.6 into 10.9 2023-07-10 11:22:21 +03:00
Monty
99bd226059 MDEV-31558 Add InnoDB engine information to the slow query log
The new statistics is enabled by adding the "engine", "innodb" or "full"
option to --log-slow-verbosity

Example output:

 # Pages_accessed: 184  Pages_read: 95  Pages_updated: 0  Old_rows_read: 1
 # Pages_read_time: 17.0204  Engine_time: 248.1297

Page_read_time is time doing physical reads inside a storage engine.
(Writes cannot be tracked as these are usually done in the background).
Engine_time is the time spent inside the storage engine for the full
duration of the read/write/update calls. It uses the same code as
'analyze statement' for calculating the time spent.

The engine statistics is done with a generic interface that should be
easy for any engine to use. It can also easily be extended to provide
even more statistics.

Currently only InnoDB has counters for Pages_% and Undo_% status.
Engine_time works for all engines.

Implementation details:

class ha_handler_stats holds all engine stats.  This class is included
in handler and THD classes.
While a query is running, all statistics is updated in the handler. In
close_thread_tables() the statistics is added to the THD.

handler::handler_stats is a pointer to where statistics should be
collected. This is set to point to handler::active_handler_stats if
stats are requested. If not, it is set to 0.
handler_stats has also an element, 'active' that is 1 if stats are
requested. This is to allow engines to avoid doing any 'if's while
updating the statistics.

Cloned or partition tables have the pointer set to the base table if
status are requested.

There is a small performance impact when using --log-slow-verbosity=engine:
- All engine calls in 'select' will be timed.
- IO calls for InnoDB reads will be timed.
- Incrementation of counters are done on local variables and accesses
  are inline, so these should have very little impact.
- Statistics has to be reset for each statement for the THD and each
  used handler. This is only 40 bytes, which should be neglectable.
- For partition tables we have to loop over all partitions to update
  the handler_status as part of table_init(). Can be optimized in the
  future to only do this is log-slow-verbosity changes. For this to work
  we have to update handler_status for all opened partitions and
  also for all partitions opened in the future.

Other things:
- Added options 'engine' and 'full' to log-slow-verbosity.
- Some of the new files in the test suite comes from Percona server, which
  has similar status information.
- buf_page_optimistic_get(): Do not increment any counter, since we are
  only validating a pointer, not performing any buf_pool.page_hash lookup.
- Added THD argument to save_explain_data_intern().
- Switched arguments for save_explain_.*_data() to have
  always THD first (generates better code as other functions also have THD
  first).
2023-07-07 12:53:18 +03:00
Sergei Golubchik
1570c6e3e0 bugfix: join a=b where cast(a as type_of_b) can produce NULL
optimizer implicitly assumed that if `a` in `a=b` is not NULL,
then it's safe to convert `a` to the type of `b` and search the
result in the index(b).

which is not always the case, as converting a non-null value
to a different type might produce NULL. And searching for NULL
in the index might find NULL there, so NULL will be equal to NULL,
making `a=b` behave as if it was `a<=>b`
2023-07-05 22:08:29 +02:00
Sergei Golubchik
22e5a5ff6e generalize ER_QUERY_EXCEEDED_ROWS_EXAMINED_LIMIT
make it "query reached <some limit> result may be incomplete"
2023-07-03 15:46:24 +02:00
Marko Mäkelä
71a1a28a49 Merge 10.10 into 10.11 2023-06-27 17:45:06 +03:00
Marko Mäkelä
135e976696 Merge 10.9 into 10.10 2023-06-27 17:43:31 +03:00
Marko Mäkelä
eb6b521f1b Merge 10.6 into 10.9 2023-06-27 13:48:46 +03:00
Marko Mäkelä
493083833b Merge 10.5 into 10.6 2023-06-26 17:11:38 +03:00
Sergei Petrunia
f7e9ac0d88 MDEV-31449: Assertion s->table->opt_range_condition_rows <= s->found_records
Fix a typo in make_join_statistics(): when updating statistics for
derived table, set s->table->... not "table->..."
2023-06-15 11:27:31 +03:00
Marko Mäkelä
5d7b957eb0 Merge 10.10 into 10.11 2023-06-08 11:23:08 +03:00
Marko Mäkelä
e704a13b32 Merge 10.9 into 10.10 2023-06-08 11:22:12 +03:00
Marko Mäkelä
223c2c5b9d Merge 10.6 into 10.9 2023-06-08 10:46:19 +03:00
Oleksandr Byelkin
04f0b955dd Merge branch '10.6' into 10.6.14 2023-06-07 19:59:52 +02:00
Oleksandr Byelkin
78b1831c9f Merge branch '10.4' into 10.4.30 2023-06-07 15:08:29 +02:00
Marko Mäkelä
609b4e997a Merge mariadb-10.5.21 into 10.5 2023-06-07 15:31:55 +03:00
Marko Mäkelä
c04284e747 Merge 10.10 into 10.11 2023-06-07 15:01:43 +03:00
Marko Mäkelä
82230aa423 Merge 10.9 into 10.10 2023-06-07 14:48:37 +03:00
Sergei Golubchik
a42a6fa99b Merge branch 'bb-10.5-release' into bb-10.6-release 2023-06-05 18:53:02 +02:00
Sergei Golubchik
bed70468ea Merge branch 'bb-10.4-release' into bb-10.5-release 2023-06-05 17:50:51 +02:00
Sergei Petrunia
928012a27a MDEV-31403: Server crashes in st_join_table::choose_best_splitting
The code in choose_best_splitting() assumed that the join prefix is
in join->positions[].

This is not necessarily the case. This function might be called when
the join prefix is in join->best_positions[], too.
Follow the approach from best_access_path(), which calls this function:
pass the current join prefix as an argument,
"const POSITION *join_positions" and use that.
2023-06-05 18:24:39 +03:00
Igor Babaev
aa713f5ae2 MDEV-31224 Crash with EXPLAIN EXTENDED for multi-table update of system table
EXPLAIN EXTENDED should always print the field item used in the left part
of an equality expression from the SET clause of an update statement as a
reference to table column.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-06-03 10:39:34 +02:00
Marko Mäkelä
31be25349f Merge 10.6 into 10.9 2023-05-25 09:24:32 +03:00
Marko Mäkelä
270eeeb523 Merge 10.5 into 10.6 2023-05-23 12:25:39 +03:00
Monty
92d2ceac73 MDEV-28285 Unexpected result when combining DISTINCT, subselect and LIMIT
The problem was that when  JOIN_TAB::remove_duplicates() noticed there
can only be one possible row in the output, it adjusted limits but
didn't take into account any possible offset.

Fixed by not adjusting limit offset when setting one-row-limit.
2023-05-23 09:16:36 +03:00
Monty
16258677b3 MDEV-6768 Wrong result with aggregate with join with no result set
When a query does implicit grouping and join operation produces an empty
result set, a NULL-complemented row combination is generated.
However, constant table fields still show non-NULL values.

What happens in the is that end_send_group() is called with a
const row but without any rows matching the WHERE clause.
This last part is shown by 'join->first_record' not being set.

This causes item->no_rows_in_result() to be called for all items to reset
all sum functions to their initial state. However fields are not set
to NULL.

The used fix is to produce NULL-complemented records for constant tables
as well. Also, reset the constant table's records back in case we're
in a subquery which may get re-executed.
An alternative fix would have item->no_rows_in_result() also work
with Item_field objects.

There is some other issues with the code:
- join->no_rows_in_result_called is used but never set.
- Tables that are used with group functions are not properly marked as
  maybe_null, which is required if the table rows should be regarded as
  null-complemented (not existing).
- The code that tries to detect if mixed_implicit_grouping should be set
  didn't take into account all usage of fields and sum functions.
- Item_func::restore_to_before_no_rows_in_result() called the wrong
  function.
- join->clear() does not use a table_map argument to clear_tables(),
  which caused it to ignore constant tables.
- unclear_tables() does not correctly restore status to what is
  was before clear_tables().

Main bug fix was to always use a table_map argument to clear_tables() and
always use join->clear() and clear_tables() together with unclear_tables().

Other fixes:
- Fixed Item_func::restore_to_before_no_rows_in_result()
- Set 'join->no_rows_in_result_called' when no_rows_in_result_set()
  is called.
- Removed not used argument from setup_end_select_func().
- More code comments
- Ensure that end_send_group() modifies the same fields as are in the
  result set.
- Changed return_zero_rows() to use pointers instead of references,
  similar to the rest of the code.

Reviewer: Sergei Petrunia <sergey@mariadb.com>
2023-05-22 17:15:46 +03:00
Oleg Smirnov
60f0765b58 MDEV-30143 Segfault on select query using index for group-by and filesort
The problem was trying to access JOIN_TAB::select which is set to NULL
when using the filesort. The correct way is accessing either
JOIN_TAB::select or JOIN_TAB::filesort->select depending on whether
the filesort is used.
This commit introduces member function JOIN_TAB::get_sql_select()
encapsulating that check so the code duplication is eliminated.

The new condition (s->table->quick_keys.is_set(best_key->key))
was added to  best_access_path() to eliminate a Valgrind error.
The cause of that error was using TRASH_ALLOC(quick_key_parts)
instead of bzero(quick_key_parts); hence, accessing
s->table->quick_key_parts[best_key->key]) without prior checking
for quick_keys.is_set() might have caused reading "dirty" memory
2023-05-20 09:53:43 +07:00
Oleksandr Byelkin
de703a2b21 Merge branch '10.4' into 10.4.29 release 2023-05-11 09:07:45 +02:00
Marko Mäkelä
1916bf2a02 Merge 10.10 into 10.11 2023-05-11 10:00:06 +03:00
Marko Mäkelä
616ced88bd Merge 10.9 into 10.10 2023-05-11 09:59:27 +03:00
Marko Mäkelä
2763f733ee Merge 10.8 into 10.9 2023-05-11 09:24:59 +03:00
Marko Mäkelä
1f1eaef0af Merge 10.6 into 10.8 2023-05-11 09:00:27 +03:00
Marko Mäkelä
38ed782f55 MDEV-30812 fixup: GCC 12.2.0 -Wmaybe-uninitialized
best_access_path(): Simplify the logic for computing fanout.
This fixes up commit 4329ec5d3b
2023-05-11 08:42:28 +03:00
Igor Babaev
6544d88ff5 MDEV-31224 Crash with EXPLAIN EXTENDED for multi-table update of system table
EXPLAIN EXTENDED should always print the field item used in the left part
of an equality expression from the SET clause of an update statement as a
reference to table column.

Approved by Oleksandr Byelkin <sanja@mariadb.com>
2023-05-09 21:20:10 -07:00
Oleksandr Byelkin
2856859fa3 Merge branch '10.10' into 10.11 2023-05-05 11:31:53 +02:00
Oleksandr Byelkin
3739298241 Merge branch '10.9' into 10.10 2023-05-05 11:26:06 +02:00
Oleksandr Byelkin
2871a05ccd Merge branch '10.8' into 10.9 2023-05-05 11:21:37 +02:00
Oleksandr Byelkin
5f5f743d56 Merge branch '10.6' into 10.8 2023-05-05 11:14:33 +02:00
Oleksandr Byelkin
1c39479598 Merge branch '10.5' into 10.6 2023-05-05 11:09:46 +02:00
Oleksandr Byelkin
b735ca4773 Merge branch '10.4' into 10.5 2023-05-05 10:50:02 +02:00
Sergei Petrunia
2594da7a33 MDEV-31194: Server crash or assertion failure with join_cache_level=4
The problem, introduced in patch for MDEV-26301:

When check_join_cache_usage() decides not to use join buffer, it must
adjust the access method accordingly. For BNL-H joins this means switching
from pseudo-"ref access"(with index=MAX_KEY) to some other access method.

Failing to do this will cause assertions down the line when code that is
not aware of BNL-H will try to initialize index use for ref access with
index=MAX_KEY.

The fix is to follow the regular code path to disable the join buffer for
the join_tab ("goto no_join_cache") instead of just returning from
check_join_cache_usage().
2023-05-05 11:16:23 +03:00
Oleksandr Byelkin
1c60c7ab4b Merge branch '10.10' into 10.11 2023-05-04 11:56:52 +02:00
Oleksandr Byelkin
16e5bc4cbc Merge branch '10.9' into 10.10 2023-05-04 11:50:34 +02:00
Oleksandr Byelkin
d7fae797f4 Merge branch '10.8' into 10.9 2023-05-04 11:39:51 +02:00