Commit 97c8234b authored by tomas@poseidon.ndb.mysql.com's avatar tomas@poseidon.ndb.mysql.com

Merge tulin@bk-internal.mysql.com:/home/bk/mysql-4.1

into poseidon.ndb.mysql.com:/home/tomas/mysql-5.0
parents f92dac8d 19dab118
...@@ -104,6 +104,7 @@ lenz@mysql.com ...@@ -104,6 +104,7 @@ lenz@mysql.com
magnus@neptunus.(none) magnus@neptunus.(none)
magnus@shellback.(none) magnus@shellback.(none)
marko@hundin.mysql.fi marko@hundin.mysql.fi
mats@mysql.com
matt@mysql.com matt@mysql.com
matthias@three.local.lan matthias@three.local.lan
miguel@hegel.(none) miguel@hegel.(none)
......
...@@ -548,8 +548,9 @@ buf_pool_init( ...@@ -548,8 +548,9 @@ buf_pool_init(
} }
/*----------------------------------------*/ /*----------------------------------------*/
} else { } else {
buf_pool->frame_mem = ut_malloc( buf_pool->frame_mem = ut_malloc_low(
UNIV_PAGE_SIZE * (n_frames + 1)); UNIV_PAGE_SIZE * (n_frames + 1),
TRUE, FALSE);
} }
if (buf_pool->frame_mem == NULL) { if (buf_pool->frame_mem == NULL) {
......
...@@ -42,6 +42,10 @@ initial segment in buf_LRU_get_recent_limit */ ...@@ -42,6 +42,10 @@ initial segment in buf_LRU_get_recent_limit */
#define BUF_LRU_INITIAL_RATIO 8 #define BUF_LRU_INITIAL_RATIO 8
/* If we switch on the InnoDB monitor because there are too few available
frames in the buffer pool, we set this to TRUE */
ibool buf_lru_switched_on_innodb_mon = FALSE;
/********************************************************************** /**********************************************************************
Takes a block out of the LRU list and page hash table and sets the block Takes a block out of the LRU list and page hash table and sets the block
state to BUF_BLOCK_REMOVE_HASH. */ state to BUF_BLOCK_REMOVE_HASH. */
...@@ -287,6 +291,32 @@ buf_LRU_try_free_flushed_blocks(void) ...@@ -287,6 +291,32 @@ buf_LRU_try_free_flushed_blocks(void)
mutex_exit(&(buf_pool->mutex)); mutex_exit(&(buf_pool->mutex));
} }
/**********************************************************************
Returns TRUE if less than 15 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */
ibool
buf_LRU_buf_pool_running_out(void)
/*==============================*/
/* out: TRUE if less than 15 % of buffer pool
left */
{
ibool ret = FALSE;
mutex_enter(&(buf_pool->mutex));
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) {
ret = TRUE;
}
mutex_exit(&(buf_pool->mutex));
return(ret);
}
/********************************************************************** /**********************************************************************
Returns a free block from buf_pool. The block is taken off the free list. Returns a free block from buf_pool. The block is taken off the free list.
If it is empty, blocks are moved from the end of the LRU list to the free If it is empty, blocks are moved from the end of the LRU list to the free
...@@ -325,7 +355,8 @@ buf_LRU_get_free_block(void) ...@@ -325,7 +355,8 @@ buf_LRU_get_free_block(void)
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) {
if (!srv_print_innodb_monitor) {
if (!buf_lru_switched_on_innodb_mon) {
/* Over 80 % of the buffer pool is occupied by lock /* Over 80 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory heaps or the adaptive hash index. This may be a memory
...@@ -342,16 +373,18 @@ buf_LRU_get_free_block(void) ...@@ -342,16 +373,18 @@ buf_LRU_get_free_block(void)
"InnoDB: lock heap and hash index sizes.\n", "InnoDB: lock heap and hash index sizes.\n",
(ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE))); (ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
buf_lru_switched_on_innodb_mon = TRUE;
srv_print_innodb_monitor = TRUE; srv_print_innodb_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event); os_event_set(srv_lock_timeout_thread_event);
} }
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) } else if (buf_lru_switched_on_innodb_mon) {
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
/* Switch off the InnoDB Monitor; this is a simple way /* Switch off the InnoDB Monitor; this is a simple way
to stop the monitor if the situation becomes less urgent, to stop the monitor if the situation becomes less urgent,
but may also surprise users! */ but may also surprise users if the user also switched on the
monitor! */
buf_lru_switched_on_innodb_mon = FALSE;
srv_print_innodb_monitor = FALSE; srv_print_innodb_monitor = FALSE;
} }
......
...@@ -25,6 +25,16 @@ wasted. */ ...@@ -25,6 +25,16 @@ wasted. */
void void
buf_LRU_try_free_flushed_blocks(void); buf_LRU_try_free_flushed_blocks(void);
/*==================================*/ /*==================================*/
/**********************************************************************
Returns TRUE if less than 15 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */
ibool
buf_LRU_buf_pool_running_out(void);
/*==============================*/
/* out: TRUE if less than 15 % of buffer pool
left */
/*####################################################################### /*#######################################################################
These are low-level functions These are low-level functions
......
...@@ -53,6 +53,10 @@ Created 5/24/1996 Heikki Tuuri ...@@ -53,6 +53,10 @@ Created 5/24/1996 Heikki Tuuri
name already exists */ name already exists */
#define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is #define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is
being dropped right now */ being dropped right now */
#define DB_LOCK_TABLE_FULL 45 /* lock structs have exhausted the
buffer pool (for big transactions,
InnoDB stores the lock structs in the
buffer pool) */
/* The following are partial failure codes */ /* The following are partial failure codes */
#define DB_FAIL 1000 #define DB_FAIL 1000
......
...@@ -120,6 +120,7 @@ row_search_for_mysql( ...@@ -120,6 +120,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS, /* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND, DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK, DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */ or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */ row in the MySQL format */
......
...@@ -38,8 +38,10 @@ ut_malloc_low( ...@@ -38,8 +38,10 @@ ut_malloc_low(
/*==========*/ /*==========*/
/* out, own: allocated memory */ /* out, own: allocated memory */
ulint n, /* in: number of bytes to allocate */ ulint n, /* in: number of bytes to allocate */
ibool set_to_zero); /* in: TRUE if allocated memory should be set ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */ to zero if UNIV_SET_MEM_TO_ZERO is defined */
ibool assert_on_error); /* in: if TRUE, we crash mysqld if the memory
cannot be allocated */
/************************************************************************** /**************************************************************************
Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is Allocates memory. Sets it also to zero if UNIV_SET_MEM_TO_ZERO is
defined. */ defined. */
......
...@@ -199,7 +199,7 @@ mem_pool_create( ...@@ -199,7 +199,7 @@ mem_pool_create(
but only when allocated at a higher level in mem0mem.c. but only when allocated at a higher level in mem0mem.c.
This is to avoid masking useful Purify warnings. */ This is to avoid masking useful Purify warnings. */
pool->buf = ut_malloc_low(size, FALSE); pool->buf = ut_malloc_low(size, FALSE, TRUE);
pool->size = size; pool->size = size;
mutex_create(&(pool->mutex)); mutex_create(&(pool->mutex));
......
...@@ -308,7 +308,8 @@ row_mysql_handle_errors( ...@@ -308,7 +308,8 @@ row_mysql_handle_errors(
return(TRUE); return(TRUE);
} else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT) { } else if (err == DB_DEADLOCK || err == DB_LOCK_WAIT_TIMEOUT
|| err == DB_LOCK_TABLE_FULL) {
/* Roll back the whole transaction; this resolution was added /* Roll back the whole transaction; this resolution was added
to version 3.23.43 */ to version 3.23.43 */
......
...@@ -730,8 +730,18 @@ sel_set_rec_lock( ...@@ -730,8 +730,18 @@ sel_set_rec_lock(
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */ ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */ que_thr_t* thr) /* in: query thread */
{ {
trx_t* trx;
ulint err; ulint err;
trx = thr_get_trx(thr);
if (UT_LIST_GET_LEN(trx->trx_locks) > 10000) {
if (buf_LRU_buf_pool_running_out()) {
return(DB_LOCK_TABLE_FULL);
}
}
if (index->type & DICT_CLUSTERED) { if (index->type & DICT_CLUSTERED) {
err = lock_clust_rec_read_check_and_lock(0, rec, index, mode, err = lock_clust_rec_read_check_and_lock(0, rec, index, mode,
type, thr); type, thr);
...@@ -2790,6 +2800,7 @@ row_search_for_mysql( ...@@ -2790,6 +2800,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS, /* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND, DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK, DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */ or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */ row in the MySQL format */
......
...@@ -1172,6 +1172,9 @@ NetWare. */ ...@@ -1172,6 +1172,9 @@ NetWare. */
} }
if (ret == NULL) { if (ret == NULL) {
fprintf(stderr,
"InnoDB: Fatal error: cannot allocate the memory for the buffer pool\n");
return(DB_ERROR); return(DB_ERROR);
} }
......
...@@ -61,8 +61,10 @@ ut_malloc_low( ...@@ -61,8 +61,10 @@ ut_malloc_low(
/*==========*/ /*==========*/
/* out, own: allocated memory */ /* out, own: allocated memory */
ulint n, /* in: number of bytes to allocate */ ulint n, /* in: number of bytes to allocate */
ibool set_to_zero) /* in: TRUE if allocated memory should be set ibool set_to_zero, /* in: TRUE if allocated memory should be set
to zero if UNIV_SET_MEM_TO_ZERO is defined */ to zero if UNIV_SET_MEM_TO_ZERO is defined */
ibool assert_on_error) /* in: if TRUE, we crash mysqld if the memory
cannot be allocated */
{ {
void* ret; void* ret;
...@@ -86,9 +88,7 @@ ut_malloc_low( ...@@ -86,9 +88,7 @@ ut_malloc_low(
"InnoDB: Check if you should increase the swap file or\n" "InnoDB: Check if you should increase the swap file or\n"
"InnoDB: ulimits of your operating system.\n" "InnoDB: ulimits of your operating system.\n"
"InnoDB: On FreeBSD check you have compiled the OS with\n" "InnoDB: On FreeBSD check you have compiled the OS with\n"
"InnoDB: a big enough maximum process size.\n" "InnoDB: a big enough maximum process size.\n",
"InnoDB: We now intentionally generate a seg fault so that\n"
"InnoDB: on Linux we get a stack trace.\n",
(ulong) n, (ulong) ut_total_allocated_memory, (ulong) n, (ulong) ut_total_allocated_memory,
#ifdef __WIN__ #ifdef __WIN__
(ulong) GetLastError() (ulong) GetLastError()
...@@ -110,7 +110,15 @@ ut_malloc_low( ...@@ -110,7 +110,15 @@ ut_malloc_low(
/* Intentional segfault on NetWare causes an abend. Avoid this /* Intentional segfault on NetWare causes an abend. Avoid this
by graceful exit handling in ut_a(). */ by graceful exit handling in ut_a(). */
#if (!defined __NETWARE__) #if (!defined __NETWARE__)
if (assert_on_error) {
fprintf(stderr,
"InnoDB: We now intentionally generate a seg fault so that\n"
"InnoDB: on Linux we get a stack trace.\n");
if (*ut_mem_null_ptr) ut_mem_null_ptr = 0; if (*ut_mem_null_ptr) ut_mem_null_ptr = 0;
} else {
return(NULL);
}
#else #else
ut_a(0); ut_a(0);
#endif #endif
...@@ -144,7 +152,7 @@ ut_malloc( ...@@ -144,7 +152,7 @@ ut_malloc(
/* out, own: allocated memory */ /* out, own: allocated memory */
ulint n) /* in: number of bytes to allocate */ ulint n) /* in: number of bytes to allocate */
{ {
return(ut_malloc_low(n, TRUE)); return(ut_malloc_low(n, TRUE, TRUE));
} }
/************************************************************************** /**************************************************************************
......
slave stop;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
stop slave;
create table t1(n int);
start slave;
stop slave io_thread;
start slave io_thread;
drop table t1;
source include/master-slave.inc;
#
# Bug#6148 ()
#
connection slave;
stop slave;
# Let the master do lots of insertions
connection master;
create table t1(n int);
let $1=5000;
disable_query_log;
while ($1)
{
eval insert into t1 values($1);
dec $1;
}
enable_query_log;
save_master_pos;
connection slave;
start slave;
sleep 1;
stop slave io_thread;
start slave io_thread;
sync_with_master;
connection master;
drop table t1;
save_master_pos;
connection slave;
sync_with_master;
...@@ -379,18 +379,30 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries, ...@@ -379,18 +379,30 @@ ndb_mgm_connect(NdbMgmHandle handle, int no_retries,
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__, setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
"Unable to connect with connect string: %s", "Unable to connect with connect string: %s",
cfg.makeConnectString(buf,sizeof(buf))); cfg.makeConnectString(buf,sizeof(buf)));
if (verbose == -2)
ndbout << ", failed." << endl;
return -1; return -1;
} }
if (verbose == -1) { if (verbose == -1) {
ndbout << "retrying every " << retry_delay_in_seconds << " seconds:"; ndbout << "Retrying every " << retry_delay_in_seconds << " seconds";
if (no_retries > 0)
ndbout << ". Attempts left:";
else
ndbout << ", until connected.";;
ndbout << flush;
verbose= -2; verbose= -2;
} }
NdbSleep_SecSleep(retry_delay_in_seconds); if (no_retries > 0) {
if (verbose == -2) { if (verbose == -2) {
ndbout << " " << no_retries; ndbout << " " << no_retries;
ndbout << flush;
} }
no_retries--; no_retries--;
} }
NdbSleep_SecSleep(retry_delay_in_seconds);
}
if (verbose == -2)
ndbout << endl;
handle->cfg_i = i; handle->cfg_i = i;
......
...@@ -44,7 +44,7 @@ class CommandInterpreter { ...@@ -44,7 +44,7 @@ class CommandInterpreter {
* Constructor * Constructor
* @param mgmtSrvr: Management server to use when executing commands * @param mgmtSrvr: Management server to use when executing commands
*/ */
CommandInterpreter(const char *); CommandInterpreter(const char *, int verbose);
~CommandInterpreter(); ~CommandInterpreter();
/** /**
...@@ -94,6 +94,7 @@ class CommandInterpreter { ...@@ -94,6 +94,7 @@ class CommandInterpreter {
*/ */
void executeHelp(char* parameters); void executeHelp(char* parameters);
void executeShow(char* parameters); void executeShow(char* parameters);
void executeConnect(char* parameters);
void executePurge(char* parameters); void executePurge(char* parameters);
void executeShutdown(char* parameters); void executeShutdown(char* parameters);
void executeRun(char* parameters); void executeRun(char* parameters);
...@@ -153,6 +154,7 @@ class CommandInterpreter { ...@@ -153,6 +154,7 @@ class CommandInterpreter {
NdbMgmHandle m_mgmsrv; NdbMgmHandle m_mgmsrv;
bool connected; bool connected;
int m_verbose;
int try_reconnect; int try_reconnect;
#ifdef HAVE_GLOBAL_REPLICATION #ifdef HAVE_GLOBAL_REPLICATION
NdbRepHandle m_repserver; NdbRepHandle m_repserver;
...@@ -169,9 +171,9 @@ class CommandInterpreter { ...@@ -169,9 +171,9 @@ class CommandInterpreter {
#include "ndb_mgmclient.hpp" #include "ndb_mgmclient.hpp"
#include "ndb_mgmclient.h" #include "ndb_mgmclient.h"
Ndb_mgmclient::Ndb_mgmclient(const char *host) Ndb_mgmclient::Ndb_mgmclient(const char *host,int verbose)
{ {
m_cmd= new CommandInterpreter(host); m_cmd= new CommandInterpreter(host,verbose);
} }
Ndb_mgmclient::~Ndb_mgmclient() Ndb_mgmclient::~Ndb_mgmclient()
{ {
...@@ -275,6 +277,7 @@ static const char* helpText = ...@@ -275,6 +277,7 @@ static const char* helpText =
"REP CONNECT <host:port> Connect to REP server on host:port\n" "REP CONNECT <host:port> Connect to REP server on host:port\n"
#endif #endif
"PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n" "PURGE STALE SESSIONS Reset reserved nodeid's in the mgmt server\n"
"CONNECT Connect to management server (reconnect if already connected)\n"
"QUIT Quit management client\n" "QUIT Quit management client\n"
; ;
...@@ -373,7 +376,8 @@ convert(const char* s, int& val) { ...@@ -373,7 +376,8 @@ convert(const char* s, int& val) {
/* /*
* Constructor * Constructor
*/ */
CommandInterpreter::CommandInterpreter(const char *_host) CommandInterpreter::CommandInterpreter(const char *_host,int verbose)
: m_verbose(verbose)
{ {
m_mgmsrv = ndb_mgm_create_handle(); m_mgmsrv = ndb_mgm_create_handle();
if(m_mgmsrv == NULL) { if(m_mgmsrv == NULL) {
...@@ -437,7 +441,15 @@ CommandInterpreter::connect() ...@@ -437,7 +441,15 @@ CommandInterpreter::connect()
{ {
if(!connected) { if(!connected) {
if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1)) if(!ndb_mgm_connect(m_mgmsrv, try_reconnect-1, 5, 1))
{
connected = true; connected = true;
if (m_verbose)
{
printf("Connected to Management Server at: %s:%d\n",
ndb_mgm_get_connected_host(m_mgmsrv),
ndb_mgm_get_connected_port(m_mgmsrv));
}
}
} }
return connected; return connected;
} }
...@@ -445,7 +457,7 @@ CommandInterpreter::connect() ...@@ -445,7 +457,7 @@ CommandInterpreter::connect()
bool bool
CommandInterpreter::disconnect() CommandInterpreter::disconnect()
{ {
if (ndb_mgm_disconnect(m_mgmsrv) == -1) { if (connected && (ndb_mgm_disconnect(m_mgmsrv) == -1)) {
ndbout_c("Could not disconnect from management server"); ndbout_c("Could not disconnect from management server");
printError(); printError();
} }
...@@ -459,18 +471,21 @@ CommandInterpreter::disconnect() ...@@ -459,18 +471,21 @@ CommandInterpreter::disconnect()
int int
CommandInterpreter::execute(const char *_line, int _try_reconnect) CommandInterpreter::execute(const char *_line, int _try_reconnect)
{ {
DBUG_ENTER("CommandInterpreter::execute");
DBUG_PRINT("info",("line=\"%s\"",_line));
if (_try_reconnect >= 0) if (_try_reconnect >= 0)
try_reconnect=_try_reconnect; try_reconnect=_try_reconnect;
char * line; char * line;
if(_line == NULL) { if(_line == NULL) {
// ndbout << endl; // ndbout << endl;
return false; DBUG_RETURN(false);
} }
line = my_strdup(_line,MYF(MY_WME)); line = my_strdup(_line,MYF(MY_WME));
My_auto_ptr<char> ptr(line); My_auto_ptr<char> ptr(line);
if (emptyString(line)) { if (emptyString(line)) {
return true; DBUG_RETURN(true);
} }
for (unsigned int i = 0; i < strlen(line); ++i) { for (unsigned int i = 0; i < strlen(line); ++i) {
...@@ -484,41 +499,49 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) ...@@ -484,41 +499,49 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if (strcmp(firstToken, "HELP") == 0 || if (strcmp(firstToken, "HELP") == 0 ||
strcmp(firstToken, "?") == 0) { strcmp(firstToken, "?") == 0) {
executeHelp(allAfterFirstToken); executeHelp(allAfterFirstToken);
return true; DBUG_RETURN(true);
}
else if (strcmp(firstToken, "CONNECT") == 0) {
executeConnect(allAfterFirstToken);
DBUG_RETURN(true);
} }
else if (strcmp(firstToken, "SHOW") == 0) {
if (!connect())
DBUG_RETURN(true);
if (strcmp(firstToken, "SHOW") == 0) {
executeShow(allAfterFirstToken); executeShow(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if (strcmp(firstToken, "SHUTDOWN") == 0) { else if (strcmp(firstToken, "SHUTDOWN") == 0) {
executeShutdown(allAfterFirstToken); executeShutdown(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if (strcmp(firstToken, "CLUSTERLOG") == 0){ else if (strcmp(firstToken, "CLUSTERLOG") == 0){
executeClusterLog(allAfterFirstToken); executeClusterLog(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if(strcmp(firstToken, "START") == 0 && else if(strcmp(firstToken, "START") == 0 &&
allAfterFirstToken != NULL && allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
executeStartBackup(allAfterFirstToken); executeStartBackup(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if(strcmp(firstToken, "ABORT") == 0 && else if(strcmp(firstToken, "ABORT") == 0 &&
allAfterFirstToken != NULL && allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){ strncmp(allAfterFirstToken, "BACKUP", sizeof("BACKUP") - 1) == 0){
executeAbortBackup(allAfterFirstToken); executeAbortBackup(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if (strcmp(firstToken, "PURGE") == 0) { else if (strcmp(firstToken, "PURGE") == 0) {
executePurge(allAfterFirstToken); executePurge(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
#ifdef HAVE_GLOBAL_REPLICATION #ifdef HAVE_GLOBAL_REPLICATION
else if(strcmp(firstToken, "REPLICATION") == 0 || else if(strcmp(firstToken, "REPLICATION") == 0 ||
strcmp(firstToken, "REP") == 0) { strcmp(firstToken, "REP") == 0) {
executeRep(allAfterFirstToken); executeRep(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
#endif // HAVE_GLOBAL_REPLICATION #endif // HAVE_GLOBAL_REPLICATION
else if(strcmp(firstToken, "ENTER") == 0 && else if(strcmp(firstToken, "ENTER") == 0 &&
...@@ -526,14 +549,14 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) ...@@ -526,14 +549,14 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
strncmp(allAfterFirstToken, "SINGLE USER MODE ", strncmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){ sizeof("SINGLE USER MODE") - 1) == 0){
executeEnterSingleUser(allAfterFirstToken); executeEnterSingleUser(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if(strcmp(firstToken, "EXIT") == 0 && else if(strcmp(firstToken, "EXIT") == 0 &&
allAfterFirstToken != NULL && allAfterFirstToken != NULL &&
strncmp(allAfterFirstToken, "SINGLE USER MODE ", strncmp(allAfterFirstToken, "SINGLE USER MODE ",
sizeof("SINGLE USER MODE") - 1) == 0){ sizeof("SINGLE USER MODE") - 1) == 0){
executeExitSingleUser(allAfterFirstToken); executeExitSingleUser(allAfterFirstToken);
return true; DBUG_RETURN(true);
} }
else if (strcmp(firstToken, "ALL") == 0) { else if (strcmp(firstToken, "ALL") == 0) {
analyseAfterFirstToken(-1, allAfterFirstToken); analyseAfterFirstToken(-1, allAfterFirstToken);
...@@ -542,7 +565,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) ...@@ -542,7 +565,7 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
strcmp(firstToken, "EXIT") == 0 || strcmp(firstToken, "EXIT") == 0 ||
strcmp(firstToken, "BYE") == 0) && strcmp(firstToken, "BYE") == 0) &&
allAfterFirstToken == NULL){ allAfterFirstToken == NULL){
return false; DBUG_RETURN(false);
} else { } else {
/** /**
* First token should be a digit, node ID * First token should be a digit, node ID
...@@ -552,18 +575,18 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect) ...@@ -552,18 +575,18 @@ CommandInterpreter::execute(const char *_line, int _try_reconnect)
if (! convert(firstToken, nodeId)) { if (! convert(firstToken, nodeId)) {
ndbout << "Invalid command: " << line << endl; ndbout << "Invalid command: " << line << endl;
ndbout << "Type HELP for help." << endl << endl; ndbout << "Type HELP for help." << endl << endl;
return true; DBUG_RETURN(true);
} }
if (nodeId < 0) { if (nodeId < 0) {
ndbout << "Invalid node ID: " << firstToken << "." << endl; ndbout << "Invalid node ID: " << firstToken << "." << endl;
return true; DBUG_RETURN(true);
} }
analyseAfterFirstToken(nodeId, allAfterFirstToken); analyseAfterFirstToken(nodeId, allAfterFirstToken);
} }
return true; DBUG_RETURN(true);
} }
...@@ -692,7 +715,6 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun, ...@@ -692,7 +715,6 @@ CommandInterpreter::executeForAll(const char * cmd, ExecuteFunction fun,
ndbout_c("Trying to start all nodes of system."); ndbout_c("Trying to start all nodes of system.");
ndbout_c("Use ALL STATUS to see the system start-up phases."); ndbout_c("Use ALL STATUS to see the system start-up phases.");
} else { } else {
connect();
struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv); struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(m_mgmsrv);
if(cl == 0){ if(cl == 0){
ndbout_c("Unable get status from management server"); ndbout_c("Unable get status from management server");
...@@ -826,8 +848,6 @@ CommandInterpreter::executeHelp(char* parameters) ...@@ -826,8 +848,6 @@ CommandInterpreter::executeHelp(char* parameters)
void void
CommandInterpreter::executeShutdown(char* parameters) CommandInterpreter::executeShutdown(char* parameters)
{ {
connect();
ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv); ndb_mgm_cluster_state *state = ndb_mgm_get_status(m_mgmsrv);
if(state == NULL) { if(state == NULL) {
ndbout_c("Could not get status"); ndbout_c("Could not get status");
...@@ -979,7 +999,6 @@ CommandInterpreter::executePurge(char* parameters) ...@@ -979,7 +999,6 @@ CommandInterpreter::executePurge(char* parameters)
int i; int i;
char *str; char *str;
connect();
if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) { if (ndb_mgm_purge_stale_sessions(m_mgmsrv, &str)) {
ndbout_c("Command failed"); ndbout_c("Command failed");
...@@ -999,7 +1018,6 @@ void ...@@ -999,7 +1018,6 @@ void
CommandInterpreter::executeShow(char* parameters) CommandInterpreter::executeShow(char* parameters)
{ {
int i; int i;
connect();
if (emptyString(parameters)) { if (emptyString(parameters)) {
ndbout << "Cluster Configuration" << endl ndbout << "Cluster Configuration" << endl
<< "---------------------" << endl; << "---------------------" << endl;
...@@ -1087,6 +1105,12 @@ CommandInterpreter::executeShow(char* parameters) ...@@ -1087,6 +1105,12 @@ CommandInterpreter::executeShow(char* parameters)
} }
} }
void
CommandInterpreter::executeConnect(char* parameters)
{
disconnect();
connect();
}
//***************************************************************************** //*****************************************************************************
//***************************************************************************** //*****************************************************************************
...@@ -1094,7 +1118,6 @@ void ...@@ -1094,7 +1118,6 @@ void
CommandInterpreter::executeClusterLog(char* parameters) CommandInterpreter::executeClusterLog(char* parameters)
{ {
int i; int i;
connect();
if (parameters != 0 && strlen(parameters) != 0) { if (parameters != 0 && strlen(parameters) != 0) {
enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL; enum ndb_mgm_clusterlog_level severity = NDB_MGM_CLUSTERLOG_ALL;
int isOk = true; int isOk = true;
...@@ -1240,7 +1263,6 @@ CommandInterpreter::executeClusterLog(char* parameters) ...@@ -1240,7 +1263,6 @@ CommandInterpreter::executeClusterLog(char* parameters)
void void
CommandInterpreter::executeStop(int processId, const char *, bool all) CommandInterpreter::executeStop(int processId, const char *, bool all)
{ {
connect();
int result = 0; int result = 0;
if(all) { if(all) {
result = ndb_mgm_stop(m_mgmsrv, 0, 0); result = ndb_mgm_stop(m_mgmsrv, 0, 0);
...@@ -1262,7 +1284,6 @@ CommandInterpreter::executeStop(int processId, const char *, bool all) ...@@ -1262,7 +1284,6 @@ CommandInterpreter::executeStop(int processId, const char *, bool all)
void void
CommandInterpreter::executeEnterSingleUser(char* parameters) CommandInterpreter::executeEnterSingleUser(char* parameters)
{ {
connect();
strtok(parameters, " "); strtok(parameters, " ");
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
char* id = strtok(NULL, " "); char* id = strtok(NULL, " ");
...@@ -1289,7 +1310,6 @@ CommandInterpreter::executeEnterSingleUser(char* parameters) ...@@ -1289,7 +1310,6 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
void void
CommandInterpreter::executeExitSingleUser(char* parameters) CommandInterpreter::executeExitSingleUser(char* parameters)
{ {
connect();
int result = ndb_mgm_exit_single_user(m_mgmsrv, 0); int result = ndb_mgm_exit_single_user(m_mgmsrv, 0);
if (result != 0) { if (result != 0) {
ndbout_c("Exiting single user mode failed."); ndbout_c("Exiting single user mode failed.");
...@@ -1304,7 +1324,6 @@ void ...@@ -1304,7 +1324,6 @@ void
CommandInterpreter::executeStart(int processId, const char* parameters, CommandInterpreter::executeStart(int processId, const char* parameters,
bool all) bool all)
{ {
connect();
int result; int result;
if(all) { if(all) {
result = ndb_mgm_start(m_mgmsrv, 0, 0); result = ndb_mgm_start(m_mgmsrv, 0, 0);
...@@ -1328,7 +1347,6 @@ void ...@@ -1328,7 +1347,6 @@ void
CommandInterpreter::executeRestart(int processId, const char* parameters, CommandInterpreter::executeRestart(int processId, const char* parameters,
bool all) bool all)
{ {
connect();
int result; int result;
int nostart = 0; int nostart = 0;
int initialstart = 0; int initialstart = 0;
...@@ -1378,7 +1396,6 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters, ...@@ -1378,7 +1396,6 @@ CommandInterpreter::executeDumpState(int processId, const char* parameters,
ndbout << "Expected argument" << endl; ndbout << "Expected argument" << endl;
return; return;
} }
connect();
Uint32 no = 0; Uint32 no = 0;
int pars[25]; int pars[25];
...@@ -1418,7 +1435,6 @@ CommandInterpreter::executeStatus(int processId, ...@@ -1418,7 +1435,6 @@ CommandInterpreter::executeStatus(int processId,
return; return;
} }
connect();
ndb_mgm_node_status status; ndb_mgm_node_status status;
Uint32 startPhase, version; Uint32 startPhase, version;
bool system; bool system;
...@@ -1469,7 +1485,6 @@ void ...@@ -1469,7 +1485,6 @@ void
CommandInterpreter::executeLogLevel(int processId, const char* parameters, CommandInterpreter::executeLogLevel(int processId, const char* parameters,
bool all) bool all)
{ {
connect();
(void) all; (void) all;
BaseString tmp(parameters); BaseString tmp(parameters);
...@@ -1525,7 +1540,6 @@ void CommandInterpreter::executeError(int processId, ...@@ -1525,7 +1540,6 @@ void CommandInterpreter::executeError(int processId,
return; return;
} }
connect();
// Copy parameters since strtok will modify it // Copy parameters since strtok will modify it
char* newpar = my_strdup(parameters,MYF(MY_WME)); char* newpar = my_strdup(parameters,MYF(MY_WME));
My_auto_ptr<char> ap1(newpar); My_auto_ptr<char> ap1(newpar);
...@@ -1589,7 +1603,6 @@ void ...@@ -1589,7 +1603,6 @@ void
CommandInterpreter::executeLog(int processId, CommandInterpreter::executeLog(int processId,
const char* parameters, bool all) const char* parameters, bool all)
{ {
connect();
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
Vector<const char *> blocks; Vector<const char *> blocks;
if (! parseBlockSpecification(parameters, blocks)) { if (! parseBlockSpecification(parameters, blocks)) {
...@@ -1657,7 +1670,6 @@ CommandInterpreter::executeTestOn(int processId, ...@@ -1657,7 +1670,6 @@ CommandInterpreter::executeTestOn(int processId,
ndbout << "No parameters expected to this command." << endl; ndbout << "No parameters expected to this command." << endl;
return; return;
} }
connect();
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply); int result = ndb_mgm_start_signallog(m_mgmsrv, processId, &reply);
if (result != 0) { if (result != 0) {
...@@ -1676,7 +1688,6 @@ CommandInterpreter::executeTestOff(int processId, ...@@ -1676,7 +1688,6 @@ CommandInterpreter::executeTestOff(int processId,
ndbout << "No parameters expected to this command." << endl; ndbout << "No parameters expected to this command." << endl;
return; return;
} }
connect();
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply); int result = ndb_mgm_stop_signallog(m_mgmsrv, processId, &reply);
if (result != 0) { if (result != 0) {
...@@ -1798,8 +1809,6 @@ CommandInterpreter::executeEventReporting(int processId, ...@@ -1798,8 +1809,6 @@ CommandInterpreter::executeEventReporting(int processId,
ndbout << "Expected argument" << endl; ndbout << "Expected argument" << endl;
return; return;
} }
connect();
BaseString tmp(parameters); BaseString tmp(parameters);
Vector<BaseString> spec; Vector<BaseString> spec;
tmp.split(spec, "="); tmp.split(spec, "=");
...@@ -1850,7 +1859,6 @@ CommandInterpreter::executeEventReporting(int processId, ...@@ -1850,7 +1859,6 @@ CommandInterpreter::executeEventReporting(int processId,
void void
CommandInterpreter::executeStartBackup(char* /*parameters*/) CommandInterpreter::executeStartBackup(char* /*parameters*/)
{ {
connect();
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
unsigned int backupId; unsigned int backupId;
...@@ -1897,8 +1905,6 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/) ...@@ -1897,8 +1905,6 @@ CommandInterpreter::executeStartBackup(char* /*parameters*/)
void void
CommandInterpreter::executeAbortBackup(char* parameters) CommandInterpreter::executeAbortBackup(char* parameters)
{ {
connect();
strtok(parameters, " "); strtok(parameters, " ");
struct ndb_mgm_reply reply; struct ndb_mgm_reply reply;
char* id = strtok(NULL, "\0"); char* id = strtok(NULL, "\0");
...@@ -1952,7 +1958,6 @@ CommandInterpreter::executeRep(char* parameters) ...@@ -1952,7 +1958,6 @@ CommandInterpreter::executeRep(char* parameters)
return; return;
} }
connect();
char * line = my_strdup(parameters,MYF(MY_WME)); char * line = my_strdup(parameters,MYF(MY_WME));
My_auto_ptr<char> ap1((char*)line); My_auto_ptr<char> ap1((char*)line);
char * firstToken = strtok(line, " "); char * firstToken = strtok(line, " ");
......
...@@ -56,17 +56,18 @@ handler(int sig){ ...@@ -56,17 +56,18 @@ handler(int sig){
} }
} }
static const char default_prompt[]= "ndb_mgm> ";
static unsigned _try_reconnect; static unsigned _try_reconnect;
static char *opt_connect_str= 0; static char *opt_connect_str= 0;
static const char *prompt= default_prompt;
static struct my_option my_long_options[] = static struct my_option my_long_options[] =
{ {
NDB_STD_OPTS("ndb_mgm"), NDB_STD_OPTS("ndb_mgm"),
{ "try-reconnect", 't', { "try-reconnect", 't',
"Specify number of retries for connecting to ndb_mgmd, default infinite", "Specify number of tries for connecting to ndb_mgmd (0 = infinite)",
(gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0, (gptr*) &_try_reconnect, (gptr*) &_try_reconnect, 0,
GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, GET_UINT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
}; };
static void short_usage_sub(void) static void short_usage_sub(void)
...@@ -116,13 +117,13 @@ read_and_execute(int _try_reconnect) ...@@ -116,13 +117,13 @@ read_and_execute(int _try_reconnect)
} }
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
/* Get a line from the user. */ /* Get a line from the user. */
line_read = readline ("ndb_mgm> "); line_read = readline (prompt);
/* If the line has any text in it, save it on the history. */ /* If the line has any text in it, save it on the history. */
if (line_read && *line_read) if (line_read && *line_read)
add_history (line_read); add_history (line_read);
#else #else
static char linebuffer[254]; static char linebuffer[254];
fputs("ndb_mgm> ", stdout); fputs(prompt, stdout);
linebuffer[sizeof(linebuffer)-1]=0; linebuffer[sizeof(linebuffer)-1]=0;
line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin); line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
if (line_read == linebuffer) { if (line_read == linebuffer) {
...@@ -155,12 +156,16 @@ int main(int argc, char** argv){ ...@@ -155,12 +156,16 @@ int main(int argc, char** argv){
opt_connect_str= buf; opt_connect_str= buf;
} }
if (!isatty(0))
{
prompt= 0;
}
ndbout << "-- NDB Cluster -- Management Client --" << endl; ndbout << "-- NDB Cluster -- Management Client --" << endl;
printf("Connecting to Management Server: %s\n", opt_connect_str ? opt_connect_str : "default");
signal(SIGPIPE, handler); signal(SIGPIPE, handler);
com = new Ndb_mgmclient(opt_connect_str); com = new Ndb_mgmclient(opt_connect_str,1);
while(read_and_execute(_try_reconnect)); while(read_and_execute(_try_reconnect));
delete com; delete com;
......
...@@ -21,7 +21,7 @@ class CommandInterpreter; ...@@ -21,7 +21,7 @@ class CommandInterpreter;
class Ndb_mgmclient class Ndb_mgmclient
{ {
public: public:
Ndb_mgmclient(const char*); Ndb_mgmclient(const char*,int verbose=0);
~Ndb_mgmclient(); ~Ndb_mgmclient();
int execute(const char *_line, int _try_reconnect=-1); int execute(const char *_line, int _try_reconnect=-1);
int execute(int argc, char** argv, int _try_reconnect=-1); int execute(int argc, char** argv, int _try_reconnect=-1);
......
...@@ -432,15 +432,20 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server, ...@@ -432,15 +432,20 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
theFacade = 0; theFacade = 0;
m_newConfig = NULL; m_newConfig = NULL;
if (config_filename)
m_configFilename.assign(config_filename); m_configFilename.assign(config_filename);
else
m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0; m_nextConfigGenerationNumber = 0;
m_config_retriever= new ConfigRetriever(connect_string, m_config_retriever= new ConfigRetriever(connect_string,
NDB_VERSION, NDB_MGM_NODE_TYPE_MGM); NDB_VERSION, NDB_MGM_NODE_TYPE_MGM);
// if connect_string explicitly given or
// no config filename is given then
// first try to allocate nodeid from another management server // first try to allocate nodeid from another management server
if(m_config_retriever->do_connect(0,0,0) == 0) if ((connect_string || config_filename == NULL) &&
(m_config_retriever->do_connect(0,0,0) == 0))
{ {
int tmp_nodeid= 0; int tmp_nodeid= 0;
tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/); tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
......
...@@ -176,7 +176,6 @@ int main(int argc, char** argv) ...@@ -176,7 +176,6 @@ int main(int argc, char** argv)
#endif #endif
global_mgmt_server_check = 1; global_mgmt_server_check = 1;
glob.config_filename= "config.ini";
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 }; const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv); load_defaults("my",load_default_groups,&argc,&argv);
......
...@@ -241,11 +241,12 @@ ErrorBundle ErrorCodes[] = { ...@@ -241,11 +241,12 @@ ErrorBundle ErrorCodes[] = {
{ 877, AE, "877" }, { 877, AE, "877" },
{ 878, AE, "878" }, { 878, AE, "878" },
{ 879, AE, "879" }, { 879, AE, "879" },
{ 880, AE, "Tried to read too much - too many getValue calls" },
{ 884, AE, "Stack overflow in interpreter" }, { 884, AE, "Stack overflow in interpreter" },
{ 885, AE, "Stack underflow in interpreter" }, { 885, AE, "Stack underflow in interpreter" },
{ 886, AE, "More than 65535 instructions executed in interpreter" }, { 886, AE, "More than 65535 instructions executed in interpreter" },
{ 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" },
{ 4256, AE, "Must call Ndb::init() before this function" }, { 4256, AE, "Must call Ndb::init() before this function" },
{ 880, AE, "Tried to read too much - too many getValue calls" },
{ 4257, AE, "Tried to read too much - too many getValue calls" }, { 4257, AE, "Tried to read too much - too many getValue calls" },
/** /**
......
...@@ -410,6 +410,9 @@ convert_error_code_to_mysql( ...@@ -410,6 +410,9 @@ convert_error_code_to_mysql(
} else if (error == (int) DB_NO_SAVEPOINT) { } else if (error == (int) DB_NO_SAVEPOINT) {
return(HA_ERR_NO_SAVEPOINT); return(HA_ERR_NO_SAVEPOINT);
} else if (error == (int) DB_LOCK_TABLE_FULL) {
return(HA_ERR_LOCK_TABLE_FULL);
} else { } else {
return(-1); // Unknown error return(-1); // Unknown error
} }
......
...@@ -918,7 +918,7 @@ bool load_master_data(THD* thd) ...@@ -918,7 +918,7 @@ bool load_master_data(THD* thd)
int error; int error;
if (init_master_info(active_mi, master_info_file, relay_log_info_file, if (init_master_info(active_mi, master_info_file, relay_log_info_file,
0)) 0, (SLAVE_IO | SLAVE_SQL)))
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
strmake(active_mi->master_log_name, row[0], strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name)); sizeof(active_mi->master_log_name));
......
...@@ -160,7 +160,7 @@ int init_slave() ...@@ -160,7 +160,7 @@ int init_slave()
} }
if (init_master_info(active_mi,master_info_file,relay_log_info_file, if (init_master_info(active_mi,master_info_file,relay_log_info_file,
!master_host)) !master_host, (SLAVE_IO | SLAVE_SQL)))
{ {
sql_print_error("Failed to initialize the master info structure"); sql_print_error("Failed to initialize the master info structure");
goto err; goto err;
...@@ -1981,7 +1981,8 @@ void clear_until_condition(RELAY_LOG_INFO* rli) ...@@ -1981,7 +1981,8 @@ void clear_until_condition(RELAY_LOG_INFO* rli)
int init_master_info(MASTER_INFO* mi, const char* master_info_fname, int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname, const char* slave_info_fname,
bool abort_if_no_master_info_file) bool abort_if_no_master_info_file,
int thread_mask)
{ {
int fd,error; int fd,error;
char fname[FN_REFLEN+128]; char fname[FN_REFLEN+128];
...@@ -1995,8 +1996,15 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname, ...@@ -1995,8 +1996,15 @@ int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
last time. If this case pos_in_file would be set and we would last time. If this case pos_in_file would be set and we would
get a crash when trying to read the signature for the binary get a crash when trying to read the signature for the binary
relay log. relay log.
We only rewind the read position if we are starting the SQL
thread. The handle_slave_sql thread assumes that the read
position is at the beginning of the file, and will read the
"signature" and then fast-forward to the last position read.
*/ */
if (thread_mask & SLAVE_SQL) {
my_b_seek(mi->rli.cur_log, (my_off_t) 0); my_b_seek(mi->rli.cur_log, (my_off_t) 0);
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
...@@ -520,7 +520,8 @@ void clear_until_condition(RELAY_LOG_INFO* rli); ...@@ -520,7 +520,8 @@ void clear_until_condition(RELAY_LOG_INFO* rli);
void clear_slave_error_timestamp(RELAY_LOG_INFO* rli); void clear_slave_error_timestamp(RELAY_LOG_INFO* rli);
int init_master_info(MASTER_INFO* mi, const char* master_info_fname, int init_master_info(MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname, const char* slave_info_fname,
bool abort_if_no_master_info_file); bool abort_if_no_master_info_file,
int thread_mask);
void end_master_info(MASTER_INFO* mi); void end_master_info(MASTER_INFO* mi);
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname); int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
void end_relay_log_info(RELAY_LOG_INFO* rli); void end_relay_log_info(RELAY_LOG_INFO* rli);
......
...@@ -779,7 +779,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report) ...@@ -779,7 +779,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
thread_mask&= thd->lex->slave_thd_opt; thread_mask&= thd->lex->slave_thd_opt;
if (thread_mask) //some threads are stopped, start them if (thread_mask) //some threads are stopped, start them
{ {
if (init_master_info(mi,master_info_file,relay_log_info_file, 0)) if (init_master_info(mi,master_info_file,relay_log_info_file, 0,
thread_mask))
slave_errno=ER_MASTER_INFO; slave_errno=ER_MASTER_INFO;
else if (server_id_supplied && *mi->host) else if (server_id_supplied && *mi->host)
{ {
...@@ -1074,7 +1075,8 @@ bool change_master(THD* thd, MASTER_INFO* mi) ...@@ -1074,7 +1075,8 @@ bool change_master(THD* thd, MASTER_INFO* mi)
thd->proc_info = "Changing master"; thd->proc_info = "Changing master";
LEX_MASTER_INFO* lex_mi= &thd->lex->mi; LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
// TODO: see if needs re-write // TODO: see if needs re-write
if (init_master_info(mi, master_info_file, relay_log_info_file, 0)) if (init_master_info(mi, master_info_file, relay_log_info_file, 0,
thread_mask))
{ {
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0)); my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
unlock_slave_threads(mi); unlock_slave_threads(mi);
......
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