1
0
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:
Michael Widenius
2009-10-19 20:14:48 +03:00
parent daccf17483
commit ab0905c6d7
58 changed files with 2551 additions and 471 deletions

View File

@ -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;