mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
This is based on the userstatv2 patch from Percona and OurDelta.
The original code comes, as far as I know, from Google (Mark Callaghan's team) with additional work from Percona, Ourdelta and Weldon Whipple. This code provides the same functionallity, but with a lot of changes to make it faster and better fit the MariaDB infrastucture. Added new status variables: - Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics - Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_sent, Rows_read Added new variable / startup option 'userstat' to control if user statistics should be enabled or not Added my_getcputime(); Returns cpu time used by this thread. New FLUSH commands: - FLUSH SLOW QUERY LOG - FLUSH TABLE_STATISTICS - FLUSH INDEX_STATISTICS - FLUSH USER_STATISTICS - FLUSH CLIENT_STATISTICS New SHOW commands: - SHOW CLIENT_STATISTICS - SHOW USER_STATISTICS - SHOW TABLE_STATISTICS - SHOW INDEX_STATISTICS New Information schemas: - CLIENT_STATISTICS - USER_STATISTICS - INDEX_STATISTICS - TABLE_STATISTICS Added support for all new flush commands to mysqladmin Added handler::ha_... wrappers for all handler read calls to do statistics counting - Changed all code to use new ha_... calls - Count number of read rows, changed rows and rows read trough an index Added counting of number of bytes sent to binary log (status variable Binlog_bytes_written) Added counting of access denied errors (status variable Access_denied_erors) Bugs fixed: - Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long - CLOCK_GETTIME was not propely working on Linuxm client/mysqladmin.cc: Added support for all new flush commmands and some common combinations: flush-slow-log flush-table-statistics flush-index-statistics flush-user-statistics flush-client-statistics flush-all-status flush-all-statistics configure.in: Added checking if clock_gettime needs the librt. (Fixes Bug #37639 clock_gettime is never used/enabled in Linux/Unix) include/my_sys.h: Added my_getcputime() include/mysql_com.h: Added LIST_PROCESS_HOST_LEN & new REFRESH target defines mysql-test/r/information_schema.result: New information schema tables added mysql-test/r/information_schema_all_engines.result: New information schema tables added mysql-test/r/information_schema_db.result: New information schema tables added mysql-test/r/log_slow.result: Added testing that flosh slow query logs is accepted mysql-test/r/status_user.result: Basic testing of user, client, table and index statistics mysql-test/t/log_slow.test: Added testing that flosh slow query logs is accepted mysql-test/t/status_user-master.opt: Ensure that we get a fresh restart before running status_user.test mysql-test/t/status_user.test: Basic testing of user, client, table and index statistics mysys/my_getsystime.c: Added my_getcputime() Returns cpu time used by this thread. sql/authors.h: Updated authors to have core and original MySQL developers first. sql/event_data_objects.cc: Updated call to mysql_reset_thd_for_next_command() sql/event_db_repository.cc: Changed to use new ha_... calls sql/filesort.cc: Changed to use new ha_... calls sql/ha_partition.cc: Changed to use new ha_... calls Fixed comment syntax sql/handler.cc: Changed to use new ha_... calls Reset table statistics Added code to update global table and index status Added counting of rows changed sql/handler.h: Added table and index statistics variables Added function reset_statistics() Added handler::ha_... wrappers for all handler read calls to do statistics counting Protected all normal read calls to ensure we use the new calls in the server. Made ha_partition a friend class so that partition code can call the old read functions sql/item_subselect.cc: Changed to use new ha_... calls sql/lex.h: Added keywords for new information schema tables and flush commands sql/log.cc: Added flush_slow_log() Added counting of number of bytes sent to binary log Removed not needed test of thd (It's used before, so it's safe to use) Added THD object to MYSQL_BIN_LOG::write_cache() to simplify statistics counting sql/log.h: Added new parameter to write_cache() Added flush_slow_log() functions. sql/log_event.cc: Updated call to mysql_reset_thd_for_next_command() Changed to use new ha_... calls sql/log_event_old.cc: Updated call to mysql_reset_thd_for_next_command() Changed to use new ha_... calls sql/mysql_priv.h: Updated call to mysql_reset_thd_for_next_command() Added new statistics functions and variables needed by these. sql/mysqld.cc: Added new statistics variables and structures to handle these Added new status variables: - Com_show_client_statistics, Com_show_index_statistics, Com_show_table_statistics, Com_show_user_statistics - Access_denied_errors, Busy_time (clock time), Binlog_bytes_written, Cpu_time, Empty_queries, Rows_set, Rows_read Added new option 'userstat' to control if user statistics should be enabled or not sql/opt_range.cc: Changed to use new ha_... calls sql/opt_range.h: Changed to use new ha_... calls sql/opt_sum.cc: Changed to use new ha_... calls sql/records.cc: Changed to use new ha_... calls sql/set_var.cc: Added variable 'userstat' sql/sp.cc: Changed to use new ha_... calls sql/sql_acl.cc: Changed to use new ha_... calls Added counting of access_denied_errors sql/sql_base.cc: Added call to statistics functions sql/sql_class.cc: Added usage of org_status_var, to store status variables at start of command Added functions THD::update_stats(), THD::update_all_stats() Fixed bug in add_to_status() and add_diff_to_status() where longlong variables where threated as long sql/sql_class.h: Added new status variables to status_var Moved variables that was not ulong in status_var last. Added variables to THD for storing temporary values during statistics counting sql/sql_connect.cc: Variables and functions to calculate user and client statistics Added counting of access_denied_errors and lost_connections sql/sql_cursor.cc: Changed to use new ha_... calls sql/sql_handler.cc: Changed to use new ha_... calls sql/sql_help.cc: Changed to use new ha_... calls sql/sql_insert.cc: Changed to use new ha_... calls sql/sql_lex.h: Added SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS, SQLCOM_SHOW_CLIENT_STATS sql/sql_parse.cc: Added handling of: - SHOW CLIENT_STATISTICS - SHOW USER_STATISTICS - SHOW TABLE_STATISTICS - SHOW INDEX_STATISTICS Added handling of new FLUSH commands: - FLUSH SLOW QUERY LOGS - FLUSH TABLE_STATISTICS - FLUSH INDEX_STATISTICS - FLUSH USER_STATISTICS - FLUSH CLIENT_STATISTICS Added THD parameter to mysql_reset_thd_for_next_command() Added initialization and calls to user statistics functions Added increment of statistics variables empty_queries, rows_sent and access_denied_errors. Added counting of cpu time per query sql/sql_plugin.cc: Changed to use new ha_... calls sql/sql_prepare.cc: Updated call to mysql_reset_thd_for_next_command() sql/sql_select.cc: Changed to use new ha_... calls Indentation changes sql/sql_servers.cc: Changed to use new ha_... calls sql/sql_show.cc: Added counting of access denied errors Added function for new information schema tables: - CLIENT_STATISTICS - USER_STATISTICS - INDEX_STATISTICS - TABLE_STATISTICS Changed to use new ha_... calls sql/sql_table.cc: Changed to use new ha_... calls sql/sql_udf.cc: Changed to use new ha_... calls sql/sql_update.cc: Changed to use new ha_... calls sql/sql_yacc.yy: Add new show and flush commands sql/structs.h: Add name_length to KEY to avoid some strlen Added cache_name to KEY for fast storage of keyvalue in cache Added structs USER_STATS, TABLE_STATS, INDEX_STATS Added function prototypes for statistics functions sql/table.cc: Store db+table+index name into keyinfo->cache_name sql/table.h: Added new information schema tables sql/tztime.cc: Changed to use new ha_... calls
This commit is contained in:
148
sql/handler.cc
148
sql/handler.cc
@ -1236,6 +1236,7 @@ int ha_commit_one_phase(THD *thd, bool all)
|
||||
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
|
||||
error=1;
|
||||
}
|
||||
/* Should this be done only if is_real_trans is set ? */
|
||||
status_var_increment(thd->status_var.ha_commit_count);
|
||||
ha_info_next= ha_info->next();
|
||||
ha_info->reset(); /* keep it conveniently zero-filled */
|
||||
@ -2092,6 +2093,8 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode,
|
||||
dup_ref=ref+ALIGN_SIZE(ref_length);
|
||||
cached_table_flags= table_flags();
|
||||
}
|
||||
rows_read= rows_changed= 0;
|
||||
memset(index_rows_read, 0, sizeof(index_rows_read));
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -2513,9 +2516,10 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment,
|
||||
key_copy(key, table->record[0],
|
||||
table->key_info + table->s->next_number_index,
|
||||
table->s->next_number_key_offset);
|
||||
error= index_read_map(table->record[1], key,
|
||||
make_prev_keypart_map(table->s->next_number_keypart),
|
||||
HA_READ_PREFIX_LAST);
|
||||
error= ha_index_read_map(table->record[1], key,
|
||||
make_prev_keypart_map(table->s->
|
||||
next_number_keypart),
|
||||
HA_READ_PREFIX_LAST);
|
||||
/*
|
||||
MySQL needs to call us for next row: assume we are inserting ("a",null)
|
||||
here, we return 3, and next this statement will want to insert
|
||||
@ -3549,6 +3553,122 @@ void handler::get_dynamic_partition_info(PARTITION_INFO *stat_info,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Updates the global table stats with the TABLE this handler represents
|
||||
*/
|
||||
|
||||
void handler::update_global_table_stats()
|
||||
{
|
||||
TABLE_STATS * table_stats;
|
||||
|
||||
status_var_add(table->in_use->status_var.rows_read, rows_read);
|
||||
|
||||
if (!table->in_use->userstat_running)
|
||||
{
|
||||
rows_read= rows_changed= 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rows_read + rows_changed == 0)
|
||||
return; // Nothing to update.
|
||||
|
||||
DBUG_ASSERT(table->s && table->s->table_cache_key.str);
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_table_stats);
|
||||
/* Gets the global table stats, creating one if necessary. */
|
||||
if (!(table_stats= (TABLE_STATS*)
|
||||
hash_search(&global_table_stats,
|
||||
(uchar*) table->s->table_cache_key.str,
|
||||
table->s->table_cache_key.length)))
|
||||
{
|
||||
if (!(table_stats = ((TABLE_STATS*)
|
||||
my_malloc(sizeof(TABLE_STATS),
|
||||
MYF(MY_WME | MY_ZEROFILL)))))
|
||||
{
|
||||
/* Out of memory error already given */
|
||||
goto end;
|
||||
}
|
||||
memcpy(table_stats->table, table->s->table_cache_key.str,
|
||||
table->s->table_cache_key.length);
|
||||
table_stats->table_name_length= table->s->table_cache_key.length;
|
||||
table_stats->engine_type= ht->db_type;
|
||||
/* No need to set variables to 0, as we use MY_ZEROFILL above */
|
||||
|
||||
if (my_hash_insert(&global_table_stats, (uchar*) table_stats))
|
||||
{
|
||||
/* Out of memory error is already given */
|
||||
my_free(table_stats, 0);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
// Updates the global table stats.
|
||||
table_stats->rows_read+= rows_read;
|
||||
table_stats->rows_changed+= rows_changed;
|
||||
table_stats->rows_changed_x_indexes+= (rows_changed *
|
||||
(table->s->keys ? table->s->keys :
|
||||
1));
|
||||
rows_read= rows_changed= 0;
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_global_table_stats);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Updates the global index stats with this handler's accumulated index reads.
|
||||
*/
|
||||
|
||||
void handler::update_global_index_stats()
|
||||
{
|
||||
DBUG_ASSERT(table->s);
|
||||
|
||||
if (!table->in_use->userstat_running)
|
||||
{
|
||||
/* Reset all index read values */
|
||||
bzero(index_rows_read, sizeof(index_rows_read[0]) * table->s->keys);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint index = 0; index < table->s->keys; index++)
|
||||
{
|
||||
if (index_rows_read[index])
|
||||
{
|
||||
INDEX_STATS* index_stats;
|
||||
uint key_length;
|
||||
KEY *key_info = &table->key_info[index]; // Rows were read using this
|
||||
|
||||
DBUG_ASSERT(key_info->cache_name);
|
||||
if (!key_info->cache_name)
|
||||
continue;
|
||||
key_length= table->s->table_cache_key.length + key_info->name_length + 1;
|
||||
pthread_mutex_lock(&LOCK_global_index_stats);
|
||||
// Gets the global index stats, creating one if necessary.
|
||||
if (!(index_stats= (INDEX_STATS*) hash_search(&global_index_stats,
|
||||
key_info->cache_name,
|
||||
key_length)))
|
||||
{
|
||||
if (!(index_stats = ((INDEX_STATS*)
|
||||
my_malloc(sizeof(INDEX_STATS),
|
||||
MYF(MY_WME | MY_ZEROFILL)))))
|
||||
goto end; // Error is already given
|
||||
|
||||
memcpy(index_stats->index, key_info->cache_name, key_length);
|
||||
index_stats->index_name_length= key_length;
|
||||
if (my_hash_insert(&global_index_stats, (uchar*) index_stats))
|
||||
{
|
||||
my_free(index_stats, 0);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
/* Updates the global index stats. */
|
||||
index_stats->rows_read+= index_rows_read[index];
|
||||
index_rows_read[index]= 0;
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_global_index_stats);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
** Some general functions that isn't in the handler class
|
||||
****************************************************************************/
|
||||
@ -4207,17 +4327,16 @@ int handler::read_range_first(const key_range *start_key,
|
||||
range_key_part= table->key_info[active_index].key_part;
|
||||
|
||||
if (!start_key) // Read first record
|
||||
result= index_first(table->record[0]);
|
||||
result= ha_index_first(table->record[0]);
|
||||
else
|
||||
result= index_read_map(table->record[0],
|
||||
start_key->key,
|
||||
start_key->keypart_map,
|
||||
start_key->flag);
|
||||
result= ha_index_read_map(table->record[0],
|
||||
start_key->key,
|
||||
start_key->keypart_map,
|
||||
start_key->flag);
|
||||
if (result)
|
||||
DBUG_RETURN((result == HA_ERR_KEY_NOT_FOUND)
|
||||
? HA_ERR_END_OF_FILE
|
||||
: result);
|
||||
|
||||
DBUG_RETURN (compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
|
||||
}
|
||||
|
||||
@ -4243,11 +4362,11 @@ int handler::read_range_next()
|
||||
if (eq_range)
|
||||
{
|
||||
/* We trust that index_next_same always gives a row in range */
|
||||
DBUG_RETURN(index_next_same(table->record[0],
|
||||
end_range->key,
|
||||
end_range->length));
|
||||
DBUG_RETURN(ha_index_next_same(table->record[0],
|
||||
end_range->key,
|
||||
end_range->length));
|
||||
}
|
||||
result= index_next(table->record[0]);
|
||||
result= ha_index_next(table->record[0]);
|
||||
if (result)
|
||||
DBUG_RETURN(result);
|
||||
DBUG_RETURN(compare_key(end_range) <= 0 ? 0 : HA_ERR_END_OF_FILE);
|
||||
@ -4629,6 +4748,7 @@ int handler::ha_write_row(uchar *buf)
|
||||
|
||||
if (unlikely(error= write_row(buf)))
|
||||
DBUG_RETURN(error);
|
||||
rows_changed++;
|
||||
if (unlikely(error= binlog_log_row(table, 0, buf, log_func)))
|
||||
DBUG_RETURN(error); /* purecov: inspected */
|
||||
DBUG_RETURN(0);
|
||||
@ -4650,6 +4770,7 @@ int handler::ha_update_row(const uchar *old_data, uchar *new_data)
|
||||
|
||||
if (unlikely(error= update_row(old_data, new_data)))
|
||||
return error;
|
||||
rows_changed++;
|
||||
if (unlikely(error= binlog_log_row(table, old_data, new_data, log_func)))
|
||||
return error;
|
||||
return 0;
|
||||
@ -4664,6 +4785,7 @@ int handler::ha_delete_row(const uchar *buf)
|
||||
|
||||
if (unlikely(error= delete_row(buf)))
|
||||
return error;
|
||||
rows_changed++;
|
||||
if (unlikely(error= binlog_log_row(table, buf, 0, log_func)))
|
||||
return error;
|
||||
return 0;
|
||||
|
Reference in New Issue
Block a user