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

into poseidon.ndb.mysql.com:/home/tomas/mysql-5.0


BitKeeper/etc/logging_ok:
  auto-union
innobase/buf/buf0buf.c:
  Auto merged
innobase/buf/buf0lru.c:
  Auto merged
innobase/row/row0mysql.c:
  Auto merged
innobase/row/row0sel.c:
  Auto merged
ndb/src/mgmsrv/main.cpp:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/repl_failsafe.cc:
  Auto merged
sql/slave.cc:
  Auto merged
sql/slave.h:
  Auto merged
sql/sql_repl.cc:
  Auto merged
This commit is contained in:
unknown 2004-11-26 13:44:49 +00:00
commit 42af43e375
26 changed files with 250 additions and 88 deletions

View File

@ -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)

View File

@ -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) {

View File

@ -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)
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 @@ loop:
} 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 @@ loop:
"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;
} }

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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. */

View File

@ -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));

View File

@ -308,7 +308,8 @@ handle_new_error:
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 */

View File

@ -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(
/* 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 */

View File

@ -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);
} }

View File

@ -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(
"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(
/* 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(
/* 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));
} }
/************************************************************************** /**************************************************************************

View File

@ -0,0 +1,12 @@
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;

View File

@ -0,0 +1,34 @@
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;

View File

@ -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;

View File

@ -44,7 +44,7 @@ public:
* 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 @@ private:
*/ */
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 @@ private:
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 @@ private:
#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 =
"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) {
/* /*
* 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()
{ {
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()
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()
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)
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, "SHOW") == 0) { else if (strcmp(firstToken, "CONNECT") == 0) {
executeConnect(allAfterFirstToken);
DBUG_RETURN(true);
}
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)
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)
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)
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,
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)
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)
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
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)
} }
} }
void
CommandInterpreter::executeConnect(char* parameters)
{
disconnect();
connect();
}
//***************************************************************************** //*****************************************************************************
//***************************************************************************** //*****************************************************************************
@ -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)
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)
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)
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
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
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,
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,
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
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,
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
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,
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,
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,
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,
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*/)
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)
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, " ");

View File

@ -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)
} }
#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){
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;

View File

@ -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);

View File

@ -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*/);

View File

@ -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);

View File

@ -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" },
/** /**

View File

@ -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
} }

View File

@ -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));

View File

@ -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)
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,
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);
} }

View File

@ -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);

View File

@ -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)
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);