summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2014-10-08 21:54:35 +0530
committerVenkatesh Duggirala <venkatesh.duggirala@oracle.com>2014-10-08 21:54:35 +0530
commit0827d756276dfaaeac6873daae852c8263146294 (patch)
tree05ded92647b28f5e59f363fc4e2d255844e25b9d
parent929680913417e6a09330376b9d99f3bf33db7ff3 (diff)
downloadmariadb-git-0827d756276dfaaeac6873daae852c8263146294.tar.gz
Bug #18808072 MYSQLBINLOG USES LOCALTIME() TO PRINT EVENTS, CAUSES KERNEL MUTEX CONTENTION
Problem: For every event read, mysqlbinlog calls localtime() which in turn calls stat(/etc/localtime) which is causing kernel mutex contention. Analysis and Fix: localtime() calls stat(/etc/localtime) for every instance of the call where as localtime_r() the reentrant version was optimized to store the read only tz internal structure. Hence it will not call stat(/etc/localtime). It will call only once at the beginning. The mysql server is calling localtime_r() and mysqlbinlog tool is one place where we are still using localtime(). Once the process (mysqlbinlog) is started if timezone is changed it will be not picked up the the process and it will continue with the same values as the beginning of the process. This behavior is in-lined with mysql server. Also adding localtime_r() and gmtime_r() support for windows.
-rw-r--r--client/mysqlbinlog.cc3
-rw-r--r--cmake/os/WindowsCache.cmake6
-rw-r--r--include/my_pthread.h16
-rw-r--r--mysys/my_wincond.c24
-rw-r--r--sql/log_event.cc5
5 files changed, 19 insertions, 35 deletions
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index dbc30680959..73a801c4b21 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2102,6 +2102,7 @@ int main(int argc, char** argv)
DBUG_PROCESS(argv[0]);
my_init_time(); // for time functions
+ tzset(); // set tzname
if (load_defaults("my", load_default_groups, &argc, &argv))
exit(1);
diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake
index 897012896c8..bbed14556b9 100644
--- a/cmake/os/WindowsCache.cmake
+++ b/cmake/os/WindowsCache.cmake
@@ -1,4 +1,4 @@
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -88,7 +88,7 @@ SET(HAVE_GETRLIMIT CACHE INTERNAL "")
SET(HAVE_GETRUSAGE CACHE INTERNAL "")
SET(HAVE_GETTIMEOFDAY CACHE INTERNAL "")
SET(HAVE_GETWD CACHE INTERNAL "")
-SET(HAVE_GMTIME_R CACHE INTERNAL "")
+SET(HAVE_GMTIME_R 1 CACHE INTERNAL "")
SET(HAVE_GRP_H CACHE INTERNAL "")
SET(HAVE_IA64INTRIN_H CACHE INTERNAL "")
SET(HAVE_IEEEFP_H CACHE INTERNAL "")
@@ -109,7 +109,7 @@ SET(HAVE_LANGINFO_H CACHE INTERNAL "")
SET(HAVE_LDIV 1 CACHE INTERNAL "")
SET(HAVE_LIMITS_H 1 CACHE INTERNAL "")
SET(HAVE_LOCALE_H 1 CACHE INTERNAL "")
-SET(HAVE_LOCALTIME_R CACHE INTERNAL "")
+SET(HAVE_LOCALTIME_R 1 CACHE INTERNAL "")
SET(HAVE_LOG2 CACHE INTERNAL "")
SET(HAVE_LONGJMP 1 CACHE INTERNAL "")
SET(HAVE_LRAND48 CACHE INTERNAL "")
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 20d929ba8eb..92676bd727c 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -142,8 +142,18 @@ int pthread_attr_init(pthread_attr_t *connect_att);
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
int pthread_attr_destroy(pthread_attr_t *connect_att);
int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
-struct tm *localtime_r(const time_t *timep,struct tm *tmp);
-struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
+
+static inline struct tm *localtime_r(const time_t *timep, struct tm *tmp)
+{
+ localtime_s(tmp, timep);
+ return tmp;
+}
+
+static inline struct tm *gmtime_r(const time_t *clock, struct tm *res)
+{
+ gmtime_s(res, clock);
+ return res;
+}
void pthread_exit(void *a);
int pthread_join(pthread_t thread, void **value_ptr);
diff --git a/mysys/my_wincond.c b/mysys/my_wincond.c
index 4794bb391b6..ac0166c87b8 100644
--- a/mysys/my_wincond.c
+++ b/mysys/my_wincond.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -344,26 +344,4 @@ int pthread_attr_destroy(pthread_attr_t *connect_att)
return 0;
}
-/****************************************************************************
-** Fix localtime_r() to be a bit safer
-****************************************************************************/
-
-struct tm *localtime_r(const time_t *timep,struct tm *tmp)
-{
- if (*timep == (time_t) -1) /* This will crash win32 */
- {
- bzero(tmp,sizeof(*tmp));
- }
- else
- {
- struct tm *res=localtime(timep);
- if (!res) /* Wrong date */
- {
- bzero(tmp,sizeof(*tmp)); /* Keep things safe */
- return 0;
- }
- *tmp= *res;
- }
- return tmp;
-}
#endif /* __WIN__ */
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 403c512ab3a..38efb2a9c6b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2162,13 +2162,8 @@ void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
DBUG_ENTER("Log_event::print_timestamp");
if (!ts)
ts = &when;
-#ifdef MYSQL_SERVER // This is always false
struct tm tm_tmp;
localtime_r(ts,(res= &tm_tmp));
-#else
- res=localtime(ts);
-#endif
-
my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
res->tm_year % 100,
res->tm_mon+1,