summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Petrunia <sergey@mariadb.com>2022-04-26 15:18:15 +0300
committerSergei Petrunia <sergey@mariadb.com>2022-04-26 15:18:15 +0300
commit2d18943a63ba51657c0e8ff0d4c98b16786a81b0 (patch)
tree8a74a5f20839ad2378caf6bc794a6813ab6fc5e3 /sql
parentc01ee954bf3b10fef85af7b8c77d319ff7bd6b61 (diff)
parent9b2d36660bbb4f93c6b9e0761c91d57d47f59196 (diff)
downloadmariadb-git-bb-10.2-mdev26047.tar.gz
Merge branch '10.2' of github.com:MariaDB/server into 10.2bb-10.2-mdev26047-v2bb-10.2-mdev26047
Diffstat (limited to 'sql')
-rw-r--r--sql/rpl_gtid.h1
-rw-r--r--sql/slave.cc164
-rw-r--r--sql/sp_head.cc2
-rw-r--r--sql/sql_handler.cc4
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_yacc.yy18
-rw-r--r--sql/table.cc2
-rw-r--r--sql/tztime.cc8
8 files changed, 161 insertions, 42 deletions
diff --git a/sql/rpl_gtid.h b/sql/rpl_gtid.h
index e4949ff0d39..bb171f3d95d 100644
--- a/sql/rpl_gtid.h
+++ b/sql/rpl_gtid.h
@@ -26,6 +26,7 @@
extern const LEX_STRING rpl_gtid_slave_state_table_name;
class String;
+#define PARAM_GTID(G) G.domain_id, G.server_id, G.seq_no
struct rpl_gtid
{
diff --git a/sql/slave.cc b/sql/slave.cc
index 2ff1a0490e9..31e50753c9e 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -6196,23 +6196,75 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
}
}
- if (unlikely(mi->gtid_reconnect_event_skip_count))
- {
- goto default_action;
- }
-
/*
- We have successfully queued to relay log everything before this GTID, so
+ Unless the previous group is malformed,
+ we have successfully queued to relay log everything before this GTID, so
in case of reconnect we can start from after any previous GTID.
- (Normally we would have updated gtid_current_pos earlier at the end of
- the previous event group, but better leave an extra check here for
- safety).
+ (We must have updated gtid_current_pos earlier at the end of
+ the previous event group. Unless ...)
*/
- if (mi->events_queued_since_last_gtid)
+ if (unlikely(mi->events_queued_since_last_gtid >
+ mi->gtid_reconnect_event_skip_count))
{
- mi->gtid_current_pos.update(&mi->last_queued_gtid);
- mi->events_queued_since_last_gtid= 0;
+ /*
+ ...unless the last group has not been completed. An assert below
+ can be satisfied only with the strict mode that ensures
+ against "genuine" gtid duplicates.
+ */
+ rpl_gtid *gtid_in_slave_state=
+ mi->gtid_current_pos.find(mi->last_queued_gtid.domain_id);
+
+ // Slave gtid state must not have updated yet to the last received gtid.
+ DBUG_ASSERT((mi->using_gtid == Master_info::USE_GTID_NO ||
+ !opt_gtid_strict_mode) ||
+ (!gtid_in_slave_state ||
+ !(*gtid_in_slave_state == mi->last_queued_gtid)));
+
+ DBUG_EXECUTE_IF("slave_discard_xid_for_gtid_0_x_1000",
+ {
+ /* Inject an event group that is missing its XID commit event. */
+ if (mi->last_queued_gtid.domain_id == 0 &&
+ mi->last_queued_gtid.seq_no == 1000)
+ {
+ sql_print_warning(
+ "Unexpected break of being relay-logged GTID %u-%u-%llu "
+ "event group by the current GTID event %u-%u-%llu",
+ PARAM_GTID(mi->last_queued_gtid),PARAM_GTID(event_gtid));
+ DBUG_SET("-d,slave_discard_xid_for_gtid_0_x_1000");
+ goto dbug_gtid_accept;
+ }
+ });
+ error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
+ sql_print_error("Unexpected break of being relay-logged GTID %u-%u-%llu "
+ "event group by the current GTID event %u-%u-%llu",
+ PARAM_GTID(mi->last_queued_gtid),PARAM_GTID(event_gtid));
+ goto err;
+ }
+ else if (unlikely(mi->gtid_reconnect_event_skip_count > 0))
+ {
+ if (mi->gtid_reconnect_event_skip_count ==
+ mi->events_queued_since_last_gtid)
+ {
+ DBUG_ASSERT(event_gtid == mi->last_queued_gtid);
+
+ goto default_action;
+ }
+
+ DBUG_ASSERT(0);
}
+ // else_likely{...
+#ifndef DBUG_OFF
+dbug_gtid_accept:
+ DBUG_EXECUTE_IF("slave_discard_gtid_0_x_1002",
+ {
+ if (mi->last_queued_gtid.server_id == 27697 &&
+ mi->last_queued_gtid.seq_no == 1002)
+ {
+ DBUG_SET("-d,slave_discard_gtid_0_x_1002");
+ goto skip_relay_logging;
+ }
+ });
+#endif
mi->last_queued_gtid= event_gtid;
mi->last_queued_gtid_standalone=
(gtid_flag & Gtid_log_event::FL_STANDALONE) != 0;
@@ -6222,6 +6274,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
++mi->events_queued_since_last_gtid;
inc_pos= event_len;
+ // ...} eof else_likely
}
break;
/*
@@ -6274,6 +6327,12 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
case XID_EVENT:
DBUG_EXECUTE_IF("slave_discard_xid_for_gtid_0_x_1000",
{
+ if (mi->last_queued_gtid.server_id == 27697 &&
+ mi->last_queued_gtid.seq_no == 1000)
+ {
+ DBUG_SET("-d,slave_discard_xid_for_gtid_0_x_1000");
+ goto skip_relay_logging;
+ }
/* Inject an event group that is missing its XID commit event. */
if (mi->last_queued_gtid.domain_id == 0 &&
mi->last_queued_gtid.seq_no == 1000)
@@ -6319,15 +6378,48 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
}
};);
- if (mi->using_gtid != Master_info::USE_GTID_NO && mi->gtid_event_seen)
+ if (mi->using_gtid != Master_info::USE_GTID_NO)
{
- if (unlikely(mi->gtid_reconnect_event_skip_count))
+ if (likely(mi->gtid_event_seen))
{
- --mi->gtid_reconnect_event_skip_count;
- gtid_skip_enqueue= true;
+ if (unlikely(mi->gtid_reconnect_event_skip_count))
+ {
+ if (!got_gtid_event &&
+ mi->gtid_reconnect_event_skip_count ==
+ mi->events_queued_since_last_gtid)
+ goto gtid_not_start; // the 1st re-sent must be gtid
+
+ --mi->gtid_reconnect_event_skip_count;
+ gtid_skip_enqueue= true;
+ }
+ else if (likely(mi->events_queued_since_last_gtid))
+ {
+ DBUG_ASSERT(!got_gtid_event);
+
+ ++mi->events_queued_since_last_gtid;
+ }
+ else if (Log_event::is_group_event((Log_event_type) (uchar)
+ buf[EVENT_TYPE_OFFSET]))
+ {
+ goto gtid_not_start; // no first gtid event in this group
+ }
+ }
+ else if (Log_event::is_group_event((Log_event_type) (uchar)
+ buf[EVENT_TYPE_OFFSET]))
+ {
+ gtid_not_start:
+
+ DBUG_ASSERT(!got_gtid_event);
+
+ error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
+ sql_print_error("The current group of events starts with "
+ "a non-GTID %s event; "
+ "the last seen GTID is %u-%u-%llu",
+ Log_event::get_type_str((Log_event_type) (uchar)
+ buf[EVENT_TYPE_OFFSET]),
+ mi->last_queued_gtid);
+ goto err;
}
- else if (mi->events_queued_since_last_gtid)
- ++mi->events_queued_since_last_gtid;
}
if (!is_compress_event)
@@ -6500,15 +6592,35 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len)
Query_log_event::peek_is_commit_rollback(buf, event_len,
checksum_alg))))))
{
- /*
- The whole of the current event group is queued. So in case of
- reconnect we can start from after the current GTID.
- */
- mi->gtid_current_pos.update(&mi->last_queued_gtid);
- mi->events_queued_since_last_gtid= 0;
+ DBUG_ASSERT(mi->events_queued_since_last_gtid > 1);
- /* Reset the domain_id_filter flag. */
- mi->domain_id_filter.reset_filter();
+ if (unlikely(gtid_skip_enqueue))
+ {
+ error= ER_SLAVE_RELAY_LOG_WRITE_FAILURE;
+ sql_print_error("Recieved a group closing %s event "
+ "at %llu position in the group while there are "
+ "still %llu events to skip upon reconnecting; "
+ "the last seen GTID is %u-%u-%llu",
+ Log_event::get_type_str((Log_event_type) (uchar)
+ buf[EVENT_TYPE_OFFSET]),
+ (mi->events_queued_since_last_gtid -
+ mi->gtid_reconnect_event_skip_count),
+ mi->events_queued_since_last_gtid,
+ mi->last_queued_gtid);
+ goto err;
+ }
+ else
+ {
+ /*
+ The whole of the current event group is queued. So in case of
+ reconnect we can start from after the current GTID.
+ */
+ mi->gtid_current_pos.update(&mi->last_queued_gtid);
+ mi->events_queued_since_last_gtid= 0;
+
+ /* Reset the domain_id_filter flag. */
+ mi->domain_id_filter.reset_filter();
+ }
}
skip_relay_logging:
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index cb5348cd110..66df02d99fb 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -700,7 +700,7 @@ void
sp_head::set_stmt_end(THD *thd)
{
Lex_input_stream *lip= & thd->m_parser_state->m_lip; /* shortcut */
- const char *end_ptr= lip->get_cpp_ptr(); /* shortcut */
+ const char *end_ptr= lip->get_cpp_tok_start(); /* shortcut */
uint not_used;
/* Make the string of parameters. */
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index ec3756eceba..132556f57b8 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -613,8 +613,10 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
if (!in_prepare)
{
MY_BITMAP *old_map= dbug_tmp_use_all_columns(table, &table->write_set);
- (void) item->save_in_field(key_part->field, 1);
+ int res= item->save_in_field(key_part->field, 1);
dbug_tmp_restore_column_map(&table->write_set, old_map);
+ if (res)
+ return 1;
}
key_len+= key_part->store_length;
keypart_map= (keypart_map << 1) | 1;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index d2186f60709..e9d81417ee6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -16333,8 +16333,7 @@ Field *create_tmp_field_from_field(THD *thd, Field *org_field,
table->s->db_create_options|= HA_OPTION_PACK_RECORD;
else if (org_field->type() == FIELD_TYPE_DOUBLE)
((Field_double *) new_field)->not_fixed= TRUE;
- new_field->vcol_info= new_field->default_value=
- new_field->check_constraint= 0;
+ new_field->vcol_info= 0;
new_field->cond_selectivity= 1.0;
new_field->next_equal_field= NULL;
new_field->option_list= NULL;
@@ -16901,6 +16900,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
table->intersect_keys.init();
table->keys_in_use_for_query.init();
table->no_rows_with_nulls= param->force_not_null_cols;
+ table->expr_arena= thd;
table->s= share;
init_tmp_table_share(thd, share, "", 0, "(temporary)", tmpname);
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 528d4ee4bdc..bade0bd3752 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1035,10 +1035,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%parse-param { THD *thd }
%lex-param { THD *thd }
/*
- Currently there are 98 shift/reduce conflicts.
+ Currently there are 119 shift/reduce conflicts.
We should not introduce new conflicts any more.
*/
-%expect 115
+%expect 119
/*
Comments for TOKENS.
@@ -1258,6 +1258,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
%token FOLLOWS_SYM /* MYSQL trigger*/
%token FOLLOWING_SYM /* SQL-2011-N */
%token FORCE_SYM
+%token FORCE_LOOKAHEAD /* INTERNAL never returned by the lexer */
%token FOREIGN /* SQL-2003-R */
%token FOR_SYM /* SQL-2003-R */
%token FORMAT_SYM
@@ -2710,6 +2711,9 @@ server_option:
}
;
+/* this rule is used to force look-ahead in the parser */
+force_lookahead: {} | FORCE_LOOKAHEAD {} ;
+
event_tail:
remember_name EVENT_SYM opt_if_not_exists sp_name
{
@@ -2854,7 +2858,7 @@ ev_sql_stmt:
lex->sp_chistics.suid= SP_IS_SUID; //always the definer!
lex->sphead->set_body_start(thd, lip->get_cpp_ptr());
}
- sp_proc_stmt
+ sp_proc_stmt force_lookahead
{
LEX *lex= thd->lex;
@@ -16838,8 +16842,8 @@ trigger_tail:
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
- sp_proc_stmt /* $20 */
- { /* $21 */
+ sp_proc_stmt force_lookahead
+ {
LEX *lex= Lex;
sp_head *sp= lex->sphead;
@@ -16939,7 +16943,7 @@ sf_tail:
lex->sphead->set_body_start(thd, lip->get_cpp_tok_start());
}
- sp_proc_stmt_in_returns_clause /* $15 */
+ sp_proc_stmt_in_returns_clause /* $15 */ force_lookahead
{
LEX *lex= thd->lex;
sp_head *sp= lex->sphead;
@@ -17020,7 +17024,7 @@ sp_tail:
{
Lex->sphead->set_body_start(thd, YYLIP->get_cpp_tok_start());
}
- sp_proc_stmt
+ sp_proc_stmt force_lookahead
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
diff --git a/sql/table.cc b/sql/table.cc
index a5f1a5d96cf..605a2e0ddbf 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -5984,7 +5984,7 @@ Item *Field_iterator_view::create_item(THD *thd)
Item *create_view_field(THD *thd, TABLE_LIST *view, Item **field_ref,
const char *name)
{
- bool save_wrapper= thd->lex->select_lex.no_wrap_view_item;
+ bool save_wrapper= thd->lex->current_select->no_wrap_view_item;
Item *field= *field_ref;
DBUG_ENTER("create_view_field");
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 47bc44f3386..8790673c5a0 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -2642,7 +2642,7 @@ static struct my_option my_long_options[] =
&opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"version", 'V', "Output version information and exit.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"skip-write-binlog", 'S', "Do not replicate changes to time zone tables to other nodes in a Galera cluster.",
+ {"skip-write-binlog", 'S', "Do not replicate changes to time zone tables to the binary log, or to other nodes in a Galera cluster.",
&opt_skip_write_binlog,&opt_skip_write_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -2738,9 +2738,9 @@ main(int argc, char **argv)
sql_log_bin and wsrep_on to avoid Galera replicating below
truncate table clauses. This will allow user to set different
time zones to nodes in Galera cluster. */
- printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON'), 'SET SESSION SQL_LOG_BIN=?, WSREP_ON=OFF;', 'do ?');\n"
- "prepare set_wsrep_write_binlog from @prep1;\n"
- "set @toggle=0; execute set_wsrep_write_binlog using @toggle;\n");
+ printf("set @prep1=if((select count(*) from information_schema.global_variables where variable_name='wsrep_on' and variable_value='ON'), 'SET SESSION WSREP_ON=OFF', 'do 0');\n"
+ "SET SESSION SQL_LOG_BIN=0;\n"
+ "execute immediate @prep1;\n");
}
else
{