1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merge 10.4 into 10.5

This commit is contained in:
Marko Mäkelä
2020-05-04 18:43:00 +03:00
15 changed files with 181 additions and 44 deletions

View File

@ -631,7 +631,13 @@ typedef struct st_key_multi_range
key_range start_key; key_range start_key;
key_range end_key; key_range end_key;
range_id_t ptr; /* Free to use by caller (ptr to row etc) */ range_id_t ptr; /* Free to use by caller (ptr to row etc) */
uint range_flag; /* key range flags see above */ /*
A set of range flags that describe both endpoints: UNIQUE_RANGE,
NULL_RANGE, EQ_RANGE, GEOM_FLAG.
(Flags that describe one endpoint, NO_{MIN|MAX}_RANGE, NEAR_{MIN|MAX} will
not be set here)
*/
uint range_flag;
} KEY_MULTI_RANGE; } KEY_MULTI_RANGE;

View File

@ -8229,6 +8229,37 @@ JSON_DETAILED(JSON_EXTRACT(trace, '$**.semijoin_table_pullout'))
] ]
drop table t1,t2,t3; drop table t1,t2,t3;
# #
# MDEV-22401: Optimizer trace: multi-component range is not printed correctly
#
create table t1 (kp1 int, kp2 int, key(kp1, kp2));
insert into t1 values (1,1),(1,5),(5,1),(5,5);
set optimizer_trace=1;
select * from t1 force index(kp1) where (kp1=2 and kp2 >=4);
kp1 kp2
select JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives'))
[
[
{
"index": "kp1",
"ranges":
[
"(2,4) <= (kp1,kp2) <= (2)"
],
"rowid_ordered": false,
"using_mrr": false,
"index_only": true,
"rows": 1,
"cost": 0.345829876,
"chosen": true
}
]
]
drop table t1;
# End of 10.4 tests
#
# Test many rows to see output of big cost numbers # Test many rows to see output of big cost numbers
# #
select count(*) from seq_1_to_10000000; select count(*) from seq_1_to_10000000;
@ -8326,4 +8357,5 @@ select count(*) from seq_1_to_10000000 {
} }
] ]
} 0 0 } 0 0
# End of 10.5 tests
set optimizer_trace='enabled=off'; set optimizer_trace='enabled=off';

View File

@ -569,6 +569,20 @@ select JSON_DETAILED(JSON_EXTRACT(trace, '$**.semijoin_table_pullout')) from INF
drop table t1,t2,t3; drop table t1,t2,t3;
--echo #
--echo # MDEV-22401: Optimizer trace: multi-component range is not printed correctly
--echo #
create table t1 (kp1 int, kp2 int, key(kp1, kp2));
insert into t1 values (1,1),(1,5),(5,1),(5,5);
set optimizer_trace=1;
select * from t1 force index(kp1) where (kp1=2 and kp2 >=4);
select JSON_DETAILED(JSON_EXTRACT(trace, '$**.range_scan_alternatives')) from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
drop table t1;
--echo # End of 10.4 tests
--echo # --echo #
--echo # Test many rows to see output of big cost numbers --echo # Test many rows to see output of big cost numbers
--echo # --echo #
@ -576,4 +590,5 @@ drop table t1,t2,t3;
select count(*) from seq_1_to_10000000; select count(*) from seq_1_to_10000000;
select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE; select * from INFORMATION_SCHEMA.OPTIMIZER_TRACE;
--echo # End of 10.5 tests
set optimizer_trace='enabled=off'; set optimizer_trace='enabled=off';

View File

@ -2130,4 +2130,20 @@ EXPLAIN
} }
} }
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT
#
set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref|filter a,b b|a 5|5 const 2 (14%) Using where; Using rowid filter
SELECT * FROM t1 WHERE a > 0 AND b=0;
a b
1 0
drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;

View File

@ -339,4 +339,20 @@ eval EXPLAIN FORMAT=JSON $q;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT
--echo #
set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
SELECT * FROM t1 WHERE a > 0 AND b=0;
drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;

View File

@ -2079,6 +2079,22 @@ EXPLAIN
} }
} }
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-22160: SIGSEGV in st_join_table::save_explain_data on SELECT
#
set @save_optimizer_switch= @@optimizer_switch;
SET @@optimizer_switch="index_merge_sort_union=OFF";
CREATE TABLE t1 (a INT, b INT, INDEX(a), INDEX(b));
INSERT INTO t1 VALUES (0,0),(1,0),(-1,1), (-2,1), (-2,3), (-3,4), (-2,4);
explain
SELECT * FROM t1 WHERE a > 0 AND b=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref|filter a,b b|a 5|5 const 2 (14%) Using where; Using rowid filter
SELECT * FROM t1 WHERE a > 0 AND b=0;
a b
1 0
drop table t1;
SET @@optimizer_switch=@save_optimizer_switch;
set @@use_stat_tables=@save_use_stat_tables; set @@use_stat_tables=@save_use_stat_tables;
# #
# MDEV-18755: possible RORI-plan and possible plan with range filter # MDEV-18755: possible RORI-plan and possible plan with range filter

View File

@ -0,0 +1,10 @@
connection node_2;
connection node_1;
connection node_1;
show status like 'wsrep_cluster_conf_id';
Variable_name Value
wsrep_cluster_conf_id 2
connection node_2;
show status like 'wsrep_cluster_conf_id';
Variable_name Value
wsrep_cluster_conf_id 2

View File

@ -0,0 +1,7 @@
--source include/galera_cluster.inc
--connection node_1
show status like 'wsrep_cluster_conf_id';
--connection node_2
show status like 'wsrep_cluster_conf_id';

View File

@ -3223,8 +3223,18 @@ double records_in_column_ranges(PARAM *param, uint idx,
key_range *min_endp, *max_endp; key_range *min_endp, *max_endp;
min_endp= range.start_key.length? &range.start_key : NULL; min_endp= range.start_key.length? &range.start_key : NULL;
max_endp= range.end_key.length? &range.end_key : NULL; max_endp= range.end_key.length? &range.end_key : NULL;
rows= get_column_range_cardinality(field, min_endp, max_endp, int range_flag= range.range_flag;
range.range_flag);
if (!range.start_key.length)
range_flag |= NO_MIN_RANGE;
if (!range.end_key.length)
range_flag |= NO_MAX_RANGE;
if (range.start_key.flag == HA_READ_AFTER_KEY)
range_flag |= NEAR_MIN;
if (range.start_key.flag == HA_READ_BEFORE_KEY)
range_flag |= NEAR_MAX;
rows= get_column_range_cardinality(field, min_endp, max_endp, range_flag);
if (DBL_MAX == rows) if (DBL_MAX == rows)
{ {
total_rows= DBL_MAX; total_rows= DBL_MAX;
@ -15830,24 +15840,29 @@ void print_range(String *out, const KEY_PART_INFO *key_part,
return; return;
} }
if (!(flag & NO_MIN_RANGE)) if (range->start_key.length)
{ {
print_key_value(out, key_part, range->start_key.key, print_key_value(out, key_part, range->start_key.key,
range->start_key.length); range->start_key.length);
if (flag & NEAR_MIN) if (range->start_key.flag == HA_READ_AFTER_KEY)
out->append(STRING_WITH_LEN(" < ")); out->append(STRING_WITH_LEN(" < "));
else else if (range->start_key.flag == HA_READ_KEY_EXACT ||
range->start_key.flag == HA_READ_KEY_OR_NEXT)
out->append(STRING_WITH_LEN(" <= ")); out->append(STRING_WITH_LEN(" <= "));
else
out->append(STRING_WITH_LEN(" ? "));
} }
print_keyparts_name(out, key_part, n_key_parts, keypart_map); print_keyparts_name(out, key_part, n_key_parts, keypart_map);
if (!(flag & NO_MAX_RANGE)) if (range->end_key.length)
{ {
if (flag & NEAR_MAX) if (range->end_key.flag == HA_READ_BEFORE_KEY)
out->append(STRING_WITH_LEN(" < ")); out->append(STRING_WITH_LEN(" < "));
else else if (range->end_key.flag == HA_READ_AFTER_KEY)
out->append(STRING_WITH_LEN(" <= ")); out->append(STRING_WITH_LEN(" <= "));
else
out->append(STRING_WITH_LEN(" ? "));
print_key_value(out, key_part, range->end_key.key, print_key_value(out, key_part, range->end_key.key,
range->end_key.length); range->end_key.length);
} }

View File

@ -262,7 +262,6 @@ walk_up_n_right:
else else
{ {
max_key_parts= MY_MAX(cur->min_key_parts, cur->max_key_parts); max_key_parts= MY_MAX(cur->min_key_parts, cur->max_key_parts);
range->range_flag= cur->min_key_flag | cur->max_key_flag;
range->start_key.key= seq->param->min_key; range->start_key.key= seq->param->min_key;
range->start_key.length= (uint)(cur->min_key - seq->param->min_key); range->start_key.length= (uint)(cur->min_key - seq->param->min_key);
@ -298,6 +297,7 @@ walk_up_n_right:
!memcmp(seq->param->min_key, seq->param->max_key, // (2) !memcmp(seq->param->min_key, seq->param->max_key, // (2)
range->start_key.length); range->start_key.length);
range->range_flag= 0;
if (is_eq_range_pred) if (is_eq_range_pred)
{ {
range->range_flag = EQ_RANGE; range->range_flag = EQ_RANGE;

View File

@ -201,6 +201,7 @@ void Wsrep_server_service::log_view(
wsrep_update_cluster_state_uuid(os.str().c_str()); wsrep_update_cluster_state_uuid(os.str().c_str());
mysql_mutex_unlock(&LOCK_status); mysql_mutex_unlock(&LOCK_status);
wsrep_config_state->set(view); wsrep_config_state->set(view);
wsrep_cluster_conf_id= view.view_seqno().get();
if (view.status() == wsrep::view::primary) if (view.status() == wsrep::view::primary)
{ {

View File

@ -4134,29 +4134,37 @@ innobase_commit_low(
{ {
#ifdef WITH_WSREP #ifdef WITH_WSREP
const char* tmp = 0; const char* tmp = 0;
if (trx->is_wsrep()) { const bool is_wsrep = trx->is_wsrep();
THD* thd = trx->mysql_thd;
if (is_wsrep) {
#ifdef WSREP_PROC_INFO #ifdef WSREP_PROC_INFO
char info[64]; char info[64];
info[sizeof(info) - 1] = '\0'; info[sizeof(info) - 1] = '\0';
snprintf(info, sizeof(info) - 1, snprintf(info, sizeof(info) - 1,
"innobase_commit_low():trx_commit_for_mysql(%lld)", "innobase_commit_low():trx_commit_for_mysql(%lld)",
(long long) wsrep_thd_trx_seqno(trx->mysql_thd)); (long long) wsrep_thd_trx_seqno(thd));
tmp = thd_proc_info(trx->mysql_thd, info); tmp = thd_proc_info(thd, info);
#else #else
tmp = thd_proc_info(trx->mysql_thd, "innobase_commit_low()"); tmp = thd_proc_info(thd, "innobase_commit_low()");
#endif /* WSREP_PROC_INFO */ #endif /* WSREP_PROC_INFO */
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (trx_is_started(trx)) { if (trx_is_started(trx)) {
trx_commit_for_mysql(trx); trx_commit_for_mysql(trx);
} } else {
trx->will_lock = 0; trx->will_lock = 0;
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (trx->is_wsrep()) { thd_proc_info(trx->mysql_thd, tmp); } trx->wsrep = false;
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
} }
#ifdef WITH_WSREP
if (is_wsrep) {
thd_proc_info(thd, tmp);
#endif /* WITH_WSREP */
}
}
/*****************************************************************//** /*****************************************************************//**
Creates an InnoDB transaction struct for the thd if it does not yet have one. Creates an InnoDB transaction struct for the thd if it does not yet have one.
Starts a new InnoDB transaction if a transaction is not yet started. And Starts a new InnoDB transaction if a transaction is not yet started. And
@ -4820,22 +4828,12 @@ static int innobase_close_connection(handlerton *hton, THD *thd)
DBUG_ASSERT(hton == innodb_hton_ptr); DBUG_ASSERT(hton == innodb_hton_ptr);
if (auto trx= thd_to_trx(thd)) if (auto trx= thd_to_trx(thd))
{ {
if (trx->state == TRX_STATE_PREPARED) if (trx->state == TRX_STATE_PREPARED && trx->has_logged_persistent())
{
if (trx->has_logged_persistent())
{ {
trx_disconnect_prepared(trx); trx_disconnect_prepared(trx);
return 0; return 0;
} }
innobase_rollback_trx(trx); innobase_rollback_trx(trx);
}
/*
in theory it may fire if preceding rollback failed,
but what can we do about it?
*/
DBUG_ASSERT(!trx_is_started(trx));
/* some bad guy missed to reset trx->will_lock somewhere, reset it here */
trx->will_lock= 0;
trx_free(trx); trx_free(trx);
} }
return 0; return 0;
@ -5809,7 +5807,6 @@ ha_innobase::open(const char* name, int, uint)
sql_print_error("Failed to open table %s.\n", sql_print_error("Failed to open table %s.\n",
norm_name); norm_name);
} }
no_such_table:
set_my_errno(ENOENT); set_my_errno(ENOENT);
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@ -5835,7 +5832,8 @@ no_such_table:
ib_table->file_unreadable = true; ib_table->file_unreadable = true;
ib_table->corrupted = true; ib_table->corrupted = true;
dict_table_close(ib_table, FALSE, FALSE); dict_table_close(ib_table, FALSE, FALSE);
goto no_such_table; set_my_errno(ENOENT);
DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
} }
innobase_copy_frm_flags_from_table_share(ib_table, table->s); innobase_copy_frm_flags_from_table_share(ib_table, table->s);

View File

@ -442,6 +442,7 @@ Check transaction state */
ut_ad(!(t)->id); \ ut_ad(!(t)->id); \
ut_ad(!(t)->has_logged()); \ ut_ad(!(t)->has_logged()); \
ut_ad(!(t)->is_referenced()); \ ut_ad(!(t)->is_referenced()); \
ut_ad(!(t)->is_wsrep()); \
ut_ad(!(t)->read_view.is_open()); \ ut_ad(!(t)->read_view.is_open()); \
ut_ad((t)->lock.wait_thr == NULL); \ ut_ad((t)->lock.wait_thr == NULL); \
ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \ ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0); \

View File

@ -208,6 +208,9 @@ dberr_t trx_rollback_for_mysql(trx_t* trx)
case TRX_STATE_NOT_STARTED: case TRX_STATE_NOT_STARTED:
trx->will_lock = 0; trx->will_lock = 0;
ut_ad(trx->mysql_thd); ut_ad(trx->mysql_thd);
#ifdef WITH_WSREP
trx->wsrep = false;
#endif
return(DB_SUCCESS); return(DB_SUCCESS);
case TRX_STATE_ACTIVE: case TRX_STATE_ACTIVE:

View File

@ -109,9 +109,6 @@ trx_init(
trx->state = TRX_STATE_NOT_STARTED; trx->state = TRX_STATE_NOT_STARTED;
trx->is_recovered = false; trx->is_recovered = false;
#ifdef WITH_WSREP
trx->wsrep = false;
#endif /* WITH_WSREP */
trx->op_info = ""; trx->op_info = "";
@ -1489,6 +1486,17 @@ inline void trx_t::commit_in_memory(const mtr_t *mtr)
DBUG_LOG("trx", "Commit in memory: " << this); DBUG_LOG("trx", "Commit in memory: " << this);
state= TRX_STATE_NOT_STARTED; state= TRX_STATE_NOT_STARTED;
#ifdef WITH_WSREP
/* Serialization history has been written and the transaction is
committed in memory, which makes this commit ordered. Release commit
order critical section. */
if (wsrep)
{
wsrep= false;
wsrep_commit_ordered(mysql_thd);
}
#endif /* WITH_WSREP */
assert_trx_is_free(this); assert_trx_is_free(this);
trx_init(this); trx_init(this);
trx_mutex_exit(this); trx_mutex_exit(this);
@ -1566,13 +1574,6 @@ void trx_t::commit()
local_mtr.start(); local_mtr.start();
} }
commit_low(mtr); commit_low(mtr);
#ifdef WITH_WSREP
/* Serialization history has been written and the transaction is
committed in memory, which makes this commit ordered. Release commit
order critical section. */
if (mtr && is_wsrep())
wsrep_commit_ordered(mysql_thd);
#endif /* WITH_WSREP */
} }
/****************************************************************//** /****************************************************************//**