Commit 65a1eb18 authored by unknown's avatar unknown

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

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

parents f01820f2 42af43e3
......@@ -104,6 +104,7 @@ lenz@mysql.com
magnus@neptunus.(none)
magnus@shellback.(none)
marko@hundin.mysql.fi
mats@mysql.com
matt@mysql.com
matthias@three.local.lan
miguel@hegel.(none)
......
......@@ -548,8 +548,9 @@ buf_pool_init(
}
/*----------------------------------------*/
} else {
buf_pool->frame_mem = ut_malloc(
UNIV_PAGE_SIZE * (n_frames + 1));
buf_pool->frame_mem = ut_malloc_low(
UNIV_PAGE_SIZE * (n_frames + 1),
TRUE, FALSE);
}
if (buf_pool->frame_mem == NULL) {
......
......@@ -42,6 +42,10 @@ initial segment in buf_LRU_get_recent_limit */
#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
state to BUF_BLOCK_REMOVE_HASH. */
......@@ -287,6 +291,32 @@ buf_LRU_try_free_flushed_blocks(void)
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.
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)
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ 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
heaps or the adaptive hash index. This may be a memory
......@@ -342,16 +373,18 @@ buf_LRU_get_free_block(void)
"InnoDB: lock heap and hash index sizes.\n",
(ulong) (buf_pool->curr_size / (1024 * 1024 / UNIV_PAGE_SIZE)));
buf_lru_switched_on_innodb_mon = TRUE;
srv_print_innodb_monitor = TRUE;
os_event_set(srv_lock_timeout_thread_event);
}
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
} else if (buf_lru_switched_on_innodb_mon) {
/* Switch off the InnoDB Monitor; this is a simple way
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;
}
......
......@@ -25,6 +25,16 @@ wasted. */
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
......
......@@ -53,7 +53,11 @@ Created 5/24/1996 Heikki Tuuri
name already exists */
#define DB_TABLESPACE_DELETED 44 /* tablespace does not exist or is
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 */
#define DB_FAIL 1000
#define DB_OVERFLOW 1001
......
......@@ -120,6 +120,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */
......
......@@ -38,8 +38,10 @@ ut_malloc_low(
/*==========*/
/* out, own: allocated memory */
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 */
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
defined. */
......
......@@ -199,7 +199,7 @@ mem_pool_create(
but only when allocated at a higher level in mem0mem.c.
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;
mutex_create(&(pool->mutex));
......
......@@ -308,7 +308,8 @@ row_mysql_handle_errors(
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
to version 3.23.43 */
......
......@@ -730,8 +730,18 @@ sel_set_rec_lock(
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or LOC_REC_NOT_GAP */
que_thr_t* thr) /* in: query thread */
{
trx_t* trx;
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) {
err = lock_clust_rec_read_check_and_lock(0, rec, index, mode,
type, thr);
......@@ -2790,6 +2800,7 @@ row_search_for_mysql(
/* out: DB_SUCCESS,
DB_RECORD_NOT_FOUND,
DB_END_OF_INDEX, DB_DEADLOCK,
DB_LOCK_TABLE_FULL,
or DB_TOO_BIG_RECORD */
byte* buf, /* in/out: buffer for the fetched
row in the MySQL format */
......
......@@ -1172,6 +1172,9 @@ NetWare. */
}
if (ret == NULL) {
fprintf(stderr,
"InnoDB: Fatal error: cannot allocate the memory for the buffer pool\n");
return(DB_ERROR);
}
......
......@@ -61,8 +61,10 @@ ut_malloc_low(
/*==========*/
/* out, own: allocated memory */
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 */
ibool assert_on_error) /* in: if TRUE, we crash mysqld if the memory
cannot be allocated */
{
void* ret;
......@@ -86,9 +88,7 @@ ut_malloc_low(
"InnoDB: Check if you should increase the swap file or\n"
"InnoDB: ulimits of your operating system.\n"
"InnoDB: On FreeBSD check you have compiled the OS with\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",
"InnoDB: a big enough maximum process size.\n",
(ulong) n, (ulong) ut_total_allocated_memory,
#ifdef __WIN__
(ulong) GetLastError()
......@@ -110,7 +110,15 @@ ut_malloc_low(
/* Intentional segfault on NetWare causes an abend. Avoid this
by graceful exit handling in ut_a(). */
#if (!defined __NETWARE__)
if (*ut_mem_null_ptr) ut_mem_null_ptr = 0;
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;
} else {
return(NULL);
}
#else
ut_a(0);
#endif
......@@ -144,7 +152,7 @@ ut_malloc(
/* out, own: allocated memory */
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,
setError(handle, NDB_MGM_COULD_NOT_CONNECT_TO_SOCKET, __LINE__,
"Unable to connect with connect string: %s",
cfg.makeConnectString(buf,sizeof(buf)));
if (verbose == -2)
ndbout << ", failed." << endl;
return -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;
}
NdbSleep_SecSleep(retry_delay_in_seconds);
if (verbose == -2) {
ndbout << " " << no_retries;
if (no_retries > 0) {
if (verbose == -2) {
ndbout << " " << no_retries;
ndbout << flush;
}
no_retries--;
}
no_retries--;
NdbSleep_SecSleep(retry_delay_in_seconds);
}
if (verbose == -2)
ndbout << endl;
handle->cfg_i = i;
......
This diff is collapsed.
......@@ -56,17 +56,18 @@ handler(int sig){
}
}
static const char default_prompt[]= "ndb_mgm> ";
static unsigned _try_reconnect;
static char *opt_connect_str= 0;
static const char *prompt= default_prompt;
static struct my_option my_long_options[] =
{
NDB_STD_OPTS("ndb_mgm"),
{ "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,
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}
};
static void short_usage_sub(void)
......@@ -116,13 +117,13 @@ read_and_execute(int _try_reconnect)
}
#ifdef HAVE_READLINE
/* 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 (line_read && *line_read)
add_history (line_read);
#else
static char linebuffer[254];
fputs("ndb_mgm> ", stdout);
fputs(prompt, stdout);
linebuffer[sizeof(linebuffer)-1]=0;
line_read = fgets(linebuffer, sizeof(linebuffer)-1, stdin);
if (line_read == linebuffer) {
......@@ -155,12 +156,16 @@ int main(int argc, char** argv){
opt_connect_str= buf;
}
if (!isatty(0))
{
prompt= 0;
}
ndbout << "-- NDB Cluster -- Management Client --" << endl;
printf("Connecting to Management Server: %s\n", opt_connect_str ? opt_connect_str : "default");
signal(SIGPIPE, handler);
com = new Ndb_mgmclient(opt_connect_str);
com = new Ndb_mgmclient(opt_connect_str,1);
while(read_and_execute(_try_reconnect));
delete com;
......
......@@ -21,7 +21,7 @@ class CommandInterpreter;
class Ndb_mgmclient
{
public:
Ndb_mgmclient(const char*);
Ndb_mgmclient(const char*,int verbose=0);
~Ndb_mgmclient();
int execute(const char *_line, int _try_reconnect=-1);
int execute(int argc, char** argv, int _try_reconnect=-1);
......
......@@ -432,15 +432,20 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
theFacade = 0;
m_newConfig = NULL;
m_configFilename.assign(config_filename);
if (config_filename)
m_configFilename.assign(config_filename);
else
m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0;
m_config_retriever= new ConfigRetriever(connect_string,
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
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;
tmp_nodeid= m_config_retriever->allocNodeId(0 /*retry*/,0 /*delay*/);
......
......@@ -176,7 +176,6 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
glob.config_filename= "config.ini";
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
......
......@@ -241,11 +241,12 @@ ErrorBundle ErrorCodes[] = {
{ 877, AE, "877" },
{ 878, AE, "878" },
{ 879, AE, "879" },
{ 880, AE, "Tried to read too much - too many getValue calls" },
{ 884, AE, "Stack overflow in interpreter" },
{ 885, AE, "Stack underflow 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" },
{ 880, 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(
} else if (error == (int) DB_NO_SAVEPOINT) {
return(HA_ERR_NO_SAVEPOINT);
} else if (error == (int) DB_LOCK_TABLE_FULL) {
return(HA_ERR_LOCK_TABLE_FULL);
} else {
return(-1); // Unknown error
}
......
......@@ -917,8 +917,8 @@ bool load_master_data(THD* thd)
*/
int error;
if (init_master_info(active_mi, master_info_file, relay_log_info_file,
0))
if (init_master_info(active_mi, master_info_file, relay_log_info_file,
0, (SLAVE_IO | SLAVE_SQL)))
my_message(ER_MASTER_INFO, ER(ER_MASTER_INFO), MYF(0));
strmake(active_mi->master_log_name, row[0],
sizeof(active_mi->master_log_name));
......
......@@ -160,7 +160,7 @@ int init_slave()
}
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");
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,
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;
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
get a crash when trying to read the signature for the binary
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.
*/
my_b_seek(mi->rli.cur_log, (my_off_t) 0);
if (thread_mask & SLAVE_SQL) {
my_b_seek(mi->rli.cur_log, (my_off_t) 0);
}
DBUG_RETURN(0);
}
......
......@@ -520,7 +520,8 @@ void clear_until_condition(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,
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);
int init_relay_log_info(RELAY_LOG_INFO* rli, const char* info_fname);
void end_relay_log_info(RELAY_LOG_INFO* rli);
......
......@@ -779,7 +779,8 @@ int start_slave(THD* thd , MASTER_INFO* mi, bool net_report)
thread_mask&= thd->lex->slave_thd_opt;
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;
else if (server_id_supplied && *mi->host)
{
......@@ -1074,7 +1075,8 @@ bool change_master(THD* thd, MASTER_INFO* mi)
thd->proc_info = "Changing master";
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
// 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));
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