1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00
Commit Graph

8566 Commits

Author SHA1 Message Date
Monty
fccfad153f MDEV-31864 Assertion `d >= 0' failed in COST_ADD with join_cache_level > 2 and partitions
The problem was a partitioned table had 0 rows, which caused a division by
zero at hash_join_fanout()
Fix: Do not call hash_join_fanout with 0 rows.
2023-08-08 23:54:48 +03:00
Oleksandr Byelkin
036df5f970 Merge branch '10.10' into 10.11 2023-08-08 14:57:31 +02:00
Oleksandr Byelkin
ced243a099 Merge branch '10.9' into 10.10 2023-08-05 20:34:09 +02:00
Oleksandr Byelkin
998edc374e Merge branch '10.6' into 10.9 2023-08-04 13:27:20 +02:00
Oleksandr Byelkin
c7b6707fe1 Merge branch '10.5' into 10.6 2023-08-04 12:14:00 +02:00
Oleksandr Byelkin
34a8e78581 Merge branch '10.6' into 10.9 2023-08-04 08:01:06 +02:00
Oleg Smirnov
8e8c020fb3 MDEV-31743 Server crash in store_length, assertion failure in Type_handler_string_result::sort_length
After MDEV-21580 the truncation of SORT_FIELD::length
  set_if_smaller(sortorder->length, thd->variables.max_sort_length)

became conditional:
  if (is_variable_sized())
    set_if_smaller(length, thd->variables.max_sort_length)

To provide correct functioning of is_variable_sized() SORT_FIELD::type
must be set properly. This commit adds the necessary initialization
of SORT_FIELD::type to JOIN_TAB::remove_duplicates() as it is done
in filesort's sortlength() function.

DBUG_ASSERT is added to sortlength() just in case to prevent
a possible uint32 overflow
2023-08-03 18:03:31 +07:00
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ä
c6ac1e39b6 Merge 11.0 into 11.1 2023-07-26 15:13:43 +03:00
Marko Mäkelä
f2b4972bd4 Merge 10.11 into 11.0 2023-07-26 15:13:06 +03: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
Oleg Smirnov
d6c6102cad MDEV-30828 Prevent pushing down unions with incorrect ORDER BY
Fake_select_lex->join was prepared at the unit execution stage so
the validation of fake_select_lex before the unit pushdown
was incomplete. That caused pushing down of statements having
an incorrect ORDER BY clause.
This commit moves preparation of the fake_select_lex->join to the unit
prepare() method, before initializing of the pushdown handler,
so incorrect clauses error out before being pushed down
2023-06-30 12:36:47 +07:00
Marko Mäkelä
8290a46d50 Merge 11.0 into 11.1 2023-06-28 09:38:59 +03: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
Monty
3d617fdc7f MDEV-31375 Assertion `dbl_records <= s->records' failed with optimizer_use_condition_selectivity=1
The reason for the crash wad that 'best splitting' optimization
predicted less rows to be found than what opt_range did.
This code in apply_selectivity_for_table(), when using use_cond_selectivity=1,
was not prepared for this case which caused an assert in debug builds.
Production builds is not affected.

The fix is to choose the smaller of the two row counts. It will have a
minimum on costs when using use_cond_selectivity=1 and should not cause
any problems in production.
2023-06-21 15:44:25 +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ä
3883eb63dc Merge 11.0 into 11.1 2023-06-08 14:09:21 +03:00
Marko Mäkelä
5fb2c031f7 Merge 10.11 into 11.0 2023-06-08 13:49:48 +03:00
Marko Mäkelä
cb9d97ef38 Merge mariadb-11.0.2 into 11.0 2023-06-08 11:35:36 +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
Monty
ded4ed3220 MDEV-30944 Range_rowid_filter::fill() leaves file->keyread at MAX_KEY
This test case exposed 2 different bugs:
- When replacing a range with an index scan on a covering key
  in test_if_skip_sort_order() we didn't disable filtering.
  Filtering does not make much sense in this case.
  - Fixed by disabling filtering in this case.
- Range_rowid_filter::fill() did not take into account that keyread
  could already active, which caused an assert when it tried to
  activate another keyread.
  - Fixed by remembering old keyread state at start and restoring it
    at end.

Other things:
- ha_start_keyread() allowed multiple calls. This is wrong, especially
  as we do no check if the index changed!
  I added an assert() to ensure that we don't call it there is already
  an active keyread.
- ha_end_keyread() always called ha_extra(), even if keyread was not
  active.  Added a check to avoid the extra call.
2023-06-07 18:44:12 +03:00
Monty
07b02ab40e MDEV-31356: Range cost calculations does not take into account join_buffer
This patch also fixes
MDEV-31391 Assertion `((best.records_out) == 0.0 ... failed

Cost changes caused by this change:
- range queries with join buffer now have a notable smaller cost.
- range ranges are bit more expensive as the MULTI_RANGE_COST is now
  properly applied to it in all cases (this extra cost is equal to a
  key lookup).
- table scan cost is slight smaller as we now assume data is cached in
  the engine after the first scan pass. (We did this before for range
  scans and other access methods).
- partition tables had wrong values for max_row_blocks and
  max_index_blocks.  Correcting this, causes range access on
  partitioned tables to have slightly higher cost because of the
  increased estimated IO.
- Using first match + join buffer caused 'filtered' to be calcualted
  wrong.  (Only affected EXPLAIN, not query costs).
- Added cost_without_join_buffer to optimizer_trace.
- check_quick_select() adjusted the number of rows according to persistent
  statistics, but did not adjust cost. Now fixed.

The big change in the patch are:

- In best_access_path(), where we now are using storing the cost in
  'ALL_READ_COST cost' and only converting it to a double at the end.
   This allows us to more exactly calculate the effect of the join_cache.
- In JOIN_TAB::estimate_scan_time(), store the cost also in a
  ALL_READ_COST object.

One of effect if this change is that when joining very small tables:

t1    some_access_method
t2    range
t3    ALL         Use join buffer

This is swiched to

t1      some_access_method
t3      ALL
t2      range      use join buffer

Both plans has the same cost, but as table scan in this case has less
cost than rang, the table scan will be considered first and thus have
precidence.

Test case changes:
- optimizer_trace          - Addition of cost_without_join_buffer
- subselect_mat_cost_bugs  - Small tables and scan versus range
- range & range_mrr_icp    - Range + join_cache is faster than ref
- optimizer_trace          - cost_without_join_buffer, smaller scan cost,
                             range setup cost.
- mrr                      - range+join_buffer used as smaller cost
2023-06-07 18:42:58 +03: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
Oleg Smirnov
3118132228 MDEV-25080 Allow pushdown of UNIONs to foreign engines
Allow queries of multiple SELECTs combined together with
UNIONs/EXCEPTs/INTERSECTs to be pushed down to foreign engines.
If the foreign engine provides an interface method "create_unit"
and the UNIT is a top-level unit of the SQL query then the server
tries to push the whole SELECT_LEX_UNIT down to the engine for execution.
The engine should perform necessary checks and if they succeed,
execute the query. If the engine is unable to execute the whole unit,
then another attempt is made to push down SELECTs composing the unit
separately using the "create_select" interface method. In this case
the results of separate SELECTs are combined at the server side
thus composing the final result
2023-06-05 20:15:57 +02:00
Sergei Golubchik
cbabb95915 Merge branch '11.0' into 11.1 2023-06-05 20:15:15 +02:00
Sergei Golubchik
0005f2f06c Merge branch 'bb-10.11-release' into bb-11.0-release 2023-06-05 19:27:00 +02:00
Sergei Golubchik
4e2b93dffe Merge branch 'bb-10.10-release' into bb-10.11-release 2023-06-05 19:04:58 +02:00
Sergei Golubchik
30bba8e275 Merge branch 'github/bb-10.9-release' into bb-10.10-release 2023-06-05 18:59:43 +02:00
Sergei Golubchik
33fd519ca7 Merge branch 'github/bb-10.6-release' into bb-10.9-release 2023-06-05 18:55:26 +02: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