Commit dd782a87 authored by igor@rurik.mysql.com's avatar igor@rurik.mysql.com

Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1

into rurik.mysql.com:/home/igor/mysql-4.1
parents deaf7f96 dcb0e65d
......@@ -78,4 +78,4 @@ drop database mysqltest;
prepare stmt4 from ' show full processlist ';
execute stmt4;
Id User Host db Command Time State Info
number root localhost test Query time NULL show full processlist
number root localhost test Execute time NULL show full processlist
......@@ -424,8 +424,6 @@ struct Query_cache_query_flags
#define query_cache_invalidate_by_MyISAM_filename_ref NULL
#endif /*HAVE_QUERY_CACHE*/
#define prepare_execute(A) ((A)->command == COM_EXECUTE)
int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create, bool silent);
int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create);
int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent);
......@@ -462,6 +460,7 @@ void mysql_execute_command(THD *thd);
bool do_command(THD *thd);
bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length);
void log_slow_statement(THD *thd);
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
bool table_cache_init(void);
......@@ -899,6 +898,8 @@ extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
extern ulong max_binlog_size, max_relay_log_size;
extern ulong rpl_recovery_rank, thread_cache_size;
extern ulong com_stat[(uint) SQLCOM_END], com_other, back_log;
extern ulong com_stmt_prepare, com_stmt_execute, com_stmt_send_long_data;
extern ulong com_stmt_reset, com_stmt_close;
extern ulong specialflag, current_pid;
extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
extern my_bool relay_log_purge, opt_innodb_safe_binlog;
......@@ -918,6 +919,7 @@ extern my_bool opt_slave_compressed_protocol, use_temp_pool;
extern my_bool opt_readonly, lower_case_file_system;
extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
extern my_bool opt_secure_auth;
extern my_bool opt_log_slow_admin_statements;
extern uint opt_crash_binlog_innodb;
extern char *shared_memory_base_name, *mysqld_unix_port;
extern bool opt_enable_shared_memory;
......
......@@ -294,6 +294,7 @@ my_bool opt_sync_bdb_logs, opt_sync_frm, opt_allow_suspicious_udfs;
my_bool opt_secure_auth= 0;
my_bool opt_short_log_format= 0;
my_bool opt_log_queries_not_using_indexes= 0;
my_bool opt_log_slow_admin_statements= 0;
my_bool lower_case_file_system= 0;
my_bool opt_innodb_safe_binlog= 0;
volatile bool mqh_used = 0;
......@@ -315,6 +316,8 @@ ulong slave_net_timeout, slave_trans_retries;
ulong thread_cache_size=0, binlog_cache_size=0, max_binlog_cache_size=0;
ulong query_cache_size=0;
ulong com_stat[(uint) SQLCOM_END], com_other;
ulong com_stmt_prepare, com_stmt_execute, com_stmt_send_long_data;
ulong com_stmt_close, com_stmt_reset;
ulong bytes_sent, bytes_received, net_big_packet_count;
ulong refresh_version, flush_version; /* Increments on each reload */
ulong query_id, long_query_count;
......@@ -4196,7 +4199,8 @@ enum options_mysqld
OPT_TIME_FORMAT,
OPT_DATETIME_FORMAT,
OPT_LOG_QUERIES_NOT_USING_INDEXES,
OPT_DEFAULT_TIME_ZONE
OPT_DEFAULT_TIME_ZONE,
OPT_LOG_SLOW_ADMIN_STATEMENTS
};
......@@ -4456,7 +4460,7 @@ Disable with --skip-isam.",
"Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
"Log queries that are executed without benefit of any index.",
"Log queries that are executed without benefit of any index to the slow log if it is open.",
(gptr*) &opt_log_queries_not_using_indexes, (gptr*) &opt_log_queries_not_using_indexes,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-short-format", OPT_SHORT_LOG_FORMAT,
......@@ -4467,8 +4471,13 @@ Disable with --skip-isam.",
"Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.",
(gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL,
NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
"Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements to the slow log if it is open.",
(gptr*) &opt_log_slow_admin_statements,
(gptr*) &opt_log_slow_admin_statements,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-queries", OPT_SLOW_QUERY_LOG,
"Log slow queries to this log file. Defaults logging to hostname-slow.log file.",
"Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options.",
(gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
0, 0, 0, 0, 0, 0},
{"log-update", OPT_UPDATE_LOG,
......@@ -5467,6 +5476,11 @@ struct show_var_st status_vars[]= {
{"Com_show_warnings", (char*) (com_stat+(uint) SQLCOM_SHOW_WARNS),SHOW_LONG},
{"Com_slave_start", (char*) (com_stat+(uint) SQLCOM_SLAVE_START),SHOW_LONG},
{"Com_slave_stop", (char*) (com_stat+(uint) SQLCOM_SLAVE_STOP),SHOW_LONG},
{"Com_stmt_prepare", (char*) &com_stmt_prepare, SHOW_LONG},
{"Com_stmt_execute", (char*) &com_stmt_execute, SHOW_LONG},
{"Com_stmt_send_long_data", (char*) &com_stmt_send_long_data, SHOW_LONG},
{"Com_stmt_reset", (char*) &com_stmt_reset, SHOW_LONG},
{"Com_stmt_close", (char*) &com_stmt_close, SHOW_LONG},
{"Com_truncate", (char*) (com_stat+(uint) SQLCOM_TRUNCATE),SHOW_LONG},
{"Com_unlock_tables", (char*) (com_stat+(uint) SQLCOM_UNLOCK_TABLES),SHOW_LONG},
{"Com_update", (char*) (com_stat+(uint) SQLCOM_UPDATE),SHOW_LONG},
......@@ -6084,6 +6098,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
case (int) OPT_SLOW_QUERY_LOG:
opt_slow_log=1;
break;
case (int) OPT_LOG_SLOW_ADMIN_STATEMENTS:
opt_log_slow_admin_statements= 1;
break;
case (int) OPT_SKIP_NEW:
opt_specialflag|= SPECIAL_NO_NEW_FUNC;
delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
......@@ -6443,6 +6460,9 @@ static void get_options(int argc,char **argv)
if (opt_bdb)
sql_print_warning("this binary does not contain BDB storage engine");
#endif
if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) &&
!opt_slow_log)
sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
/*
Check that the default storage engine is actually available.
......
......@@ -916,7 +916,7 @@ class THD :public ilink,
bool query_error, bootstrap, cleanup_done;
bool tmp_table_used;
bool charset_is_system_charset, charset_is_collation_connection;
bool slow_command;
bool enable_slow_log; /* enable slow log for current statement */
my_bool volatile killed;
/*
......
......@@ -59,7 +59,6 @@ static void remove_escape(char *name);
static void refresh_status(void);
static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name);
static void log_slow_query(THD *thd);
const char *any_db="*any*"; // Special symbol for check_access
......@@ -1342,10 +1341,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->command=command;
/*
Commands which will always take a long time should be marked with
this so that they will not get logged to the slow query log
Commands which always take a long time are logged into
the slow log only if opt_log_slow_admin_statements is set.
*/
thd->slow_command=FALSE;
thd->enable_slow_log= TRUE;
thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id=query_id;
......@@ -1383,7 +1382,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint tbl_len= *(uchar*) (packet + db_len + 1);
statistic_increment(com_other, &LOCK_status);
thd->slow_command= TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
db= thd->alloc(db_len + tbl_len + 2);
tbl_name= strmake(db, packet + 1, db_len)+1;
strmake(tbl_name, packet + db_len + 2, tbl_len);
......@@ -1515,7 +1514,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif
ulong length= (ulong)(packet_end-packet);
log_slow_query(thd);
log_slow_statement(thd);
/* Remove garbage at start of query */
while (my_isspace(thd->charset(), *packet) && length > 0)
......@@ -1658,7 +1657,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
uint32 slave_server_id;
statistic_increment(com_other,&LOCK_status);
thd->slow_command = TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
if (check_global_access(thd, REPL_SLAVE_ACL))
break;
......@@ -1827,7 +1826,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->is_fatal_error)
send_error(thd,0); // End of memory ?
log_slow_query(thd);
log_slow_statement(thd);
thd->proc_info="cleaning up";
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
......@@ -1843,13 +1842,16 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
}
static void log_slow_query(THD *thd)
void log_slow_statement(THD *thd)
{
time_t start_of_query=thd->start_time;
thd->end_time(); // Set start time
/* If not reading from backup and if the query took too long */
if (!thd->slow_command && !thd->user_time) // do not log 'slow_command' queries
/*
Do not log administrative statements unless the appropriate option is
set; do not log into slow log if reading from backup.
*/
if (thd->enable_slow_log && !thd->user_time)
{
thd->proc_info="logging slow query";
......@@ -2190,6 +2192,8 @@ mysql_execute_command(THD *thd)
DBUG_PRINT("info", ("DEALLOCATE PREPARE: %.*s\n",
lex->prepared_stmt_name.length,
lex->prepared_stmt_name.str));
/* We account deallocate in the same manner as mysql_stmt_close */
statistic_increment(com_stmt_close, &LOCK_status);
if ((stmt= thd->stmt_map.find_by_name(&lex->prepared_stmt_name)))
{
thd->stmt_map.erase(stmt);
......@@ -2292,7 +2296,7 @@ mysql_execute_command(THD *thd)
check_table_access(thd,SELECT_ACL, tables,0) ||
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_backup_table(thd, tables);
break;
......@@ -2303,7 +2307,7 @@ mysql_execute_command(THD *thd)
check_table_access(thd, INSERT_ACL, tables,0) ||
check_global_access(thd, FILE_ACL))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_restore_table(thd, tables);
break;
}
......@@ -2538,7 +2542,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_CREATE_INDEX:
if (check_one_table_access(thd, INDEX_ACL, tables))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
if (end_active_trans(thd))
res= -1;
else
......@@ -2624,7 +2628,7 @@ mysql_execute_command(THD *thd)
res= -1;
else
{
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res= mysql_alter_table(thd, select_lex->db, lex->name,
&lex->create_info,
tables, lex->create_list,
......@@ -2716,7 +2720,7 @@ mysql_execute_command(THD *thd)
if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_repair_table(thd, tables, &lex->check_opt);
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
......@@ -2736,7 +2740,7 @@ mysql_execute_command(THD *thd)
if (check_db_used(thd,tables) ||
check_table_access(thd, SELECT_ACL | EXTRA_ACL , tables,0))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_check_table(thd, tables, &lex->check_opt);
break;
}
......@@ -2745,7 +2749,7 @@ mysql_execute_command(THD *thd)
if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_analyze_table(thd, tables, &lex->check_opt);
/* ! we write after unlocking the table */
if (!res && !lex->no_write_to_binlog)
......@@ -2766,7 +2770,7 @@ mysql_execute_command(THD *thd)
if (check_db_used(thd,tables) ||
check_table_access(thd,SELECT_ACL | INSERT_ACL, tables,0))
goto error; /* purecov: inspected */
thd->slow_command=TRUE;
thd->enable_slow_log= opt_log_slow_admin_statements;
res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
mysql_recreate_table(thd, tables, 1) :
mysql_optimize_table(thd, tables, &lex->check_opt);
......
......@@ -820,7 +820,8 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
DBUG_ENTER("insert_params_from_vars");
List_iterator<LEX_STRING> var_it(varnames);
String str;
String buf;
const String *val;
uint32 length= 0;
if (query->copy(stmt->query, stmt->query_length, default_charset_info))
DBUG_RETURN(1);
......@@ -831,32 +832,35 @@ static bool insert_params_from_vars_with_log(Prepared_statement *stmt,
varname= var_it++;
if (get_var_with_binlog(stmt->thd, *varname, &entry))
DBUG_RETURN(1);
DBUG_ASSERT(entry);
if (param->set_from_user_var(stmt->thd, entry))
DBUG_RETURN(1);
/* Insert @'escaped-varname' instead of parameter in the query */
char *buf, *ptr;
str.length(0);
if (str.reserve(entry->name.length*2+3))
DBUG_RETURN(1);
if (entry)
{
char *begin, *ptr;
buf.length(0);
if (buf.reserve(entry->name.length*2+3))
DBUG_RETURN(1);
buf= str.c_ptr_quick();
ptr= buf;
*ptr++= '@';
*ptr++= '\'';
ptr+=
escape_string_for_mysql(&my_charset_utf8_general_ci,
ptr, entry->name.str, entry->name.length);
*ptr++= '\'';
str.length(ptr - buf);
begin= ptr= buf.c_ptr_quick();
*ptr++= '@';
*ptr++= '\'';
ptr+= escape_string_for_mysql(&my_charset_utf8_general_ci,
ptr, entry->name.str, entry->name.length);
*ptr++= '\'';
buf.length(ptr - begin);
val= &buf;
}
else
val= &my_null_string;
if (param->convert_str_value(stmt->thd))
DBUG_RETURN(1); /* out of memory */
if (query->replace(param->pos_in_query+length, 1, str))
if (query->replace(param->pos_in_query+length, 1, *val))
DBUG_RETURN(1);
length+= str.length()-1;
length+= val->length()-1;
}
DBUG_RETURN(0);
}
......@@ -1558,6 +1562,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_PRINT("prep_query", ("%s", packet));
/*
If this is an SQLCOM_PREPARE, we also increase Com_prepare_sql.
However, it seems handy if com_stmt_prepare is increased always,
no matter what kind of prepare is processed.
*/
statistic_increment(com_stmt_prepare, &LOCK_status);
if (stmt == 0)
{
send_error(thd, ER_OUT_OF_RESOURCES);
......@@ -1596,7 +1607,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length,
DBUG_RETURN(1);
}
mysql_log.write(thd, COM_PREPARE, "[%lu] %s", stmt->id, packet);
mysql_log.write(thd, thd->command, "[%lu] %s", stmt->id, packet);
thd->current_arena= stmt;
mysql_init_query(thd, (uchar *) thd->query, thd->query_length);
......@@ -1763,6 +1774,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
packet+= 9; /* stmt_id + 5 bytes of flags */
statistic_increment(com_stmt_execute, &LOCK_status);
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute",
SEND_ERROR)))
DBUG_VOID_RETURN;
......@@ -1796,9 +1808,6 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query))
goto set_params_data_err;
#endif
mysql_log.write(thd, COM_EXECUTE, "[%lu] %s", stmt->id,
expanded_query.length() ? expanded_query.c_ptr() :
stmt->query);
thd->protocol= &thd->protocol_prep; // Switch to binary protocol
execute_stmt(thd, stmt, &expanded_query, TRUE);
thd->protocol= &thd->protocol_simple; // Use normal protocol
......@@ -1827,6 +1836,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
String expanded_query;
DBUG_ENTER("mysql_sql_stmt_execute");
/* See comment for statistics_increment in mysql_stmt_prepare */
statistic_increment(com_stmt_execute, &LOCK_status);
if (!(stmt= (Prepared_statement*)thd->stmt_map.find_by_name(stmt_name)))
{
my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_name->length,
......@@ -1853,6 +1864,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name)
my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE");
send_error(thd);
}
thd->command= COM_EXECUTE; /* For nice messages in general log */
execute_stmt(thd, stmt, &expanded_query, FALSE);
DBUG_VOID_RETURN;
}
......@@ -1887,6 +1899,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
my_error(ER_OUTOFMEMORY, 0, expanded_query->length());
DBUG_VOID_RETURN;
}
mysql_log.write(thd, thd->command, "[%lu] %s", stmt->id, thd->query);
/*
At first execution of prepared statement we will perform logical
transformations of the query tree (i.e. negations elimination).
......@@ -1900,6 +1913,14 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt,
thd->lex->unit.cleanup();
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
/*
'start_time' is set in dispatch_command, but THD::query will
be freed when we return from this function. So let's log the slow
query here.
*/
log_slow_statement(thd);
/* Prevent from second logging in the end of dispatch_command */
thd->enable_slow_log= FALSE;
/* Free Items that were created during this execution of the PS. */
free_items(thd->free_list);
......@@ -1941,6 +1962,7 @@ void mysql_stmt_reset(THD *thd, char *packet)
DBUG_ENTER("mysql_stmt_reset");
statistic_increment(com_stmt_reset, &LOCK_status);
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset",
SEND_ERROR)))
DBUG_VOID_RETURN;
......@@ -1973,6 +1995,7 @@ void mysql_stmt_free(THD *thd, char *packet)
DBUG_ENTER("mysql_stmt_free");
statistic_increment(com_stmt_close, &LOCK_status);
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_close",
DONT_SEND_ERROR)))
DBUG_VOID_RETURN;
......@@ -2012,6 +2035,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length)
DBUG_ENTER("mysql_stmt_get_longdata");
statistic_increment(com_stmt_send_long_data, &LOCK_status);
#ifndef EMBEDDED_LIBRARY
/* Minimal size of long data packet is 6 bytes */
if ((ulong) (packet_end - packet) < MYSQL_LONG_DATA_HEADER)
......@@ -2068,10 +2092,12 @@ Prepared_statement::Prepared_statement(THD *thd_arg)
*last_error= '\0';
}
void Prepared_statement::setup_set_params()
{
/* Setup binary logging */
if (mysql_bin_log.is_open() && is_update_query(lex->sql_command))
if (mysql_bin_log.is_open() && is_update_query(lex->sql_command) ||
mysql_log.is_open() || mysql_slow_log.is_open())
{
set_params_from_vars= insert_params_from_vars_with_log;
#ifndef EMBEDDED_LIBRARY
......@@ -2091,6 +2117,7 @@ void Prepared_statement::setup_set_params()
}
}
Prepared_statement::~Prepared_statement()
{
free_items(free_list);
......
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