summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <cmiller@zippy.(none)>2006-07-10 13:38:22 -0400
committerunknown <cmiller@zippy.(none)>2006-07-10 13:38:22 -0400
commitd6e3a9ddcb6a877feb65a98953b3ec9e6426be47 (patch)
tree555b6e52dd857768fcf99821dd6c45b62b80dd30 /storage
parent9b6a1384114a41beb8b492aed335096ef03c86df (diff)
parent8154ca618b68784098dcb8b84ba2cf77707c80e4 (diff)
downloadmariadb-git-d6e3a9ddcb6a877feb65a98953b3ec9e6426be47.tar.gz
Merge zippy.(none):/home/cmiller/work/mysql/merge/mysql-5.1
into zippy.(none):/home/cmiller/work/mysql/merge/mysql-5.1-new-maint mysql-test/mysql-test-run.pl: Auto merged mysql-test/r/create.result: Auto merged mysql-test/r/ps.result: Auto merged mysql-test/r/sp.result: Auto merged mysql-test/t/create.test: Auto merged mysql-test/t/ndb_autodiscover3.test: Auto merged mysql-test/t/ps.test: Auto merged mysql-test/t/sp.test: Auto merged mysql-test/t/wait_timeout.test: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged
Diffstat (limited to 'storage')
-rw-r--r--storage/myisam/mi_check.c5
-rw-r--r--storage/myisam/mi_create.c17
-rw-r--r--storage/myisam/mi_delete_table.c24
-rw-r--r--storage/myisam/mi_dynrec.c3
-rw-r--r--storage/myisam/mi_rkey.c24
-rw-r--r--storage/myisam/rt_index.c8
-rw-r--r--storage/myisam/rt_mbr.c6
-rw-r--r--storage/ndb/include/kernel/AttributeHeader.hpp3
-rw-r--r--storage/ndb/include/mgmapi/ndbd_exit_codes.h1
-rw-r--r--storage/ndb/include/ndbapi/Ndb.hpp1
-rw-r--r--storage/ndb/include/ndbapi/NdbDictionary.hpp3
-rw-r--r--storage/ndb/src/common/debugger/signaldata/SignalNames.cpp2
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/DictLock.txt12
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp3
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp40
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp67
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp21
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp1
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp41
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.cpp56
-rw-r--r--storage/ndb/src/kernel/blocks/suma/Suma.hpp3
-rw-r--r--storage/ndb/src/kernel/error/ndbd_exit_codes.c2
-rw-r--r--storage/ndb/src/kernel/vm/SimulatedBlock.cpp9
-rw-r--r--storage/ndb/src/kernel/vm/SimulatedBlock.hpp3
-rw-r--r--storage/ndb/src/ndbapi/ClusterMgr.cpp3
-rw-r--r--storage/ndb/src/ndbapi/DictCache.cpp13
-rw-r--r--storage/ndb/src/ndbapi/Ndb.cpp42
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp24
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp97
-rw-r--r--storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp2
-rw-r--r--storage/ndb/src/ndbapi/NdbScanOperation.cpp56
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp15
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp3
-rw-r--r--storage/ndb/src/ndbapi/ndberror.c2
-rw-r--r--storage/ndb/test/ndbapi/testNodeRestart.cpp1
-rw-r--r--storage/ndb/test/run-test/daily-basic-tests.txt4
-rw-r--r--storage/ndb/tools/desc.cpp3
-rw-r--r--storage/ndb/tools/restore/consumer_restore.cpp39
43 files changed, 472 insertions, 192 deletions
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index d91597e9138..91c04866b5a 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -1158,13 +1158,14 @@ int chk_data_link(MI_CHECK *param, MI_INFO *info,int extend)
#ifdef HAVE_RTREE_KEYS
(keyinfo->flag & HA_SPATIAL) ?
rtree_find_first(info, key, info->lastkey, key_length,
- SEARCH_SAME) :
+ MBR_EQUAL | MBR_DATA) :
#endif
_mi_search(info,keyinfo,info->lastkey,key_length,
SEARCH_SAME, info->s->state.key_root[key]);
if (search_result)
{
- mi_check_print_error(param,"Record at: %10s Can't find key for index: %2d",
+ mi_check_print_error(param,"Record at: %10s "
+ "Can't find key for index: %2d",
llstr(start_recpos,llbuff),key+1);
if (error++ > MAXERR || !(param->testflag & T_VERBOSE))
goto err2;
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 22cbde278be..c5a9af08def 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -60,6 +60,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
my_off_t key_root[MI_MAX_POSSIBLE_KEY],key_del[MI_MAX_KEY_BLOCK_SIZE];
MI_CREATE_INFO tmp_create_info;
DBUG_ENTER("mi_create");
+ DBUG_PRINT("enter", ("keys: %u columns: %u uniques: %u flags: %u",
+ keys, columns, uniques, flags));
if (!ci)
{
@@ -482,6 +484,16 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uniques * MI_UNIQUEDEF_SIZE +
(key_segs + unique_key_parts)*HA_KEYSEG_SIZE+
columns*MI_COLUMNDEF_SIZE);
+ DBUG_PRINT("info", ("info_length: %u", info_length));
+ /* There are only 16 bits for the total header length. */
+ if (info_length > 65535)
+ {
+ my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
+ "indexes and/or unique constraints.",
+ MYF(0), name + dirname_length(name));
+ my_errno= HA_WRONG_CREATE_OPTION;
+ goto err;
+ }
bmove(share.state.header.file_version,(byte*) myisam_file_magic,4);
ci->old_options=options| (ci->old_options & HA_OPTION_TEMP_COMPRESS_RECORD ?
@@ -650,6 +662,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
errpos=3;
}
+ DBUG_PRINT("info", ("write state info and base info"));
if (mi_state_info_write(file, &share.state, 2) ||
mi_base_info_write(file, &share.base))
goto err;
@@ -663,6 +676,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
#endif
/* Write key and keyseg definitions */
+ DBUG_PRINT("info", ("write key and keyseg definitions"));
for (i=0 ; i < share.base.keys - uniques; i++)
{
uint sp_segs=(keydefs[i].flag & HA_SPATIAL) ? 2*SPDIMS : 0;
@@ -713,6 +727,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
}
/* Save unique definition */
+ DBUG_PRINT("info", ("write unique definitions"));
for (i=0 ; i < share.state.header.uniques ; i++)
{
HA_KEYSEG *keyseg_end;
@@ -743,6 +758,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
goto err;
}
}
+ DBUG_PRINT("info", ("write field definitions"));
for (i=0 ; i < share.base.fields ; i++)
if (mi_recinfo_write(file, &recinfo[i]))
goto err;
@@ -757,6 +773,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
#endif
/* Enlarge files */
+ DBUG_PRINT("info", ("enlarge to keystart: %lu", (ulong) share.base.keystart));
if (my_chsize(file,(ulong) share.base.keystart,0,MYF(0)))
goto err;
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
index df0e9deb3ec..b72e97d3215 100644
--- a/storage/myisam/mi_delete_table.c
+++ b/storage/myisam/mi_delete_table.c
@@ -34,12 +34,24 @@ int mi_delete_table(const char *name)
#ifdef USE_RAID
{
MI_INFO *info;
- /* we use 'open_for_repair' to be able to delete a crashed table */
- if (!(info=mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
- DBUG_RETURN(my_errno);
- raid_type = info->s->base.raid_type;
- raid_chunks = info->s->base.raid_chunks;
- mi_close(info);
+ /*
+ When built with RAID support, we need to determine if this table
+ makes use of the raid feature. If yes, we need to remove all raid
+ chunks. This is done with my_raid_delete(). Unfortunately it is
+ necessary to open the table just to check this. We use
+ 'open_for_repair' to be able to open even a crashed table. If even
+ this open fails, we assume no raid configuration for this table
+ and try to remove the normal data file only. This may however
+ leave the raid chunks behind.
+ */
+ if (!(info= mi_open(name, O_RDONLY, HA_OPEN_FOR_REPAIR)))
+ raid_type= 0;
+ else
+ {
+ raid_type= info->s->base.raid_type;
+ raid_chunks= info->s->base.raid_chunks;
+ mi_close(info);
+ }
}
#ifdef EXTRA_DEBUG
check_table_is_closed(name,"delete");
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index 9d76a1fb9a5..0487500ad33 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -1329,6 +1329,9 @@ int _mi_read_dynamic_record(MI_INFO *info, my_off_t filepos, byte *buf)
info->rec_cache.pos_in_file <= block_info.next_filepos &&
flush_io_cache(&info->rec_cache))
goto err;
+ /* A corrupted table can have wrong pointers. (Bug# 19835) */
+ if (block_info.next_filepos == HA_OFFSET_ERROR)
+ goto panic;
info->rec_cache.seek_not_done=1;
if ((b_type=_mi_get_block_info(&block_info,file,
block_info.next_filepos))
diff --git a/storage/myisam/mi_rkey.c b/storage/myisam/mi_rkey.c
index e6f4d39ab49..a9a8cbacb4b 100644
--- a/storage/myisam/mi_rkey.c
+++ b/storage/myisam/mi_rkey.c
@@ -68,6 +68,7 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
if (fast_mi_readinfo(info))
goto err;
+
if (share->concurrent_insert)
rw_rdlock(&share->key_root_lock[inx]);
@@ -90,24 +91,35 @@ int mi_rkey(MI_INFO *info, byte *buf, int inx, const byte *key, uint key_len,
case HA_KEY_ALG_BTREE:
default:
if (!_mi_search(info, keyinfo, key_buff, use_key_length,
- myisam_read_vec[search_flag], info->s->state.key_root[inx]))
+ myisam_read_vec[search_flag], info->s->state.key_root[inx]))
{
- while (info->lastpos >= info->state->data_file_length)
+ /*
+ If we are searching for an exact key (including the data pointer)
+ and this was added by an concurrent insert,
+ then the result is "key not found".
+ */
+ if ((search_flag == HA_READ_KEY_EXACT) &&
+ (info->lastpos >= info->state->data_file_length))
+ {
+ my_errno= HA_ERR_KEY_NOT_FOUND;
+ info->lastpos= HA_OFFSET_ERROR;
+ }
+ else while (info->lastpos >= info->state->data_file_length)
{
/*
Skip rows that are inserted by other threads since we got a lock
Note that this can only happen if we are not searching after an
exact key, because the keys are sorted according to position
*/
-
if (_mi_search_next(info, keyinfo, info->lastkey,
- info->lastkey_length,
- myisam_readnext_vec[search_flag],
- info->s->state.key_root[inx]))
+ info->lastkey_length,
+ myisam_readnext_vec[search_flag],
+ info->s->state.key_root[inx]))
break;
}
}
}
+
if (share->concurrent_insert)
rw_unlock(&share->key_root_lock[inx]);
diff --git a/storage/myisam/rt_index.c b/storage/myisam/rt_index.c
index 97554dca4e6..1806476dc39 100644
--- a/storage/myisam/rt_index.c
+++ b/storage/myisam/rt_index.c
@@ -183,9 +183,11 @@ int rtree_find_first(MI_INFO *info, uint keynr, uchar *key, uint key_length,
return -1;
}
- /* Save searched key */
- memcpy(info->first_mbr_key, key, keyinfo->keylength -
- info->s->base.rec_reflength);
+ /*
+ Save searched key, include data pointer.
+ The data pointer is required if the search_flag contains MBR_DATA.
+ */
+ memcpy(info->first_mbr_key, key, keyinfo->keylength);
info->last_rkey_length = key_length;
info->rtree_recursion_depth = -1;
diff --git a/storage/myisam/rt_mbr.c b/storage/myisam/rt_mbr.c
index c43daec2f7c..897862c1c9a 100644
--- a/storage/myisam/rt_mbr.c
+++ b/storage/myisam/rt_mbr.c
@@ -52,10 +52,14 @@
if (EQUAL_CMP(amin, amax, bmin, bmax)) \
return 1; \
} \
- else /* if (nextflag & MBR_DISJOINT) */ \
+ else if (nextflag & MBR_DISJOINT) \
{ \
if (DISJOINT_CMP(amin, amax, bmin, bmax)) \
return 1; \
+ }\
+ else /* if unknown comparison operator */ \
+ { \
+ DBUG_ASSERT(0); \
}
#define RT_CMP_KORR(type, korr_func, len, nextflag) \
diff --git a/storage/ndb/include/kernel/AttributeHeader.hpp b/storage/ndb/include/kernel/AttributeHeader.hpp
index b17bb456bf0..b78b5912bec 100644
--- a/storage/ndb/include/kernel/AttributeHeader.hpp
+++ b/storage/ndb/include/kernel/AttributeHeader.hpp
@@ -39,12 +39,13 @@ public:
STATIC_CONST( RANGE_NO = 0xFFFB ); // Read range no (when batched ranges)
STATIC_CONST( ROW_SIZE = 0xFFFA );
- STATIC_CONST( FRAGMENT_MEMORY= 0xFFF9 );
+ STATIC_CONST( FRAGMENT_FIXED_MEMORY= 0xFFF9 );
STATIC_CONST( RECORDS_IN_RANGE = 0xFFF8 );
STATIC_CONST( DISK_REF = 0xFFF7 );
STATIC_CONST( ROWID = 0xFFF6 );
STATIC_CONST( ROW_GCI = 0xFFF5 );
+ STATIC_CONST( FRAGMENT_VARSIZED_MEMORY = 0xFFF4 );
// NOTE: in 5.1 ctors and init take size in bytes
diff --git a/storage/ndb/include/mgmapi/ndbd_exit_codes.h b/storage/ndb/include/mgmapi/ndbd_exit_codes.h
index b16f1a63a8d..79df36e7955 100644
--- a/storage/ndb/include/mgmapi/ndbd_exit_codes.h
+++ b/storage/ndb/include/mgmapi/ndbd_exit_codes.h
@@ -71,6 +71,7 @@ typedef ndbd_exit_classification_enum ndbd_exit_classification;
#define NDBD_EXIT_INDEX_NOTINRANGE 2304
#define NDBD_EXIT_ARBIT_SHUTDOWN 2305
#define NDBD_EXIT_POINTER_NOTINRANGE 2306
+#define NDBD_EXIT_PARTITIONED_SHUTDOWN 2307
#define NDBD_EXIT_SR_OTHERNODEFAILED 2308
#define NDBD_EXIT_NODE_NOT_DEAD 2309
#define NDBD_EXIT_SR_REDOLOG 2310
diff --git a/storage/ndb/include/ndbapi/Ndb.hpp b/storage/ndb/include/ndbapi/Ndb.hpp
index dcd03cdc467..07f11f6e78a 100644
--- a/storage/ndb/include/ndbapi/Ndb.hpp
+++ b/storage/ndb/include/ndbapi/Ndb.hpp
@@ -1553,6 +1553,7 @@ private:
const char* aCatalogName, const char* aSchemaName);
void connected(Uint32 block_reference);
+ void report_node_connected(Uint32 nodeId);
NdbTransaction* startTransactionLocal(Uint32 aPrio, Uint32 aFragmentId);
diff --git a/storage/ndb/include/ndbapi/NdbDictionary.hpp b/storage/ndb/include/ndbapi/NdbDictionary.hpp
index ea4a2a9ca29..35b0d927bda 100644
--- a/storage/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/storage/ndb/include/ndbapi/NdbDictionary.hpp
@@ -525,7 +525,8 @@ public:
const char* getDefaultValue() const;
static const Column * FRAGMENT;
- static const Column * FRAGMENT_MEMORY;
+ static const Column * FRAGMENT_FIXED_MEMORY;
+ static const Column * FRAGMENT_VARSIZED_MEMORY;
static const Column * ROW_COUNT;
static const Column * COMMIT_COUNT;
static const Column * ROW_SIZE;
diff --git a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
index 7304a46a278..a96d0de0560 100644
--- a/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
+++ b/storage/ndb/src/common/debugger/signaldata/SignalNames.cpp
@@ -365,6 +365,8 @@ const GsnName SignalNames [] = {
,{ GSN_EVENT_SUBSCRIBE_REF, "EVENT_SUBSCRIBE_REF" }
,{ GSN_DUMP_STATE_ORD, "DUMP_STATE_ORD" }
+ ,{ GSN_NODE_START_REP, "NODE_START_REP" }
+
,{ GSN_START_INFOREQ, "START_INFOREQ" }
,{ GSN_START_INFOREF, "START_INFOREF" }
,{ GSN_START_INFOCONF, "START_INFOCONF" }
diff --git a/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt b/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt
index 17f24119e9d..72e23ed15a5 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt
+++ b/storage/ndb/src/kernel/blocks/dbdict/DictLock.txt
@@ -85,10 +85,14 @@ DIH/s
START_MECONF
DIH/s
-* sp7 - release DICT lock
+* (copy data, omitted)
-DIH/s
- DICT_UNLOCK_ORD
- DICT/m
+* SL_STARTED - release DICT lock
+
+CNTR/s
+ NODE_START_REP
+ DIH/s
+ DICT_UNLOCK_ORD
+ DICT/m
# vim: set et sw=4:
diff --git a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
index 46effed867f..9d9ea6af2f5 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/Dbdih.hpp
@@ -1609,6 +1609,9 @@ private:
void dump_replica_info();
+ // DIH specifics for execNODE_START_REP (sendDictUnlockOrd)
+ void exec_node_start_rep(Signal* signal);
+
/*
* Lock master DICT. Only current use is by starting node
* during NR. A pool of slave records is convenient anyway.
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index c265f54bf30..0595c018b2e 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -1387,24 +1387,6 @@ void Dbdih::execNDB_STTOR(Signal* signal)
}
ndbrequire(false);
break;
- case ZNDB_SPH7:
- jam();
- switch (typestart) {
- case NodeState::ST_INITIAL_START:
- case NodeState::ST_SYSTEM_RESTART:
- jam();
- ndbsttorry10Lab(signal, __LINE__);
- return;
- case NodeState::ST_NODE_RESTART:
- case NodeState::ST_INITIAL_NODE_RESTART:
- jam();
- sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
- c_dictLockSlavePtrI_nodeRestart = RNIL;
- ndbsttorry10Lab(signal, __LINE__);
- return;
- }
- ndbrequire(false);
- break;
default:
jam();
ndbsttorry10Lab(signal, __LINE__);
@@ -1413,6 +1395,27 @@ void Dbdih::execNDB_STTOR(Signal* signal)
}//Dbdih::execNDB_STTOR()
void
+Dbdih::exec_node_start_rep(Signal* signal)
+{
+ /*
+ * Send DICT_UNLOCK_ORD when this node is SL_STARTED.
+ *
+ * Sending it before (sp 7) conflicts with code which assumes
+ * SL_STARTING means we are in copy phase of NR.
+ *
+ * NodeState::starting.restartType is not supposed to be used
+ * when SL_STARTED. Also it seems NODE_START_REP can arrive twice.
+ *
+ * For these reasons there are no consistency checks and
+ * we rely on c_dictLockSlavePtrI_nodeRestart alone.
+ */
+ if (c_dictLockSlavePtrI_nodeRestart != RNIL) {
+ sendDictUnlockOrd(signal, c_dictLockSlavePtrI_nodeRestart);
+ c_dictLockSlavePtrI_nodeRestart = RNIL;
+ }
+}
+
+void
Dbdih::createMutexes(Signal * signal, Uint32 count){
Callback c = { safe_cast(&Dbdih::createMutex_done), count };
@@ -1636,6 +1639,7 @@ void Dbdih::nodeRestartPh2Lab(Signal* signal)
void Dbdih::recvDictLockConf_nodeRestart(Signal* signal, Uint32 data, Uint32 ret)
{
ndbrequire(c_dictLockSlavePtrI_nodeRestart == RNIL);
+ ndbrequire(data != RNIL);
c_dictLockSlavePtrI_nodeRestart = data;
nodeRestartPh2Lab2(signal);
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index c1d4175833e..be52e06eb81 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -238,6 +238,7 @@ class Dbtup;
#define ZSCAN_MARKERS 18
#define ZOPERATION_EVENT_REP 19
#define ZPREP_DROP_TABLE 20
+#define ZENABLE_EXPAND_CHECK 21
/* ------------------------------------------------------------------------- */
/* NODE STATE DURING SYSTEM RESTART, VARIABLES CNODES_SR_STATE */
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 3890fb69b2e..695580d556c 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -416,6 +416,35 @@ void Dblqh::execCONTINUEB(Signal* signal)
checkDropTab(signal);
return;
break;
+ case ZENABLE_EXPAND_CHECK:
+ {
+ jam();
+ fragptr.i = signal->theData[1];
+ if (fragptr.i != RNIL)
+ {
+ jam();
+ c_redo_complete_fragments.getPtr(fragptr);
+ signal->theData[0] = fragptr.p->tabRef;
+ signal->theData[1] = fragptr.p->fragId;
+ sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
+
+ c_redo_complete_fragments.next(fragptr);
+ signal->theData[0] = ZENABLE_EXPAND_CHECK;
+ signal->theData[1] = fragptr.i;
+ sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
+ return;
+ }
+ else
+ {
+ jam();
+ c_redo_complete_fragments.remove();
+ StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
+ conf->startingNodeId = getOwnNodeId();
+ sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
+ StartRecConf::SignalLength, JBB);
+ return;
+ }
+ }
default:
ndbrequire(false);
break;
@@ -469,6 +498,7 @@ void Dblqh::execSTTOR(Signal* signal)
csignalKey = signal->theData[6];
#if defined VM_TRACE || defined ERROR_INSERT || defined NDBD_TRACENR
char *name;
+ FILE *out = 0;
#endif
switch (tstartPhase) {
case ZSTART_PHASE1:
@@ -480,8 +510,14 @@ void Dblqh::execSTTOR(Signal* signal)
sendsttorryLab(signal);
#if defined VM_TRACE || defined ERROR_INSERT || defined NDBD_TRACENR
- name = NdbConfig_SignalLogFileName(getOwnNodeId());
- tracenrout = new NdbOut(* new FileOutputStream(fopen(name, "w+")));
+#ifdef VM_TRACE
+ out = globalSignalLoggers.getOutputStream();
+#endif
+ if (out == 0) {
+ name = NdbConfig_SignalLogFileName(getOwnNodeId());
+ out = fopen(name, "a");
+ }
+ tracenrout = new NdbOut(* new FileOutputStream(out));
#endif
#ifdef ERROR_INSERT
@@ -15658,24 +15694,23 @@ void Dblqh::srFourthComp(Signal* signal)
} else if ((cstartType == NodeState::ST_NODE_RESTART) ||
(cstartType == NodeState::ST_SYSTEM_RESTART)) {
jam();
-
-
+ if(cstartType == NodeState::ST_SYSTEM_RESTART)
+ {
+ jam();
+ if (c_redo_complete_fragments.first(fragptr))
+ {
+ jam();
+ signal->theData[0] = ZENABLE_EXPAND_CHECK;
+ signal->theData[1] = fragptr.i;
+ sendSignal(DBLQH_REF, GSN_CONTINUEB, signal, 2, JBB);
+ return;
+ }
+ }
StartRecConf * conf = (StartRecConf*)signal->getDataPtrSend();
conf->startingNodeId = getOwnNodeId();
sendSignal(cmasterDihBlockref, GSN_START_RECCONF, signal,
- StartRecConf::SignalLength, JBB);
-
- if(cstartType == NodeState::ST_SYSTEM_RESTART){
- c_redo_complete_fragments.first(fragptr);
- while(fragptr.i != RNIL){
- signal->theData[0] = fragptr.p->tabRef;
- signal->theData[1] = fragptr.p->fragId;
- sendSignal(DBACC_REF, GSN_EXPANDCHECK2, signal, 2, JBB);
- c_redo_complete_fragments.next(fragptr);
- }
- c_redo_complete_fragments.remove();
- }
+ StartRecConf::SignalLength, JBB);
} else {
ndbrequire(false);
}//if
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index 9bc916c8c22..3cf62fe08ec 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -604,6 +604,7 @@ struct Fragrecord {
Uint32 currentPageRange;
Uint32 rootPageRange;
Uint32 noOfPages;
+ Uint32 noOfVarPages;
Uint32 noOfPagesToGrow;
DLList<Page>::Head emptyPrimPage; // allocated pages (not init)
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
index 90fdd8c69d7..82bac432545 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp
@@ -351,6 +351,7 @@ void Dbtup::initFragRange(Fragrecord* const regFragPtr)
regFragPtr->rootPageRange = RNIL;
regFragPtr->currentPageRange = RNIL;
regFragPtr->noOfPages = 0;
+ regFragPtr->noOfVarPages = 0;
regFragPtr->noOfPagesToGrow = 2;
regFragPtr->nextStartRange = 0;
}//initFragRange()
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
index 940ccf54ba7..677eff53559 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
@@ -1135,13 +1135,20 @@ Dbtup::read_pseudo(Uint32 attrId,
case AttributeHeader::FRAGMENT:
* outBuffer = fragptr.p->fragmentId;
return 1;
- case AttributeHeader::FRAGMENT_MEMORY:
- {
- Uint64 tmp= fragptr.p->noOfPages;
- tmp*= 32768;
- memcpy(outBuffer,&tmp,8);
- }
- return 2;
+ case AttributeHeader::FRAGMENT_FIXED_MEMORY:
+ {
+ Uint64 tmp= fragptr.p->noOfPages;
+ tmp*= 32768;
+ memcpy(outBuffer,&tmp,8);
+ }
+ return 2;
+ case AttributeHeader::FRAGMENT_VARSIZED_MEMORY:
+ {
+ Uint64 tmp= fragptr.p->noOfVarPages;
+ tmp*= 32768;
+ memcpy(outBuffer,&tmp,8);
+ }
+ return 2;
case AttributeHeader::ROW_SIZE:
* outBuffer = tabptr.p->m_offsets[MM].m_fix_header_size << 2;
return 1;
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
index 52ab66b5c0e..5f6dd68956a 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupVarAlloc.cpp
@@ -302,6 +302,7 @@ Dbtup::get_empty_var_page(Fragrecord* fragPtr)
Uint32 cnt;
allocConsPages(10, cnt, ptr.i);
+ fragPtr->noOfVarPages+= cnt;
if (unlikely(cnt == 0))
{
return RNIL;
diff --git a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
index 70c0fdfc988..de080237668 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/Qmgr.hpp
@@ -248,6 +248,7 @@ private:
void execAPI_FAILCONF(Signal* signal);
void execREAD_NODESREQ(Signal* signal);
void execSET_VAR_REQ(Signal* signal);
+ void execAPI_FAILREQ(Signal* signal);
void execREAD_NODESREF(Signal* signal);
void execREAD_NODESCONF(Signal* signal);
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
index 6ee24561b0a..8ec5e681045 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrInit.cpp
@@ -81,6 +81,7 @@ Qmgr::Qmgr(Block_context& ctx)
addRecSignal(GSN_API_REGREQ, &Qmgr::execAPI_REGREQ);
addRecSignal(GSN_API_VERSION_REQ, &Qmgr::execAPI_VERSION_REQ);
addRecSignal(GSN_DISCONNECT_REP, &Qmgr::execDISCONNECT_REP);
+ addRecSignal(GSN_API_FAILREQ, &Qmgr::execAPI_FAILREQ);
addRecSignal(GSN_API_FAILCONF, &Qmgr::execAPI_FAILCONF);
addRecSignal(GSN_READ_NODESREQ, &Qmgr::execREAD_NODESREQ);
addRecSignal(GSN_SET_VAR_REQ, &Qmgr::execSET_VAR_REQ);
diff --git a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
index 1eac369ec65..0da2de3b7a2 100644
--- a/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
+++ b/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp
@@ -438,6 +438,7 @@ void Qmgr::execCONNECT_REP(Signal* signal)
void
Qmgr::execREAD_NODESCONF(Signal* signal)
{
+ jamEntry();
check_readnodes_reply(signal,
refToNode(signal->getSendersBlockRef()),
GSN_READ_NODESCONF);
@@ -446,6 +447,7 @@ Qmgr::execREAD_NODESCONF(Signal* signal)
void
Qmgr::execREAD_NODESREF(Signal* signal)
{
+ jamEntry();
check_readnodes_reply(signal,
refToNode(signal->getSendersBlockRef()),
GSN_READ_NODESREF);
@@ -907,9 +909,9 @@ retry:
char buf[255];
BaseString::snprintf(buf, sizeof(buf),
- "Partitioned cluster! check StartPartialTimeout, "
- " node %d thinks %d is president, "
- " I think president is: %d",
+ "check StartPartialTimeout, "
+ "node %d thinks %d is president, "
+ "I think president is: %d",
nodeId, president, cpresident);
ndbout_c(buf);
@@ -941,7 +943,7 @@ retry:
CRASH_INSERTION(932);
progError(__LINE__,
- NDBD_EXIT_ARBIT_SHUTDOWN,
+ NDBD_EXIT_PARTITIONED_SHUTDOWN,
buf);
ndbrequire(false);
@@ -2338,6 +2340,8 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo)
ndbrequire(failedNodePtr.p->failState == NORMAL);
failedNodePtr.p->failState = WAITING_FOR_FAILCONF1;
+ NodeReceiverGroup rg(QMGR, c_clusterNodes);
+ sendSignal(rg, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(DBTC_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(DBDICT_REF, GSN_API_FAILREQ, signal, 2, JBA);
sendSignal(SUMA_REF, GSN_API_FAILREQ, signal, 2, JBA);
@@ -2361,6 +2365,27 @@ void Qmgr::sendApiFailReq(Signal* signal, Uint16 failedNodeNo)
CloseComReqConf::SignalLength, JBA);
}//Qmgr::sendApiFailReq()
+void Qmgr::execAPI_FAILREQ(Signal* signal)
+{
+ jamEntry();
+ NodeRecPtr failedNodePtr;
+ failedNodePtr.i = signal->theData[0];
+ // signal->theData[1] == QMGR_REF
+ ptrCheckGuard(failedNodePtr, MAX_NODES, nodeRec);
+
+ ndbrequire(getNodeInfo(failedNodePtr.i).getType() != NodeInfo::DB);
+
+ // ignore if api not active
+ if (failedNodePtr.p->phase != ZAPI_ACTIVE)
+ return;
+
+ signal->theData[0] = NDB_LE_Disconnected;
+ signal->theData[1] = failedNodePtr.i;
+ sendSignal(CMVMI_REF, GSN_EVENT_REP, signal, 2, JBB);
+
+ node_failed(signal, failedNodePtr.i);
+}
+
void Qmgr::execAPI_FAILCONF(Signal* signal)
{
NodeRecPtr failedNodePtr;
@@ -2798,7 +2823,7 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
break;
case FailRep::ZPARTITIONED_CLUSTER:
{
- code = NDBD_EXIT_ARBIT_SHUTDOWN;
+ code = NDBD_EXIT_PARTITIONED_SHUTDOWN;
char buf1[100], buf2[100];
c_clusterNodes.getText(buf1);
if (signal->getLength()== FailRep::SignalLength + FailRep::ExtraLength &&
@@ -2809,16 +2834,14 @@ void Qmgr::failReportLab(Signal* signal, Uint16 aFailedNode,
part.assign(NdbNodeBitmask::Size, rep->partition);
part.getText(buf2);
BaseString::snprintf(extra, sizeof(extra),
- "Partitioned cluster!"
- " Our cluster: %s other cluster: %s",
+ "Our cluster: %s other cluster: %s",
buf1, buf2);
}
else
{
jam();
BaseString::snprintf(extra, sizeof(extra),
- "Partitioned cluster!"
- " Our cluster: %s ", buf1);
+ "Our cluster: %s", buf1);
}
msg = extra;
break;
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.cpp b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
index 42666a9e5d9..2b746fdbdd8 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.cpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.cpp
@@ -1445,12 +1445,13 @@ Suma::initTable(Signal *signal, Uint32 tableId, TablePtr &tabPtr)
tabPtr.p->m_error = 0;
tabPtr.p->m_schemaVersion = RNIL;
tabPtr.p->m_state = Table::DEFINING;
- tabPtr.p->m_hasTriggerDefined[0] = 0;
- tabPtr.p->m_hasTriggerDefined[1] = 0;
- tabPtr.p->m_hasTriggerDefined[2] = 0;
- tabPtr.p->m_triggerIds[0] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->m_triggerIds[1] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->m_triggerIds[2] = ILLEGAL_TRIGGER_ID;
+ tabPtr.p->m_drop_subbPtr.p = 0;
+ for (int j= 0; j < 3; j++)
+ {
+ tabPtr.p->m_hasTriggerDefined[j] = 0;
+ tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
+ tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
+ }
c_tables.add(tabPtr);
@@ -2491,6 +2492,13 @@ Suma::execSUB_STOP_REQ(Signal* signal){
DBUG_VOID_RETURN;
}
+ if (tabPtr.p->m_drop_subbPtr.p != 0) {
+ jam();
+ DBUG_PRINT("error", ("table locked"));
+ sendSubStopRef(signal, 1420);
+ DBUG_VOID_RETURN;
+ }
+
DBUG_PRINT("info",("subscription: %u tableId: %u[i=%u] id: %u key: %u",
subPtr.i, subPtr.p->m_tableId, tabPtr.i,
subPtr.p->m_subscriptionId,subPtr.p->m_subscriptionKey));
@@ -2543,7 +2551,7 @@ Suma::execSUB_STOP_REQ(Signal* signal){
subPtr.p->m_senderRef = senderRef; // store ref to requestor
subPtr.p->m_senderData = senderData; // store ref to requestor
- tabPtr.p->m_drop_subbPtr= subbPtr;
+ tabPtr.p->m_drop_subbPtr = subbPtr;
if (subPtr.p->m_state == Subscription::DEFINED)
{
@@ -2560,6 +2568,7 @@ Suma::execSUB_STOP_REQ(Signal* signal){
tabPtr.p->m_tableId, tabPtr.p->n_subscribers));
tabPtr.p->checkRelease(*this);
sendSubStopComplete(signal, tabPtr.p->m_drop_subbPtr);
+ tabPtr.p->m_drop_subbPtr.p = 0;
}
else
{
@@ -2667,7 +2676,8 @@ Suma::reportAllSubscribers(Signal *signal,
{
SubTableData * data = (SubTableData*)signal->getDataPtrSend();
- if (table_event == NdbDictionary::Event::_TE_SUBSCRIBE)
+ if (table_event == NdbDictionary::Event::_TE_SUBSCRIBE &&
+ !c_startup.m_restart_server_node_id)
{
data->gci = m_last_complete_gci + 1;
data->tableId = subPtr.p->m_tableId;
@@ -2893,6 +2903,9 @@ Suma::Table::dropTrigger(Signal* signal,Suma& suma)
jam();
DBUG_ENTER("Suma::dropTrigger");
+ m_hasOutstandingTriggerReq[0] =
+ m_hasOutstandingTriggerReq[1] =
+ m_hasOutstandingTriggerReq[2] = 1;
for(Uint32 j = 0; j<3; j++){
jam();
suma.suma_ndbrequire(m_triggerIds[j] != ILLEGAL_TRIGGER_ID);
@@ -2971,14 +2984,18 @@ Suma::Table::runDropTrigger(Signal* signal,
suma.suma_ndbrequire(type < 3);
suma.suma_ndbrequire(m_triggerIds[type] == triggerId);
+ suma.suma_ndbrequire(m_hasTriggerDefined[type] > 0);
+ suma.suma_ndbrequire(m_hasOutstandingTriggerReq[type] == 1);
m_hasTriggerDefined[type]--;
+ m_hasOutstandingTriggerReq[type] = 0;
if (m_hasTriggerDefined[type] == 0)
{
jam();
m_triggerIds[type] = ILLEGAL_TRIGGER_ID;
}
- if( m_hasTriggerDefined[0] != m_hasTriggerDefined[1] ||
- m_hasTriggerDefined[0] != m_hasTriggerDefined[2])
+ if( m_hasOutstandingTriggerReq[0] ||
+ m_hasOutstandingTriggerReq[1] ||
+ m_hasOutstandingTriggerReq[2])
{
// more to come
jam();
@@ -2996,6 +3013,7 @@ Suma::Table::runDropTrigger(Signal* signal,
checkRelease(suma);
suma.sendSubStopComplete(signal, m_drop_subbPtr);
+ m_drop_subbPtr.p = 0;
}
void Suma::suma_ndbrequire(bool v) { ndbrequire(v); }
@@ -3550,13 +3568,17 @@ Suma::execDROP_TAB_CONF(Signal *signal)
DBUG_PRINT("info",("drop table id: %d[i=%u]", tableId, tabPtr.i));
tabPtr.p->m_state = Table::DROPPED;
- tabPtr.p->m_hasTriggerDefined[0] = 0;
- tabPtr.p->m_hasTriggerDefined[1] = 0;
- tabPtr.p->m_hasTriggerDefined[2] = 0;
- tabPtr.p->m_triggerIds[0] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->m_triggerIds[1] = ILLEGAL_TRIGGER_ID;
- tabPtr.p->m_triggerIds[2] = ILLEGAL_TRIGGER_ID;
-
+ for (int j= 0; j < 3; j++)
+ {
+ if (!tabPtr.p->m_hasOutstandingTriggerReq[j])
+ {
+ tabPtr.p->m_hasTriggerDefined[j] = 0;
+ tabPtr.p->m_hasOutstandingTriggerReq[j] = 0;
+ tabPtr.p->m_triggerIds[j] = ILLEGAL_TRIGGER_ID;
+ }
+ else
+ tabPtr.p->m_hasTriggerDefined[j] = 1;
+ }
if (senderRef == 0)
{
DBUG_VOID_RETURN;
diff --git a/storage/ndb/src/kernel/blocks/suma/Suma.hpp b/storage/ndb/src/kernel/blocks/suma/Suma.hpp
index 51f5fa4a8c8..4408d6aff8d 100644
--- a/storage/ndb/src/kernel/blocks/suma/Suma.hpp
+++ b/storage/ndb/src/kernel/blocks/suma/Suma.hpp
@@ -301,7 +301,8 @@ public:
union { Uint32 m_tableId; Uint32 key; };
Uint32 m_schemaVersion;
- Uint32 m_hasTriggerDefined[3]; // Insert/Update/Delete
+ Uint8 m_hasTriggerDefined[3]; // Insert/Update/Delete
+ Uint8 m_hasOutstandingTriggerReq[3]; // Insert/Update/Delete
Uint32 m_triggerIds[3]; // Insert/Update/Delete
Uint32 m_error;
diff --git a/storage/ndb/src/kernel/error/ndbd_exit_codes.c b/storage/ndb/src/kernel/error/ndbd_exit_codes.c
index 172125c35a1..2c32c31a15f 100644
--- a/storage/ndb/src/kernel/error/ndbd_exit_codes.c
+++ b/storage/ndb/src/kernel/error/ndbd_exit_codes.c
@@ -54,6 +54,8 @@ static const ErrStruct errArray[] =
{NDBD_EXIT_ARBIT_SHUTDOWN, XAE, "Node lost connection to other nodes and "
"can not form a unpartitioned cluster, please investigate if there are "
"error(s) on other node(s)"},
+ {NDBD_EXIT_PARTITIONED_SHUTDOWN, XAE, "Partitioned cluster detected. "
+ "Please check if cluster is already running"},
{NDBD_EXIT_POINTER_NOTINRANGE, XIE, "Pointer too large"},
{NDBD_EXIT_SR_OTHERNODEFAILED, XRE, "Another node failed during system "
"restart, please investigate error(s) on other node(s)"},
diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
index 1de47197867..4e01038d343 100644
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp
@@ -921,6 +921,15 @@ SimulatedBlock::execCONTINUE_FRAGMENTED(Signal * signal){
void
SimulatedBlock::execNODE_START_REP(Signal* signal)
{
+ // common stuff for all blocks
+
+ // block specific stuff by virtual method override (default empty)
+ exec_node_start_rep(signal);
+}
+
+void
+SimulatedBlock::exec_node_start_rep(Signal* signal)
+{
}
void
diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
index ab698f7826c..3e90b20705e 100644
--- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
+++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp
@@ -446,7 +446,8 @@ private:
void execCONTINUE_FRAGMENTED(Signal* signal);
void execAPI_START_REP(Signal* signal);
void execNODE_START_REP(Signal* signal);
-
+ virtual void exec_node_start_rep(Signal* signal);
+
Uint32 c_fragmentIdCounter;
ArrayPool<FragmentInfo> c_fragmentInfoPool;
DLHashTable<FragmentInfo> c_fragmentInfoHash;
diff --git a/storage/ndb/src/ndbapi/ClusterMgr.cpp b/storage/ndb/src/ndbapi/ClusterMgr.cpp
index 63fdb73c49f..49815ae6c13 100644
--- a/storage/ndb/src/ndbapi/ClusterMgr.cpp
+++ b/storage/ndb/src/ndbapi/ClusterMgr.cpp
@@ -396,6 +396,8 @@ ClusterMgr::execNF_COMPLETEREP(const Uint32 * theData){
void
ClusterMgr::reportConnected(NodeId nodeId){
+ DBUG_ENTER("ClusterMgr::reportConnected");
+ DBUG_PRINT("info", ("nodeId: %u", nodeId));
/**
* Ensure that we are sending heartbeat every 100 ms
* until we have got the first reply from NDB providing
@@ -421,6 +423,7 @@ ClusterMgr::reportConnected(NodeId nodeId){
theNode.nfCompleteRep = true;
theFacade.ReportNodeAlive(nodeId);
+ DBUG_VOID_RETURN;
}
void
diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp
index 8a0bf2f8e8b..c06bb6fc62a 100644
--- a/storage/ndb/src/ndbapi/DictCache.cpp
+++ b/storage/ndb/src/ndbapi/DictCache.cpp
@@ -312,12 +312,15 @@ GlobalDictCache::invalidate_all()
if (vers->size())
{
TableVersion * ver = & vers->back();
- ver->m_impl->m_status = NdbDictionary::Object::Invalid;
- ver->m_status = DROPPED;
- if (ver->m_refCount == 0)
+ if (ver->m_status != RETREIVING)
{
- delete ver->m_impl;
- vers->erase(vers->size() - 1);
+ ver->m_impl->m_status = NdbDictionary::Object::Invalid;
+ ver->m_status = DROPPED;
+ if (ver->m_refCount == 0)
+ {
+ delete ver->m_impl;
+ vers->erase(vers->size() - 1);
+ }
}
}
curr = m_tableHash.getNext(curr);
diff --git a/storage/ndb/src/ndbapi/Ndb.cpp b/storage/ndb/src/ndbapi/Ndb.cpp
index 5b0a9e9d330..5eddbc35665 100644
--- a/storage/ndb/src/ndbapi/Ndb.cpp
+++ b/storage/ndb/src/ndbapi/Ndb.cpp
@@ -1025,14 +1025,19 @@ int Ndb::initAutoIncrement()
setDatabaseName("sys");
setDatabaseSchemaName("def");
- m_sys_tab_0 = getDictionary()->getTableGlobal("SYSTAB_0");
+ m_sys_tab_0 = theDictionary->getTableGlobal("SYSTAB_0");
// Restore current name space
setDatabaseName(currentDb.c_str());
setDatabaseSchemaName(currentSchema.c_str());
+ if (m_sys_tab_0 == NULL) {
+ assert(theDictionary->m_error.code != 0);
+ theError.code = theDictionary->m_error.code;
+ return -1;
+ }
- return (m_sys_tab_0 == NULL);
+ return 0;
}
int
@@ -1043,19 +1048,19 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
Uint32 aTableId = table->m_id;
DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op));
- NdbTransaction* tConnection;
- NdbOperation* tOperation= 0; // Compiler warning if not initialized
+ NdbTransaction* tConnection = NULL;
+ NdbOperation* tOperation = NULL;
Uint64 tValue;
NdbRecAttr* tRecAttrResult;
- CHECK_STATUS_MACRO_ZERO;
+ CHECK_STATUS_MACRO;
- if (initAutoIncrement())
- goto error_return;
+ if (initAutoIncrement() == -1)
+ goto error_handler;
tConnection = this->startTransaction();
if (tConnection == NULL)
- goto error_return;
+ goto error_handler;
tOperation = tConnection->getNdbOperation(m_sys_tab_0);
if (tOperation == NULL)
@@ -1065,7 +1070,7 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
{
case 0:
tOperation->interpretedUpdateTuple();
- tOperation->equal("SYSKEY_0", aTableId );
+ tOperation->equal("SYSKEY_0", aTableId);
tOperation->incValue("NEXTID", opValue);
tRecAttrResult = tOperation->getValue("NEXTID");
@@ -1130,14 +1135,21 @@ Ndb::opTupleIdOnNdb(const NdbTableImpl* table,
DBUG_RETURN(0);
- error_handler:
- theError.code = tConnection->theError.code;
- this->closeTransaction(tConnection);
- error_return:
+error_handler:
DBUG_PRINT("error", ("ndb=%d con=%d op=%d",
theError.code,
- tConnection ? tConnection->theError.code : -1,
- tOperation ? tOperation->theError.code : -1));
+ tConnection != NULL ? tConnection->theError.code : -1,
+ tOperation != NULL ? tOperation->theError.code : -1));
+
+ if (theError.code == 0 && tConnection != NULL)
+ theError.code = tConnection->theError.code;
+ if (theError.code == 0 && tOperation != NULL)
+ theError.code = tOperation->theError.code;
+ DBUG_ASSERT(theError.code != 0);
+
+ if (tConnection != NULL)
+ this->closeTransaction(tConnection);
+
DBUG_RETURN(-1);
}
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 1e33a843a42..b9c03f0b209 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -328,9 +328,14 @@ NdbColumnImpl::create_pseudo(const char * name){
col->m_impl.m_attrId = AttributeHeader::FRAGMENT;
col->m_impl.m_attrSize = 4;
col->m_impl.m_arraySize = 1;
- } else if(!strcmp(name, "NDB$FRAGMENT_MEMORY")){
+ } else if(!strcmp(name, "NDB$FRAGMENT_FIXED_MEMORY")){
col->setType(NdbDictionary::Column::Bigunsigned);
- col->m_impl.m_attrId = AttributeHeader::FRAGMENT_MEMORY;
+ col->m_impl.m_attrId = AttributeHeader::FRAGMENT_FIXED_MEMORY;
+ col->m_impl.m_attrSize = 8;
+ col->m_impl.m_arraySize = 1;
+ } else if(!strcmp(name, "NDB$FRAGMENT_VARSIZED_MEMORY")){
+ col->setType(NdbDictionary::Column::Bigunsigned);
+ col->m_impl.m_attrId = AttributeHeader::FRAGMENT_VARSIZED_MEMORY;
col->m_impl.m_attrSize = 8;
col->m_impl.m_arraySize = 1;
} else if(!strcmp(name, "NDB$ROW_COUNT")){
@@ -1316,7 +1321,8 @@ NdbDictionaryImpl::~NdbDictionaryImpl()
m_globalHash->lock();
if(--f_dictionary_count == 0){
delete NdbDictionary::Column::FRAGMENT;
- delete NdbDictionary::Column::FRAGMENT_MEMORY;
+ delete NdbDictionary::Column::FRAGMENT_FIXED_MEMORY;
+ delete NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY;
delete NdbDictionary::Column::ROW_COUNT;
delete NdbDictionary::Column::COMMIT_COUNT;
delete NdbDictionary::Column::ROW_SIZE;
@@ -1326,7 +1332,8 @@ NdbDictionaryImpl::~NdbDictionaryImpl()
delete NdbDictionary::Column::ROWID;
delete NdbDictionary::Column::ROW_GCI;
NdbDictionary::Column::FRAGMENT= 0;
- NdbDictionary::Column::FRAGMENT_MEMORY= 0;
+ NdbDictionary::Column::FRAGMENT_FIXED_MEMORY= 0;
+ NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY= 0;
NdbDictionary::Column::ROW_COUNT= 0;
NdbDictionary::Column::COMMIT_COUNT= 0;
NdbDictionary::Column::ROW_SIZE= 0;
@@ -1483,8 +1490,10 @@ NdbDictionaryImpl::setTransporter(class Ndb* ndb,
if(f_dictionary_count++ == 0){
NdbDictionary::Column::FRAGMENT=
NdbColumnImpl::create_pseudo("NDB$FRAGMENT");
- NdbDictionary::Column::FRAGMENT_MEMORY=
- NdbColumnImpl::create_pseudo("NDB$FRAGMENT_MEMORY");
+ NdbDictionary::Column::FRAGMENT_FIXED_MEMORY=
+ NdbColumnImpl::create_pseudo("NDB$FRAGMENT_FIXED_MEMORY");
+ NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY=
+ NdbColumnImpl::create_pseudo("NDB$FRAGMENT_VARSIZED_MEMORY");
NdbDictionary::Column::ROW_COUNT=
NdbColumnImpl::create_pseudo("NDB$ROW_COUNT");
NdbDictionary::Column::COMMIT_COUNT=
@@ -5041,7 +5050,8 @@ template class Vector<NdbTableImpl*>;
template class Vector<NdbColumnImpl*>;
const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT = 0;
-const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_MEMORY = 0;
+const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_FIXED_MEMORY = 0;
+const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY = 0;
const NdbDictionary::Column * NdbDictionary::Column::ROW_COUNT = 0;
const NdbDictionary::Column * NdbDictionary::Column::COMMIT_COUNT = 0;
const NdbDictionary::Column * NdbDictionary::Column::ROW_SIZE = 0;
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
index 6f096046440..06b0d7ea5b9 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp
@@ -942,6 +942,7 @@ NdbEventBuffer::NdbEventBuffer(Ndb *ndb) :
{
#ifdef VM_TRACE
m_latest_command= "NdbEventBuffer::NdbEventBuffer";
+ m_flush_gci = 0;
#endif
if ((p_cond = NdbCondition_Create()) == NULL) {
@@ -1109,6 +1110,8 @@ NdbEventBuffer::flushIncompleteEvents(Uint64 gci)
/**
* Find min complete gci
*/
+ // called by user thread, so we need to lock the data
+ lock();
Uint32 i;
Uint32 sz= m_active_gci.size();
Gci_container* array = (Gci_container*)m_active_gci.getBase();
@@ -1127,6 +1130,10 @@ NdbEventBuffer::flushIncompleteEvents(Uint64 gci)
bzero(tmp, sizeof(Gci_container));
}
}
+#ifdef VM_TRACE
+ m_flush_gci = gci;
+#endif
+ unlock();
return 0;
}
@@ -1301,7 +1308,11 @@ operator<<(NdbOut& out, const Gci_container_pod& gci)
static
Gci_container*
-find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci)
+find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci
+#ifdef VM_TRACE
+ ,Uint64 flush_gci
+#endif
+ )
{
Uint32 pos = (gci & ACTIVE_GCI_MASK);
Gci_container *bucket= ((Gci_container*)active->getBase()) + pos;
@@ -1322,6 +1333,13 @@ find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci)
bzero(bucket, sizeof(Gci_container));
bucket->m_gci = gci;
bucket->m_gcp_complete_rep_count = ~(Uint32)0;
+#ifdef VM_TRACE
+ if (gci < flush_gci)
+ {
+ ndbout_c("received old gci %llu < flush gci %llu", gci, flush_gci);
+ assert(false);
+ }
+#endif
return bucket;
}
move_pos += ACTIVE_GCI_DIRECTORY_SIZE;
@@ -1336,7 +1354,16 @@ find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci)
bucket += ACTIVE_GCI_DIRECTORY_SIZE;
if(bucket->m_gci == gci)
+ {
+#ifdef VM_TRACE
+ if (gci < flush_gci)
+ {
+ ndbout_c("received old gci %llu < flush gci %llu", gci, flush_gci);
+ assert(false);
+ }
+#endif
return bucket;
+ }
} while(pos < size);
@@ -1346,14 +1373,22 @@ find_bucket_chained(Vector<Gci_container_pod> * active, Uint64 gci)
inline
Gci_container*
-find_bucket(Vector<Gci_container_pod> * active, Uint64 gci)
+find_bucket(Vector<Gci_container_pod> * active, Uint64 gci
+#ifdef VM_TRACE
+ ,Uint64 flush_gci
+#endif
+ )
{
Uint32 pos = (gci & ACTIVE_GCI_MASK);
Gci_container *bucket= ((Gci_container*)active->getBase()) + pos;
if(likely(gci == bucket->m_gci))
return bucket;
- return find_bucket_chained(active,gci);
+ return find_bucket_chained(active,gci
+#ifdef VM_TRACE
+ , flush_gci
+#endif
+ );
}
static
@@ -1386,7 +1421,11 @@ NdbEventBuffer::execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep)
const Uint64 gci= rep->gci;
const Uint32 cnt= rep->gcp_complete_rep_count;
- Gci_container *bucket = find_bucket(&m_active_gci, gci);
+ Gci_container *bucket = find_bucket(&m_active_gci, gci
+#ifdef VM_TRACE
+ , m_flush_gci
+#endif
+ );
if (unlikely(bucket == 0))
{
@@ -1522,6 +1561,46 @@ NdbEventBuffer::complete_outof_order_gcis()
}
void
+NdbEventBuffer::report_node_connected(Uint32 node_id)
+{
+ NdbEventOperation* op= m_ndb->getEventOperation(0);
+ if (op == 0)
+ return;
+
+ DBUG_ENTER("NdbEventBuffer::report_node_connected");
+ SubTableData data;
+ LinearSectionPtr ptr[3];
+ bzero(&data, sizeof(data));
+ bzero(ptr, sizeof(ptr));
+
+ data.tableId = ~0;
+ data.operation = NdbDictionary::Event::_TE_ACTIVE;
+ data.req_nodeid = (Uint8)node_id;
+ data.ndbd_nodeid = (Uint8)node_id;
+ data.logType = SubTableData::LOG;
+ data.gci = m_latestGCI + 1;
+ /**
+ * Insert this event for each operation
+ */
+ {
+ // no need to lock()/unlock(), receive thread calls this
+ NdbEventOperationImpl* impl = &op->m_impl;
+ do if (!impl->m_node_bit_mask.isclear())
+ {
+ data.senderData = impl->m_oid;
+ insertDataL(impl, &data, ptr);
+ } while((impl = impl->m_next));
+ for (impl = m_dropped_ev_op; impl; impl = impl->m_next)
+ if (!impl->m_node_bit_mask.isclear())
+ {
+ data.senderData = impl->m_oid;
+ insertDataL(impl, &data, ptr);
+ }
+ }
+ DBUG_VOID_RETURN;
+}
+
+void
NdbEventBuffer::report_node_failure(Uint32 node_id)
{
NdbEventOperation* op= m_ndb->getEventOperation(0);
@@ -1579,6 +1658,10 @@ NdbEventBuffer::completeClusterFailed()
data.logType = SubTableData::LOG;
data.gci = m_latestGCI + 1;
+#ifdef VM_TRACE
+ m_flush_gci = 0;
+#endif
+
/**
* Insert this event for each operation
*/
@@ -1712,7 +1795,11 @@ NdbEventBuffer::insertDataL(NdbEventOperationImpl *op,
if ( likely((Uint32)op->mi_type & (1 << (Uint32)sdata->operation)) )
{
- Gci_container* bucket= find_bucket(&m_active_gci, gci);
+ Gci_container* bucket= find_bucket(&m_active_gci, gci
+#ifdef VM_TRACE
+ , m_flush_gci
+#endif
+ );
DBUG_PRINT_EVENT("info", ("data insertion in eventId %d", op->m_eventId));
DBUG_PRINT_EVENT("info", ("gci=%d tab=%d op=%d node=%d",
diff --git a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
index c14ca83128f..561e79a137e 100644
--- a/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp
@@ -422,6 +422,7 @@ public:
void execSUB_GCP_COMPLETE_REP(const SubGcpCompleteRep * const rep);
void complete_outof_order_gcis();
+ void report_node_connected(Uint32 node_id);
void report_node_failure(Uint32 node_id);
void completeClusterFailed();
@@ -462,6 +463,7 @@ public:
#ifdef VM_TRACE
const char *m_latest_command;
+ Uint64 m_flush_gci;
#endif
Ndb *m_ndb;
diff --git a/storage/ndb/src/ndbapi/NdbScanOperation.cpp b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
index 5852570a686..21caf8349b6 100644
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -1574,62 +1574,6 @@ NdbScanOperation::close_impl(TransporterFacade* tp, bool forceSend,
return -1;
}
- bool holdLock = false;
- if (theSCAN_TABREQ)
- {
- ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
- holdLock = ScanTabReq::getHoldLockFlag(req->requestInfo);
- }
-
- /**
- * When using locks, force close of scan directly
- */
- if (holdLock && theError.code == 0 &&
- (m_sent_receivers_count + m_conf_receivers_count + m_api_receivers_count))
- {
- NdbApiSignal tSignal(theNdb->theMyRef);
- tSignal.setSignal(GSN_SCAN_NEXTREQ);
-
- Uint32* theData = tSignal.getDataPtrSend();
- Uint64 transId = theNdbCon->theTransactionId;
- theData[0] = theNdbCon->theTCConPtr;
- theData[1] = 1;
- theData[2] = transId;
- theData[3] = (Uint32) (transId >> 32);
-
- tSignal.setLength(4);
- int ret = tp->sendSignal(&tSignal, nodeId);
- if (ret)
- {
- setErrorCode(4008);
- return -1;
- }
-
- /**
- * If no receiver is outstanding...
- * set it to 1 as execCLOSE_SCAN_REP resets it
- */
- m_sent_receivers_count = m_sent_receivers_count ? m_sent_receivers_count : 1;
-
- while(theError.code == 0 && (m_sent_receivers_count + m_conf_receivers_count))
- {
- int return_code = poll_guard->wait_scan(WAITFOR_SCAN_TIMEOUT, nodeId, forceSend);
- switch(return_code){
- case 0:
- break;
- case -1:
- setErrorCode(4008);
- case -2:
- m_api_receivers_count = 0;
- m_conf_receivers_count = 0;
- m_sent_receivers_count = 0;
- theNdbCon->theReleaseOnClose = true;
- return -1;
- }
- }
- return 0;
- }
-
/**
* Wait for outstanding
*/
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
index ecaf6a3f435..0527744afe1 100644
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp
@@ -177,6 +177,7 @@ Ndb::executeMessage(void* NdbObject,
void Ndb::connected(Uint32 ref)
{
+// cluster connect, a_node == own reference
theMyRef= ref;
Uint32 tmpTheNode= refToNode(ref);
Uint64 tBlockNo= refToBlock(ref);
@@ -209,16 +210,30 @@ void Ndb::connected(Uint32 ref)
theNode= tmpTheNode; // flag that Ndb object is initialized
}
+void Ndb::report_node_connected(Uint32 nodeId)
+{
+ if (theEventBuffer)
+ {
+ // node connected
+ // eventOperations in the ndb object should be notified
+ theEventBuffer->report_node_connected(nodeId);
+ }
+}
+
void
Ndb::statusMessage(void* NdbObject, Uint32 a_node, bool alive, bool nfComplete)
{
DBUG_ENTER("Ndb::statusMessage");
+ DBUG_PRINT("info", ("a_node: %u alive: %u nfComplete: %u",
+ a_node, alive, nfComplete));
Ndb* tNdb = (Ndb*)NdbObject;
if (alive) {
if (nfComplete) {
+ // cluster connect, a_node == own reference
tNdb->connected(a_node);
DBUG_VOID_RETURN;
}//if
+ tNdb->report_node_connected(a_node);
} else {
if (nfComplete) {
tNdb->report_node_failure_completed(a_node);
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp
index 15127953051..2f421271e91 100644
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp
@@ -794,6 +794,8 @@ TransporterFacade::connected()
void
TransporterFacade::ReportNodeDead(NodeId tNodeId)
{
+ DBUG_ENTER("TransporterFacade::ReportNodeDead");
+ DBUG_PRINT("enter",("nodeid= %d", tNodeId));
/**
* When a node fails we must report this to each Ndb object.
* The function that is used for communicating node failures is called.
@@ -810,6 +812,7 @@ TransporterFacade::ReportNodeDead(NodeId tNodeId)
(*RegPC) (obj, tNodeId, false, false);
}
}
+ DBUG_VOID_RETURN;
}
void
diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c
index 486d78538f0..d0d26c19cfa 100644
--- a/storage/ndb/src/ndbapi/ndberror.c
+++ b/storage/ndb/src/ndbapi/ndberror.c
@@ -484,6 +484,8 @@ ErrorBundle ErrorCodes[] = {
{ 1418, DMEC, SE, "Subscription dropped, no new subscribers allowed" },
{ 1419, DMEC, SE, "Subscription already dropped" },
+ { 1420, DMEC, TR, "Subscriber manager busy with adding/removing a table" },
+
{ 4004, DMEC, AE, "Attribute name not found in the Table" },
{ 4100, DMEC, AE, "Status Error in NDB" },
diff --git a/storage/ndb/test/ndbapi/testNodeRestart.cpp b/storage/ndb/test/ndbapi/testNodeRestart.cpp
index 5474837228a..ad1ea5ed6f2 100644
--- a/storage/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/storage/ndb/test/ndbapi/testNodeRestart.cpp
@@ -294,6 +294,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
}
i++;
}
+ ctx->stopTest();
return result;
}
diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt
index 8d893f11288..68e653b1ead 100644
--- a/storage/ndb/test/run-test/daily-basic-tests.txt
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt
@@ -531,6 +531,10 @@ max-time: 1500
cmd: testDict
args: -n TemporaryTables T1 T6 T7 T8
+max-time: 1500
+cmd: testDict
+args: -n Restart_NR2 T1
+
#
# TEST NDBAPI
#
diff --git a/storage/ndb/tools/desc.cpp b/storage/ndb/tools/desc.cpp
index 7c5ce68c950..49f188d12c0 100644
--- a/storage/ndb/tools/desc.cpp
+++ b/storage/ndb/tools/desc.cpp
@@ -293,7 +293,8 @@ void print_part_info(Ndb* pNdb, NDBT_Table* pTab)
{ "Partition", 0, NdbDictionary::Column::FRAGMENT },
{ "Row count", 0, NdbDictionary::Column::ROW_COUNT },
{ "Commit count", 0, NdbDictionary::Column::COMMIT_COUNT },
- { "Frag memory", 0, NdbDictionary::Column::FRAGMENT_MEMORY },
+ { "Frag fixed memory", 0, NdbDictionary::Column::FRAGMENT_FIXED_MEMORY },
+ { "Frag varsized memory", 0, NdbDictionary::Column::FRAGMENT_VARSIZED_MEMORY },
{ 0, 0, 0 }
};
diff --git a/storage/ndb/tools/restore/consumer_restore.cpp b/storage/ndb/tools/restore/consumer_restore.cpp
index b190652232e..6f9b025222c 100644
--- a/storage/ndb/tools/restore/consumer_restore.cpp
+++ b/storage/ndb/tools/restore/consumer_restore.cpp
@@ -148,17 +148,38 @@ BackupRestore::finalize_table(const TableS & table){
bool ret= true;
if (!m_restore && !m_restore_meta)
return ret;
- if (table.have_auto_inc())
+ if (!table.have_auto_inc())
+ return ret;
+
+ Uint64 max_val= table.get_max_auto_val();
+ do
{
- Uint64 max_val= table.get_max_auto_val();
- Uint64 auto_val;
+ Uint64 auto_val = ~(Uint64)0;
int r= m_ndb->readAutoIncrementValue(get_table(table.m_dictTable), auto_val);
- if (r == -1 && m_ndb->getNdbError().code != 626)
+ if (r == -1 && m_ndb->getNdbError().status == NdbError::TemporaryError)
+ {
+ NdbSleep_MilliSleep(50);
+ continue; // retry
+ }
+ else if (r == -1 && m_ndb->getNdbError().code != 626)
+ {
ret= false;
- else if (r == -1 || max_val+1 > auto_val)
- ret= m_ndb->setAutoIncrementValue(get_table(table.m_dictTable), max_val+1, false) != -1;
- }
- return ret;
+ }
+ else if ((r == -1 && m_ndb->getNdbError().code == 626) ||
+ max_val+1 > auto_val || auto_val == ~(Uint64)0)
+ {
+ r= m_ndb->setAutoIncrementValue(get_table(table.m_dictTable),
+ max_val+1, false);
+ if (r == -1 &&
+ m_ndb->getNdbError().status == NdbError::TemporaryError)
+ {
+ NdbSleep_MilliSleep(50);
+ continue; // retry
+ }
+ ret = (r == 0);
+ }
+ return (ret);
+ } while (1);
}
@@ -792,8 +813,6 @@ BackupRestore::table(const TableS & table){
}
info << "Successfully restored table event " << event_name << endl ;
}
-
- m_ndb->setAutoIncrementValue(tab, ~(Uint64)0, false);
}
const NdbDictionary::Table* null = 0;
m_new_tables.fill(table.m_dictTable->getTableId(), null);