summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <sasha@mysql.sashanet.com>2002-03-26 22:23:51 -0700
committerunknown <sasha@mysql.sashanet.com>2002-03-26 22:23:51 -0700
commitef261914d3fdaaf25f1415b8625cc9ff89f9266a (patch)
treeaddd464870d8ce2dc41b174031430761b68ff23e
parent4252578b687e972cb482ab22efca01b8ea484221 (diff)
parent079a551ca735e79f3d7a2ebbecf8be4d4ba7608a (diff)
downloadmariadb-git-ef261914d3fdaaf25f1415b8625cc9ff89f9266a.tar.gz
Merge work:/home/bk/mysql-4.0
into mysql.sashanet.com:/reiser-data/mysql-4.0 sql/lex.h: Auto merged sql/mysqld.cc: Auto merged sql/slave.cc: Auto merged sql/sql_yacc.yy: Auto merged
-rw-r--r--dbug/dbug.c28
-rw-r--r--include/my_sys.h4
-rw-r--r--mysql-test/r/multi_update.result27
-rw-r--r--mysql-test/r/rpl000015.result6
-rw-r--r--mysql-test/t/multi_update.test11
-rw-r--r--mysql-test/t/rpl000014.test1
-rw-r--r--mysql-test/t/rpl000015-slave-master-info.opt2
-rw-r--r--mysql-test/t/rpl000015.test1
-rw-r--r--mysys/my_static.h6
-rw-r--r--mysys/my_thr_init.c39
-rw-r--r--mysys/safemalloc.c70
-rw-r--r--sql/lex.h2
-rw-r--r--sql/log.cc1
-rw-r--r--sql/log_event.cc3
-rw-r--r--sql/mysqld.cc24
-rw-r--r--sql/slave.cc10
-rw-r--r--sql/sql_lex.cc1
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_repl.cc47
-rw-r--r--sql/sql_yacc.yy16
20 files changed, 273 insertions, 28 deletions
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 9e1e51d2404..8f214bfbe7c 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -21,7 +21,8 @@
* all copies and derivative works. Thank you. *
* *
* The author makes no warranty of any kind with respect to this *
- * product and explicitly disclaims any implied warranties of mer- *
+ * product and explicitly disclaims any implied warranties of mer- *ct_lex.table_list.first=0;
+ thd->lex.selec
* chantability or fitness for any particular purpose. *
* *
******************************************************************************
@@ -58,7 +59,7 @@
* seismo!bpa!sjuvax!bbanerje
*
* Michael Widenius:
- * DBUG_DUMP - To dump a pice of memory.
+ * DBUG_DUMP - To dump a block of memory.
* PUSH_FLAG "O" - To be used insted of "o" if we don't
* want flushing (for slow systems)
* PUSH_FLAG "A" - as 'O', but we will append to the out file instead
@@ -707,7 +708,13 @@ char ***_sframep_ __attribute__((unused)))
int save_errno=errno;
if (!init_done)
_db_push_ (_DBUG_START_CONDITION_);
- state=code_state();
+ /* Sasha: the test below is so we could call functions with DBUG_ENTER
+ before my_thread_init(). I needed this because I suspected corruption
+ of a block allocated by my_thread_init() itself, so I wanted to use
+ my_malloc()/my_free() in my_thread_init()/my_thread_end()
+ */
+ if (!(state=code_state()))
+ return;
*_sfunc_ = state->func;
*_sfile_ = state->file;
@@ -855,6 +862,9 @@ uint _line_,
const char *keyword)
{
CODE_STATE *state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!state)
+ return;
state->u_line = _line_;
state->u_keyword = (char*) keyword;
}
@@ -890,7 +900,9 @@ void _db_doprnt_ (const char *format,...)
{
va_list args;
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
va_start(args,format);
@@ -942,7 +954,9 @@ uint length)
int pos;
char dbuff[90];
CODE_STATE *state;
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return;
if (_db_keyword_ ((char*) keyword))
{
@@ -1224,7 +1238,9 @@ const char *keyword)
if (!init_done)
_db_push_ ("");
- state=code_state();
+ /* Sasha: pre-my_thread_init() safety */
+ if (!(state=code_state()))
+ return FALSE;
result = FALSE;
if (DEBUGGING &&
state->level <= stack -> maxdepth &&
diff --git a/include/my_sys.h b/include/my_sys.h
index 4aee27e2939..3950bfce758 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -137,6 +137,10 @@ extern int NEAR my_errno; /* Last error in mysys */
#define NORMAL_SAFEMALLOC sf_malloc_quick=0
extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick;
extern ulonglong safemalloc_mem_limit;
+/* keep track of shutdown,signal, and main threads so that my_end() will not
+ report errors with them
+*/
+extern pthread_t shutdown_th, main_th,signal_th;
#define CALLER_INFO_PROTO , const char *sFile, uint uLine
#define CALLER_INFO , __FILE__, __LINE__
#define ORIG_CALLER_INFO , sFile, uLine
diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result
index b1423667c44..85819d9571d 100644
--- a/mysql-test/r/multi_update.result
+++ b/mysql-test/r/multi_update.result
@@ -2,7 +2,34 @@ drop table if exists t1,t2,t3;
create table t1(id1 int not null auto_increment primary key, t char(12));
create table t2(id2 int not null, t char(12));
create table t3(id3 int not null, t char(12), index(id3));
+select count(*) from t1 where id1 > 95;
+count(*)
+5
+select count(*) from t2 where id2 > 95;
+count(*)
+25
+select count(*) from t3 where id3 > 95;
+count(*)
+250
update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+count(*)
+10
+select count(*) from t1 where id1 > 90;
+count(*)
+10
+select count(*) from t2 where t = "bbb";
+count(*)
+10
+select count(*) from t2 where id2 > 90;
+count(*)
+50
+select count(*) from t3 where t = "cc";
+count(*)
+500
+select count(*) from t3 where id3 > 90;
+count(*)
+500
delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
check table t1, t2, t3;
Table Op Msg_type Msg_text
diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result
index 03370bc6b0d..1546e5eb48d 100644
--- a/mysql-test/r/rpl000015.result
+++ b/mysql-test/r/rpl000015.result
@@ -9,16 +9,16 @@ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Lo
change master to master_host='127.0.0.1';
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
-127.0.0.1 test MASTER_PORT 60 4 slave-relay-bin.001 4 No No 0 0 0
+127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0
change master to master_host='127.0.0.1',master_user='root',
master_password='',master_port=MASTER_PORT;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
-127.0.0.1 root MASTER_PORT 60 4 slave-relay-bin.001 4 No No 0 0 0
+127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.001 4 No No 0 0 0
slave start;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos
-127.0.0.1 root MASTER_PORT 60 master-bin.001 79 slave-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79
+127.0.0.1 root MASTER_PORT 7 master-bin.001 79 slave-relay-bin.001 120 master-bin.001 Yes Yes 0 0 79
drop table if exists t1;
create table t1 (n int);
insert into t1 values (10),(45),(90);
diff --git a/mysql-test/t/multi_update.test b/mysql-test/t/multi_update.test
index 11697f794a9..c16189168d2 100644
--- a/mysql-test/t/multi_update.test
+++ b/mysql-test/t/multi_update.test
@@ -29,7 +29,18 @@ while ($1)
dec $1;
}
enable_query_log;
+
+select count(*) from t1 where id1 > 95;
+select count(*) from t2 where id2 > 95;
+select count(*) from t3 where id3 > 95;
+
update t1,t2,t3 set t1.t="aaa", t2.t="bbb", t3.t="cc" where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 90;
+select count(*) from t1 where t = "aaa";
+select count(*) from t1 where id1 > 90;
+select count(*) from t2 where t = "bbb";
+select count(*) from t2 where id2 > 90;
+select count(*) from t3 where t = "cc";
+select count(*) from t3 where id3 > 90;
delete t1.*, t2.*, t3.* from t1,t2,t3 where t1.id1 = t2.id2 and t2.id2 = t3.id3 and t1.id1 > 95;
check table t1, t2, t3;
diff --git a/mysql-test/t/rpl000014.test b/mysql-test/t/rpl000014.test
index a673a23dde2..df15fa6e600 100644
--- a/mysql-test/t/rpl000014.test
+++ b/mysql-test/t/rpl000014.test
@@ -8,6 +8,7 @@ sync_with_master;
show slave status;
change master to master_log_pos=73;
slave stop;
+
change master to master_log_pos=73;
--replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT
show slave status;
diff --git a/mysql-test/t/rpl000015-slave-master-info.opt b/mysql-test/t/rpl000015-slave-master-info.opt
index 80190bf6d29..28bc753dd56 100644
--- a/mysql-test/t/rpl000015-slave-master-info.opt
+++ b/mysql-test/t/rpl000015-slave-master-info.opt
@@ -1 +1 @@
---server-id=2
+--server-id=22 --master-connect-retry=7
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index 8fd04613ab8..c42e14699c5 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -8,6 +8,7 @@ connection slave;
reset slave;
--replace_result $MASTER_MYPORT MASTER_PORT
show slave status;
+
change master to master_host='127.0.0.1';
# The following needs to be cleaned up when change master is fixed
--replace_result $MASTER_MYPORT MASTER_PORT 3306 MASTER_PORT 3334 MASTER_PORT
diff --git a/mysys/my_static.h b/mysys/my_static.h
index 4f944938b8d..ca384009063 100644
--- a/mysys/my_static.h
+++ b/mysys/my_static.h
@@ -38,6 +38,7 @@ struct irem {
my_string _sFileName; /* File in which memory was new'ed */
uint _uLineNum; /* Line number in above file */
uint _uDataSize; /* Size requested */
+ pthread_t thread_id;
long _lSpecialValue; /* Underrun marker value */
};
@@ -56,6 +57,11 @@ extern const char *soundex_map;
extern USED_MEM* my_once_root_block;
extern uint my_once_extra;
+/* these threads are exept from safemalloc leak scrutiny unless
+ PEDANTIC_SAFEMALLOC is defined
+*/
+extern pthread_t signal_thread,kill_thread;
+
#ifndef HAVE_TEMPNAM
extern int _my_tempnam_used;
#endif
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index b4d98feeeb6..2c7fd098c63 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -105,19 +105,33 @@ static long thread_id=0;
my_bool my_thread_init(void)
{
struct st_my_thread_var *tmp;
+#ifdef EXTRA_DEBUG
+ fprintf(stderr,"my_thread_init(): thread_id=%ld\n",pthread_self());
+#endif
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
pthread_mutex_lock(&THR_LOCK_lock);
#endif
#if !defined(__WIN__) || defined(USE_TLS)
if (my_pthread_getspecific(struct st_my_thread_var *,THR_KEY_mysys))
{
+#ifdef EXTRA_DEBUG
+ fprintf(stderr,"my_thread_init() called more than once in thread %ld\n",
+ pthread_self());
+#endif
pthread_mutex_unlock(&THR_LOCK_lock);
return 0; /* Safequard */
}
/* We must have many calloc() here because these are freed on
pthread_exit */
+ /*
+ Sasha: the above comment does not make sense. I have changed calloc() to
+ equivalent my_malloc() but it was calloc() before. It seems like the
+ comment is out of date - we always call my_thread_end() before
+ pthread_exit() to clean up. Note that I have also fixed up DBUG
+ code to be able to call it from my_thread_init()
+ */
if (!(tmp=(struct st_my_thread_var *)
- calloc(1,sizeof(struct st_my_thread_var))))
+ my_malloc(sizeof(struct st_my_thread_var),MYF(MY_WME|MY_ZEROFILL))))
{
pthread_mutex_unlock(&THR_LOCK_lock);
return 1;
@@ -125,6 +139,9 @@ my_bool my_thread_init(void)
pthread_setspecific(THR_KEY_mysys,tmp);
#else
+ /* Sasha: TODO - explain what exactly we are doing on Windows
+ At first glance, I have a hard time following the code
+ */
if (THR_KEY_mysys.id) /* Already initialized */
{
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
@@ -146,9 +163,18 @@ my_bool my_thread_init(void)
void my_thread_end(void)
{
struct st_my_thread_var *tmp=my_thread_var;
+#ifdef EXTRA_DEBUG
+ fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
+ tmp,pthread_self());
+#endif
if (tmp)
{
#if !defined(DBUG_OFF)
+ /* Sasha: tmp->dbug is allocated inside DBUG library
+ so for now we will not mess with trying to use my_malloc()/
+ my_free(), but in the future it would be nice to figure out a
+ way to do it
+ */
if (tmp->dbug)
{
free(tmp->dbug);
@@ -160,12 +186,15 @@ void my_thread_end(void)
#endif
pthread_mutex_destroy(&tmp->mutex);
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
- free(tmp);
+ /* we need to setspecific to 0 BEFORE we call my_free, as my_free
+ uses some DBUG_ macros that will use the follow the specific
+ pointer after the block it is pointing to has been freed if
+ specific does not get reset first
+ */
+ pthread_setspecific(THR_KEY_mysys,0);
+ my_free((gptr)tmp,MYF(MY_WME));
#endif
}
-#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
- pthread_setspecific(THR_KEY_mysys,0);
-#endif
}
struct st_my_thread_var *_my_thread_var(void)
diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c
index d8c089c2ff0..062f9b9db02 100644
--- a/mysys/safemalloc.c
+++ b/mysys/safemalloc.c
@@ -73,14 +73,25 @@
#include "mysys_err.h"
ulonglong safemalloc_mem_limit = ~(ulonglong)0;
+pthread_t shutdown_th=0,main_th=0,signal_th=0;
#define pNext tInt._pNext
#define pPrev tInt._pPrev
#define sFileName tInt._sFileName
#define uLineNum tInt._uLineNum
#define uDataSize tInt._uDataSize
+#define thread_id tInt.thread_id
#define lSpecialValue tInt._lSpecialValue
+#ifndef PEDANTIC_SAFEMALLOC
+static int sf_malloc_tampered = 0; /* set to 1 after TERMINATE() if we had
+ to fiddle with cNewCount and the linked
+ list of blocks so that _sanity() will
+ not fuss when it is not supposed to
+ */
+#endif
+
+
/* Static functions prototypes */
static int check_ptr(const char *where, byte *ptr, const char *sFile,
@@ -174,6 +185,7 @@ gptr _mymalloc (uint uSize, const char *sFile, uint uLine, myf MyFlags)
pTmp -> sFileName = (my_string) sFile;
pTmp -> uLineNum = uLine;
pTmp -> uDataSize = uSize;
+ pTmp->thread_id = pthread_self();
pTmp -> pPrev = NULL;
/* Add this remember structure to the linked list */
@@ -359,6 +371,12 @@ static int check_ptr(const char *where, byte *ptr, const char *sFile,
return 0;
}
+static int legal_leak(struct remember* pPtr)
+{
+ return pthread_self() == pPtr->thread_id || main_th == pPtr->thread_id
+ || shutdown_th == pPtr->thread_id
+ || signal_th == pPtr->thread_id;
+}
/*
* TERMINATE(FILE *file)
@@ -376,6 +394,47 @@ void TERMINATE (FILE *file)
/* NEW and the number of calls to FREE. >0 means more */
/* NEWs than FREEs. <0, etc. */
+#ifndef PEDANTIC_SAFEMALLOC
+ /* Avoid false alarms for blocks that we cannot free before my_end()
+ This does miss some positives, but that is ok. This will only miss
+ failures to free things allocated in the main thread which
+ performs only one-time allocations. If you really need to
+ debug memory allocations in the main thread,
+ #define PEDANTIC_SAFEMALLOC
+ */
+ if ((pPtr=pRememberRoot))
+ {
+ while (pPtr)
+ {
+ if (legal_leak(pPtr))
+ {
+ sf_malloc_tampered=1;
+ cNewCount--;
+ lCurMemory -= pPtr->uDataSize;
+ if (pPtr->pPrev)
+ {
+ struct remember* tmp;
+ tmp = pPtr->pPrev->pNext = pPtr->pNext;
+ if (tmp)
+ tmp->pPrev = pPtr->pPrev;
+ pPtr->pNext = pPtr->pPrev = 0;
+ pPtr = tmp;
+ }
+ else
+ {
+ pRememberRoot = pPtr->pNext;
+ pPtr->pNext = pPtr->pPrev = 0;
+ pPtr = pRememberRoot;
+ if (pPtr)
+ pPtr->pPrev=0;
+ }
+ }
+ else
+ pPtr = pPtr->pNext;
+ }
+ }
+#endif
+
if (cNewCount)
{
if (file)
@@ -402,10 +461,14 @@ void TERMINATE (FILE *file)
if (file)
{
fprintf (file,
- "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'\n",
+ "\t%6u bytes at 0x%09lx, allocated at line %4u in '%s'",
pPtr -> uDataSize,
(ulong) &(pPtr -> aData[sf_malloc_prehunc]),
pPtr -> uLineNum, pPtr -> sFileName);
+#ifdef THREAD
+ fprintf(file, " in thread %ld", pPtr->thread_id);
+#endif
+ fprintf(file, "\n");
(void) fflush(file);
}
DBUG_PRINT("safe",
@@ -484,6 +547,10 @@ int _sanity (const char *sFile, uint uLine)
uint count=0;
pthread_mutex_lock(&THR_LOCK_malloc);
+#ifndef PEDANTIC_SAFEMALLOC
+ if (sf_malloc_tampered && cNewCount < 0)
+ cNewCount=0;
+#endif
count=cNewCount;
for (pTmp = pRememberRoot; pTmp != NULL && count-- ; pTmp = pTmp -> pNext)
flag+=_checkchunk (pTmp, sFile, uLine);
@@ -492,6 +559,7 @@ int _sanity (const char *sFile, uint uLine)
{
const char *format="Safemalloc link list destroyed, discovered at '%s:%d'";
fprintf (stderr, format, sFile, uLine); fputc('\n',stderr);
+ fprintf (stderr, "root=%p,count=%d,pTmp=%p\n", pRememberRoot,count,pTmp);
(void) fflush(stderr);
DBUG_PRINT("safe",(format, sFile, uLine));
flag=1;
diff --git a/sql/lex.h b/sql/lex.h
index 10c1ad766d5..8c7beb64b9b 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -280,6 +280,8 @@ static SYMBOL symbols[] = {
{ "READ", SYM(READ_SYM),0,0},
{ "REAL", SYM(REAL),0,0},
{ "REFERENCES", SYM(REFERENCES),0,0},
+ { "RELAY_LOG_FILE", SYM(RELAY_LOG_FILE_SYM),0,0},
+ { "RELAY_LOG_POS", SYM(RELAY_LOG_POS_SYM),0,0},
{ "RELOAD", SYM(RELOAD),0,0},
{ "REGEXP", SYM(REGEXP),0,0},
{ "RENAME", SYM(RENAME),0,0},
diff --git a/sql/log.cc b/sql/log.cc
index 1052b3379b3..dc6b1d35cef 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -479,6 +479,7 @@ err:
rli->relay_log_pos = 4;
strnmov(rli->relay_log_name,rli->linfo.log_file_name,
sizeof(rli->relay_log_name));
+ flush_relay_log_info(rli);
}
/*
No need to free io_buf because we allocated both fname and io_buf in
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 528110deb74..8db10a84661 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1607,7 +1607,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
{
mysql_parse(thd, thd->query, q_len);
if (expected_error !=
- (actual_error = thd->net.last_errno) && expected_error)
+ (actual_error = thd->net.last_errno) && expected_error &&
+ !ignored_error_code(actual_error))
{
const char* errmsg = "Slave: did not get the expected error\
running query from master - expected: '%s' (%d), got '%s' (%d)";
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index d33ec9b92ca..a0154f980f1 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -38,7 +38,17 @@
#define ONE_THREAD
#endif
-/* do stack traces are only supported on linux intel */
+#ifdef SAFEMALLOC
+#define SHUTDOWN_THD shutdown_th=pthread_self();
+#define MAIN_THD main_th=pthread_self();
+#define SIGNAL_THD signal_th=pthread_self();
+#else
+#define SHUTDOWN_THD
+#define MAIN_THD
+#define SIGNAL_THD
+#endif
+
+/* stack traces are only supported on linux intel */
#if defined(__linux__) && defined(__i386__) && defined(USE_PSTACK)
#define HAVE_STACK_TRACE_ON_SEGV
#include "../pstack/pstack.h"
@@ -701,6 +711,7 @@ static void __cdecl kill_server(int sig_ptr)
sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
#if defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2)
+ SHUTDOWN_THD;
my_thread_init(); // If this is a new thread
#endif
close_connections();
@@ -716,6 +727,7 @@ static void __cdecl kill_server(int sig_ptr)
#ifdef USE_ONE_SIGNAL_HAND
static pthread_handler_decl(kill_server_thread,arg __attribute__((unused)))
{
+ SHUTDOWN_THD;
my_thread_init(); // Initialize new thread
kill_server(0);
my_thread_end(); // Normally never reached
@@ -1262,6 +1274,7 @@ static void init_signals(void)
signal(SIGALRM, SIG_IGN);
signal(SIGBREAK,SIG_IGN);
signal_thread = pthread_self();
+ SIGNAL_THD;
}
static void start_signal_handler(void)
@@ -1387,6 +1400,7 @@ static void init_signals(void)
sigaction(SIGBUS, &sa, NULL);
#endif
sigaction(SIGILL, &sa, NULL);
+ sigaction(SIGFPE, &sa, NULL);
}
(void) sigemptyset(&set);
#ifdef THREAD_SPECIFIC_SIGPIPE
@@ -1454,7 +1468,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
int sig;
my_thread_init(); // Init new thread
DBUG_ENTER("signal_hand");
-
+ SIGNAL_THD;
/* Setup alarm handler */
init_thr_alarm(max_connections+max_insert_delayed_threads);
#if SIGINT != THR_KILL_SIGNAL
@@ -1509,7 +1523,10 @@ static void *signal_hand(void *arg __attribute__((unused)))
else
while ((error=my_sigwait(&set,&sig)) == EINTR) ;
if (cleanup_done)
+ {
+ my_thread_end();
pthread_exit(0); // Safety
+ }
switch (sig) {
case SIGTERM:
case SIGQUIT:
@@ -1603,6 +1620,7 @@ int uname(struct utsname *a)
pthread_handler_decl(handle_shutdown,arg)
{
MSG msg;
+ SHUTDOWN_THD;
my_thread_init();
/* this call should create the message queue for this thread */
@@ -1629,6 +1647,7 @@ int __stdcall handle_kill(ulong ctrl_type)
#ifdef OS2
pthread_handler_decl(handle_shutdown,arg)
{
+ SHUTDOWN_THD;
my_thread_init();
// wait semaphore
@@ -1700,6 +1719,7 @@ int main(int argc, char **argv)
my_umask=0660; // Default umask for new files
my_umask_dir=0700; // Default umask for new directories
+ MAIN_THD;
MY_INIT(argv[0]); // init my_sys library & pthreads
tzset(); // Set tzname
diff --git a/sql/slave.cc b/sql/slave.cc
index 176f5db2f79..9050bf7362f 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -345,7 +345,13 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
}
}
DBUG_ASSERT(thd != 0);
- KICK_SLAVE(thd);
+ /* is is criticate to test if the slave is running. Otherwise, we might
+ be referening freed memory trying to kick it
+ */
+ if (*slave_running)
+ {
+ KICK_SLAVE(thd);
+ }
while (*slave_running)
{
/* there is a small chance that slave thread might miss the first
@@ -367,7 +373,9 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
DBUG_ASSERT_LOCK(cond_lock);
pthread_cond_timedwait(term_cond, cond_lock, &abstime);
if (*slave_running)
+ {
KICK_SLAVE(thd);
+ }
}
if (term_lock)
pthread_mutex_unlock(term_lock);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 43195bc908b..42a8a700da3 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -151,6 +151,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length)
lex->yacc_yyss=lex->yacc_yyvs=0;
lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE);
lex->slave_thd_opt=0;
+ bzero(&lex->mi,sizeof(lex->mi));
return lex;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ecfb3dec99c..6961ab8c712 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -98,6 +98,8 @@ typedef struct st_lex_master_info
uint port, connect_retry;
ulonglong pos;
ulong server_id;
+ char* relay_log_name;
+ ulong relay_log_pos;
} LEX_MASTER_INFO;
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index c6384817512..bbe92f3e526 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -690,6 +690,7 @@ int change_master(THD* thd, MASTER_INFO* mi)
{
int error=0,restart_thread_mask;
const char* errmsg=0;
+ bool need_relay_log_purge=1;
// kill slave thread
lock_slave_threads(mi);
@@ -742,17 +743,47 @@ int change_master(THD* thd, MASTER_INFO* mi)
if (lex_mi->connect_retry)
mi->connect_retry = lex_mi->connect_retry;
+ if (lex_mi->relay_log_name)
+ {
+ need_relay_log_purge = 0;
+ strnmov(mi->rli.relay_log_name,lex_mi->relay_log_name,
+ sizeof(mi->rli.relay_log_name));
+ }
+
+ if (lex_mi->relay_log_pos)
+ {
+ need_relay_log_purge=0;
+ mi->rli.relay_log_pos=lex_mi->relay_log_pos;
+ }
+
flush_master_info(mi);
- pthread_mutex_unlock(&mi->data_lock);
- thd->proc_info="purging old relay logs";
- if (purge_relay_logs(&mi->rli,0 /* not only reset, but also reinit*/,
- &errmsg))
+ if (need_relay_log_purge)
{
- send_error(&thd->net, 0, "Failed purging old relay logs");
- unlock_slave_threads(mi);
- return 1;
+ pthread_mutex_unlock(&mi->data_lock);
+ thd->proc_info="purging old relay logs";
+ if (purge_relay_logs(&mi->rli,0 /* not only reset, but also reinit*/,
+ &errmsg))
+ {
+ send_error(&thd->net, 0, "Failed purging old relay logs");
+ unlock_slave_threads(mi);
+ return 1;
+ }
+ pthread_mutex_lock(&mi->rli.data_lock);
+ }
+ else
+ {
+ const char* msg;
+ if (init_relay_log_pos(&mi->rli,0/*log already inited*/,
+ 0 /*pos already inited*/,
+ 0 /*no data lock*/,
+ &msg))
+ {
+ net_printf(&thd->net,0,"Failed initializing relay log position: %s",msg);
+ unlock_slave_threads(mi);
+ return 1;
+ }
+
}
- pthread_mutex_lock(&mi->rli.data_lock);
mi->rli.master_log_pos = mi->master_log_pos;
strnmov(mi->rli.master_log_name,mi->master_log_name,
sizeof(mi->rli.master_log_name));
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 00330c7cab7..8012768e508 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -241,6 +241,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token MASTER_PORT_SYM
%token MASTER_CONNECT_RETRY_SYM
%token MASTER_SERVER_ID_SYM
+%token RELAY_LOG_FILE_SYM
+%token RELAY_LOG_POS_SYM
%token MATCH
%token MAX_ROWS
%token MAX_QUERIES_PER_HOUR
@@ -701,6 +703,16 @@ master_def:
{
Lex->mi.connect_retry = $3;
}
+ |
+ RELAY_LOG_FILE_SYM EQ TEXT_STRING
+ {
+ Lex->mi.relay_log_name = $3.str;
+ }
+ |
+ RELAY_LOG_POS_SYM EQ ULONG_NUM
+ {
+ Lex->mi.relay_log_pos = $3;
+ }
/* create a table */
@@ -3013,6 +3025,7 @@ keyword:
| ISSUER_SYM {}
| INNOBASE_SYM {}
| INSERT_METHOD {}
+ | IO_THREAD {}
| LAST_SYM {}
| LEVEL_SYM {}
| LOCAL_SYM {}
@@ -3055,6 +3068,8 @@ keyword:
| RAID_CHUNKSIZE {}
| RAID_STRIPED_SYM {}
| RAID_TYPE {}
+ | RELAY_LOG_FILE_SYM {}
+ | RELAY_LOG_POS_SYM {}
| RELOAD {}
| REPAIR {}
| REPEATABLE_SYM {}
@@ -3074,6 +3089,7 @@ keyword:
| SQL_CACHE_SYM {}
| SQL_NO_CACHE_SYM {}
| SQL_QUERY_CACHE_TYPE_SYM {}
+ | SQL_THREAD {}
| START_SYM {}
| STATUS_SYM {}
| STOP_SYM {}