Commit f486f49e authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-4824 userstats - wrong user statistics

(and valgrind warnings)

* move thd userstat initialization to the same function
  that was adding thd userstat to global counters.
* initialize thd->start_bytes_received in THD::init
  (when thd->userstat_running is set)
parent 80a523db
create user foo@localhost identified by 'foo';
flush user_statistics;
set global userstat=1;
select 1;
1
1
select user, bytes_received from information_schema.user_statistics where user = 'foo';
user bytes_received
foo 18
connect(localhost,foo,bar,test,MASTER_PORT,MASTER_SOCKET);
ERROR 28000: Access denied for user 'foo'@'localhost' (using password: YES)
select user, bytes_received from information_schema.user_statistics where user = 'foo';
user bytes_received
foo 18
drop user foo@localhost;
set global userstat=0;
#
# MDEV-4824 userstats - wrong user statistics
#
--source include/not_embedded.inc
create user foo@localhost identified by 'foo';
flush user_statistics;
set global userstat=1;
connect(foo, localhost, foo, foo);
select 1;
disconnect foo;
connection default;
# wait for user_statistics changes to become visible
let $wait_condition= select count(*) = 1 from information_schema.processlist;
--source include/wait_condition.inc
# 41 is for ps-procotol
--replace_result 41 18
select user, bytes_received from information_schema.user_statistics where user = 'foo';
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error ER_ACCESS_DENIED_ERROR
connect(foo, localhost, foo, bar);
connection default;
--replace_result 41 18
select user, bytes_received from information_schema.user_statistics where user = 'foo';
drop user foo@localhost;
set global userstat=0;
...@@ -1337,7 +1337,7 @@ Event_job_data::execute(THD *thd, bool drop) ...@@ -1337,7 +1337,7 @@ Event_job_data::execute(THD *thd, bool drop)
DBUG_ENTER("Event_job_data::execute"); DBUG_ENTER("Event_job_data::execute");
mysql_reset_thd_for_next_command(thd, 0); mysql_reset_thd_for_next_command(thd);
/* /*
MySQL parser currently assumes that current database is either MySQL parser currently assumes that current database is either
......
...@@ -5353,7 +5353,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, ...@@ -5353,7 +5353,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
*/ */
lex_start(thd); lex_start(thd);
thd->lex->local_file= local_fname; thd->lex->local_file= local_fname;
mysql_reset_thd_for_next_command(thd, 0); mysql_reset_thd_for_next_command(thd);
if (!use_rli_only_for_errors) if (!use_rli_only_for_errors)
{ {
...@@ -7353,7 +7353,7 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -7353,7 +7353,7 @@ int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
as the present method does not call mysql_parse(). as the present method does not call mysql_parse().
*/ */
lex_start(thd); lex_start(thd);
mysql_reset_thd_for_next_command(thd, 0); mysql_reset_thd_for_next_command(thd);
/* old copy may exist already */ /* old copy may exist already */
mysql_file_delete(key_file_log_event_data, fname, MYF(0)); mysql_file_delete(key_file_log_event_data, fname, MYF(0));
if ((fd= mysql_file_create(key_file_log_event_data, if ((fd= mysql_file_create(key_file_log_event_data,
...@@ -8308,7 +8308,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli) ...@@ -8308,7 +8308,7 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
we need to do any changes to that value after this function. we need to do any changes to that value after this function.
*/ */
lex_start(thd); lex_start(thd);
mysql_reset_thd_for_next_command(thd, 0); mysql_reset_thd_for_next_command(thd);
/* /*
The current statement is just about to begin and The current statement is just about to begin and
has not yet modified anything. Note, all.modified is reset has not yet modified anything. Note, all.modified is reset
......
...@@ -87,7 +87,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info ...@@ -87,7 +87,7 @@ Old_rows_log_event::do_apply_event(Old_rows_log_event *ev, const Relay_log_info
we need to do any changes to that value after this function. we need to do any changes to that value after this function.
*/ */
lex_start(ev_thd); lex_start(ev_thd);
mysql_reset_thd_for_next_command(ev_thd, 0); mysql_reset_thd_for_next_command(ev_thd);
/* /*
This is a row injection, so we flag the "statement" as This is a row injection, so we flag the "statement" as
......
...@@ -1260,6 +1260,7 @@ void THD::init(void) ...@@ -1260,6 +1260,7 @@ void THD::init(void)
reset_current_stmt_binlog_format_row(); reset_current_stmt_binlog_format_row();
bzero((char *) &status_var, sizeof(status_var)); bzero((char *) &status_var, sizeof(status_var));
bzero((char *) &org_status_var, sizeof(org_status_var)); bzero((char *) &org_status_var, sizeof(org_status_var));
start_bytes_received= 0;
if (variables.sql_log_bin) if (variables.sql_log_bin)
variables.option_bits|= OPTION_BIN_LOG; variables.option_bits|= OPTION_BIN_LOG;
......
...@@ -1556,7 +1556,7 @@ class THD :public Statement, ...@@ -1556,7 +1556,7 @@ class THD :public Statement,
/* Slave applier execution context */ /* Slave applier execution context */
Relay_log_info* rli_slave; Relay_log_info* rli_slave;
void reset_for_next_command(bool calculate_userstat); void reset_for_next_command();
/* /*
Constant for THD::where initialization in the beginning of every query. Constant for THD::where initialization in the beginning of every query.
......
...@@ -717,7 +717,6 @@ bool do_command(THD *thd) ...@@ -717,7 +717,6 @@ bool do_command(THD *thd)
net_new_transaction(net); net_new_transaction(net);
/* Save for user statistics */ /* Save for user statistics */
thd->start_bytes_received= thd->status_var.bytes_received; thd->start_bytes_received= thd->status_var.bytes_received;
...@@ -926,6 +925,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -926,6 +925,14 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (!(server_command_flags[command] & CF_SKIP_QUESTIONS)) if (!(server_command_flags[command] & CF_SKIP_QUESTIONS))
statistic_increment(thd->status_var.questions, &LOCK_status); statistic_increment(thd->status_var.questions, &LOCK_status);
/* Copy data for user stats */
if ((thd->userstat_running= opt_userstat_running))
{
thd->start_cpu_time= my_getcputime();
memcpy(&thd->org_status_var, &thd->status_var, sizeof(thd->status_var));
thd->select_commands= thd->update_commands= thd->other_commands= 0;
}
/** /**
Clear the set of flags that are expected to be cleared at the Clear the set of flags that are expected to be cleared at the
beginning of each command. beginning of each command.
...@@ -1176,7 +1183,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1176,7 +1183,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
break; break;
} }
packet= arg_end + 1; packet= arg_end + 1;
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
lex_start(thd); lex_start(thd);
/* Must be before we init the table list. */ /* Must be before we init the table list. */
if (lower_case_table_names) if (lower_case_table_names)
...@@ -5446,15 +5453,15 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize) ...@@ -5446,15 +5453,15 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
@todo Call it after we use THD for queries, not before. @todo Call it after we use THD for queries, not before.
*/ */
void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat) void mysql_reset_thd_for_next_command(THD *thd)
{ {
thd->reset_for_next_command(calculate_userstat); thd->reset_for_next_command();
} }
void THD::reset_for_next_command(bool calculate_userstat) void THD::reset_for_next_command()
{ {
THD *thd= this; THD *thd= this;
DBUG_ENTER("mysql_reset_thd_for_next_command"); DBUG_ENTER("THD::reset_for_next_command");
DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */ DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
DBUG_ASSERT(! thd->in_sub_stmt); DBUG_ASSERT(! thd->in_sub_stmt);
DBUG_ASSERT(thd->transaction.on); DBUG_ASSERT(thd->transaction.on);
...@@ -5500,14 +5507,6 @@ void THD::reset_for_next_command(bool calculate_userstat) ...@@ -5500,14 +5507,6 @@ void THD::reset_for_next_command(bool calculate_userstat)
thd->sent_row_count= thd->examined_row_count= 0; thd->sent_row_count= thd->examined_row_count= 0;
thd->accessed_rows_and_keys= 0; thd->accessed_rows_and_keys= 0;
/* Copy data for user stats */
if ((thd->userstat_running= calculate_userstat))
{
thd->start_cpu_time= my_getcputime();
memcpy(&thd->org_status_var, &thd->status_var, sizeof(thd->status_var));
thd->select_commands= thd->update_commands= thd->other_commands= 0;
}
thd->query_plan_flags= QPLAN_INIT; thd->query_plan_flags= QPLAN_INIT;
thd->query_plan_fsort_passes= 0; thd->query_plan_fsort_passes= 0;
...@@ -5716,7 +5715,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length, ...@@ -5716,7 +5715,7 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
FIXME: cleanup the dependencies in the code to simplify this. FIXME: cleanup the dependencies in the code to simplify this.
*/ */
lex_start(thd); lex_start(thd);
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0) if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
{ {
...@@ -5819,7 +5818,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length) ...@@ -5819,7 +5818,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
if (!(error= parser_state.init(thd, rawbuf, length))) if (!(error= parser_state.init(thd, rawbuf, length)))
{ {
lex_start(thd); lex_start(thd);
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
if (!parse_sql(thd, & parser_state, NULL) && if (!parse_sql(thd, & parser_state, NULL) &&
all_tables_not_ok(thd, lex->select_lex.table_list.first)) all_tables_not_ok(thd, lex->select_lex.table_list.first))
......
...@@ -83,7 +83,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length); ...@@ -83,7 +83,7 @@ bool alloc_query(THD *thd, const char *packet, uint packet_length);
void mysql_init_select(LEX *lex); void mysql_init_select(LEX *lex);
void mysql_parse(THD *thd, char *rawbuf, uint length, void mysql_parse(THD *thd, char *rawbuf, uint length,
Parser_state *parser_state); Parser_state *parser_state);
void mysql_reset_thd_for_next_command(THD *thd, my_bool calculate_userstat); void mysql_reset_thd_for_next_command(THD *thd);
bool mysql_new_select(LEX *lex, bool move_down); bool mysql_new_select(LEX *lex, bool move_down);
void create_select_for_variable(const char *var_name); void create_select_for_variable(const char *var_name);
void create_table_set_open_action_and_adjust_tables(LEX *lex); void create_table_set_open_action_and_adjust_tables(LEX *lex);
......
...@@ -2269,7 +2269,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length) ...@@ -2269,7 +2269,7 @@ void mysqld_stmt_prepare(THD *thd, const char *packet, uint packet_length)
DBUG_PRINT("prep_query", ("%s", packet)); DBUG_PRINT("prep_query", ("%s", packet));
/* First of all clear possible warnings from the previous command */ /* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
if (! (stmt= new Prepared_statement(thd))) if (! (stmt= new Prepared_statement(thd)))
goto end; /* out of memory: error is set in Sql_alloc */ goto end; /* out of memory: error is set in Sql_alloc */
...@@ -2659,7 +2659,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length) ...@@ -2659,7 +2659,7 @@ void mysqld_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
packet+= 9; /* stmt_id + 5 bytes of flags */ packet+= 9; /* stmt_id + 5 bytes of flags */
/* First of all clear possible warnings from the previous command */ /* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
if (!(stmt= find_prepared_statement(thd, stmt_id))) if (!(stmt= find_prepared_statement(thd, stmt_id)))
{ {
...@@ -2758,7 +2758,7 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length) ...@@ -2758,7 +2758,7 @@ void mysqld_stmt_fetch(THD *thd, char *packet, uint packet_length)
DBUG_ENTER("mysqld_stmt_fetch"); DBUG_ENTER("mysqld_stmt_fetch");
/* First of all clear possible warnings from the previous command */ /* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_fetch); status_var_increment(thd->status_var.com_stmt_fetch);
if (!(stmt= find_prepared_statement(thd, stmt_id))) if (!(stmt= find_prepared_statement(thd, stmt_id)))
...@@ -2818,7 +2818,7 @@ void mysqld_stmt_reset(THD *thd, char *packet) ...@@ -2818,7 +2818,7 @@ void mysqld_stmt_reset(THD *thd, char *packet)
DBUG_ENTER("mysqld_stmt_reset"); DBUG_ENTER("mysqld_stmt_reset");
/* First of all clear possible warnings from the previous command */ /* First of all clear possible warnings from the previous command */
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd);
status_var_increment(thd->status_var.com_stmt_reset); status_var_increment(thd->status_var.com_stmt_reset);
if (!(stmt= find_prepared_statement(thd, stmt_id))) if (!(stmt= find_prepared_statement(thd, stmt_id)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment