Commit 4d57b851 authored by Ingo Struewing's avatar Ingo Struewing

WL#4259 - Debug Sync Facility

Backport from 6.0 to 5.1.
Only those sync points are included, which are used in debug_sync.test.

  The Debug Sync Facility allows to place synchronization points
  in the code:
  
  open_tables(...)
  
  DEBUG_SYNC(thd, "after_open_tables");
  
  lock_tables(...)
  
  When activated, a sync point can
  
  - Send a signal and/or
  - Wait for a signal
  
  Nomenclature:
  
  - signal:            A value of a global variable that persists
                       until overwritten by a new signal. The global
                       variable can also be seen as a "signal post"
                       or "flag mast". Then the signal is what is
                       attached to the "signal post" or "flag mast".
  
  - send a signal:     Assign the value (the signal) to the global
                       variable ("set a flag") and broadcast a
                       global condition to wake those waiting for
                       a signal.
  
  - wait for a signal: Loop over waiting for the global condition until
                       the global value matches the wait-for signal.
  
  Please find more information in the top comment in debug_sync.cc
  or in the worklog entry.


.bzrignore:
  WL#4259 - Debug Sync Facility
  Added the symbolic link libmysqld/debug_sync.cc.
CMakeLists.txt:
  WL#4259 - Debug Sync Facility
  Added definition for ENABLED_DEBUG_SYNC.
configure.in:
  WL#4259 - Debug Sync Facility
  Added definition for ENABLED_DEBUG_SYNC.
include/my_sys.h:
  WL#4259 - Debug Sync Facility
  Added definition for the DEBUG_SYNC_C macro.
libmysqld/CMakeLists.txt:
  WL#4259 - Debug Sync Facility
  Added sql/debug_sync.cc.
libmysqld/Makefile.am:
  WL#4259 - Debug Sync Facility
  Added sql/debug_sync.cc.
mysql-test/include/have_debug_sync.inc:
  WL#4259 - Debug Sync Facility
  New include file.
mysql-test/mysql-test-run.pl:
  WL#4259 - Debug Sync Facility
  Added option --debug_sync_timeout.
mysql-test/r/debug_sync.result:
  WL#4259 - Debug Sync Facility
  New test result.
mysql-test/r/have_debug_sync.require:
  WL#4259 - Debug Sync Facility
  New require file.
mysql-test/t/debug_sync.test:
  WL#4259 - Debug Sync Facility
  New test file.
mysys/my_static.c:
  WL#4259 - Debug Sync Facility
  Added definition for debug_sync_C_callback_ptr.
mysys/thr_lock.c:
  WL#4259 - Debug Sync Facility
  Added sync point "wait_for_lock".
sql/CMakeLists.txt:
  WL#4259 - Debug Sync Facility
  Added debug_sync.cc and debug_sync.h.
sql/Makefile.am:
  WL#4259 - Debug Sync Facility
  Added debug_sync.cc and debug_sync.h.
sql/debug_sync.cc:
  WL#4259 - Debug Sync Facility
  New source file.
sql/debug_sync.h:
  WL#4259 - Debug Sync Facility
  New header file.
sql/mysqld.cc:
  WL#4259 - Debug Sync Facility
  Added opt_debug_sync_timeout.
  Added calls to debug_sync_init() and debug_sync_end().
  Fixed a purecov comment (unrelated).
sql/set_var.cc:
  WL#4259 - Debug Sync Facility
  Added server variable "debug_sync".
sql/set_var.h:
  WL#4259 - Debug Sync Facility
  Added declaration for server variable "debug_sync".
sql/share/errmsg.txt:
  WL#4259 - Debug Sync Facility
  Added error messages ER_DEBUG_SYNC_TIMEOUT and ER_DEBUG_SYNC_HIT_LIMIT.
sql/sql_base.cc:
  WL#4259 - Debug Sync Facility
  Added sync points "after_flush_unlock" and "before_lock_tables_takes_lock".
sql/sql_class.cc:
  WL#4259 - Debug Sync Facility
  Added initialization for debug_sync_control to THD::THD.
  Added calls to debug_sync_init_thread() and debug_sync_end_thread().
sql/sql_class.h:
  WL#4259 - Debug Sync Facility
  Added element debug_sync_control to THD.
storage/myisam/myisamchk.c:
  Fixed a typo in an error message string (unrelated).
parent 6a89842e
...@@ -3064,3 +3064,4 @@ sql/share/spanish ...@@ -3064,3 +3064,4 @@ sql/share/spanish
sql/share/swedish sql/share/swedish
sql/share/ukrainian sql/share/ukrainian
libmysqld/examples/mysqltest.cc libmysqld/examples/mysqltest.cc
libmysqld/debug_sync.cc
...@@ -66,6 +66,12 @@ IF(EXTRA_DEBUG) ...@@ -66,6 +66,12 @@ IF(EXTRA_DEBUG)
ADD_DEFINITIONS(-D EXTRA_DEBUG) ADD_DEFINITIONS(-D EXTRA_DEBUG)
ENDIF(EXTRA_DEBUG) ENDIF(EXTRA_DEBUG)
IF(ENABLED_DEBUG_SYNC)
ADD_DEFINITIONS(-D ENABLED_DEBUG_SYNC)
ENDIF(ENABLED_DEBUG_SYNC)
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DENABLED_DEBUG_SYNC")
# in some places we use DBUG_OFF # in some places we use DBUG_OFF
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF") SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DDBUG_OFF")
SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF") SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DDBUG_OFF")
......
...@@ -1708,6 +1708,23 @@ else ...@@ -1708,6 +1708,23 @@ else
CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS" CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS"
fi fi
# Debug Sync Facility. NOTE: depends on 'with_debug'. Must be behind it.
AC_MSG_CHECKING(if Debug Sync Facility should be enabled.)
AC_ARG_ENABLE(debug_sync,
AS_HELP_STRING([--enable-debug-sync],
[Build a version with Debug Sync Facility]),
[ enable_debug_sync=$enableval ],
[ enable_debug_sync=$with_debug ])
if test "$enable_debug_sync" != "no"
then
AC_DEFINE([ENABLED_DEBUG_SYNC], [1],
[If Debug Sync Facility should be enabled])
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
# If we should allow error injection tests # If we should allow error injection tests
AC_ARG_WITH(error-inject, AC_ARG_WITH(error-inject,
AC_HELP_STRING([--with-error-inject],[Enable error injection in MySQL Server]), AC_HELP_STRING([--with-error-inject],[Enable error injection in MySQL Server]),
......
...@@ -172,6 +172,16 @@ extern char *my_strndup(const char *from, size_t length, ...@@ -172,6 +172,16 @@ extern char *my_strndup(const char *from, size_t length,
#define TRASH(A,B) /* nothing */ #define TRASH(A,B) /* nothing */
#endif #endif
#if defined(ENABLED_DEBUG_SYNC)
extern void (*debug_sync_C_callback_ptr)(const char *, size_t);
#define DEBUG_SYNC_C(_sync_point_name_) do { \
if (debug_sync_C_callback_ptr != NULL) \
(*debug_sync_C_callback_ptr)(STRING_WITH_LEN(_sync_point_name_)); } \
while(0)
#else
#define DEBUG_SYNC_C(_sync_point_name_)
#endif /* defined(ENABLED_DEBUG_SYNC) */
#ifdef HAVE_LARGE_PAGES #ifdef HAVE_LARGE_PAGES
extern uint my_get_large_page_size(void); extern uint my_get_large_page_size(void);
extern uchar * my_large_malloc(size_t size, myf my_flags); extern uchar * my_large_malloc(size_t size, myf my_flags);
......
...@@ -129,6 +129,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ...@@ -129,6 +129,7 @@ SET(LIBMYSQLD_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc
../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc ../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc
../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc ../sql/sql_binlog.cc ../sql/sql_manager.cc ../sql/sql_map.cc
../sql/sql_parse.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc ../sql/sql_parse.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc
../sql/debug_sync.cc
../sql/sql_prepare.cc ../sql/sql_rename.cc ../sql/sql_repl.cc ../sql/sql_prepare.cc ../sql/sql_rename.cc ../sql/sql_repl.cc
../sql/sql_select.cc ../sql/sql_servers.cc ../sql/sql_select.cc ../sql/sql_servers.cc
../sql/sql_show.cc ../sql/sql_state.c ../sql/sql_string.cc ../sql/sql_show.cc ../sql/sql_state.c ../sql/sql_string.cc
......
...@@ -74,6 +74,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \ ...@@ -74,6 +74,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
debug_sync.cc \
sql_tablespace.cc \ sql_tablespace.cc \
rpl_injector.cc my_user.c partition_info.cc \ rpl_injector.cc my_user.c partition_info.cc \
sql_servers.cc event_parse_data.cc sql_servers.cc event_parse_data.cc
......
--require r/have_debug_sync.require
disable_query_log;
let $value= query_get_value(SHOW VARIABLES LIKE 'debug_sync', Value, 1);
eval SELECT ('$value' LIKE 'ON %') AS debug_sync;
enable_query_log;
...@@ -226,6 +226,7 @@ my @default_valgrind_args= ("--show-reachable=yes"); ...@@ -226,6 +226,7 @@ my @default_valgrind_args= ("--show-reachable=yes");
my @valgrind_args; my @valgrind_args;
my $opt_valgrind_path; my $opt_valgrind_path;
my $opt_callgrind; my $opt_callgrind;
my $opt_debug_sync_timeout= 300; # Default timeout for WAIT_FOR actions.
our $opt_warnings= 1; our $opt_warnings= 1;
...@@ -867,6 +868,7 @@ sub command_line_setup { ...@@ -867,6 +868,7 @@ sub command_line_setup {
'valgrind-option=s' => \@valgrind_args, 'valgrind-option=s' => \@valgrind_args,
'valgrind-path=s' => \$opt_valgrind_path, 'valgrind-path=s' => \$opt_valgrind_path,
'callgrind' => \$opt_callgrind, 'callgrind' => \$opt_callgrind,
'debug-sync-timeout=i' => \$opt_debug_sync_timeout,
# Directories # Directories
'tmpdir=s' => \$opt_tmpdir, 'tmpdir=s' => \$opt_tmpdir,
...@@ -4170,6 +4172,11 @@ sub mysqld_arguments ($$$) { ...@@ -4170,6 +4172,11 @@ sub mysqld_arguments ($$$) {
mtr_add_arg($args, "%s", "--core-file"); mtr_add_arg($args, "%s", "--core-file");
} }
# Enable the debug sync facility, set default wait timeout.
# Facility stays disabled if timeout value is zero.
mtr_add_arg($args, "--loose-debug-sync-timeout=%s",
$opt_debug_sync_timeout);
return $args; return $args;
} }
...@@ -5280,6 +5287,8 @@ Misc options ...@@ -5280,6 +5287,8 @@ Misc options
to turn off. to turn off.
sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time sleep=SECONDS Passed to mysqltest, will be used as fixed sleep time
debug-sync-timeout=NUM Set default timeout for WAIT_FOR debug sync
actions. Disable facility with NUM=0.
gcov Collect coverage information after the test. gcov Collect coverage information after the test.
The result is a gcov file per source and header file. The result is a gcov file per source and header file.
experimental=<file> Refer to list of tests considered experimental; experimental=<file> Refer to list of tests considered experimental;
......
This diff is collapsed.
This diff is collapsed.
...@@ -92,6 +92,14 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)= ...@@ -92,6 +92,14 @@ int (*error_handler_hook)(uint error,const char *str,myf MyFlags)=
int (*fatal_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; my_message_no_curses;
#if defined(ENABLED_DEBUG_SYNC)
/**
Global pointer to be set if callback function is defined
(e.g. in mysqld). See sql/debug_sync.cc.
*/
void (*debug_sync_C_callback_ptr)(const char *, size_t);
#endif /* defined(ENABLED_DEBUG_SYNC) */
#ifdef __WIN__ #ifdef __WIN__
/* from my_getsystime.c */ /* from my_getsystime.c */
ulonglong query_performance_frequency, query_performance_offset; ulonglong query_performance_frequency, query_performance_offset;
......
...@@ -398,6 +398,28 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, ...@@ -398,6 +398,28 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
my_bool can_deadlock= test(data->owner->info->n_cursors); my_bool can_deadlock= test(data->owner->info->n_cursors);
DBUG_ENTER("wait_for_lock"); DBUG_ENTER("wait_for_lock");
/*
One can use this to signal when a thread is going to wait for a lock.
See debug_sync.cc.
Beware of waiting for a signal here. The lock has aquired its mutex.
While waiting on a signal here, the locking thread could not aquire
the mutex to release the lock. One could lock up the table
completely.
In detail it works so: When thr_lock() tries to acquire a table
lock, it locks the lock->mutex, checks if it can have the lock, and
if not, it calls wait_for_lock(). Here it unlocks the table lock
while waiting on a condition. The sync point is located before this
wait for condition. If we have a waiting action here, we hold the
the table locks mutex all the time. Any attempt to look at the table
lock by another thread blocks it immediately on lock->mutex. This
can easily become an unexpected and unobvious blockage. So be
warned: Do not request a WAIT_FOR action for the 'wait_for_lock'
sync point unless you really know what you do.
*/
DEBUG_SYNC_C("wait_for_lock");
if (!in_wait_list) if (!in_wait_list)
{ {
(*wait->last)=data; /* Wait for lock */ (*wait->last)=data; /* Wait for lock */
......
...@@ -64,6 +64,7 @@ SET (SQL_SOURCE ...@@ -64,6 +64,7 @@ SET (SQL_SOURCE
sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc sql_error.cc sql_handler.cc sql_help.cc sql_insert.cc sql_lex.cc
sql_list.cc sql_load.cc sql_manager.cc sql_map.cc sql_parse.cc 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 sql_partition.cc sql_plugin.cc sql_prepare.cc sql_rename.cc
debug_sync.cc debug_sync.h
sql_repl.cc sql_select.cc sql_show.cc sql_state.c sql_string.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_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 sql_update.cc sql_view.cc strfunc.cc table.cc thr_malloc.cc
......
...@@ -58,6 +58,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ...@@ -58,6 +58,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
ha_ndbcluster.h ha_ndbcluster_cond.h \ ha_ndbcluster.h ha_ndbcluster_cond.h \
ha_ndbcluster_binlog.h ha_ndbcluster_tables.h \ ha_ndbcluster_binlog.h ha_ndbcluster_tables.h \
ha_partition.h rpl_constants.h \ ha_partition.h rpl_constants.h \
debug_sync.h \
opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \ opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
rpl_reporting.h \ rpl_reporting.h \
log.h sql_show.h rpl_rli.h rpl_mi.h \ log.h sql_show.h rpl_rli.h rpl_mi.h \
...@@ -102,6 +103,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ ...@@ -102,6 +103,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \
discover.cc time.cc opt_range.cc opt_sum.cc \ discover.cc time.cc opt_range.cc opt_sum.cc \
records.cc filesort.cc handler.cc \ records.cc filesort.cc handler.cc \
ha_partition.cc \ ha_partition.cc \
debug_sync.cc \
sql_db.cc sql_table.cc sql_rename.cc sql_crypt.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_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
......
This diff is collapsed.
#ifndef DEBUG_SYNC_INCLUDED
#define DEBUG_SYNC_INCLUDED
/* Copyright (C) 2008 Sun Microsystems, Inc.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/**
@file
Declarations for the Debug Sync Facility. See debug_sync.cc for details.
*/
#ifdef USE_PRAGMA_INTERFACE
#pragma interface /* gcc class implementation */
#endif
#include <my_global.h>
class THD;
#if defined(ENABLED_DEBUG_SYNC)
/* Macro to be put in the code at synchronization points. */
#define DEBUG_SYNC(_thd_, _sync_point_name_) \
do { if (unlikely(opt_debug_sync_timeout)) \
debug_sync(_thd_, STRING_WITH_LEN(_sync_point_name_)); \
} while (0)
/* Command line option --debug-sync-timeout. See mysqld.cc. */
extern uint opt_debug_sync_timeout;
/* Default WAIT_FOR timeout if command line option is given without argument. */
#define DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT 300
/* Debug Sync prototypes. See debug_sync.cc. */
extern int debug_sync_init(void);
extern void debug_sync_end(void);
extern void debug_sync_init_thread(THD *thd);
extern void debug_sync_end_thread(THD *thd);
extern void debug_sync(THD *thd, const char *sync_point_name, size_t name_len);
#else /* defined(ENABLED_DEBUG_SYNC) */
#define DEBUG_SYNC(_thd_, _sync_point_name_) /* disabled DEBUG_SYNC */
#endif /* defined(ENABLED_DEBUG_SYNC) */
#endif /* DEBUG_SYNC_INCLUDED */
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#include "mysqld_suffix.h" #include "mysqld_suffix.h"
#include "mysys_err.h" #include "mysys_err.h"
#include "events.h" #include "events.h"
#include "debug_sync.h"
#include "../storage/myisam/ha_myisam.h" #include "../storage/myisam/ha_myisam.h"
...@@ -486,6 +487,9 @@ my_bool lower_case_file_system= 0; ...@@ -486,6 +487,9 @@ my_bool lower_case_file_system= 0;
my_bool opt_large_pages= 0; my_bool opt_large_pages= 0;
my_bool opt_myisam_use_mmap= 0; my_bool opt_myisam_use_mmap= 0;
uint opt_large_page_size= 0; uint opt_large_page_size= 0;
#if defined(ENABLED_DEBUG_SYNC)
uint opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
my_bool opt_old_style_user_limits= 0, trust_function_creators= 0; my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
/* /*
True if there is at least one per-hour limit for some user, so we should True if there is at least one per-hour limit for some user, so we should
...@@ -1333,6 +1337,10 @@ void clean_up(bool print_message) ...@@ -1333,6 +1337,10 @@ void clean_up(bool print_message)
#ifdef USE_REGEX #ifdef USE_REGEX
my_regex_end(); my_regex_end();
#endif #endif
#if defined(ENABLED_DEBUG_SYNC)
/* End the debug sync facility. See debug_sync.cc. */
debug_sync_end();
#endif /* defined(ENABLED_DEBUG_SYNC) */
#if !defined(EMBEDDED_LIBRARY) #if !defined(EMBEDDED_LIBRARY)
if (!opt_bootstrap) if (!opt_bootstrap)
...@@ -3464,6 +3472,12 @@ static int init_common_variables(const char *conf_file_name, int argc, ...@@ -3464,6 +3472,12 @@ static int init_common_variables(const char *conf_file_name, int argc,
sys_var_slow_log_path.value= my_strdup(s, MYF(0)); sys_var_slow_log_path.value= my_strdup(s, MYF(0));
sys_var_slow_log_path.value_length= strlen(s); sys_var_slow_log_path.value_length= strlen(s);
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the debug sync facility. See debug_sync.cc. */
if (debug_sync_init())
return 1; /* purecov: tested */
#endif /* defined(ENABLED_DEBUG_SYNC) */
#if (ENABLE_TEMP_POOL) #if (ENABLE_TEMP_POOL)
if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1)) if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
return 1; return 1;
...@@ -4858,7 +4872,7 @@ void create_thread_to_handle_connection(THD *thd) ...@@ -4858,7 +4872,7 @@ void create_thread_to_handle_connection(THD *thd)
handle_one_connection, handle_one_connection,
(void*) thd))) (void*) thd)))
{ {
/* purify: begin inspected */ /* purecov: begin inspected */
DBUG_PRINT("error", DBUG_PRINT("error",
("Can't create thread to handle request (error %d)", ("Can't create thread to handle request (error %d)",
error)); error));
...@@ -5671,6 +5685,9 @@ enum options_mysqld ...@@ -5671,6 +5685,9 @@ enum options_mysqld
OPT_SECURE_FILE_PRIV, OPT_SECURE_FILE_PRIV,
OPT_MIN_EXAMINED_ROW_LIMIT, OPT_MIN_EXAMINED_ROW_LIMIT,
OPT_LOG_SLOW_SLAVE_STATEMENTS, OPT_LOG_SLOW_SLAVE_STATEMENTS,
#if defined(ENABLED_DEBUG_SYNC)
OPT_DEBUG_SYNC_TIMEOUT,
#endif /* defined(ENABLED_DEBUG_SYNC) */
OPT_OLD_MODE, OPT_OLD_MODE,
OPT_SLAVE_EXEC_MODE, OPT_SLAVE_EXEC_MODE,
OPT_GENERAL_LOG_FILE, OPT_GENERAL_LOG_FILE,
...@@ -6442,6 +6459,14 @@ log and this option does nothing anymore.", ...@@ -6442,6 +6459,14 @@ log and this option does nothing anymore.",
"Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.", "Decision to use in heuristic recover process. Possible values are COMMIT or ROLLBACK.",
(uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover, (uchar**) &opt_tc_heuristic_recover,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
#if defined(ENABLED_DEBUG_SYNC)
{"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
"Enable the debug sync facility "
"and optionally specify a default wait timeout in seconds. "
"A zero value keeps the facility disabled.",
(uchar**) &opt_debug_sync_timeout, 0,
0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
#endif /* defined(ENABLED_DEBUG_SYNC) */
{"temp-pool", OPT_TEMP_POOL, {"temp-pool", OPT_TEMP_POOL,
#if (ENABLE_TEMP_POOL) #if (ENABLE_TEMP_POOL)
"Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.",
...@@ -7626,6 +7651,9 @@ static int mysql_init_variables(void) ...@@ -7626,6 +7651,9 @@ static int mysql_init_variables(void)
bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list)); bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
bzero((char *) &global_status_var, sizeof(global_status_var)); bzero((char *) &global_status_var, sizeof(global_status_var));
opt_large_pages= 0; opt_large_pages= 0;
#if defined(ENABLED_DEBUG_SYNC)
opt_debug_sync_timeout= 0;
#endif /* defined(ENABLED_DEBUG_SYNC) */
key_map_full.set_all(); key_map_full.set_all();
/* Character sets */ /* Character sets */
...@@ -8360,6 +8388,22 @@ mysqld_get_one_option(int optid, ...@@ -8360,6 +8388,22 @@ mysqld_get_one_option(int optid,
lower_case_table_names= argument ? atoi(argument) : 1; lower_case_table_names= argument ? atoi(argument) : 1;
lower_case_table_names_used= 1; lower_case_table_names_used= 1;
break; break;
#if defined(ENABLED_DEBUG_SYNC)
case OPT_DEBUG_SYNC_TIMEOUT:
/*
Debug Sync Facility. See debug_sync.cc.
Default timeout for WAIT_FOR action.
Default value is zero (facility disabled).
If option is given without an argument, supply a non-zero value.
*/
if (!argument)
{
/* purecov: begin tested */
opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
/* purecov: end */
}
break;
#endif /* defined(ENABLED_DEBUG_SYNC) */
} }
return 0; return 0;
} }
......
...@@ -625,6 +625,12 @@ static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache", ...@@ -625,6 +625,12 @@ static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
&table_cache_size); &table_cache_size);
static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout", static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
&table_lock_wait_timeout); &table_lock_wait_timeout);
#if defined(ENABLED_DEBUG_SYNC)
/* Debug Sync Facility. Implemented in debug_sync.cc. */
static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
#endif /* defined(ENABLED_DEBUG_SYNC) */
static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size", static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
&thread_cache_size); &thread_cache_size);
#if HAVE_POOL_OF_THREADS == 1 #if HAVE_POOL_OF_THREADS == 1
......
...@@ -637,6 +637,21 @@ public: ...@@ -637,6 +637,21 @@ public:
}; };
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
#if defined(ENABLED_DEBUG_SYNC)
/* Debug Sync Facility. Implemented in debug_sync.cc. */
class sys_var_debug_sync :public sys_var_thd
{
public:
sys_var_debug_sync(sys_var_chain *chain, const char *name_arg)
:sys_var_thd(name_arg)
{ chain_sys_var(chain); }
bool check(THD *thd, set_var *var);
bool update(THD *thd, set_var *var);
SHOW_TYPE show_type() { return SHOW_CHAR; }
bool check_update_type(Item_result type) { return type != STRING_RESULT; }
uchar *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
};
#endif /* defined(ENABLED_DEBUG_SYNC) */
/* some variables that require special handling */ /* some variables that require special handling */
......
...@@ -6206,3 +6206,10 @@ ER_TOO_MANY_CONCURRENT_TRXS ...@@ -6206,3 +6206,10 @@ ER_TOO_MANY_CONCURRENT_TRXS
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED
eng "Non-ASCII separator arguments are not fully supported" eng "Non-ASCII separator arguments are not fully supported"
ER_DEBUG_SYNC_TIMEOUT
eng "debug sync point wait timed out"
ger "Debug Sync Point Wartezeit berschritten"
ER_DEBUG_SYNC_HIT_LIMIT
eng "debug sync point hit limit reached"
ger "Debug Sync Point Hit Limit erreicht"
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
/* Basic functions needed by many modules */ /* Basic functions needed by many modules */
#include "mysql_priv.h" #include "mysql_priv.h"
#include "debug_sync.h"
#include "sql_select.h" #include "sql_select.h"
#include "sp_head.h" #include "sp_head.h"
#include "sp.h" #include "sp.h"
...@@ -950,6 +951,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, ...@@ -950,6 +951,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock,
close_old_data_files(thd,thd->open_tables,1,1); close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd); mysql_ha_flush(thd);
DEBUG_SYNC(thd, "after_flush_unlock");
bool found=1; bool found=1;
/* Wait until all threads has closed all the tables we had locked */ /* Wait until all threads has closed all the tables we had locked */
...@@ -5289,6 +5291,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen) ...@@ -5289,6 +5291,8 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
} }
} }
DEBUG_SYNC(thd, "before_lock_tables_takes_lock");
if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start), if (! (thd->lock= mysql_lock_tables(thd, start, (uint) (ptr - start),
lock_flag, need_reopen))) lock_flag, need_reopen)))
{ {
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "sp_rcontext.h" #include "sp_rcontext.h"
#include "sp_cache.h" #include "sp_cache.h"
#include "debug_sync.h"
/* /*
The following is used to initialise Table_ident with a internal The following is used to initialise Table_ident with a internal
...@@ -584,6 +585,9 @@ THD::THD() ...@@ -584,6 +585,9 @@ THD::THD()
derived_tables_processing(FALSE), derived_tables_processing(FALSE),
spcont(NULL), spcont(NULL),
m_parser_state(NULL) m_parser_state(NULL)
#if defined(ENABLED_DEBUG_SYNC)
, debug_sync_control(0)
#endif /* defined(ENABLED_DEBUG_SYNC) */
{ {
ulong tmp; ulong tmp;
...@@ -832,6 +836,11 @@ void THD::init(void) ...@@ -832,6 +836,11 @@ void THD::init(void)
reset_current_stmt_binlog_row_based(); reset_current_stmt_binlog_row_based();
bzero((char *) &status_var, sizeof(status_var)); bzero((char *) &status_var, sizeof(status_var));
sql_log_bin_toplevel= options & OPTION_BIN_LOG; sql_log_bin_toplevel= options & OPTION_BIN_LOG;
#if defined(ENABLED_DEBUG_SYNC)
/* Initialize the Debug Sync Facility. See debug_sync.cc. */
debug_sync_init_thread(this);
#endif /* defined(ENABLED_DEBUG_SYNC) */
} }
...@@ -911,6 +920,12 @@ void THD::cleanup(void) ...@@ -911,6 +920,12 @@ void THD::cleanup(void)
lock=locked_tables; locked_tables=0; lock=locked_tables; locked_tables=0;
close_thread_tables(this); close_thread_tables(this);
} }
#if defined(ENABLED_DEBUG_SYNC)
/* End the Debug Sync Facility. See debug_sync.cc. */
debug_sync_end_thread(this);
#endif /* defined(ENABLED_DEBUG_SYNC) */
mysql_ha_cleanup(this); mysql_ha_cleanup(this);
delete_dynamic(&user_var_events); delete_dynamic(&user_var_events);
hash_free(&user_vars); hash_free(&user_vars);
......
...@@ -1896,6 +1896,11 @@ public: ...@@ -1896,6 +1896,11 @@ public:
partition_info *work_part_info; partition_info *work_part_info;
#endif #endif
#if defined(ENABLED_DEBUG_SYNC)
/* Debug Sync facility. See debug_sync.cc. */
struct st_debug_sync_control *debug_sync_control;
#endif /* defined(ENABLED_DEBUG_SYNC) */
THD(); THD();
~THD(); ~THD();
......
...@@ -837,7 +837,7 @@ static int myisamchk(MI_CHECK *param, char * filename) ...@@ -837,7 +837,7 @@ static int myisamchk(MI_CHECK *param, char * filename)
mi_check_print_error(param,"'%s' is marked as crashed after last repair",filename); mi_check_print_error(param,"'%s' is marked as crashed after last repair",filename);
break; break;
case HA_ERR_OLD_FILE: case HA_ERR_OLD_FILE:
mi_check_print_error(param,"'%s' is a old type of MyISAM-table", filename); mi_check_print_error(param,"'%s' is an old type of MyISAM-table", filename);
break; break;
case HA_ERR_END_OF_FILE: case HA_ERR_END_OF_FILE:
mi_check_print_error(param,"Couldn't read complete header from '%s'", filename); mi_check_print_error(param,"Couldn't read complete header from '%s'", filename);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment