Second try at stack-guard patch, also apply fix for bug #435494
This commit is contained in:
parent
0198dfa540
commit
e6fb210ebd
@ -1,26 +1,84 @@
|
|||||||
mysql is not accounting for the "guard page" when setting thread stack size
|
mysql is not accounting for the "guard page" when setting thread stack size
|
||||||
requests. This is fatal on PPC systems, which may use guard pages as large
|
requests. This is fatal on PPC systems, which may use guard pages as large
|
||||||
as 64K. I'll bet a good deal that the hacks it uses for IA64 are a result
|
as 64K. This patch also documents the IA64 situation a bit better.
|
||||||
of misdiagnosis of a similar problem, so remove them.
|
|
||||||
|
|
||||||
It is not at this point entirely clear whether mysql is wrong in ignoring
|
Note: there are quite a few other setstacksize calls besides the two in
|
||||||
the guard page, or whether this is a RHEL bug (see our bz#435337). So not
|
mysqld.cc; is it important to fix any of the others?
|
||||||
reporting this upstream yet. But we need the patch now, so we can build mysql
|
|
||||||
in rawhide (the build machines are using RHEL5 kernels).
|
|
||||||
|
|
||||||
|
|
||||||
diff -Naur mysql-5.0.45.orig/sql/mysqld.cc mysql-5.0.45/sql/mysqld.cc
|
diff -Naur mysql-5.0.45.orig/sql/mysqld.cc mysql-5.0.45/sql/mysqld.cc
|
||||||
--- mysql-5.0.45.orig/sql/mysqld.cc 2007-07-04 09:06:03.000000000 -0400
|
--- mysql-5.0.45.orig/sql/mysqld.cc 2007-07-04 09:06:03.000000000 -0400
|
||||||
+++ mysql-5.0.45/sql/mysqld.cc 2008-02-28 15:17:20.000000000 -0500
|
+++ mysql-5.0.45/sql/mysqld.cc 2008-03-03 17:16:25.000000000 -0500
|
||||||
@@ -2286,6 +2286,7 @@
|
@@ -2281,6 +2281,68 @@
|
||||||
{
|
DBUG_VOID_RETURN;
|
||||||
int error;
|
}
|
||||||
pthread_attr_t thr_attr;
|
|
||||||
+ size_t guard_size = 0;
|
|
||||||
DBUG_ENTER("start_signal_handler");
|
|
||||||
|
|
||||||
(void) pthread_attr_init(&thr_attr);
|
+/* pthread_attr_setstacksize without so much platform-dependency */
|
||||||
@@ -2294,15 +2295,9 @@
|
+/* returns the actual stack size if possible */
|
||||||
|
+static size_t my_setstacksize(pthread_attr_t *attr, size_t stacksize)
|
||||||
|
+{
|
||||||
|
+ size_t guard_size = 0;
|
||||||
|
+
|
||||||
|
+#if defined(__ia64__) || defined(__ia64)
|
||||||
|
+ /*
|
||||||
|
+ On IA64, half of the requested stack size is used for "normal stack"
|
||||||
|
+ and half for "register stack". The space measured by check_stack_overrun
|
||||||
|
+ is the "normal stack", so double the request to make sure we have the
|
||||||
|
+ caller-expected amount of normal stack.
|
||||||
|
+
|
||||||
|
+ NOTE: there is no guarantee that the register stack can't grow faster
|
||||||
|
+ than normal stack, so it's very unclear that we won't dump core due to
|
||||||
|
+ stack overrun despite check_stack_overrun's efforts. Experimentation
|
||||||
|
+ shows that in the execution_constants test, the register stack grows
|
||||||
|
+ less than half as fast as normal stack, but perhaps other scenarios are
|
||||||
|
+ less forgiving. If it turns out that more space is needed for the
|
||||||
|
+ register stack, that could be forced (rather inefficiently) by using a
|
||||||
|
+ multiplier higher than 2 here.
|
||||||
|
+ */
|
||||||
|
+ stacksize *= 2;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ On many machines, the "guard space" is subtracted from the requested
|
||||||
|
+ stack size, and that space is quite large on some platforms. So add
|
||||||
|
+ it to our request, if we can find out what it is.
|
||||||
|
+
|
||||||
|
+ FIXME: autoconfiscate use of pthread_attr_getguardsize
|
||||||
|
+ */
|
||||||
|
+ if (pthread_attr_getguardsize(attr, &guard_size))
|
||||||
|
+ guard_size = 0; /* if can't find it out, treat as 0 */
|
||||||
|
+
|
||||||
|
+ pthread_attr_setstacksize(attr, stacksize + guard_size);
|
||||||
|
+
|
||||||
|
+ /* Retrieve actual stack size if possible */
|
||||||
|
+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
|
||||||
|
+ {
|
||||||
|
+ size_t real_stack_size= 0;
|
||||||
|
+ /* We must ignore real_stack_size = 0 as Solaris 2.9 can return 0 here */
|
||||||
|
+ if (pthread_attr_getstacksize(attr, &real_stack_size) == 0 &&
|
||||||
|
+ real_stack_size > guard_size)
|
||||||
|
+ {
|
||||||
|
+ real_stack_size -= guard_size;
|
||||||
|
+ if (real_stack_size < stacksize)
|
||||||
|
+ {
|
||||||
|
+ if (global_system_variables.log_warnings)
|
||||||
|
+ sql_print_warning("Asked for %ld thread stack, but got %ld",
|
||||||
|
+ (long) stacksize, (long) real_stack_size);
|
||||||
|
+ stacksize= real_stack_size;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#if defined(__ia64__) || defined(__ia64)
|
||||||
|
+ stacksize /= 2;
|
||||||
|
+#endif
|
||||||
|
+ return stacksize;
|
||||||
|
+}
|
||||||
|
|
||||||
|
static void start_signal_handler(void)
|
||||||
|
{
|
||||||
|
@@ -2294,15 +2356,7 @@
|
||||||
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
(void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
||||||
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
|
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
|
||||||
my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
|
my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
|
||||||
@ -33,13 +91,11 @@ diff -Naur mysql-5.0.45.orig/sql/mysqld.cc mysql-5.0.45/sql/mysqld.cc
|
|||||||
-#else
|
-#else
|
||||||
- pthread_attr_setstacksize(&thr_attr,thread_stack);
|
- pthread_attr_setstacksize(&thr_attr,thread_stack);
|
||||||
-#endif
|
-#endif
|
||||||
+
|
+ (void) my_setstacksize(&thr_attr,thread_stack);
|
||||||
+ pthread_attr_getguardsize(&thr_attr, &guard_size);
|
|
||||||
+ pthread_attr_setstacksize(&thr_attr, thread_stack + guard_size);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void) pthread_mutex_lock(&LOCK_thread_count);
|
(void) pthread_mutex_lock(&LOCK_thread_count);
|
||||||
@@ -3499,37 +3494,29 @@
|
@@ -3499,41 +3553,12 @@
|
||||||
init_signals();
|
init_signals();
|
||||||
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
|
if (!(opt_specialflag & SPECIAL_NO_PRIOR))
|
||||||
my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
|
my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
|
||||||
@ -53,27 +109,17 @@ diff -Naur mysql-5.0.45.orig/sql/mysqld.cc mysql-5.0.45/sql/mysqld.cc
|
|||||||
- pthread_attr_setstacksize(&connection_attrib,thread_stack);
|
- pthread_attr_setstacksize(&connection_attrib,thread_stack);
|
||||||
-#endif
|
-#endif
|
||||||
-#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
|
-#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
|
||||||
+
|
- {
|
||||||
{
|
- /* Retrieve used stack size; Needed for checking stack overflows */
|
||||||
+ size_t guard_size = 0;
|
|
||||||
+ size_t stack_size = 0;
|
|
||||||
+
|
|
||||||
+ pthread_attr_getguardsize(&connection_attrib, &guard_size);
|
|
||||||
+
|
|
||||||
+ pthread_attr_setstacksize(&connection_attrib, thread_stack + guard_size);
|
|
||||||
+
|
|
||||||
+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
|
|
||||||
/* Retrieve used stack size; Needed for checking stack overflows */
|
|
||||||
- size_t stack_size= 0;
|
- size_t stack_size= 0;
|
||||||
pthread_attr_getstacksize(&connection_attrib, &stack_size);
|
- pthread_attr_getstacksize(&connection_attrib, &stack_size);
|
||||||
-#if defined(__ia64__) || defined(__ia64)
|
-#if defined(__ia64__) || defined(__ia64)
|
||||||
- stack_size/= 2;
|
- stack_size/= 2;
|
||||||
-#endif
|
-#endif
|
||||||
/* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
|
- /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
|
||||||
- if (stack_size && stack_size < thread_stack)
|
- if (stack_size && stack_size < thread_stack)
|
||||||
+ if (stack_size && stack_size < thread_stack + guard_size)
|
- {
|
||||||
{
|
- if (global_system_variables.log_warnings)
|
||||||
if (global_system_variables.log_warnings)
|
|
||||||
- sql_print_warning("Asked for %lu thread stack, but got %ld",
|
- sql_print_warning("Asked for %lu thread stack, but got %ld",
|
||||||
- thread_stack, (long) stack_size);
|
- thread_stack, (long) stack_size);
|
||||||
-#if defined(__ia64__) || defined(__ia64)
|
-#if defined(__ia64__) || defined(__ia64)
|
||||||
@ -81,14 +127,16 @@ diff -Naur mysql-5.0.45.orig/sql/mysqld.cc mysql-5.0.45/sql/mysqld.cc
|
|||||||
-#else
|
-#else
|
||||||
- thread_stack= stack_size;
|
- thread_stack= stack_size;
|
||||||
-#endif
|
-#endif
|
||||||
+ sql_print_warning("Asked for %lu+%lu thread stack, but got %ld",
|
|
||||||
+ thread_stack, (long) guard_size, (long) stack_size);
|
|
||||||
+ thread_stack= stack_size - guard_size;
|
|
||||||
}
|
|
||||||
- }
|
- }
|
||||||
#endif
|
- }
|
||||||
+ }
|
-#endif
|
||||||
+
|
+
|
||||||
#ifdef __NETWARE__
|
#ifdef __NETWARE__
|
||||||
/* Increasing stacksize of threads on NetWare */
|
/* Increasing stacksize of threads on NetWare */
|
||||||
|
-
|
||||||
|
pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
|
||||||
|
+#else
|
||||||
|
+ thread_stack = my_setstacksize(&connection_attrib,thread_stack);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
(void) thr_setconcurrency(concurrency); // 10 by default
|
||||||
|
@ -68,7 +68,7 @@ start(){
|
|||||||
if [ $ret -eq 0 ]; then
|
if [ $ret -eq 0 ]; then
|
||||||
STARTTIMEOUT=30
|
STARTTIMEOUT=30
|
||||||
while [ $STARTTIMEOUT -gt 0 ]; do
|
while [ $STARTTIMEOUT -gt 0 ]; do
|
||||||
RESPONSE=`/usr/bin/mysqladmin -uUNKNOWN_MYSQL_USER ping 2>&1` && break
|
RESPONSE=`/usr/bin/mysqladmin --socket="$socketfile" --user=UNKNOWN_MYSQL_USER ping 2>&1` && break
|
||||||
echo "$RESPONSE" | grep -q "Access denied for user" && break
|
echo "$RESPONSE" | grep -q "Access denied for user" && break
|
||||||
sleep 1
|
sleep 1
|
||||||
let STARTTIMEOUT=${STARTTIMEOUT}-1
|
let STARTTIMEOUT=${STARTTIMEOUT}-1
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
Name: mysql
|
Name: mysql
|
||||||
Version: 5.0.45
|
Version: 5.0.45
|
||||||
Release: 10%{?dist}
|
Release: 11%{?dist}
|
||||||
Summary: MySQL client programs and shared libraries
|
Summary: MySQL client programs and shared libraries
|
||||||
Group: Applications/Databases
|
Group: Applications/Databases
|
||||||
URL: http://www.mysql.com
|
URL: http://www.mysql.com
|
||||||
@ -484,6 +484,11 @@ fi
|
|||||||
%{_mandir}/man1/mysql_client_test.1*
|
%{_mandir}/man1/mysql_client_test.1*
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Mon Mar 3 2008 Tom Lane <tgl@redhat.com> 5.0.45-11
|
||||||
|
- Fix mysql-stack-guard patch to work correctly on IA64
|
||||||
|
- Fix mysql.init to wait correctly when socket is not in default place
|
||||||
|
Related: #435494
|
||||||
|
|
||||||
* Mon Mar 03 2008 Dennis Gilmore <dennis@ausil.us> 5.0.45-10
|
* Mon Mar 03 2008 Dennis Gilmore <dennis@ausil.us> 5.0.45-10
|
||||||
- add sparc64 to 64 bit arches for test suite checking
|
- add sparc64 to 64 bit arches for test suite checking
|
||||||
- add sparc, sparcv9 and sparc64 to multilib handling
|
- add sparc, sparcv9 and sparc64 to multilib handling
|
||||||
|
Loading…
Reference in New Issue
Block a user