Slow query log to file now displays queries with microsecond precission

--long-query-time is now given in seconds with microseconds as decimals
--min_examined_row_limit added for slow query log
long_query_time user variable is now double with 6 decimals
Added functions to get time in microseconds
Added faster time() functions for system that has gethrtime()  (Solaris)
We now do less time() calls.
Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers
set_var.cc and my_getopt() can now handle DOUBLE variables.
All time() calls changed to my_time()
my_time() now does retry's if time() call fails.
Added debug function for stopping in mysql_admin_table() when tables are locked
Some trivial function and struct variable renames to avoid merge errors.
Fixed compiler warnings
Initialization of some time variables on windows moved to my_init() 


include/my_getopt.h:
  Added support for double arguments
include/my_sys.h:
  Fixed wrong type to packfrm()
  Added new my_time functions
include/mysql/plugin.h:
  Added support for DOUBLE
libmysql/CMakeLists.txt:
  Added new time functions
libmysql/Makefile.shared:
  Added new time functions
mysql-test/r/variables.result:
  Testing of long_query_time
mysql-test/t/variables.test:
  Testing of long_query_time
mysys/charset.c:
  Fixed compiler warnings
mysys/default_modify.c:
  Fixed compiler warnings
mysys/hash.c:
  Fixed compiler warnings
mysys/mf_getdate.c:
  Use my_time()
mysys/mf_iocache2.c:
  Fixed compiler warnings
mysys/mf_pack.c:
  Fixed compiler warnings
mysys/mf_path.c:
  Fixed compiler warnings
mysys/my_append.c:
  Fixed compiler warnings
mysys/my_compress.c:
  Fixed compiler warnings
mysys/my_copy.c:
  Fixed compiler warnings
mysys/my_gethwaddr.c:
  Fixed compiler warnings
mysys/my_getopt.c:
  Added support for double arguments
mysys/my_getsystime.c:
  Added functions to get time in microseconds.
  Added faster time() functions for system that has gethrtime()  (Solaris)
  Moved windows initialization code to my_init()
mysys/my_init.c:
  Added initializing of variables needed for windows time functions
mysys/my_static.c:
  Added variables needed for windows time functions
mysys/my_static.h:
  Added variables needed for windows time functions
mysys/my_thr_init.c:
  Added THR_LOCK_time, used for faster my_time()
mysys/mysys_priv.h:
  Added THR_LOCK_time, used for faster my_time()
mysys/thr_alarm.c:
  time() -> my_time()
sql/event_data_objects.cc:
  end_time() -> set_current_time()
sql/event_queue.cc:
  end_time() -> set_current_time()
sql/event_scheduler.cc:
  Fixed compiler warnings
sql/field.h:
  Added field->in_read_set() and field->in_write_set() for easier field manipulation by handlers
sql/item.h:
  Added decimal to Item_float(double)
sql/item_cmpfunc.h:
  Added decimal to Item_float(double)
sql/item_timefunc.cc:
  time() -> my_time()
sql/item_xmlfunc.cc:
  Fixed compiler warning
sql/lock.cc:
  lock_time() -> set_time_after_lock()
sql/log.cc:
  Timing in slow query log to file is now done in microseconds
  Changed some while() loops to for() loops.
  Fixed indentation
  time() -> my_time()
sql/log.h:
  Slow query logging is now done based on microseconds
sql/log_event.cc:
  time() -> my_time()
  Fixed arguments to new Item_float()
sql/mysql_priv.h:
  Fixed compiler warnings
  Added opt_log_slow_slave_statements
sql/mysqld.cc:
  Added --log_slow_slave_statements and --min_examined_row_limit
  --long-query-time now takes a double argument with microsecond resolution
  Don't write shutdown message when using --help
  Removed not needed \n
  Thread create time and connect time is now done in microseconds
  time() -> my_time()
  Avoid some time() calls
sql/net_serv.cc:
  Fixed compiler warnings
sql/parse_file.cc:
  time() -> my_time()
sql/set_var.cc:
  Added support for DOUBLE variables
  Added support for variables that are given in seconds with microsecond resolution
sql/set_var.h:
  Added support for variables that are given in seconds with microsecond resolution
sql/slave.cc:
  Allow logging of slave queries to slow query log if 'opt_log_slow_slave_statements' is given
  time() -> my_time()
sql/sql_cache.h:
  Fixed compiler warning()
sql/sql_class.cc:
  Initialize new THD variables
sql/sql_class.h:
  long_query_time is now in microseconds
  Added min_examined_row_limit
  Reordered some THD elements for higher efficency
  Added timers in microseconds (connect_utime, thr_create_utime, start_utime and utime_after_lock)
  Start of query is now recorded both in seconds and in microseconds.
  Following renames was made for more clarity and avoid merge problems from earlier versions:
  connect_time -> connect_utime
  thr_create_time -> thr_create_utime
  end_time()  -> set_current_time()
  lock_time() -> set_time_after_lock()
  
  Added THD::start_utime, which is start of query in microseconds from some arbitary time
  Added function THD::current_utime()
  
  Removed safe_time() as retry's are handled in my_time()
sql/sql_connect.cc:
  User resources are now using microsecond resolution
sql/sql_insert.cc:
  end_time() -> set_current_time()
sql-common/client.c:
  time() -> my_time()
sql/sql_parse.cc:
  Testing if we should print to slow_query_log() is now done with microsecond precission.
  If min_examined_row_limit is given, only log queries to slow query log that has examined more rows than this.
sql/sql_select.cc:
  Simplify code now that Item_float() takes decimals as argument
sql/sql_show.cc:
  time() -> my_time()
  Added support for SYS_DOUBLE
sql/sql_table.cc:
  Added debug function for stopping in mysql_admin_table() when tables are locked
sql/structs.h:
  intime -> reset_utime
This commit is contained in:
unknown 2007-07-30 11:33:50 +03:00
parent ae8d075508
commit b59217ebbb
56 changed files with 625 additions and 245 deletions

View file

@ -31,6 +31,7 @@ C_MODE_START
#define GET_DISABLED 11
#define GET_ENUM 12
#define GET_SET 13
#define GET_DOUBLE 14
#define GET_ASK_ADDR 128
#define GET_TYPE_MASK 127

View file

@ -833,7 +833,7 @@ extern my_bool my_compress(uchar *, size_t *, size_t *);
extern my_bool my_uncompress(uchar *, size_t , size_t *);
extern uchar *my_compress_alloc(const uchar *packet, size_t *len,
size_t *complen);
extern int packfrm(const uchar *, size_t, uchar **, size_t *);
extern int packfrm(uchar *, size_t, uchar **, size_t *);
extern int unpackfrm(uchar **, size_t *, const uchar *);
extern ha_checksum my_checksum(ha_checksum crc, const uchar *mem,
@ -846,7 +846,11 @@ extern void my_sleep(ulong m_seconds);
extern uint my_set_max_open_files(uint files);
void my_free_open_file_info(void);
extern time_t my_time(myf flags);
extern ulonglong my_getsystime(void);
extern ulonglong my_micro_time();
extern ulonglong my_micro_time_and_time(time_t *time_arg);
time_t my_time_possible_from_micro(ulonglong microtime);
extern my_bool my_gethwaddr(uchar *to);
extern int my_getncpus();

View file

@ -110,7 +110,7 @@ enum enum_mysql_show_type
{
SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG,
SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR,
SHOW_ARRAY, SHOW_FUNC
SHOW_ARRAY, SHOW_FUNC, SHOW_DOUBLE
};
struct st_mysql_show_var {

View file

@ -63,7 +63,7 @@ ADD_LIBRARY(libmysql SHARED dll.c libmysql.def
../strings/strmov.c ../strings/strnlen.c ../strings/strnmov.c ../strings/strtod.c
../strings/strtoll.c ../strings/strtoull.c ../strings/strxmov.c ../strings/strxnmov.c
../mysys/thr_mutex.c ../mysys/typelib.c ../vio/vio.c ../vio/viosocket.c
../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c)
../vio/viossl.c ../vio/viosslfactories.c ../strings/xml.c ../mysys/my_getsystime.c)
ADD_DEPENDENCIES(libmysql dbug vio mysys strings GenError zlib yassl taocrypt)
TARGET_LINK_LIBRARIES(libmysql mysys strings wsock32)

View file

@ -68,7 +68,7 @@ mysysobjects1 = my_init.lo my_static.lo my_malloc.lo my_realloc.lo \
mf_iocache2.lo my_seek.lo my_sleep.lo \
my_pread.lo mf_cache.lo md5.lo sha1.lo \
my_getopt.lo my_gethostbyname.lo my_port.lo \
my_rename.lo my_chsize.lo
my_rename.lo my_chsize.lo my_getsystime.lo
sqlobjects = net.lo
sql_cmn_objects = pack.lo client.lo my_time.lo

View file

@ -444,7 +444,14 @@ set interactive_timeout=100;
set join_buffer_size=100;
set last_insert_id=1;
set global local_infile=1;
set long_query_time=100;
set long_query_time=0.000001;
select @@long_query_time;
@@long_query_time
0.000001
set long_query_time=100.000001;
select @@long_query_time;
@@long_query_time
100.000001
set low_priority_updates=1;
set max_allowed_packet=100;
set global max_binlog_cache_size=100;

View file

@ -268,7 +268,10 @@ set interactive_timeout=100;
set join_buffer_size=100;
set last_insert_id=1;
set global local_infile=1;
set long_query_time=100;
set long_query_time=0.000001;
select @@long_query_time;
set long_query_time=100.000001;
select @@long_query_time;
set low_priority_updates=1;
set max_allowed_packet=100;
set global max_binlog_cache_size=100;

View file

@ -323,14 +323,14 @@ static int charset_initialized=0;
static my_bool my_read_charset_file(const char *filename, myf myflags)
{
char *buf;
uchar *buf;
int fd;
uint len, tmp_len;
MY_STAT stat_info;
if (!my_stat(filename, &stat_info, MYF(myflags)) ||
((len= (uint)stat_info.st_size) > MY_MAX_ALLOWED_BUF) ||
!(buf= (char *)my_malloc(len,myflags)))
!(buf= (uchar*) my_malloc(len,myflags)))
return TRUE;
if ((fd=my_open(filename,O_RDONLY,myflags)) < 0)
@ -340,7 +340,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
if (tmp_len != len)
goto error;
if (my_parse_charset_xml(buf,len,add_collation))
if (my_parse_charset_xml((char*) buf,len,add_collation))
{
#ifdef NOT_YET
printf("ERROR at line %d pos %d '%s'\n",
@ -350,7 +350,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags)
#endif
}
my_free(buf, myflags);
my_free(buf, myflags);
return FALSE;
error:

View file

@ -218,7 +218,7 @@ int modify_defaults_file(const char *file_location, const char *option,
if (my_chsize(fileno(cnf_file), (my_off_t) (dst_ptr - file_buffer), 0,
MYF(MY_WME)) ||
my_fseek(cnf_file, 0, MY_SEEK_SET, MYF(0)) ||
my_fwrite(cnf_file, file_buffer, (size_t) (dst_ptr - file_buffer),
my_fwrite(cnf_file, (uchar*) file_buffer, (size_t) (dst_ptr - file_buffer),
MYF(MY_NABP)))
goto err;
}

View file

@ -137,7 +137,7 @@ void my_hash_reset(HASH *hash)
DBUG_VOID_RETURN;
}
/* some helper functions */
/* some helper functions */
/*
This function is char* instead of uchar* as HPUX11 compiler can't
@ -149,9 +149,9 @@ hash_key(const HASH *hash, const uchar *record, size_t *length,
my_bool first)
{
if (hash->get_key)
return (*hash->get_key)(record,length,first);
return (char*) (*hash->get_key)(record,length,first);
*length=hash->key_length;
return (uchar*) record+hash->key_offset;
return (char*) record+hash->key_offset;
}
/* Calculate pos according to keys */
@ -313,12 +313,14 @@ my_bool my_hash_insert(HASH *info,const uchar *record)
uchar *ptr_to_rec,*ptr_to_rec2;
HASH_LINK *data,*empty,*gpos,*gpos2,*pos;
LINT_INIT(gpos); LINT_INIT(gpos2);
LINT_INIT(ptr_to_rec); LINT_INIT(ptr_to_rec2);
LINT_INIT(gpos);
LINT_INIT(gpos2);
LINT_INIT(ptr_to_rec);
LINT_INIT(ptr_to_rec2);
if (HASH_UNIQUE & info->flags)
{
char *key= (char*) hash_key(info, record, &idx, 1);
uchar *key= (uchar*) hash_key(info, record, &idx, 1);
if (hash_search(info, key, idx))
return(TRUE); /* Duplicate entry */
}
@ -544,14 +546,16 @@ my_bool hash_update(HASH *hash, uchar *record, uchar *old_key,
if (HASH_UNIQUE & hash->flags)
{
HASH_SEARCH_STATE state;
char *found, *new_key= hash_key(hash, record, &idx, 1);
uchar *found, *new_key= (uchar*) hash_key(hash, record, &idx, 1);
if ((found= hash_first(hash, new_key, idx, &state)))
{
do
{
if (found != (char*) record)
if (found != record)
DBUG_RETURN(1); /* Duplicate entry */
}
while ((found= hash_next(hash, new_key, idx, &state)));
}
}
data=dynamic_element(&hash->array,0,HASH_LINK*);

View file

@ -42,7 +42,7 @@ void get_date(register char * to, int flag, time_t date)
struct tm tm_tmp;
#endif
skr=date ? (time_t) date : time((time_t*) 0);
skr=date ? (time_t) date : my_time(0);
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
if (flag & GETDATE_GMT)
localtime_r(&skr,&tm_tmp);

View file

@ -246,7 +246,7 @@ size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length)
for (;;)
{
char *pos,*end;
uchar *pos, *end;
if (length > max_length)
length=max_length;
for (pos=info->read_pos,end=pos+length ; pos < end ;)
@ -323,7 +323,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
length= (size_t) (fmt - start);
out_length+=length;
if (my_b_write(info, start, length))
if (my_b_write(info, (const uchar*) start, length))
goto err;
if (*fmt == '\0') /* End of format */
@ -378,14 +378,14 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
size_t length2 = strlen(par);
/* TODO: implement minimum width and precision */
out_length+= length2;
if (my_b_write(info, par, length2))
if (my_b_write(info, (uchar*) par, length2))
goto err;
}
else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
{
char *par = va_arg(args, char *);
out_length+= precision;
if (my_b_write(info, par, precision))
if (my_b_write(info, (uchar*) par, precision))
goto err;
}
else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
@ -400,7 +400,7 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
else
length2= (size_t) (int10_to_str((long) (uint) iarg,buff,10)- buff);
out_length+= length2;
if (my_b_write(info, buff, length2))
if (my_b_write(info, (uchar*) buff, length2))
goto err;
}
else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
@ -416,13 +416,13 @@ size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
else
length2= (size_t) (int10_to_str(iarg,buff,10)- buff);
out_length+= length2;
if (my_b_write(info, buff, length2))
if (my_b_write(info, (uchar*) buff, length2))
goto err;
}
else
{
/* %% or unknown code */
if (my_b_write(info, backtrack, fmt-backtrack))
if (my_b_write(info, (uchar*) backtrack, (size_t) (fmt-backtrack)))
goto err;
out_length+= fmt-backtrack;
}

View file

@ -56,7 +56,7 @@ void pack_dirname(char * to, const char *from)
(buff_length == d_length && !bcmp(buff,start,d_length))) &&
*start != FN_LIBCHAR && *start)
{ /* Put current dir before */
bchange(to,d_length,buff,buff_length,strlen(to)+1);
bchange((uchar*) to, d_length, (uchar*) buff, buff_length, strlen(to)+1);
}
}
@ -328,7 +328,7 @@ size_t unpack_dirname(char * to, const char *from)
if (buff+h_length < suffix)
bmove(buff+h_length,suffix,length);
else
bmove_upp(buff+h_length+length,suffix+length,length);
bmove_upp((uchar*) buff+h_length+length, (uchar*) suffix+length, length);
bmove(buff,tilde_expansion,h_length);
}
}

View file

@ -46,7 +46,7 @@ char * my_path(char * to, const char *progname,
if (!test_if_hard_path(to))
{
if (!my_getwd(curr_dir,FN_REFLEN,MYF(0)))
bchange(to,0,curr_dir, (uint) strlen(curr_dir), (uint) strlen(to)+1);
bchange((uchar*) to, 0, (uchar*) curr_dir, strlen(curr_dir), strlen(to)+1);
}
}
else

View file

@ -27,21 +27,22 @@ struct utimbuf {
};
#endif
/* Append a file to another */
/*
Append a file to another
NOTES
Don't set MY_FNABP or MY_NABP bits on when calling this function
*/
int my_append(const char *from, const char *to, myf MyFlags)
/* Dont set MY_FNABP or MY_NABP bits on
when calling this funktion */
{
uint Count;
File from_file,to_file;
char buff[IO_SIZE];
uchar buff[IO_SIZE];
DBUG_ENTER("my_append");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
from_file=to_file= -1;
from_file= to_file= -1;
if ((from_file=my_open(from,O_RDONLY,MyFlags)) >= 0)
{

View file

@ -154,17 +154,20 @@ my_bool my_uncompress(uchar *packet, size_t len, size_t *complen)
SYNOPSIS
packfrm()
data Data reference to frm file data
data Data reference to frm file data.
len Length of frm file data
out:pack_data Reference to the pointer to the packed frm data
out:pack_len Length of packed frm file data
NOTES
data is replaced with compressed content
RETURN VALUES
0 Success
>0 Failure
*/
int packfrm(const uchar *data, size_t len,
int packfrm(uchar *data, size_t len,
uchar **pack_data, size_t *pack_len)
{
int error;
@ -178,8 +181,8 @@ int packfrm(const uchar *data, size_t len,
if (my_compress((uchar*)data, &org_len, &comp_len))
goto err;
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", org_len, comp_len));
DBUG_DUMP("compressed", (char*)data, org_len);
DBUG_PRINT("info", ("org_len: %lu comp_len: %lu", (ulong) org_len, (ulong) comp_len));
DBUG_DUMP("compressed", data, org_len);
error= 2;
blob_len= BLOB_HEADER + org_len;
@ -235,7 +238,7 @@ int unpackfrm(uchar **unpack_data, size_t *unpack_len,
complen= uint4korr(pack_data+8);
DBUG_PRINT("blob",("ver: %lu complen: %lu orglen: %lu",
ver, complen, orglen));
ver, (ulong) complen, (ulong) orglen));
DBUG_DUMP("blob->data", pack_data + BLOB_HEADER, complen);
if (ver != 1)

View file

@ -54,7 +54,7 @@ int my_copy(const char *from, const char *to, myf MyFlags)
my_bool new_file_stat= 0; /* 1 if we could stat "to" */
int create_flag;
File from_file,to_file;
char buff[IO_SIZE];
uchar buff[IO_SIZE];
MY_STAT stat_buff,new_stat_buff;
DBUG_ENTER("my_copy");
DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));
@ -80,10 +80,12 @@ int my_copy(const char *from, const char *to, myf MyFlags)
MyFlags)) < 0)
goto err;
while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0)
while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
{
if (Count == (uint) -1 ||
my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
goto err;
}
if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
DBUG_RETURN(-1); /* Error on close */

View file

@ -19,7 +19,7 @@
#include "mysys_priv.h"
#include <m_string.h>
#ifndef MAIN
#if !defined(__FreeBSD__) || defined(__linux__)
static my_bool memcpy_and_test(uchar *to, uchar *from, uint len)
{
uint i, res=1;

View file

@ -32,6 +32,7 @@ my_bool getopt_compare_strings(const char *s,
static longlong getopt_ll(char *arg, const struct my_option *optp, int *err);
static ulonglong getopt_ull(char *arg, const struct my_option *optp,
int *err);
static double getopt_double(char *arg, const struct my_option *optp, int *err);
static void init_variables(const struct my_option *options);
static int setval(const struct my_option *opts, uchar* *value, char *argument,
my_bool set_maximum_value);
@ -611,6 +612,9 @@ static int setval(const struct my_option *opts, uchar* *value, char *argument,
case GET_ULL:
*((ulonglong*) result_pos)= getopt_ull(argument, opts, &err);
break;
case GET_DOUBLE:
*((double*) result_pos)= getopt_double(argument, opts, &err);
break;
case GET_STR:
*((char**) result_pos)= argument;
break;
@ -720,7 +724,7 @@ my_bool getopt_compare_strings(register const char *s, register const char *t,
be k|K for kilo, m|M for mega or g|G for giga.
*/
static longlong eval_num_suffix (char *argument, int *error, char *option_name)
static longlong eval_num_suffix(char *argument, int *error, char *option_name)
{
char *endchar;
longlong num;
@ -801,6 +805,37 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
}
/*
Get double value withing ranges
Evaluates and returns the value that user gave as an argument to a variable.
RETURN
decimal value of arg
In case of an error, prints an error message and sets *err to
EXIT_ARGUMENT_INVALID. Otherwise err is not touched
*/
static double getopt_double(char *arg, const struct my_option *optp, int *err)
{
double num;
int error;
char *end= arg + 1000; /* Big enough as *arg is \0 terminated */
num= my_strtod(arg, &end, &error);
if (end[0] != 0 || error)
{
fprintf(stderr,
"%s: ERROR: Invalid decimal value for option '%s'\n",
my_progname, optp->name);
*err= EXIT_ARGUMENT_INVALID;
return 0.0;
}
if (optp->max_value && num > (double) optp->max_value)
num= (double) optp->max_value;
return max(num, (double) optp->min_value);
}
/*
Init one value to it's default values
@ -838,6 +873,9 @@ static void init_one_value(const struct my_option *option, uchar* *variable,
case GET_SET:
*((ulonglong*) variable)= (ulonglong) value;
break;
case GET_DOUBLE:
*((double*) variable)= (double) value;
break;
case GET_STR:
/*
Do not clear variable value if it has no default value.
@ -1052,6 +1090,9 @@ void my_print_variables(const struct my_option *options)
longlong2str(*((ulonglong*) value), buff, 10);
printf("%s\n", buff);
break;
case GET_DOUBLE:
printf("%g\n", *(double*) value);
break;
default:
printf("(Disabled)\n");
break;

View file

@ -29,28 +29,17 @@ ulonglong my_getsystime()
clock_gettime(CLOCK_REALTIME, &tp);
return (ulonglong)tp.tv_sec*10000000+(ulonglong)tp.tv_nsec/100;
#elif defined(__WIN__)
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
static __int64 offset=0, freq;
LARGE_INTEGER t_cnt;
if (!offset)
struct timeval tv;
if (query_performance_frequency)
{
/* strictly speaking there should be a mutex to protect
initialization section. But my_getsystime() is called from
UUID() code, and UUID() calls are serialized with a mutex anyway
*/
LARGE_INTEGER li;
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
li.LowPart=ft.dwLowDateTime;
li.HighPart=ft.dwHighDateTime;
offset=li.QuadPart-OFFSET_TO_EPOC;
QueryPerformanceFrequency(&li);
freq=li.QuadPart;
QueryPerformanceCounter(&t_cnt);
offset-=t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq;
return (t_cnt.QuadPart / query_performance_frequency * 10000000+
t_cnt.QuadPart % query_performance_frequency * 10000000/
query_performance_frequency+query_performance_offset);
}
QueryPerformanceCounter(&t_cnt);
return t_cnt.QuadPart/freq*10000000+t_cnt.QuadPart%freq*10000000/freq+offset;
gettimeofday(&tv,NULL);
return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
#elif defined(__NETWARE__)
NXTime_t tm;
NXGetTime(NX_SINCE_1970, NX_NSECONDS, &tm);
@ -62,3 +51,164 @@ ulonglong my_getsystime()
return (ulonglong)tv.tv_sec*10000000+(ulonglong)tv.tv_usec*10;
#endif
}
/*
Return current time
SYNOPSIS
my_time()
flags If MY_WME is set, write error if time call fails
*/
#define DELTA_FOR_SECONDS LL(500000000) /* Half a second */
time_t my_time(myf flags __attribute__((unused)))
{
#ifdef HAVE_GETHRTIME
static hrtime_t prev_gethrtime= 0;
static time_t cur_time= 0;
hrtime_t cur_gethrtime;
pthread_mutex_lock(&THR_LOCK_time);
cur_gethrtime= gethrtime();
if ((prev_gethrtime - cur_gethrtime) > DELTA_FOR_SECONDS)
{
cur_time= time(0);
prev_gethrtime= cur_gethrtime;
}
pthread_mutex_unlock(&THR_LOCK_time);
return cur_time;
#else
time_t t;
/* The following loop is here beacuse time() may fail on some systems */
while ((t= time(0)) == (time_t) -1)
{
if (flags & MY_WME)
fprintf(stderr, "%s: Warning: time() call failed\n", my_progname);
}
return t;
#endif
}
/*
Return time in micro seconds
SYNOPSIS
my_micro_time()
NOTES
This function is to be used to measure performance in micro seconds.
As it's not defined whats the start time for the clock, this function
us only useful to measure time between two moments.
For windows platforms we need the frequency value of the CUP. This is
initalized in my_init.c through QueryPerformanceFrequency().
If Windows platform doesn't support QueryPerformanceFrequency() we will
obtain the time via GetClockCount, which only supports milliseconds.
RETURN
Value in microseconds from some undefined point in time
*/
ulonglong my_micro_time()
{
ulonglong newtime;
#if defined(__WIN__)
if (query_performance_frequency)
{
QueryPerformanceCounter(&newtime);
newtime/= (query_performance_frequency * 1000000);
}
else
newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
#elif defined(HAVE_GETHRTIME)
return gethrtime()/1000;
#else
struct timeval t;
/* The following loop is here because gettimeofday may fail on some systems */
while (gettimeofday(&t, NULL) != 0)
{}
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
#endif /* defined(__WIN__) */
return newtime;
}
/*
Return time in seconds and timer in microseconds
SYNOPSIS
my_micro_time_and_time()
time_arg Will be set to seconds since epoch (00:00:00 UTC, January 1,
1970)
NOTES
This function is to be useful when we need both the time and microtime.
For example in MySQL this is used to get the query time start of a query and
to measure the time of a query (for the slow query log)
IMPLEMENTATION
Same as my_micro_time()
RETURN
Value in microseconds from some undefined point in time
*/
ulonglong my_micro_time_and_time(time_t *time_arg)
{
ulonglong newtime;
#if defined(__WIN__)
if (query_performance_frequency)
{
QueryPerformanceCounter((LARGE_INTEGER *) &newtime);
newtime/= (query_performance_frequency * 1000000);
}
else
newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
(void) time(time_arg);
#else
struct timeval t;
/* The following loop is here because gettimeofday may fail on some systems */
while (gettimeofday(&t, NULL) != 0)
{}
*time_arg= t.tv_sec;
newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
#endif /* defined(__WIN__) */
return newtime;
}
/*
Returns current time
SYNOPSIS
my_time_possible_from_micro()
microtime Value from very recent my_micro_time()
NOTES
This function returns the current time. The microtime argument is only used
if my_micro_time() uses a function that can safely be converted to the current
time.
RETURN
current time
*/
time_t my_time_possible_from_micro(ulonglong microtime __attribute__((unused)))
{
#if defined(__WIN__)
time_t t;
while ((t= time(0)) == (time_t) -1)
{}
return t;
#elif defined(HAVE_GETHRTIME)
return my_time(0); /* Cached time */
#else
return (time_t) (microtime / 1000000);
#endif /* defined(__WIN__) */
}

View file

@ -371,6 +371,28 @@ static void my_win_init(void)
/* chiude la chiave */
RegCloseKey(hSoftMysql) ;
/* The following is used by time functions */
#define OFFSET_TO_EPOC ((__int64) 134774 * 24 * 60 * 60 * 1000 * 1000 * 10)
#define MS 10000000
{
FILETIME ft;
LARGE_INTEGER li, t_cnt;
DBUG_ASSERT(sizeof(LARGE_INTEGER) == sizeof(query_performance_frequency));
if (QueryPerformanceFrequency((LARGE_INTEGER *)&query_performance_frequency))
query_performance_frequency= 0;
else
{
GetSystemTimeAsFileTime(&ft);
li.LowPart= ft.dwLowDateTime;
li.HighPart= ft.dwHighDateTime;
query_performance_offset= li.QuadPart-OFFSET_TO_EPOC;
QueryPerformanceCounter(&t_cnt);
query_performance_offset-= (t_cnt.QuadPart / query_performance_frequency * MS +
t_cnt.QuadPart % query_performance_frequency * MS /
query_performance_frequency);
}
}
DBUG_VOID_RETURN ;
}

View file

@ -93,6 +93,11 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
int (*fatal_error_handler_hook)(uint error,const char *str,myf MyFlags)=
my_message_no_curses;
#ifdef __WIN__
/* from my_getsystime.c */
ulonglong query_performance_frequency, query_performance_offset;
#endif
/* How to disable options */
my_bool NEAR my_disable_locking=0;
my_bool NEAR my_disable_async_io=0;

View file

@ -66,6 +66,8 @@ extern struct st_irem *sf_malloc_root;
extern struct st_my_file_info my_file_info_default[MY_NFILE];
extern ulonglong query_performance_frequency, query_performance_offset;
#if defined(THREAD) && !defined(__WIN__)
extern sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif

View file

@ -30,7 +30,7 @@ pthread_key(struct st_my_thread_var, THR_KEY_mysys);
#endif /* USE_TLS */
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads;
THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time;
pthread_cond_t THR_COND_threads;
uint THR_thread_count= 0;
uint my_thread_end_wait_time= 5;
@ -146,6 +146,7 @@ my_bool my_thread_global_init(void)
pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST);
pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST);
pthread_cond_init(&THR_COND_threads, NULL);
#if defined( __WIN__) || defined(OS2)
win_pthread_init();
@ -202,6 +203,7 @@ void my_thread_global_end(void)
pthread_mutex_destroy(&THR_LOCK_myisam);
pthread_mutex_destroy(&THR_LOCK_heap);
pthread_mutex_destroy(&THR_LOCK_net);
pthread_mutex_destroy(&THR_LOCK_time);
pthread_mutex_destroy(&THR_LOCK_charset);
if (all_threads_killed)
{

View file

@ -28,7 +28,7 @@
#include <my_pthread.h>
extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache;
extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net;
extern pthread_mutex_t THR_LOCK_charset;
extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time;
#else
#include <my_no_pthread.h>
#endif

View file

@ -157,7 +157,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
DBUG_ENTER("thr_alarm");
DBUG_PRINT("enter",("thread: %s sec: %d",my_thread_name(),sec));
now=(ulong) time((time_t*) 0);
now=(ulong) my_time(0);
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
if (alarm_aborted > 0)
@ -351,7 +351,7 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
}
else
{
ulong now=(ulong) time((time_t*) 0);
ulong now=(ulong) my_time(0);
ulong next=now+10-(now%10);
while ((alarm_data=(ALARM*) queue_top(&alarm_queue))->expire_time <= now)
{
@ -480,7 +480,7 @@ void thr_alarm_info(ALARM_INFO *info)
info->max_used_alarms= max_used_alarms;
if ((info->active_alarms= alarm_queue.elements))
{
ulong now=(ulong) time((time_t*) 0);
ulong now=(ulong) my_time(0);
long time_diff;
ALARM *alarm_data= (ALARM*) queue_top(&alarm_queue);
time_diff= (long) (alarm_data->expire_time - now);
@ -528,7 +528,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
{
if (alarm_queue.elements)
{
ulong sleep_time,now=time((time_t*) 0);
ulong sleep_time,now= my_time(0);
if (alarm_aborted)
sleep_time=now+1;
else
@ -685,7 +685,7 @@ static void *test_thread(void *arg)
for (i=1 ; i <= 10 ; i++)
{
wait_time=param ? 11-i : i;
start_time=time((time_t*) 0);
start_time= my_time(0);
if (thr_alarm(&got_alarm,wait_time,0))
{
printf("Thread: %s Alarms aborted\n",my_thread_name());
@ -747,7 +747,7 @@ static void *test_thread(void *arg)
}
}
printf("Thread: %s Slept for %d (%d) sec\n",my_thread_name(),
(int) (time((time_t*) 0)-start_time), wait_time); fflush(stdout);
(int) (my_time(0)-start_time), wait_time); fflush(stdout);
thr_end_alarm(&got_alarm);
fflush(stdout);
}

View file

@ -232,7 +232,7 @@ static int wait_for_data(my_socket fd, uint timeout)
implementations of select that don't adjust tv upon
failure to reflect the time remaining
*/
start_time = time(NULL);
start_time= my_time(0);
for (;;)
{
tv.tv_sec = (long) timeout;
@ -246,7 +246,7 @@ static int wait_for_data(my_socket fd, uint timeout)
#endif
if (res == 0) /* timeout */
return -1;
now_time=time(NULL);
now_time= my_time(0);
timeout-= (uint) (now_time - start_time);
if (errno != EINTR || (int) timeout <= 0)
return -1;

View file

@ -1644,7 +1644,7 @@ err:
void
Event_queue_element::mark_last_executed(THD *thd)
{
thd->end_time();
thd->set_current_time();
last_executed= (my_time_t) thd->query_start();
last_executed_changed= TRUE;

View file

@ -550,7 +550,7 @@ Event_queue::get_top_for_execution_if_time(THD *thd,
top= ((Event_queue_element*) queue_element(&queue, 0));
thd->end_time(); /* Get current time */
thd->set_current_time(); /* Get current time */
next_activation_at= top->execute_at;
if (next_activation_at > thd->query_start())

View file

@ -283,8 +283,7 @@ Event_worker_thread::run(THD *thd, Event_queue_element_for_exec *event)
res= post_init_event_thread(thd);
DBUG_ENTER("Event_worker_thread::run");
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx",
(long) time(NULL), (long) thd));
DBUG_PRINT("info", ("Time is %ld, THD: 0x%lx", (long) my_time(0), (long) thd));
if (res)
goto end;

View file

@ -1394,6 +1394,8 @@ public:
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
uint32 max_display_length();
uint is_equal(Create_field *new_field);
inline bool in_read_set() { return bitmap_is_set(table->read_set, field_index); }
inline bool in_write_set() { return bitmap_is_set(table->write_set, field_index); }
};

View file

@ -1712,8 +1712,11 @@ public:
max_length=length;
fixed= 1;
}
Item_float(double value_par) :presentation(0), value(value_par) { fixed= 1; }
Item_float(double value_par, uint decimal_par) :presentation(0), value(value_par)
{
decimals= (uint8) decimal_par;
fixed= 1;
}
int save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }

View file

@ -853,6 +853,7 @@ public:
friend int cmp_longlong(void *cmp_arg, packed_longlong *a,packed_longlong *b);
};
class in_double :public in_vector
{
double tmp;
@ -862,16 +863,16 @@ public:
uchar *get_value(Item *item);
Item *create_item()
{
return new Item_float(0.0);
return new Item_float(0.0, 0);
}
void value_to_item(uint pos, Item *item)
{
((Item_float*)item)->value= ((double*) base)[pos];
}
Item_result result_type() { return REAL_RESULT; }
};
class in_decimal :public in_vector
{
my_decimal val;

View file

@ -1594,7 +1594,7 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions)
void Item_func_sysdate_local::store_now_in_TIME(MYSQL_TIME *now_time)
{
THD *thd= current_thd;
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) time(NULL));
thd->variables.time_zone->gmt_sec_to_TIME(now_time, (my_time_t) my_time(0));
thd->time_zone_used= 1;
}

View file

@ -2767,7 +2767,7 @@ String *Item_xml_str_func::parse_xml(String *raw_xml, String *parsed_xml_buf)
if ((rc= my_xml_parse(&p, raw_xml->ptr(), raw_xml->length())) != MY_XML_OK)
{
char buf[128];
my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %lu: %s",
my_snprintf(buf, sizeof(buf)-1, "parse error at line %d pos %u: %s",
my_xml_error_lineno(&p) + 1,
my_xml_error_pos(&p) + 1,
my_xml_error_string(&p));

View file

@ -246,7 +246,7 @@ retry:
}
}
thd->lock_time();
thd->set_time_after_lock();
DBUG_RETURN (sql_lock);
}

View file

@ -524,8 +524,8 @@ err:
user_host the pointer to the string with user@host info
user_host_len length of the user_host string. this is computed once
and passed to all general log event handlers
query_time Amount of time the query took to execute (in seconds)
lock_time Amount of time the query was locked (in seconds)
query_time Amount of time the query took to execute (in microseconds)
lock_time Amount of time the query was locked (in microseconds)
is_command The flag, which determines, whether the sql_text is a
query or an administrator command (these are treated
differently by the old logging routines)
@ -545,13 +545,12 @@ err:
bool Log_to_csv_event_handler::
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
const char *user_host, uint user_host_len,
longlong query_time, longlong lock_time, bool is_command,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
{
/* table variables */
TABLE *table= slow_log.table;
CHARSET_INFO *client_cs= thd->variables.character_set_client;
DBUG_ENTER("log_slow");
/* below should never happen */
@ -582,6 +581,8 @@ bool Log_to_csv_event_handler::
if (query_start_arg)
{
longlong query_time= (longlong) (query_utime/1000000);
longlong lock_time= (longlong) (lock_utime/1000000);
/*
A TIME field can not hold the full longlong range; query_time or
lock_time may be truncated without warning here, if greater than
@ -694,12 +695,12 @@ void Log_to_file_event_handler::init_pthread_objects()
bool Log_to_file_event_handler::
log_slow(THD *thd, time_t current_time, time_t query_start_arg,
const char *user_host, uint user_host_len,
longlong query_time, longlong lock_time, bool is_command,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
{
return mysql_slow_log.write(thd, current_time, query_start_arg,
user_host, user_host_len,
query_time, lock_time, is_command,
query_utime, lock_utime, is_command,
sql_text, sql_text_len);
}
@ -774,10 +775,10 @@ bool LOGGER::error_log_print(enum loglevel level, const char *format,
va_list args)
{
bool error= FALSE;
Log_event_handler **current_handler= error_log_handler_list;
Log_event_handler **current_handler;
/* currently we don't need locking here as there is no error_log table */
while (*current_handler)
for (current_handler= error_log_handler_list ; *current_handler ;)
error= (*current_handler++)->log_error(level, format, args) || error;
return error;
@ -904,28 +905,27 @@ bool LOGGER::flush_logs(THD *thd)
SYNOPSIS
slow_log_print()
thd THD of the query being logged
query The query being logged
query_length The length of the query string
query_start_arg Query start timestamp
thd THD of the query being logged
query The query being logged
query_length The length of the query string
current_utime Current time in microseconds (from undefined start)
RETURN
FALSE - OK
TRUE - error occured
FALSE OK
TRUE error occured
*/
bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
time_t query_start_arg)
ulonglong current_utime)
{
bool error= FALSE;
Log_event_handler **current_handler= slow_log_handler_list;
Log_event_handler **current_handler;
bool is_command= FALSE;
char user_host_buff[MAX_USER_HOST_SIZE];
time_t current_time;
Security_context *sctx= thd->security_ctx;
uint user_host_len= 0;
longlong query_time= 0, lock_time= 0;
ulonglong query_utime, lock_utime;
/*
Print the message to the buffer if we have slow log enabled
@ -933,10 +933,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
if (*slow_log_handler_list)
{
current_time= time(NULL);
time_t current_time;
/* do not log slow queries from replication threads */
if (thd->slave_thread)
if (thd->slave_thread && !opt_log_slow_slave_statements)
return 0;
lock();
@ -947,17 +947,22 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
}
/* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff;
user_host_len= (strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
sctx->host ? sctx->host : "", " [",
sctx->ip ? sctx->ip : "", "]", NullS) -
user_host_buff);
if (query_start_arg)
current_time= my_time_possible_from_micro(current_utime);
if (thd->start_utime)
{
query_time= (longlong) (current_time - query_start_arg);
lock_time= (longlong) (thd->time_after_lock - query_start_arg);
query_utime= (current_utime - thd->start_utime);
lock_utime= (thd->utime_after_lock - thd->start_utime);
}
else
{
query_utime= lock_utime= 0;
}
if (!query)
@ -967,10 +972,10 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
query_length= command_name[thd->command].length;
}
while (*current_handler)
error= (*current_handler++)->log_slow(thd, current_time, query_start_arg,
for (current_handler= slow_log_handler_list; *current_handler ;)
error= (*current_handler++)->log_slow(thd, current_time, thd->start_time,
user_host_buff, user_host_len,
query_time, lock_time, is_command,
query_utime, lock_utime, is_command,
query, query_length) || error;
unlock();
@ -995,7 +1000,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
Security_context *sctx= thd->security_ctx;
ulong id;
uint message_buff_len= 0, user_host_len= 0;
time_t current_time;
if (thd)
{ /* Normal thread */
if ((thd->options & OPTION_LOG_OFF)
@ -1017,8 +1022,6 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
unlock();
return 0;
}
time_t current_time= time(NULL);
user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
sctx->priv_user ? sctx->priv_user : "", "[",
sctx->user ? sctx->user : "", "] @ ",
@ -1033,6 +1036,7 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
else
message_buff[0]= '\0';
current_time= my_time(0);
while (*current_handler)
error+= (*current_handler++)->
log_general(current_time, user_host_buff,
@ -2165,8 +2169,8 @@ err:
user_host the pointer to the string with user@host info
user_host_len length of the user_host string. this is computed once
and passed to all general log event handlers
query_time Amount of time the query took to execute (in seconds)
lock_time Amount of time the query was locked (in seconds)
query_utime Amount of time the query took to execute (in microseconds)
lock_utime Amount of time the query was locked (in microseconds)
is_command The flag, which determines, whether the sql_text is a
query or an administrator command.
sql_text the very text of the query or administrator command
@ -2184,8 +2188,8 @@ err:
bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
time_t query_start_arg, const char *user_host,
uint user_host_len, longlong query_time,
longlong lock_time, bool is_command,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)
{
bool error= 0;
@ -2198,6 +2202,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
{ // Safety agains reopen
int tmp_errno= 0;
char buff[80], *end;
char query_time_buff[22+7], lock_time_buff[22+7];
uint buff_len;
end= buff;
@ -2228,10 +2233,12 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time,
tmp_errno= errno;
}
/* For slow query log */
sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0);
sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0);
if (my_b_printf(&log_file,
"# Query_time: %lu Lock_time: %lu"
"# Query_time: %s Lock_time: %s"
" Rows_sent: %lu Rows_examined: %lu\n",
(ulong) query_time, (ulong) lock_time,
query_time_buff, lock_time_buff,
(ulong) thd->sent_row_count,
(ulong) thd->examined_row_count) == (uint) -1)
tmp_errno= errno;
@ -3872,9 +3879,9 @@ int error_log_print(enum loglevel level, const char *format,
bool slow_log_print(THD *thd, const char *query, uint query_length,
time_t query_start_arg)
ulonglong current_utime)
{
return logger.slow_log_print(thd, query, query_length, query_start_arg);
return logger.slow_log_print(thd, query, query_length, current_utime);
}
@ -3902,7 +3909,7 @@ void MYSQL_BIN_LOG::rotate_and_purge(uint flags)
#ifdef HAVE_REPLICATION
if (expire_logs_days)
{
time_t purge_time= time(0) - expire_logs_days*24*60*60;
time_t purge_time= my_time(0) - expire_logs_days*24*60*60;
if (purge_time >= 0)
purge_logs_before_date(purge_time);
}
@ -4499,7 +4506,7 @@ static void print_buffer_to_file(enum loglevel level, const char *buffer)
VOID(pthread_mutex_lock(&LOCK_error_log));
skr=time(NULL);
skr= my_time(0);
localtime_r(&skr, &tm_tmp);
start=&tm_tmp;

View file

@ -198,7 +198,7 @@ public:
const char *sql_text, uint sql_text_len);
bool write(THD *thd, time_t current_time, time_t query_start_arg,
const char *user_host, uint user_host_len,
longlong query_time, longlong lock_time, bool is_command,
ulonglong query_utime, ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
bool open_slow_log(const char *log_name)
{
@ -393,8 +393,8 @@ public:
virtual bool log_slow(THD *thd, time_t current_time,
time_t query_start_arg, const char *user_host,
uint user_host_len, longlong query_time,
longlong lock_time, bool is_command,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len)= 0;
virtual bool log_error(enum loglevel level, const char *format,
va_list args)= 0;
@ -442,8 +442,8 @@ public:
virtual bool log_slow(THD *thd, time_t current_time,
time_t query_start_arg, const char *user_host,
uint user_host_len, longlong query_time,
longlong lock_time, bool is_command,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
@ -479,8 +479,8 @@ public:
virtual bool log_slow(THD *thd, time_t current_time,
time_t query_start_arg, const char *user_host,
uint user_host_len, longlong query_time,
longlong lock_time, bool is_command,
uint user_host_len, ulonglong query_utime,
ulonglong lock_utime, bool is_command,
const char *sql_text, uint sql_text_len);
virtual bool log_error(enum loglevel level, const char *format,
va_list args);
@ -564,7 +564,7 @@ public:
bool error_log_print(enum loglevel level, const char *format,
va_list args);
bool slow_log_print(THD *thd, const char *query, uint query_length,
time_t query_start_arg);
ulonglong current_utime);
bool general_log_print(THD *thd,enum enum_server_command command,
const char *format, va_list args);

View file

@ -456,7 +456,7 @@ Log_event::Log_event()
thd(0)
{
server_id= ::server_id;
when= time(NULL);
when= my_time(0);
log_pos= 0;
}
#endif /* !MYSQL_CLIENT */
@ -2073,7 +2073,7 @@ int Query_log_event::do_apply_event(RELAY_LOG_INFO const *rli,
/* Execute the query (note that we bypass dispatch_command()) */
const char* found_semicolon= NULL;
mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
log_slow_statement(thd);
}
else
{
@ -4349,7 +4349,7 @@ int User_var_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
switch (type) {
case REAL_RESULT:
float8get(real_val, val);
it= new Item_float(real_val);
it= new Item_float(real_val, 0);
val= (char*) &real_val; // Pointer to value in native format
val_len= 8;
break;
@ -6173,7 +6173,7 @@ int Rows_log_event::do_apply_event(RELAY_LOG_INFO const *rli)
problem. When WL#2975 is implemented, just remove the member
st_relay_log_info::last_event_start_time and all its occurences.
*/
const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= time(0);
const_cast<RELAY_LOG_INFO*>(rli)->last_event_start_time= my_time(0);
}
DBUG_RETURN(0);

View file

@ -167,6 +167,7 @@ public:
void restore_env(THD *thd, Object_creation_ctx *backup_ctx);
protected:
Object_creation_ctx() {}
virtual Object_creation_ctx *create_backup_ctx(THD *thd) = 0;
virtual void change_env(THD *thd) const = 0;
@ -734,7 +735,7 @@ int error_log_print(enum loglevel level, const char *format,
va_list args);
bool slow_log_print(THD *thd, const char *query, uint query_length,
time_t query_start_arg);
ulonglong current_utime);
bool general_log_print(THD *thd, enum enum_server_command command,
const char *format,...);
@ -1791,7 +1792,7 @@ 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 char* opt_secure_file_priv;
extern my_bool opt_log_slow_admin_statements;
extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
extern my_bool sp_automatic_privileges, opt_noacl;
extern my_bool opt_old_style_user_limits, trust_function_creators;
extern uint opt_crash_binlog_innodb;

View file

@ -338,6 +338,7 @@ static char *default_collation_name;
static char *default_storage_engine_str;
static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
static I_List<THD> thread_cache;
static double long_query_time;
static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
@ -406,6 +407,7 @@ my_bool opt_sync_frm, opt_allow_suspicious_udfs;
my_bool opt_secure_auth= 0;
char* opt_secure_file_priv= 0;
my_bool opt_log_slow_admin_statements= 0;
my_bool opt_log_slow_slave_statements= 0;
my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0;
my_bool opt_myisam_use_mmap= 0;
@ -1143,7 +1145,7 @@ extern "C" void unireg_abort(int exit_code)
sql_print_error("Aborting\n");
else if (opt_help)
usage();
clean_up(exit_code || !opt_bootstrap); /* purecov: inspected */
clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
wait_for_signal_thread_to_end();
clean_up_mutexes();
@ -1240,12 +1242,12 @@ void clean_up(bool print_message)
my_regex_end();
#endif
if (print_message && errmesg)
sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
#if !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap)
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
#endif
if (print_message && errmesg && server_start_time)
sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
thread_scheduler.end();
finish_client_errs();
my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
@ -1797,7 +1799,7 @@ static bool cache_thread()
this thread for handling of new THD object/connection.
*/
thd->mysys_var->abort= 0;
thd->thr_create_time= time(NULL);
thd->thr_create_utime= my_micro_time();
threads.append(thd);
return(1);
}
@ -2174,7 +2176,7 @@ extern "C" sig_handler handle_segfault(int sig)
segfaulted = 1;
curr_time= time(NULL);
curr_time= my_time(0);
localtime_r(&curr_time, &tm);
fprintf(stderr,"\
@ -2717,7 +2719,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
tzset(); // Set tzname
max_system_variables.pseudo_thread_id= (ulong)~0;
server_start_time= time((time_t*) 0);
server_start_time= my_time(0);
rpl_filter= new Rpl_filter;
binlog_filter= new Rpl_filter;
if (!rpl_filter || !binlog_filter)
@ -2952,7 +2954,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
&& !(log_output_options & LOG_NONE))
sql_print_warning("Although a path was specified for the "
"--log-slow-queries option, log tables are used. "
"To enable logging to files use the --log-output option.");
"To enable logging to files use the --log-output=file option.");
s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
sys_var_general_log_path.value= my_strdup(s, MYF(0));
@ -3540,7 +3542,7 @@ server.");
#ifdef HAVE_REPLICATION
if (opt_bin_log && expire_logs_days)
{
time_t purge_time= time(0) - expire_logs_days*24*60*60;
time_t purge_time= server_start_time - expire_logs_days*24*60*60;
if (purge_time >= 0)
mysql_bin_log.purge_logs_before_date(purge_time);
}
@ -4289,7 +4291,7 @@ void create_thread_to_handle_connection(THD *thd)
thread_created++;
threads.append(thd);
DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
thd->connect_time = time(NULL);
thd->connect_utime= thd->start_utime= my_micro_time();
if ((error=pthread_create(&thd->real_id,&connection_attrib,
handle_one_connection,
(void*) thd)))
@ -5076,6 +5078,8 @@ enum options_mysqld
OPT_THREAD_HANDLING,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS,
OPT_OLD_MODE
};
@ -5377,8 +5381,13 @@ Disable with --skip-large-pages.",
(uchar**) &opt_log_slow_admin_statements,
(uchar**) &opt_log_slow_admin_statements,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
"Log slow statements executed by slave thread to the slow log if it is open.",
(uchar**) &opt_log_slow_slave_statements,
(uchar**) &opt_log_slow_slave_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. Must be enabled to activate other slow log options.",
"Log slow queries to a table or log file. Defaults logging to table mysql.slow_log or hostname-slow.log if --log-output=file is used. Must be enabled to activate other slow log options.",
(uchar**) &opt_slow_logname, (uchar**) &opt_slow_logname, 0, GET_STR, OPT_ARG,
0, 0, 0, 0, 0, 0},
{"log-tc", OPT_LOG_TC,
@ -5967,10 +5976,10 @@ log and this option does nothing anymore.",
0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
1, 100, 0, 1, 0},
{"long_query_time", OPT_LONG_QUERY_TIME,
"Log all queries that have taken more than long_query_time seconds to execute to file.",
(uchar**) &global_system_variables.long_query_time,
(uchar**) &max_system_variables.long_query_time, 0, GET_ULONG,
REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
"Log all queries that have taken more than long_query_time seconds to execute to file. "
"The argument will be treated as a decimal value with microsecond precission.",
(uchar**) &long_query_time, (uchar**) &long_query_time, 0, GET_DOUBLE,
REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
{"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
"If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system",
(uchar**) &lower_case_table_names,
@ -6068,6 +6077,11 @@ The minimum value for this variable is 4096.",
"After this many write locks, allow some read locks to run in between.",
(uchar**) &max_write_lock_count, (uchar**) &max_write_lock_count, 0, GET_ULONG,
REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0},
{"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
"Don't log queries which examine less than min_examined_row_limit rows to file.",
(uchar**) &global_system_variables.min_examined_row_limit,
(uchar**) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0},
{"multi_range_count", OPT_MULTI_RANGE_COUNT,
"Number of key ranges to request at once.",
(uchar**) &global_system_variables.multi_range_count,
@ -6959,7 +6973,7 @@ Starts the MySQL database server\n");
printf("Usage: %s [OPTIONS]\n", my_progname);
if (!opt_verbose)
puts("\nFor more help options (several pages), use mysqld --verbose --help\n");
puts("\nFor more help options (several pages), use mysqld --verbose --help");
else
{
#ifdef __WIN__
@ -6984,7 +6998,7 @@ Starts the MySQL database server\n");
puts("\n\
To see what values a running MySQL server is using, type\n\
'mysqladmin variables' instead of 'mysqld --verbose --help'.\n");
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
}
}
#endif /*!EMBEDDED_LIBRARY*/
@ -7714,7 +7728,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
}
return 0;
}
/* Initiates DEBUG - but no debugging here ! */
/* Handle arguments for multiple key caches */
static uchar* *
mysql_getopt_value(const char *keyname, uint key_length,
@ -7772,9 +7788,10 @@ static void get_options(int *argc,char **argv)
(*argc)++; /* add back one for the progname handle_options removes */
/* no need to do this for argv as we are discarding it. */
if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) &&
if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
opt_log_slow_slave_statements) &&
!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");
sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log-slow-queries is not set");
#if defined(HAVE_BROKEN_REALPATH)
my_use_symdir=0;
@ -7818,6 +7835,10 @@ static void get_options(int *argc,char **argv)
/* Set global variables based on startup options */
myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
/* long_query_time is in microseconds */
global_system_variables.long_query_time= max_system_variables.long_query_time=
(longlong) (long_query_time * 1000000.0);
if (opt_short_log_format)
opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;

View file

@ -437,7 +437,7 @@ net_write_command(NET *net,uchar command,
uchar buff[NET_HEADER_SIZE+1];
uint header_size=NET_HEADER_SIZE+1;
DBUG_ENTER("net_write_command");
DBUG_PRINT("enter",("length: %lu", len));
DBUG_PRINT("enter",("length: %lu", (ulong) len));
buff[4]=command; /* For first packet */

View file

@ -135,7 +135,7 @@ write_parameter(IO_CACHE *file, uchar* base, File_option *parameter,
{
/* string have to be allocated already */
LEX_STRING *val_s= (LEX_STRING *)(base + parameter->offset);
time_t tm= time(NULL);
time_t tm= my_time(0);
get_date(val_s->str, GETDATE_DATE_TIME|GETDATE_GMT|GETDATE_FIXEDLENGTH,
tm);

View file

@ -250,8 +250,8 @@ static sys_var_bool_ptr
sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes",
&opt_log_queries_not_using_indexes);
static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
static sys_var_thd_ulong sys_long_query_time(&vars, "long_query_time",
&SV::long_query_time);
static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time",
&SV::long_query_time);
static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates",
&SV::low_priority_updates,
fix_low_priority_updates);
@ -315,6 +315,8 @@ static sys_var_thd_ulong sys_max_tmp_tables(&vars, "max_tmp_tables",
&SV::max_tmp_tables);
static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
&max_write_lock_count);
static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit",
&SV::min_examined_row_limit);
static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count",
&SV::multi_range_count);
static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
@ -1473,6 +1475,15 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
pthread_mutex_unlock(&LOCK_global_system_variables);
return new Item_int(value);
}
case SHOW_DOUBLE:
{
double value;
pthread_mutex_lock(&LOCK_global_system_variables);
value= *(double*) value_ptr(thd, var_type, base);
pthread_mutex_unlock(&LOCK_global_system_variables);
/* 6, as this is for now only used with microseconds */
return new Item_float(value, 6);
}
case SHOW_HA_ROWS:
{
ha_rows value;
@ -2532,6 +2543,60 @@ void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
thd->variables.lc_time_names= global_system_variables.lc_time_names;
}
/*
Handling of microseoncds given as seconds.part_seconds
NOTES
The argument to long query time is in seconds in decimal
which is converted to ulonglong integer holding microseconds for storage.
This is used for handling long_query_time
*/
bool sys_var_microseconds::update(THD *thd, set_var *var)
{
double num= var->value->val_real();
longlong microseconds;
if (num > (double) option_limits->max_value)
num= (double) option_limits->max_value;
if (num < (double) option_limits->min_value)
num= (double) option_limits->min_value;
microseconds= (longlong) (num * 1000000.0 + 0.5);
if (var->type == OPT_GLOBAL)
{
pthread_mutex_lock(&LOCK_global_system_variables);
(global_system_variables.*offset)= microseconds;
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
thd->variables.*offset= microseconds;
return 0;
}
void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
{
longlong microseconds= (longlong) (option_limits->def_value * 1000000.0);
if (type == OPT_GLOBAL)
{
pthread_mutex_lock(&LOCK_global_system_variables);
global_system_variables.*offset= microseconds;
pthread_mutex_unlock(&LOCK_global_system_variables);
}
else
thd->variables.*offset= microseconds;
}
uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
LEX_STRING *base)
{
thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
global_system_variables.*offset :
thd->variables.*offset) / 1000000.0;
return (uchar*) &thd->tmp_double_value;
}
/*
Functions to update thd->options bits
*/

View file

@ -113,9 +113,10 @@ class sys_var_long_ptr_global: public sys_var_global
{
public:
ulong *value;
sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
pthread_mutex_t *guard_arg,
sys_after_update_func after_update_arg= NULL)
sys_var_long_ptr_global(sys_var_chain *chain, const char *name_arg,
ulong *value_ptr_arg,
pthread_mutex_t *guard_arg,
sys_after_update_func after_update_arg= NULL)
:sys_var_global(name_arg, after_update_arg, guard_arg),
value(value_ptr_arg)
{ chain_sys_var(chain); }
@ -911,6 +912,27 @@ public:
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
class sys_var_microseconds :public sys_var_thd
{
ulonglong SV::*offset;
public:
sys_var_microseconds(sys_var_chain *chain, const char *name_arg,
ulonglong SV::*offset_arg):
sys_var_thd(name_arg), offset(offset_arg)
{ chain_sys_var(chain); }
bool check(THD *thd, set_var *var) {return 0;}
bool update(THD *thd, set_var *var);
void set_default(THD *thd, enum_var_type type);
SHOW_TYPE show_type() { return SHOW_DOUBLE; }
bool check_update_type(Item_result type)
{
return (type != INT_RESULT && type != REAL_RESULT && type != DECIMAL_RESULT);
}
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
class sys_var_trust_routine_creators :public sys_var_bool_ptr
{
/* We need a derived class only to have a warn_deprecated() */

View file

@ -1460,6 +1460,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet
+ MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
thd->slave_thread = 1;
thd->enable_slow_log= opt_log_slow_slave_statements;
set_slave_thread_options(thd);
thd->client_capabilities = CLIENT_LOCAL_FILES;
pthread_mutex_lock(&LOCK_thread_count);
@ -1491,7 +1492,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
DBUG_ENTER("safe_sleep");
thr_alarm_init(&alarmed);
time_t start_time= time((time_t*) 0);
time_t start_time= my_time(0);
time_t end_time= start_time+sec;
while ((nap_time= (int) (end_time - start_time)) > 0)
@ -1508,7 +1509,7 @@ static int safe_sleep(THD* thd, int sec, CHECK_KILLED_FUNC thread_killed,
if ((*thread_killed)(thd,thread_killed_arg))
DBUG_RETURN(1);
start_time=time((time_t*) 0);
start_time= my_time(0);
}
DBUG_RETURN(0);
}
@ -1796,7 +1797,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
thd->set_time(); // time the query
thd->lex->current_select= 0;
if (!ev->when)
ev->when = time(NULL);
ev->when= my_time(0);
ev->thd = thd; // because up to this point, ev->thd == 0
int reason= ev->shall_skip(rli);

View file

@ -142,6 +142,7 @@ struct Query_cache_query
uint8 tbls_type;
unsigned int last_pkt_nr;
Query_cache_query() {} /* Remove gcc warning */
inline void init_n_lock();
void unlock_n_destroy();
inline ulonglong found_rows() { return limit_found_rows; }

View file

@ -407,7 +407,8 @@ THD::THD()
// Must be reset to handle error with THD's created for init of mysqld
lex->current_select= 0;
start_time=(time_t) 0;
time_after_lock=(time_t) 0;
start_utime= 0L;
utime_after_lock= 0L;
current_linfo = 0;
slave_thread = 0;
bzero(&variables, sizeof(variables));

View file

@ -249,18 +249,19 @@ struct system_variables
ulonglong myisam_max_sort_file_size;
ulonglong max_heap_table_size;
ulonglong tmp_table_size;
ulonglong long_query_time;
ha_rows select_limit;
ha_rows max_join_size;
ulong auto_increment_increment, auto_increment_offset;
ulong bulk_insert_buff_size;
ulong join_buff_size;
ulong long_query_time;
ulong max_allowed_packet;
ulong max_error_count;
ulong max_length_for_sort_data;
ulong max_sort_length;
ulong max_tmp_tables;
ulong max_insert_delayed_threads;
ulong min_examined_row_limit;
ulong multi_range_count;
ulong myisam_repair_threads;
ulong myisam_sort_buff_size;
@ -1025,8 +1026,6 @@ public:
Security_context main_security_ctx;
Security_context *security_ctx;
/* remote (peer) port */
uint16 peer_port;
/*
Points to info-string that we show in SHOW PROCESSLIST
You are supposed to update thd->proc_info only if you have coded
@ -1034,6 +1033,14 @@ public:
*/
const char *proc_info;
/*
Used in error messages to tell user in what part of MySQL we found an
error. E. g. when where= "having clause", if fix_fields() fails, user
will know that the error was in having clause.
*/
const char *where;
double tmp_double_value; /* Used in set_var.cc */
ulong client_capabilities; /* What the client supports */
ulong max_client_packet_length;
@ -1055,14 +1062,12 @@ public:
enum enum_server_command command;
uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
/*
Used in error messages to tell user in what part of MySQL we found an
error. E. g. when where= "having clause", if fix_fields() fails, user
will know that the error was in having clause.
*/
const char *where;
time_t start_time,time_after_lock,user_time;
time_t connect_time,thr_create_time; // track down slow pthread_create
/* remote (peer) port */
uint16 peer_port;
time_t start_time, user_time;
ulonglong connect_utime, thr_create_utime; // track down slow pthread_create
ulonglong start_utime, utime_after_lock;
thr_lock_type update_lock_default;
Delayed_insert *di;
@ -1570,27 +1575,25 @@ public:
proc_info = old_msg;
pthread_mutex_unlock(&mysys_var->mutex);
}
static inline void safe_time(time_t *t)
{
/**
Wrapper around time() which retries on error (-1)
@details
This is needed because, despite the documentation, time() may fail
in some circumstances. Here we retry time() until it succeeds, and
log the failure so that performance problems related to this can be
identified.
*/
while(unlikely(time(t) == ((time_t) -1)))
sql_print_information("time() failed with %d", errno);
}
inline time_t query_start() { query_start_used=1; return start_time; }
inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }}
inline void end_time() { safe_time(&start_time); }
inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; }
inline void lock_time() { safe_time(&time_after_lock); }
inline void set_time()
{
if (user_time)
{
start_time= user_time;
start_utime= utime_after_lock= my_micro_time();
}
else
start_utime= utime_after_lock= my_micro_time_and_time(&start_time);
}
inline void set_current_time() { start_time= my_time(MY_WME); }
inline void set_time(time_t t)
{
start_time= user_time= t;
start_utime= utime_after_lock= my_micro_time();
}
void set_time_after_lock() { utime_after_lock= my_micro_time(); }
ulonglong current_utime() { return my_micro_time(); }
inline ulonglong found_rows(void)
{
return limit_found_rows;

View file

@ -97,7 +97,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
uc->len= temp_len;
uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
uc->user_resources= *mqh;
uc->intime= thd->thr_create_time;
uc->reset_utime= thd->thr_create_utime;
if (my_hash_insert(&hash_user_connections, (uchar*) uc))
{
my_free((char*) uc,0);
@ -223,16 +223,16 @@ void decrease_user_connections(USER_CONN *uc)
void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
{
time_t check_time = thd->start_time ? thd->start_time : time(NULL);
ulonglong check_time= thd->start_utime;
DBUG_ENTER("time_out_user_resource_limits");
/* If more than a hour since last check, reset resource checking */
if (check_time - uc->intime >= 3600)
if (check_time - uc->reset_utime >= LL(3600000000))
{
uc->questions=1;
uc->updates=0;
uc->conn_per_hour=0;
uc->intime=check_time;
uc->reset_utime= check_time;
}
DBUG_VOID_RETURN;
@ -1053,8 +1053,8 @@ void prepare_new_connection_state(THD* thd)
pthread_handler_t handle_one_connection(void *arg)
{
THD *thd= (THD*) arg;
uint launch_time =
(uint) ((thd->thr_create_time = time(NULL)) - thd->connect_time);
ulong launch_time= (ulong) ((thd->thr_create_utime= my_micro_time()) -
thd->connect_utime);
if (thread_scheduler.init_new_connection_thread())
{
@ -1063,7 +1063,7 @@ pthread_handler_t handle_one_connection(void *arg)
thread_scheduler.end_thread(thd,0);
return 0;
}
if (launch_time >= slow_launch_time)
if (launch_time >= slow_launch_time*1000000L)
statistic_increment(slow_launch_threads,&LOCK_status);
/*

View file

@ -2196,7 +2196,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
/* Add thread to THD list so that's it's visible in 'show processlist' */
pthread_mutex_lock(&LOCK_thread_count);
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
thd->end_time();
thd->set_current_time();
threads.append(thd);
thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
pthread_mutex_unlock(&LOCK_thread_count);

View file

@ -1297,7 +1297,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
void log_slow_statement(THD *thd)
{
time_t start_of_query;
DBUG_ENTER("log_slow_statement");
/*
@ -1308,25 +1307,24 @@ void log_slow_statement(THD *thd)
if (unlikely(thd->in_sub_stmt))
DBUG_VOID_RETURN; // Don't set time for sub stmt
start_of_query= thd->start_time;
thd->end_time(); // Set start time
/*
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";
ulonglong end_utime_of_query= thd->current_utime();
if ((ulong) (thd->start_time - thd->time_after_lock) >
thd->variables.long_query_time ||
((thd->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
opt_log_queries_not_using_indexes))
thd->proc_info="logging slow query";
if (((end_utime_of_query - thd->utime_after_lock) >
thd->variables.long_query_time ||
((thd->server_status &
(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
opt_log_queries_not_using_indexes)) &&
thd->examined_row_count >= thd->variables.min_examined_row_limit)
{
thd->status_var.long_query_count++;
slow_log_print(thd, thd->query, thd->query_length, start_of_query);
slow_log_print(thd, thd->query, thd->query_length, end_utime_of_query);
}
}
DBUG_VOID_RETURN;

View file

@ -15508,15 +15508,11 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
/* Add "filtered" field to item_list. */
if (join->thd->lex->describe & DESCRIBE_EXTENDED)
{
Item_float *filtered;
float f;
float f= 0.0;
if (examined_rows)
f= (float) (100.0 * join->best_positions[i].records_read /
examined_rows);
else
f= 0.0;
item_list.push_back((filtered= new Item_float(f)));
filtered->decimals= 2;
item_list.push_back(new Item_float(f, 2));
}

View file

@ -1663,11 +1663,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
if (mysys_var)
pthread_mutex_unlock(&mysys_var->mutex);
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;
#else
thd_info->start_time= tmp->start_time;
#endif
thd_info->query=0;
if (tmp->query)
{
@ -1686,7 +1682,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thread_info *thd_info;
time_t now= time(0);
time_t now= my_time(0);
while ((thd_info=thread_infos.get()))
{
protocol->prepare_for_resend();
@ -1716,7 +1712,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
TABLE *table= tables->table;
CHARSET_INFO *cs= system_charset_info;
char *user;
time_t now= time(0);
time_t now= my_time(0);
DBUG_ENTER("fill_process_list");
user= thd->security_ctx->master_access & PROCESS_ACL ?
@ -2069,11 +2065,11 @@ static bool show_status_array(THD *thd, const char *wild,
*/
switch (show_type) {
case SHOW_DOUBLE_STATUS:
{
value= ((char *) status_var + (ulong) value);
end= buff + sprintf(buff, "%f", *(double*) value);
/* fall through */
case SHOW_DOUBLE:
end= buff + my_sprintf(buff, (buff, "%f", *(double*) value));
break;
}
case SHOW_LONG_STATUS:
value= ((char *) status_var + (ulong) value);
/* fall through */
@ -2083,6 +2079,7 @@ static bool show_status_array(THD *thd, const char *wild,
break;
case SHOW_LONGLONG_STATUS:
value= ((char *) status_var + (ulonglong) value);
/* fall through */
case SHOW_LONGLONG:
end= longlong10_to_str(*(longlong*) value, buff, 10);
break;

View file

@ -54,6 +54,20 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
HA_CREATE_INFO *create_info,
Alter_info *alter_info);
#ifndef DBUG_OFF
/* Wait until we get a 'mysql_kill' signal */
static void wait_for_kill_signal(THD *thd)
{
while (thd->killed == 0)
sleep(1);
// Reset signal and continue as if nothing happend
thd->killed= THD::NOT_KILLED;
}
#endif
/*
Translate a file name to a table name (WL #1324).
@ -4111,6 +4125,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
RTFC_WAIT_OTHER_THREAD_FLAG |
RTFC_CHECK_KILLED_FLAG);
thd->exit_cond(old_message);
DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
if (thd->killed)
goto err;
/* Flush entries in the query cache involving this table. */

View file

@ -209,6 +209,11 @@ typedef struct user_conn {
char *user;
/* Pointer to host part of the key. */
char *host;
/*
The moment of time when per hour counters were reset last time
(i.e. start of "hour" for conn_per_hour, updates, questions counters).
*/
ulonglong reset_utime;
/* Total length of the key. */
uint len;
/* Current amount of concurrent connections for this account. */
@ -220,11 +225,6 @@ typedef struct user_conn {
uint conn_per_hour, updates, questions;
/* Maximum amount of resources which account is allowed to consume. */
USER_RESOURCES user_resources;
/*
The moment of time when per hour counters were reset last time
(i.e. start of "hour" for conn_per_hour, updates, questions counters).
*/
time_t intime;
} USER_CONN;
/* Bits in form->update */