summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README3
-rw-r--r--cmd-line-utils/libedit/chartype.h6
-rw-r--r--cmd-line-utils/libedit/eln.c2
-rw-r--r--cmd-line-utils/libedit/readline.c2
-rw-r--r--configure.in2
-rw-r--r--include/my_stacktrace.h69
-rw-r--r--libmysqld/CMakeLists.txt1
-rw-r--r--mysql-test/r/archive.result19
-rw-r--r--mysql-test/r/key_cache.result16
-rw-r--r--mysql-test/r/mysqlcheck.result1
-rw-r--r--mysql-test/suite/innodb/r/innodb.result5
-rw-r--r--mysql-test/suite/innodb/t/innodb.test11
-rw-r--r--mysql-test/suite/innodb_plugin/r/innodb.result11
-rw-r--r--mysql-test/suite/innodb_plugin/t/innodb.test11
-rw-r--r--mysql-test/t/archive.test14
-rw-r--r--mysql-test/t/disabled.def1
-rw-r--r--mysql-test/t/key_cache.test16
-rw-r--r--mysql-test/t/merge.test10
-rw-r--r--mysql-test/t/mysqlcheck.test1
-rw-r--r--mysys/stacktrace.c371
-rwxr-xr-xsql/CMakeLists.txt3
-rw-r--r--sql/Makefile.am1
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc209
-rw-r--r--sql/signal_handler.cc256
-rw-r--r--sql/sql_table.cc5
-rw-r--r--storage/archive/ha_archive.cc37
-rw-r--r--storage/innobase/handler/ha_innodb.cc1
-rw-r--r--storage/innodb_plugin/ChangeLog18
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc1
-rw-r--r--storage/innodb_plugin/include/page0page.h4
-rw-r--r--storage/innodb_plugin/page/page0page.c4
-rw-r--r--storage/myisam/mi_close.c7
-rw-r--r--storage/myisam/mi_packrec.c7
-rw-r--r--storage/myisam/mi_preload.c3
-rw-r--r--storage/xtradb/handler/ha_innodb.cc1
-rw-r--r--storage/xtradb/page/page0page.c2
37 files changed, 837 insertions, 297 deletions
diff --git a/README b/README
index d74813f3810..b35acd95357 100644
--- a/README
+++ b/README
@@ -45,6 +45,9 @@ https://bugs.launchpad.net/maria
Bugs in the MySQL code can also be submitted at http://bugs.mysql.com
+The code for MariaDB, including all revision history, can be found at:
+https://code.launchpad.net/maria
+
***************************************************************************
diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h
index 678d13683be..40012afb47d 100644
--- a/cmd-line-utils/libedit/chartype.h
+++ b/cmd-line-utils/libedit/chartype.h
@@ -45,11 +45,11 @@
* seems to actually advertise this properly, despite Unicode 3.1 having
* been around since 2001... */
-/* XXXMYSQL : Added FreeBSD to bypass this check.
- TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */
+/* XXXMYSQL : Added FreeBSD & AIX to bypass this check.
+ TODO : Verify if FreeBSD & AIX stores ISO 10646 in wchar_t. */
#if !defined(__NetBSD__) && !defined(__sun) \
&& !(defined(__APPLE__) && defined(__MACH__)) \
- && !defined(__FreeBSD__)
+ && !defined(__FreeBSD__) && !defined(_AIX)
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c
index 4b9f16c38f3..f996367115a 100644
--- a/cmd-line-utils/libedit/eln.c
+++ b/cmd-line-utils/libedit/eln.c
@@ -200,7 +200,7 @@ el_set(EditLine *el, int op, ...)
ret = -1;
goto out;
}
- // XXX: The two strdup's leak
+ /* XXX: The two strdups leak. */
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
func);
ct_free_argv(wargv);
diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c
index eaf26d4c497..a2a92edc1b4 100644
--- a/cmd-line-utils/libedit/readline.c
+++ b/cmd-line-utils/libedit/readline.c
@@ -1978,7 +1978,7 @@ rl_callback_read_char()
} else
wbuf = NULL;
(*(void (*)(const char *))rl_linefunc)(wbuf);
- //el_set(e, EL_UNBUFFERED, 1);
+ /*el_set(e, EL_UNBUFFERED, 1);*/
}
}
diff --git a/configure.in b/configure.in
index 179f4bfcce2..fb7d8e7bf71 100644
--- a/configure.in
+++ b/configure.in
@@ -12,7 +12,7 @@ dnl
dnl When changing the major version number please also check the switch
dnl statement in mysqlbinlog::check_master_version(). You may also need
dnl to update version.c in ndb.
-AC_INIT([MariaDB Server], [5.1.60-MariaDB], [], [mysql])
+AC_INIT([MariaDB Server], [5.1.61-MariaDB], [], [mysql])
AC_CONFIG_SRCDIR([sql/mysqld.cc])
AC_CANONICAL_SYSTEM
diff --git a/include/my_stacktrace.h b/include/my_stacktrace.h
index 5138ea98191..a2fd89852fc 100644
--- a/include/my_stacktrace.h
+++ b/include/my_stacktrace.h
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2001, 2010, Oracle and/or its affiliates.
+/* Copyright (c) 2001, 2011, Oracle and/or its affiliates.
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
@@ -12,8 +11,7 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef _my_stacktrace_h_
#define _my_stacktrace_h_
@@ -63,6 +61,69 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep);
void my_write_core(int sig);
#endif
+
+
+/**
+ Async-signal-safe utility functions used by signal handler routines.
+ Declared here in order to unit-test them.
+ These are not general-purpose, but tailored to the signal handling routines.
+*/
+/**
+ Converts a longlong value to string.
+ @param base 10 for decimal, 16 for hex values (0..9a..f)
+ @param val The value to convert
+ @param buf Assumed to point to the *end* of the buffer.
+ @returns Pointer to the first character of the converted string.
+ Negative values:
+ for base-10 the return string will be prepended with '-'
+ for base-16 the return string will contain 16 characters
+ Implemented with simplicity, and async-signal-safety in mind.
+*/
+char *my_safe_itoa(int base, longlong val, char *buf);
+
+/**
+ Converts a ulonglong value to string.
+ @param base 10 for decimal, 16 for hex values (0..9a..f)
+ @param val The value to convert
+ @param buf Assumed to point to the *end* of the buffer.
+ @returns Pointer to the first character of the converted string.
+ Implemented with simplicity, and async-signal-safety in mind.
+*/
+char *my_safe_utoa(int base, ulonglong val, char *buf);
+
+/**
+ A (very) limited version of snprintf.
+ @param to Destination buffer.
+ @param n Size of destination buffer.
+ @param fmt printf() style format string.
+ @returns Number of bytes written, including terminating '\0'
+ Supports 'd' 'i' 'u' 'x' 'p' 's' conversion.
+ Supports 'l' and 'll' modifiers for integral types.
+ Does not support any width/precision.
+ Implemented with simplicity, and async-signal-safety in mind.
+*/
+size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 3, 4);
+
+/**
+ A (very) limited version of snprintf, which writes the result to STDERR.
+ @sa my_safe_snprintf
+ Implemented with simplicity, and async-signal-safety in mind.
+ @note Has an internal buffer capacity of 512 bytes,
+ which should suffice for our signal handling routines.
+*/
+size_t my_safe_printf_stderr(const char* fmt, ...)
+ ATTRIBUTE_FORMAT(printf, 1, 2);
+
+/**
+ Writes up to count bytes from buffer to STDERR.
+ Implemented with simplicity, and async-signal-safety in mind.
+ @param buf Buffer containing data to be written.
+ @param count Number of bytes to write.
+ @returns Number of bytes written.
+*/
+size_t my_write_stderr(const void *buf, size_t count);
+
C_MODE_END
#endif /* _my_stacktrace_h_ */
diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
index b74a38cc8a6..94b5b8c3133 100644
--- a/libmysqld/CMakeLists.txt
+++ b/libmysqld/CMakeLists.txt
@@ -103,6 +103,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/password.c ../sql/discover.cc ../sql/derror.cc
../sql/field.cc ../sql/field_conv.cc
../sql/filesort.cc ../sql/gstream.cc ../sql/ha_partition.cc
+ ../sql/signal_handler.cc
../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc
../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc
../sql/item.cc ../sql/item_create.cc ../sql/item_func.cc
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index 347635abb82..0ec84efa842 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -12782,3 +12782,22 @@ a b c d e f
-1 b c d e 1
DROP TABLE t1;
SET sort_buffer_size=DEFAULT;
+#
+# BUG#11758979 - 51252: ARCHIVE TABLES CAUSE 100% CPU USAGE
+# AND HANG IN SHOW TABLE STATUS
+# (to be executed with valgrind)
+CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE;
+INSERT INTO t1 VALUES(NULL, '');
+FLUSH TABLE t1;
+# we need this select to workaround BUG#11764364
+SELECT * FROM t1;
+a b
+NULL
+CHECKSUM TABLE t1 EXTENDED;
+Table Checksum
+test.t1 286155052
+FLUSH TABLE t1;
+OPTIMIZE TABLE t1;
+Table Op Msg_type Msg_text
+test.t1 optimize status OK
+DROP TABLE t1;
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index f80fea0fc76..78dd65fdcb1 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -365,3 +365,19 @@ Variable_name Value
key_cache_block_size 1536
SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
DROP TABLE t1;
+#
+# Bug#12361113: crash when load index into cache
+#
+# Note that this creates an empty disabled key cache!
+SET GLOBAL key_cache_none.key_cache_block_size = 1024;
+CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM;
+INSERT INTO t1 VALUES (1, 1);
+CACHE INDEX t1 in key_cache_none;
+ERROR HY000: Unknown key cache 'key_cache_none'
+# The bug crashed the server at LOAD INDEX below. Now it will succeed
+# since the default cache is used due to CACHE INDEX failed for
+# key_cache_none.
+LOAD INDEX INTO CACHE t1;
+Table Op Msg_type Msg_text
+test.t1 preload_keys status OK
+DROP TABLE t1;
diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result
index 812fd12e197..6ba5078ed00 100644
--- a/mysql-test/r/mysqlcheck.result
+++ b/mysql-test/r/mysqlcheck.result
@@ -139,6 +139,7 @@ DROP TABLE `@`;
CREATE TABLE `я` (a INT);
SET NAMES DEFAULT;
mysqlcheck --default-character-set="latin1" --databases test
+call mtr.add_suppression("Can't find file: '..test.@003f.frm'");
test.?
Error : Table doesn't exist
status : Operation failed
diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result
index 37eaa8800be..809d372f695 100644
--- a/mysql-test/suite/innodb/r/innodb.result
+++ b/mysql-test/suite/innodb/r/innodb.result
@@ -2371,3 +2371,8 @@ t1 CREATE TABLE `t1` (
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t1;
set storage_engine=MyISAM;
+Variable_name Value
+Handler_read_key 0
+f1
+Variable_name Value
+Handler_read_key 1
diff --git a/mysql-test/suite/innodb/t/innodb.test b/mysql-test/suite/innodb/t/innodb.test
index 72893f562c1..5df7347c552 100644
--- a/mysql-test/suite/innodb/t/innodb.test
+++ b/mysql-test/suite/innodb/t/innodb.test
@@ -1394,6 +1394,17 @@ eval set storage_engine=$default;
-- disable_query_log
SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
+#
+# Test fix for bug 13117023. InnoDB increments HA_READ_KEY_COUNT (aka
+# HANDLER_READ_KEY) when it should not.
+#
+create table t1 (f1 integer primary key) engine=innodb;
+flush status;
+show status like "handler_read_key";
+select f1 from t1;
+show status like "handler_read_key";
+drop table t1;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/suite/innodb_plugin/r/innodb.result b/mysql-test/suite/innodb_plugin/r/innodb.result
index a81dd1d3a86..f346e2d5917 100644
--- a/mysql-test/suite/innodb_plugin/r/innodb.result
+++ b/mysql-test/suite/innodb_plugin/r/innodb.result
@@ -3257,3 +3257,14 @@ Handler_update 1
Variable_name Value
Handler_delete 1
DROP TABLE bug58912;
+create table t1 (f1 integer primary key) engine=innodb;
+flush status;
+show status like "handler_read_key";
+Variable_name Value
+Handler_read_key 0
+select f1 from t1;
+f1
+show status like "handler_read_key";
+Variable_name Value
+Handler_read_key 1
+drop table t1;
diff --git a/mysql-test/suite/innodb_plugin/t/innodb.test b/mysql-test/suite/innodb_plugin/t/innodb.test
index 59e0328bb8d..c0b479fee2e 100644
--- a/mysql-test/suite/innodb_plugin/t/innodb.test
+++ b/mysql-test/suite/innodb_plugin/t/innodb.test
@@ -2573,6 +2573,17 @@ SET GLOBAL innodb_thread_concurrency = @innodb_thread_concurrency_orig;
# Clean up after the Bug#55284/Bug#58912 test case.
DROP TABLE bug58912;
+#
+# Test fix for bug 13117023. InnoDB increments HA_READ_KEY_COUNT (aka
+# HANDLER_READ_KEY) when it should not.
+#
+create table t1 (f1 integer primary key) engine=innodb;
+flush status;
+show status like "handler_read_key";
+select f1 from t1;
+show status like "handler_read_key";
+drop table t1;
+
#######################################################################
# #
# Please, DO NOT TOUCH this file as well as the innodb.result file. #
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index 9ecbee1ac9f..6f788fc3cc6 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1713,3 +1713,17 @@ INSERT INTO t1 SELECT t1.* FROM t1,t1 t2,t1 t3,t1 t4,t1 t5,t1 t6;
SELECT * FROM t1 ORDER BY f LIMIT 1;
DROP TABLE t1;
SET sort_buffer_size=DEFAULT;
+
+--echo #
+--echo # BUG#11758979 - 51252: ARCHIVE TABLES CAUSE 100% CPU USAGE
+--echo # AND HANG IN SHOW TABLE STATUS
+--echo # (to be executed with valgrind)
+CREATE TABLE t1(a BLOB, b VARCHAR(200)) ENGINE=ARCHIVE;
+INSERT INTO t1 VALUES(NULL, '');
+FLUSH TABLE t1;
+--echo # we need this select to workaround BUG#11764364
+SELECT * FROM t1;
+CHECKSUM TABLE t1 EXTENDED;
+FLUSH TABLE t1;
+OPTIMIZE TABLE t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 84c981c08c1..d8ef026914d 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -12,4 +12,3 @@
kill : Bug#11748945 2008-12-03 HHunger need some changes to be robust enough for pushbuild.
read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exists
main.log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists
-
diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test
index f12d20e962e..adba2adddb5 100644
--- a/mysql-test/t/key_cache.test
+++ b/mysql-test/t/key_cache.test
@@ -248,3 +248,19 @@ SET GLOBAL key_cache_block_size= @bug28478_key_cache_block_size;
DROP TABLE t1;
# End of 4.1 tests
+
+--echo #
+--echo # Bug#12361113: crash when load index into cache
+--echo #
+
+--echo # Note that this creates an empty disabled key cache!
+SET GLOBAL key_cache_none.key_cache_block_size = 1024;
+CREATE TABLE t1 (a INT, b INTEGER NOT NULL, KEY (b) ) ENGINE = MYISAM;
+INSERT INTO t1 VALUES (1, 1);
+--error ER_UNKNOWN_KEY_CACHE
+CACHE INDEX t1 in key_cache_none;
+--echo # The bug crashed the server at LOAD INDEX below. Now it will succeed
+--echo # since the default cache is used due to CACHE INDEX failed for
+--echo # key_cache_none.
+LOAD INDEX INTO CACHE t1;
+DROP TABLE t1;
diff --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index 90386a97fc6..eecf892869f 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -1848,9 +1848,13 @@ CREATE TABLE t1(a INT);
--echo # Test reattach merge failure
LOCK TABLES m1 READ;
--echo # Replace 't1' with 't3' table using file operations.
-remove_file $MYSQLD_DATADIR/test/t1.frm;
-remove_file $MYSQLD_DATADIR/test/t1.MYI;
-remove_file $MYSQLD_DATADIR/test/t1.MYD;
+# move + remove is a work around for windows.
+move_file $MYSQLD_DATADIR/test/t1.frm $MYSQLD_DATADIR/test/oldt1.frm;
+move_file $MYSQLD_DATADIR/test/t1.MYI $MYSQLD_DATADIR/test/oldt1.MYI;
+move_file $MYSQLD_DATADIR/test/t1.MYD $MYSQLD_DATADIR/test/oldt1.MYD;
+remove_file $MYSQLD_DATADIR/test/oldt1.frm;
+remove_file $MYSQLD_DATADIR/test/oldt1.MYI;
+remove_file $MYSQLD_DATADIR/test/oldt1.MYD;
copy_file $MYSQLD_DATADIR/test/t3.frm $MYSQLD_DATADIR/test/t1.frm;
copy_file $MYSQLD_DATADIR/test/t3.MYI $MYSQLD_DATADIR/test/t1.MYI;
copy_file $MYSQLD_DATADIR/test/t3.MYD $MYSQLD_DATADIR/test/t1.MYD;
diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test
index 986b5aba385..bf99d48fd6a 100644
--- a/mysql-test/t/mysqlcheck.test
+++ b/mysql-test/t/mysqlcheck.test
@@ -138,6 +138,7 @@ CREATE TABLE `я` (a INT);
SET NAMES DEFAULT;
--echo mysqlcheck --default-character-set="latin1" --databases test
# Error returned depends on platform, replace it with "Table doesn't exist"
+call mtr.add_suppression("Can't find file: '..test.@003f.frm'");
--replace_result "Can't find file: './test/@003f.frm' (errno: 22)" "Table doesn't exist" "Table 'test.?' doesn't exist" "Table doesn't exist"
--exec $MYSQL_CHECK --default-character-set="latin1" --databases test
--echo mysqlcheck --default-character-set="utf8" --databases test
diff --git a/mysys/stacktrace.c b/mysys/stacktrace.c
index 119dadab1a9..dce01a0c3b9 100644
--- a/mysys/stacktrace.c
+++ b/mysys/stacktrace.c
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2001, 2010, Oracle and/or its affiliates
+/* Copyright (c) 2001, 2011, Oracle and/or its affiliates.
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
@@ -12,10 +11,13 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
-/* Workaround for Bug#32082: VOID redefinition on Win results in compile errors*/
+/*
+ Workaround for Bug#32082: VOID redefinition on Win results in
+ compile errors
+*/
#define DONT_DEFINE_VOID 1
#include <my_global.h>
@@ -57,10 +59,11 @@ void my_init_stacktrace()
static void print_buffer(char *buffer, size_t count)
{
+ const char s[]= " ";
for (; count && *buffer; --count)
{
- int c= (int) *buffer++;
- fputc(isprint(c) ? c : ' ', stderr);
+ my_write_stderr(isprint(*buffer) ? buffer : s, 1);
+ ++buffer;
}
}
@@ -124,10 +127,10 @@ static int safe_print_str(const char *addr, int max_len)
/* Output a new line if something was printed. */
if (total != (size_t) max_len)
- fputc('\n', stderr);
+ my_safe_printf_stderr("%s", "\n");
if (nbytes == -1)
- fprintf(stderr, "Can't read from address %p: %m.\n", addr);
+ my_safe_printf_stderr("Can't read from address %p\n", addr);
close(fd);
@@ -149,13 +152,13 @@ void my_safe_print_str(const char* val, int max_len)
if (!PTR_SANE(val))
{
- fprintf(stderr, "is an invalid pointer\n");
+ my_safe_printf_stderr("%s", "is an invalid pointer\n");
return;
}
for (; max_len && PTR_SANE(val) && *val; --max_len)
- fputc(*val++, stderr);
- fputc('\n', stderr);
+ my_write_stderr((val++), 1);
+ my_safe_printf_stderr("%s", "\n");
}
#if defined(HAVE_PRINTSTACK)
@@ -167,14 +170,15 @@ void my_print_stacktrace(uchar* stack_bottom __attribute__((unused)),
ulong thread_stack __attribute__((unused)))
{
if (printstack(fileno(stderr)) == -1)
- fprintf(stderr, "Error when traversing the stack, stack appears corrupt.\n");
+ my_safe_printf_stderr("%s",
+ "Error when traversing the stack, stack appears corrupt.\n");
else
- fprintf(stderr,
- "Please read "
- "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
- "and follow instructions on how to resolve the stack trace.\n"
- "Resolved stack trace is much more helpful in diagnosing the\n"
- "problem, so please do resolve it\n");
+ my_safe_printf_stderr("%s"
+ "Please read "
+ "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
+ "and follow instructions on how to resolve the stack trace.\n"
+ "Resolved stack trace is much more helpful in diagnosing the\n"
+ "problem, so please do resolve it\n");
}
#elif HAVE_BACKTRACE && (HAVE_BACKTRACE_SYMBOLS || HAVE_BACKTRACE_SYMBOLS_FD)
@@ -212,9 +216,9 @@ static void my_demangle_symbols(char **addrs, int n)
}
if (demangled)
- fprintf(stderr, "%s(%s+%s\n", addrs[i], demangled, end);
+ my_safe_printf_stderr("%s(%s+%s\n", addrs[i], demangled, end);
else
- fprintf(stderr, "%s\n", addrs[i]);
+ my_safe_printf_stderr("%s\n", addrs[i]);
}
}
@@ -225,8 +229,8 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
void *addrs[128];
char **strings= NULL;
int n = backtrace(addrs, array_elements(addrs));
- fprintf(stderr, "stack_bottom = %p thread_stack 0x%lx\n",
- stack_bottom, thread_stack);
+ my_safe_printf_stderr("stack_bottom = %p thread_stack 0x%lx\n",
+ stack_bottom, thread_stack);
#if BACKTRACE_DEMANGLE
if ((strings= backtrace_symbols(addrs, n)))
{
@@ -319,8 +323,9 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
#endif
if (!fp)
{
- fprintf(stderr, "frame pointer is NULL, did you compile with\n\
--fomit-frame-pointer? Aborting backtrace!\n");
+ my_safe_printf_stderr("%s",
+ "frame pointer is NULL, did you compile with\n"
+ "-fomit-frame-pointer? Aborting backtrace!\n");
return;
}
@@ -328,24 +333,28 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{
ulong tmp= min(0x10000,thread_stack);
/* Assume that the stack starts at the previous even 65K */
- stack_bottom= (uchar*) (((ulong) &fp + tmp) &
- ~(ulong) 0xFFFF);
- fprintf(stderr, "Cannot determine thread, fp=%p, backtrace may not be correct.\n", fp);
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
+ my_safe_printf_stderr("Cannot determine thread, fp=%p, "
+ "backtrace may not be correct.\n", fp);
}
if (fp > (uchar**) stack_bottom ||
fp < (uchar**) stack_bottom - thread_stack)
{
- fprintf(stderr, "Bogus stack limit or frame pointer,\
- fp=%p, stack_bottom=%p, thread_stack=%ld, aborting backtrace.\n",
- fp, stack_bottom, thread_stack);
+ my_safe_printf_stderr("Bogus stack limit or frame pointer, "
+ "fp=%p, stack_bottom=%p, thread_stack=%ld, "
+ "aborting backtrace.\n",
+ fp, stack_bottom, thread_stack);
return;
}
- fprintf(stderr, "Stack range sanity check OK, backtrace follows:\n");
+ my_safe_printf_stderr("%s",
+ "Stack range sanity check OK, backtrace follows:\n");
#if defined(__alpha__) && defined(__GNUC__)
- fprintf(stderr, "Warning: Alpha stacks are difficult -\
- will be taking some wild guesses, stack trace may be incorrect or \
- terminate abruptly\n");
+ my_safe_printf_stderr("%s",
+ "Warning: Alpha stacks are difficult -"
+ "will be taking some wild guesses, stack trace may be incorrect or "
+ "terminate abruptly\n");
+
/* On Alpha, we need to get pc */
__asm __volatile__ ("bsr %0, do_next; do_next: "
:"=r"(pc)
@@ -359,8 +368,9 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{
#if defined(__i386__) || defined(__x86_64__)
uchar** new_fp = (uchar**)*fp;
- fprintf(stderr, "%p\n", frame_count == sigreturn_frame_count ?
- *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
+ my_safe_printf_stderr("%p\n",
+ frame_count == sigreturn_frame_count ?
+ *(fp + SIGRETURN_FRAME_OFFSET) : *(fp + 1));
#endif /* defined(__386__) || defined(__x86_64__) */
#if defined(__alpha__) && defined(__GNUC__)
@@ -374,38 +384,40 @@ void my_print_stacktrace(uchar* stack_bottom, ulong thread_stack)
{
pc = find_prev_pc(pc, fp);
if (pc)
- fprintf(stderr, "%p\n", pc);
+ my_safe_printf_stderr("%p\n", pc);
else
{
- fprintf(stderr, "Not smart enough to deal with the rest\
- of this stack\n");
+ my_safe_printf_stderr("%s",
+ "Not smart enough to deal with the rest of this stack\n");
goto end;
}
}
else
{
- fprintf(stderr, "Not smart enough to deal with the rest of this stack\n");
+ my_safe_printf_stderr("%s",
+ "Not smart enough to deal with the rest of this stack\n");
goto end;
}
#endif /* defined(__alpha__) && defined(__GNUC__) */
if (new_fp <= fp )
{
- fprintf(stderr, "New value of fp=%p failed sanity check,\
- terminating stack trace!\n", new_fp);
+ my_safe_printf_stderr("New value of fp=%p failed sanity check, "
+ "terminating stack trace!\n", new_fp);
goto end;
}
fp = new_fp;
++frame_count;
}
-
- fprintf(stderr, "Stack trace seems successful - bottom reached\n");
+ my_safe_printf_stderr("%s",
+ "Stack trace seems successful - bottom reached\n");
end:
- fprintf(stderr,
- "Please read http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
- "and follow instructions on how to resolve the stack trace.\n"
- "Resolved stack trace is much more helpful in diagnosing the\n"
- "problem, so please do resolve it\n");
+ my_safe_printf_stderr("%s",
+ "Please read "
+ "http://dev.mysql.com/doc/refman/5.1/en/resolve-stack-dump.html\n"
+ "and follow instructions on how to resolve the stack trace.\n"
+ "Resolved stack trace is much more helpful in diagnosing the\n"
+ "problem, so please do resolve it\n");
}
#endif /* TARGET_OS_LINUX */
#endif /* HAVE_STACKTRACE */
@@ -438,10 +450,12 @@ void my_write_core(int sig)
#include <tlhelp32.h>
/*
- Stack tracing on Windows is implemented using Debug Helper library(dbghelp.dll)
- We do not redistribute dbghelp and the one comes with older OS (up to Windows 2001)
- is missing some important functions like functions StackWalk64 or MinidumpWriteDump.
- Hence, we have to load functions at runtime using LoadLibrary/GetProcAddress.
+ Stack tracing on Windows is implemented using Debug Helper
+ library(dbghelp.dll) We do not redistribute dbghelp and the one
+ comes with older OS (up to Windows 2001) is missing some important
+ functions like functions StackWalk64 or MinidumpWriteDump. Hence,
+ we have to load functions at runtime using
+ LoadLibrary/GetProcAddress.
*/
typedef DWORD (WINAPI *SymSetOptions_FctType)(DWORD dwOptions);
@@ -530,10 +544,11 @@ void my_set_exception_pointers(EXCEPTION_POINTERS *ep)
/*
- Get symbol path - semicolon-separated list of directories to search for debug
- symbols. We expect PDB in the same directory as corresponding exe or dll,
- so the path is build from directories of the loaded modules. If environment
- variable _NT_SYMBOL_PATH is set, it's value appended to the symbol search path
+ Get symbol path - semicolon-separated list of directories to search
+ for debug symbols. We expect PDB in the same directory as
+ corresponding exe or dll, so the path is build from directories of
+ the loaded modules. If environment variable _NT_SYMBOL_PATH is set,
+ it's value appended to the symbol search path
*/
static void get_symbol_path(char *path, size_t size)
{
@@ -657,9 +672,9 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
if(!have_module)
{
/*
- ModuleInfo structure has been "compatibly" extended in releases after XP,
- and its size was increased. To make XP dbghelp.dll function
- happy, pretend passing the old structure.
+ ModuleInfo structure has been "compatibly" extended in
+ releases after XP, and its size was increased. To make XP
+ dbghelp.dll function happy, pretend passing the old structure.
*/
module.SizeOfStruct= MODULE64_SIZE_WINXP;
have_module= pSymGetModuleInfo64(hProcess, addr, &module);
@@ -670,7 +685,7 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
&(package.sym));
have_source= pSymGetLineFromAddr64(hProcess, addr, &line_offset, &line);
- fprintf(stderr, "%p ", addr);
+ my_safe_printf_stderr("%p ", addr);
if(have_module)
{
char *base_image_name= strrchr(module.ImageName, '\\');
@@ -678,12 +693,13 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
base_image_name++;
else
base_image_name= module.ImageName;
- fprintf(stderr, "%s!", base_image_name);
+ my_safe_printf_stderr("%s!", base_image_name);
}
if(have_symbol)
- fprintf(stderr, "%s()", package.sym.Name);
+ my_safe_printf_stderr("%s()", package.sym.Name);
+
else if(have_module)
- fprintf(stderr, "???");
+ my_safe_printf_stderr("%s", "???");
if(have_source)
{
@@ -692,11 +708,11 @@ void my_print_stacktrace(uchar* unused1, ulong unused2)
base_file_name++;
else
base_file_name= line.FileName;
- fprintf(stderr,"[%s:%u]", base_file_name, line.LineNumber);
+ my_safe_printf_stderr("[%s:%u]",
+ base_file_name, line.LineNumber);
}
- fprintf(stderr, "\n");
+ my_safe_printf_stderr("%s", "\n");
}
- fflush(stderr);
}
@@ -733,22 +749,22 @@ void my_write_core(int unused)
if(pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),
hFile, MiniDumpNormal, &info, 0, 0))
{
- fprintf(stderr, "Minidump written to %s\n",
- _fullpath(path, dump_fname, sizeof(path)) ? path : dump_fname);
+ my_safe_printf_stderr("Minidump written to %s\n",
+ _fullpath(path, dump_fname, sizeof(path)) ?
+ path : dump_fname);
}
else
{
- fprintf(stderr,"MiniDumpWriteDump() failed, last error %u\n",
- GetLastError());
+ my_safe_printf_stderr("MiniDumpWriteDump() failed, last error %u\n",
+ (uint) GetLastError());
}
CloseHandle(hFile);
}
else
{
- fprintf(stderr, "CreateFile(%s) failed, last error %u\n", dump_fname,
- GetLastError());
+ my_safe_printf_stderr("CreateFile(%s) failed, last error %u\n",
+ dump_fname, (uint) GetLastError());
}
- fflush(stderr);
}
@@ -756,11 +772,212 @@ void my_safe_print_str(const char *val, int len)
{
__try
{
- fprintf(stderr,"=%.*s\n", len, val);
+ my_write_stderr(val, len);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
- fprintf(stderr,"is an invalid string pointer\n");
+ my_safe_printf_stderr("%s", "is an invalid string pointer\n");
}
}
#endif /*__WIN__*/
+
+
+#ifdef __WIN__
+size_t my_write_stderr(const void *buf, size_t count)
+{
+ DWORD bytes_written;
+ SetFilePointer(GetStdHandle(STD_ERROR_HANDLE), 0, NULL, FILE_END);
+ WriteFile(GetStdHandle(STD_ERROR_HANDLE), buf, count, &bytes_written, NULL);
+ return bytes_written;
+}
+#else
+size_t my_write_stderr(const void *buf, size_t count)
+{
+ return (size_t) write(STDERR_FILENO, buf, count);
+}
+#endif
+
+
+static const char digits[]= "0123456789abcdef";
+
+char *my_safe_utoa(int base, ulonglong val, char *buf)
+{
+ *buf--= 0;
+ do {
+ *buf--= digits[val % base];
+ } while ((val /= base) != 0);
+ return buf + 1;
+}
+
+
+char *my_safe_itoa(int base, longlong val, char *buf)
+{
+ char *orig_buf= buf;
+ const my_bool is_neg= (val < 0);
+ *buf--= 0;
+
+ if (is_neg)
+ val= -val;
+ if (is_neg && base == 16)
+ {
+ int ix;
+ val-= 1;
+ for (ix= 0; ix < 16; ++ix)
+ buf[-ix]= '0';
+ }
+
+ do {
+ *buf--= digits[val % base];
+ } while ((val /= base) != 0);
+
+ if (is_neg && base == 10)
+ *buf--= '-';
+
+ if (is_neg && base == 16)
+ {
+ int ix;
+ buf= orig_buf - 1;
+ for (ix= 0; ix < 16; ++ix, --buf)
+ {
+ switch (*buf)
+ {
+ case '0': *buf= 'f'; break;
+ case '1': *buf= 'e'; break;
+ case '2': *buf= 'd'; break;
+ case '3': *buf= 'c'; break;
+ case '4': *buf= 'b'; break;
+ case '5': *buf= 'a'; break;
+ case '6': *buf= '9'; break;
+ case '7': *buf= '8'; break;
+ case '8': *buf= '7'; break;
+ case '9': *buf= '6'; break;
+ case 'a': *buf= '5'; break;
+ case 'b': *buf= '4'; break;
+ case 'c': *buf= '3'; break;
+ case 'd': *buf= '2'; break;
+ case 'e': *buf= '1'; break;
+ case 'f': *buf= '0'; break;
+ }
+ }
+ }
+ return buf+1;
+}
+
+
+static const char *check_longlong(const char *fmt, my_bool *have_longlong)
+{
+ *have_longlong= FALSE;
+ if (*fmt == 'l')
+ {
+ fmt++;
+ if (*fmt != 'l')
+ *have_longlong= (sizeof(long) == sizeof(longlong));
+ else
+ {
+ fmt++;
+ *have_longlong= TRUE;
+ }
+ }
+ return fmt;
+}
+
+static size_t my_safe_vsnprintf(char *to, size_t size,
+ const char* format, va_list ap)
+{
+ char *start= to;
+ char *end= start + size - 1;
+ for (; *format; ++format)
+ {
+ my_bool have_longlong = FALSE;
+ if (*format != '%')
+ {
+ if (to == end) /* end of buffer */
+ break;
+ *to++= *format; /* copy ordinary char */
+ continue;
+ }
+ ++format; /* skip '%' */
+
+ format= check_longlong(format, &have_longlong);
+
+ switch (*format)
+ {
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'x':
+ case 'p':
+ {
+ longlong ival= 0;
+ ulonglong uval = 0;
+ if (*format == 'p')
+ have_longlong= (sizeof(void *) == sizeof(longlong));
+ if (have_longlong)
+ {
+ if (*format == 'u')
+ uval= va_arg(ap, ulonglong);
+ else
+ ival= va_arg(ap, longlong);
+ }
+ else
+ {
+ if (*format == 'u')
+ uval= va_arg(ap, unsigned int);
+ else
+ ival= va_arg(ap, int);
+ }
+
+ {
+ char buff[22];
+ const int base= (*format == 'x' || *format == 'p') ? 16 : 10;
+ char *val_as_str= (*format == 'u') ?
+ my_safe_utoa(base, uval, &buff[sizeof(buff)-1]) :
+ my_safe_itoa(base, ival, &buff[sizeof(buff)-1]);
+
+ /* Strip off "ffffffff" if we have 'x' format without 'll' */
+ if (*format == 'x' && !have_longlong && ival < 0)
+ val_as_str+= 8;
+
+ while (*val_as_str && to < end)
+ *to++= *val_as_str++;
+ continue;
+ }
+ }
+ case 's':
+ {
+ const char *val= va_arg(ap, char*);
+ if (!val)
+ val= "(null)";
+ while (*val && to < end)
+ *to++= *val++;
+ continue;
+ }
+ }
+ }
+ *to= 0;
+ return to - start;
+}
+
+
+size_t my_safe_snprintf(char* to, size_t n, const char* fmt, ...)
+{
+ size_t result;
+ va_list args;
+ va_start(args,fmt);
+ result= my_safe_vsnprintf(to, n, fmt, args);
+ va_end(args);
+ return result;
+}
+
+
+size_t my_safe_printf_stderr(const char* fmt, ...)
+{
+ char to[512];
+ size_t result;
+ va_list args;
+ va_start(args,fmt);
+ result= my_safe_vsnprintf(to, sizeof(to), fmt, args);
+ va_end(args);
+ my_write_stderr(to, result);
+ return result;
+}
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 535f53335be..37c59a12541 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -64,6 +64,7 @@ SET (SQL_SOURCE
sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc
sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
debug_sync.cc debug_sync.h
+ signal_handler.cc
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.cc
sql_table.cc sql_test.cc sql_trigger.cc sql_udf.cc sql_union.cc
sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc
@@ -112,7 +113,7 @@ IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
ADD_CUSTOM_COMMAND(TARGET mysqld PRE_LINK
COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js
${PLATFORM} ${LIB_LOCATIONS} > mysqld.def
- WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/sql)
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
ENDIF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS)
ADD_DEPENDENCIES(sql GenError)
diff --git a/sql/Makefile.am b/sql/Makefile.am
index c413f8ce771..739b36a4d1d 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -105,6 +105,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
records.cc filesort.cc handler.cc \
ha_partition.cc \
debug_sync.cc \
+ signal_handler.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 7b3c264c896..5aeadd4d30b 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1988,10 +1988,11 @@ extern ulong expire_logs_days, sync_binlog_period, sync_binlog_counter;
extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size;
extern ulong tc_log_page_waits;
extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
+extern my_bool opt_expect_abort, opt_stack_trace;
extern uint test_flags,select_errors,ha_open_options;
extern uint protocol_version, mysqld_port, mysqld_extra_port, dropping_tables;
extern uint delay_key_write_options;
-extern ulong max_long_data_size;
+extern ulong max_long_data_size, max_used_connections;
#endif /* MYSQL_SERVER */
#if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
extern MYSQL_PLUGIN_IMPORT uint lower_case_table_names;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index c4ec0b741f0..9ca0080e976 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -116,9 +116,6 @@ extern "C" { // Because of SCO 3.2V4.2
#ifdef __WIN__
#include <crtdbg.h>
-#define SIGNAL_FMT "exception 0x%x"
-#else
-#define SIGNAL_FMT "signal %d"
#endif
#ifdef __NETWARE__
@@ -261,7 +258,7 @@ inline void setup_fpu()
extern "C" int gethostname(char *name, int namelen);
#endif
-extern "C" sig_handler handle_segfault(int sig);
+extern "C" sig_handler handle_fatal_signal(int sig);
#if defined(__linux__)
#define ENABLE_TEMP_POOL 1
@@ -413,6 +410,10 @@ TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
/* static variables */
+#ifdef HAVE_NPTL
+volatile sig_atomic_t ld_assume_kernel_is_set= 0;
+#endif
+
/* the default log output is log tables */
static bool lower_case_table_names_used= 0;
static bool max_long_data_size_used= false;
@@ -420,11 +421,11 @@ static bool volatile select_thread_in_use, signal_thread_in_use;
static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_short_log_format= 0;
-static my_bool opt_ignore_wrong_options= 0, opt_expect_abort= 0;
+static my_bool opt_ignore_wrong_options= 0;
static my_bool opt_sync= 0;
static uint kill_cached_threads, wake_thread;
ulong thread_created;
-static ulong max_used_connections;
+ulong max_used_connections;
static ulong my_bind_addr; /**< the address we bind to */
static volatile ulong cached_thread_count= 0;
static const char *sql_mode_str= "OFF";
@@ -559,7 +560,7 @@ TYPELIB binlog_format_typelib=
ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
#ifdef HAVE_INITGROUPS
-static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
+volatile sig_atomic_t calling_initgroups= 0; /**< Used in SIGSEGV handler. */
#endif
uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
uint mysqld_extra_port;
@@ -738,8 +739,12 @@ char *opt_logname, *opt_slow_logname;
/* Static variables */
-static bool kill_in_progress, segfaulted;
-static my_bool opt_stack_trace;
+static volatile sig_atomic_t kill_in_progress;
+#ifdef HAVE_STACKTRACE
+static my_bool opt_do_pstack;
+my_bool opt_stack_trace;
+#endif /* HAVE_STACKTRACE */
+my_bool opt_expect_abort= 0;
static my_bool opt_bootstrap, opt_myisam_log;
static int cleanup_done;
static ulong opt_specialflag, opt_myisam_block_size;
@@ -1677,9 +1682,9 @@ static void set_user(const char *user, struct passwd *user_info_arg)
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;
+ calling_initgroups= 1;
initgroups((char*) user, user_info_arg->pw_gid);
- calling_initgroups= FALSE;
+ calling_initgroups= 0;
#endif
if (setgid(user_info_arg->pw_gid) == -1)
{
@@ -2250,7 +2255,7 @@ LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
__try
{
my_set_exception_pointers(ex_pointers);
- handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
+ handle_fatal_signal(ex_pointers->ExceptionRecord->ExceptionCode);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
@@ -2560,176 +2565,6 @@ extern "C" char *my_demangle(const char *mangled_name, int *status)
}
#endif
-
-extern "C" sig_handler handle_segfault(int sig)
-{
- time_t curr_time;
- struct tm tm;
-#ifdef HAVE_STACKTRACE
- THD *thd=current_thd;
-#endif
-
- /*
- Strictly speaking, one needs a mutex here
- but since we have got SIGSEGV already, things are a mess
- so not having the mutex is not as bad as possibly using a buggy
- mutex - so we keep things simple
- */
- if (segfaulted)
- {
- fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
- exit(1);
- }
-
- segfaulted = 1;
-
- curr_time= my_time(0);
- localtime_r(&curr_time, &tm);
-
- fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d ",
- tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
- if (opt_expect_abort && sig == SIGABRT)
- {
- fprintf(stderr,"[Note] mysqld did an expected abort\n");
- goto end;
- }
-
- fprintf(stderr,"[ERROR] mysqld got " SIGNAL_FMT " ;\n\
-This could be because you hit a bug. It is also possible that this binary\n\
-or one of the libraries it was linked against is corrupt, improperly built,\n\
-or misconfigured. This error can also be caused by malfunctioning hardware.\n",
- sig);
- fprintf(stderr, "\
-We will try our best to scrape up some info that will hopefully help diagnose\n\
-the problem, but since we have already crashed, something is definitely wrong\n\
-and this may fail.\n\n");
- fprintf(stderr, "key_buffer_size=%lu\n",
- (ulong) dflt_key_cache->key_cache_mem_size);
- fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
- fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
- fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads +
- (uint) extra_max_connections);
- fprintf(stderr, "threads_connected=%u\n", thread_count);
- fprintf(stderr, "It is possible that mysqld could use up to \n\
-key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
-bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
- (global_system_variables.read_buff_size +
- global_system_variables.sortbuff_size) *
- (thread_scheduler.max_threads + extra_max_connections) +
- (max_connections + extra_max_connections)* sizeof(THD))
- / 1024);
- fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
-
-#if defined(HAVE_LINUXTHREADS)
- if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
- {
- fprintf(stderr, "\
-You seem to be running 32-bit Linux and have %d concurrent connections.\n\
-If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
-yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
-the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
- thread_count);
- }
-#endif /* HAVE_LINUXTHREADS */
-
-#ifdef HAVE_STACKTRACE
-
- if (opt_stack_trace)
- {
- fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
- fprintf(stderr, "Attempting backtrace. You can use the following "
- "information to find out\nwhere mysqld died. If "
- "you see no messages after this, something went\n"
- "terribly wrong...\n");
- my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
- my_thread_stack_size);
- }
- if (thd)
- {
- const char *kreason= "UNKNOWN";
- switch (thd->killed) {
- case THD::NOT_KILLED:
- kreason= "NOT_KILLED";
- break;
- case THD::KILL_BAD_DATA:
- kreason= "KILL_BAD_DATA";
- break;
- case THD::KILL_CONNECTION:
- kreason= "KILL_CONNECTION";
- break;
- case THD::KILL_QUERY:
- kreason= "KILL_QUERY";
- break;
- case THD::KILLED_NO_VALUE:
- kreason= "KILLED_NO_VALUE";
- break;
- }
- fprintf(stderr, "\nTrying to get some variables.\n"
- "Some pointers may be invalid and cause the dump to abort.\n");
- fprintf(stderr, "Query (%p): ", thd->query());
- my_safe_print_str(thd->query(), min(1024, thd->query_length()));
- fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
- fprintf(stderr, "Status: %s\n", kreason);
- fputc('\n', stderr);
- }
- fprintf(stderr, "\
-The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
-information that should help you find out what is causing the crash.\n");
- fflush(stderr);
-#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
-
-#ifdef HAVE_NPTL
- if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
- fprintf(stderr,"\n\
-You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
-This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
-You should either build a dynamically-linked binary, or force LinuxThreads\n\
-to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
-the documentation for your distribution on how to do that.\n");
-#endif
-
- if (locked_in_memory)
- {
- fprintf(stderr, "\n\
-The \"--memlock\" argument, which was enabled, uses system calls that are\n\
-unreliable and unstable on some operating systems and operating-system\n\
-versions (notably, some versions of Linux). This crash could be due to use\n\
-of those buggy OS calls. You should consider whether you really need the\n\
-\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
-bugs.\n");
- }
-
-#ifdef HAVE_WRITE_CORE
- if (test_flags & TEST_CORE_ON_SIGNAL)
- {
- fprintf(stderr, "Writing a core file\n");
- fflush(stderr);
- my_write_core(sig);
- }
-#endif
-
-end:
-#ifndef __WIN__
- /* Terminate */
- exit(1);
-#else
- /* On Windows, do not terminate, but pass control to exception filter */
- ;
-#endif
-}
-
#if !defined(__WIN__) && !defined(__NETWARE__)
#ifndef SA_RESETHAND
#define SA_RESETHAND 0
@@ -2758,9 +2593,9 @@ static void init_signals(void)
my_init_stacktrace();
#endif
#if defined(__amiga__)
- sa.sa_handler=(void(*)())handle_segfault;
+ sa.sa_handler=(void(*)())handle_fatal_signal;
#else
- sa.sa_handler=handle_segfault;
+ sa.sa_handler=handle_fatal_signal;
#endif
sigaction(SIGSEGV, &sa, NULL);
sigaction(SIGABRT, &sa, NULL);
@@ -4509,6 +4344,10 @@ int win_main(int argc, char **argv)
int main(int argc, char **argv)
#endif
{
+#ifdef HAVE_NPTL
+ ld_assume_kernel_is_set= (getenv("LD_ASSUME_KERNEL") != 0);
+#endif
+
MY_INIT(argv[0]); // init my_sys library & pthreads
/* nothing should come before this line ^^^ */
@@ -8165,7 +8004,7 @@ static int mysql_init_variables(void)
opt_secure_file_priv= 0;
opt_bootstrap= opt_myisam_log= 0;
mqh_used= 0;
- segfaulted= kill_in_progress= 0;
+ kill_in_progress= 0;
cleanup_done= 0;
defaults_argc= 0;
defaults_argv= 0;
diff --git a/sql/signal_handler.cc b/sql/signal_handler.cc
new file mode 100644
index 00000000000..23d898fdb5e
--- /dev/null
+++ b/sql/signal_handler.cc
@@ -0,0 +1,256 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates.
+ Copyright (c) 2011, Monty Program Ab.
+
+ 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
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA */
+
+#include "my_global.h"
+#include <signal.h>
+
+#include "mysql_priv.h"
+#include "my_stacktrace.h"
+
+#ifdef __WIN__
+#include <crtdbg.h>
+#define SIGNAL_FMT "exception 0x%x"
+#else
+#define SIGNAL_FMT "signal %d"
+#endif
+
+/*
+ We are handling signals in this file.
+ Any global variables we read should be 'volatile sig_atomic_t'
+ to guarantee that we read some consistent value.
+ */
+static volatile sig_atomic_t segfaulted= 0;
+extern ulong max_used_connections;
+extern volatile sig_atomic_t calling_initgroups;
+#ifdef HAVE_NPTL
+extern volatile sig_atomic_t ld_assume_kernel_is_set;
+#endif
+
+/**
+ * Handler for fatal signals
+ *
+ * Fatal events (seg.fault, bus error etc.) will trigger
+ * this signal handler. The handler will try to dump relevant
+ * debugging information to stderr and dump a core image.
+ *
+ * Signal handlers can only use a set of 'safe' system calls
+ * and library functions. A list of safe calls in POSIX systems
+ * are available at:
+ * http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html
+ * For MS Windows, guidelines are available at:
+ * http://msdn.microsoft.com/en-us/library/xdkz3x12(v=vs.71).aspx
+ *
+ * @param sig Signal number
+*/
+extern "C" sig_handler handle_fatal_signal(int sig)
+{
+ time_t curr_time;
+ struct tm tm;
+#ifdef HAVE_STACKTRACE
+ THD *thd;
+#endif
+
+ if (segfaulted)
+ {
+ my_safe_printf_stderr("Fatal " SIGNAL_FMT " while backtracing\n", sig);
+ _exit(1); /* Quit without running destructors */
+ }
+
+ segfaulted = 1;
+
+ curr_time= my_time(0);
+ localtime_r(&curr_time, &tm);
+
+ my_safe_printf_stderr("%02d%02d%02d %2d:%02d:%02d ",
+ tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+ if (opt_expect_abort && sig == SIGABRT)
+ {
+ fprintf(stderr,"[Note] mysqld did an expected abort\n");
+ goto end;
+ }
+
+ my_safe_printf_stderr("[ERROR] mysqld got " SIGNAL_FMT " ;\n",sig);
+
+ my_safe_printf_stderr("%s",
+ "This could be because you hit a bug. It is also possible that this binary\n"
+ "or one of the libraries it was linked against is corrupt, improperly built,\n"
+ "or misconfigured. This error can also be caused by malfunctioning hardware.\n");
+
+ my_safe_printf_stderr("%s",
+ "To report this bug, see http://kb.askmonty.org/en/reporting-bugs\n");
+
+ my_safe_printf_stderr("%s",
+ "We will try our best to scrape up some info that will hopefully help\n"
+ "diagnose the problem, but since we have already crashed, \n"
+ "something is definitely wrong and this may fail.\n\n");
+
+ my_safe_printf_stderr("key_buffer_size=%lu\n",
+ (ulong) dflt_key_cache->key_cache_mem_size);
+
+ my_safe_printf_stderr("read_buffer_size=%ld\n",
+ (long) global_system_variables.read_buff_size);
+
+ my_safe_printf_stderr("max_used_connections=%lu\n",
+ (ulong) max_used_connections);
+
+ my_safe_printf_stderr("max_threads=%u\n",
+ (uint) thread_scheduler.max_threads);
+
+ my_safe_printf_stderr("thread_count=%u\n", (uint) thread_count);
+
+ my_safe_printf_stderr("connection_count=%u\n", (uint) connection_count);
+
+ my_safe_printf_stderr("It is possible that mysqld could use up to \n"
+ "key_buffer_size + "
+ "(read_buffer_size + sort_buffer_size)*max_threads = "
+ "%lu K bytes of memory\n",
+ ((ulong) dflt_key_cache->key_cache_mem_size +
+ (global_system_variables.read_buff_size +
+ global_system_variables.sortbuff_size) *
+ thread_scheduler.max_threads +
+ max_connections * sizeof(THD)) / 1024);
+
+ my_safe_printf_stderr("%s",
+ "Hope that's ok; if not, decrease some variables in the equation.\n\n");
+
+#if defined(HAVE_LINUXTHREADS)
+ if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
+ {
+ my_safe_printf_stderr(
+ "You seem to be running 32-bit Linux and have "
+ "%d concurrent connections.\n"
+ "If you have not changed STACK_SIZE in LinuxThreads "
+ "and built the binary \n"
+ "yourself, LinuxThreads is quite likely to steal "
+ "a part of the global heap for\n"
+ "the thread stack. Please read "
+ "http://dev.mysql.com/doc/mysql/en/linux-installation.html\n\n"
+ thread_count);
+ }
+#endif /* HAVE_LINUXTHREADS */
+
+#ifdef HAVE_STACKTRACE
+ thd= current_thd;
+
+ if (opt_stack_trace)
+ {
+ my_safe_printf_stderr("Thread pointer: 0x%p\n", thd);
+ my_safe_printf_stderr("%s",
+ "Attempting backtrace. You can use the following "
+ "information to find out\n"
+ "where mysqld died. If you see no messages after this, something went\n"
+ "terribly wrong...\n");
+ my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
+ my_thread_stack_size);
+ }
+ if (thd)
+ {
+ const char *kreason= "UNKNOWN";
+ switch (thd->killed) {
+ case THD::NOT_KILLED:
+ kreason= "NOT_KILLED";
+ break;
+ case THD::KILL_BAD_DATA:
+ kreason= "KILL_BAD_DATA";
+ break;
+ case THD::KILL_CONNECTION:
+ kreason= "KILL_CONNECTION";
+ break;
+ case THD::KILL_QUERY:
+ kreason= "KILL_QUERY";
+ break;
+ case THD::KILLED_NO_VALUE:
+ kreason= "KILLED_NO_VALUE";
+ break;
+ }
+ my_safe_printf_stderr("%s", "\n"
+ "Trying to get some variables.\n"
+ "Some pointers may be invalid and cause the dump to abort.\n");
+
+ my_safe_printf_stderr("Query (%p): ", thd->query());
+ my_safe_print_str(thd->query(), min(1024U, thd->query_length()));
+ my_safe_printf_stderr("Connection ID (thread ID): %lu\n",
+ (ulong) thd->thread_id);
+ my_safe_printf_stderr("Status: %s\n\n", kreason);
+ }
+ my_safe_printf_stderr("%s",
+ "The manual page at "
+ "http://dev.mysql.com/doc/mysql/en/crashing.html contains\n"
+ "information that should help you find out what is causing the crash.\n");
+
+#endif /* HAVE_STACKTRACE */
+
+#ifdef HAVE_INITGROUPS
+ if (calling_initgroups)
+ {
+ my_safe_printf_stderr("%s", "\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 \n"
+ "glibc and configured to use LDAP in /etc/nsswitch.conf.\n"
+ "You will need to either upgrade to a version of glibc that does not\n"
+ "have this problem (2.3.4 or later when used with nscd),\n"
+ "disable LDAP in your nsswitch.conf, or use a "
+ "mysqld that is not statically linked.\n");
+ }
+#endif
+
+#ifdef HAVE_NPTL
+ if (thd_lib_detected == THD_LIB_LT && !ld_assume_kernel_is_set)
+ {
+ my_safe_printf_stderr("%s",
+ "You are running a statically-linked LinuxThreads binary on an NPTL\n"
+ "system. This can result in crashes on some distributions due to "
+ "LT/NPTL conflicts.\n"
+ "You should either build a dynamically-linked binary, "
+ "or force LinuxThreads\n"
+ "to be used with the LD_ASSUME_KERNEL environment variable.\n"
+ "Please consult the documentation for your distribution "
+ "on how to do that.\n");
+ }
+#endif
+
+ if (locked_in_memory)
+ {
+ my_safe_printf_stderr("%s", "\n"
+ "The \"--memlock\" argument, which was enabled, "
+ "uses system calls that are\n"
+ "unreliable and unstable on some operating systems and "
+ "operating-system versions (notably, some versions of Linux).\n"
+ "This crash could be due to use of those buggy OS calls.\n"
+ "You should consider whether you really need the "
+ "\"--memlock\" parameter and/or consult the OS distributer about "
+ "\"mlockall\" bugs.\n");
+ }
+
+#ifdef HAVE_WRITE_CORE
+ if (test_flags & TEST_CORE_ON_SIGNAL)
+ {
+ my_safe_printf_stderr("%s", "Writing a core file\n");
+ fflush(stderr);
+ my_write_core(sig);
+ }
+#endif
+
+end:
+#ifndef __WIN__
+ /*
+ Quit, without running destructors (etc.)
+ On Windows, do not terminate, but pass control to exception filter.
+ */
+ _exit(1); // Using _exit(), since exit() is not async signal safe
+#endif
+}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 465404d32d2..9ee834bd0d0 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -5199,6 +5199,11 @@ bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
DBUG_RETURN(TRUE);
}
pthread_mutex_unlock(&LOCK_global_system_variables);
+ if (!key_cache->key_cache_inited)
+ {
+ my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
+ DBUG_RETURN(TRUE);
+ }
check_opt.key_cache= key_cache;
DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
"assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index ec26ef65321..618fc1ea7f3 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -772,6 +772,7 @@ uint32 ha_archive::max_row_length(const uchar *buf)
ptr != end ;
ptr++)
{
+ if (!table->field[*ptr]->is_null())
length += 2 + ((Field_blob*)table->field[*ptr])->get_length();
}
@@ -1599,13 +1600,15 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
{
int rc= 0;
const char *old_proc_info;
- ha_rows count= share->rows_recorded;
+ ha_rows count;
DBUG_ENTER("ha_archive::check");
old_proc_info= thd_proc_info(thd, "Checking table");
- /* Flush any waiting data */
pthread_mutex_lock(&share->mutex);
- azflush(&(share->archive_write), Z_SYNC_FLUSH);
+ count= share->rows_recorded;
+ /* Flush any waiting data */
+ if (share->archive_write_open)
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
pthread_mutex_unlock(&share->mutex);
if (init_archive_reader())
@@ -1615,18 +1618,34 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
start of the file.
*/
read_data_header(&archive);
+ for (ha_rows cur_count= count; cur_count; cur_count--)
+ {
+ if ((rc= get_row(&archive, table->record[0])))
+ goto error;
+ }
+ /*
+ Now read records that may have been inserted concurrently.
+ Acquire share->mutex so tail of the table is not modified by
+ concurrent writers.
+ */
+ pthread_mutex_lock(&share->mutex);
+ count= share->rows_recorded - count;
+ if (share->archive_write_open)
+ azflush(&(share->archive_write), Z_SYNC_FLUSH);
while (!(rc= get_row(&archive, table->record[0])))
count--;
-
- thd_proc_info(thd, old_proc_info);
+ pthread_mutex_unlock(&share->mutex);
if ((rc && rc != HA_ERR_END_OF_FILE) || count)
- {
- share->crashed= FALSE;
- DBUG_RETURN(HA_ADMIN_CORRUPT);
- }
+ goto error;
+ thd_proc_info(thd, old_proc_info);
DBUG_RETURN(HA_ADMIN_OK);
+
+error:
+ thd_proc_info(thd, old_proc_info);
+ share->crashed= FALSE;
+ DBUG_RETURN(HA_ADMIN_CORRUPT);
}
/*
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 6709f790994..a4d79a5934e 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4802,7 +4802,6 @@ ha_innobase::innobase_get_index(
dict_index_t* index = 0;
DBUG_ENTER("innobase_get_index");
- ha_statistic_increment(&SSV::ha_read_key_count);
ut_ad(user_thd == ha_thd());
ut_a(prebuilt->trx == thd_to_trx(user_thd));
diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog
index 951a1bd9c3b..d836b390c52 100644
--- a/storage/innodb_plugin/ChangeLog
+++ b/storage/innodb_plugin/ChangeLog
@@ -1,3 +1,14 @@
+2011-12-13 The InnoDB Team
+
+ * handler/ha_innodb.cc, innodb.test, innodb.result:
+ Fix Bug#13117023: InnoDB was incrementing the handler_read_key,
+ also the SSV::ha_read_key_count, at the wrong place.
+
+2011-12-10 The InnoDB Team
+
+ * include/page0page.h, page/page0page.c:
+ Fix Bug#13418887 ERROR IN DIAGNOSTIC FUNCTION PAGE_REC_PRINT()
+
2011-11-10 The InnoDB Team
* handler/ha_innodb.cc, row/row0ins.c, innodb_replace.test:
@@ -13,7 +24,12 @@
2011-10-27 The InnoDB Team
* row/row0mysql.c:
- Fix Bug#12884631 62146: TABLES ARE LOST FOR DDL
+ Fix Bug #12884631 62146: TABLES ARE LOST FOR DDL
+
+2011-10-25 The InnoDB Team
+
+ * handler/ha_innodb.cc, row/row0ins.c:
+ Fix Bug#13002783 PARTIALLY UNINITIALIZED CASCADE UPDATE VECTOR
2011-10-20 The InnoDB Team
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index 848c1b5c733..bb47bd24867 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -5520,7 +5520,6 @@ ha_innobase::innobase_get_index(
dict_index_t* index = 0;
DBUG_ENTER("innobase_get_index");
- ha_statistic_increment(&SSV::ha_read_key_count);
if (keynr != MAX_KEY && table->s->keys > 0) {
key = table->key_info + keynr;
diff --git a/storage/innodb_plugin/include/page0page.h b/storage/innodb_plugin/include/page0page.h
index 12c4fed75d2..ea9c212581c 100644
--- a/storage/innodb_plugin/include/page0page.h
+++ b/storage/innodb_plugin/include/page0page.h
@@ -892,6 +892,7 @@ page_parse_create(
ulint comp, /*!< in: nonzero=compact page format */
buf_block_t* block, /*!< in: block or NULL */
mtr_t* mtr); /*!< in: mtr or NULL */
+#ifndef UNIV_HOTBACKUP
/************************************************************//**
Prints record contents including the data relevant only in
the index page context. */
@@ -901,6 +902,7 @@ page_rec_print(
/*===========*/
const rec_t* rec, /*!< in: physical record */
const ulint* offsets);/*!< in: record descriptor */
+# ifdef UNIV_BTR_PRINT
/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
@@ -940,6 +942,8 @@ page_print(
in directory */
ulint rn); /*!< in: print rn first and last records
in directory */
+# endif /* UNIV_BTR_PRINT */
+#endif /* !UNIV_HOTBACKUP */
/***************************************************************//**
The following is used to validate a record on a page. This function
differs from rec_validate as it can also check the n_owned field and
diff --git a/storage/innodb_plugin/page/page0page.c b/storage/innodb_plugin/page/page0page.c
index 93869e997b5..52f6678be0a 100644
--- a/storage/innodb_plugin/page/page0page.c
+++ b/storage/innodb_plugin/page/page0page.c
@@ -1613,13 +1613,14 @@ page_rec_print(
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
(ulong) rec_get_n_owned_old(rec),
(ulong) rec_get_heap_no_old(rec),
- (ulong) rec_get_next_offs(rec, TRUE));
+ (ulong) rec_get_next_offs(rec, FALSE));
}
page_rec_check(rec);
rec_validate(rec, offsets);
}
+# ifdef UNIV_BTR_PRINT
/***************************************************************//**
This is used to print the contents of the directory for
debugging purposes. */
@@ -1780,6 +1781,7 @@ page_print(
page_dir_print(page, dn);
page_print_list(block, index, rn);
}
+# endif /* UNIV_BTR_PRINT */
#endif /* !UNIV_HOTBACKUP */
/***************************************************************//**
diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c
index d3888417fbd..56e66cccf7d 100644
--- a/storage/myisam/mi_close.c
+++ b/storage/myisam/mi_close.c
@@ -89,7 +89,12 @@ int mi_close(register MI_INFO *info)
}
#ifdef HAVE_MMAP
if (share->file_map)
- _mi_unmap_file(info);
+ {
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ _mi_unmap_file(info);
+ else
+ mi_munmap_file(info);
+ }
#endif
if (share->decode_trees)
{
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index 7b90ba8276b..dde3817c5e2 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -1554,13 +1554,14 @@ my_bool _mi_memmap_file(MI_INFO *info)
void _mi_unmap_file(MI_INFO *info)
{
- VOID(my_munmap((char*) info->s->file_map,
- (size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
+ DBUG_ASSERT(info->s->options & HA_OPTION_COMPRESS_RECORD);
+
+ VOID(my_munmap((char*) info->s->file_map, (size_t) info->s->mmaped_length));
if (myisam_mmap_size != SIZE_T_MAX)
{
pthread_mutex_lock(&THR_LOCK_myisam_mmap);
- myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN;
+ myisam_mmap_used-= info->s->mmaped_length;
pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
}
}
diff --git a/storage/myisam/mi_preload.c b/storage/myisam/mi_preload.c
index cb8d2984921..b5594f63d47 100644
--- a/storage/myisam/mi_preload.c
+++ b/storage/myisam/mi_preload.c
@@ -56,6 +56,9 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
if (!keys || !mi_is_any_key_active(key_map) || key_file_length == pos)
DBUG_RETURN(0);
+ /* Preload into a non initialized key cache should never happen. */
+ DBUG_ASSERT(share->key_cache->key_cache_inited);
+
block_length= keyinfo[0].block_length;
if (ignore_leaves)
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 536871fb9ab..34e25b59ac4 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5947,7 +5947,6 @@ ha_innobase::innobase_get_index(
dict_index_t* index = 0;
DBUG_ENTER("innobase_get_index");
- ha_statistic_increment(&SSV::ha_read_key_count);
if (keynr != MAX_KEY && table->s->keys > 0) {
key = table->key_info + keynr;
diff --git a/storage/xtradb/page/page0page.c b/storage/xtradb/page/page0page.c
index a284b1480a3..6243029019d 100644
--- a/storage/xtradb/page/page0page.c
+++ b/storage/xtradb/page/page0page.c
@@ -1625,7 +1625,7 @@ page_rec_print(
" n_owned: %lu; heap_no: %lu; next rec: %lu\n",
(ulong) rec_get_n_owned_old(rec),
(ulong) rec_get_heap_no_old(rec),
- (ulong) rec_get_next_offs(rec, TRUE));
+ (ulong) rec_get_next_offs(rec, FALSE));
}
page_rec_check(rec);