summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/buf/buf0buf.c4
-rw-r--r--storage/innobase/buf/buf0flu.c4
-rw-r--r--storage/innobase/data/data0data.c10
-rw-r--r--storage/innobase/dict/dict0dict.c24
-rw-r--r--storage/innobase/include/btr0btr.h10
-rw-r--r--storage/innobase/include/data0type.ic2
-rw-r--r--storage/innobase/include/dict0dict.h7
-rw-r--r--storage/innobase/include/dict0mem.h14
-rw-r--r--storage/innobase/include/mem0mem.h3
-rw-r--r--storage/innobase/include/mem0mem.ic3
-rw-r--r--storage/innobase/include/os0file.h11
-rw-r--r--storage/innobase/include/row0mysql.h10
-rw-r--r--storage/innobase/include/trx0trx.h21
-rw-r--r--storage/innobase/include/ut0mem.h25
-rw-r--r--storage/innobase/mem/mem0mem.c4
-rw-r--r--storage/innobase/os/os0file.c23
-rw-r--r--storage/innobase/os/os0proc.c9
-rw-r--r--storage/innobase/rem/rem0rec.c2
-rw-r--r--storage/innobase/row/row0ins.c43
-rw-r--r--storage/innobase/row/row0mysql.c21
-rw-r--r--storage/innobase/srv/srv0start.c2
-rw-r--r--storage/innobase/trx/trx0sys.c19
-rw-r--r--storage/innobase/trx/trx0trx.c27
-rw-r--r--storage/innobase/ut/ut0mem.c48
-rw-r--r--storage/myisam/ft_boolean_search.c3
-rw-r--r--storage/myisam/mi_check.c40
-rw-r--r--storage/myisam/mi_dbug.c4
-rw-r--r--storage/myisam/mi_delete.c2
-rw-r--r--storage/myisam/mi_delete_all.c2
-rw-r--r--storage/myisam/mi_key.c2
-rw-r--r--storage/myisam/mi_open.c11
-rw-r--r--storage/myisam/mi_rkey.c7
-rw-r--r--storage/myisam/mi_search.c16
-rw-r--r--storage/myisam/mi_test1.c5
-rw-r--r--storage/myisam/mi_update.c2
-rw-r--r--storage/myisam/mi_write.c2
-rw-r--r--storage/myisam/myisamchk.c30
-rw-r--r--storage/myisam/myisamdef.h7
-rw-r--r--storage/myisam/myisampack.c22
-rw-r--r--storage/myisam/sp_key.c2
-rw-r--r--storage/myisammrg/myrg_rkey.c17
-rw-r--r--storage/ndb/include/kernel/GlobalSignalNumbers.h10
-rw-r--r--storage/ndb/include/kernel/signaldata/ApiVersion.hpp5
-rw-r--r--storage/ndb/include/kernel/signaldata/StopReq.hpp10
-rw-r--r--storage/ndb/include/mgmapi/ndb_logevent.h11
-rw-r--r--storage/ndb/include/ndbapi/Ndb.hpp28
-rw-r--r--storage/ndb/include/ndbapi/NdbBlob.hpp6
-rw-r--r--storage/ndb/include/ndbapi/NdbIndexOperation.hpp1
-rw-r--r--storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp3
-rw-r--r--storage/ndb/include/ndbapi/NdbOperation.hpp7
-rw-r--r--storage/ndb/include/ndbapi/NdbRecAttr.hpp7
-rw-r--r--storage/ndb/include/ndbapi/NdbTransaction.hpp8
-rw-r--r--storage/ndb/src/common/debugger/EventLogger.cpp24
-rw-r--r--storage/ndb/src/common/util/SimpleProperties.cpp7
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp8
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Makefile.am12
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp169
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp15
-rw-r--r--storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp65
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp2
-rw-r--r--storage/ndb/src/mgmapi/ndb_logevent.cpp2
-rw-r--r--storage/ndb/src/mgmclient/CommandInterpreter.cpp7
-rw-r--r--storage/ndb/src/mgmsrv/Config.cpp87
-rw-r--r--storage/ndb/src/mgmsrv/Config.hpp10
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.cpp52
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.cpp377
-rw-r--r--storage/ndb/src/mgmsrv/InitConfigFileParser.hpp22
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp1536
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.hpp190
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp241
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp120
-rw-r--r--storage/ndb/src/mgmsrv/Services.cpp59
-rw-r--r--storage/ndb/src/mgmsrv/Services.hpp3
-rw-r--r--storage/ndb/src/mgmsrv/main.cpp24
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.cpp19
-rw-r--r--storage/ndb/src/ndbapi/NdbApiSignal.hpp3
-rw-r--r--storage/ndb/src/ndbapi/NdbBlob.cpp2
-rw-r--r--storage/ndb/src/ndbapi/NdbImpl.hpp119
-rw-r--r--storage/ndb/src/ndbapi/NdbRecAttr.cpp4
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.cpp16
-rw-r--r--storage/ndb/src/ndbapi/NdbUtil.hpp41
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp9
-rw-r--r--storage/ndb/src/ndbapi/Ndbinit.cpp46
-rw-r--r--storage/ndb/src/ndbapi/Ndblist.cpp506
-rw-r--r--storage/ndb/src/ndbapi/ObjectMap.hpp33
-rw-r--r--storage/ndb/tools/ndb_condig.cpp221
-rw-r--r--storage/ndb/tools/restore/Restore.cpp2
-rw-r--r--storage/ndb/tools/restore/consumer_restore.cpp2
89 files changed, 2204 insertions, 2468 deletions
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index aa3aef7f97c..3a3b64dd51b 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -321,7 +321,9 @@ buf_page_is_corrupted(
fprintf(stderr,
" InnoDB: Error: page %lu log sequence number %lu %lu\n"
"InnoDB: is in the future! Current system log sequence number %lu %lu.\n"
-"InnoDB: Your database may be corrupt.\n",
+"InnoDB: Your database may be corrupt or you may have copied the InnoDB\n"
+"InnoDB: tablespace but not the InnoDB log files. See\n"
+"http://dev.mysql.com/doc/mysql/en/backing-up.html for more information.\n",
(ulong) mach_read_from_4(read_buf + FIL_PAGE_OFFSET),
(ulong) ut_dulint_get_high(
mach_read_from_8(read_buf + FIL_PAGE_LSN)),
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index ffb16790b2d..e39d1ae0a71 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -230,7 +230,7 @@ buf_flush_buffered_writes(void)
ulint len2;
ulint i;
- if (trx_doublewrite == NULL) {
+ if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) {
os_aio_simulated_wake_handler_threads();
return;
@@ -503,7 +503,7 @@ buf_flush_write_block_low(
#endif
buf_flush_init_for_writing(block->frame, block->newest_modification,
block->space, block->offset);
- if (!trx_doublewrite) {
+ if (!srv_use_doublewrite_buf || !trx_doublewrite) {
fil_io(OS_FILE_WRITE | OS_AIO_SIMULATED_WAKE_LATER,
FALSE, block->space, block->offset, 0, UNIV_PAGE_SIZE,
(void*)block->frame, (void*)block);
diff --git a/storage/innobase/data/data0data.c b/storage/innobase/data/data0data.c
index 194213a04e1..19304a7a8e1 100644
--- a/storage/innobase/data/data0data.c
+++ b/storage/innobase/data/data0data.c
@@ -561,12 +561,12 @@ dtuple_convert_big_rec(
}
/* We do not store externally fields which are smaller than
- DICT_MAX_COL_PREFIX_LEN */
+ DICT_MAX_INDEX_COL_LEN */
- ut_a(DICT_MAX_COL_PREFIX_LEN > REC_1BYTE_OFFS_LIMIT);
+ ut_a(DICT_MAX_INDEX_COL_LEN > REC_1BYTE_OFFS_LIMIT);
if (longest < BTR_EXTERN_FIELD_REF_SIZE + 10
- + DICT_MAX_COL_PREFIX_LEN) {
+ + DICT_MAX_INDEX_COL_LEN) {
/* Cannot shorten more */
mem_heap_free(heap);
@@ -588,10 +588,10 @@ dtuple_convert_big_rec(
dfield = dtuple_get_nth_field(entry, longest_i);
vector->fields[n_fields].field_no = longest_i;
- ut_a(dfield->len > DICT_MAX_COL_PREFIX_LEN);
+ ut_a(dfield->len > DICT_MAX_INDEX_COL_LEN);
vector->fields[n_fields].len = dfield->len
- - DICT_MAX_COL_PREFIX_LEN;
+ - DICT_MAX_INDEX_COL_LEN;
vector->fields[n_fields].data = mem_heap_alloc(heap,
vector->fields[n_fields].len);
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 5eee57c250b..fb95ffbd80c 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1625,7 +1625,7 @@ dict_index_add_col(
variable-length fields, so that the extern flag can be embedded in
the length word. */
- if (field->fixed_len > DICT_MAX_COL_PREFIX_LEN) {
+ if (field->fixed_len > DICT_MAX_INDEX_COL_LEN) {
field->fixed_len = 0;
}
@@ -2189,7 +2189,7 @@ dict_foreign_error_report(
dict_foreign_error_report_low(file, fk->foreign_table_name);
fputs(msg, file);
fputs(" Constraint:\n", file);
- dict_print_info_on_foreign_key_in_create_format(file, NULL, fk);
+ dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE);
if (fk->foreign_index) {
fputs("\nThe index in the foreign key in table is ", file);
ut_print_name(file, NULL, fk->foreign_index->name);
@@ -4330,9 +4330,10 @@ CREATE TABLE. */
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign)/* in: foreign key constraint */
+ FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ ibool add_newline) /* in: whether to add a newline */
{
const char* stripped_id;
ulint i;
@@ -4345,7 +4346,16 @@ dict_print_info_on_foreign_key_in_create_format(
stripped_id = foreign->id;
}
- fputs(",\n CONSTRAINT ", file);
+ putc(',', file);
+
+ if (add_newline) {
+ /* SHOW CREATE TABLE wants constraints each printed nicely
+ on its own line, while error messages want no newlines
+ inserted. */
+ fputs("\n ", file);
+ }
+
+ fputs(" CONSTRAINT ", file);
ut_print_name(file, trx, stripped_id);
fputs(" FOREIGN KEY (", file);
@@ -4447,7 +4457,7 @@ dict_print_info_on_foreign_keys(
while (foreign != NULL) {
if (create_table_format) {
dict_print_info_on_foreign_key_in_create_format(
- file, trx, foreign);
+ file, trx, foreign, TRUE);
} else {
ulint i;
fputs("; (", file);
diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h
index 1f3a32fa70c..d28b0b129a1 100644
--- a/storage/innobase/include/btr0btr.h
+++ b/storage/innobase/include/btr0btr.h
@@ -23,16 +23,6 @@ special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
-/* Maximum key size in a B-tree: the records on non-leaf levels must be
-shorter than this */
-
-#define BTR_PAGE_MAX_KEY_SIZE 1024
-
-/* If data in page drops below this limit, we try to compress it.
-NOTE! The value has to be > 2 * BTR_MAX_KEY_SIZE */
-
-#define BTR_COMPRESS_LIMIT (UNIV_PAGE_SIZE / 4 + 1);
-
/* Latching modes for the search function (in btr0cur.*) */
#define BTR_SEARCH_LEAF RW_S_LATCH
#define BTR_MODIFY_LEAF RW_X_LATCH
diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic
index 06d45dd5501..d4a7b3c64b8 100644
--- a/storage/innobase/include/data0type.ic
+++ b/storage/innobase/include/data0type.ic
@@ -420,7 +420,7 @@ dtype_get_fixed_size(
}
/***************************************************************************
-Returns the size of a fixed size data type, 0 if not a fixed size type. */
+Returns the minimum size of a data type. */
UNIV_INLINE
ulint
dtype_get_min_size(
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index a1232acdca7..5215d51cabe 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -375,9 +375,10 @@ CREATE TABLE. */
void
dict_print_info_on_foreign_key_in_create_format(
/*============================================*/
- FILE* file, /* in: file where to print */
- trx_t* trx, /* in: transaction */
- dict_foreign_t* foreign);/* in: foreign key constraint */
+ FILE* file, /* in: file where to print */
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign, /* in: foreign key constraint */
+ ibool add_newline); /* in: whether to add a newline */
/************************************************************************
Displays the names of the index and the table. */
void
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index ff6c4ec9b28..7eec86d0bcb 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -152,12 +152,12 @@ struct dict_col_struct{
in some of the functions below */
};
-/* DICT_MAX_COL_PREFIX_LEN is measured in bytes. Starting from 4.1.6, we
-set max col prefix len to < 3 * 256, so that one can create a column prefix
-index on 255 characters of a TEXT field also in the UTF-8 charset. In that
-charset, a character may take at most 3 bytes. */
+/* DICT_MAX_INDEX_COL_LEN is measured in bytes and is the max index column
+length + 1. Starting from 4.1.6, we set it to < 3 * 256, so that one can
+create a column prefix index on 255 characters of a TEXT field also in the
+UTF-8 charset. In that charset, a character may take at most 3 bytes. */
-#define DICT_MAX_COL_PREFIX_LEN 768
+#define DICT_MAX_INDEX_COL_LEN 768
/* Data structure for a field in an index */
struct dict_field_struct{
@@ -169,12 +169,12 @@ struct dict_field_struct{
prefix in bytes in a MySQL index of
type, e.g., INDEX (textcol(25));
must be smaller than
- DICT_MAX_COL_PREFIX_LEN; NOTE that
+ DICT_MAX_INDEX_COL_LEN; NOTE that
in the UTF-8 charset, MySQL sets this
to 3 * the prefix len in UTF-8 chars */
ulint fixed_len; /* 0 or the fixed length of the
column if smaller than
- DICT_MAX_COL_PREFIX_LEN */
+ DICT_MAX_INDEX_COL_LEN */
ulint fixed_offs; /* offset to the field, or
ULINT_UNDEFINED if it is not fixed
within the record (due to preceding
diff --git a/storage/innobase/include/mem0mem.h b/storage/innobase/include/mem0mem.h
index 87afdb8f91c..3768e93c03e 100644
--- a/storage/innobase/include/mem0mem.h
+++ b/storage/innobase/include/mem0mem.h
@@ -99,8 +99,7 @@ heap freeing. */
/*********************************************************************
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap which allocates memory from dynamic space. For debugging
-purposes, takes also the file name and line as argument in the debug
-version. */
+purposes, takes also the file name and line as argument. */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index 8c87c884d78..28562f7c9f8 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -371,8 +371,7 @@ mem_heap_free_top(
/*********************************************************************
NOTE: Use the corresponding macros instead of this function. Creates a
memory heap which allocates memory from dynamic space. For debugging
-purposes, takes also the file name and line as argument in the debug
-version. */
+purposes, takes also the file name and line as argument. */
UNIV_INLINE
mem_heap_t*
mem_heap_create_func(
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index adbc4afafd2..224fd59a76b 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -432,6 +432,17 @@ os_file_read(
offset */
ulint n); /* in: number of bytes to read */
/***********************************************************************
+Rewind file to its start, read at most size - 1 bytes from it to str, and
+NUL-terminate str. All errors are silently ignored. This function is
+mostly meant to be used with temporary files. */
+
+void
+os_file_read_string(
+/*================*/
+ FILE* file, /* in: file to read from */
+ char* str, /* in: buffer where to read */
+ ulint size); /* in: size of buffer */
+/***********************************************************************
Requests a synchronous positioned read operation. This function does not do
any error handling. In case of error it returns FALSE. */
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index a61705b90be..b5da4634d98 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -335,8 +335,14 @@ int
row_create_index_for_mysql(
/*=======================*/
/* out: error number or DB_SUCCESS */
- dict_index_t* index, /* in: index defintion */
- trx_t* trx); /* in: transaction handle */
+ dict_index_t* index, /* in: index definition */
+ trx_t* trx, /* in: transaction handle */
+ const ulint* field_lengths); /* in: if not NULL, must contain
+ dict_index_get_n_fields(index)
+ actual field lengths for the
+ index columns, which are
+ then checked for not being too
+ large. */
/*************************************************************************
Scans a table create SQL string and adds to the data dictionary
the foreign key constraints declared in the string. This function
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 5dbf003594f..0dc82893ad1 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -56,6 +56,22 @@ void
trx_search_latch_release_if_reserved(
/*=================================*/
trx_t* trx); /* in: transaction */
+/**********************************************************************
+Set detailed error message for the transaction. */
+void
+trx_set_detailed_error(
+/*===================*/
+ trx_t* trx, /* in: transaction struct */
+ const char* msg); /* in: detailed error message */
+/*****************************************************************
+Set detailed error message for the transaction from a file. Note that the
+file is rewinded before reading from it. */
+
+void
+trx_set_detailed_error_from_file(
+/*=============================*/
+ trx_t* trx, /* in: transaction struct */
+ FILE* file); /* in: file to read message from */
/********************************************************************
Retrieves the error_info field from a trx. */
@@ -205,7 +221,7 @@ trx_recover_for_mysql(
XID* xid_list, /* in/out: prepared transactions */
ulint len); /* in: number of slots in xid_list */
/***********************************************************************
-This function is used to commit one X/Open XA distributed transaction
+This function is used to find one X/Open XA distributed transaction
which is in the prepared state */
trx_t *
trx_get_trx_by_xid(
@@ -649,6 +665,9 @@ struct trx_struct{
trx_undo_arr_t* undo_no_arr; /* array of undo numbers of undo log
records which are currently processed
by a rollback operation */
+ /*------------------------------*/
+ char detailed_error[256]; /* detailed error message for last
+ error, or empty. */
};
#define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
diff --git a/storage/innobase/include/ut0mem.h b/storage/innobase/include/ut0mem.h
index 74357f6bf13..b9bbe0b5c92 100644
--- a/storage/innobase/include/ut0mem.h
+++ b/storage/innobase/include/ut0mem.h
@@ -119,6 +119,31 @@ int
ut_strcmp(const void* str1, const void* str2);
/**************************************************************************
+Copies up to size - 1 characters from the NUL-terminated string src to
+dst, NUL-terminating the result. Returns strlen(src), so truncation
+occurred if the return value >= size. */
+
+ulint
+ut_strlcpy(
+/*=======*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size); /* in: size of destination buffer */
+
+/**************************************************************************
+Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
+(size - 1) bytes of src, not the first. */
+
+ulint
+ut_strlcpy_rev(
+/*===========*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size); /* in: size of destination buffer */
+
+/**************************************************************************
Compute strlen(ut_strcpyq(str, q)). */
UNIV_INLINE
ulint
diff --git a/storage/innobase/mem/mem0mem.c b/storage/innobase/mem/mem0mem.c
index 85f0119d02a..daf78008d45 100644
--- a/storage/innobase/mem/mem0mem.c
+++ b/storage/innobase/mem/mem0mem.c
@@ -187,9 +187,7 @@ mem_heap_create_block(
}
block->magic_n = MEM_BLOCK_MAGIC_N;
- ut_memcpy(&(block->file_name), file_name + ut_strlen(file_name) - 7,
- 7);
- block->file_name[7]='\0';
+ ut_strlcpy_rev(block->file_name, file_name, sizeof(block->file_name));
block->line = line;
#ifdef MEM_PERIODIC_CHECK
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 9c87b59f018..20a3303d12d 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -2249,6 +2249,29 @@ error_handling:
}
/***********************************************************************
+Rewind file to its start, read at most size - 1 bytes from it to str, and
+NUL-terminate str. All errors are silently ignored. This function is
+mostly meant to be used with temporary files. */
+
+void
+os_file_read_string(
+/*================*/
+ FILE* file, /* in: file to read from */
+ char* str, /* in: buffer where to read */
+ ulint size) /* in: size of buffer */
+{
+ size_t flen;
+
+ if (size == 0) {
+ return;
+ }
+
+ rewind(file);
+ flen = fread(str, 1, size - 1, file);
+ str[flen] = '\0';
+}
+
+/***********************************************************************
Requests a synchronous write operation. */
ibool
diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c
index 167aed93de7..24bb007e504 100644
--- a/storage/innobase/os/os0proc.c
+++ b/storage/innobase/os/os0proc.c
@@ -292,6 +292,9 @@ os_awe_allocate_physical_mem(
return(TRUE);
#else
+ UT_NOT_USED(n_megabytes);
+ UT_NOT_USED(page_info);
+
return(FALSE);
#endif
}
@@ -349,6 +352,8 @@ os_awe_allocate_virtual_mem_window(
return(ptr);
#else
+ UT_NOT_USED(size);
+
return(NULL);
#endif
}
@@ -476,6 +481,10 @@ os_awe_map_physical_mem_to_window(
return(TRUE);
#else
+ UT_NOT_USED(ptr);
+ UT_NOT_USED(n_mem_pages);
+ UT_NOT_USED(page_info);
+
return(FALSE);
#endif
}
diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c
index fbc33aea669..9480c978755 100644
--- a/storage/innobase/rem/rem0rec.c
+++ b/storage/innobase/rem/rem0rec.c
@@ -621,7 +621,7 @@ rec_set_nth_field_extern_bit_new(
if (field->fixed_len) {
/* fixed-length fields cannot be external
(Fixed-length fields longer than
- DICT_MAX_COL_PREFIX_LEN will be treated as
+ DICT_MAX_INDEX_COL_LEN will be treated as
variable-length ones in dict_index_add_col().) */
ut_ad(i != ith);
continue;
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 75d8117a73e..5e833372299 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -579,6 +579,32 @@ row_ins_cascade_calc_update_vec(
}
/*************************************************************************
+Set detailed error message associated with foreign key errors for
+the given transaction. */
+static
+void
+row_ins_set_detailed(
+/*=================*/
+ trx_t* trx, /* in: transaction */
+ dict_foreign_t* foreign) /* in: foreign key constraint */
+{
+
+ FILE* tf = os_file_create_tmpfile();
+
+ if (tf) {
+ ut_print_name(tf, trx, foreign->foreign_table_name);
+ dict_print_info_on_foreign_key_in_create_format(tf, trx,
+ foreign, FALSE);
+
+ trx_set_detailed_error_from_file(trx, tf);
+
+ fclose(tf);
+ } else {
+ trx_set_detailed_error(trx, "temp file creation failed");
+ }
+}
+
+/*************************************************************************
Reports a foreign key error associated with an update or a delete of a
parent table index entry. */
static
@@ -598,6 +624,8 @@ row_ins_foreign_report_err(
FILE* ef = dict_foreign_err_file;
trx_t* trx = thr_get_trx(thr);
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -607,7 +635,8 @@ row_ins_foreign_report_err(
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
- dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
+ dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
+ TRUE);
putc('\n', ef);
fputs(errstr, ef);
fputs(" in parent table, in index ", ef);
@@ -648,7 +677,9 @@ row_ins_foreign_report_add_err(
child table */
{
FILE* ef = dict_foreign_err_file;
-
+
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -657,7 +688,8 @@ row_ins_foreign_report_add_err(
fputs("Foreign key constraint fails for table ", ef);
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
- dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign);
+ dict_print_info_on_foreign_key_in_create_format(ef, trx, foreign,
+ TRUE);
fputs("\nTrying to add in child table, in index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
if (entry) {
@@ -1224,6 +1256,9 @@ run_again:
if (check_table == NULL || check_table->ibd_file_missing) {
if (check_ref) {
FILE* ef = dict_foreign_err_file;
+
+ row_ins_set_detailed(trx, foreign);
+
mutex_enter(&dict_foreign_err_mutex);
rewind(ef);
ut_print_timestamp(ef);
@@ -1233,7 +1268,7 @@ run_again:
ut_print_name(ef, trx, foreign->foreign_table_name);
fputs(":\n", ef);
dict_print_info_on_foreign_key_in_create_format(ef,
- trx, foreign);
+ trx, foreign, TRUE);
fputs("\nTrying to add to index ", ef);
ut_print_name(ef, trx, foreign->foreign_index->name);
fputs(" tuple:\n", ef);
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 26aae117d1d..82f7daf2ed8 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -1973,13 +1973,20 @@ row_create_index_for_mysql(
/*=======================*/
/* out: error number or DB_SUCCESS */
dict_index_t* index, /* in: index definition */
- trx_t* trx) /* in: transaction handle */
+ trx_t* trx, /* in: transaction handle */
+ const ulint* field_lengths) /* in: if not NULL, must contain
+ dict_index_get_n_fields(index)
+ actual field lengths for the
+ index columns, which are
+ then checked for not being too
+ large. */
{
ind_node_t* node;
mem_heap_t* heap;
que_thr_t* thr;
ulint err;
ulint i, j;
+ ulint len;
#ifdef UNIV_SYNC_DEBUG
ut_ad(rw_lock_own(&dict_operation_lock, RW_LOCK_EX));
@@ -2018,10 +2025,16 @@ row_create_index_for_mysql(
}
}
- /* Check also that prefix_len < DICT_MAX_COL_PREFIX_LEN */
+ /* Check also that prefix_len and actual length
+ < DICT_MAX_INDEX_COL_LEN */
+
+ len = dict_index_get_nth_field(index, i)->prefix_len;
- if (dict_index_get_nth_field(index, i)->prefix_len
- >= DICT_MAX_COL_PREFIX_LEN) {
+ if (field_lengths) {
+ len = ut_max(len, field_lengths[i]);
+ }
+
+ if (len >= DICT_MAX_INDEX_COL_LEN) {
err = DB_TOO_BIG_RECORD;
goto error_handling;
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index 325b0a109cf..e5151ebf631 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -1540,7 +1540,7 @@ NetWare. */
#endif
sync_order_checks_on = TRUE;
- if (srv_use_doublewrite_buf && trx_doublewrite == NULL) {
+ if (trx_doublewrite == NULL) {
/* Create the doublewrite buffer to a new tablespace */
trx_sys_create_doublewrite_buf();
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index bf48c30e942..23f1dc40d00 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -126,22 +126,6 @@ trx_doublewrite_init(
}
/********************************************************************
-Frees the doublewrite buffer. */
-static
-void
-trx_doublewrite_free(void)
-/*======================*/
-{
- mutex_free(&(trx_doublewrite->mutex));
-
- mem_free(trx_doublewrite->buf_block_arr);
- ut_free(trx_doublewrite->write_buf_unaligned);
-
- mem_free(trx_doublewrite);
- trx_doublewrite = NULL;
-}
-
-/********************************************************************
Marks the trx sys header when we have successfully upgraded to the >= 4.1.x
multiple tablespace format. */
@@ -529,9 +513,6 @@ trx_sys_doublewrite_init_or_restore_pages(
fil_flush_file_spaces(FIL_TABLESPACE);
- if (!srv_use_doublewrite_buf)
- trx_doublewrite_free();
-
leave_func:
ut_free(unaligned_read_buf);
}
diff --git a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
index 078befb81d2..090057f5d46 100644
--- a/storage/innobase/trx/trx0trx.c
+++ b/storage/innobase/trx/trx0trx.c
@@ -52,6 +52,32 @@ trx_start_if_not_started_noninline(
trx_start_if_not_started(trx);
}
+/*****************************************************************
+Set detailed error message for the transaction. */
+
+void
+trx_set_detailed_error(
+/*===================*/
+ trx_t* trx, /* in: transaction struct */
+ const char* msg) /* in: detailed error message */
+{
+ ut_strlcpy(trx->detailed_error, msg, sizeof(trx->detailed_error));
+}
+
+/*****************************************************************
+Set detailed error message for the transaction from a file. Note that the
+file is rewinded before reading from it. */
+
+void
+trx_set_detailed_error_from_file(
+/*=============================*/
+ trx_t* trx, /* in: transaction struct */
+ FILE* file) /* in: file to read message from */
+{
+ os_file_read_string(file, trx->detailed_error,
+ sizeof(trx->detailed_error));
+}
+
/********************************************************************
Retrieves the error_info field from a trx. */
@@ -130,6 +156,7 @@ trx_create(
trx->undo_no_arr = NULL;
trx->error_state = DB_SUCCESS;
+ trx->detailed_error[0] = '\0';
trx->sess = sess;
trx->que_state = TRX_QUE_RUNNING;
diff --git a/storage/innobase/ut/ut0mem.c b/storage/innobase/ut/ut0mem.c
index 3e8fd79a739..47b1e24e5e1 100644
--- a/storage/innobase/ut/ut0mem.c
+++ b/storage/innobase/ut/ut0mem.c
@@ -343,6 +343,54 @@ ut_free_all_mem(void)
}
/**************************************************************************
+Copies up to size - 1 characters from the NUL-terminated string src to
+dst, NUL-terminating the result. Returns strlen(src), so truncation
+occurred if the return value >= size. */
+
+ulint
+ut_strlcpy(
+/*=======*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size) /* in: size of destination buffer */
+{
+ ulint src_size = strlen(src);
+
+ if (size != 0) {
+ ulint n = ut_min(src_size, size - 1);
+
+ memcpy(dst, src, n);
+ dst[n] = '\0';
+ }
+
+ return(src_size);
+}
+
+/**************************************************************************
+Like ut_strlcpy, but if src doesn't fit in dst completely, copies the last
+(size - 1) bytes of src, not the first. */
+
+ulint
+ut_strlcpy_rev(
+/*===========*/
+ /* out: strlen(src) */
+ char* dst, /* in: destination buffer */
+ const char* src, /* in: source buffer */
+ ulint size) /* in: size of destination buffer */
+{
+ ulint src_size = strlen(src);
+
+ if (size != 0) {
+ ulint n = ut_min(src_size, size - 1);
+
+ memcpy(dst, src + src_size - n, n + 1);
+ }
+
+ return(src_size);
+}
+
+/**************************************************************************
Make a quoted copy of a NUL-terminated string. Leading and trailing
quotes will not be included; only embedded quotes will be escaped.
See also ut_strlenq() and ut_memcpyq(). */
diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c
index 078853bad19..563abf9f0cf 100644
--- a/storage/myisam/ft_boolean_search.c
+++ b/storage/myisam/ft_boolean_search.c
@@ -510,7 +510,8 @@ static int _ftb_check_phrase(const byte *s0, const byte *e0,
for (;;)
{
n_word= (FT_WORD *)phrase_element->data;
- if (my_strnncoll(cs, h_word.pos, h_word.len, n_word->pos, n_word->len))
+ if (my_strnncoll(cs, (const uchar *) h_word.pos, h_word.len,
+ (const uchar *) n_word->pos, n_word->len))
break;
if (! (phrase_element= phrase_element->next))
DBUG_RETURN(1);
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index ee64f9b9979..074a1b23686 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -80,6 +80,7 @@ void myisamchk_init(MI_CHECK *param)
param->start_check_pos=0;
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
+ param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
}
/* Check the status flags for the table */
@@ -559,10 +560,11 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
ha_checksum *key_checksum, uint level)
{
int flag;
- uint used_length,comp_flag,nod_flag,key_length=0,not_used;
+ uint used_length,comp_flag,nod_flag,key_length=0;
uchar key[MI_MAX_POSSIBLE_KEY_BUFF],*temp_buff,*keypos,*old_keypos,*endpos;
my_off_t next_page,record;
char llbuff[22];
+ uint diff_pos;
DBUG_ENTER("chk_index");
DBUG_DUMP("buff",(byte*) buff,mi_getint(buff));
@@ -620,7 +622,7 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
}
if ((*keys)++ &&
(flag=ha_key_cmp(keyinfo->seg,info->lastkey,key,key_length,
- comp_flag, &not_used)) >=0)
+ comp_flag, &diff_pos)) >=0)
{
DBUG_DUMP("old",(byte*) info->lastkey, info->lastkey_length);
DBUG_DUMP("new",(byte*) key, key_length);
@@ -636,11 +638,11 @@ static int chk_index(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{
if (*keys != 1L) /* not first_key */
{
- uint diff;
- ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
- SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
- &diff);
- param->unique_count[diff-1]++;
+ if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
+ ha_key_cmp(keyinfo->seg,info->lastkey,key,USE_WHOLE_KEY,
+ SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
+ &diff_pos);
+ param->unique_count[diff_pos-1]++;
}
}
(*key_checksum)+= mi_byte_checksum((byte*) key,
@@ -1090,7 +1092,7 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
"Keypointers and record positions doesn't match");
error=1;
}
- else if (param->glob_crc != info->s->state.checksum &&
+ else if (param->glob_crc != info->state->checksum &&
(info->s->options &
(HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD)))
{
@@ -1386,7 +1388,7 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
info->state->data_file_length=sort_param.max_pos;
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (!(param->testflag & T_SILENT))
{
@@ -2014,7 +2016,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
sort_param.sort_info=&sort_info;
sort_param.fix_datafile= (my_bool) (! rep_quick);
sort_param.master =1;
-
+
del=info->state->del;
param->glob_crc=0;
if (param->testflag & T_CALC_CHECKSUM)
@@ -2154,7 +2156,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
my_errno);
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
mi_check_print_warning(param,
@@ -2575,7 +2577,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
my_errno);
}
if (param->testflag & T_CALC_CHECKSUM)
- share->state.checksum=param->glob_crc;
+ info->state->checksum=param->glob_crc;
if (my_chsize(share->kfile,info->state->key_file_length,0,MYF(0)))
mi_check_print_warning(param,
@@ -3250,9 +3252,10 @@ static int sort_key_write(MI_SORT_PARAM *sort_param, const void *a)
cmp=ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
(uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_UPDATE,
&diff_pos);
- ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
- (uchar*) a, USE_WHOLE_KEY,SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL,
- &diff_pos);
+ if (param->stats_method == MI_STATS_METHOD_NULLS_NOT_EQUAL)
+ ha_key_cmp(sort_param->seg,sort_info->key_block->lastkey,
+ (uchar*) a, USE_WHOLE_KEY,
+ SEARCH_FIND | SEARCH_NULL_ARE_NOT_EQUAL, &diff_pos);
sort_param->unique[diff_pos-1]++;
}
else
@@ -3805,7 +3808,7 @@ int recreate_table(MI_CHECK *param, MI_INFO **org_info, char *filename)
(*org_info)->s->state.create_time=share.state.create_time;
(*org_info)->s->state.unique=(*org_info)->this_unique=
share.state.unique;
- (*org_info)->s->state.checksum=share.state.checksum;
+ (*org_info)->state->checksum=info.state->checksum;
(*org_info)->state->del=info.state->del;
(*org_info)->s->state.dellink=share.state.dellink;
(*org_info)->state->empty=info.state->empty;
@@ -3989,9 +3992,10 @@ void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
unique[0]= (#different values of {keypart1}) - 1
unique[1]= (#different values of {keypart2,keypart1} tuple) - unique[0] - 1
...
- Here we assume that NULL != NULL (see SEARCH_NULL_ARE_NOT_EQUAL). The
- 'unique' array is collected in one sequential scan through the entire
+ The 'unique' array is collected in one sequential scan through the entire
index. This is done in two places: in chk_index() and in sort_key_write().
+ Statistics collection may consider NULLs as either equal or unequal (see
+ SEARCH_NULL_ARE_NOT_EQUAL, MI_STATS_METHOD_*).
Output is an array:
rec_per_key_part[k] =
diff --git a/storage/myisam/mi_dbug.c b/storage/myisam/mi_dbug.c
index e782d21afe7..ddc8a403a33 100644
--- a/storage/myisam/mi_dbug.c
+++ b/storage/myisam/mi_dbug.c
@@ -40,12 +40,12 @@ void _mi_print_key(FILE *stream, register HA_KEYSEG *keyseg,
end= key+ keyseg->length;
if (keyseg->flag & HA_NULL_PART)
{
- if (!*key)
+ /* A NULL value is encoded by a 1-byte flag. Zero means NULL. */
+ if (! *(key++))
{
fprintf(stream,"NULL");
continue;
}
- key++;
}
switch (keyseg->type) {
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 60a07254e82..62ca7f8ff61 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -93,7 +93,7 @@ int mi_delete(MI_INFO *info,const byte *record)
if ((*share->delete_record)(info))
goto err; /* Remove record from database */
- info->s->state.checksum-=info->checksum;
+ info->state->checksum-=info->checksum;
info->update= HA_STATE_CHANGED+HA_STATE_DELETED+HA_STATE_ROW_CHANGED;
info->state->records--;
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index 3033249886f..a30abb95070 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -41,7 +41,7 @@ int mi_delete_all_rows(MI_INFO *info)
info->state->key_file_length=share->base.keystart;
info->state->data_file_length=0;
info->state->empty=info->state->key_empty=0;
- state->checksum=0;
+ info->state->checksum=0;
for (i=share->base.max_key_block_length/MI_MIN_KEY_BLOCK_LENGTH ; i-- ; )
state->key_del[i]= HA_OFFSET_ERROR;
diff --git a/storage/myisam/mi_key.c b/storage/myisam/mi_key.c
index ae50900a190..4cabfc91197 100644
--- a/storage/myisam/mi_key.c
+++ b/storage/myisam/mi_key.c
@@ -358,7 +358,7 @@ static int _mi_put_key_in_record(register MI_INFO *info, uint keynr,
byte *blob_ptr;
DBUG_ENTER("_mi_put_key_in_record");
- blob_ptr= info->lastkey2; /* Place to put blob parts */
+ blob_ptr= (byte*) info->lastkey2; /* Place to put blob parts */
key=(byte*) info->lastkey; /* KEy that was read */
key_end=key+info->lastkey_length;
for (keyseg=info->s->keyinfo[keynr].seg ; keyseg->type ;keyseg++)
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index 82663e0c318..955d55cf765 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -199,7 +199,8 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d",
len,MI_BASE_INFO_SIZE))
}
- disk_pos=my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
+ disk_pos= (char*)
+ my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base);
share->state.state_length=base_pos;
if (!(open_flags & HA_OPEN_FOR_REPAIR) &&
@@ -822,7 +823,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
mi_sizestore(ptr,state->state.empty); ptr +=8;
mi_sizestore(ptr,state->state.key_empty); ptr +=8;
mi_int8store(ptr,state->auto_increment); ptr +=8;
- mi_int8store(ptr,(ulonglong) state->checksum);ptr +=8;
+ mi_int8store(ptr,(ulonglong) state->state.checksum);ptr +=8;
mi_int4store(ptr,state->process); ptr +=4;
mi_int4store(ptr,state->unique); ptr +=4;
mi_int4store(ptr,state->status); ptr +=4;
@@ -863,7 +864,7 @@ uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite)
}
-char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
+uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
{
uint i,keys,key_parts,key_blocks;
memcpy_fixed(&state->header,ptr, sizeof(state->header));
@@ -884,7 +885,7 @@ char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state)
state->state.empty = mi_sizekorr(ptr); ptr +=8;
state->state.key_empty= mi_sizekorr(ptr); ptr +=8;
state->auto_increment=mi_uint8korr(ptr); ptr +=8;
- state->checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
+ state->state.checksum=(ha_checksum) mi_uint8korr(ptr); ptr +=8;
state->process= mi_uint4korr(ptr); ptr +=4;
state->unique = mi_uint4korr(ptr); ptr +=4;
state->status = mi_uint4korr(ptr); ptr +=4;
@@ -974,7 +975,7 @@ uint mi_base_info_write(File file, MI_BASE_INFO *base)
}
-char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
+uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base)
{
base->keystart = mi_sizekorr(ptr); ptr +=8;
base->max_data_file_length = mi_sizekorr(ptr); ptr +=8;
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
index 635a7eb2c48..575a5e34488 100644
--- a/storage/myisam/mi_rkey.c
+++ b/storage/myisam/mi_rkey.c
@@ -31,8 +31,8 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
HA_KEYSEG *last_used_keyseg;
uint pack_key_length, use_key_length, nextflag;
DBUG_ENTER("mi_rkey");
- DBUG_PRINT("enter",("base: %lx inx: %d search_flag: %d",
- info,inx,search_flag));
+ DBUG_PRINT("enter", ("base: %p buf: %p inx: %d search_flag: %d",
+ info, buf, inx, search_flag));
if ((inx = _mi_check_index(info,inx)) < 0)
DBUG_RETURN(my_errno);
@@ -56,9 +56,12 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
{
if (key_len == 0)
key_len=USE_WHOLE_KEY;
+ /* Save the packed key for later use in the second buffer of lastkey. */
key_buff=info->lastkey+info->s->base.max_key_length;
pack_key_length=_mi_pack_key(info,(uint) inx, key_buff, (uchar*) key,
key_len, &last_used_keyseg);
+ /* Save packed_key_length for use by the MERGE engine. */
+ info->pack_key_length= pack_key_length;
DBUG_EXECUTE("key",_mi_print_key(DBUG_FILE, keyinfo->seg,
key_buff, pack_key_length););
}
diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c
index b7360dba7f3..185f196a814 100644
--- a/storage/myisam/mi_search.c
+++ b/storage/myisam/mi_search.c
@@ -915,11 +915,21 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
reg1 HA_KEYSEG *keyseg;
uchar *start_key,*page,*page_end,*from,*from_end;
uint length,tmp;
+ DBUG_ENTER("_mi_get_binary_pack_key");
page= *page_pos;
page_end=page+MI_MAX_KEY_BUFF+1;
start_key=key;
+ /*
+ Keys are compressed the following way:
+
+ prefix length Packed length of prefix for the prev key. (1 or 3 bytes)
+ for each key segment:
+ [is null] Null indicator if can be null (1 byte, zero means null)
+ [length] Packed length if varlength (1 or 3 bytes)
+ pointer Reference to the data file (last_keyseg->length).
+ */
get_key_length(length,page);
if (length)
{
@@ -930,7 +940,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_DUMP("key",(char*) *page_pos,16);
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
- return 0; /* Wrong key */
+ DBUG_RETURN(0); /* Wrong key */
}
from=key; from_end=key+length;
}
@@ -992,12 +1002,12 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag,
DBUG_PRINT("error",("Error when unpacking key"));
mi_print_error(keyinfo->share, HA_ERR_CRASHED);
my_errno=HA_ERR_CRASHED;
- return 0; /* Error */
+ DBUG_RETURN(0); /* Error */
}
memcpy((byte*) key,(byte*) from,(size_t) length);
*page_pos= from+length;
}
- return((uint) (key-start_key)+keyseg->length);
+ DBUG_RETURN((uint) (key-start_key)+keyseg->length);
}
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 5727c699469..60225ccc7f3 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -237,7 +237,7 @@ static int run_test(const char *filename)
pos=HA_OFFSET_ERROR;
}
if (found != row_count)
- printf("Found %ld of %ld rows\n", found,row_count);
+ printf("Found %ld of %ld rows\n", (ulong) found, (ulong) row_count);
}
if (!silent)
@@ -303,7 +303,8 @@ static int run_test(const char *filename)
if ((error=mi_rrnd(file,read_record,i == 1 ? 0L : HA_OFFSET_ERROR)) == -1)
{
if (found != row_count-deleted)
- printf("Found only %ld of %ld rows\n",found,row_count-deleted);
+ printf("Found only %ld of %ld rows\n", (ulong) found,
+ (ulong) (row_count - deleted));
break;
}
if (!error)
diff --git a/storage/myisam/mi_update.c b/storage/myisam/mi_update.c
index ab23f2e6da9..86652996afe 100644
--- a/storage/myisam/mi_update.c
+++ b/storage/myisam/mi_update.c
@@ -162,7 +162,7 @@ int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec)
if (auto_key_changed)
update_auto_increment(info,newrec);
if (share->calc_checksum)
- share->state.checksum+=(info->checksum - old_checksum);
+ info->state->checksum+=(info->checksum - old_checksum);
info->update= (HA_STATE_CHANGED | HA_STATE_ROW_CHANGED | HA_STATE_AKTIV |
key_changed);
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index c8f9aa84a41..8785adae9a2 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -142,7 +142,7 @@ int mi_write(MI_INFO *info, byte *record)
{
if ((*share->write_record)(info,record))
goto err;
- share->state.checksum+=info->checksum;
+ info->state->checksum+=info->checksum;
}
if (share->base.auto_key)
update_auto_increment(info,record);
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 78ae756bf7c..a90495e5fcb 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -67,6 +67,7 @@ static const char *field_pack[]=
"no zeros", "blob", "constant", "table-lockup",
"always zero","varchar","unique-hash","?","?"};
+static const char *myisam_stats_method_str="nulls_unequal";
static void get_options(int *argc,char * * *argv);
static void print_version(void);
@@ -155,7 +156,7 @@ enum options_mc {
OPT_READ_BUFFER_SIZE, OPT_WRITE_BUFFER_SIZE, OPT_SORT_BUFFER_SIZE,
OPT_SORT_KEY_BLOCKS, OPT_DECODE_BITS, OPT_FT_MIN_WORD_LEN,
OPT_FT_MAX_WORD_LEN, OPT_FT_STOPWORD_FILE,
- OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE
+ OPT_MAX_RECORD_LENGTH, OPT_AUTO_CLOSE, OPT_STATS_METHOD
};
static struct my_option my_long_options[] =
@@ -336,6 +337,11 @@ static struct my_option my_long_options[] =
"Use stopwords from this file instead of built-in list.",
(gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"stats_method", OPT_STATS_METHOD,
+ "Specifies how index statistics collection code should threat NULLs. "
+ "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), and \"nulls_equal\" (emulate 4.0 behavior).",
+ (gptr*) &myisam_stats_method_str, (gptr*) &myisam_stats_method_str, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -465,6 +471,12 @@ static void usage(void)
#include <help_end.h>
+const char *myisam_stats_method_names[] = {"nulls_unequal", "nulls_equal",
+ NullS};
+TYPELIB myisam_stats_method_typelib= {
+ array_elements(myisam_stats_method_names) - 1, "",
+ myisam_stats_method_names, NULL};
+
/* Read options */
static my_bool
@@ -684,6 +696,18 @@ get_one_option(int optid,
else
check_param.testflag|= T_CALC_CHECKSUM;
break;
+ case OPT_STATS_METHOD:
+ {
+ int method;
+ myisam_stats_method_str= argument;
+ if ((method=find_type(argument, &myisam_stats_method_typelib, 2)) <= 0)
+ {
+ fprintf(stderr, "Invalid value of stats_method: %s.\n", argument);
+ exit(1);
+ }
+ check_param.stats_method= (enum_mi_stats_method) (method-1);
+ break;
+ }
#ifdef DEBUG /* Only useful if debugging */
case OPT_START_CHECK_POS:
check_param.start_check_pos= strtoull(argument, NULL, 0);
@@ -1237,7 +1261,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name)
share->base.raid_chunksize);
}
if (share->options & (HA_OPTION_CHECKSUM | HA_OPTION_COMPRESS_RECORD))
- printf("Checksum: %23s\n",llstr(info->s->state.checksum,llbuff));
+ printf("Checksum: %23s\n",llstr(info->state->checksum,llbuff));
;
if (share->options & HA_OPTION_DELAY_KEY_WRITE)
printf("Keys are only flushed at close\n");
@@ -1552,7 +1576,7 @@ static int mi_sort_records(MI_CHECK *param,
old_record_count=info->state->records;
info->state->records=0;
if (sort_info.new_data_file_type != COMPRESSED_RECORD)
- share->state.checksum=0;
+ info->state->checksum=0;
if (sort_record_index(&sort_param,info,keyinfo,share->state.key_root[sort_key],
temp_buff, sort_key,new_file,update_index) ||
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 82f7fd7360e..87a1b757d88 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -38,6 +38,7 @@ typedef struct st_mi_status_info
my_off_t key_empty; /* lost space in indexfile */
my_off_t key_file_length;
my_off_t data_file_length;
+ ha_checksum checksum;
} MI_STATUS_INFO;
typedef struct st_mi_state_info
@@ -75,7 +76,6 @@ typedef struct st_mi_state_info
ulong sec_index_changed; /* Updated when new sec_index */
ulong sec_index_used; /* which extra index are in use */
ulonglong key_map; /* Which keys are in use */
- ha_checksum checksum;
ulong version; /* timestamp of create */
time_t create_time; /* Time when created database */
time_t recover_time; /* Time for last recover */
@@ -261,6 +261,7 @@ struct st_myisam_info {
uint last_rkey_length; /* Last length in mi_rkey() */
enum ha_rkey_function last_key_func; /* CONTAIN, OVERLAP, etc */
uint save_lastkey_length;
+ uint pack_key_length; /* For MYISAMMRG */
int errkey; /* Got last error on this key */
int lock_type; /* How database was locked */
int tmp_lock_type; /* When locked by readinfo */
@@ -679,10 +680,10 @@ extern uint read_pack_length(uint version, const uchar *buf, ulong *length);
extern uint calc_pack_length(uint version, ulong length);
uint mi_state_info_write(File file, MI_STATE_INFO *state, uint pWrite);
-char *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
+uchar *mi_state_info_read(uchar *ptr, MI_STATE_INFO *state);
uint mi_state_info_read_dsk(File file, MI_STATE_INFO *state, my_bool pRead);
uint mi_base_info_write(File file, MI_BASE_INFO *base);
-char *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base);
+uchar *my_n_base_info_read(uchar *ptr, MI_BASE_INFO *base);
int mi_keyseg_write(File file, const HA_KEYSEG *keyseg);
char *mi_keyseg_read(char *ptr, HA_KEYSEG *keyseg);
uint mi_keydef_write(File file, MI_KEYDEF *keydef);
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index 3b091cd6ea2..114e80d8f1a 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -2008,7 +2008,7 @@ static char *hexdigits(ulonglong value)
static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees,
my_off_t tot_elements,my_off_t filelength)
{
- byte *buff=file_buffer.pos;
+ byte *buff= (byte*) file_buffer.pos;
bzero(buff,HEAD_LENGTH);
memcpy_fixed(buff,myisam_pack_file_magic,4);
@@ -2024,7 +2024,7 @@ static int write_header(PACK_MRG_INFO *mrg,uint head_length,uint trees,
if (test_only)
return 0;
VOID(my_seek(file_buffer.file,0L,MY_SEEK_SET,MYF(0)));
- return my_write(file_buffer.file,file_buffer.pos,HEAD_LENGTH,
+ return my_write(file_buffer.file,(const byte *) file_buffer.pos,HEAD_LENGTH,
MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)) != 0;
}
@@ -2472,7 +2472,7 @@ static int compress_isam_file(PACK_MRG_INFO *mrg, HUFF_COUNTS *huff_counts)
{
if (flush_buffer((ulong) max_calc_length + (ulong) max_pack_length))
break;
- record_pos=file_buffer.pos;
+ record_pos= (byte*) file_buffer.pos;
file_buffer.pos+=max_pack_length;
for (start_pos=record, count= huff_counts; count < end_count ; count++)
{
@@ -2795,7 +2795,8 @@ static char *make_old_name(char *new_name, char *old_name)
static void init_file_buffer(File file, pbool read_buffer)
{
file_buffer.file=file;
- file_buffer.buffer=my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),MYF(MY_WME));
+ file_buffer.buffer= (uchar*) my_malloc(ALIGN_SIZE(RECORD_CACHE_SIZE),
+ MYF(MY_WME));
file_buffer.end=file_buffer.buffer+ALIGN_SIZE(RECORD_CACHE_SIZE)-8;
file_buffer.pos_in_file=0;
error_on_write=0;
@@ -2837,7 +2838,8 @@ static int flush_buffer(ulong neaded_length)
file_buffer.pos_in_file+=length;
if (test_only)
return 0;
- if (error_on_write|| my_write(file_buffer.file,file_buffer.buffer,
+ if (error_on_write|| my_write(file_buffer.file,
+ (const byte*) file_buffer.buffer,
length,
MYF(MY_WME | MY_NABP | MY_WAIT_IF_FULL)))
{
@@ -2850,13 +2852,13 @@ static int flush_buffer(ulong neaded_length)
{
char *tmp;
neaded_length+=256; /* some margin */
- tmp=my_realloc(file_buffer.buffer, neaded_length,MYF(MY_WME));
+ tmp= my_realloc((char*) file_buffer.buffer, neaded_length,MYF(MY_WME));
if (!tmp)
return 1;
file_buffer.pos= ((uchar*) tmp +
(ulong) (file_buffer.pos - file_buffer.buffer));
- file_buffer.buffer=tmp;
- file_buffer.end=tmp+neaded_length-8;
+ file_buffer.buffer= (uchar*) tmp;
+ file_buffer.end= (uchar*) (tmp+neaded_length-8);
}
return 0;
}
@@ -2965,7 +2967,7 @@ static int save_state(MI_INFO *isam_file,PACK_MRG_INFO *mrg,my_off_t new_length,
share->state.key_root[key]= HA_OFFSET_ERROR;
for (key=0 ; key < share->state.header.max_block_size ; key++)
share->state.key_del[key]= HA_OFFSET_ERROR;
- share->state.checksum=crc; /* Save crc here */
+ isam_file->state->checksum=crc; /* Save crc here */
share->changed=1; /* Force write of header */
share->state.open_count=0;
share->global_changed=0;
@@ -3001,7 +3003,7 @@ static int save_state_mrg(File file,PACK_MRG_INFO *mrg,my_off_t new_length,
state.dellink= HA_OFFSET_ERROR;
state.version=(ulong) time((time_t*) 0);
mi_clear_all_keys_active(state.key_map);
- state.checksum=crc;
+ state.state.checksum=crc;
if (isam_file->s->base.keys)
isamchk_neaded=1;
state.changed=STATE_CHANGED | STATE_NOT_ANALYZED; /* Force check of table */
diff --git a/storage/myisam/sp_key.c b/storage/myisam/sp_key.c
index 1d43f89cba9..77cecdc0931 100644
--- a/storage/myisam/sp_key.c
+++ b/storage/myisam/sp_key.c
@@ -142,7 +142,7 @@ static int sp_add_point_to_mbr(uchar *(*wkb), uchar *end, uint n_dims,
{
if ((*wkb) > end - 8)
return -1;
- get_double(&ord, *wkb);
+ get_double(&ord, (const byte*) *wkb);
(*wkb)+= 8;
if (ord < *mbr)
float8store((char*) mbr, ord);
diff --git a/storage/myisammrg/myrg_rkey.c b/storage/myisammrg/myrg_rkey.c
index a85ef6a3b5e..f87b264081e 100644
--- a/storage/myisammrg/myrg_rkey.c
+++ b/storage/myisammrg/myrg_rkey.c
@@ -44,11 +44,12 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
MYRG_TABLE *table;
MI_INFO *mi;
int err;
+ DBUG_ENTER("myrg_rkey");
LINT_INIT(key_buff);
LINT_INIT(pack_key_length);
if (_myrg_init_queue(info,inx,search_flag))
- return my_errno;
+ DBUG_RETURN(my_errno);
for (table=info->open_tables ; table != info->end_table ; table++)
{
@@ -57,8 +58,9 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
if (table == info->open_tables)
{
err=mi_rkey(mi,0,inx,key,key_len,search_flag);
+ /* Get the saved packed key and packed key length. */
key_buff=(byte*) mi->lastkey+mi->s->base.max_key_length;
- pack_key_length=mi->last_rkey_length;
+ pack_key_length=mi->pack_key_length;
}
else
{
@@ -71,17 +73,22 @@ int myrg_rkey(MYRG_INFO *info,byte *buf,int inx, const byte *key,
{
if (err == HA_ERR_KEY_NOT_FOUND)
continue;
- return err;
+ DBUG_PRINT("exit", ("err: %d", err));
+ DBUG_RETURN(err);
}
/* adding to queue */
queue_insert(&(info->by_key),(byte *)table);
}
+ DBUG_PRINT("info", ("tables with matches: %u", info->by_key.elements));
if (!info->by_key.elements)
- return HA_ERR_KEY_NOT_FOUND;
+ DBUG_RETURN(HA_ERR_KEY_NOT_FOUND);
mi=(info->current_table=(MYRG_TABLE *)queue_top(&(info->by_key)))->table;
mi->once_flags|= RRND_PRESERVE_LASTINX;
- return _myrg_mi_read_record(mi,buf);
+ DBUG_PRINT("info", ("using table no: %d",
+ info->current_table - info->open_tables + 1));
+ DBUG_DUMP("result key", (byte*) mi->lastkey, mi->lastkey_length);
+ DBUG_RETURN(_myrg_mi_read_record(mi,buf));
}
diff --git a/storage/ndb/include/kernel/GlobalSignalNumbers.h b/storage/ndb/include/kernel/GlobalSignalNumbers.h
index 141e7392250..2cecd109ac1 100644
--- a/storage/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/storage/ndb/include/kernel/GlobalSignalNumbers.h
@@ -554,7 +554,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_STATISTICS_CONF 454
#define GSN_START_ORD 455
-/* 456 unused */
/* 457 unused */
#define GSN_EVENT_SUBSCRIBE_REQ 458
@@ -830,14 +829,6 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_656
-/**
- * Management server
- */
-#define GSN_MGM_LOCK_CONFIG_REQ 657
-#define GSN_MGM_LOCK_CONFIG_REP 658
-#define GSN_MGM_UNLOCK_CONFIG_REQ 659
-#define GSN_MGM_UNLOCK_CONFIG_REP 660
-
#define GSN_UTIL_CREATE_LOCK_REQ 132
#define GSN_UTIL_CREATE_LOCK_REF 133
#define GSN_UTIL_CREATE_LOCK_CONF 188
@@ -894,6 +885,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_RESUME_REQ 682
#define GSN_STOP_REQ 443
#define GSN_STOP_REF 444
+#define GSN_STOP_CONF 456
#define GSN_API_VERSION_REQ 697
#define GSN_API_VERSION_CONF 698
diff --git a/storage/ndb/include/kernel/signaldata/ApiVersion.hpp b/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
index 28281e7d186..a3774c9fba6 100644
--- a/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
+++ b/storage/ndb/include/kernel/signaldata/ApiVersion.hpp
@@ -49,12 +49,11 @@ class ApiVersionConf {
*/
friend class MgmtSrv;
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
Uint32 senderRef;
Uint32 nodeId; //api node id
Uint32 version; // Version of API node
-
-
+ Uint32 inet_addr;
};
#endif
diff --git a/storage/ndb/include/kernel/signaldata/StopReq.hpp b/storage/ndb/include/kernel/signaldata/StopReq.hpp
index ea453ae115d..8e6a0b90a91 100644
--- a/storage/ndb/include/kernel/signaldata/StopReq.hpp
+++ b/storage/ndb/include/kernel/signaldata/StopReq.hpp
@@ -67,6 +67,13 @@ public:
static bool getStopAbort(const Uint32 & requestInfo);
};
+struct StopConf
+{
+ STATIC_CONST( SignalLength = 2 );
+ Uint32 senderData;
+ Uint32 nodeState;
+};
+
class StopRef
{
/**
@@ -86,7 +93,8 @@ public:
OK = 0,
NodeShutdownInProgress = 1,
SystemShutdownInProgress = 2,
- NodeShutdownWouldCauseSystemCrash = 3
+ NodeShutdownWouldCauseSystemCrash = 3,
+ TransactionAbortFailed = 4
};
public:
diff --git a/storage/ndb/include/mgmapi/ndb_logevent.h b/storage/ndb/include/mgmapi/ndb_logevent.h
index f3f9d04e6d0..b0c14f91c4c 100644
--- a/storage/ndb/include/mgmapi/ndb_logevent.h
+++ b/storage/ndb/include/mgmapi/ndb_logevent.h
@@ -148,9 +148,9 @@ extern "C" {
/** NDB_MGM_EVENT_CATEGORY_INFO */
NDB_LE_InfoEvent = 49,
- /* GREP */
- NDB_LE_GrepSubscriptionInfo = 52,
- NDB_LE_GrepSubscriptionAlert = 53,
+ /* SINGLE USER */
+ NDB_LE_SingleUser = 52,
+ /* NDB_LE_ UNUSED = 53, */
/** NDB_MGM_EVENT_CATEGORY_BACKUP */
NDB_LE_BackupStarted = 54,
@@ -607,6 +607,11 @@ extern "C" {
unsigned backup_id;
unsigned error;
} BackupAborted;
+ /** Log event data @ref NDB_LE_SingleUser */
+ struct {
+ unsigned type;
+ unsigned node_id;
+ } SingleUser;
#ifndef DOXYGEN_FIX
};
#else
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp
index cae2c4653e6..f8337d4b281 100644
--- a/storage/ndb/include/ndbapi/Ndb.hpp
+++ b/storage/ndb/include/ndbapi/Ndb.hpp
@@ -986,10 +986,10 @@ class NdbBlob;
class NdbReceiver;
class TransporterFacade;
class PollGuard;
+template <class T> struct Ndb_free_list_t;
typedef void (* NdbEventCallback)(NdbEventOperation*, Ndb*, void*);
-
#if defined NDB_OSE
/**
* Default time to wait for response after request has been sent to
@@ -1473,8 +1473,20 @@ public:
*/
NdbTransaction* hupp( NdbTransaction* );
Uint32 getReference() const { return theMyRef;}
+
+ struct Free_list_usage
+ {
+ const char * m_name;
+ Uint32 m_created;
+ Uint32 m_free;
+ Uint32 m_sizeof;
+ };
+
+ Free_list_usage * get_free_list_usage(Free_list_usage*);
#endif
+
+
/*****************************************************************************
* These are service routines used by the other classes in the NDBAPI.
****************************************************************************/
@@ -1650,22 +1662,8 @@ private:
class NdbDictionaryImpl* theDictionary;
class NdbEventBuffer* theEventBuffer;
- NdbTransaction* theConIdleList; // First connection in idle list.
-
- NdbOperation* theOpIdleList; // First operation in the idle list.
-
- NdbIndexScanOperation* theScanOpIdleList; // First scan operation in the idle list.
- NdbIndexOperation* theIndexOpIdleList; // First index operation in the idle list.
NdbTransaction* theTransactionList;
NdbTransaction** theConnectionArray;
- NdbRecAttr* theRecAttrIdleList;
- NdbApiSignal* theSignalIdleList; // First signal in idlelist.
- NdbLabel* theLabelList; // First label descriptor in list
- NdbBranch* theBranchList; // First branch descriptor in list
- NdbSubroutine* theSubroutineList; // First subroutine descriptor in
- NdbCall* theCallList; // First call descriptor in list
- NdbReceiver* theScanList;
- NdbBlob* theNdbBlobIdleList;
Uint32 theMyRef; // My block reference
Uint32 theNode; // The node number of our node
diff --git a/storage/ndb/include/ndbapi/NdbBlob.hpp b/storage/ndb/include/ndbapi/NdbBlob.hpp
index 271287b765c..cb0caafe34f 100644
--- a/storage/ndb/include/ndbapi/NdbBlob.hpp
+++ b/storage/ndb/include/ndbapi/NdbBlob.hpp
@@ -277,7 +277,7 @@ private:
// for keeping in lists
NdbBlob* theNext;
// initialization
- NdbBlob();
+ NdbBlob(Ndb*);
void init();
void release();
// classify operations
@@ -329,6 +329,10 @@ private:
int getOperationType() const;
friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
#endif
+
+ void next(NdbBlob* obj) { theNext= obj;}
+ NdbBlob* next() { return theNext;}
+ friend struct Ndb_free_list_t<NdbBlob>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbIndexOperation.hpp b/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
index 3de6835238e..a8a15978568 100644
--- a/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -181,6 +181,7 @@ private:
// Private attributes
const NdbIndexImpl* m_theIndex;
+ friend struct Ndb_free_list_t<NdbIndexOperation>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
index fd7e9f2d05c..dea0a079d4a 100644
--- a/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp
@@ -168,9 +168,10 @@ private:
int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
Uint32 m_sort_columns;
-
Uint32 m_this_bound_start;
Uint32 * m_first_bound_word;
+
+ friend struct Ndb_free_list_t<NdbIndexScanOperation>;
};
#endif
diff --git a/storage/ndb/include/ndbapi/NdbOperation.hpp b/storage/ndb/include/ndbapi/NdbOperation.hpp
index fca610772cc..1035c642c97 100644
--- a/storage/ndb/include/ndbapi/NdbOperation.hpp
+++ b/storage/ndb/include/ndbapi/NdbOperation.hpp
@@ -22,6 +22,7 @@
#include "NdbError.hpp"
#include "NdbReceiver.hpp"
#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class Ndb;
class NdbApiSignal;
@@ -756,8 +757,6 @@ protected:
/******************************************************************************
* These are the methods used to create and delete the NdbOperation objects.
*****************************************************************************/
- NdbOperation(Ndb* aNdb);
- virtual ~NdbOperation();
bool needReply();
/******************************************************************************
@@ -769,6 +768,8 @@ protected:
int init(const class NdbTableImpl*, NdbTransaction* aCon);
void initInterpreter();
+ NdbOperation(Ndb* aNdb);
+ virtual ~NdbOperation();
void next(NdbOperation*); // Set next pointer
NdbOperation* next(); // Get next pointer
public:
@@ -965,6 +966,8 @@ protected:
* IgnoreError on connection level.
*/
Int8 m_abortOption;
+
+ friend struct Ndb_free_list_t<NdbOperation>;
};
#ifdef NDB_NO_DROPPED_SIGNAL
diff --git a/storage/ndb/include/ndbapi/NdbRecAttr.hpp b/storage/ndb/include/ndbapi/NdbRecAttr.hpp
index 50de4f3277e..3607a64f3b3 100644
--- a/storage/ndb/include/ndbapi/NdbRecAttr.hpp
+++ b/storage/ndb/include/ndbapi/NdbRecAttr.hpp
@@ -17,7 +17,8 @@
#ifndef NdbRecAttr_H
#define NdbRecAttr_H
-#include <NdbDictionary.hpp>
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbOperation;
@@ -248,7 +249,6 @@ public:
const NdbRecAttr* next() const;
#endif
private:
- NdbRecAttr();
Uint32 attrId() const; /* Get attribute id */
bool setNULL(); /* Set NULL indicator */
@@ -258,6 +258,7 @@ private:
void release(); /* Release memory if allocated */
void init(); /* Initialise object when allocated */
+ NdbRecAttr(Ndb*);
void next(NdbRecAttr* aRecAttr);
NdbRecAttr* next();
@@ -280,6 +281,8 @@ private:
Uint32 theAttrSize;
Uint32 theArraySize;
const NdbDictionary::Column* m_column;
+
+ friend struct Ndb_free_list_t<NdbRecAttr>;
};
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
diff --git a/storage/ndb/include/ndbapi/NdbTransaction.hpp b/storage/ndb/include/ndbapi/NdbTransaction.hpp
index 2e102b104d8..a6ba6a11c4d 100644
--- a/storage/ndb/include/ndbapi/NdbTransaction.hpp
+++ b/storage/ndb/include/ndbapi/NdbTransaction.hpp
@@ -18,8 +18,9 @@
#define NdbTransaction_H
#include <ndb_types.h>
-#include <NdbError.hpp>
-#include <NdbDictionary.hpp>
+#include "NdbError.hpp"
+#include "NdbDictionary.hpp"
+#include "Ndb.hpp"
class NdbTransaction;
class NdbOperation;
@@ -581,9 +582,7 @@ private:
/**************************************************************************
* These are the create and delete methods of this class. *
**************************************************************************/
-
NdbTransaction(Ndb* aNdb);
-
~NdbTransaction();
void init(); // Initialize connection object for new transaction
@@ -807,6 +806,7 @@ private:
void define_scan_op(NdbIndexScanOperation*);
friend class HugoOperations;
+ friend struct Ndb_free_list_t<NdbTransaction>;
};
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
diff --git a/storage/ndb/src/common/debugger/EventLogger.cpp b/storage/ndb/src/common/debugger/EventLogger.cpp
index 06345695107..36796e700b4 100644
--- a/storage/ndb/src/common/debugger/EventLogger.cpp
+++ b/storage/ndb/src/common/debugger/EventLogger.cpp
@@ -669,6 +669,27 @@ void getTextBackupAborted(QQQQ) {
theData[3]);
}
+void getTextSingleUser(QQQQ) {
+ switch (theData[1])
+ {
+ case 0:
+ BaseString::snprintf(m_text, m_text_len, "Entering single user mode");
+ break;
+ case 1:
+ BaseString::snprintf(m_text, m_text_len,
+ "Entered single user mode "
+ "Node %d has exclusive access", theData[2]);
+ break;
+ case 2:
+ BaseString::snprintf(m_text, m_text_len,"Exiting single user mode");
+ break;
+ default:
+ BaseString::snprintf(m_text, m_text_len,
+ "Unknown single user report %d", theData[1]);
+ break;
+ }
+}
+
#if 0
BaseString::snprintf(m_text,
m_text_len,
@@ -753,6 +774,9 @@ const EventLoggerBase::EventRepLogLevelMatrix EventLoggerBase::matrix[] = {
ROW(InfoEvent, LogLevel::llInfo, 2, Logger::LL_INFO ),
ROW(EventBufferStatus, LogLevel::llInfo, 7, Logger::LL_INFO ),
+ //Single User
+ ROW(SingleUser, LogLevel::llInfo, 7, Logger::LL_INFO ),
+
// Backup
ROW(BackupStarted, LogLevel::llBackup, 7, Logger::LL_INFO ),
ROW(BackupCompleted, LogLevel::llBackup, 7, Logger::LL_INFO ),
diff --git a/storage/ndb/src/common/util/SimpleProperties.cpp b/storage/ndb/src/common/util/SimpleProperties.cpp
index c25aaea491a..c9251c6a854 100644
--- a/storage/ndb/src/common/util/SimpleProperties.cpp
+++ b/storage/ndb/src/common/util/SimpleProperties.cpp
@@ -51,11 +51,12 @@ SimpleProperties::Writer::add(const char * value, int len){
union {
Uint32 lastWord;
char lastBytes[4];
- };
- memcpy(lastBytes,
+ } tmp;
+ tmp.lastWord =0 ;
+ memcpy(tmp.lastBytes,
value + putLen*4,
len - putLen*4);
- return putWord(lastWord);
+ return putWord(tmp.lastWord);
}
bool
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
index 063e36a775f..cbffd6bcb6b 100644
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -3262,6 +3262,7 @@ Backup::execBACKUP_FRAGMENT_REQ(Signal* signal)
req->requestInfo = 0;
req->savePointId = 0;
req->tableId = table.tableId;
+ ScanFragReq::setReadCommittedFlag(req->requestInfo, 1);
ScanFragReq::setLockMode(req->requestInfo, 0);
ScanFragReq::setHoldLockFlag(req->requestInfo, 0);
ScanFragReq::setKeyinfoFlag(req->requestInfo, 0);
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index a09ee0472a4..7ec3bde41e8 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -3255,8 +3255,8 @@ Dbdict::alterTable_backup_mutex_locked(Signal* signal,
lreq->gci = tablePtr.p->gciTableCreated;
lreq->requestType = AlterTabReq::AlterTablePrepare;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
void Dbdict::alterTableRef(Signal * signal,
@@ -3740,8 +3740,8 @@ Dbdict::execALTER_TAB_CONF(Signal * signal){
lreq->gci = gci;
lreq->requestType = AlterTabReq::AlterTableCommit;
- sendSignal(rg, GSN_ALTER_TAB_REQ, signal,
- AlterTabReq::SignalLength, JBB);
+ sendFragmentedSignal(rg, GSN_ALTER_TAB_REQ, signal,
+ AlterTabReq::SignalLength, JBB);
}
}
else {
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am b/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
index 0c22e06b855..367e3cf203b 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
+++ b/storage/ndb/src/kernel/blocks/dbdict/Makefile.am
@@ -1,12 +1,20 @@
-#SUBDIRS = printSchemafile
-
noinst_LIBRARIES = libdbdict.a
+EXTRA_PROGRAMS = printSchemaFile
libdbdict_a_SOURCES = Dbdict.cpp
+printSchemaFile_SOURCES = printSchemaFile.cpp
+
include $(top_srcdir)/storage/ndb/config/common.mk.am
include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+LDADD += \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/dbug/libdbug.a \
+ $(top_builddir)/mysys/libmysys.a \
+ $(top_builddir)/strings/libmystrings.a
+
# Don't update the files from bitkeeper
%::SCCS/s.%
diff --git a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
index 9858744a61d..f73654fd9d5 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp
@@ -1,14 +1,3 @@
-#if 0
-make -f Makefile -f - printSchemaFile <<'_eof_'
-printSchemaFile: printSchemaFile.cpp SchemaFile.hpp
- $(CXXCOMPILE) -o $@ $@.cpp -L../../../common/util/.libs -lgeneral
-ifneq ($(MYSQL_HOME),)
- ln -sf `pwd`/$@ $(MYSQL_HOME)/bin/$@
-endif
-_eof_
-exit $?
-#endif
-
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
@@ -36,14 +25,19 @@ exit $?
static const char* progname = 0;
static bool allflag = false;
static bool checkonly = false;
-static int xitcode = 0;
+static bool equalcontents = false;
+static bool okquiet = false;
static void
usage()
{
- ndbout << "Usage " << progname
- << " [-ac]"
- << " P0.SchemaLog" << endl;
+ ndbout
+ << "Usage: " << progname << " [-aceq]" << " file ..." << endl
+ << "-a print also unused slots" << endl
+ << "-c check only (return status 1 on error)" << endl
+ << "-e check also that the files have identical contents" << endl
+ << "-q no output if file is ok" << endl
+ << "Example: " << progname << " -ceq ndb_*_fs/D[12]/DBDICT/P0.SchemaLog" << endl;
}
static void
@@ -57,53 +51,78 @@ fill(const char * buf, int mod)
}
}
-static void
+static const char*
+version(Uint32 v)
+{
+ static char buf[40];
+ sprintf(buf, "%d.%d.%d", v >> 16, (v >> 8) & 0xFF, v & 0xFF);
+ return buf;
+}
+
+static int
print_head(const char * filename, const SchemaFile * sf)
{
+ int retcode = 0;
+
if (! checkonly) {
ndbout << "----- Schemafile: " << filename << " -----" << endl;
- ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %d.%d.%d FileSize: %d",
+ ndbout_c("Magic: %.*s ByteOrder: %.8x NdbVersion: %s FileSize: %d",
sizeof(sf->Magic),
sf->Magic,
sf->ByteOrder,
- sf->NdbVersion >> 16,
- (sf->NdbVersion >> 8) & 0xFF,
- sf->NdbVersion & 0xFF,
+ version(sf->NdbVersion),
sf->FileSize);
}
+
+ if (memcmp(sf->Magic, "NDBSCHMA", sizeof(sf->Magic) != 0)) {
+ ndbout << filename << ": invalid header magic" << endl;
+ retcode = 1;
+ }
+
+ if ((sf->NdbVersion >> 16) < 4 || (sf->NdbVersion >> 16) > 9) {
+ ndbout << filename << ": impossible version " << hex << sf->NdbVersion << endl;
+ retcode = 1;
+ }
+
+ return retcode;
}
-static void
-print_old(const char * filename, const SchemaFile * sf)
+static int
+print_old(const char * filename, const SchemaFile * sf, Uint32 sz)
{
- print_head(filename, sf);
+ int retcode = 0;
+
+ if (print_head(filename, sf) != 0)
+ retcode = 1;
for (Uint32 i = 0; i < sf->NoOfTableEntries; i++) {
SchemaFile::TableEntry_old te = sf->TableEntries_old[i];
if (allflag ||
(te.m_tableState != SchemaFile::INIT &&
te.m_tableState != SchemaFile::DROP_TABLE_COMMITTED)) {
- ndbout << "Table " << i << ":"
- << " State = " << te.m_tableState
- << " version = " << table_version_major(te.m_tableVersion) <<
- << "(" << table_version_minor(te.m_tableVersion) << ")"
- << " type = " << te.m_tableType
- << " noOfPages = " << te.m_noOfPages
- << " gcp: " << te.m_gcp << endl;
+ if (! checkonly)
+ ndbout << "Table " << i << ":"
+ << " State = " << te.m_tableState
+ << " version = " << te.m_tableVersion
+ << " type = " << te.m_tableType
+ << " noOfPages = " << te.m_noOfPages
+ << " gcp: " << te.m_gcp << endl;
}
}
+ return retcode;
}
-static void
+static int
print(const char * filename, const SchemaFile * xsf, Uint32 sz)
{
int retcode = 0;
- print_head(filename, xsf);
+ if (print_head(filename, xsf) != 0)
+ retcode = 1;
assert(sizeof(SchemaFile) == NDB_SF_PAGE_SIZE);
if (xsf->FileSize != sz || xsf->FileSize % NDB_SF_PAGE_SIZE != 0) {
- ndbout << "***** invalid FileSize " << xsf->FileSize << endl;
+ ndbout << filename << ": invalid FileSize " << xsf->FileSize << endl;
retcode = 1;
}
Uint32 noOfPages = xsf->FileSize / NDB_SF_PAGE_SIZE;
@@ -112,19 +131,23 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
ndbout << "----- Page: " << n << " (" << noOfPages << ") -----" << endl;
}
const SchemaFile * sf = &xsf[n];
+ if (memcmp(sf->Magic, xsf->Magic, sizeof(sf->Magic)) != 0) {
+ ndbout << filename << ": page " << n << " invalid magic" << endl;
+ retcode = 1;
+ }
if (sf->FileSize != xsf->FileSize) {
- ndbout << "***** page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
+ ndbout << filename << ": page " << n << " FileSize changed to " << sf->FileSize << "!=" << xsf->FileSize << endl;
retcode = 1;
}
Uint32 cs = 0;
for (Uint32 j = 0; j < NDB_SF_PAGE_SIZE_IN_WORDS; j++)
cs ^= ((const Uint32*)sf)[j];
if (cs != 0) {
- ndbout << "***** page " << n << " invalid CheckSum" << endl;
+ ndbout << filename << ": page " << n << " invalid CheckSum" << endl;
retcode = 1;
}
if (sf->NoOfTableEntries != NDB_SF_PAGE_ENTRIES) {
- ndbout << "***** page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
+ ndbout << filename << ": page " << n << " invalid NoOfTableEntries " << sf->NoOfTableEntries << endl;
retcode = 1;
}
for (Uint32 i = 0; i < NDB_SF_PAGE_ENTRIES; i++) {
@@ -142,31 +165,41 @@ print(const char * filename, const SchemaFile * xsf, Uint32 sz)
<< " gcp: " << te.m_gcp << endl;
}
if (te.m_unused[0] != 0 || te.m_unused[1] != 0 || te.m_unused[2] != 0) {
- ndbout << "***** entry " << j << " garbage in m_unused[3]" << endl;
+ ndbout << filename << ": entry " << j << " garbage in m_unused[3]" << endl;
retcode = 1;
}
}
}
- if (retcode != 0)
- xitcode = 1;
- else if (checkonly)
- ndbout << "ok: " << filename << endl;
+ return retcode;
}
NDB_COMMAND(printSchemafile,
"printSchemafile", "printSchemafile", "Prints a schemafile", 16384)
{
progname = argv[0];
+ int exitcode = 0;
- while (argv[1][0] == '-') {
+ while (argc > 1 && argv[1][0] == '-') {
if (strchr(argv[1], 'a') != 0)
allflag = true;
if (strchr(argv[1], 'c') != 0)
checkonly = true;
+ if (strchr(argv[1], 'e') != 0)
+ equalcontents = true;
+ if (strchr(argv[1], 'q') != 0)
+ okquiet = true;
+ if (strchr(argv[1], 'h') != 0 || strchr(argv[1], '?') != 0) {
+ usage();
+ return 0;
+ }
argc--, argv++;
}
+ const char * prevfilename = 0;
+ Uint32 * prevbuf = 0;
+ Uint32 prevbytes = 0;
+
while (argc > 1) {
const char * filename = argv[1];
argc--, argv++;
@@ -174,8 +207,9 @@ NDB_COMMAND(printSchemafile,
struct stat sbuf;
const int res = stat(filename, &sbuf);
if (res != 0) {
- ndbout << "Could not find file: \"" << filename << "\"" << endl;
- return 1;
+ ndbout << filename << ": not found errno=" << errno << endl;
+ exitcode = 1;
+ continue;
}
const Uint32 bytes = sbuf.st_size;
@@ -183,25 +217,56 @@ NDB_COMMAND(printSchemafile,
FILE * f = fopen(filename, "rb");
if (f == 0) {
- ndbout << "Failed to open file" << endl;
+ ndbout << filename << ": open failed errno=" << errno << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
Uint32 sz = fread(buf, 1, bytes, f);
fclose(f);
if (sz != bytes) {
- ndbout << "Failure while reading file" << endl;
+ ndbout << filename << ": read failed errno=" << errno << endl;
+ delete [] buf;
+ exitcode = 1;
+ continue;
+ }
+
+ if (sz < 32) {
+ ndbout << filename << ": too short (no header)" << endl;
delete [] buf;
- return 1;
+ exitcode = 1;
+ continue;
}
SchemaFile* sf = (SchemaFile *)&buf[0];
+ int ret;
if (sf->NdbVersion < NDB_SF_VERSION_5_0_6)
- print_old(filename, sf);
+ ret = print_old(filename, sf, sz);
else
- print(filename, sf, sz);
- delete [] buf;
+ ret = print(filename, sf, sz);
+
+ if (ret != 0) {
+ ndbout << filename << ": check failed"
+ << " version=" << version(sf->NdbVersion) << endl;
+ exitcode = 1;
+ } else if (! okquiet) {
+ ndbout << filename << ": ok"
+ << " version=" << version(sf->NdbVersion) << endl;
+ }
+
+ if (equalcontents && prevfilename != 0) {
+ if (prevbytes != bytes || memcmp(prevbuf, buf, bytes) != 0) {
+ ndbout << filename << ": differs from " << prevfilename << endl;
+ exitcode = 1;
+ }
+ }
+
+ prevfilename = filename;
+ delete [] prevbuf;
+ prevbuf = buf;
+ prevbytes = bytes;
}
- return xitcode;
+ delete [] prevbuf;
+ return exitcode;
}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
index 9631a2b2e9b..65a61174596 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
@@ -1004,8 +1004,19 @@ Dbtup::read_pseudo(Uint32 attrId, Uint32* outBuffer){
return 1;
case AttributeHeader::FRAGMENT_MEMORY:
{
- Uint64 tmp= fragptr.p->noOfPages;
- tmp*= 32768;
+ Uint64 tmp = 0;
+ tmp += fragptr.p->noOfPages;
+ {
+ /**
+ * Each fragment is split into 2...get #pages from other as well
+ */
+ Uint32 twin = fragptr.p->fragmentId ^ 1;
+ FragrecordPtr twinPtr;
+ getFragmentrec(twinPtr, twin, tabptr.p);
+ ndbrequire(twinPtr.p != 0);
+ tmp += twinPtr.p->noOfPages;
+ }
+ tmp *= 32768;
memcpy(outBuffer,&tmp,8);
}
return 2;
diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
index a943ea3c3c9..f4b0a7774d8 100644
--- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp
@@ -1975,6 +1975,11 @@ Ndbcntr::execRESUME_REQ(Signal* signal){
//ResumeRef * const ref = (ResumeRef *)&signal->theData[0];
jamEntry();
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 2;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+
//Uint32 senderData = req->senderData;
//BlockReference senderRef = req->senderRef;
NodeState newState(NodeState::SL_STARTED);
@@ -2013,12 +2018,11 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
return;
}
- if(c_stopRec.stopReq.senderRef != 0 && !singleuser){
- jam();
+ if(c_stopRec.stopReq.senderRef != 0){
/**
* Requested a system shutdown
*/
- if(StopReq::getSystemStop(req->requestInfo)){
+ if(!singleuser && StopReq::getSystemStop(req->requestInfo)){
jam();
sendSignalWithDelay(reference(), GSN_STOP_REQ, signal, 100,
StopReq::SignalLength);
@@ -2040,23 +2044,28 @@ Ndbcntr::execSTOP_REQ(Signal* signal){
c_stopRec.stopReq = * req;
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
- if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) && !singleuser) {
- jam();
- if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
- ((Configuration&)theConfiguration).stopOnError(false);
- }
- }
if(!singleuser) {
+ if(StopReq::getSystemStop(c_stopRec.stopReq.requestInfo)) {
+ jam();
+ if(StopReq::getPerformRestart(c_stopRec.stopReq.requestInfo)){
+ ((Configuration&)theConfiguration).stopOnError(false);
+ }
+ }
if(!c_stopRec.checkNodeFail(signal)){
jam();
return;
}
+ signal->theData[0] = NDB_LE_NDBStopStarted;
+ signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
}
-
- signal->theData[0] = NDB_LE_NDBStopStarted;
- signal->theData[1] = StopReq::getSystemStop(c_stopRec.stopReq.requestInfo) ? 1 : 0;
- sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
-
+ else
+ {
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 0;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+ }
+
NodeState newState(NodeState::SL_STOPPING_1,
StopReq::getSystemStop(c_stopRec.stopReq.requestInfo));
@@ -2138,9 +2147,11 @@ Ndbcntr::StopRecord::checkNodeFail(Signal* signal){
stopReq.senderRef = 0;
- NodeState newState(NodeState::SL_STARTED);
-
- cntr.updateNodeState(signal, newState);
+ if (cntr.getNodeState().startLevel != NodeState::SL_SINGLEUSER)
+ {
+ NodeState newState(NodeState::SL_STARTED);
+ cntr.updateNodeState(signal, newState);
+ }
signal->theData[0] = NDB_LE_NDBStopAborted;
cntr.sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 1, JBB);
@@ -2236,12 +2247,24 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
jamEntry();
if(c_stopRec.stopReq.singleuser) {
jam();
+
NodeState newState(NodeState::SL_SINGLEUSER);
newState.setSingleUser(true);
newState.setSingleUserApi(c_stopRec.stopReq.singleUserApi);
updateNodeState(signal, newState);
c_stopRec.stopInitiatedTime = NdbTick_CurrentMillisecond();
+ StopConf * const stopConf = (StopConf *)&signal->theData[0];
+ stopConf->senderData = c_stopRec.stopReq.senderData;
+ stopConf->nodeState = (Uint32) NodeState::SL_SINGLEUSER;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_CONF, signal, StopConf::SignalLength, JBB);
+
+ c_stopRec.stopReq.senderRef = 0; // the command is done
+
+ signal->theData[0] = NDB_LE_SingleUser;
+ signal->theData[1] = 1;
+ signal->theData[2] = c_stopRec.stopReq.singleUserApi;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 3, JBB);
}
else
{
@@ -2259,7 +2282,13 @@ void Ndbcntr::execABORT_ALL_CONF(Signal* signal){
void Ndbcntr::execABORT_ALL_REF(Signal* signal){
jamEntry();
- ndbrequire(false);
+ AbortAllRef *abortAllRef = (AbortAllRef *)&signal->theData[0];
+ AbortAllRef::ErrorCode errorCode = (AbortAllRef::ErrorCode) abortAllRef->errorCode;
+
+ StopRef * const stopRef = (StopRef *)&signal->theData[0];
+ stopRef->senderData = c_stopRec.stopReq.senderData;
+ stopRef->errorCode = StopRef::TransactionAbortFailed;
+ sendSignal(c_stopRec.stopReq.senderRef, GSN_STOP_REF, signal, StopRef::SignalLength, JBB);
}
void
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 75cb92b98c1..4d7ed288592 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -2016,6 +2016,8 @@ Qmgr::execAPI_VERSION_REQ(Signal * signal) {
else
conf->version = 0;
conf->nodeId = nodeId;
+ struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
+ conf->inet_addr= in.s_addr;
sendSignal(senderRef,
GSN_API_VERSION_CONF,
diff --git a/storage/ndb/src/mgmapi/ndb_logevent.cpp b/storage/ndb/src/mgmapi/ndb_logevent.cpp
index a5ffb302c22..5fb83e58c6c 100644
--- a/storage/ndb/src/mgmapi/ndb_logevent.cpp
+++ b/storage/ndb/src/mgmapi/ndb_logevent.cpp
@@ -297,6 +297,8 @@ struct Ndb_logevent_body_row ndb_logevent_body[]= {
ROW( BackupAborted, "backup_id", 2, backup_id),
ROW( BackupAborted, "error", 3, error),
+ ROW( SingleUser, "type", 1, type),
+ ROW( SingleUser, "node_id", 2, node_id),
{ NDB_LE_ILLEGAL_TYPE, 0, 0, 0, 0, 0}
};
diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
index 0a9b4e4a956..1e32ba65c6b 100644
--- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp
+++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp
@@ -1369,9 +1369,8 @@ CommandInterpreter::executeEnterSingleUser(char* parameters)
ndbout_c("Entering single user mode for node %d failed", nodeId);
printError();
} else {
- ndbout_c("Entering single user mode");
- ndbout_c("Access will be granted for API node %d only.", nodeId);
- ndbout_c("Use ALL STATUS to see when single user mode has been entered.");
+ ndbout_c("Single user mode entered");
+ ndbout_c("Access is granted for API node %d only.", nodeId);
}
}
@@ -1384,7 +1383,7 @@ CommandInterpreter::executeExitSingleUser(char* parameters)
printError();
} else {
ndbout_c("Exiting single user mode in progress.");
- ndbout_c("Use ALL STATUS to see when single user mode has been exited.");
+ ndbout_c("Use ALL STATUS or SHOW to see when single user mode has been exited.");
}
}
diff --git a/storage/ndb/src/mgmsrv/Config.cpp b/storage/ndb/src/mgmsrv/Config.cpp
index 5ff9cbe04ad..6ff5fb789f0 100644
--- a/storage/ndb/src/mgmsrv/Config.cpp
+++ b/storage/ndb/src/mgmsrv/Config.cpp
@@ -179,90 +179,3 @@ void Config::printConfigFile(NdbOut &out) const {
}
#endif
}
-
-Uint32
-Config::getGenerationNumber() const {
-#if 0
- Uint32 ret;
- const Properties *prop = NULL;
-
- get("SYSTEM", &prop);
-
- if(prop != NULL)
- if(prop->get("ConfigGenerationNumber", &ret))
- return ret;
-
- return 0;
-#else
- return 0;
-#endif
-}
-
-int
-Config::setGenerationNumber(Uint32 gen) {
-#if 0
- Properties *prop = NULL;
-
- getCopy("SYSTEM", &prop);
-
- if(prop != NULL) {
- MGM_REQUIRE(prop->put("ConfigGenerationNumber", gen, true));
- MGM_REQUIRE(put("SYSTEM", prop, true));
- return 0;
- }
- return -1;
-#else
- return -1;
-#endif
-}
-
-bool
-Config::change(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
-#if 0
- const char *name;
- Properties::Iterator it(this);
-
- for(name = it.first(); name != NULL; name = it.next()) {
- Properties *prop = NULL;
- if(strcasecmp(section.c_str(), name) == 0) {
- getCopy(name, &prop);
- if(prop == NULL) /* doesn't exist */
- return false;
- if(value == "") {
- prop->remove(param.c_str());
- put(section.c_str(), prop, true);
- } else {
- PropertiesType t;
- if(!prop->getTypeOf(param.c_str(), &t)) /* doesn't exist */
- return false;
- switch(t) {
- case PropertiesType_Uint32:
- long val;
- char *ep;
- errno = 0;
- val = strtol(value.c_str(), &ep, 0);
- if(value.length() == 0 || *ep != '\0') /* not a number */
- return false;
- if(errno == ERANGE)
- return false;
- prop->put(param.c_str(), (unsigned int)val, true);
- put(section.c_str(), prop, true);
- break;
- case PropertiesType_char:
- prop->put(param.c_str(), value.c_str(), true);
- put(section.c_str(), prop, true);
- break;
- default:
- return false;
- }
- }
- break;
- }
- }
- return true;
-#else
- return false;
-#endif
-}
diff --git a/storage/ndb/src/mgmsrv/Config.hpp b/storage/ndb/src/mgmsrv/Config.hpp
index b5e1e17b027..8e16ddf1810 100644
--- a/storage/ndb/src/mgmsrv/Config.hpp
+++ b/storage/ndb/src/mgmsrv/Config.hpp
@@ -60,16 +60,6 @@ public:
printConfigFile(ndb);
}
- Uint32 getGenerationNumber() const;
- int setGenerationNumber(Uint32);
-
- /** Change configuration
- */
- bool change(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
-
/**
* Info
*/
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
index 4e96047e54d..a870c395bd2 100644
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -241,6 +241,9 @@ struct DepricationTransform {
static
const DepricationTransform f_deprication[] = {
{ DB_TOKEN, "Discless", "Diskless", 0, 1 },
+ { DB_TOKEN, "Id", "nodeid", 0, 1 },
+ { API_TOKEN, "Id", "nodeid", 0, 1 },
+ { MGM_TOKEN, "Id", "nodeid", 0, 1 },
{ 0, 0, 0, 0, 0}
};
@@ -405,9 +408,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
DB_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ DB_TOKEN,
"Number identifying the database node ("DB_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1244,9 +1259,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
API_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ API_TOKEN,
"Number identifying application node ("API_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -1375,9 +1402,21 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
0, 0 },
{
- CFG_NODE_ID,
+ KEY_INTERNAL,
"Id",
MGM_TOKEN,
+ "",
+ ConfigInfo::CI_DEPRICATED,
+ false,
+ ConfigInfo::CI_INT,
+ MANDATORY,
+ "1",
+ STR_VALUE(MAX_NODES) },
+
+ {
+ CFG_NODE_ID,
+ "nodeid",
+ MGM_TOKEN,
"Number identifying the management server node ("MGM_TOKEN_PRINT")",
ConfigInfo::CI_USED,
false,
@@ -2516,14 +2555,14 @@ bool
transformNode(InitConfigFileParser::Context & ctx, const char * data){
Uint32 id;
- if(!ctx.m_currentSection->get("Id", &id)){
+ if(!ctx.m_currentSection->get("nodeid", &id) && !ctx.m_currentSection->get("Id", &id)){
Uint32 nextNodeId= 1;
ctx.m_userProperties.get("NextNodeId", &nextNodeId);
id= nextNodeId;
while (ctx.m_userProperties.get("AllocatedNodeId_", id, &id))
id++;
ctx.m_userProperties.put("NextNodeId", id+1, true);
- ctx.m_currentSection->put("Id", id);
+ ctx.m_currentSection->put("nodeid", id);
#if 0
ctx.reportError("Mandatory parameter Id missing from section "
"[%s] starting at line: %d",
@@ -2531,7 +2570,7 @@ transformNode(InitConfigFileParser::Context & ctx, const char * data){
return false;
#endif
} else if(ctx.m_userProperties.get("AllocatedNodeId_", id, &id)) {
- ctx.reportError("Duplicate Id in section "
+ ctx.reportError("Duplicate nodeid in section "
"[%s] starting at line: %d",
ctx.fname, ctx.m_sectionLineno);
return false;
@@ -3356,6 +3395,7 @@ transform(InitConfigFileParser::Context & ctx,
PropertiesType oldType;
require(ctx.m_currentSection->getTypeOf(oldName, &oldType));
ConfigInfo::Type newType = ctx.m_info->getType(ctx.m_currentInfo, newName);
+
if(!((oldType == PropertiesType_Uint32 || oldType == PropertiesType_Uint64)
&& (newType == ConfigInfo::CI_INT || newType == ConfigInfo::CI_INT64 || newType == ConfigInfo::CI_BOOL))){
ndbout << "oldType: " << (int)oldType << ", newType: " << (int)newType << endl;
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
index 822e10c89aa..94f07ab0ca1 100644
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -31,8 +31,10 @@ static void require(bool v) { if(!v) abort();}
//****************************************************************************
// Ctor / Dtor
//****************************************************************************
-InitConfigFileParser::InitConfigFileParser(){
+InitConfigFileParser::InitConfigFileParser(FILE * out)
+{
m_info = new ConfigInfo();
+ m_errstream = out ? out : stdout;
}
InitConfigFileParser::~InitConfigFileParser() {
@@ -42,11 +44,12 @@ InitConfigFileParser::~InitConfigFileParser() {
//****************************************************************************
// Read Config File
//****************************************************************************
-InitConfigFileParser::Context::Context(const ConfigInfo * info)
+InitConfigFileParser::Context::Context(const ConfigInfo * info, FILE * out)
: m_userProperties(true), m_configValues(1000, 20) {
m_config = new Properties(true);
m_defaults = new Properties(true);
+ m_errstream = out;
}
InitConfigFileParser::Context::~Context(){
@@ -61,10 +64,10 @@ Config *
InitConfigFileParser::parseConfig(const char * filename) {
FILE * file = fopen(filename, "r");
if(file == 0){
- ndbout << "Error opening file: " << filename << endl;
+ fprintf(m_errstream, "Error opening file: %s\n", filename);
return 0;
}
-
+
Config * ret = parseConfig(file);
fclose(file);
return ret;
@@ -75,7 +78,7 @@ InitConfigFileParser::parseConfig(FILE * file) {
char line[MAX_LINE_LENGTH];
- Context ctx(m_info);
+ Context ctx(m_info, m_errstream);
ctx.m_lineno = 0;
ctx.m_currentSection = 0;
@@ -160,6 +163,13 @@ InitConfigFileParser::parseConfig(FILE * file) {
ctx.reportError("Could not store section of configuration file.");
return 0;
}
+
+ return run_config_rules(ctx);
+}
+
+Config*
+InitConfigFileParser::run_config_rules(Context& ctx)
+{
for(size_t i = 0; ConfigInfo::m_ConfigRules[i].m_configRule != 0; i++){
ctx.type = InitConfigFileParser::Undefined;
ctx.m_currentSection = 0;
@@ -267,10 +277,10 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
}
if (status == ConfigInfo::CI_DEPRICATED) {
const char * desc = m_info->getDescription(ctx.m_currentInfo, fname);
- if(desc){
+ if(desc && desc[0]){
ctx.reportWarning("[%s] %s is depricated, use %s instead",
ctx.fname, fname, desc);
- } else {
+ } else if (desc == 0){
ctx.reportWarning("[%s] %s is depricated", ctx.fname, fname);
}
}
@@ -571,8 +581,9 @@ InitConfigFileParser::Context::reportError(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Error line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Error line %d: %s\n",
+ m_lineno, buf);
//m_currentSection->print();
}
@@ -585,6 +596,354 @@ InitConfigFileParser::Context::reportWarning(const char * fmt, ...){
va_start(ap, fmt);
if (fmt != 0)
BaseString::vsnprintf(buf, sizeof(buf)-1, fmt, ap);
- ndbout << "Warning line " << m_lineno << ": " << buf << endl;
va_end(ap);
+ fprintf(m_errstream, "Warning line %d: %s\n",
+ m_lineno, buf);
+}
+
+#include <my_sys.h>
+#include <my_getopt.h>
+
+static int order = 1;
+static
+my_bool
+parse_mycnf_opt(int, const struct my_option * opt, char * value)
+{
+ if(opt->comment)
+ ((struct my_option *)opt)->app_type++;
+ else
+ ((struct my_option *)opt)->app_type = order++;
+ return 0;
+}
+
+bool
+InitConfigFileParser::store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ for(unsigned i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment &&
+ options[i].app_type &&
+ strcmp(options[i].comment, name) == 0)
+ {
+ Uint64 value_int;
+ switch(options[i].var_type){
+ case GET_INT:
+ value_int = *(Uint32*)options[i].value;
+ break;
+ case GET_LL:
+ value_int = *(Uint64*)options[i].value;
+ break;
+ case GET_STR:
+ ctx.m_currentSection->put(options[i].name, (char*)options[i].value);
+ continue;
+ default:
+ abort();
+ }
+
+ const char * fname = options[i].name;
+ if (!m_info->verify(ctx.m_currentInfo, fname, value_int)) {
+ ctx.reportError("Illegal value %lld for parameter %s.\n"
+ "Legal values are between %Lu and %Lu",
+ value_int, fname,
+ m_info->getMin(ctx.m_currentInfo, fname),
+ m_info->getMax(ctx.m_currentInfo, fname));
+ return false;
+ }
+ if (options[i].var_type == GET_INT)
+ ctx.m_currentSection->put(options[i].name, (Uint32)value_int);
+ else
+ ctx.m_currentSection->put(options[i].name, value_int);
+ }
+ }
+ return true;
}
+
+bool
+InitConfigFileParser::handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name)
+{
+ strcpy(ctx.fname, name);
+ ctx.type = InitConfigFileParser::DefaultSection;
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = NULL;
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0);
+ if(store_in_properties(options, ctx, name))
+ return storeSection(ctx);
+ return false;
+}
+
+static
+int
+load_defaults(Vector<struct my_option>& options, const char* groups[])
+{
+ int argc = 1;
+ const char * argv[] = { "ndb_mgmd", 0, 0, 0, 0 };
+ BaseString file;
+ BaseString extra_file;
+ BaseString group_suffix;
+
+ const char *save_file = defaults_file;
+ char *save_extra_file = defaults_extra_file;
+ const char *save_group_suffix = defaults_group_suffix;
+
+ if (defaults_file)
+ {
+ file.assfmt("--defaults-file=%s", defaults_file);
+ argv[argc++] = file.c_str();
+ }
+
+ if (defaults_extra_file)
+ {
+ extra_file.assfmt("--defaults-extra-file=%s", defaults_extra_file);
+ argv[argc++] = extra_file.c_str();
+ }
+
+ if (defaults_group_suffix)
+ {
+ group_suffix.assfmt("--defaults-group-suffix=%s", defaults_group_suffix);
+ argv[argc++] = group_suffix.c_str();
+ }
+
+ char ** tmp = (char**)argv;
+ int ret = load_defaults("my", groups, &argc, &tmp);
+
+ defaults_file = save_file;
+ defaults_extra_file = save_extra_file;
+ defaults_group_suffix = save_group_suffix;
+
+ if (ret == 0)
+ {
+ return handle_options(&argc, &tmp, options.getBase(), parse_mycnf_opt);
+ }
+
+ return ret;
+}
+
+bool
+InitConfigFileParser::load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[])
+{
+ unsigned i;
+ Vector<struct my_option> copy;
+ for(i = 0; i<options.size(); i++)
+ {
+ if(options[i].comment && strcmp(options[i].comment, name) == 0)
+ {
+ options[i].app_type = 0;
+ copy.push_back(options[i]);
+ }
+ }
+
+ struct my_option end;
+ bzero(&end, sizeof(end));
+ copy.push_back(end);
+
+ if (load_defaults(copy, groups))
+ return false;
+
+ return store_in_properties(copy, ctx, name);
+}
+
+Config *
+InitConfigFileParser::parse_mycnf()
+{
+ int i;
+ Config * res = 0;
+ Vector<struct my_option> options;
+ for(i = 0; i<ConfigInfo::m_NoOfParams; i++)
+ {
+ if (strcmp(ConfigInfo::m_ParamInfo[i]._section, "DB") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "API") == 0 ||
+ strcmp(ConfigInfo::m_ParamInfo[i]._section, "MGM") == 0)
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ const ConfigInfo::ParamInfo& param = ConfigInfo::m_ParamInfo[i];
+ switch(param._type){
+ case ConfigInfo::CI_BOOL:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ break;
+ case ConfigInfo::CI_INT:
+ opt.value = (gptr*)malloc(sizeof(int));
+ opt.var_type = GET_INT;
+ break;
+ case ConfigInfo::CI_INT64:
+ opt.value = (gptr*)malloc(sizeof(Int64));
+ opt.var_type = GET_LL;
+ break;
+ case ConfigInfo::CI_STRING:
+ opt.value = (gptr*)malloc(sizeof(char *));
+ opt.var_type = GET_STR;
+ break;
+ default:
+ continue;
+ }
+ opt.name = param._fname;
+ opt.id = 256;
+ opt.app_type = 0;
+ opt.arg_type = REQUIRED_ARG;
+ opt.comment = param._section;
+ options.push_back(opt);
+ }
+ }
+
+ struct my_option *ndbd, *ndb_mgmd, *mysqld, *api;
+
+ /**
+ * Add ndbd, ndb_mgmd, api/mysqld
+ */
+ {
+ struct my_option opt;
+ bzero(&opt, sizeof(opt));
+ opt.name = "ndbd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndbd = &options.back();
+
+ opt.name = "ndb_mgmd";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ ndb_mgmd = &options.back();
+
+ opt.name = "mysqld";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ mysqld = &options.back();
+
+ opt.name = "api";
+ opt.id = 256;
+ opt.value = (gptr*)malloc(sizeof(char*));
+ opt.var_type = GET_STR;
+ opt.arg_type = REQUIRED_ARG;
+ options.push_back(opt);
+ api = &options.back();
+
+ bzero(&opt, sizeof(opt));
+ options.push_back(opt);
+ }
+
+
+ Context ctx(m_info, m_errstream);
+ const char *groups[]= { "cluster_config", 0 };
+ if (load_defaults(options, groups))
+ goto end;
+
+ ctx.m_lineno = 0;
+ if(!handle_mycnf_defaults(options, ctx, "DB"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "API"))
+ goto end;
+ if(!handle_mycnf_defaults(options, ctx, "MGM"))
+ goto end;
+
+ {
+ struct sect { struct my_option* src; const char * name; } sections[] =
+ {
+ { ndb_mgmd, "MGM" }
+ ,{ ndbd, "DB" }
+ ,{ mysqld, "API" }
+ ,{ api, "API" }
+ ,{ 0, 0 }, { 0, 0 }
+ };
+
+ for(i = 0; sections[i].src; i++)
+ {
+ for(int j = i + 1; sections[j].src; j++)
+ {
+ if (sections[j].src->app_type < sections[i].src->app_type)
+ {
+ sect swap = sections[i];
+ sections[i] = sections[j];
+ sections[j] = swap;
+ }
+ }
+ }
+
+ ctx.type = InitConfigFileParser::Section;
+ ctx.m_sectionLineno = ctx.m_lineno;
+ for(i = 0; sections[i].src; i++)
+ {
+ if (sections[i].src->app_type)
+ {
+ strcpy(ctx.fname, sections[i].name);
+ BaseString str(*(char**)sections[i].src->value);
+ Vector<BaseString> list;
+ str.split(list, ",");
+
+ const char * defaults_groups[] = { 0, 0, 0 };
+ for(unsigned j = 0; j<list.size(); j++)
+ {
+ BaseString group_idx;
+ BaseString group_host;
+ group_idx.assfmt("%s.%s.%d", groups[0],
+ sections[i].src->name, j + 1);
+ group_host.assfmt("%s.%s.%s", groups[0],
+ sections[i].src->name, list[j].c_str());
+ defaults_groups[0] = group_idx.c_str();
+ if(list[j].length())
+ defaults_groups[1] = group_host.c_str();
+ else
+ defaults_groups[1] = 0;
+
+ ctx.m_currentSection = new Properties(true);
+ ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults);
+ require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0);
+ require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname))!= 0);
+ ctx.m_currentSection->put("HostName", list[j].c_str());
+ if(!load_mycnf_groups(options, ctx, sections[i].name,
+ defaults_groups))
+ goto end;
+
+ if(!storeSection(ctx))
+ goto end;
+ }
+ }
+ }
+ }
+
+ res = run_config_rules(ctx);
+
+end:
+ for(i = 0; options[i].name; i++)
+ free(options[i].value);
+
+ return res;
+}
+
+template class Vector<struct my_option>;
+
+#if 0
+struct my_option
+{
+ const char *name; /* Name of the option */
+ int id; /* unique id or short option */
+ const char *comment; /* option comment, for autom. --help */
+ gptr *value; /* The variable value */
+ gptr *u_max_value; /* The user def. max variable value */
+ const char **str_values; /* Pointer to possible values */
+ ulong var_type;
+ enum get_opt_arg_type arg_type;
+ longlong def_value; /* Default value */
+ longlong min_value; /* Min allowed value */
+ longlong max_value; /* Max allowed value */
+ longlong sub_size; /* Subtract this from given value */
+ long block_size; /* Value should be a mult. of this */
+ int app_type; /* To be used by an application */
+};
+#endif
diff --git a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
index 1ea0a094ccd..616fd5a62fb 100644
--- a/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
+++ b/storage/ndb/src/mgmsrv/InitConfigFileParser.hpp
@@ -34,11 +34,12 @@ class ConfigInfo;
* object if the config file has correct syntax and semantic.
*/
class InitConfigFileParser {
+ FILE * m_errstream;
public:
/**
* Constructor
*/
- InitConfigFileParser();
+ InitConfigFileParser(FILE * errstream = stdout);
~InitConfigFileParser();
/**
@@ -50,6 +51,7 @@ public:
*/
Config * parseConfig(FILE * file);
Config * parseConfig(const char * filename);
+ Config * parse_mycnf();
/**
* Parser context struct
@@ -60,7 +62,7 @@ public:
* Context = Which section in init config file we are currently parsing
*/
struct Context {
- Context(const ConfigInfo *);
+ Context(const ConfigInfo *, FILE * out);
~Context();
ContextSectionType type; ///< Section type (e.g. default section,section)
@@ -82,6 +84,7 @@ public:
ConfigValuesFactory m_configValues; //
public:
+ FILE * m_errstream;
void reportError(const char * msg, ...);
void reportWarning(const char * msg, ...);
};
@@ -122,6 +125,21 @@ private:
* Information about parameters (min, max values etc)
*/
ConfigInfo* m_info;
+
+ bool handle_mycnf_defaults(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ bool load_mycnf_groups(Vector<struct my_option> & options,
+ InitConfigFileParser::Context& ctx,
+ const char * name,
+ const char *groups[]);
+
+ bool store_in_properties(Vector<struct my_option>& options,
+ InitConfigFileParser::Context& ctx,
+ const char * name);
+
+ Config* run_config_rules(Context& ctx);
};
#endif // InitConfigFileParser_H
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index 82e1d24d045..fedaea6a06c 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -66,6 +66,16 @@
#define DEBUG(x)
#endif
+#define INIT_SIGNAL_SENDER(ss,nodeId) \
+ SignalSender ss(theFacade); \
+ ss.lock(); /* lock will be released on exit */ \
+ {\
+ int result = okToSendTo(nodeId, true);\
+ if (result != 0) {\
+ return result;\
+ }\
+ }
+
extern int global_flag_send_heartbeat_now;
extern int g_no_nodeid_checks;
extern my_bool opt_core;
@@ -89,55 +99,6 @@ MgmtSrvr::logLevelThread_C(void* m)
return 0;
}
-void *
-MgmtSrvr::signalRecvThread_C(void *m)
-{
- MgmtSrvr *mgm = (MgmtSrvr*)m;
- mgm->signalRecvThreadRun();
- return 0;
-}
-
-class SigMatch
-{
-public:
- int gsn;
- void (MgmtSrvr::* function)(NdbApiSignal *signal);
-
- SigMatch() { gsn = 0; function = NULL; };
-
- SigMatch(int _gsn,
- void (MgmtSrvr::* _function)(NdbApiSignal *signal)) {
- gsn = _gsn;
- function = _function;
- };
-
- bool check(NdbApiSignal *signal) {
- if(signal->readSignalNumber() == gsn)
- return true;
- return false;
- };
-
-};
-
-void
-MgmtSrvr::signalRecvThreadRun()
-{
- Vector<SigMatch> siglist;
- siglist.push_back(SigMatch(GSN_MGM_LOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ));
- siglist.push_back(SigMatch(GSN_MGM_UNLOCK_CONFIG_REQ,
- &MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ));
-
- while(!_isStopThread) {
- SigMatch *handler = NULL;
- NdbApiSignal *signal = NULL;
- if(m_signalRecvQueue.waitFor(siglist, &handler, &signal, DEFAULT_TIMEOUT)) {
- if(handler->function != 0)
- (this->*handler->function)(signal);
- }
- }
-}
-
extern EventLogger g_eventLogger;
static NdbOut&
@@ -425,15 +386,12 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_isStopThread = false;
_logLevelThread = NULL;
_logLevelThreadSleep = 500;
- m_signalRecvThread = NULL;
theFacade = 0;
m_newConfig = NULL;
if (config_filename)
m_configFilename.assign(config_filename);
- else
- m_configFilename.assign("config.ini");
m_nextConfigGenerationNumber = 0;
@@ -468,7 +426,7 @@ MgmtSrvr::MgmtSrvr(SocketServer *socket_server,
_config= readConfig();
if (_config == 0) {
ndbout << "Unable to read config file" << endl;
- require(false);
+ exit(-1);
}
}
@@ -649,12 +607,6 @@ MgmtSrvr::start(BaseString &error_string)
"MgmtSrvr_Loglevel",
NDB_THREAD_PRIO_LOW);
- m_signalRecvThread = NdbThread_Create(signalRecvThread_C,
- (void **)this,
- 32768,
- "MgmtSrvr_Service",
- NDB_THREAD_PRIO_LOW);
-
DBUG_RETURN(true);
}
@@ -663,10 +615,6 @@ MgmtSrvr::start(BaseString &error_string)
//****************************************************************************
MgmtSrvr::~MgmtSrvr()
{
- while (theSignalIdleList != NULL) {
- freeSignal();
- }
-
if(theFacade != 0){
theFacade->stop_instance();
delete theFacade;
@@ -694,10 +642,6 @@ MgmtSrvr::~MgmtSrvr()
NdbThread_Destroy(&_logLevelThread);
}
- if (m_signalRecvThread != NULL) {
- NdbThread_WaitFor(m_signalRecvThread, &res);
- NdbThread_Destroy(&m_signalRecvThread);
- }
if (m_config_retriever)
delete m_config_retriever;
}
@@ -705,21 +649,21 @@ MgmtSrvr::~MgmtSrvr()
//****************************************************************************
//****************************************************************************
-int MgmtSrvr::okToSendTo(NodeId processId, bool unCond)
+int MgmtSrvr::okToSendTo(NodeId nodeId, bool unCond)
{
- if(processId == 0)
+ if(nodeId == 0)
return 0;
- if (getNodeType(processId) != NDB_MGM_NODE_TYPE_NDB)
+ if (getNodeType(nodeId) != NDB_MGM_NODE_TYPE_NDB)
return WRONG_PROCESS_TYPE;
// Check if we have contact with it
if(unCond){
- if(theFacade->theClusterMgr->getNodeInfo(processId).connected)
+ if(theFacade->theClusterMgr->getNodeInfo(nodeId).connected)
return 0;
return NO_CONTACT_WITH_PROCESS;
}
- if (theFacade->get_node_alive(processId) == 0) {
+ if (theFacade->get_node_alive(nodeId) == 0) {
return NO_CONTACT_WITH_PROCESS;
} else {
return 0;
@@ -740,241 +684,454 @@ void report_unknown_signal(SimpleSignal *signal)
****************************************************************************/
int
-MgmtSrvr::start(int processId)
+MgmtSrvr::start(int nodeId)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StartOrd* const startOrd = CAST_PTR(StartOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
+ StartOrd* const startOrd = CAST_PTR(StartOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_START_ORD, StartOrd::SignalLength);
startOrd->restartInfo = 0;
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
+}
+
+/*****************************************************************************
+ * Version handling
+ *****************************************************************************/
+
+int
+MgmtSrvr::versionNode(int nodeId, Uint32 &version, const char **address)
+{
+ version= 0;
+ if (getOwnNodeId() == nodeId)
+ {
+ /**
+ * If we're inquiring about our own node id,
+ * We know what version we are (version implies connected for mgm)
+ * but would like to find out from elsewhere what address they're using
+ * to connect to us. This means that secondary mgm servers
+ * can list ip addresses for mgm servers.
+ *
+ * If we don't get an address (i.e. no db nodes),
+ * we get the address from the configuration.
+ */
+ sendVersionReq(nodeId, version, address);
+ version= NDB_VERSION;
+ if(!*address)
+ {
+ ndb_mgm_configuration_iterator
+ iter(*_config->m_configValues, CFG_SECTION_NODE);
+ unsigned tmp= 0;
+ for(iter.first();iter.valid();iter.next())
+ {
+ if(iter.get(CFG_NODE_ID, &tmp)) require(false);
+ if((unsigned)nodeId!=tmp)
+ continue;
+ if(iter.get(CFG_NODE_HOST, address)) require(false);
+ break;
+ }
+ }
}
-
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB)
+ {
+ ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(node.connected)
+ version= node.m_info.m_version;
+ *address= get_connect_address(nodeId);
+ }
+ else if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM)
+ {
+ return sendVersionReq(nodeId, version, address);
+ }
+
+ return 0;
+}
+
+int
+MgmtSrvr::sendVersionReq(int v_nodeId, Uint32 &version, const char **address)
+{
+ SignalSender ss(theFacade);
+ ss.lock();
+
+ SimpleSignal ssig;
+ ApiVersionReq* req = CAST_PTR(ApiVersionReq, ssig.getDataPtrSend());
+ req->senderRef = ss.getOwnRef();
+ req->nodeId = v_nodeId;
+ ssig.set(ss, TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
+ ApiVersionReq::SignalLength);
+
+ int do_send = 1;
+ NodeId nodeId;
+
+ while (1)
+ {
+ if (do_send)
+ {
+ bool next;
+ nodeId = 0;
+
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+
+ const ClusterMgr::Node &node=
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if(next && node.m_state.startLevel != NodeState::SL_STARTED)
+ {
+ NodeId tmp=nodeId;
+ while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
+ okToSendTo(nodeId, true) != 0);
+ if(!next)
+ nodeId= tmp;
+ }
+
+ if(!next) return NO_CONTACT_WITH_DB_NODES;
+
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ do_send = 0;
+ }
+
+ SimpleSignal *signal = ss.waitFor();
+
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_API_VERSION_CONF: {
+ const ApiVersionConf * const conf =
+ CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
+ assert(conf->nodeId == v_nodeId);
+ version = conf->version;
+ struct in_addr in;
+ in.s_addr= conf->inet_addr;
+ *address= inet_ntoa(in);
+ return 0;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ do_send = 1; // retry with other node
+ continue;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ do_send = 1; // retry with other node
+ continue;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ break;
+ } // while(1)
+
return 0;
}
-/**
- * Restart one database node
+/*
+ * Common method for handeling all STOP_REQ signalling that
+ * is used by Stopping, Restarting and Single user commands
*/
-int
-MgmtSrvr::restartNode(int processId, bool nostart,
- bool initalStart, bool abort,
- StopCallback callback, void * anyData)
+
+int MgmtSrvr::sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart)
{
- int result;
+ stoppedNodes.clear();
- if(m_stopRec.singleUserMode)
- return 5060;
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- if(m_stopRec.inUse){
- return 5029;
- }
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ StopReq* const stopReq = CAST_PTR(StopReq, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
stopReq->requestInfo = 0;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
- stopReq->singleuser = 0;
stopReq->apiTimeout = 5000;
stopReq->transactionTimeout = 1000;
stopReq->readOperationTimeout = 1000;
stopReq->operationTimeout = 1000;
stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
+ stopReq->senderRef = ss.getOwnRef();
+ if (singleUserNodeId)
+ {
+ stopReq->singleuser = 1;
+ stopReq->singleUserApi = singleUserNodeId;
+ StopReq::setSystemStop(stopReq->requestInfo, false);
+ StopReq::setPerformRestart(stopReq->requestInfo, false);
+ StopReq::setStopAbort(stopReq->requestInfo, false);
}
-
- if (result == -1 && theWaitState != WAIT_NODEFAILURE) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
+ else
+ {
+ stopReq->singleuser = 0;
+ StopReq::setSystemStop(stopReq->requestInfo, stop);
+ StopReq::setPerformRestart(stopReq->requestInfo, restart);
+ StopReq::setStopAbort(stopReq->requestInfo, abort);
+ StopReq::setNoStart(stopReq->requestInfo, nostart);
+ StopReq::setInitialStart(stopReq->requestInfo, initialStart);
}
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
+ // send the signals
+ NodeBitmask nodes;
+ if (nodeId)
+ {
+ {
+ int r;
+ if((r = okToSendTo(nodeId, true)) != 0)
+ return r;
+ }
+ {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK)
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ nodes.set(nodeId);
}
+ else
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ if(okToSendTo(nodeId, true) == 0)
+ {
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ nodes.set(nodeId);
+ }
+ }
+
+ // now wait for the replies
+ int error = 0;
+ while (!nodes.isclear())
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_STOP_REF:{
+ const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d refused stop", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ nodes.clear(nodeId);
+ error = translateStopRef(ref->errorCode);
+ break;
+ }
+ case GSN_STOP_CONF:{
+ const StopConf * const ref = CAST_CONSTPTR(StopConf, signal->getDataPtr());
+ const NodeId nodeId = refToNode(signal->header.theSendersBlockRef);
+#ifdef VM_TRACE
+ ndbout_c("Node %d single user mode", nodeId);
+#endif
+ assert(nodes.get(nodeId));
+ assert(singleUserNodeId != 0);
+ nodes.clear(nodeId);
+ stoppedNodes.set(nodeId);
+ break;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+#ifdef VM_TRACE
+ ndbout_c("Node %d fail completed", rep->failedNodeId);
+#endif
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ NodeBitmask failedNodes;
+ failedNodes.assign(NodeBitmask::Size, rep->theNodes);
+#ifdef VM_TRACE
+ {
+ ndbout << "Failed nodes:";
+ for (unsigned i = 0; i < 32*NodeBitmask::Size; i++)
+ if(failedNodes.get(i))
+ ndbout << " " << i;
+ ndbout << endl;
+ }
+#endif
+ failedNodes.bitAND(nodes);
+ if (!failedNodes.isclear())
+ {
+ nodes.bitANDC(failedNodes); // clear the failed nodes
+ if (singleUserNodeId == 0)
+ stoppedNodes.bitOR(failedNodes);
+ }
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+#ifdef VM_TRACE
+ ndbout_c("Unknown signal %d", gsn);
+#endif
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ }
+ return error;
}
-/**
- * Restart all database nodes
+/*
+ * Stop one node
*/
-int
-MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
- int * stopCount, StopCallback callback, void * anyData)
+
+int MgmtSrvr::stopNode(int nodeId, bool abort)
{
- if(m_stopRec.singleUserMode)
- return 5060;
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ false,
+ false,
+ false);
+}
+
+/*
+ * Perform system shutdown
+ */
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- /**
- * Restart all database nodes into idle ("no-started") state
- */
- Uint32 timeOut = 0;
- NodeId nodeId = 0;
+int MgmtSrvr::stop(int * stopCount, bool abort)
+{
NodeBitmask nodes;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Enter single user mode on all live nodes
+ */
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, true);
- if (callback == 0) {
- // Start node in idle ("no-started") state
- StopReq::setNoStart(stopReq->requestInfo, 1);
- } else {
- StopReq::setNoStart(stopReq->requestInfo, nostart);
- }
- StopReq::setInitialStart(stopReq->requestInfo, initalStart);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- int res;
- if(callback == 0){
- res = sendSignal(nodeId, WAIT_STOP, signal, true);
- } else {
- res = sendSignal(nodeId, NO_WAIT, signal, true);
- }
-
- if(res != -1){
- nodes.set(nodeId);
- }
- }
- }
-
- if(stopCount != 0){
- * stopCount = m_stopRec.sentCount;
+int MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId)
+{
+ if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API)
+ return 5062;
+ NodeId nodeId = 0;
+ ClusterMgr::Node node;
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB))
+ {
+ node = theFacade->theClusterMgr->getNodeInfo(nodeId);
+ if((node.m_state.startLevel != NodeState::SL_STARTED) &&
+ (node.m_state.startLevel != NodeState::SL_NOTHING))
+ return 5063;
}
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ singleUserNodeId,
+ false,
+ false,
+ false,
+ false,
+ false);
+ if (stopCount)
+ *stopCount = nodes.count();
+ return ret;
+}
+
+/*
+ * Perform node restart
+ */
- if(m_stopRec.sentCount == 0){
- m_stopRec.inUse = false;
- return 0;
- }
-
- if(callback != 0){
- return 0;
- }
-
- theFacade->lock_mutex();
- int waitTime = timeOut/m_stopRec.sentCount;
- if (receiveOptimisedResponse(waitTime) != 0) {
- m_stopRec.inUse = false;
- return -1;
- }
-
+int MgmtSrvr::restartNode(int nodeId, bool nostart, bool initialStart,
+ bool abort)
+{
+ NodeBitmask nodes;
+ return sendSTOP_REQ(nodeId,
+ nodes,
+ 0,
+ abort,
+ false,
+ true,
+ nostart,
+ initialStart);
+}
+
+/*
+ * Perform system restart
+ */
+
+int MgmtSrvr::restart(bool nostart, bool initialStart,
+ bool abort, int * stopCount )
+{
+ NodeBitmask nodes;
+ int ret = sendSTOP_REQ(0,
+ nodes,
+ 0,
+ abort,
+ true,
+ true,
+ true,
+ initialStart);
+
+ if (ret)
+ return ret;
+
+ if (stopCount)
+ *stopCount = nodes.count();
+
+#ifdef VM_TRACE
+ ndbout_c("Stopped %d nodes", nodes.count());
+#endif
/**
* Here all nodes were correctly stopped,
* so we wait for all nodes to be contactable
*/
- nodeId = 0;
+ int waitTime = 12000;
+ NodeId nodeId = 0;
NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+
+ ndbout_c(" %d", nodes.get(1));
+ ndbout_c(" %d", nodes.get(2));
+
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
enum ndb_mgm_node_status s;
s = NDB_MGM_NODE_STATUS_NO_CONTACT;
+#ifdef VM_TRACE
+ ndbout_c("Waiting for %d not started", nodeId);
+#endif
while (s != NDB_MGM_NODE_STATUS_NOT_STARTED && waitTime > 0) {
Uint32 startPhase = 0, version = 0, dynamicId = 0, nodeGroup = 0;
Uint32 connectCount = 0;
bool system;
+ const char *address;
status(nodeId, &s, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ &system, &dynamicId, &nodeGroup, &connectCount, &address);
NdbSleep_MilliSleep(100);
waitTime = (maxTime - NdbTick_CurrentMillisecond());
}
}
- if(nostart){
- m_stopRec.inUse = false;
+ if(nostart)
return 0;
- }
/**
* Now we start all database nodes (i.e. we make them non-idle)
* We ignore the result we get from the start command.
*/
nodeId = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB) && nodes.get(nodeId)) {
+ while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) {
+ if (!nodes.get(nodeId))
+ continue;
int result;
result = start(nodeId);
DEBUG("Starting node " << nodeId << " with result " << result);
@@ -983,455 +1140,43 @@ MgmtSrvr::restart(bool nostart, bool initalStart, bool abort,
* Maybe the user only wanted to restart a subset of the nodes.
* It is also easy for the user to check which nodes have
* started and which nodes have not.
- *
- * if (result != 0) {
- * m_stopRec.inUse = false;
- * return result;
- * }
*/
}
- m_stopRec.inUse = false;
return 0;
}
-/*****************************************************************************
- * Version handling
- *****************************************************************************/
-
-int
-MgmtSrvr::versionNode(int processId, bool abort,
- VersionCallback callback, void * anyData)
-{
- int version;
-
- if(m_versionRec.inUse)
- return OPERATION_IN_PROGRESS;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
-
- if (getOwnNodeId() == processId)
- {
- version= NDB_VERSION;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB)
- {
- ClusterMgr::Node node= theFacade->theClusterMgr->getNodeInfo(processId);
- if(node.connected)
- version= node.m_info.m_version;
- else
- version= 0;
- }
- else if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM)
- {
- return sendVersionReq(processId);
- }
- else
- version= 0;
-
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, version, this,0);
- m_versionRec.inUse = false ;
-
- m_versionRec.version[processId]= version;
-
- return 0;
-}
-
-int
-MgmtSrvr::sendVersionReq(int processId)
-{
- Uint32 ndbnode=0;
- int result;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- if(okToSendTo(i, true) == 0)
- {
- ndbnode = i;
- break;
- }
- }
- }
-
- if (ndbnode == 0) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return NO_CONTACT_WITH_CLUSTER;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- return COULD_NOT_ALLOCATE_MEMORY;
- }
- ApiVersionReq* req = CAST_PTR(ApiVersionReq, signal->getDataPtrSend());
- req->senderRef = _ownReference;
- req->nodeId = processId;
-
- signal->set(TestOrd::TraceAPI, QMGR, GSN_API_VERSION_REQ,
- ApiVersionReq::SignalLength);
-
-
- // if(m_versionRec.callback == 0){
- Uint32 timeOut = 0;
- timeOut = 10000;
- result = sendRecSignal(ndbnode, WAIT_VERSION, signal, true, timeOut);
- //} else {
- //result = sendSignal(processId, NO_WAIT, signal, true);
- // }
-
- if (result == -1) {
- m_versionRec.inUse = false;
- if(m_versionRec.callback != 0)
- m_versionRec.callback(processId, 0, this,0);
- m_versionRec.version[processId] = 0;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- m_versionRec.inUse = false;
- return 0;
-}
-
-int
-MgmtSrvr::version(int * stopCount, bool abort,
- VersionCallback callback, void * anyData)
-{
- ClusterMgr::Node node;
- int version;
-
- if(m_versionRec.inUse)
- return 1;
-
- m_versionRec.callback = callback;
- m_versionRec.inUse = true ;
- Uint32 i;
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_MGM) {
- m_versionRec.callback(i, NDB_VERSION, this,0);
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- version = node.m_info.m_version;
- if(theFacade->theClusterMgr->getNodeInfo(i).connected)
- m_versionRec.callback(i, version, this,0);
- else
- m_versionRec.callback(i, 0, this,0);
-
- }
- }
- for(i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_API) {
- return sendVersionReq(i);
- }
- }
-
- return 0;
-}
-
-int
-MgmtSrvr::stopNode(int processId, bool abort, StopCallback callback,
- void * anyData)
-
-{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse)
- return 5029;
-
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ, StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- m_stopRec.sentCount = 1;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = processId;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- if(callback == NULL){
- Uint32 timeOut = 0;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
- result = sendRecSignal(processId, WAIT_STOP, signal, true, timeOut);
- } else {
- result = sendSignal(processId, NO_WAIT, signal, true);
- }
-
- if (result == -1) {
- m_stopRec.inUse = false;
- return SEND_OR_RECEIVE_FAILED;
- }
-
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
-}
-
int
-MgmtSrvr::stop(int * stopCount, bool abort, StopCallback callback,
- void * anyData)
+MgmtSrvr::exitSingleUser(int * stopCount, bool abort)
{
- if(m_stopRec.singleUserMode)
- return 5060;
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- m_stopRec.singleUserMode = false;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 0;
- StopReq::setSystemStop(stopReq->requestInfo, true);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, abort);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
-
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
- if(m_stopRec.sentCount > 0){
- if(callback == 0){
- theFacade->lock_mutex();
- receiveOptimisedResponse(timeOut / m_stopRec.sentCount);
- } else {
- return 0;
- }
- }
-
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
-
-/*****************************************************************************
- * Single user mode
- ****************************************************************************/
-
-int
-MgmtSrvr::enterSingleUser(int * stopCount, Uint32 singleUserNodeId,
- EnterSingleCallback callback, void * anyData)
-{
- if(m_stopRec.singleUserMode) {
- return 5060;
- }
-
- if (getNodeType(singleUserNodeId) != NDB_MGM_NODE_TYPE_API) {
- return 5062;
- }
- ClusterMgr::Node node;
-
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel != NodeState::SL_STARTED) &&
- (node.m_state.startLevel != NodeState::SL_NOTHING)) {
- return 5063;
- }
- }
- }
-
- if(m_stopRec.inUse){
- return 5029;
- }
-
- if(singleUserNodeId == 0)
- return 1;
- m_stopRec.singleUserMode = true;
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
- Uint32 timeOut = 0;
- while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
- if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- StopReq* const stopReq = CAST_PTR(StopReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_STOP_REQ,
- StopReq::SignalLength);
-
- stopReq->requestInfo = 0;
- stopReq->singleuser = 1;
- stopReq->singleUserApi = singleUserNodeId;
- StopReq::setSystemStop(stopReq->requestInfo, false);
- StopReq::setPerformRestart(stopReq->requestInfo, false);
- StopReq::setStopAbort(stopReq->requestInfo, false);
-
- stopReq->apiTimeout = 5000;
- stopReq->transactionTimeout = 1000;
- stopReq->readOperationTimeout = 1000;
- stopReq->operationTimeout = 1000;
- stopReq->senderData = 12;
- stopReq->senderRef = _ownReference;
- timeOut += stopReq->apiTimeout;
- timeOut += stopReq->transactionTimeout;
- timeOut += stopReq->readOperationTimeout;
- timeOut += stopReq->operationTimeout;
- timeOut *= 3;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
- }
- }
-
- if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
+ int count = 0;
- if(callback == 0){
- m_stopRec.inUse = false;
- return 0;
- // return m_stopRec.reply;
- } else {
- return 0;
- }
+ SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
- m_stopRec.inUse = false;
- return m_stopRec.reply;
-}
+ SimpleSignal ssig;
+ ResumeReq* const resumeReq =
+ CAST_PTR(ResumeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
+ ResumeReq::SignalLength);
+ resumeReq->senderData = 12;
+ resumeReq->senderRef = ss.getOwnRef();
-int
-MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
- ExitSingleCallback callback, void * anyData)
-{
- m_stopRec.sentCount = 0;
- m_stopRec.reply = 0;
- m_stopRec.nodeId = 0;
- m_stopRec.anyData = anyData;
- m_stopRec.callback = callback;
- m_stopRec.inUse = true;
-
- NodeId nodeId = 0;
while(getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)){
if(okToSendTo(nodeId, true) == 0){
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- ResumeReq* const resumeReq =
- CAST_PTR(ResumeReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, NDBCNTR, GSN_RESUME_REQ,
- StopReq::SignalLength);
- resumeReq->senderData = 12;
- resumeReq->senderRef = _ownReference;
-
- m_stopRec.sentCount++;
- if(callback == 0)
- sendSignal(nodeId, WAIT_STOP, signal, true);
- else
- sendSignal(nodeId, NO_WAIT, signal, true);
+ SendStatus result = ss.sendSignal(nodeId, &ssig);
+ if (result == SEND_OK)
+ count++;
}
}
- m_stopRec.singleUserMode = false;
-
if(stopCount != 0)
- * stopCount = m_stopRec.sentCount;
-
+ * stopCount = count;
- if(callback == 0){
- m_stopRec.inUse = false;
- return m_stopRec.reply;
- } else {
- return 0;
- }
-
- m_stopRec.inUse = false;
- return m_stopRec.reply;
+ return 0;
}
-
/*****************************************************************************
* Status
****************************************************************************/
@@ -1439,32 +1184,32 @@ MgmtSrvr::exitSingleUser(int * stopCount, bool abort,
#include <ClusterMgr.hpp>
int
-MgmtSrvr::status(int processId,
+MgmtSrvr::status(int nodeId,
ndb_mgm_node_status * _status,
Uint32 * version,
Uint32 * _phase,
bool * _system,
Uint32 * dynamic,
Uint32 * nodegroup,
- Uint32 * connectCount)
+ Uint32 * connectCount,
+ const char **address)
{
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_API ||
- getNodeType(processId) == NDB_MGM_NODE_TYPE_MGM) {
- if(versionNode(processId, false,0,0) ==0)
- * version = m_versionRec.version[processId];
- else
- * version = 0;
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_API ||
+ getNodeType(nodeId) == NDB_MGM_NODE_TYPE_MGM) {
+ versionNode(nodeId, *version, address);
+ } else {
+ *address= get_connect_address(nodeId);
}
const ClusterMgr::Node node =
- theFacade->theClusterMgr->getNodeInfo(processId);
+ theFacade->theClusterMgr->getNodeInfo(nodeId);
if(!node.connected){
* _status = NDB_MGM_NODE_STATUS_NO_CONTACT;
return 0;
}
- if (getNodeType(processId) == NDB_MGM_NODE_TYPE_NDB) {
+ if (getNodeType(nodeId) == NDB_MGM_NODE_TYPE_NDB) {
* version = node.m_info.m_version;
}
@@ -1527,67 +1272,81 @@ MgmtSrvr::status(int processId,
}
int
-MgmtSrvr::setEventReportingLevelImpl(int processId,
+MgmtSrvr::setEventReportingLevelImpl(int nodeId,
const EventSubscribeReq& ll)
{
-
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal signal(_ownReference);
+ INIT_SIGNAL_SENDER(ss,nodeId);
+ SimpleSignal ssig;
EventSubscribeReq * dst =
- CAST_PTR(EventSubscribeReq, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
- EventSubscribeReq::SignalLength);
-
- theFacade->lock_mutex();
- send(&signal, processId, NODE_TYPE_DB);
- theFacade->unlock_mutex();
-
+ CAST_PTR(EventSubscribeReq, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_EVENT_SUBSCRIBE_REQ,
+ EventSubscribeReq::SignalLength);
+ *dst = ll;
+
+ send(ss,ssig,nodeId,NODE_TYPE_DB);
+
+#if 0
+ while (1)
+ {
+ SimpleSignal *signal = ss.waitFor();
+ int gsn = signal->readSignalNumber();
+ switch (gsn) {
+ case GSN_EVENT_SUBSCRIBE_CONF:{
+ break;
+ }
+ case GSN_EVENT_SUBSCRIBE_REF:{
+ return SEND_OR_RECEIVE_FAILED;
+ }
+ case GSN_NF_COMPLETEREP:{
+ const NFCompleteRep * const rep =
+ CAST_CONSTPTR(NFCompleteRep, signal->getDataPtr());
+ if (rep->failedNodeId == nodeId)
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ case GSN_NODE_FAILREP:{
+ const NodeFailRep * const rep =
+ CAST_CONSTPTR(NodeFailRep, signal->getDataPtr());
+ if (NodeBitmask::get(rep->theNodes,nodeId))
+ return SEND_OR_RECEIVE_FAILED;
+ break;
+ }
+ default:
+ report_unknown_signal(signal);
+ return SEND_OR_RECEIVE_FAILED;
+ }
+
+ }
+#endif
return 0;
}
//****************************************************************************
//****************************************************************************
int
-MgmtSrvr::setNodeLogLevelImpl(int processId, const SetLogLevelOrd & ll)
+MgmtSrvr::setNodeLogLevelImpl(int nodeId, const SetLogLevelOrd & ll)
{
- int result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal signal(_ownReference);
-
- SetLogLevelOrd * dst = CAST_PTR(SetLogLevelOrd, signal.getDataPtrSend());
-
- * dst = ll;
-
- signal.set(TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
- SetLogLevelOrd::SignalLength);
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_SET_LOGLEVELORD,
+ SetLogLevelOrd::SignalLength);
+ SetLogLevelOrd* const dst = CAST_PTR(SetLogLevelOrd, ssig.getDataPtrSend());
+ *dst = ll;
- theFacade->lock_mutex();
- theFacade->sendSignalUnCond(&signal, processId);
- theFacade->unlock_mutex();
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
+MgmtSrvr::send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type){
Uint32 max = (node == 0) ? MAX_NODES : node + 1;
for(; node < max; node++){
while(nodeTypes[node] != (int)node_type && node < max) node++;
if(nodeTypes[node] != (int)node_type)
break;
- theFacade->sendSignalUnCond(signal, node);
+ ss.sendSignal(node, &ssig);
}
return 0;
}
@@ -1596,34 +1355,21 @@ MgmtSrvr::send(NdbApiSignal* signal, Uint32 node, Uint32 node_type){
//****************************************************************************
int
-MgmtSrvr::insertError(int processId, int errorNo)
+MgmtSrvr::insertError(int nodeId, int errorNo)
{
if (errorNo < 0) {
return INVALID_ERROR_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
+ TamperOrd::SignalLength);
+ TamperOrd* const tamperOrd = CAST_PTR(TamperOrd, ssig.getDataPtrSend());
tamperOrd->errorNo = errorNo;
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TAMPER_ORD,
- TamperOrd::SignalLength);
-
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1632,37 +1378,23 @@ MgmtSrvr::insertError(int processId, int errorNo)
//****************************************************************************
int
-MgmtSrvr::setTraceNo(int processId, int traceNo)
+MgmtSrvr::setTraceNo(int nodeId, int traceNo)
{
if (traceNo < 0) {
return INVALID_TRACE_NUMBER;
}
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
-
// Assume TRACE command causes toggling. Not really defined... ? TODO
testOrd->setTraceCommand(TestOrd::Toggle,
(TestOrd::TraceSpecification)traceNo);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
//****************************************************************************
@@ -1681,14 +1413,10 @@ MgmtSrvr::getBlockNumber(const BaseString &blockName)
//****************************************************************************
int
-MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
+MgmtSrvr::setSignalLoggingMode(int nodeId, LogMode mode,
const Vector<BaseString>& blocks)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
// Convert from MgmtSrvr format...
@@ -1723,12 +1451,10 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
return -1;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
if (blocks.size() == 0 || blocks[0] == "ALL") {
@@ -1738,78 +1464,44 @@ MgmtSrvr::setSignalLoggingMode(int processId, LogMode mode,
for(unsigned i = 0; i < blocks.size(); i++){
int blockNumber = getBlockNumber(blocks[i]);
if (blockNumber == -1) {
- releaseSignal(signal);
return INVALID_BLOCK_NAME;
}
testOrd->addSignalLoggerCommand(blockNumber, command, logSpec);
} // for
} // else
-
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
-
/*****************************************************************************
* Signal tracing
*****************************************************************************/
-int MgmtSrvr::startSignalTracing(int processId)
+int MgmtSrvr::startSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
+ INIT_SIGNAL_SENDER(ss,nodeId);
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::On);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
int
-MgmtSrvr::stopSignalTracing(int processId)
+MgmtSrvr::stopSignalTracing(int nodeId)
{
- int result;
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
-
- TestOrd* const testOrd = CAST_PTR(TestOrd, signal->getDataPtrSend());
+ SimpleSignal ssig;
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
+ TestOrd* const testOrd = CAST_PTR(TestOrd, ssig.getDataPtrSend());
testOrd->clear();
testOrd->setTestCommand(TestOrd::Off);
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_TEST_ORD, TestOrd::SignalLength);
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1818,7 +1510,7 @@ MgmtSrvr::stopSignalTracing(int processId)
*****************************************************************************/
int
-MgmtSrvr::dumpState(int processId, const char* args)
+MgmtSrvr::dumpState(int nodeId, const char* args)
{
// Convert the space separeted args
// string to an int array
@@ -1840,29 +1532,20 @@ MgmtSrvr::dumpState(int processId, const char* args)
}
}
- return dumpState(processId, args_array, numArgs);
+ return dumpState(nodeId, args_array, numArgs);
}
int
-MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
+MgmtSrvr::dumpState(int nodeId, const Uint32 args[], Uint32 no)
{
- int result;
-
- result = okToSendTo(processId, true);
- if (result != 0) {
- return result;
- }
-
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ INIT_SIGNAL_SENDER(ss,nodeId);
const Uint32 len = no > 25 ? 25 : no;
+ SimpleSignal ssig;
DumpStateOrd * const dumpOrd =
- CAST_PTR(DumpStateOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
+ CAST_PTR(DumpStateOrd, ssig.getDataPtrSend());
+ ssig.set(ss,TestOrd::TraceAPI, CMVMI, GSN_DUMP_STATE_ORD, len);
for(Uint32 i = 0; i<25; i++){
if (i < len)
dumpOrd->args[i] = args[i];
@@ -1870,12 +1553,7 @@ MgmtSrvr::dumpState(int processId, const Uint32 args[], Uint32 no)
dumpOrd->args[i] = 0;
}
- result = sendSignal(processId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -1906,42 +1584,18 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
int gsn = signal->readSignalNumber();
switch (gsn) {
- case GSN_API_VERSION_CONF: {
- if (theWaitState == WAIT_VERSION) {
- const ApiVersionConf * const conf =
- CAST_CONSTPTR(ApiVersionConf, signal->getDataPtr());
- if(m_versionRec.callback != 0)
- m_versionRec.callback(conf->nodeId, conf->version, this, 0);
- else {
- m_versionRec.version[conf->nodeId]=conf->version;
- }
- } else return;
- theWaitState = NO_WAIT;
- }
- break;
-
case GSN_EVENT_SUBSCRIBE_CONF:
break;
-
+ case GSN_EVENT_SUBSCRIBE_REF:
+ break;
case GSN_EVENT_REP:
eventReport(signal->getDataPtr());
break;
- case GSN_STOP_REF:{
- const StopRef * const ref = CAST_CONSTPTR(StopRef, signal->getDataPtr());
- const NodeId nodeId = refToNode(signal->theSendersBlockRef);
- handleStopReply(nodeId, ref->errorCode);
- return;
- }
+ case GSN_NF_COMPLETEREP:
break;
-
- case GSN_MGM_LOCK_CONFIG_REP:
- case GSN_MGM_LOCK_CONFIG_REQ:
- case GSN_MGM_UNLOCK_CONFIG_REP:
- case GSN_MGM_UNLOCK_CONFIG_REQ: {
- m_signalRecvQueue.receive(new NdbApiSignal(*signal));
+ case GSN_NODE_FAILREP:
break;
- }
default:
g_eventLogger.error("Unknown signal received. SignalNumber: "
@@ -1956,75 +1610,6 @@ MgmtSrvr::handleReceivedSignal(NdbApiSignal* signal)
}
}
-/**
- * A database node was either stopped or there was some error
- */
-void
-MgmtSrvr::handleStopReply(NodeId nodeId, Uint32 errCode)
-{
- /**
- * If we are in single user mode and get a stop reply from a
- * DB node, then we have had a node crash.
- * If all DB nodes are gone, and we are still in single user mode,
- * the set m_stopRec.singleUserMode = false;
- */
- if(m_stopRec.singleUserMode) {
- ClusterMgr::Node node;
- bool failure = true;
- for(Uint32 i = 0; i<MAX_NODES; i++) {
- if (getNodeType(i) == NDB_MGM_NODE_TYPE_NDB) {
- node = theFacade->theClusterMgr->getNodeInfo(i);
- if((node.m_state.startLevel == NodeState::SL_NOTHING))
- failure = true;
- else
- failure = false;
- }
- }
- if(failure) {
- m_stopRec.singleUserMode = false;
- }
- }
- if(m_stopRec.inUse == false)
- return;
-
- if(!(m_stopRec.nodeId == 0 || m_stopRec.nodeId == nodeId))
- goto error;
-
- if(m_stopRec.sentCount <= 0)
- goto error;
-
- if(!(theWaitState == WAIT_STOP || m_stopRec.callback != 0))
- goto error;
-
- if(errCode != 0)
- m_stopRec.reply = translateStopRef(errCode);
-
- m_stopRec.sentCount --;
- if(m_stopRec.sentCount == 0){
- if(theWaitState == WAIT_STOP){
- theWaitState = NO_WAIT;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- return;
- }
- if(m_stopRec.callback != 0){
- m_stopRec.inUse = false;
- StopCallback callback = m_stopRec.callback;
- m_stopRec.callback = NULL;
- (* callback)(m_stopRec.nodeId,
- m_stopRec.anyData,
- m_stopRec.reply);
- return;
- }
- }
- return;
-
- error:
- if(errCode != 0){
- g_eventLogger.error("Unexpected signal received. SignalNumber: %i from %d",
- GSN_STOP_REF, nodeId);
- }
-}
-
void
MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
{
@@ -2040,16 +1625,8 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
rep->setEventType(NDB_LE_Connected);
if(nfComplete)
{
- handleStopReply(nodeId, 0);
DBUG_VOID_RETURN;
}
-
- if(theWaitNode == nodeId &&
- theWaitState != NO_WAIT && theWaitState != WAIT_STOP)
- {
- theWaitState = WAIT_NODEFAILURE;
- NdbCondition_Signal(theMgmtWaitForResponseCondPtr);
- }
}
rep->setNodeId(_ownNodeId);
@@ -2401,6 +1978,7 @@ MgmtSrvr::eventReport(const Uint32 * theData)
/***************************************************************************
* Backup
***************************************************************************/
+
int
MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
{
@@ -2415,7 +1993,6 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
if(!next) return NO_CONTACT_WITH_DB_NODES;
SimpleSignal ssig;
-
BackupReq* req = CAST_PTR(BackupReq, ssig.getDataPtrSend());
ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_BACKUP_REQ,
BackupReq::SignalLength);
@@ -2430,8 +2007,7 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
while (1) {
if (do_send)
{
- SendStatus result = ss.sendSignal(nodeId, &ssig);
- if (result != SEND_OK) {
+ if (ss.sendSignal(nodeId, &ssig) != SEND_OK) {
return SEND_OR_RECEIVE_FAILED;
}
if (waitCompleted == 0)
@@ -2533,13 +2109,13 @@ MgmtSrvr::startBackup(Uint32& backupId, int waitCompleted)
return SEND_OR_RECEIVE_FAILED;
}
}
-
- return 0;
}
int
MgmtSrvr::abortBackup(Uint32 backupId)
{
+ SignalSender ss(theFacade);
+
bool next;
NodeId nodeId = 0;
while((next = getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_NDB)) == true &&
@@ -2549,44 +2125,17 @@ MgmtSrvr::abortBackup(Uint32 backupId)
return NO_CONTACT_WITH_DB_NODES;
}
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- return COULD_NOT_ALLOCATE_MEMORY;
- }
+ SimpleSignal ssig;
- AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
- AbortBackupOrd::SignalLength);
+ AbortBackupOrd* ord = CAST_PTR(AbortBackupOrd, ssig.getDataPtrSend());
+ ssig.set(ss, TestOrd::TraceAPI, BACKUP, GSN_ABORT_BACKUP_ORD,
+ AbortBackupOrd::SignalLength);
ord->requestType = AbortBackupOrd::ClientAbort;
ord->senderData = 19;
ord->backupId = backupId;
- int result = sendSignal(nodeId, NO_WAIT, signal, true);
- if (result == -1) {
- return SEND_OR_RECEIVE_FAILED;
- }
-
- return 0;
-}
-
-
-NodeId
-MgmtSrvr::getPrimaryNode() const {
-#if 0
- Uint32 tmp;
- const Properties *prop = NULL;
-
- getConfig()->get("SYSTEM", &prop);
- if(prop == NULL)
- return 0;
-
- prop->get("PrimaryMGMNode", &tmp);
-
- return tmp;
-#else
- return 0;
-#endif
+ return ss.sendSignal(nodeId, &ssig) == SEND_OK ? 0 : SEND_OR_RECEIVE_FAILED;
}
@@ -2739,7 +2288,6 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value,
NdbMutex_Unlock(m_configMutex);
return 0;
}
-
int
MgmtSrvr::setConnectionDbParameter(int node1,
int node2,
@@ -2874,10 +2422,6 @@ int MgmtSrvr::set_connect_string(const char *str)
}
-template class Vector<SigMatch>;
-#if __SUNPRO_CC != 0x560
-template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned);
-#endif
template class MutexVector<unsigned short>;
template class MutexVector<Ndb_mgmd_event_service::Event_listener>;
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
index e43a0ff4149..d61c0ce8db7 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.hpp
@@ -22,15 +22,17 @@
#include <NdbCondition.h>
#include <mgmapi.h>
-
+#include <NdbTCP.h>
+#include <ConfigRetriever.hpp>
#include <Vector.hpp>
#include <NodeBitmask.hpp>
#include <signaldata/ManagementServer.hpp>
-#include "SignalQueue.hpp"
#include <ndb_version.h>
#include <EventLogger.hpp>
#include <signaldata/EventSubscribeReq.hpp>
+#include <SignalSender.hpp>
+
/**
* @desc Block number for Management server.
* @todo This should probably be somewhere else. I don't know where atm.
@@ -200,51 +202,26 @@ public:
~MgmtSrvr();
- int status(int processId,
- ndb_mgm_node_status * status,
+ /**
+ * Get status on a node.
+ * address may point to a common area (e.g. from inet_addr)
+ * There is no gaurentee that it is preserved across calls.
+ * Copy the string if you are not going to use it immediately.
+ */
+ int status(int nodeId,
+ ndb_mgm_node_status * status,
Uint32 * version,
Uint32 * phase,
bool * systemShutdown,
Uint32 * dynamicId,
Uint32 * nodeGroup,
- Uint32 * connectCount);
+ Uint32 * connectCount,
+ const char **address);
// All the functions below may return any of this error codes:
// NO_CONTACT_WITH_PROCESS, PROCESS_NOT_CONFIGURED, WRONG_PROCESS_TYPE,
// COULD_NOT_ALLOCATE_MEMORY, SEND_OR_RECEIVE_FAILED
-
- typedef void (* StopCallback)(int nodeId, void * anyData, int errorCode);
-
- typedef void (* VersionCallback)(int nodeId, int version,
- void * anyData, int errorCode);
-
-
- typedef void (* EnterSingleCallback)(int nodeId, void * anyData,
- int errorCode);
- typedef void (* ExitSingleCallback)(int nodeId, void * anyData,
- int errorCode);
-
- /**
- * Lock configuration
- */
- int lockConf();
-
- /**
- * Unlock configuration, and commit it if commit is true
- */
- int unlockConf(bool commit);
-
- /**
- * Commit new configuration
- */
- int commitConfig();
-
- /**
- * Rollback configuration
- */
- int rollbackConfig();
-
/**
* Save a configuration to permanent storage
*/
@@ -273,12 +250,12 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int stopNode(int nodeId, bool abort = false, StopCallback = 0, void *any= 0);
+ int stopNode(int nodeId, bool abort = false);
/**
* Stop the system
*/
- int stop(int * cnt = 0, bool abort = false, StopCallback = 0, void *any = 0);
+ int stop(int * cnt = 0, bool abort = false);
/**
* print version info about a node
@@ -286,27 +263,18 @@ public:
* @param processId: Id of the DB process to stop
* @return 0 if succeeded, otherwise: as stated above, plus:
*/
- int versionNode(int nodeId, bool abort = false,
- VersionCallback = 0, void *any= 0);
+ int versionNode(int nodeId, Uint32 &version, const char **address);
/**
- * print version info about all node in the system
- */
- int version(int * cnt = 0, bool abort = false,
- VersionCallback = 0, void *any = 0);
-
- /**
* Maintenance on the system
*/
- int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0,
- EnterSingleCallback = 0, void *any = 0);
+ int enterSingleUser(int * cnt = 0, Uint32 singleuserNodeId = 0);
/**
* Resume from maintenance on the system
*/
- int exitSingleUser(int * cnt = 0, bool abort = false,
- ExitSingleCallback = 0, void *any = 0);
+ int exitSingleUser(int * cnt = 0, bool abort = false);
/**
* Start DB process.
@@ -320,15 +288,14 @@ public:
* @param processId: Id of the DB process to start
*/
int restartNode(int processId, bool nostart, bool initialStart,
- bool abort = false,
- StopCallback = 0, void * anyData = 0);
+ bool abort = false);
/**
* Restart the system
*/
int restart(bool nostart, bool initialStart,
bool abort = false,
- int * stopCount = 0, StopCallback = 0, void * anyData = 0);
+ int * stopCount = 0);
struct BackupEvent {
enum Event {
@@ -478,13 +445,6 @@ public:
const Config * getConfig() const;
/**
- * Change configuration paramter
- */
- bool changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value);
-
- /**
* Returns the node count for the specified node type.
*
* @param type The node type.
@@ -493,11 +453,6 @@ public:
int getNodeCount(enum ndb_mgm_node_type type) const;
/**
- * Returns the nodeId of the management master
- */
- NodeId getPrimaryNode() const;
-
- /**
* Returns the port number.
* @return port number.
*/
@@ -523,8 +478,17 @@ public:
private:
//**************************************************************************
- int setEventReportingLevel(int processId, LogLevel::EventCategory, Uint32);
-
+ int send(SignalSender &ss, SimpleSignal &ssig, Uint32 node, Uint32 node_type);
+
+ int sendSTOP_REQ(NodeId nodeId,
+ NodeBitmask &stoppedNodes,
+ Uint32 singleUserNodeId,
+ bool abort,
+ bool stop,
+ bool restart,
+ bool nostart,
+ bool initialStart);
+
/**
* Check if it is possible to send a signal to a (DB) process
*
@@ -588,9 +552,6 @@ private:
// Returns: -
//**************************************************************************
- void handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal);
- void handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal);
-
//**************************************************************************
// Specific signal handling data
//**************************************************************************
@@ -614,59 +575,8 @@ private:
enum WaitSignalType {
NO_WAIT, // We don't expect to receive any signal
WAIT_SET_VAR, // Accept SET_VAR_CONF and SET_VAR_REF
- WAIT_SUBSCRIBE_CONF, // Accept event subscription confirmation
- WAIT_STOP,
- WAIT_BACKUP_STARTED,
- WAIT_BACKUP_COMPLETED,
- WAIT_VERSION,
- WAIT_NODEFAILURE
+ WAIT_SUBSCRIBE_CONF // Accept event subscription confirmation
};
-
- /**
- * Get an unused signal
- * @return A signal if succeeded, NULL otherwise
- */
- NdbApiSignal* getSignal();
-
- /**
- * Add a signal to the list of unused signals
- * @param signal: The signal to add
- */
- void releaseSignal(NdbApiSignal* signal);
-
- /**
- * Remove a signal from the list of unused signals and delete
- * the memory for it.
- */
- void freeSignal();
-
- /**
- * Send a signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise
- */
- int sendSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false);
-
- /**
- * Send a signal and wait for an answer signal
- * @param processId: Id of the receiver process
- * @param waitState: State denoting a set of signals we accept to receive.
- * @param signal: The signal to send
- * @return 0 if succeeded, -1 otherwise (for example failed to send or
- * failed to receive expected signal).
- */
- int sendRecSignal(Uint16 processId, WaitSignalType waitState,
- NdbApiSignal* signal, bool force = false,
- int waitTime = WAIT_FOR_RESPONSE_TIMEOUT);
-
- /**
- * Wait for a signal to arrive.
- * @return 0 if signal arrived, -1 otherwise
- */
- int receiveOptimisedResponse(int waitTime);
/**
* This function is called from "outside" of MgmtSrvr
@@ -677,7 +587,7 @@ private:
static void signalReceivedNotification(void* mgmtSrvr,
NdbApiSignal* signal,
struct LinearSectionPtr ptr[3]);
-
+
/**
* Called from "outside" of MgmtSrvr when a DB process has died.
* @param mgmtSrvr: The MgmtSrvr object wreceiveOptimisedResponsehich
@@ -714,31 +624,7 @@ private:
class TransporterFacade * theFacade;
- class SignalQueue m_signalRecvQueue;
-
- struct StopRecord {
- StopRecord(){ inUse = false; callback = 0; singleUserMode = false;}
- bool inUse;
- bool singleUserMode;
- int sentCount;
- int reply;
- int nodeId;
- void * anyData;
- StopCallback callback;
- };
- StopRecord m_stopRec;
-
- struct VersionRecord {
- VersionRecord(){ inUse = false; callback = 0;}
- bool inUse;
- Uint32 version[MAX_NODES];
- VersionCallback callback;
- };
- VersionRecord m_versionRec;
- int sendVersionReq( int processId);
-
-
- void handleStopReply(NodeId nodeId, Uint32 errCode);
+ int sendVersionReq( int processId, Uint32 &version, const char **address);
int translateStopRef(Uint32 errCode);
bool _isStopThread;
@@ -759,14 +645,8 @@ private:
static void *logLevelThread_C(void *);
void logLevelThreadRun();
- struct NdbThread *m_signalRecvThread;
- static void *signalRecvThread_C(void *);
- void signalRecvThreadRun();
-
Config *_props;
- int send(class NdbApiSignal* signal, Uint32 node, Uint32 node_type);
-
ConfigRetriever *m_config_retriever;
};
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
index 6c4b4e9ae3c..e56643a3d7e 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp
@@ -23,228 +23,6 @@
#include <ConfigRetriever.hpp>
#include <ndb_version.h>
-void
-MgmtSrvr::handle_MGM_LOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmLockConfigReq * const req = CAST_CONSTPTR(MgmLockConfigReq, signal->getDataPtr());
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- return; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REP,
- MgmLockConfigRep::SignalLength);
-
- MgmLockConfigRep *lockRep = CAST_PTR(MgmLockConfigRep, reply->getDataPtrSend());
-
- lockRep->errorCode = MgmLockConfigRep::UNKNOWN_ERROR;
-
- if(req->newConfigGeneration < m_nextConfigGenerationNumber) {
- lockRep->errorCode = MgmLockConfigRep::GENERATION_MISMATCH;
- goto done;
- }
- NdbMutex_Lock(m_configMutex);
-
- m_nextConfigGenerationNumber = req->newConfigGeneration+1;
-
- lockRep->errorCode = MgmLockConfigRep::OK;
-
- done:
- sendSignal(sender, NO_WAIT, reply, true);
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-void
-MgmtSrvr::handle_MGM_UNLOCK_CONFIG_REQ(NdbApiSignal *signal) {
- NodeId sender = refToNode(signal->theSendersBlockRef);
- const MgmUnlockConfigReq * const req = CAST_CONSTPTR(MgmUnlockConfigReq, signal->getDataPtr());
- MgmUnlockConfigRep *unlockRep;
-
- NdbApiSignal *reply = getSignal();
- if(signal == NULL)
- goto error; /** @todo handle allocation failure */
-
- reply->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REP,
- MgmUnlockConfigRep::SignalLength);
-
- unlockRep = CAST_PTR(MgmUnlockConfigRep, reply->getDataPtrSend());
-
- unlockRep->errorCode = MgmUnlockConfigRep::UNKNOWN_ERROR;
-
-
- NdbMutex_Lock(m_configMutex);
-
- if(req->commitConfig == 1) {
- m_newConfig = fetchConfig();
- commitConfig();
- } else
- rollbackConfig();
-
- unlockRep->errorCode = MgmUnlockConfigRep::OK;
-
- sendSignal(sender, NO_WAIT, reply, true);
- error:
- NdbMutex_Unlock(m_configMutex);
- return;
-}
-
-
-/**
- * Prepare all MGM nodes for configuration changes
- *
- * @returns 0 on success, or -1 on failure
- */
-int
-MgmtSrvr::lockConf() {
- int result = -1;
- MgmLockConfigReq* lockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- if(NdbMutex_Trylock(m_configMutex) != 0)
- return -1;
-
- m_newConfig = new Config(*_config); /* copy the existing config */
- _config = m_newConfig;
-
- m_newConfig = new Config(*_config);
-
- m_nextConfigGenerationNumber++;
-
- /* Make sure the new configuration _always_ is at least one step older */
- if(m_nextConfigGenerationNumber < m_newConfig->getGenerationNumber()+1)
- m_nextConfigGenerationNumber = _config->getGenerationNumber()+1;
-
- m_newConfig->setGenerationNumber(m_nextConfigGenerationNumber);
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- lockReq = CAST_PTR(MgmLockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_LOCK_CONFIG_REQ,
- MgmLockConfigReq::SignalLength);
-
- lockReq->newConfigGeneration = m_nextConfigGenerationNumber;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_LOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- ndbout << __FILE__ << ":" << __LINE__ << endl;
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Unlocks configuration
- *
- * @returns 0 on success, ! 0 on error
- */
-int
-MgmtSrvr::unlockConf(bool commit) {
- int result = -1;
- MgmUnlockConfigReq* unlockReq;
- NodeId node = 0;
-
- /* Check if this is the master node */
- if(getPrimaryNode() != _ownNodeId)
- goto done;
-
- errno = 0;
- if(NdbMutex_Lock(m_configMutex) != 0)
- return -1;
-
- if(commit)
- commitConfig();
- else
- rollbackConfig();
-
- node = 0;
- while(getNextNodeId(&node, NDB_MGM_NODE_TYPE_MGM)) {
- if(node != _ownNodeId) {
- NdbApiSignal* signal = getSignal();
- if (signal == NULL) {
- result = COULD_NOT_ALLOCATE_MEMORY;
- goto done;
- }
-
- unlockReq = CAST_PTR(MgmUnlockConfigReq, signal->getDataPtrSend());
- signal->set(TestOrd::TraceAPI,
- MGMSRV,
- GSN_MGM_UNLOCK_CONFIG_REQ,
- MgmUnlockConfigReq::SignalLength);
- unlockReq->commitConfig = commit;
-
- result = sendSignal(node, NO_WAIT, signal, true);
-
- NdbApiSignal *reply =
- m_signalRecvQueue.waitFor(GSN_MGM_UNLOCK_CONFIG_REP, 0);
-
- if(reply == NULL) {
- /** @todo handle timeout/error */
- result = -1;
- goto done;
- }
-
- }
- }
-
- done:
- NdbMutex_Unlock(m_configMutex);
- return result;
-}
-
-/**
- * Commit the new configuration
- */
-int
-MgmtSrvr::commitConfig() {
- int ret = saveConfig(m_newConfig);
- delete _config;
- _config = m_newConfig;
- m_newConfig = NULL;
- ndbout << "commit " << ret << endl;
- return ret;
-}
-
-/**
- * Rollback to the old configuration
- */
-int
-MgmtSrvr::rollbackConfig() {
- delete m_newConfig;
- m_newConfig = NULL;
- ndbout << "rollback" << endl;
- return saveConfig(_config);
-}
-
/**
* Save a configuration to the running configuration file
*/
@@ -274,7 +52,15 @@ Config *
MgmtSrvr::readConfig() {
Config *conf;
InitConfigFileParser parser;
- conf = parser.parseConfig(m_configFilename.c_str());
+ if (m_configFilename.length())
+ {
+ conf = parser.parseConfig(m_configFilename.c_str());
+ }
+ else
+ {
+ ndbout_c("Reading cluster configuration using my.cnf");
+ conf = parser.parse_mycnf();
+ }
return conf;
}
@@ -288,12 +74,3 @@ MgmtSrvr::fetchConfig() {
}
return 0;
}
-
-bool
-MgmtSrvr::changeConfig(const BaseString &section,
- const BaseString &param,
- const BaseString &value) {
- if(m_newConfig == NULL)
- return false;
- return m_newConfig->change(section, param, value);
-}
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
index f93948abc75..c99936e1861 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp
@@ -20,123 +20,3 @@
// Some kind of reuse should be preferred.
//******************************************************************************
-#include "MgmtSrvr.hpp"
-#include <NdbApiSignal.hpp>
-#include <NdbTick.h>
-
-
-NdbApiSignal*
-MgmtSrvr::getSignal()
-{
- NdbApiSignal* tSignal;
- tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- return tSignal;
- } else
- {
- tSignal = new NdbApiSignal(_ownReference);
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
- return tSignal;
-}
-
-
-void
-MgmtSrvr::releaseSignal(NdbApiSignal* aSignal)
-{
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
-}
-
-
-void
-MgmtSrvr::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-}
-
-
-int
-MgmtSrvr::sendSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal,
- aNodeId);
- } else {
- tReturnCode = theFacade->sendSignal(aSignal,
- aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theFacade->unlock_mutex();
- return 0;
-}
-
-
-int
-MgmtSrvr::sendRecSignal(Uint16 aNodeId,
- WaitSignalType aWaitState,
- NdbApiSignal* aSignal,
- bool force,
- int waitTime)
-{
- int tReturnCode;
- theFacade->lock_mutex();
- if(force){
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- } else {
- tReturnCode = theFacade->sendSignalUnCond(aSignal, aNodeId);
- }
- releaseSignal(aSignal);
- if (tReturnCode == -1) {
- theFacade->unlock_mutex();
- return -1;
- }
- theWaitState = aWaitState;
- theWaitNode = aNodeId;
- return receiveOptimisedResponse(waitTime);
-}
-
-
-int
-MgmtSrvr::receiveOptimisedResponse(int waitTime)
-{
- int tResultCode;
- theFacade->checkForceSend(_blockNumber);
- NDB_TICKS maxTime = NdbTick_CurrentMillisecond() + waitTime;
-
- while (theWaitState != NO_WAIT && theWaitState != WAIT_NODEFAILURE
- && waitTime > 0) {
- NdbCondition_WaitTimeout(theMgmtWaitForResponseCondPtr,
- theFacade->theMutexPtr,
- waitTime);
- if(theWaitState == NO_WAIT || theWaitState == WAIT_NODEFAILURE)
- break;
- waitTime = (maxTime - NdbTick_CurrentMillisecond());
- }//while
-
- if(theWaitState == NO_WAIT) {
- tResultCode = 0;
- } else {
- tResultCode = -1;
- }
- theFacade->unlock_mutex();
- return tResultCode;
-}
-
-
diff --git a/storage/ndb/src/mgmsrv/Services.cpp b/storage/ndb/src/mgmsrv/Services.cpp
index 3992796e304..e2a7c3d0c29 100644
--- a/storage/ndb/src/mgmsrv/Services.cpp
+++ b/storage/ndb/src/mgmsrv/Services.cpp
@@ -216,21 +216,6 @@ ParserRow<MgmApiSession> commands[] = {
MGM_ARG("level", Int, Mandatory, "Severety level"),
MGM_ARG("enable", Int, Mandatory, "1=disable, 0=enable, -1=toggle"),
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
- MGM_CMD("config change", &MgmApiSession::configChange, ""),
- MGM_ARG("section", String, Mandatory, "Section"),
- MGM_ARG("parameter", String, Mandatory, "Parameter"),
- MGM_ARG("value", String, Mandatory, "Value"),
-
- MGM_CMD("config lock", &MgmApiSession::configLock, ""),
-
- MGM_CMD("config unlock", &MgmApiSession::configUnlock, ""),
- MGM_ARG("commit", Int, Mandatory, "Commit changes"),
-
MGM_CMD("set parameter", &MgmApiSession::setParameter, ""),
MGM_ARG("node", String, Mandatory, "Node"),
MGM_ARG("parameter", String, Mandatory, "Parameter"),
@@ -910,8 +895,10 @@ printNodeStatus(OutputStream *output,
nodeGroup = 0,
connectCount = 0;
bool system;
- mgmsrv.status(nodeId, &status, &version, &startPhase,
- &system, &dynamicId, &nodeGroup, &connectCount);
+ const char *address= NULL;
+ mgmsrv.status(nodeId, &status, &version, &startPhase,
+ &system, &dynamicId, &nodeGroup, &connectCount,
+ &address);
output->println("node.%d.type: %s",
nodeId,
ndb_mgm_get_node_type_string(type));
@@ -923,7 +910,7 @@ printNodeStatus(OutputStream *output,
output->println("node.%d.dynamic_id: %d", nodeId, dynamicId);
output->println("node.%d.node_group: %d", nodeId, nodeGroup);
output->println("node.%d.connect_count: %d", nodeId, connectCount);
- output->println("node.%d.address: %s", nodeId, mgmsrv.get_connect_address(nodeId));
+ output->println("node.%d.address: %s", nodeId, address ? address : "");
}
}
@@ -1192,42 +1179,6 @@ MgmApiSession::setLogFilter(Parser_t::Context &ctx,
m_output->println("");
}
-void
-MgmApiSession::configLock(Parser_t::Context &,
- Properties const &) {
- int ret = m_mgmsrv.lockConf();
- m_output->println("config lock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configUnlock(Parser_t::Context &,
- Properties const &args) {
- Uint32 commit;
- args.get("commit", &commit);
- int ret = m_mgmsrv.unlockConf(commit == 1);
- m_output->println("config unlock reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
-void
-MgmApiSession::configChange(Parser_t::Context &,
- Properties const &args) {
- BaseString section, param, value;
- args.get("section", section);
- args.get("parameter", param);
- args.get("value", value);
-
- int ret = m_mgmsrv.changeConfig(section.c_str(),
- param.c_str(),
- value.c_str());
- m_output->println("config change reply");
- m_output->println("result: %d", ret);
- m_output->println("");
-}
-
static NdbOut&
operator<<(NdbOut& out, const LogLevel & ll)
{
diff --git a/storage/ndb/src/mgmsrv/Services.hpp b/storage/ndb/src/mgmsrv/Services.hpp
index 7d5d8cb9c8c..8672010d66c 100644
--- a/storage/ndb/src/mgmsrv/Services.hpp
+++ b/storage/ndb/src/mgmsrv/Services.hpp
@@ -83,9 +83,6 @@ public:
void setClusterLogLevel(Parser_t::Context &ctx,
const class Properties &args);
void setLogFilter(Parser_t::Context &ctx, const class Properties &args);
- void configLock(Parser_t::Context &ctx, const class Properties &args);
- void configUnlock(Parser_t::Context &ctx, const class Properties &args);
- void configChange(Parser_t::Context &ctx, const class Properties &args);
void setParameter(Parser_t::Context &ctx, const class Properties &args);
void setConnectionParameter(Parser_t::Context &ctx,
diff --git a/storage/ndb/src/mgmsrv/main.cpp b/storage/ndb/src/mgmsrv/main.cpp
index ec20101493e..f0c2ac298a5 100644
--- a/storage/ndb/src/mgmsrv/main.cpp
+++ b/storage/ndb/src/mgmsrv/main.cpp
@@ -102,6 +102,7 @@ static int opt_daemon; // NOT bool, bool need not be int
static int opt_non_interactive;
static int opt_interactive;
static const char * opt_config_filename= 0;
+static int opt_mycnf = 0;
struct MgmGlobals {
MgmGlobals();
@@ -166,6 +167,10 @@ static struct my_option my_long_options[] =
"Don't run as daemon, but don't read from stdin",
(gptr*) &opt_non_interactive, (gptr*) &opt_non_interactive, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
+ { "mycnf", 256,
+ "Read cluster config from my.cnf",
+ (gptr*) &opt_mycnf, (gptr*) &opt_mycnf, 0,
+ GET_BOOL, 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}
};
@@ -199,7 +204,7 @@ int main(int argc, char** argv)
#endif
global_mgmt_server_check = 1;
-
+
const char *load_default_groups[]= { "mysql_cluster","ndb_mgmd",0 };
load_defaults("my",load_default_groups,&argc,&argv);
@@ -217,13 +222,26 @@ int main(int argc, char** argv)
opt_daemon= 0;
}
+ if (opt_mycnf && opt_config_filename)
+ {
+ ndbout_c("Both --mycnf and -f is not supported");
+ return 0;
+ }
+
+ if (opt_mycnf == 0 && opt_config_filename == 0)
+ {
+ struct stat buf;
+ if (stat("config.ini", &buf) != -1)
+ opt_config_filename = "config.ini";
+ }
+
glob->socketServer = new SocketServer();
MgmApiService * mapi = new MgmApiService();
glob->mgmObject = new MgmtSrvr(glob->socketServer,
- opt_config_filename,
- opt_connect_str);
+ opt_config_filename,
+ opt_connect_str);
if (g_print_full_config)
goto the_end;
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.cpp b/storage/ndb/src/ndbapi/NdbApiSignal.cpp
index b1671e593e1..94695185224 100644
--- a/storage/ndb/src/ndbapi/NdbApiSignal.cpp
+++ b/storage/ndb/src/ndbapi/NdbApiSignal.cpp
@@ -62,6 +62,25 @@ NdbApiSignal::NdbApiSignal(BlockReference ref)
theNextSignal = 0;
}
+NdbApiSignal::NdbApiSignal(Ndb* ndb)
+{
+ BlockReference ref = ndb->theMyRef;
+ theVerId_signalNumber = 0; // 4 bit ver id - 16 bit gsn
+ theReceiversBlockNumber = 0; // Only 16 bit blocknum
+ theSendersBlockRef = refToBlock(ref);
+ theLength = 0;
+ theSendersSignalId = 0;
+ theSignalId = 0;
+ theTrace = 0;
+ m_noOfSections = 0;
+ m_fragmentInfo = 0;
+ for (int i = 0; i < 25; i++)
+ theData[i] = 0x13579753;
+
+ setDataPtr(&theData[0]);
+ theNextSignal = 0;
+}
+
/**
* Copy constructor
*/
diff --git a/storage/ndb/src/ndbapi/NdbApiSignal.hpp b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
index 353c575d420..9d04a8594a8 100644
--- a/storage/ndb/src/ndbapi/NdbApiSignal.hpp
+++ b/storage/ndb/src/ndbapi/NdbApiSignal.hpp
@@ -46,7 +46,8 @@
class NdbApiSignal : public SignalHeader
{
public:
- NdbApiSignal(BlockReference myRef);
+ NdbApiSignal(Ndb* ndb);
+ NdbApiSignal(BlockReference ref);
NdbApiSignal(const NdbApiSignal &);
NdbApiSignal(const SignalHeader &header)
: SignalHeader(header), theNextSignal(0), theRealData(0) {};
diff --git a/storage/ndb/src/ndbapi/NdbBlob.cpp b/storage/ndb/src/ndbapi/NdbBlob.cpp
index 77ab87ce5c1..28d657f3fe9 100644
--- a/storage/ndb/src/ndbapi/NdbBlob.cpp
+++ b/storage/ndb/src/ndbapi/NdbBlob.cpp
@@ -141,7 +141,7 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
// initialization
-NdbBlob::NdbBlob()
+NdbBlob::NdbBlob(Ndb*)
{
init();
}
diff --git a/storage/ndb/src/ndbapi/NdbImpl.hpp b/storage/ndb/src/ndbapi/NdbImpl.hpp
index 5e630b54d68..30e0d28a765 100644
--- a/storage/ndb/src/ndbapi/NdbImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbImpl.hpp
@@ -32,6 +32,21 @@
#include "NdbDictionaryImpl.hpp"
#include "ObjectMap.hpp"
+template <class T>
+struct Ndb_free_list_t
+{
+ Ndb_free_list_t();
+ ~Ndb_free_list_t();
+
+ void fill(Ndb*, Uint32 cnt);
+ T* seize(Ndb*);
+ void release(T*);
+ void clear();
+ Uint32 get_sizeof() const { return sizeof(T); }
+ T * m_free_list;
+ Uint32 m_alloc_cnt, m_free_cnt;
+};
+
/**
* Private parts of the Ndb object (corresponding to Ndb.hpp in public API)
*/
@@ -66,7 +81,6 @@ public:
int m_optimized_node_selection;
-
BaseString m_dbname; // Database name
BaseString m_schemaname; // Schema name
@@ -78,6 +92,22 @@ public:
m_schemaname.c_str(), table_name_separator);
}
+ /**
+ * NOTE free lists must be _after_ theNdbObjectIdMap take
+ * assure that destructors are run in correct order
+ */
+ Ndb_free_list_t<NdbTransaction> theConIdleList;
+ Ndb_free_list_t<NdbOperation> theOpIdleList;
+ Ndb_free_list_t<NdbIndexScanOperation> theScanOpIdleList;
+ Ndb_free_list_t<NdbIndexOperation> theIndexOpIdleList;
+ Ndb_free_list_t<NdbRecAttr> theRecAttrIdleList;
+ Ndb_free_list_t<NdbApiSignal> theSignalIdleList;
+ Ndb_free_list_t<NdbLabel> theLabelList;
+ Ndb_free_list_t<NdbBranch> theBranchList;
+ Ndb_free_list_t<NdbSubroutine> theSubroutineList;
+ Ndb_free_list_t<NdbCall> theCallList;
+ Ndb_free_list_t<NdbBlob> theNdbBlobIdleList;
+ Ndb_free_list_t<NdbReceiver> theScanList;
};
#ifdef VM_TRACE
@@ -152,4 +182,91 @@ enum LockMode {
Delete
};
+template<class T>
+inline
+Ndb_free_list_t<T>::Ndb_free_list_t()
+{
+ m_free_list= 0;
+ m_alloc_cnt= m_free_cnt= 0;
+}
+
+template<class T>
+inline
+Ndb_free_list_t<T>::~Ndb_free_list_t()
+{
+ clear();
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::fill(Ndb* ndb, Uint32 cnt)
+{
+ if (m_free_list == 0)
+ {
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = new T(ndb);
+ }
+ while(m_alloc_cnt < cnt)
+ {
+ T* obj= new T(ndb);
+ if(obj == 0)
+ return;
+
+ obj->next(m_free_list);
+ m_free_cnt++;
+ m_alloc_cnt++;
+ m_free_list = obj;
+ }
+}
+
+template<class T>
+inline
+T*
+Ndb_free_list_t<T>::seize(Ndb* ndb)
+{
+ T* tmp = m_free_list;
+ if (tmp)
+ {
+ m_free_list = (T*)tmp->next();
+ tmp->next(NULL);
+ m_free_cnt--;
+ return tmp;
+ }
+
+ if((tmp = new T(ndb)))
+ {
+ m_alloc_cnt++;
+ }
+
+ return tmp;
+}
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::release(T* obj)
+{
+ obj->next(m_free_list);
+ m_free_list = obj;
+ m_free_cnt++;
+}
+
+
+template<class T>
+inline
+void
+Ndb_free_list_t<T>::clear()
+{
+ T* obj = m_free_list;
+ while(obj)
+ {
+ T* curr = obj;
+ obj = (T*)obj->next();
+ delete curr;
+ m_alloc_cnt--;
+ }
+}
+
#endif
diff --git a/storage/ndb/src/ndbapi/NdbRecAttr.cpp b/storage/ndb/src/ndbapi/NdbRecAttr.cpp
index 5e5306fc33a..5201c6c9c04 100644
--- a/storage/ndb/src/ndbapi/NdbRecAttr.cpp
+++ b/storage/ndb/src/ndbapi/NdbRecAttr.cpp
@@ -22,7 +22,7 @@
#include "NdbDictionaryImpl.hpp"
#include <NdbTCP.h>
-NdbRecAttr::NdbRecAttr()
+NdbRecAttr::NdbRecAttr(Ndb*)
{
init();
}
@@ -98,7 +98,7 @@ NdbRecAttr::copyout()
NdbRecAttr *
NdbRecAttr::clone() const {
- NdbRecAttr * ret = new NdbRecAttr();
+ NdbRecAttr * ret = new NdbRecAttr(0);
ret->theAttrId = theAttrId;
ret->theNULLind = theNULLind;
diff --git a/storage/ndb/src/ndbapi/NdbUtil.cpp b/storage/ndb/src/ndbapi/NdbUtil.cpp
index 5c74d251ff9..6019ea675a1 100644
--- a/storage/ndb/src/ndbapi/NdbUtil.cpp
+++ b/storage/ndb/src/ndbapi/NdbUtil.cpp
@@ -30,8 +30,7 @@ Comment:
#include "NdbUtil.hpp"
-NdbLabel::NdbLabel() :
- theNext(NULL)
+NdbLabel::NdbLabel(Ndb*)
{
}
@@ -39,8 +38,7 @@ NdbLabel::~NdbLabel()
{
}
-NdbSubroutine::NdbSubroutine() :
- theNext(NULL)
+NdbSubroutine::NdbSubroutine(Ndb*)
{
}
@@ -48,9 +46,8 @@ NdbSubroutine::~NdbSubroutine()
{
}
-NdbBranch::NdbBranch() :
- theSignal(NULL),
- theNext(NULL)
+NdbBranch::NdbBranch(Ndb*) :
+ theSignal(NULL)
{
}
@@ -58,9 +55,8 @@ NdbBranch::~NdbBranch()
{
}
-NdbCall::NdbCall() :
- theSignal(NULL),
- theNext(NULL)
+NdbCall::NdbCall(Ndb*) :
+ theSignal(NULL)
{
}
diff --git a/storage/ndb/src/ndbapi/NdbUtil.hpp b/storage/ndb/src/ndbapi/NdbUtil.hpp
index 80fc15ddd8c..268f6c69e6f 100644
--- a/storage/ndb/src/ndbapi/NdbUtil.hpp
+++ b/storage/ndb/src/ndbapi/NdbUtil.hpp
@@ -31,44 +31,53 @@ Comment:
#include <ndb_global.h>
+class Ndb;
class NdbApiSignal;
class NdbOperation;
-class NdbLabel
+template<class T>
+struct Free_list_element
+{
+ Free_list_element() { theNext = 0;}
+ void next(T* obj) { theNext = obj;}
+ T* next() { return theNext;}
+
+ T* theNext;
+};
+
+class NdbLabel : public Free_list_element<NdbLabel>
{
friend class NdbOperation;
friend class Ndb;
-
-private:
- NdbLabel();
+public:
+ NdbLabel(Ndb*);
~NdbLabel();
- NdbLabel* theNext;
+private:
Uint32 theSubroutine[16];
Uint32 theLabelAddress[16];
Uint32 theLabelNo[16];
};
-class NdbSubroutine
+class NdbSubroutine : public Free_list_element<NdbSubroutine>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbSubroutine();
+public:
+ NdbSubroutine(Ndb*);
~NdbSubroutine();
- NdbSubroutine* theNext;
Uint32 theSubroutineAddress[16];
};
-class NdbBranch
+class NdbBranch : public Free_list_element<NdbBranch>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbBranch();
+public:
+ NdbBranch(Ndb*);
~NdbBranch();
NdbApiSignal* theSignal;
@@ -76,22 +85,20 @@ private:
Uint32 theBranchAddress;
Uint32 theBranchLabel;
Uint32 theSubroutine;
- NdbBranch* theNext;
};
-class NdbCall
+class NdbCall : public Free_list_element<NdbCall>
{
friend class NdbOperation;
friend class Ndb;
-private:
- NdbCall();
+public:
+ NdbCall(Ndb*);
~NdbCall();
NdbApiSignal* theSignal;
Uint32 theSignalAddress;
Uint32 theSubroutine;
- NdbCall* theNext;
};
#endif
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
index 48608345acd..d68248e6981 100644
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp
@@ -146,15 +146,6 @@ Ndb::init(int aMaxNoOfTransactions)
error_handler:
ndbout << "error_handler" << endl;
releaseTransactionArrays();
- while ( theConIdleList != NULL )
- freeNdbCon();
- while ( theSignalIdleList != NULL )
- freeSignal();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while (theOpIdleList != NULL)
- freeOperation();
-
delete theDictionary;
TransporterFacade::instance()->close(theNdbBlockNumber, 0);
DBUG_RETURN(-1);
diff --git a/storage/ndb/src/ndbapi/Ndbinit.cpp b/storage/ndb/src/ndbapi/Ndbinit.cpp
index a742f571a81..bb77a69937b 100644
--- a/storage/ndb/src/ndbapi/Ndbinit.cpp
+++ b/storage/ndb/src/ndbapi/Ndbinit.cpp
@@ -29,6 +29,10 @@
#include <NdbOut.hpp>
#include <NdbSleep.h>
#include "ObjectMap.hpp"
+#include <NdbIndexScanOperation.hpp>
+#include <NdbIndexOperation.hpp>
+#include "NdbUtil.hpp"
+#include <NdbBlob.hpp>
#include "NdbEventOperationImpl.hpp"
#include <EventLogger.hpp>
@@ -62,20 +66,8 @@ void Ndb::setup(Ndb_cluster_connection *ndb_cluster_connection,
theRemainingStartTransactions= 0;
theMaxNoOfTransactions= 0;
theMinNoOfEventsToWakeUp= 0;
- theConIdleList= NULL;
- theOpIdleList= NULL;
- theScanOpIdleList= NULL;
- theIndexOpIdleList= NULL;
theTransactionList= NULL;
theConnectionArray= NULL;
- theRecAttrIdleList= NULL;
- theSignalIdleList= NULL;
- theLabelList= NULL;
- theBranchList= NULL;
- theSubroutineList= NULL;
- theCallList= NULL;
- theScanList= NULL;
- theNdbBlobIdleList= NULL;
the_last_check_time= 0;
theFirstTransId= 0;
theRestartGCI= 0;
@@ -160,33 +152,6 @@ Ndb::~Ndb()
TransporterFacade::instance()->close(theNdbBlockNumber, theFirstTransId);
}
-// if (theSchemaConToNdbList != NULL)
-// closeSchemaTransaction(theSchemaConToNdbList);
- while ( theConIdleList != NULL )
- freeNdbCon();
- while (theOpIdleList != NULL)
- freeOperation();
- while (theScanOpIdleList != NULL)
- freeScanOperation();
- while (theIndexOpIdleList != NULL)
- freeIndexOperation();
- while (theLabelList != NULL)
- freeNdbLabel();
- while (theBranchList != NULL)
- freeNdbBranch();
- while (theSubroutineList != NULL)
- freeNdbSubroutine();
- while (theCallList != NULL)
- freeNdbCall();
- while (theScanList != NULL)
- freeNdbScanRec();
- while (theNdbBlobIdleList != NULL)
- freeNdbBlob();
- while (theRecAttrIdleList != NULL)
- freeRecAttr();
- while ( theSignalIdleList != NULL )
- freeSignal();
-
releaseTransactionArrays();
delete []theConnectionArray;
@@ -242,7 +207,8 @@ NdbImpl::NdbImpl(Ndb_cluster_connection *ndb_cluster_connection,
m_ndb_cluster_connection(ndb_cluster_connection->m_impl),
m_dictionary(ndb),
theCurrentConnectIndex(0),
- theNdbObjectIdMap(1024,1024),
+ theNdbObjectIdMap(ndb_cluster_connection->m_impl.m_transporter_facade->theMutexPtr,
+ 1024,1024),
theNoOfDBnodes(0),
m_ev_op(0)
{
diff --git a/storage/ndb/src/ndbapi/Ndblist.cpp b/storage/ndb/src/ndbapi/Ndblist.cpp
index 96d0f4d7de5..f82348fc91d 100644
--- a/storage/ndb/src/ndbapi/Ndblist.cpp
+++ b/storage/ndb/src/ndbapi/Ndblist.cpp
@@ -75,24 +75,7 @@ Ndb::checkFailedNode()
int
Ndb::createConIdleList(int aNrOfCon)
{
- for (int i = 0; i < aNrOfCon; i++)
- {
- NdbTransaction* tNdbCon = new NdbTransaction(this);
- if (tNdbCon == NULL)
- {
- return -1;
- }
- if (theConIdleList == NULL)
- {
- theConIdleList = tNdbCon;
- theConIdleList->next(NULL);
- } else
- {
- tNdbCon->next(theConIdleList);
- theConIdleList = tNdbCon;
- }
- tNdbCon->Status(NdbTransaction::NotConnected);
- }
+ theImpl->theConIdleList.fill(this, aNrOfCon);
return aNrOfCon;
}
@@ -108,19 +91,7 @@ Ndb::createConIdleList(int aNrOfCon)
int
Ndb::createOpIdleList(int aNrOfOp)
{
- for (int i = 0; i < aNrOfOp; i++){
- NdbOperation* tOp = new NdbOperation(this);
- if ( tOp == NULL ){
- return -1;
- }
- if (theOpIdleList == NULL){
- theOpIdleList = tOp;
- theOpIdleList->next(NULL);
- } else{
- tOp->next(theOpIdleList);
- theOpIdleList = tOp;
- }
- }
+ theImpl->theOpIdleList.fill(this, aNrOfOp);
return aNrOfOp;
}
@@ -134,22 +105,7 @@ Ndb::createOpIdleList(int aNrOfOp)
NdbBranch*
Ndb::getNdbBranch()
{
- NdbBranch* tNdbBranch;
- if ( theBranchList == NULL )
- {
- tNdbBranch = new NdbBranch;
- if (tNdbBranch == NULL)
- {
- return NULL;
- }
- tNdbBranch->theNext = NULL;
- } else
- {
- tNdbBranch = theBranchList;
- theBranchList = tNdbBranch->theNext;
- tNdbBranch->theNext = NULL;
- }
- return tNdbBranch;
+ return theImpl->theBranchList.seize(this);
}
/***************************************************************************
@@ -162,22 +118,7 @@ Ndb::getNdbBranch()
NdbCall*
Ndb::getNdbCall()
{
- NdbCall* tNdbCall;
- if ( theCallList == NULL )
- {
- tNdbCall = new NdbCall;
- if (tNdbCall == NULL)
- {
- return NULL;
- }
- tNdbCall->theNext = NULL;
- } else
- {
- tNdbCall = theCallList;
- theCallList = tNdbCall->theNext;
- tNdbCall->theNext = NULL;
- }
- return tNdbCall;
+ return theImpl->theCallList.seize(this);
}
/***************************************************************************
@@ -190,19 +131,7 @@ Ndb::getNdbCall()
NdbTransaction*
Ndb::getNdbCon()
{
- NdbTransaction* tNdbCon;
- if ( theConIdleList == NULL ) {
- tNdbCon = new NdbTransaction(this);
- if (tNdbCon == NULL) {
- return NULL;
- }//if
- tNdbCon->next(NULL);
- } else
- {
- tNdbCon = theConIdleList;
- theConIdleList = tNdbCon->next();
- tNdbCon->next(NULL);
- }
+ NdbTransaction* tNdbCon = theImpl->theConIdleList.seize(this);
tNdbCon->theMagicNumber = 0x37412619;
return tNdbCon;
}
@@ -217,22 +146,7 @@ Ndb::getNdbCon()
NdbLabel*
Ndb::getNdbLabel()
{
- NdbLabel* tNdbLabel;
- if ( theLabelList == NULL )
- {
- tNdbLabel = new NdbLabel;
- if (tNdbLabel == NULL)
- {
- return NULL;
- }
- tNdbLabel->theNext = NULL;
- } else
- {
- tNdbLabel = theLabelList;
- theLabelList = tNdbLabel->theNext;
- tNdbLabel->theNext = NULL;
- }
- return tNdbLabel;
+ return theImpl->theLabelList.seize(this);
}
/***************************************************************************
@@ -246,23 +160,7 @@ Ndb::getNdbLabel()
NdbReceiver*
Ndb::getNdbScanRec()
{
- NdbReceiver* tNdbScanRec;
- if ( theScanList == NULL )
- {
- tNdbScanRec = new NdbReceiver(this);
- if (tNdbScanRec == NULL)
- {
- return NULL;
- }
- tNdbScanRec->next(NULL);
- } else
- {
- tNdbScanRec = theScanList;
- theScanList = tNdbScanRec->next();
- tNdbScanRec->next(NULL);
- }
-
- return tNdbScanRec;
+ return theImpl->theScanList.seize(this);
}
/***************************************************************************
@@ -275,22 +173,7 @@ Ndb::getNdbScanRec()
NdbSubroutine*
Ndb::getNdbSubroutine()
{
- NdbSubroutine* tNdbSubroutine;
- if ( theSubroutineList == NULL )
- {
- tNdbSubroutine = new NdbSubroutine;
- if (tNdbSubroutine == NULL)
- {
- return NULL;
- }
- tNdbSubroutine->theNext = NULL;
- } else
- {
- tNdbSubroutine = theSubroutineList;
- theSubroutineList = tNdbSubroutine->theNext;
- tNdbSubroutine->theNext = NULL;
- }
- return tNdbSubroutine;
+ return theImpl->theSubroutineList.seize(this);
}
/***************************************************************************
@@ -303,18 +186,7 @@ Remark: Get an operation from theOpIdleList and return the object .
NdbOperation*
Ndb::getOperation()
{
- NdbOperation* tOp = theOpIdleList;
- if (tOp != NULL ) {
- NdbOperation* tOpNext = tOp->next();
- tOp->next(NULL);
- theOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theOpIdleList.seize(this);
}
/***************************************************************************
@@ -327,18 +199,7 @@ Remark: Get an operation from theScanOpIdleList and return the object .
NdbIndexScanOperation*
Ndb::getScanOperation()
{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- if (tOp != NULL ) {
- NdbIndexScanOperation* tOpNext = (NdbIndexScanOperation*)tOp->next();
- tOp->next(NULL);
- theScanOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexScanOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theScanOpIdleList.seize(this);
}
/***************************************************************************
@@ -351,18 +212,7 @@ Remark: Get an operation from theIndexOpIdleList and return the object .
NdbIndexOperation*
Ndb::getIndexOperation()
{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- if (tOp != NULL ) {
- NdbIndexOperation* tOpNext = (NdbIndexOperation*) tOp->next();
- tOp->next(NULL);
- theIndexOpIdleList = tOpNext;
- return tOp;
- } else {
- tOp = new NdbIndexOperation(this);
- if (tOp != NULL)
- tOp->next(NULL);
- }
- return tOp;
+ return theImpl->theIndexOpIdleList.seize(this);
}
/***************************************************************************
@@ -374,21 +224,14 @@ Return Value: Return a reference to a receive attribute object.
NdbRecAttr*
Ndb::getRecAttr()
{
- NdbRecAttr* tRecAttr;
- tRecAttr = theRecAttrIdleList;
- if (tRecAttr != NULL) {
- NdbRecAttr* tRecAttrNext = tRecAttr->next();
+ NdbRecAttr* tRecAttr = theImpl->theRecAttrIdleList.seize(this);
+ if (tRecAttr != NULL)
+ {
tRecAttr->init();
- theRecAttrIdleList = tRecAttrNext;
return tRecAttr;
- } else {
- tRecAttr = new NdbRecAttr;
- if (tRecAttr == NULL)
- return NULL;
- tRecAttr->next(NULL);
- }//if
- tRecAttr->init();
- return tRecAttr;
+ }
+
+ return NULL;
}
/***************************************************************************
@@ -400,34 +243,16 @@ Return Value: Return a reference to a signal object.
NdbApiSignal*
Ndb::getSignal()
{
- NdbApiSignal* tSignal = theSignalIdleList;
- if (tSignal != NULL){
- NdbApiSignal* tSignalNext = tSignal->next();
- tSignal->next(NULL);
- theSignalIdleList = tSignalNext;
- } else {
- tSignal = new NdbApiSignal(theMyRef);
-#ifdef POORMANSPURIFY
- cnewSignals++;
-#endif
- if (tSignal != NULL)
- tSignal->next(NULL);
- }
-#ifdef POORMANSPURIFY
- cgetSignals++;
-#endif
- return tSignal;
+ return theImpl->theSignalIdleList.seize(this);
}
NdbBlob*
Ndb::getNdbBlob()
{
- NdbBlob* tBlob = theNdbBlobIdleList;
- if (tBlob != NULL) {
- theNdbBlobIdleList = tBlob->theNext;
+ NdbBlob* tBlob = theImpl->theNdbBlobIdleList.seize(this);
+ if(tBlob)
+ {
tBlob->init();
- } else {
- tBlob = new NdbBlob;
}
return tBlob;
}
@@ -441,8 +266,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbBranch(NdbBranch* aNdbBranch)
{
- aNdbBranch->theNext = theBranchList;
- theBranchList = aNdbBranch;
+ theImpl->theBranchList.release(aNdbBranch);
}
/***************************************************************************
@@ -454,8 +278,7 @@ Remark: Add a NdbBranch object into the Branch idlelist.
void
Ndb::releaseNdbCall(NdbCall* aNdbCall)
{
- aNdbCall->theNext = theCallList;
- theCallList = aNdbCall;
+ theImpl->theCallList.release(aNdbCall);
}
/***************************************************************************
@@ -467,9 +290,8 @@ Remark: Add a Connection object into the signal idlelist.
void
Ndb::releaseNdbCon(NdbTransaction* aNdbCon)
{
- aNdbCon->next(theConIdleList);
aNdbCon->theMagicNumber = 0xFE11DD;
- theConIdleList = aNdbCon;
+ theImpl->theConIdleList.release(aNdbCon);
}
/***************************************************************************
@@ -481,8 +303,7 @@ Remark: Add a NdbLabel object into the Label idlelist.
void
Ndb::releaseNdbLabel(NdbLabel* aNdbLabel)
{
- aNdbLabel->theNext = theLabelList;
- theLabelList = aNdbLabel;
+ theImpl->theLabelList.release(aNdbLabel);
}
/***************************************************************************
@@ -494,8 +315,7 @@ Remark: Add a NdbScanReceiver object into the Scan idlelist.
void
Ndb::releaseNdbScanRec(NdbReceiver* aNdbScanRec)
{
- aNdbScanRec->next(theScanList);
- theScanList = aNdbScanRec;
+ theImpl->theScanList.release(aNdbScanRec);
}
/***************************************************************************
@@ -507,8 +327,7 @@ Remark: Add a NdbSubroutine object into theSubroutine idlelist.
void
Ndb::releaseNdbSubroutine(NdbSubroutine* aNdbSubroutine)
{
- aNdbSubroutine->theNext = theSubroutineList;
- theSubroutineList = aNdbSubroutine;
+ theImpl->theSubroutineList.release(aNdbSubroutine);
}
/***************************************************************************
@@ -521,16 +340,14 @@ void
Ndb::releaseOperation(NdbOperation* anOperation)
{
if(anOperation->m_tcReqGSN == GSN_TCKEYREQ){
- anOperation->next(theOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D0;
- theOpIdleList = anOperation;
+ theImpl->theOpIdleList.release(anOperation);
} else {
assert(anOperation->m_tcReqGSN == GSN_TCINDXREQ);
- anOperation->next(theIndexOpIdleList);
anOperation->theNdbCon = NULL;
anOperation->theMagicNumber = 0xFE11D1;
- theIndexOpIdleList = (NdbIndexOperation*)anOperation;
+ theImpl->theIndexOpIdleList.release((NdbIndexOperation*)anOperation);
}
}
@@ -553,10 +370,9 @@ Ndb::releaseScanOperation(NdbIndexScanOperation* aScanOperation)
}
}
#endif
- aScanOperation->next(theScanOpIdleList);
aScanOperation->theNdbCon = NULL;
aScanOperation->theMagicNumber = 0xFE11D2;
- theScanOpIdleList = aScanOperation;
+ theImpl->theScanOpIdleList.release(aScanOperation);
DBUG_VOID_RETURN;
}
@@ -570,8 +386,7 @@ void
Ndb::releaseRecAttr(NdbRecAttr* aRecAttr)
{
aRecAttr->release();
- aRecAttr->next(theRecAttrIdleList);
- theRecAttrIdleList = aRecAttr;
+ theImpl->theRecAttrIdleList.release(aRecAttr);
}
/***************************************************************************
@@ -598,8 +413,7 @@ Ndb::releaseSignal(NdbApiSignal* aSignal)
#ifdef POORMANSPURIFY
creleaseSignals++;
#endif
- aSignal->next(theSignalIdleList);
- theSignalIdleList = aSignal;
+ theImpl->theSignalIdleList.release(aSignal);
}
void
@@ -616,162 +430,7 @@ void
Ndb::releaseNdbBlob(NdbBlob* aBlob)
{
aBlob->release();
- aBlob->theNext = theNdbBlobIdleList;
- theNdbBlobIdleList = aBlob;
-}
-
-/***************************************************************************
-void freeOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeOperation()
-{
- NdbOperation* tOp = theOpIdleList;
- theOpIdleList = theOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeScanOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeScanOperation()
-{
- NdbIndexScanOperation* tOp = theScanOpIdleList;
- theScanOpIdleList = (NdbIndexScanOperation *)tOp->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeIndexOperation();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeIndexOperation()
-{
- NdbIndexOperation* tOp = theIndexOpIdleList;
- theIndexOpIdleList = (NdbIndexOperation *) theIndexOpIdleList->next();
- delete tOp;
-}
-
-/***************************************************************************
-void freeNdbBranch();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbBranch()
-{
- NdbBranch* tNdbBranch = theBranchList;
- theBranchList = theBranchList->theNext;
- delete tNdbBranch;
-}
-
-/***************************************************************************
-void freeNdbCall();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCall()
-{
- NdbCall* tNdbCall = theCallList;
- theCallList = theCallList->theNext;
- delete tNdbCall;
-}
-
-/***************************************************************************
-void freeNdbScanRec();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbScanRec()
-{
- NdbReceiver* tNdbScanRec = theScanList;
- theScanList = theScanList->next();
- delete tNdbScanRec;
-}
-
-/***************************************************************************
-void freeNdbCon();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbCon()
-{
- NdbTransaction* tNdbCon = theConIdleList;
- theConIdleList = theConIdleList->next();
- delete tNdbCon;
-}
-
-/***************************************************************************
-void freeNdbLabel();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbLabel()
-{
- NdbLabel* tNdbLabel = theLabelList;
- theLabelList = theLabelList->theNext;
- delete tNdbLabel;
-}
-
-/***************************************************************************
-void freeNdbSubroutine();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeNdbSubroutine()
-{
- NdbSubroutine* tNdbSubroutine = theSubroutineList;
- theSubroutineList = theSubroutineList->theNext;
- delete tNdbSubroutine;
-}
-
-/***************************************************************************
-void freeRecAttr();
-
-Remark: Always release the first item in the free list
-***************************************************************************/
-void
-Ndb::freeRecAttr()
-{
- NdbRecAttr* tRecAttr = theRecAttrIdleList;
- theRecAttrIdleList = theRecAttrIdleList->next();
- delete tRecAttr;
-}
-
-/***************************************************************************
-void freeSignal();
-
-Remark: Delete a signal object from the signal idlelist.
-***************************************************************************/
-void
-Ndb::freeSignal()
-{
- NdbApiSignal* tSignal = theSignalIdleList;
- theSignalIdleList = tSignal->next();
- delete tSignal;
-#ifdef POORMANSPURIFY
- cfreeSignals++;
-#endif
-}
-
-void
-Ndb::freeNdbBlob()
-{
- NdbBlob* tBlob = theNdbBlobIdleList;
- theNdbBlobIdleList = tBlob->theNext;
- delete tBlob;
+ theImpl->theNdbBlobIdleList.release(aBlob);
}
/****************************************************************************
@@ -826,3 +485,102 @@ Ndb::releaseConnectToNdb(NdbTransaction* a_con)
DBUG_VOID_RETURN;
}
+template<class T>
+static
+Ndb::Free_list_usage*
+update(Ndb::Free_list_usage* curr,
+ Ndb_free_list_t<T> & list,
+ const char * name)
+{
+ curr->m_name = name;
+ curr->m_created = list.m_alloc_cnt;
+ curr->m_free = list.m_free_cnt;
+ curr->m_sizeof = sizeof(T);
+ return curr;
+}
+
+Ndb::Free_list_usage*
+Ndb::get_free_list_usage(Ndb::Free_list_usage* curr)
+{
+ if (curr == 0)
+ {
+ return 0;
+ }
+
+ if(curr->m_name == 0)
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+ else if(!strcmp(curr->m_name, "NdbTransaction"))
+ {
+ update(curr, theImpl->theOpIdleList, "NdbOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbOperation"))
+ {
+ update(curr, theImpl->theScanOpIdleList, "NdbIndexScanOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexScanOperation"))
+ {
+ update(curr, theImpl->theIndexOpIdleList, "NdbIndexOperation");
+ }
+ else if(!strcmp(curr->m_name, "NdbIndexOperation"))
+ {
+ update(curr, theImpl->theRecAttrIdleList, "NdbRecAttr");
+ }
+ else if(!strcmp(curr->m_name, "NdbRecAttr"))
+ {
+ update(curr, theImpl->theSignalIdleList, "NdbApiSignal");
+ }
+ else if(!strcmp(curr->m_name, "NdbApiSignal"))
+ {
+ update(curr, theImpl->theLabelList, "NdbLabel");
+ }
+ else if(!strcmp(curr->m_name, "NdbLabel"))
+ {
+ update(curr, theImpl->theBranchList, "NdbBranch");
+ }
+ else if(!strcmp(curr->m_name, "NdbBranch"))
+ {
+ update(curr, theImpl->theSubroutineList, "NdbSubroutine");
+ }
+ else if(!strcmp(curr->m_name, "NdbSubroutine"))
+ {
+ update(curr, theImpl->theCallList, "NdbCall");
+ }
+ else if(!strcmp(curr->m_name, "NdbCall"))
+ {
+ update(curr, theImpl->theNdbBlobIdleList, "NdbBlob");
+ }
+ else if(!strcmp(curr->m_name, "NdbBlob"))
+ {
+ update(curr, theImpl->theScanList, "NdbReceiver");
+ }
+ else if(!strcmp(curr->m_name, "NdbReceiver"))
+ {
+ return 0;
+ }
+ else
+ {
+ update(curr, theImpl->theConIdleList, "NdbTransaction");
+ }
+
+ return curr;
+}
+
+#define TI(T) \
+ template Ndb::Free_list_usage* \
+ update(Ndb::Free_list_usage*, Ndb_free_list_t<T> &, const char * name);\
+ template struct Ndb_free_list_t<T>
+
+TI(NdbBlob);
+TI(NdbCall);
+TI(NdbLabel);
+TI(NdbBranch);
+TI(NdbSubroutine);
+TI(NdbApiSignal);
+TI(NdbRecAttr);
+TI(NdbOperation);
+TI(NdbReceiver);
+TI(NdbConnection);
+TI(NdbIndexOperation);
+TI(NdbIndexScanOperation);
diff --git a/storage/ndb/src/ndbapi/ObjectMap.hpp b/storage/ndb/src/ndbapi/ObjectMap.hpp
index dc2a5046f77..e3db479f677 100644
--- a/storage/ndb/src/ndbapi/ObjectMap.hpp
+++ b/storage/ndb/src/ndbapi/ObjectMap.hpp
@@ -30,7 +30,7 @@ class NdbObjectIdMap //: NdbLockable
{
public:
STATIC_CONST( InvalidId = ~(Uint32)0 );
- NdbObjectIdMap(Uint32 initalSize = 128, Uint32 expandSize = 10);
+ NdbObjectIdMap(NdbMutex*, Uint32 initalSize = 128, Uint32 expandSize = 10);
~NdbObjectIdMap();
Uint32 map(void * object);
@@ -46,14 +46,16 @@ private:
void * m_obj;
} * m_map;
+ NdbMutex * m_mutex;
void expand(Uint32 newSize);
};
inline
-NdbObjectIdMap::NdbObjectIdMap(Uint32 sz, Uint32 eSz) {
+NdbObjectIdMap::NdbObjectIdMap(NdbMutex* mutex, Uint32 sz, Uint32 eSz) {
m_size = 0;
m_firstFree = InvalidId;
m_map = 0;
+ m_mutex = mutex;
m_expandSize = eSz;
expand(sz);
#ifdef DEBUG_OBJECTMAP
@@ -126,21 +128,26 @@ NdbObjectIdMap::getObject(Uint32 id){
inline void
NdbObjectIdMap::expand(Uint32 incSize){
+ NdbMutex_Lock(m_mutex);
Uint32 newSize = m_size + incSize;
- MapEntry * tmp = (MapEntry*)malloc(newSize * sizeof(MapEntry));
+ MapEntry * tmp = (MapEntry*)realloc(m_map, newSize * sizeof(MapEntry));
- if (m_map) {
- memcpy(tmp, m_map, m_size * sizeof(MapEntry));
- free((void*)m_map);
+ if (likely(tmp != 0))
+ {
+ m_map = tmp;
+
+ for(Uint32 i = m_size; i<newSize; i++){
+ m_map[i].m_next = i + 1;
+ }
+ m_firstFree = m_size;
+ m_map[newSize-1].m_next = InvalidId;
+ m_size = newSize;
}
- m_map = tmp;
-
- for(Uint32 i = m_size; i<newSize; i++){
- m_map[i].m_next = i + 1;
+ else
+ {
+ ndbout_c("NdbObjectIdMap::expand unable to expand!!");
}
- m_firstFree = m_size;
- m_map[newSize-1].m_next = InvalidId;
- m_size = newSize;
+ NdbMutex_Unlock(m_mutex);
}
#endif
diff --git a/storage/ndb/tools/ndb_condig.cpp b/storage/ndb/tools/ndb_condig.cpp
index 725249a5af5..1b9a771f243 100644
--- a/storage/ndb/tools/ndb_condig.cpp
+++ b/storage/ndb/tools/ndb_condig.cpp
@@ -23,6 +23,8 @@
#include <my_getopt.h>
#include <mysql_version.h>
+#include <netdb.h>
+
#include <NdbOut.hpp>
#include <mgmapi.h>
#include <mgmapi_configuration.hpp>
@@ -40,6 +42,8 @@ static const char * g_type = 0;
static const char * g_host = 0;
static const char * g_field_delimiter=",";
static const char * g_row_delimiter=" ";
+static const char * g_config_file = 0;
+static int g_mycnf = 0;
int g_print_full_config, opt_ndb_shm;
my_bool opt_core;
@@ -90,6 +94,12 @@ static struct my_option my_long_options[] =
{ "rows", 'r', "Row separator",
(gptr*) &g_row_delimiter, (gptr*) &g_row_delimiter,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "config-file", 256, "Path to config.ini",
+ (gptr*) &g_config_file, (gptr*) &g_config_file,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ { "mycnf", 256, "Read config from my.cnf",
+ (gptr*) &g_mycnf, (gptr*) &g_mycnf,
+ 0, GET_BOOL, 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}
};
@@ -124,6 +134,11 @@ struct Match
{
int m_key;
BaseString m_value;
+ virtual int eval(const Iter&);
+};
+
+struct HostMatch : public Match
+{
virtual int eval(NdbMgmHandle, const Iter&);
};
@@ -132,18 +147,21 @@ struct Apply
Apply() {}
Apply(int val) { m_key = val;}
int m_key;
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
struct NodeTypeApply : public Apply
{
- virtual int apply(NdbMgmHandle, const Iter&);
+ virtual int apply(const Iter&);
};
static int parse_query(Vector<Apply*>&, int &argc, char**& argv);
static int parse_where(Vector<Match*>&, int &argc, char**& argv);
-static int eval(NdbMgmHandle, const Iter&, const Vector<Match*>&);
-static int apply(NdbMgmHandle, const Iter&, const Vector<Apply*>&);
+static int eval(const Iter&, const Vector<Match*>&);
+static int apply(const Iter&, const Vector<Apply*>&);
+static ndb_mgm_configuration* fetch_configuration();
+static ndb_mgm_configuration* load_configuration();
+
int
main(int argc, char** argv){
NDB_INIT(argv[0]);
@@ -154,51 +172,16 @@ main(int argc, char** argv){
ndb_std_get_one_option)))
return -1;
- NdbMgmHandle mgm = ndb_mgm_create_handle();
- if(mgm == NULL) {
- fprintf(stderr, "Cannot create handle to management server.\n");
- exit(-1);
- }
+ ndb_mgm_configuration * conf = 0;
- ndb_mgm_set_error_stream(mgm, stderr);
-
- if (ndb_mgm_set_connectstring(mgm, g_connectstring))
- {
- fprintf(stderr, "* %5d: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- fprintf(stderr,
- "* %s", ndb_mgm_get_latest_error_desc(mgm));
- exit(-1);
- }
+ if (g_config_file || g_mycnf)
+ conf = load_configuration();
+ else
+ conf = fetch_configuration();
- if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ if (conf == 0)
{
- fprintf(stderr, "Connect failed");
- fprintf(stderr, " code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Connected to %s:%d\n",
- ndb_mgm_get_connected_host(mgm),
- ndb_mgm_get_connected_port(mgm));
- }
-
- ndb_mgm_configuration * conf = ndb_mgm_get_configuration(mgm, 0);
- if(conf == 0)
- {
- fprintf(stderr, "Could not get configuration");
- fprintf(stderr, "code: %d, msg: %s\n",
- ndb_mgm_get_latest_error(mgm),
- ndb_mgm_get_latest_error_msg(mgm));
- exit(-1);
- }
- else if(g_verbose)
- {
- fprintf(stderr, "Fetched configuration\n");
+ return -1;
}
Vector<Apply*> select_list;
@@ -224,12 +207,12 @@ main(int argc, char** argv){
iter.first();
for(iter.first(); iter.valid(); iter.next())
{
- if(eval(mgm, iter, where_clause))
+ if(eval(iter, where_clause))
{
if(prev)
printf("%s", g_row_delimiter);
prev= true;
- apply(mgm, iter, select_list);
+ apply(iter, select_list);
}
}
printf("\n");
@@ -297,9 +280,10 @@ parse_where(Vector<Match*>& where, int &argc, char**& argv)
Match m;
if(g_host)
{
- m.m_key = CFG_NODE_HOST;
- m.m_value.assfmt("%s", g_host);
- where.push_back(new Match(m));
+ HostMatch *m = new HostMatch;
+ m->m_key = CFG_NODE_HOST;
+ m->m_value.assfmt("%s", g_host);
+ where.push_back(m);
}
if(g_type)
@@ -323,11 +307,11 @@ template class Vector<Match*>;
static
int
-eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
+eval(const Iter& iter, const Vector<Match*>& where)
{
for(unsigned i = 0; i<where.size(); i++)
{
- if(where[i]->eval(mgm, iter) == 0)
+ if(where[i]->eval(iter) == 0)
return 0;
}
@@ -336,11 +320,11 @@ eval(NdbMgmHandle mgm, const Iter& iter, const Vector<Match*>& where)
static
int
-apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
+apply(const Iter& iter, const Vector<Apply*>& list)
{
for(unsigned i = 0; i<list.size(); i++)
{
- list[i]->apply(mgm, iter);
+ list[i]->apply(iter);
if(i + 1 != list.size())
printf("%s", g_field_delimiter);
}
@@ -348,19 +332,19 @@ apply(NdbMgmHandle mgm, const Iter& iter, const Vector<Apply*>& list)
}
int
-Match::eval(NdbMgmHandle h, const Iter& iter)
+Match::eval(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
const char* valc;
if (iter.get(m_key, &val32) == 0)
{
- if(atoi(m_value.c_str()) != val32)
+ if(atoi(m_value.c_str()) != (int)val32)
return 0;
}
else if(iter.get(m_key, &val64) == 0)
{
- if(strtoll(m_value.c_str(), (char **)NULL, 10) != val64)
+ if(strtoll(m_value.c_str(), (char **)NULL, 10) != (long long)val64)
return 0;
}
else if(iter.get(m_key, &valc) == 0)
@@ -376,7 +360,41 @@ Match::eval(NdbMgmHandle h, const Iter& iter)
}
int
-Apply::apply(NdbMgmHandle h, const Iter& iter)
+HostMatch::eval(NdbMgmHandle h, const Iter& iter)
+{
+ const char* valc;
+
+ if(iter.get(m_key, &valc) == 0)
+ {
+ struct hostent *h1, *h2;
+
+ h1 = gethostbyname(m_value.c_str());
+ if (h1 == NULL) {
+ return 0;
+ }
+
+ h2 = gethostbyname(valc);
+ if (h2 == NULL) {
+ return 0;
+ }
+
+ if (h1->h_addrtype != h2->h_addrtype) {
+ return 0;
+ }
+
+ if (h1->h_length != h2->h_length)
+ {
+ return 0;
+ }
+
+ return 0 == memcmp(h1->h_addr, h2->h_addr, h1->h_length);
+ }
+
+ return 0;
+}
+
+int
+Apply::apply(const Iter& iter)
{
Uint32 val32;
Uint64 val64;
@@ -397,7 +415,7 @@ Apply::apply(NdbMgmHandle h, const Iter& iter)
}
int
-NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
+NodeTypeApply::apply(const Iter& iter)
{
Uint32 val32;
if (iter.get(CFG_TYPE_OF_SECTION, &val32) == 0)
@@ -406,3 +424,86 @@ NodeTypeApply::apply(NdbMgmHandle h, const Iter& iter)
}
return 0;
}
+
+ndb_mgm_configuration*
+fetch_configuration()
+{
+ ndb_mgm_configuration* conf = 0;
+ NdbMgmHandle mgm = ndb_mgm_create_handle();
+ if(mgm == NULL) {
+ fprintf(stderr, "Cannot create handle to management server.\n");
+ return 0;
+ }
+
+ ndb_mgm_set_error_stream(mgm, stderr);
+
+ if (ndb_mgm_set_connectstring(mgm, g_connectstring))
+ {
+ fprintf(stderr, "* %5d: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ fprintf(stderr,
+ "* %s", ndb_mgm_get_latest_error_desc(mgm));
+ goto noconnect;
+ }
+
+ if(ndb_mgm_connect(mgm, try_reconnect-1, 5, 1))
+ {
+ fprintf(stderr, "Connect failed");
+ fprintf(stderr, " code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ goto noconnect;
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Connected to %s:%d\n",
+ ndb_mgm_get_connected_host(mgm),
+ ndb_mgm_get_connected_port(mgm));
+ }
+
+ conf = ndb_mgm_get_configuration(mgm, 0);
+ if(conf == 0)
+ {
+ fprintf(stderr, "Could not get configuration");
+ fprintf(stderr, "code: %d, msg: %s\n",
+ ndb_mgm_get_latest_error(mgm),
+ ndb_mgm_get_latest_error_msg(mgm));
+ }
+ else if(g_verbose)
+ {
+ fprintf(stderr, "Fetched configuration\n");
+ }
+
+ ndb_mgm_disconnect(mgm);
+noconnect:
+ ndb_mgm_destroy_handle(&mgm);
+
+ return conf;
+}
+
+#include <Config.hpp>
+
+ndb_mgm_configuration*
+load_configuration()
+{
+ InitConfigFileParser parser(stderr);
+ if (g_config_file)
+ {
+ if (g_verbose)
+ fprintf(stderr, "Using config.ini : %s", g_config_file);
+
+ Config* conf = parser.parseConfig(g_config_file);
+ if (conf)
+ return conf->m_configValues;
+ }
+
+ if (g_verbose)
+ fprintf(stderr, "Using my.cnf");
+
+ Config* conf = parser.parse_mycnf();
+ if (conf)
+ return conf->m_configValues;
+
+ return 0;
+}
diff --git a/storage/ndb/tools/restore/Restore.cpp b/storage/ndb/tools/restore/Restore.cpp
index 6c01b753b43..9efafd19468 100644
--- a/storage/ndb/tools/restore/Restore.cpp
+++ b/storage/ndb/tools/restore/Restore.cpp
@@ -870,7 +870,7 @@ operator<<(NdbOut& ndbout, const AttributeS& attr){
return ndbout;
}
- NdbRecAttr tmprec;
+ NdbRecAttr tmprec(0);
tmprec.setup(desc.m_column, (char *)data.void_value);
ndbout << tmprec;
diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp
index 5786bdac697..552246a4f9e 100644
--- a/storage/ndb/tools/restore/consumer_restore.cpp
+++ b/storage/ndb/tools/restore/consumer_restore.cpp
@@ -38,7 +38,7 @@ BackupRestore::init()
m_cluster_connection = new Ndb_cluster_connection(g_connect_string);
if(m_cluster_connection->connect(12, 5, 1) != 0)
{
- return -1;
+ return false;
}
m_ndb = new Ndb(m_cluster_connection);