Commit 7d4ea5cf authored by unknown's avatar unknown

Merge


extra/perror.c:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/sql_acl.cc:
  Merge change in warning message
sql/sql_parse.cc:
  Hand-merge
parents c0cb1faa 87762300
...@@ -245,16 +245,17 @@ int main(int argc,char *argv[]) ...@@ -245,16 +245,17 @@ int main(int argc,char *argv[])
msg = strerror(code); msg = strerror(code);
/* /*
Don't print message for not existing error messages or for We don't print the OS error message if it is the same as the
unknown errors. We test for 'Uknown Errors' just as an unknown_error message we retrieved above, or it starts with
extra safety for Netware 'Unknown Error' (without regard to case).
*/ */
if (msg && strcmp(msg, "Unknown Error") && if (msg &&
my_strnncoll(&my_charset_latin1, msg, 13, "Unknown Error", 13) &&
(!unknown_error || strcmp(msg, unknown_error))) (!unknown_error || strcmp(msg, unknown_error)))
{ {
found=1; found=1;
if (verbose) if (verbose)
printf("Error code %3d: %s\n",code,msg); printf("OS error code %3d: %s\n",code,msg);
else else
puts(msg); puts(msg);
} }
...@@ -269,7 +270,7 @@ int main(int argc,char *argv[]) ...@@ -269,7 +270,7 @@ int main(int argc,char *argv[])
else else
{ {
if (verbose) if (verbose)
printf("MySQL error: %3d = %s\n",code,msg); printf("MySQL error code %3d: %s\n",code,msg);
else else
puts(msg); puts(msg);
} }
......
...@@ -31,3 +31,20 @@ select 5'abcd' ...@@ -31,3 +31,20 @@ select 5'abcd'
select 'finish'; select 'finish';
finish finish
finish finish
flush status;
create table t1 (i int);
insert into t1 values (1);
select * from t1 where i = 1;
insert into t1 values (2),(3),(4);
select * from t1 where i = 2;
select * from t1 where i = 3||||
i
1
i
2
i
3
show status like 'Slow_queries'||||
Variable_name Value
Slow_queries 2
drop table t1||||
--log-slow-queries=slow.log
--log-queries-not-using-indexes
...@@ -14,3 +14,18 @@ select "abcd'";'abcd'select "'abcd";'abcd' ...@@ -14,3 +14,18 @@ select "abcd'";'abcd'select "'abcd";'abcd'
select 5'abcd' select 5'abcd'
delimiter ;'abcd' delimiter ;'abcd'
select 'finish'; select 'finish';
# Bug #8475: Make sure every statement that is a slow query in
# a multi-statement query gets logged as a slow query.
flush status;
delimiter ||||;
create table t1 (i int);
insert into t1 values (1);
select * from t1 where i = 1;
insert into t1 values (2),(3),(4);
select * from t1 where i = 2;
select * from t1 where i = 3||||
show status like 'Slow_queries'||||
drop table t1||||
delimiter ;||||
...@@ -316,12 +316,14 @@ my_bool opt_old_style_user_limits= 0; ...@@ -316,12 +316,14 @@ my_bool opt_old_style_user_limits= 0;
volatile bool mqh_used = 0; volatile bool mqh_used = 0;
my_bool sp_automatic_privileges= 1; my_bool sp_automatic_privileges= 1;
#ifdef HAVE_INITGROUPS
static bool calling_initgroups= FALSE; /* Used in SIGSEGV handler. */
#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options; uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint delay_key_write_options, protocol_version; uint delay_key_write_options, protocol_version;
uint lower_case_table_names; uint lower_case_table_names;
uint tc_heuristic_recover= 0; uint tc_heuristic_recover= 0;
uint volatile thread_count, thread_running, kill_cached_threads, wake_thread; uint volatile thread_count, thread_running, kill_cached_threads, wake_thread;
ulong back_log, connect_timeout, concurrency; ulong back_log, connect_timeout, concurrency;
ulong server_id, thd_startup_options; ulong server_id, thd_startup_options;
ulong table_cache_size, thread_stack, thread_stack_min, what_to_log; ulong table_cache_size, thread_stack, thread_stack_min, what_to_log;
...@@ -1166,7 +1168,15 @@ static void set_user(const char *user, struct passwd *user_info) ...@@ -1166,7 +1168,15 @@ static void set_user(const char *user, struct passwd *user_info)
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__) #if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
DBUG_ASSERT(user_info); DBUG_ASSERT(user_info);
#ifdef HAVE_INITGROUPS #ifdef HAVE_INITGROUPS
initgroups((char*) user,user_info->pw_gid); /*
We can get a SIGSEGV when calling initgroups() on some systems when NSS
is configured to use LDAP and the server is statically linked. We set
calling_initgroups as a flag to the SIGSEGV handler that is then used to
output a specific message to help the user resolve this problem.
*/
calling_initgroups= TRUE;
initgroups((char*) user, user_info->pw_gid);
calling_initgroups= FALSE;
#endif #endif
if (setgid(user_info->pw_gid) == -1) if (setgid(user_info->pw_gid) == -1)
{ {
...@@ -1921,6 +1931,17 @@ information that should help you find out what is causing the crash.\n"); ...@@ -1921,6 +1931,17 @@ information that should help you find out what is causing the crash.\n");
fflush(stderr); fflush(stderr);
#endif /* HAVE_STACKTRACE */ #endif /* HAVE_STACKTRACE */
#ifdef HAVE_INITGROUPS
if (calling_initgroups)
fprintf(stderr, "\n\
This crash occured while the server was calling initgroups(). This is\n\
often due to the use of a mysqld that is statically linked against glibc\n\
and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
mysqld that is not statically linked.\n");
#endif
if (test_flags & TEST_CORE_ON_SIGNAL) if (test_flags & TEST_CORE_ON_SIGNAL)
{ {
fprintf(stderr, "Writing a core file\n"); fprintf(stderr, "Writing a core file\n");
......
...@@ -212,7 +212,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -212,7 +212,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
if (strcmp(host.db, tmp_name) != 0) if (strcmp(host.db, tmp_name) != 0)
sql_print_warning("'host' entry '%s|%s' had database in mixed " sql_print_warning("'host' entry '%s|%s' had database in mixed "
"case that has been forced to lowercase because " "case that has been forced to lowercase because "
"lower_case_table_names is set.", "lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.",
host.host.hostname, host.db); host.host.hostname, host.db);
} }
host.access= get_access(table,2); host.access= get_access(table,2);
...@@ -437,7 +438,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -437,7 +438,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
{ {
sql_print_warning("'db' entry '%s %s@%s' had database in mixed " sql_print_warning("'db' entry '%s %s@%s' had database in mixed "
"case that has been forced to lowercase because " "case that has been forced to lowercase because "
"lower_case_table_names is set.", "lower_case_table_names is set. It will not be "
"possible to remove this privilege using REVOKE.",
db.db, db.user, db.host.hostname, db.host.hostname); db.db, db.user, db.host.hostname, db.host.hostname);
} }
} }
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
extern "C" int gethostname(char *name, int namelen); extern "C" int gethostname(char *name, int namelen);
#endif #endif
static void time_out_user_resource_limits(THD *thd, USER_CONN *uc);
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
static int check_for_max_user_connections(THD *thd, USER_CONN *uc); static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
#endif #endif
...@@ -70,6 +71,7 @@ static void remove_escape(char *name); ...@@ -70,6 +71,7 @@ static void remove_escape(char *name);
static void refresh_status(void); static void refresh_status(void);
static bool append_file_to_dir(THD *thd, const char **filename_ptr, static bool append_file_to_dir(THD *thd, const char **filename_ptr,
const char *table_name); const char *table_name);
static void log_slow_query(THD *thd);
const char *any_db="*any*"; // Special symbol for check_access const char *any_db="*any*"; // Special symbol for check_access
...@@ -486,6 +488,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc) ...@@ -486,6 +488,7 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
error=1; error=1;
goto end; goto end;
} }
time_out_user_resource_limits(thd, uc);
if (uc->user_resources.user_conn && if (uc->user_resources.user_conn &&
uc->user_resources.user_conn < uc->connections) uc->user_resources.user_conn < uc->connections)
{ {
...@@ -604,36 +607,56 @@ bool is_update_query(enum enum_sql_command command) ...@@ -604,36 +607,56 @@ bool is_update_query(enum enum_sql_command command)
} }
/* /*
Check if maximum queries per hour limit has been reached Reset per-hour user resource limits when it has been more than
returns 0 if OK. an hour since they were last checked
In theory we would need a mutex in the USER_CONN structure for this to SYNOPSIS:
be 100 % safe, but as the worst scenario is that we would miss counting time_out_user_resource_limits()
a couple of queries, this isn't critical. thd Thread handler
*/ uc User connection details
NOTE:
This assumes that the LOCK_user_conn mutex has been acquired, so it is
safe to test and modify members of the USER_CONN structure.
*/
static bool check_mqh(THD *thd, uint check_command) static void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
{ {
#ifdef NO_EMBEDDED_ACCESS_CHECKS bool error= 0;
return(0);
#else
bool error=0;
time_t check_time = thd->start_time ? thd->start_time : time(NULL); time_t check_time = thd->start_time ? thd->start_time : time(NULL);
USER_CONN *uc=thd->user_connect; DBUG_ENTER("time_out_user_resource_limits");
DBUG_ENTER("check_mqh");
DBUG_ASSERT(uc != 0);
/* If more than a hour since last check, reset resource checking */ /* If more than a hour since last check, reset resource checking */
if (check_time - uc->intime >= 3600) if (check_time - uc->intime >= 3600)
{ {
(void) pthread_mutex_lock(&LOCK_user_conn);
uc->questions=1; uc->questions=1;
uc->updates=0; uc->updates=0;
uc->conn_per_hour=0; uc->conn_per_hour=0;
uc->intime=check_time; uc->intime=check_time;
(void) pthread_mutex_unlock(&LOCK_user_conn);
} }
DBUG_VOID_RETURN;
}
/*
Check if maximum queries per hour limit has been reached
returns 0 if OK.
*/
static bool check_mqh(THD *thd, uint check_command)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
bool error= 0;
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
USER_CONN *uc=thd->user_connect;
DBUG_ENTER("check_mqh");
DBUG_ASSERT(uc != 0);
(void) pthread_mutex_lock(&LOCK_user_conn);
time_out_user_resource_limits(thd, uc);
/* Check that we have not done too many questions / hour */ /* Check that we have not done too many questions / hour */
if (uc->user_resources.questions && if (uc->user_resources.questions &&
uc->questions++ >= uc->user_resources.questions) uc->questions++ >= uc->user_resources.questions)
...@@ -656,7 +679,10 @@ static bool check_mqh(THD *thd, uint check_command) ...@@ -656,7 +679,10 @@ static bool check_mqh(THD *thd, uint check_command)
} }
} }
end: end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error); DBUG_RETURN(error);
#else
return (0);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
} }
...@@ -1630,6 +1656,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1630,6 +1656,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
#endif #endif
ulong length= (ulong)(packet_end-packet); ulong length= (ulong)(packet_end-packet);
log_slow_query(thd);
/* Remove garbage at start of query */ /* Remove garbage at start of query */
while (my_isspace(thd->charset(), *packet) && length > 0) while (my_isspace(thd->charset(), *packet) && length > 0)
{ {
...@@ -1640,6 +1668,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1640,6 +1668,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->query_length= length; thd->query_length= length;
thd->query= packet; thd->query= packet;
thd->query_id= next_query_id(); thd->query_id= next_query_id();
thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
...@@ -1968,6 +1997,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1968,6 +1997,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->net.report_error) if (thd->net.report_error)
net_send_error(thd); net_send_error(thd);
log_slow_query(thd);
thd->proc_info="cleaning up";
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
thd->proc_info=0;
thd->command=COM_SLEEP;
thd->query=0;
thd->query_length=0;
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
}
static void log_slow_query(THD *thd)
{
time_t start_of_query=thd->start_time; time_t start_of_query=thd->start_time;
thd->end_time(); // Set start time thd->end_time(); // Set start time
...@@ -1986,18 +2033,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1986,18 +2033,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
} }
} }
thd->proc_info="cleaning up";
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
thd->proc_info=0;
thd->command=COM_SLEEP;
thd->query=0;
thd->query_length=0;
thread_running--;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
DBUG_RETURN(error);
} }
......
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