summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorunknown <tomas@poseidon.>2006-12-27 11:01:54 +0100
committerunknown <tomas@poseidon.>2006-12-27 11:01:54 +0100
commite5dd5e063a2b291b0169e1efb3be05dcaef36fc7 (patch)
tree694a692ab769c1326162c8eb2bebed6dd273cd52 /storage
parentfcbfb41f30d794a14241070a44bba841ea0417d7 (diff)
parentb2f62764c6257c166d6b5f84b0cd39a3aefcca16 (diff)
downloadmariadb-git-e5dd5e063a2b291b0169e1efb3be05dcaef36fc7.tar.gz
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.1
into poseidon.:/home/tomas/mysql-5.1-new-ndb include/my_base.h: Auto merged mysql-test/Makefile.am: Auto merged mysql-test/r/ndb_dd_ddl.result: Auto merged mysql-test/t/disabled.def: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/ha_ndbcluster.h: Auto merged sql/handler.h: Auto merged sql/item_func.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_yacc.yy: Auto merged storage/ndb/include/kernel/signaldata/BackupContinueB.hpp: Auto merged storage/ndb/src/common/util/File.cpp: Auto merged storage/ndb/src/common/util/InputStream.cpp: Auto merged storage/ndb/src/common/util/socket_io.cpp: Auto merged storage/ndb/src/kernel/blocks/backup/Backup.cpp: Auto merged storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp: Auto merged storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp: Auto merged storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp: Auto merged storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Auto merged storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp: Auto merged storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp: Auto merged storage/ndb/src/kernel/vm/SimulatedBlock.cpp: Auto merged storage/ndb/src/mgmsrv/ConfigInfo.cpp: Auto merged storage/ndb/src/mgmsrv/MgmtSrvr.cpp: Auto merged storage/ndb/src/mgmsrv/Services.cpp: Auto merged storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp: Auto merged storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp: Auto merged storage/ndb/src/ndbapi/NdbTransaction.cpp: Auto merged storage/ndb/src/ndbapi/Ndbif.cpp: Auto merged storage/ndb/src/ndbapi/TransporterFacade.cpp: Auto merged storage/ndb/src/ndbapi/ndberror.c: Auto merged storage/ndb/test/ndbapi/testBasic.cpp: Auto merged storage/ndb/test/ndbapi/testIndex.cpp: Auto merged storage/ndb/test/ndbapi/testSystemRestart.cpp: Auto merged storage/ndb/tools/ndb_condig.cpp: Auto merged sql/sql_plugin.cc: manual merge
Diffstat (limited to 'storage')
-rw-r--r--storage/ndb/include/kernel/signaldata/BackupContinueB.hpp3
-rw-r--r--storage/ndb/include/kernel/signaldata/Extent.hpp2
-rw-r--r--storage/ndb/include/mgmapi/mgmapi_config_parameters.h2
-rw-r--r--storage/ndb/ndbapi-examples/Makefile2
-rw-r--r--storage/ndb/ndbapi-examples/mgmapi_logevent2/Makefile (renamed from storage/ndb/ndbapi-examples/mgmapi_logevent_dual/Makefile)2
-rw-r--r--storage/ndb/ndbapi-examples/mgmapi_logevent2/mgmapi_logevent2.cpp (renamed from storage/ndb/ndbapi-examples/mgmapi_logevent_dual/mgmapi_logevent_dual.cpp)0
-rw-r--r--storage/ndb/src/kernel/blocks/ERROR_codes.txt5
-rw-r--r--storage/ndb/src/kernel/blocks/backup/Backup.cpp35
-rw-r--r--storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp28
-rw-r--r--storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp2
-rw-r--r--storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp2
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp7
-rw-r--r--storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp17
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp46
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp54
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp156
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp6
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp28
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp231
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp1
-rw-r--r--storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp40
-rw-r--r--storage/ndb/src/kernel/blocks/diskpage.hpp5
-rw-r--r--storage/ndb/src/kernel/blocks/lgman.cpp17
-rw-r--r--storage/ndb/src/kernel/blocks/print_file.cpp48
-rw-r--r--storage/ndb/src/kernel/blocks/tsman.cpp172
-rw-r--r--storage/ndb/src/kernel/blocks/tsman.hpp54
-rw-r--r--storage/ndb/src/mgmsrv/ConfigInfo.cpp12
-rw-r--r--storage/ndb/src/mgmsrv/MgmtSrvr.cpp2
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp17
-rw-r--r--storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp2
-rw-r--r--storage/ndb/src/ndbapi/NdbTransaction.cpp9
-rw-r--r--storage/ndb/src/ndbapi/Ndbif.cpp5
-rw-r--r--storage/ndb/src/ndbapi/TransporterFacade.cpp8
-rw-r--r--storage/ndb/test/ndbapi/testBasic.cpp33
-rw-r--r--storage/ndb/test/ndbapi/testIndex.cpp66
-rw-r--r--storage/ndb/test/ndbapi/testSystemRestart.cpp66
-rw-r--r--storage/ndb/test/run-test/daily-basic-tests.txt12
38 files changed, 948 insertions, 250 deletions
diff --git a/storage/ndb/include/kernel/signaldata/BackupContinueB.hpp b/storage/ndb/include/kernel/signaldata/BackupContinueB.hpp
index ff0e90d1fbd..d96173d6807 100644
--- a/storage/ndb/include/kernel/signaldata/BackupContinueB.hpp
+++ b/storage/ndb/include/kernel/signaldata/BackupContinueB.hpp
@@ -32,7 +32,8 @@ private:
BUFFER_FULL_FRAG_COMPLETE = 3,
BUFFER_FULL_META = 4,
BACKUP_FRAGMENT_INFO = 5,
- RESET_DISK_SPEED_COUNTER = 6
+ RESET_DISK_SPEED_COUNTER = 6,
+ ZDELAY_SCAN_NEXT = 7
};
};
diff --git a/storage/ndb/include/kernel/signaldata/Extent.hpp b/storage/ndb/include/kernel/signaldata/Extent.hpp
index 86f45163be5..ea31b0968aa 100644
--- a/storage/ndb/include/kernel/signaldata/Extent.hpp
+++ b/storage/ndb/include/kernel/signaldata/Extent.hpp
@@ -74,6 +74,8 @@ struct FreeExtentReq {
Local_key key;
Uint32 table_id;
Uint32 tablespace_id;
+ Uint32 lsn_hi;
+ Uint32 lsn_lo;
} request;
struct
{
diff --git a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h
index 70af187db77..8918ec3f225 100644
--- a/storage/ndb/include/mgmapi/mgmapi_config_parameters.h
+++ b/storage/ndb/include/mgmapi/mgmapi_config_parameters.h
@@ -96,6 +96,8 @@
#define CFG_DB_CHECKPOINT_SPEED 164
#define CFG_DB_CHECKPOINT_SPEED_SR 165
+#define CFG_DB_MEMREPORT_FREQUENCY 166
+
#define CFG_DB_SGA 198 /* super pool mem */
#define CFG_DB_DATA_MEM_2 199 /* used in special build in 5.1 */
diff --git a/storage/ndb/ndbapi-examples/Makefile b/storage/ndb/ndbapi-examples/Makefile
index 2a77cb20afe..6a48afccb48 100644
--- a/storage/ndb/ndbapi-examples/Makefile
+++ b/storage/ndb/ndbapi-examples/Makefile
@@ -7,7 +7,7 @@ BIN_DIRS := ndbapi_simple \
ndbapi_scan \
mgmapi_logevent \
ndbapi_simple_dual \
- mgmapi_logevent_dual
+ mgmapi_logevent2
bins: $(patsubst %, _bins_%, $(BIN_DIRS))
diff --git a/storage/ndb/ndbapi-examples/mgmapi_logevent_dual/Makefile b/storage/ndb/ndbapi-examples/mgmapi_logevent2/Makefile
index 4a80a9fe087..95b43b11f6b 100644
--- a/storage/ndb/ndbapi-examples/mgmapi_logevent_dual/Makefile
+++ b/storage/ndb/ndbapi-examples/mgmapi_logevent2/Makefile
@@ -1,4 +1,4 @@
-TARGET = mgmapi_logevent_dual
+TARGET = mgmapi_logevent2
SRCS = $(TARGET).cpp
OBJS = $(TARGET).o
CXX = g++
diff --git a/storage/ndb/ndbapi-examples/mgmapi_logevent_dual/mgmapi_logevent_dual.cpp b/storage/ndb/ndbapi-examples/mgmapi_logevent2/mgmapi_logevent2.cpp
index 2073ec540d7..2073ec540d7 100644
--- a/storage/ndb/ndbapi-examples/mgmapi_logevent_dual/mgmapi_logevent_dual.cpp
+++ b/storage/ndb/ndbapi-examples/mgmapi_logevent2/mgmapi_logevent2.cpp
diff --git a/storage/ndb/src/kernel/blocks/ERROR_codes.txt b/storage/ndb/src/kernel/blocks/ERROR_codes.txt
index 56b5b8e4bc8..83aa1183772 100644
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt
@@ -8,7 +8,7 @@ Next DBDICT 6007
Next DBDIH 7178
Next DBTC 8039
Next CMVMI 9000
-Next BACKUP 10036
+Next BACKUP 10038
Next DBUTIL 11002
Next DBTUX 12008
Next SUMA 13001
@@ -425,6 +425,9 @@ Backup Stuff:
10034: define backup reply error
10035: Fail to allocate buffers
+10036: Halt backup for table >= 2
+10037: Resume backup (from 10036)
+
11001: Send UTIL_SEQUENCE_REF (in master)
5028: Crash when receiving LQHKEYREQ (in non-master)
diff --git a/storage/ndb/src/kernel/blocks/backup/Backup.cpp b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
index 79970ce9723..aae64b4bb6c 100644
--- a/storage/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/storage/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -355,6 +355,25 @@ Backup::execCONTINUEB(Signal* signal)
GetTabInfoReq::SignalLength, JBB);
return;
}
+ case BackupContinueB::ZDELAY_SCAN_NEXT:
+ if (ERROR_INSERTED(10036))
+ {
+ jam();
+ sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal, 300,
+ signal->getLength());
+ return;
+ }
+ else
+ {
+ jam();
+ CLEAR_ERROR_INSERT_VALUE;
+ ndbout_c("Resuming backup");
+ memmove(signal->theData, signal->theData + 1,
+ 4*ScanFragNextReq::SignalLength);
+ sendSignal(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
+ ScanFragNextReq::SignalLength, JBB);
+ return ;
+ }
default:
ndbrequire(0);
}//switch
@@ -3924,6 +3943,22 @@ Backup::checkScan(Signal* signal, BackupFilePtr filePtr)
req->transId2 = (BACKUP << 20) + (getOwnNodeId() << 8);
req->batch_size_rows= 16;
req->batch_size_bytes= 0;
+
+ if (ERROR_INSERTED(10036) &&
+ filePtr.p->tableId >= 2 &&
+ filePtr.p->operation.noOfRecords > 0)
+ {
+ ndbout_c("halting backup for table %d fragment: %d after %d records",
+ filePtr.p->tableId,
+ filePtr.p->fragmentNo,
+ filePtr.p->operation.noOfRecords);
+ memmove(signal->theData+1, signal->theData,
+ 4*ScanFragNextReq::SignalLength);
+ signal->theData[0] = BackupContinueB::ZDELAY_SCAN_NEXT;
+ sendSignalWithDelay(BACKUP_REF, GSN_CONTINUEB, signal,
+ 300, 1+ScanFragNextReq::SignalLength);
+ return;
+ }
if(ERROR_INSERTED(10032))
sendSignalWithDelay(DBLQH_REF, GSN_SCAN_NEXTREQ, signal,
100, ScanFragNextReq::SignalLength);
diff --git a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
index 6474bb5b1a3..6337e252c0b 100644
--- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
+++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp
@@ -1099,6 +1099,7 @@ private:
};
Uint32 c_errorInsert3000_TableId;
+ Uint32 c_memusage_report_frequency;
};
#endif
diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index e83c06dc38f..bf2fa5b7584 100644
--- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -111,6 +111,7 @@ void Dbacc::execCONTINUEB(Signal* signal)
}
case ZREPORT_MEMORY_USAGE:{
jam();
+ Uint32 cnt = signal->theData[1];
static int c_currentMemUsed = 0;
int now = cpagesize ? (cnoOfAllocatedPages * 100)/cpagesize : 0;
const int thresholds[] = { 99, 90, 80, 0};
@@ -124,14 +125,22 @@ void Dbacc::execCONTINUEB(Signal* signal)
}
}
- if(now != c_currentMemUsed){
- reportMemoryUsage(signal, now > c_currentMemUsed ? 1 : -1);
+ if(now != c_currentMemUsed ||
+ (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency))
+ {
+ reportMemoryUsage(signal,
+ now > c_currentMemUsed ? 1 :
+ now < c_currentMemUsed ? -1 : 0);
+ cnt = 0;
+ c_currentMemUsed = now;
+ }
+ else
+ {
+ cnt ++;
}
-
- c_currentMemUsed = now;
-
signal->theData[0] = ZREPORT_MEMORY_USAGE;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);
+ signal->theData[1] = cnt;
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
return;
}
@@ -198,7 +207,8 @@ void Dbacc::execNDB_STTOR(Signal* signal)
csystemRestart = ZFALSE;
signal->theData[0] = ZREPORT_MEMORY_USAGE;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);
+ signal->theData[1] = 0;
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
break;
default:
jam();
@@ -352,6 +362,10 @@ void Dbacc::execREAD_CONFIG_REQ(Signal* signal)
initRecords();
ndbrestart1Lab(signal);
+ c_memusage_report_frequency = 0;
+ ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY,
+ &c_memusage_report_frequency);
+
tdata0 = 0;
initialiseRecordsLab(signal, ref, senderData);
return;
diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 87d9b7e631f..5f00f62da87 100644
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -478,7 +478,7 @@ Dbdict::packTableIntoPages(SimpleProperties::Writer & w,
CreateFragmentationReq::SignalLength);
ndbrequire(signal->theData[0] == 0);
Uint16 *data = (Uint16*)&signal->theData[25];
- Uint32 count = 2 + data[0] * data[1];
+ Uint32 count = 2 + (1 + data[0]) * data[1];
w.add(DictTabInfo::ReplicaDataLen, 2*count);
for (Uint32 i = 0; i < count; i++)
data[i] = htons(data[i]);
diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index a407280cf3d..af8f86b0d84 100644
--- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -6727,7 +6727,7 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ(Signal * signal)
FragmentstorePtr fragPtr;
ReplicaRecordPtr replicaPtr;
getFragstore(primTabPtr.p, fragNo, fragPtr);
- fragments[count++] = c_nextLogPart++;
+ fragments[count++] = fragPtr.p->m_log_part_id;
fragments[count++] = fragPtr.p->preferredPrimary;
for (replicaPtr.i = fragPtr.p->storedReplicas;
replicaPtr.i != RNIL;
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 35b78c1fb15..0be59fdf96b 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -11275,7 +11275,7 @@ void Dblqh::execLCP_PREPARE_REF(Signal* signal)
/**
* First fragment mean that last LCP is complete :-)
*/
- EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, signal->length());
+ EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
jamEntry();
}
@@ -11326,7 +11326,7 @@ void Dblqh::execLCP_PREPARE_CONF(Signal* signal)
/**
* First fragment mean that last LCP is complete :-)
*/
- EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, signal->length());
+ EXECUTE_DIRECT(TSMAN, GSN_LCP_FRAG_ORD, signal, signal->length());
jamEntry();
}
@@ -11610,6 +11610,9 @@ void Dblqh::completeLcpRoundLab(Signal* signal, Uint32 lcpId)
sendSignal(LGMAN_REF, GSN_END_LCP_REQ, signal,
EndLcpReq::SignalLength, JBB);
+ EXECUTE_DIRECT(TSMAN, GSN_END_LCP_REQ, signal, EndLcpReq::SignalLength);
+ jamEntry();
+
lcpPtr.i = 0;
ptrAss(lcpPtr, lcpRecord);
lcpPtr.p->m_outstanding = 3;
diff --git a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index 8a9242e9748..44f7954f00d 100644
--- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -5057,7 +5057,7 @@ void Dbtc::execLQHKEYREF(Signal* signal)
ptrAss(tcConnectptr, tcConnectRecord);
TcConnectRecord * const regTcPtr = tcConnectptr.p;
if (regTcPtr->tcConnectstate == OS_OPERATING) {
- apiConnectptr.i = regTcPtr->apiConnect;
+ Uint32 save = apiConnectptr.i = regTcPtr->apiConnect;
ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
ApiConnectRecord * const regApiPtr = apiConnectptr.p;
compare_transid1 = regApiPtr->transid[0] ^ lqhKeyRef->transId1;
@@ -5181,7 +5181,7 @@ void Dbtc::execLQHKEYREF(Signal* signal)
regApiPtr->lqhkeyreqrec--; // Compensate for extra during read
tcKeyRef->connectPtr = indexOp;
EXECUTE_DIRECT(DBTC, GSN_TCKEYREF, signal, TcKeyRef::SignalLength);
- apiConnectptr.i = regTcPtr->apiConnect;
+ apiConnectptr.i = save;
apiConnectptr.p = regApiPtr;
} else {
jam();
@@ -5206,6 +5206,8 @@ void Dbtc::execLQHKEYREF(Signal* signal)
jam();
sendtckeyconf(signal, 1);
regApiPtr->apiConnectstate = CS_CONNECTED;
+ regApiPtr->m_transaction_nodes.clear();
+ setApiConTimer(apiConnectptr.i, 0,__LINE__);
}
return;
} else if (regApiPtr->tckeyrec > 0 || regApiPtr->m_exec_flag) {
@@ -11863,17 +11865,6 @@ void Dbtc::execTCKEYREF(Signal* signal)
case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI):
case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): {
jam();
- // If we fail index access for a non-read operation during commit
- // we abort transaction
- if (commitFlg == 1) {
- jam();
- releaseIndexOperation(regApiPtr, indexOp);
- apiConnectptr.i = indexOp->connectionIndex;
- ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
- terrorCode = tcKeyRef->errorCode;
- abortErrorLab(signal);
- break;
- }
/**
* Increase count as it will be decreased below...
* (and the code is written to handle failing lookup on "real" table
diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
index 0ce7a2a03c2..408925e4103 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp
@@ -624,7 +624,8 @@ struct Fragrecord {
DLList<ScanOp>::Head m_scanList;
- bool m_undo_complete;
+ enum { UC_LCP = 1, UC_CREATE = 2 };
+ Uint32 m_undo_complete;
Uint32 m_tablespace_id;
Uint32 m_logfile_group_id;
Disk_alloc_info m_disk_alloc_info;
@@ -988,6 +989,9 @@ ArrayPool<TupTriggerData> c_triggerPool;
,UNDO_UPDATE = File_formats::Undofile::UNDO_TUP_UPDATE
,UNDO_FREE = File_formats::Undofile::UNDO_TUP_FREE
,UNDO_CREATE = File_formats::Undofile::UNDO_TUP_CREATE
+ ,UNDO_DROP = File_formats::Undofile::UNDO_TUP_DROP
+ ,UNDO_ALLOC_EXTENT = File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT
+ ,UNDO_FREE_EXTENT = File_formats::Undofile::UNDO_TUP_FREE_EXTENT
};
struct Alloc
@@ -1020,6 +1024,30 @@ ArrayPool<TupTriggerData> c_triggerPool;
Uint32 m_table;
Uint32 m_type_length; // 16 bit type, 16 bit length
};
+
+ struct Drop
+ {
+ Uint32 m_table;
+ Uint32 m_type_length; // 16 bit type, 16 bit length
+ };
+
+ struct AllocExtent
+ {
+ Uint32 m_table;
+ Uint32 m_fragment;
+ Uint32 m_page_no;
+ Uint32 m_file_no;
+ Uint32 m_type_length;
+ };
+
+ struct FreeExtent
+ {
+ Uint32 m_table;
+ Uint32 m_fragment;
+ Uint32 m_page_no;
+ Uint32 m_file_no;
+ Uint32 m_type_length;
+ };
};
Extent_info_pool c_extent_pool;
@@ -1419,7 +1447,7 @@ public:
int nr_delete(Signal*, Uint32, Uint32 fragPtr, const Local_key*, Uint32 gci);
void nr_delete_page_callback(Signal*, Uint32 op, Uint32 page);
- void nr_delete_logbuffer_callback(Signal*, Uint32 op, Uint32 page);
+ void nr_delete_log_buffer_callback(Signal*, Uint32 op, Uint32 page);
private:
BLOCK_DEFINES(Dbtup);
@@ -2344,9 +2372,10 @@ private:
Uint32 fragId);
- void releaseFragment(Signal* signal, Uint32 tableId);
+ void releaseFragment(Signal* signal, Uint32 tableId, Uint32);
void drop_fragment_free_var_pages(Signal*);
- void drop_fragment_free_exent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
+ void drop_fragment_free_extent(Signal*, TablerecPtr, FragrecordPtr, Uint32);
+ void drop_fragment_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
void drop_fragment_unmap_pages(Signal*, TablerecPtr, FragrecordPtr, Uint32);
void drop_fragment_unmap_page_callback(Signal* signal, Uint32, Uint32);
@@ -2570,6 +2599,7 @@ private:
// Trigger variables
Uint32 c_maxTriggersPerTable;
+ Uint32 c_memusage_report_frequency;
Uint32 c_errorInsert4000TableId;
Uint32 c_min_list_size[MAX_FREE_LIST + 1];
@@ -2629,6 +2659,9 @@ private:
void disk_page_commit_callback(Signal*, Uint32 opPtrI, Uint32 page_id);
void disk_page_log_buffer_callback(Signal*, Uint32 opPtrI, Uint32);
+
+ void disk_page_alloc_extent_log_buffer_callback(Signal*, Uint32, Uint32);
+ void disk_page_free_extent_log_buffer_callback(Signal*, Uint32, Uint32);
Uint64 disk_page_undo_alloc(Page*, const Local_key*,
Uint32 sz, Uint32 gci, Uint32 logfile_group_id);
@@ -2644,6 +2677,9 @@ private:
void undo_createtable_callback(Signal* signal, Uint32 opPtrI, Uint32 unused);
void undo_createtable_logsync_callback(Signal* signal, Uint32, Uint32);
+ void drop_table_log_buffer_callback(Signal*, Uint32, Uint32);
+ void drop_table_logsync_callback(Signal*, Uint32, Uint32);
+
void disk_page_set_dirty(Ptr<Page>);
void restart_setup_page(Disk_alloc_info&, Ptr<Page>);
void update_extent_pos(Disk_alloc_info&, Ptr<Extent_info>);
@@ -2677,7 +2713,7 @@ public:
private:
void disk_restart_undo_next(Signal*);
- void disk_restart_undo_lcp(Uint32, Uint32);
+ void disk_restart_undo_lcp(Uint32, Uint32, Uint32 flag);
void disk_restart_undo_callback(Signal* signal, Uint32, Uint32);
void disk_restart_undo_alloc(Apply_undo*);
void disk_restart_undo_update(Apply_undo*);
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
index 9c70cb7f0f8..1f703599cf5 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp
@@ -151,10 +151,10 @@ void Dbtup::initOpConnection(Operationrec* regOperPtr)
static
inline
bool
-operator>=(const Local_key& key1, const Local_key& key2)
+operator>(const Local_key& key1, const Local_key& key2)
{
return key1.m_page_no > key2.m_page_no ||
- (key1.m_page_no == key2.m_page_no && key1.m_page_idx >= key2.m_page_idx);
+ (key1.m_page_no == key2.m_page_no && key1.m_page_idx > key2.m_page_idx);
}
void
@@ -175,8 +175,11 @@ Dbtup::dealloc_tuple(Signal* signal,
{
Local_key disk;
memcpy(&disk, ptr->get_disk_ref_ptr(regTabPtr), sizeof(disk));
+ PagePtr tmpptr;
+ tmpptr.i = m_pgman.m_ptr.i;
+ tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
disk_page_free(signal, regTabPtr, regFragPtr,
- &disk, *(PagePtr*)&m_pgman.m_ptr, gci);
+ &disk, tmpptr, gci);
}
if (! (bits & Tuple_header::LCP_SKIP) && lcpScan_ptr_i != RNIL)
@@ -186,7 +189,7 @@ Dbtup::dealloc_tuple(Signal* signal,
Local_key rowid = regOperPtr->m_tuple_location;
Local_key scanpos = scanOp.p->m_scanPos.m_key;
rowid.m_page_no = page->frag_page_id;
- if (rowid >= scanpos)
+ if (rowid > scanpos)
{
extra_bits = Tuple_header::LCP_KEEP; // Note REMOVE FREE
ptr->m_operation_ptr_i = lcp_keep_list;
@@ -214,6 +217,7 @@ Dbtup::commit_operation(Signal* signal,
{
ndbassert(regOperPtr->op_struct.op_type != ZDELETE);
+ Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op;
Uint32 save= tuple_ptr->m_operation_ptr_i;
Uint32 bits= tuple_ptr->m_header_bits;
@@ -263,7 +267,6 @@ Dbtup::commit_operation(Signal* signal,
Local_key key;
memcpy(&key, copy->get_disk_ref_ptr(regTabPtr), sizeof(Local_key));
Uint32 logfile_group_id= regFragPtr->m_logfile_group_id;
- Uint32 lcpScan_ptr_i= regFragPtr->m_lcp_scan_op;
PagePtr diskPagePtr = *(PagePtr*)&m_pgman.m_ptr;
ndbassert(diskPagePtr.p->m_page_no == key.m_page_no);
@@ -272,19 +275,6 @@ Dbtup::commit_operation(Signal* signal,
if(copy_bits & Tuple_header::DISK_ALLOC)
{
disk_page_alloc(signal, regTabPtr, regFragPtr, &key, diskPagePtr, gci);
-
- if(lcpScan_ptr_i != RNIL)
- {
- ScanOpPtr scanOp;
- c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i);
- Local_key rowid = regOperPtr->m_tuple_location;
- Local_key scanpos = scanOp.p->m_scanPos.m_key;
- rowid.m_page_no = pagePtr.p->frag_page_id;
- if(rowid >= scanpos)
- {
- copy_bits |= Tuple_header::LCP_SKIP;
- }
- }
}
if(regTabPtr->m_attributes[DD].m_no_of_varsize == 0)
@@ -311,6 +301,18 @@ Dbtup::commit_operation(Signal* signal,
copy_bits |= Tuple_header::DISK_PART;
}
+ if(lcpScan_ptr_i != RNIL && (bits & Tuple_header::ALLOC))
+ {
+ ScanOpPtr scanOp;
+ c_scanOpPool.getPtr(scanOp, lcpScan_ptr_i);
+ Local_key rowid = regOperPtr->m_tuple_location;
+ Local_key scanpos = scanOp.p->m_scanPos.m_key;
+ rowid.m_page_no = pagePtr.p->frag_page_id;
+ if(rowid > scanpos)
+ {
+ copy_bits |= Tuple_header::LCP_SKIP;
+ }
+ }
Uint32 clear=
Tuple_header::ALLOC | Tuple_header::FREE |
@@ -356,7 +358,12 @@ Dbtup::disk_page_commit_callback(Signal* signal,
regOperPtr.p->m_commit_disk_callback_page= page_id;
m_global_page_pool.getPtr(m_pgman.m_ptr, page_id);
- disk_page_set_dirty(*(Ptr<Page>*)&m_pgman.m_ptr);
+ {
+ PagePtr tmp;
+ tmp.i = m_pgman.m_ptr.i;
+ tmp.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
+ disk_page_set_dirty(tmp);
+ }
execTUP_COMMITREQ(signal);
if(signal->theData[0] == 0)
@@ -543,7 +550,14 @@ void Dbtup::execTUP_COMMITREQ(Signal* signal)
break;
}
get_page = true;
- disk_page_set_dirty(*(Ptr<Page>*)&m_pgman.m_ptr);
+
+ {
+ PagePtr tmpptr;
+ tmpptr.i = m_pgman.m_ptr.i;
+ tmpptr.p = reinterpret_cast<Page*>(m_pgman.m_ptr.p);
+ disk_page_set_dirty(tmpptr);
+ }
+
regOperPtr.p->m_commit_disk_callback_page= res;
regOperPtr.p->op_struct.m_load_diskpage_on_commit= 0;
}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
index 7959606b7f4..0342f2c9e0c 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupDiskAlloc.cpp
@@ -68,6 +68,26 @@ operator<<(NdbOut& out, const Ptr<Dbtup::Extent_info> & ptr)
return out;
}
+#if NOT_YET_FREE_EXTENT
+static
+inline
+bool
+check_free(const Dbtup::Extent_info* extP)
+{
+ Uint32 res = 0;
+ for (Uint32 i = 1; i<MAX_FREE_LIST; i++)
+ res += extP->m_free_page_count[i];
+ return res;
+}
+#error "Code for deallocting extents when they get empty"
+#error "This code is not yet complete"
+#endif
+
+#if NOT_YET_UNDO_ALLOC_EXTENT
+#error "This is needed for deallocting extents when they get empty"
+#error "This code is not complete yet"
+#endif
+
void
Dbtup::dump_disk_alloc(Dbtup::Disk_alloc_info & alloc)
{
@@ -444,23 +464,71 @@ Dbtup::disk_page_prealloc(Signal* signal,
/**
* We need to alloc an extent
*/
+#if NOT_YET_UNDO_ALLOC_EXTENT
+ Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id;
+
+ err = c_lgman->alloc_log_space(logfile_group_id,
+ sizeof(Disk_undo::AllocExtent)>>2);
+ if(unlikely(err))
+ {
+ return -err;
+ }
+#endif
+
if (!c_extent_pool.seize(ext))
{
+ jam();
//XXX
err= 2;
+#if NOT_YET_UNDO_ALLOC_EXTENT
+ c_lgman->free_log_space(logfile_group_id,
+ sizeof(Disk_undo::AllocExtent)>>2);
+#endif
c_page_request_pool.release(req);
ndbout_c("no free extent info");
return -err;
}
-
+
if ((err= tsman.alloc_extent(&ext.p->m_key)) < 0)
{
+ jam();
+#if NOT_YET_UNDO_ALLOC_EXTENT
+ c_lgman->free_log_space(logfile_group_id,
+ sizeof(Disk_undo::AllocExtent)>>2);
+#endif
c_extent_pool.release(ext);
c_page_request_pool.release(req);
return err;
}
int pages= err;
+#if NOT_YET_UNDO_ALLOC_EXTENT
+ {
+ /**
+ * Do something here
+ */
+ {
+ Callback cb;
+ cb.m_callbackData= ext.i;
+ cb.m_callbackFunction =
+ safe_cast(&Dbtup::disk_page_alloc_extent_log_buffer_callback);
+ Uint32 sz= sizeof(Disk_undo::AllocExtent)>>2;
+
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
+ int res= lgman.get_log_buffer(signal, sz, &cb);
+ switch(res){
+ case 0:
+ break;
+ case -1:
+ ndbrequire("NOT YET IMPLEMENTED" == 0);
+ break;
+ default:
+ execute(signal, cb, res);
+ }
+ }
+ }
+#endif
+
ndbout << "allocated " << pages << " pages: " << ext.p->m_key << endl;
ext.p->m_first_page_no = ext.p->m_key.m_page_no;
bzero(ext.p->m_free_page_count, sizeof(ext.p->m_free_page_count));
@@ -1016,6 +1084,12 @@ Dbtup::disk_page_free(Signal *signal,
extentPtr.p->m_free_space += sz;
update_extent_pos(alloc, extentPtr);
+#if NOT_YET_FREE_EXTENT
+ if (check_free(extentPtr.p) == 0)
+ {
+ ndbout_c("free: extent is free");
+ }
+#endif
}
void
@@ -1118,14 +1192,56 @@ Dbtup::disk_page_abort_prealloc_callback_1(Signal* signal,
extentPtr.p->m_free_space += sz;
update_extent_pos(alloc, extentPtr);
+#if NOT_YET_FREE_EXTENT
+ if (check_free(extentPtr.p) == 0)
+ {
+ ndbout_c("abort: extent is free");
+ }
+#endif
+}
+
+#if NOT_YET_UNDO_ALLOC_EXTENT
+void
+Dbtup::disk_page_alloc_extent_log_buffer_callback(Signal* signal,
+ Uint32 extentPtrI,
+ Uint32 unused)
+{
+ Ptr<Extent_info> extentPtr;
+ c_extent_pool.getPtr(extentPtr, extentPtrI);
+
+ Local_key key = extentPtr.p->m_key;
+ Tablespace_client2 tsman(signal, c_tsman, &key);
+
+ Ptr<Tablerec> tabPtr;
+ tabPtr.i= tsman.m_table_id;
+ ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
+
+ Ptr<Fragrecord> fragPtr;
+ getFragmentrec(fragPtr, tsman.m_fragment_id, tabPtr.p);
+
+ Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
+
+ Disk_undo::AllocExtent alloc;
+ alloc.m_table = tabPtr.i;
+ alloc.m_fragment = tsman.m_fragment_id;
+ alloc.m_page_no = key.m_page_no;
+ alloc.m_file_no = key.m_file_no;
+ alloc.m_type_length = (Disk_undo::UNDO_ALLOC_EXTENT<<16)|(sizeof(alloc)>> 2);
+
+ Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } };
+
+ Uint64 lsn= lgman.add_entry(c, 1);
+
+ tsman.update_lsn(&key, lsn);
}
+#endif
Uint64
Dbtup::disk_page_undo_alloc(Page* page, const Local_key* key,
Uint32 sz, Uint32 gci, Uint32 logfile_group_id)
{
- Logfile_client lsman(this, c_lgman, logfile_group_id);
-
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
+
Disk_undo::Alloc alloc;
alloc.m_type_length= (Disk_undo::UNDO_ALLOC << 16) | (sizeof(alloc) >> 2);
alloc.m_page_no = key->m_page_no;
@@ -1133,7 +1249,7 @@ Dbtup::disk_page_undo_alloc(Page* page, const Local_key* key,
Logfile_client::Change c[1] = {{ &alloc, sizeof(alloc) >> 2 } };
- Uint64 lsn= lsman.add_entry(c, 1);
+ Uint64 lsn= lgman.add_entry(c, 1);
m_pgman.update_lsn(* key, lsn);
return lsn;
@@ -1144,7 +1260,7 @@ Dbtup::disk_page_undo_update(Page* page, const Local_key* key,
const Uint32* src, Uint32 sz,
Uint32 gci, Uint32 logfile_group_id)
{
- Logfile_client lsman(this, c_lgman, logfile_group_id);
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
Disk_undo::Update update;
update.m_page_no = key->m_page_no;
@@ -1162,7 +1278,7 @@ Dbtup::disk_page_undo_update(Page* page, const Local_key* key,
ndbassert(4*(3 + sz + 1) == (sizeof(update) + 4*sz - 4));
- Uint64 lsn= lsman.add_entry(c, 3);
+ Uint64 lsn= lgman.add_entry(c, 3);
m_pgman.update_lsn(* key, lsn);
return lsn;
@@ -1173,7 +1289,7 @@ Dbtup::disk_page_undo_free(Page* page, const Local_key* key,
const Uint32* src, Uint32 sz,
Uint32 gci, Uint32 logfile_group_id)
{
- Logfile_client lsman(this, c_lgman, logfile_group_id);
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
Disk_undo::Free free;
free.m_page_no = key->m_page_no;
@@ -1191,7 +1307,7 @@ Dbtup::disk_page_undo_free(Page* page, const Local_key* key,
ndbassert(4*(3 + sz + 1) == (sizeof(free) + 4*sz - 4));
- Uint64 lsn= lsman.add_entry(c, 3);
+ Uint64 lsn= lgman.add_entry(c, 3);
m_pgman.update_lsn(* key, lsn);
return lsn;
@@ -1221,7 +1337,7 @@ Dbtup::disk_restart_undo(Signal* signal, Uint64 lsn,
ndbrequire(len == 3);
Uint32 tableId = ptr[1] >> 16;
Uint32 fragId = ptr[1] & 0xFFFF;
- disk_restart_undo_lcp(tableId, fragId);
+ disk_restart_undo_lcp(tableId, fragId, Fragrecord::UC_LCP);
disk_restart_undo_next(signal);
return;
}
@@ -1260,10 +1376,20 @@ Dbtup::disk_restart_undo(Signal* signal, Uint64 lsn,
ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
for(Uint32 i = 0; i<MAX_FRAG_PER_NODE; i++)
if (tabPtr.p->fragrec[i] != RNIL)
- disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i]);
+ disk_restart_undo_lcp(tabPtr.i, tabPtr.p->fragid[i],
+ Fragrecord::UC_CREATE);
disk_restart_undo_next(signal);
return;
}
+ case File_formats::Undofile::UNDO_TUP_DROP:
+ jam();
+ case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
+ jam();
+ case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
+ jam();
+ disk_restart_undo_next(signal);
+ return;
+
case File_formats::Undofile::UNDO_END:
f_undo_done = true;
return;
@@ -1297,7 +1423,7 @@ Dbtup::disk_restart_undo_next(Signal* signal)
}
void
-Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId)
+Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId, Uint32 flag)
{
Ptr<Tablerec> tabPtr;
tabPtr.i= tableId;
@@ -1309,7 +1435,7 @@ Dbtup::disk_restart_undo_lcp(Uint32 tableId, Uint32 fragId)
getFragmentrec(fragPtr, fragId, tabPtr.p);
if (!fragPtr.isNull())
{
- fragPtr.p->m_undo_complete = true;
+ fragPtr.p->m_undo_complete |= flag;
}
}
}
@@ -1518,6 +1644,12 @@ Dbtup::disk_restart_alloc_extent(Uint32 tableId, Uint32 fragId,
if (tabPtr.p->tableStatus == DEFINED)
{
getFragmentrec(fragPtr, fragId, tabPtr.p);
+ if (fragPtr.p->m_undo_complete & Fragrecord::UC_CREATE)
+ {
+ jam();
+ return -1;
+ }
+
if (!fragPtr.isNull())
{
Disk_alloc_info& alloc= fragPtr.p->m_disk_alloc_info;
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index ef52f8a87e5..52981e7fc83 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -3125,7 +3125,7 @@ Dbtup::nr_delete(Signal* signal, Uint32 senderData,
disk_page_set_dirty(disk_page);
preq.m_callback.m_callbackFunction =
- safe_cast(&Dbtup::nr_delete_logbuffer_callback);
+ safe_cast(&Dbtup::nr_delete_log_buffer_callback);
Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
res= lgman.get_log_buffer(signal, sz, &preq.m_callback);
switch(res){
@@ -3178,7 +3178,7 @@ Dbtup::nr_delete_page_callback(Signal* signal,
Callback cb;
cb.m_callbackData = userpointer;
cb.m_callbackFunction =
- safe_cast(&Dbtup::nr_delete_logbuffer_callback);
+ safe_cast(&Dbtup::nr_delete_log_buffer_callback);
Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
int res= lgman.get_log_buffer(signal, sz, &cb);
switch(res){
@@ -3198,7 +3198,7 @@ Dbtup::nr_delete_page_callback(Signal* signal,
}
void
-Dbtup::nr_delete_logbuffer_callback(Signal* signal,
+Dbtup::nr_delete_log_buffer_callback(Signal* signal,
Uint32 userpointer,
Uint32 unused)
{
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
index 2b3093ed205..3e9469c4edf 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp
@@ -163,11 +163,12 @@ void Dbtup::execCONTINUEB(Signal* signal)
break;
case ZREL_FRAG:
ljam();
- releaseFragment(signal, dataPtr);
+ releaseFragment(signal, dataPtr, signal->theData[2]);
break;
case ZREPORT_MEMORY_USAGE:{
ljam();
static int c_currentMemUsed = 0;
+ Uint32 cnt = signal->theData[1];
Uint32 tmp = c_page_pool.getSize();
int now = tmp ? (cnoOfAllocatedPages * 100)/tmp : 0;
const int thresholds[] = { 100, 90, 80, 0 };
@@ -181,12 +182,22 @@ void Dbtup::execCONTINUEB(Signal* signal)
}
}
- if(now != c_currentMemUsed){
- reportMemoryUsage(signal, now > c_currentMemUsed ? 1 : -1);
+ if(now != c_currentMemUsed ||
+ (c_memusage_report_frequency && cnt + 1 == c_memusage_report_frequency))
+ {
+ reportMemoryUsage(signal,
+ now > c_currentMemUsed ? 1 :
+ now < c_currentMemUsed ? -1 : 0);
+ cnt = 0;
c_currentMemUsed = now;
+ }
+ else
+ {
+ cnt++;
}
signal->theData[0] = ZREPORT_MEMORY_USAGE;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);
+ signal->theData[1] = cnt;
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 2);
return;
}
case ZBUILD_INDEX:
@@ -211,7 +222,7 @@ void Dbtup::execCONTINUEB(Signal* signal)
fragPtr.i= signal->theData[2];
ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
- drop_fragment_free_exent(signal, tabPtr, fragPtr, signal->theData[3]);
+ drop_fragment_free_extent(signal, tabPtr, fragPtr, signal->theData[3]);
return;
}
case ZUNMAP_PAGES:
@@ -336,6 +347,10 @@ void Dbtup::execREAD_CONFIG_REQ(Signal* signal)
clastBitMask = 1;
clastBitMask = clastBitMask << 31;
+ c_memusage_report_frequency = 0;
+ ndb_mgm_get_int_parameter(p, CFG_DB_MEMREPORT_FREQUENCY,
+ &c_memusage_report_frequency);
+
initialiseRecordsLab(signal, 0, ref, senderData);
}//Dbtup::execSIZEALT_REP()
@@ -501,7 +516,8 @@ void Dbtup::execNDB_STTOR(Signal* signal)
/* RESTART. */
/*****************************************/
signal->theData[0] = ZREPORT_MEMORY_USAGE;
- sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 2000, 1);
+ signal->theData[1] = 0;
+ sendSignalWithDelay(reference(), GSN_CONTINUEB, signal, 1000, 1);
break;
default:
ljam();
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
index 41b00b0a04b..b5010205880 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp
@@ -308,6 +308,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
if(lastAttr)
{
+ jam();
/**
* Init Disk_alloc_info
*/
@@ -319,6 +320,11 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
ndbrequire(tsman.get_tablespace_info(&rep) == 0);
regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
}
+ else
+ {
+ jam();
+ regFragPtr.p->m_logfile_group_id = RNIL;
+ }
new (&regFragPtr.p->m_disk_alloc_info)
Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
releaseFragoperrec(fragOperPtr);
@@ -563,7 +569,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
regFragPtr.p->m_tablespace_id);
ndbrequire(tsman.get_tablespace_info(&rep) == 0);
regFragPtr.p->m_logfile_group_id= rep.tablespace.logfile_group_id;
- }
+ }
+ else
+ {
+ jam();
+ regFragPtr.p->m_logfile_group_id = RNIL;
+ }
new (&regFragPtr.p->m_disk_alloc_info)
Disk_alloc_info(regTabPtr.p, rep.tablespace.extent_size);
@@ -596,7 +607,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
ndbrequire("NOT YET IMPLEMENTED" == 0);
break;
}
- execute(signal, cb, 0);
+ execute(signal, cb, regFragPtr.p->m_logfile_group_id);
return;
}
}
@@ -873,7 +884,8 @@ Dbtup::execDROP_TAB_REQ(Signal* signal)
signal->theData[0]= ZREL_FRAG;
signal->theData[1]= tabPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
+ signal->theData[2]= RNIL;
+ sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
}
void Dbtup::releaseTabDescr(Tablerec* const regTabPtr)
@@ -901,7 +913,8 @@ void Dbtup::releaseTabDescr(Tablerec* const regTabPtr)
}
}
-void Dbtup::releaseFragment(Signal* signal, Uint32 tableId)
+void Dbtup::releaseFragment(Signal* signal, Uint32 tableId,
+ Uint32 logfile_group_id)
{
TablerecPtr tabPtr;
tabPtr.i= tableId;
@@ -928,16 +941,35 @@ void Dbtup::releaseFragment(Signal* signal, Uint32 tableId)
sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
return;
}
+
+#if NOT_YET_UNDO_DROP_TABLE
+#error "This code is complete, but I prefer not to enable it until I need it"
+ if (logfile_group_id != RNIL)
+ {
+ Callback cb;
+ cb.m_callbackData= tabPtr.i;
+ cb.m_callbackFunction =
+ safe_cast(&Dbtup::drop_table_log_buffer_callback);
+ Uint32 sz= sizeof(Disk_undo::Drop) >> 2;
+ int r0 = c_lgman->alloc_log_space(logfile_group_id, sz);
+
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
+ int res= lgman.get_log_buffer(signal, sz, &cb);
+ switch(res){
+ case 0:
+ ljam();
+ return;
+ case -1:
+ ndbrequire("NOT YET IMPLEMENTED" == 0);
+ break;
+ default:
+ execute(signal, cb, logfile_group_id);
+ return;
+ }
+ }
+#endif
- DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend();
- dropConf->senderRef= reference();
- dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr;
- dropConf->tableId= tabPtr.i;
- sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF,
- signal, DropTabConf::SignalLength, JBB);
-
- releaseTabDescr(tabPtr.p);
- initTab(tabPtr.p);
+ drop_table_logsync_callback(signal, tabPtr.i, RNIL);
}
void
@@ -964,7 +996,7 @@ Dbtup::drop_fragment_unmap_pages(Signal *signal,
alloc_info.m_curr_extent_info_ptr_i= RNIL;
}
- drop_fragment_free_exent(signal, tabPtr, fragPtr, 0);
+ drop_fragment_free_extent(signal, tabPtr, fragPtr, 0);
return;
}
@@ -997,7 +1029,7 @@ Dbtup::drop_fragment_unmap_pages(Signal *signal,
}
return;
}
- drop_fragment_free_exent(signal, tabPtr, fragPtr, 0);
+ drop_fragment_free_extent(signal, tabPtr, fragPtr, 0);
}
void
@@ -1030,10 +1062,10 @@ Dbtup::drop_fragment_unmap_page_callback(Signal* signal,
}
void
-Dbtup::drop_fragment_free_exent(Signal *signal,
- TablerecPtr tabPtr,
- FragrecordPtr fragPtr,
- Uint32 pos)
+Dbtup::drop_fragment_free_extent(Signal *signal,
+ TablerecPtr tabPtr,
+ FragrecordPtr fragPtr,
+ Uint32 pos)
{
if (tabPtr.p->m_no_of_disk_attributes)
{
@@ -1043,25 +1075,32 @@ Dbtup::drop_fragment_free_exent(Signal *signal,
if(!alloc_info.m_free_extents[pos].isEmpty())
{
jam();
- Local_extent_info_list
- list(c_extent_pool, alloc_info.m_free_extents[pos]);
- Ptr<Extent_info> ext_ptr;
- list.first(ext_ptr);
+ Callback cb;
+ cb.m_callbackData= fragPtr.i;
+ cb.m_callbackFunction =
+ safe_cast(&Dbtup::drop_fragment_free_extent_log_buffer_callback);
+#if NOT_YET_UNDO_FREE_EXTENT
+ Uint32 sz= sizeof(Disk_undo::FreeExtent) >> 2;
+ int r0 = c_lgman->alloc_log_space(fragPtr.p->m_logfile_group_id, sz);
- Tablespace_client tsman(signal, c_tsman, tabPtr.i,
- fragPtr.p->fragmentId,
- fragPtr.p->m_tablespace_id);
+ Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
- tsman.free_extent(&ext_ptr.p->m_key);
- c_extent_hash.remove(ext_ptr);
- list.release(ext_ptr);
-
- signal->theData[0] = ZFREE_EXTENT;
- signal->theData[1] = tabPtr.i;
- signal->theData[2] = fragPtr.i;
- signal->theData[3] = pos;
- sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
+ int res= lgman.get_log_buffer(signal, sz, &cb);
+ switch(res){
+ case 0:
+ ljam();
+ return;
+ case -1:
+ ndbrequire("NOT YET IMPLEMENTED" == 0);
+ break;
+ default:
+ execute(signal, cb, fragPtr.p->m_logfile_group_id);
+ return;
+ }
+#else
+ execute(signal, cb, fragPtr.p->m_logfile_group_id);
return;
+#endif
}
}
@@ -1081,6 +1120,123 @@ Dbtup::drop_fragment_free_exent(Signal *signal,
}
void
+Dbtup::drop_table_log_buffer_callback(Signal* signal, Uint32 tablePtrI,
+ Uint32 logfile_group_id)
+{
+ TablerecPtr tabPtr;
+ tabPtr.i = tablePtrI;
+ ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
+
+ ndbrequire(tabPtr.p->m_no_of_disk_attributes);
+
+ Disk_undo::Drop drop;
+ drop.m_table = tabPtr.i;
+ drop.m_type_length =
+ (Disk_undo::UNDO_DROP << 16) | (sizeof(drop) >> 2);
+ Logfile_client lgman(this, c_lgman, logfile_group_id);
+
+ Logfile_client::Change c[1] = {{ &drop, sizeof(drop) >> 2 } };
+ Uint64 lsn = lgman.add_entry(c, 1);
+
+ Logfile_client::Request req;
+ req.m_callback.m_callbackData= tablePtrI;
+ req.m_callback.m_callbackFunction =
+ safe_cast(&Dbtup::drop_table_logsync_callback);
+
+ int ret = lgman.sync_lsn(signal, lsn, &req, 0);
+ switch(ret){
+ case 0:
+ return;
+ default:
+ ndbout_c("ret: %d", ret);
+ ndbrequire(false);
+ }
+}
+
+void
+Dbtup::drop_table_logsync_callback(Signal* signal,
+ Uint32 tabPtrI,
+ Uint32 logfile_group_id)
+{
+ TablerecPtr tabPtr;
+ tabPtr.i = tabPtrI;
+ ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
+
+ DropTabConf * const dropConf= (DropTabConf *)signal->getDataPtrSend();
+ dropConf->senderRef= reference();
+ dropConf->senderData= tabPtr.p->m_dropTable.tabUserPtr;
+ dropConf->tableId= tabPtr.i;
+ sendSignal(tabPtr.p->m_dropTable.tabUserRef, GSN_DROP_TAB_CONF,
+ signal, DropTabConf::SignalLength, JBB);
+
+ releaseTabDescr(tabPtr.p);
+ initTab(tabPtr.p);
+}
+
+void
+Dbtup::drop_fragment_free_extent_log_buffer_callback(Signal* signal,
+ Uint32 fragPtrI,
+ Uint32 unused)
+{
+ FragrecordPtr fragPtr;
+ fragPtr.i = fragPtrI;
+ ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
+
+ TablerecPtr tabPtr;
+ tabPtr.i = fragPtr.p->fragTableId;
+ ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
+
+ ndbrequire(tabPtr.p->m_no_of_disk_attributes);
+ Disk_alloc_info& alloc_info= fragPtr.p->m_disk_alloc_info;
+
+ for(Uint32 pos = 0; pos<EXTENT_SEARCH_MATRIX_SIZE; pos++)
+ {
+ if(!alloc_info.m_free_extents[pos].isEmpty())
+ {
+ jam();
+ Local_extent_info_list
+ list(c_extent_pool, alloc_info.m_free_extents[pos]);
+ Ptr<Extent_info> ext_ptr;
+ list.first(ext_ptr);
+
+#if NOT_YET_UNDO_FREE_EXTENT
+#error "This code is complete"
+#error "but not needed until we do dealloc of empty extents"
+ Disk_undo::FreeExtent free;
+ free.m_table = tabPtr.i;
+ free.m_fragment = fragPtr.p->fragmentId;
+ free.m_file_no = ext_ptr.p->m_key.m_file_no;
+ free.m_page_no = ext_ptr.p->m_key.m_page_no;
+ free.m_type_length =
+ (Disk_undo::UNDO_FREE_EXTENT << 16) | (sizeof(free) >> 2);
+ Logfile_client lgman(this, c_lgman, fragPtr.p->m_logfile_group_id);
+
+ Logfile_client::Change c[1] = {{ &free, sizeof(free) >> 2 } };
+ Uint64 lsn = lgman.add_entry(c, 1);
+#else
+ Uint64 lsn = 0;
+#endif
+
+ Tablespace_client tsman(signal, c_tsman, tabPtr.i,
+ fragPtr.p->fragmentId,
+ fragPtr.p->m_tablespace_id);
+
+ tsman.free_extent(&ext_ptr.p->m_key, lsn);
+ c_extent_hash.remove(ext_ptr);
+ list.release(ext_ptr);
+
+ signal->theData[0] = ZFREE_EXTENT;
+ signal->theData[1] = tabPtr.i;
+ signal->theData[2] = fragPtr.i;
+ signal->theData[3] = pos;
+ sendSignal(cownref, GSN_CONTINUEB, signal, 4, JBB);
+ return;
+ }
+ }
+ ndbrequire(false);
+}
+
+void
Dbtup::drop_fragment_free_var_pages(Signal* signal)
{
ljam();
@@ -1111,7 +1267,7 @@ Dbtup::drop_fragment_free_var_pages(Signal* signal)
sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
return;
}
-
+ Uint32 logfile_group_id = fragPtr.p->m_logfile_group_id ;
releaseFragPages(fragPtr.p);
Uint32 i;
for(i= 0; i<MAX_FRAG_PER_NODE; i++)
@@ -1125,7 +1281,8 @@ Dbtup::drop_fragment_free_var_pages(Signal* signal)
signal->theData[0]= ZREL_FRAG;
signal->theData[1]= tabPtr.i;
- sendSignal(cownref, GSN_CONTINUEB, signal, 2, JBB);
+ signal->theData[2]= logfile_group_id;
+ sendSignal(cownref, GSN_CONTINUEB, signal, 3, JBB);
return;
}
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
index b0f585e5a67..c8546209f94 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp
@@ -784,6 +784,7 @@ int Dbtup::updateAttributes(KeyReqStruct *req_struct,
memcpy(req_struct->m_tuple_ptr->get_disk_ref_ptr(regTabPtr),
inBuffer+inBufIndex+1, sz << 2);
inBufIndex += 1 + sz;
+ req_struct->in_buf_index = inBufIndex;
}
else
{
diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
index 7c734c99d2c..653a24ba6a1 100644
--- a/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
+++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupScan.cpp
@@ -53,8 +53,7 @@ Dbtup::execACC_SCANREQ(Signal* signal)
// flags
Uint32 bits = 0;
- if (!AccScanReq::getLcpScanFlag(req->requestInfo) ||
- tablePtr.p->m_no_of_disk_attributes == 0)
+ if (!AccScanReq::getLcpScanFlag(req->requestInfo))
{
// seize from pool and link to per-fragment list
LocalDLList<ScanOp> list(c_scanOpPool, frag.m_scanList);
@@ -1051,24 +1050,21 @@ Dbtup::execLCP_FRAG_ORD(Signal* signal)
tablePtr.i = req->tableId;
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
- if(tablePtr.p->m_no_of_disk_attributes)
- {
- jam();
- FragrecordPtr fragPtr;
- Uint32 fragId = req->fragmentId;
- fragPtr.i = RNIL;
- getFragmentrec(fragPtr, fragId, tablePtr.p);
- ndbrequire(fragPtr.i != RNIL);
- Fragrecord& frag = *fragPtr.p;
-
- ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL);
- frag.m_lcp_scan_op = c_lcp_scan_op;
- ScanOpPtr scanPtr;
- c_scanOpPool.getPtr(scanPtr, frag.m_lcp_scan_op);
- ndbrequire(scanPtr.p->m_fragPtrI == RNIL);
- scanPtr.p->m_fragPtrI = fragPtr.i;
-
- scanFirst(signal, scanPtr);
- scanPtr.p->m_state = ScanOp::First;
- }
+ jam();
+ FragrecordPtr fragPtr;
+ Uint32 fragId = req->fragmentId;
+ fragPtr.i = RNIL;
+ getFragmentrec(fragPtr, fragId, tablePtr.p);
+ ndbrequire(fragPtr.i != RNIL);
+ Fragrecord& frag = *fragPtr.p;
+
+ ndbrequire(frag.m_lcp_scan_op == RNIL && c_lcp_scan_op != RNIL);
+ frag.m_lcp_scan_op = c_lcp_scan_op;
+ ScanOpPtr scanPtr;
+ c_scanOpPool.getPtr(scanPtr, frag.m_lcp_scan_op);
+ ndbrequire(scanPtr.p->m_fragPtrI == RNIL);
+ scanPtr.p->m_fragPtrI = fragPtr.i;
+
+ scanFirst(signal, scanPtr);
+ scanPtr.p->m_state = ScanOp::First;
}
diff --git a/storage/ndb/src/kernel/blocks/diskpage.hpp b/storage/ndb/src/kernel/blocks/diskpage.hpp
index 044597be1cf..c75f2a0c070 100644
--- a/storage/ndb/src/kernel/blocks/diskpage.hpp
+++ b/storage/ndb/src/kernel/blocks/diskpage.hpp
@@ -154,7 +154,10 @@ struct File_formats
,UNDO_TUP_UPDATE = 4
,UNDO_TUP_FREE = 5
,UNDO_TUP_CREATE = 6
-
+ ,UNDO_TUP_DROP = 7
+ ,UNDO_TUP_ALLOC_EXTENT = 8
+ ,UNDO_TUP_FREE_EXTENT = 9
+
,UNDO_END = 0x7FFF
,UNDO_NEXT_LSN = 0x8000
};
diff --git a/storage/ndb/src/kernel/blocks/lgman.cpp b/storage/ndb/src/kernel/blocks/lgman.cpp
index dff41ab8bca..17a4c4a4a83 100644
--- a/storage/ndb/src/kernel/blocks/lgman.cpp
+++ b/storage/ndb/src/kernel/blocks/lgman.cpp
@@ -1160,14 +1160,15 @@ Lgman::process_log_sync_waiters(Signal* signal, Ptr<Logfile_group> ptr)
bool removed= false;
Ptr<Log_waiter> waiter;
list.first(waiter);
+ Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
if(waiter.p->m_sync_lsn <= ptr.p->m_last_synced_lsn)
{
removed= true;
Uint32 block = waiter.p->m_block;
SimulatedBlock* b = globalData.getBlock(block);
- b->execute(signal, waiter.p->m_callback, 0);
-
+ b->execute(signal, waiter.p->m_callback, logfile_group_id);
+
list.releaseFirst(waiter);
}
@@ -1522,12 +1523,13 @@ Lgman::process_log_buffer_waiters(Signal* signal, Ptr<Logfile_group> ptr)
bool removed= false;
Ptr<Log_waiter> waiter;
list.first(waiter);
+ Uint32 logfile_group_id = ptr.p->m_logfile_group_id;
if(waiter.p->m_size + 2*File_formats::UNDO_PAGE_WORDS < free_buffer)
{
removed= true;
Uint32 block = waiter.p->m_block;
SimulatedBlock* b = globalData.getBlock(block);
- b->execute(signal, waiter.p->m_callback, 0);
+ b->execute(signal, waiter.p->m_callback, logfile_group_id);
list.releaseFirst(waiter);
}
@@ -2061,6 +2063,7 @@ Lgman::execSTART_RECREQ(Signal* signal)
if(ptr.i != RNIL)
{
infoEvent("Applying undo to LCP: %d", m_latest_lcp);
+ ndbout_c("Applying undo to LCP: %d", m_latest_lcp);
find_log_head(signal, ptr);
return;
}
@@ -2680,13 +2683,14 @@ Lgman::execute_undo_record(Signal* signal)
case File_formats::Undofile::UNDO_LCP_FIRST:
{
Uint32 lcp = * (ptr - len + 1);
- if(lcp > m_latest_lcp)
+ if(m_latest_lcp && lcp > m_latest_lcp)
{
// Just ignore
break;
}
- if(lcp < m_latest_lcp ||
+ if(m_latest_lcp == 0 ||
+ lcp < m_latest_lcp ||
(lcp == m_latest_lcp &&
mask == File_formats::Undofile::UNDO_LCP_FIRST))
{
@@ -2699,6 +2703,9 @@ Lgman::execute_undo_record(Signal* signal)
case File_formats::Undofile::UNDO_TUP_UPDATE:
case File_formats::Undofile::UNDO_TUP_FREE:
case File_formats::Undofile::UNDO_TUP_CREATE:
+ case File_formats::Undofile::UNDO_TUP_DROP:
+ case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
+ case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
tup->disk_restart_undo(signal, lsn, mask, ptr - len + 1, len);
return;
default:
diff --git a/storage/ndb/src/kernel/blocks/print_file.cpp b/storage/ndb/src/kernel/blocks/print_file.cpp
index 14b83cccaee..696658ef8de 100644
--- a/storage/ndb/src/kernel/blocks/print_file.cpp
+++ b/storage/ndb/src/kernel/blocks/print_file.cpp
@@ -304,6 +304,8 @@ print_undo_page(int count, void* ptr, Uint32 sz){
case File_formats::Undofile::UNDO_LCP:
printf("[ %lld LCP %d tab: %d frag: %d ]", lsn,
src[0], src[1] >> 16, src[1] & 0xFFFF);
+ if(g_verbosity <= 3)
+ printf("\n");
break;
case File_formats::Undofile::UNDO_TUP_ALLOC:
if(g_verbosity > 3)
@@ -340,6 +342,48 @@ print_undo_page(int count, void* ptr, Uint32 sz){
req->m_gci);
}
break;
+ case File_formats::Undofile::UNDO_TUP_CREATE:
+ {
+ Dbtup::Disk_undo::Create *req = (Dbtup::Disk_undo::Create*)src;
+ printf("[ %lld Create %d ]", lsn, req->m_table);
+ if(g_verbosity <= 3)
+ printf("\n");
+ break;
+ }
+ case File_formats::Undofile::UNDO_TUP_DROP:
+ {
+ Dbtup::Disk_undo::Drop *req = (Dbtup::Disk_undo::Drop*)src;
+ printf("[ %lld Drop %d ]", lsn, req->m_table);
+ if(g_verbosity <= 3)
+ printf("\n");
+ break;
+ }
+ case File_formats::Undofile::UNDO_TUP_ALLOC_EXTENT:
+ {
+ Dbtup::Disk_undo::AllocExtent *req = (Dbtup::Disk_undo::AllocExtent*)src;
+ printf("[ %lld AllocExtent tab: %d frag: %d file: %d page: %d ]",
+ lsn,
+ req->m_table,
+ req->m_fragment,
+ req->m_file_no,
+ req->m_page_no);
+ if(g_verbosity <= 3)
+ printf("\n");
+ break;
+ }
+ case File_formats::Undofile::UNDO_TUP_FREE_EXTENT:
+ {
+ Dbtup::Disk_undo::FreeExtent *req = (Dbtup::Disk_undo::FreeExtent*)src;
+ printf("[ %lld FreeExtent tab: %d frag: %d file: %d page: %d ]",
+ lsn,
+ req->m_table,
+ req->m_fragment,
+ req->m_file_no,
+ req->m_page_no);
+ if(g_verbosity <= 3)
+ printf("\n");
+ break;
+ }
default:
ndbout_c("[ Unknown type %d len: %d, pos: %d ]", type, len, pos);
if(!(len && type))
@@ -361,11 +405,11 @@ print_undo_page(int count, void* ptr, Uint32 sz){
}
}
}
-
+
if(count == g_uf_zero.m_undo_pages + 1)
{
}
-
+
return 0;
}
diff --git a/storage/ndb/src/kernel/blocks/tsman.cpp b/storage/ndb/src/kernel/blocks/tsman.cpp
index 89725ca309e..48a8d470ccc 100644
--- a/storage/ndb/src/kernel/blocks/tsman.cpp
+++ b/storage/ndb/src/kernel/blocks/tsman.cpp
@@ -79,12 +79,14 @@ Tsman::Tsman(Block_context& ctx,
addRecSignal(GSN_START_RECREQ, &Tsman::execSTART_RECREQ);
+ addRecSignal(GSN_LCP_FRAG_ORD, &Tsman::execLCP_FRAG_ORD);
addRecSignal(GSN_END_LCP_REQ, &Tsman::execEND_LCP_REQ);
addRecSignal(GSN_GET_TABINFOREQ, &Tsman::execGET_TABINFOREQ);
m_tablespace_hash.setSize(10);
m_file_hash.setSize(10);
+ m_lcp_ongoing = false;
}
Tsman::~Tsman()
@@ -1101,6 +1103,7 @@ Tsman::load_extent_page_callback(Signal* signal,
ptr.p->m_online.m_lcp_free_extent_tail = RNIL;
ptr.p->m_online.m_data_pages = data_pages;
ptr.p->m_online.m_used_extent_cnt = 0;
+ ptr.p->m_online.m_extent_headers_per_extent_page = per_page;
Ptr<Tablespace> ts_ptr;
m_tablespace_pool.getPtr(ts_ptr, ptr.p->m_tablespace_ptr_i);
@@ -1182,9 +1185,8 @@ Tsman::scan_extent_headers(Signal* signal, Ptr<Datafile> ptr)
m_tablespace_pool.getPtr(lg_ptr, ptr.p->m_tablespace_ptr_i);
Uint32 firstFree= RNIL;
- Uint32 size = lg_ptr.p->m_extent_size;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
+ Uint32 size = ptr.p->m_extent_size;
+ Uint32 per_page = ptr.p->m_online.m_extent_headers_per_extent_page;
Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
Uint32 pages= ptr.p->m_online.m_offset_data_pages - 1;
Uint32 datapages= ptr.p->m_online.m_data_pages;
@@ -1410,23 +1412,21 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal)
AllocExtentReq::ErrorCode err;
ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
- Uint32 size = ts_ptr.p->m_extent_size;
Local_datafile_list tmp(m_file_pool, ts_ptr.p->m_free_files);
if (tmp.first(file_ptr))
{
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
-
+ Uint32 size = file_ptr.p->m_extent_size;
Uint32 extent = file_ptr.p->m_online.m_first_free_extent;
Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
+ Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
+ Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
Uint32 page_no = extent / per_page;
Uint32 extent_no = extent % per_page;
Page_cache_client::Request preq;
preq.m_page.m_page_no = page_no;
preq.m_page.m_file_no = file_ptr.p->m_file_no;
- preq.m_page.m_page_idx = extent;
/**
* Handling of unmapped extent header pages is not implemented
@@ -1470,6 +1470,7 @@ Tsman::execALLOC_EXTENT_REQ(Signal* signal)
*/
ndbassert(extent >= per_page);
preq.m_page.m_page_no = data_off + size * (extent - /* zero */ per_page);
+ preq.m_page.m_page_idx = extent; // extent_no
AllocExtentReq* rep = (AllocExtentReq*)signal->getDataPtr();
rep->reply.errorCode = 0;
@@ -1501,28 +1502,21 @@ void
Tsman::execFREE_EXTENT_REQ(Signal* signal)
{
jamEntry();
- Ptr<Tablespace> ts_ptr;
Ptr<Datafile> file_ptr;
FreeExtentReq req = *(FreeExtentReq*)signal->getDataPtr();
FreeExtentReq::ErrorCode err = (FreeExtentReq::ErrorCode)0;
- ndbrequire(m_tablespace_hash.find(ts_ptr, req.request.tablespace_id));
Datafile file_key;
file_key.m_file_no = req.request.key.m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
- Uint32 size = ts_ptr.p->m_extent_size;
-
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 extent = (req.request.key.m_page_no - data_off) / size + per_page;
-
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
+ struct req val = lookup_extent(req.request.key.m_page_no, file_ptr.p);
+ Uint32 extent =
+ (req.request.key.m_page_no - val.m_extent_pages) / val.m_extent_size +
+ file_ptr.p->m_online.m_extent_headers_per_extent_page;
Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = req.request.key.m_file_no;
ndbout << "Free extent: " << req.request.key << endl;
@@ -1539,16 +1533,38 @@ Tsman::execFREE_EXTENT_REQ(Signal* signal)
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
+ page->get_header(val.m_extent_no, val.m_extent_size);
ndbrequire(header->m_table == req.request.table_id);
header->m_table = RNIL;
- header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head;
- if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL)
- file_ptr.p->m_online.m_lcp_free_extent_tail= extent;
- file_ptr.p->m_online.m_lcp_free_extent_head= extent;
file_ptr.p->m_online.m_used_extent_cnt--;
+ if (m_lcp_ongoing)
+ {
+ jam();
+ header->m_next_free_extent= file_ptr.p->m_online.m_lcp_free_extent_head;
+ if(file_ptr.p->m_online.m_lcp_free_extent_head == RNIL)
+ file_ptr.p->m_online.m_lcp_free_extent_tail= extent;
+ file_ptr.p->m_online.m_lcp_free_extent_head= extent;
+ }
+ else
+ {
+ jam();
+ header->m_next_free_extent = file_ptr.p->m_online.m_first_free_extent;
+ if (file_ptr.p->m_online.m_first_free_extent == RNIL)
+ {
+ /**
+ * Move from full to free
+ */
+ Ptr<Tablespace> ptr;
+ m_tablespace_pool.getPtr(ptr, file_ptr.p->m_tablespace_ptr_i);
+ Local_datafile_list free(m_file_pool, ptr.p->m_free_files);
+ Local_datafile_list full(m_file_pool, ptr.p->m_full_files);
+ full.remove(file_ptr);
+ free.add(file_ptr);
+ }
+ file_ptr.p->m_online.m_first_free_extent = extent;
+ }
}
else
{
@@ -1583,18 +1599,10 @@ Tsman::update_page_free_bits(Signal* signal,
file_key.m_file_no = key->m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
-
- Uint32 extent = (key->m_page_no - data_off) / size + per_page;
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
+ struct req val = lookup_extent(key->m_page_no, file_ptr.p);
Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = key->m_file_no;
/**
@@ -1609,12 +1617,12 @@ Tsman::update_page_free_bits(Signal* signal,
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
+ page->get_header(val.m_extent_no, val.m_extent_size);
ndbrequire(header->m_table != RNIL);
- Uint32 page_no_in_extent = (key->m_page_no - data_off) % size;
-
+ Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
+
/**
* Toggle word
*/
@@ -1637,26 +1645,15 @@ Tsman::get_page_free_bits(Signal* signal, Local_key *key,
{
jamEntry();
- /**
- * XXX make into subroutine
- */
Ptr<Datafile> file_ptr;
Datafile file_key;
file_key.m_file_no = key->m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
- Uint32 extent = (key->m_page_no - data_off) / size + per_page;
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
+ struct req val = lookup_extent(key->m_page_no, file_ptr.p);
Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = key->m_file_no;
/**
@@ -1671,11 +1668,11 @@ Tsman::get_page_free_bits(Signal* signal, Local_key *key,
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
+ page->get_header(val.m_extent_no, val.m_extent_size);
ndbrequire(header->m_table != RNIL);
- Uint32 page_no_in_extent = (key->m_page_no - data_off) % size;
+ Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
Uint32 bits = header->get_free_bits(page_no_in_extent);
*uncommitted = (bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
*committed = (bits & COMMITTED_MASK);
@@ -1700,19 +1697,11 @@ Tsman::unmap_page(Signal* signal, Local_key *key, Uint32 uncommitted_bits)
Datafile file_key;
file_key.m_file_no = key->m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
-
- Uint32 extent = (key->m_page_no - data_off) / size + per_page;
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
+
+ struct req val = lookup_extent(key->m_page_no, file_ptr.p);
Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = key->m_file_no;
/**
@@ -1727,12 +1716,12 @@ Tsman::unmap_page(Signal* signal, Local_key *key, Uint32 uncommitted_bits)
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
+ page->get_header(val.m_extent_no, val.m_extent_size);
ndbrequire(header->m_table != RNIL);
- Uint32 page_no_in_extent = (key->m_page_no - data_off) % size;
-
+ Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
+
/**
* Toggle word
*/
@@ -1767,18 +1756,10 @@ Tsman::restart_undo_page_free_bits(Signal* signal,
file_key.m_file_no = key->m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
- Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
-
- Uint32 extent = (key->m_page_no - data_off) / size + per_page;
- Uint32 page_no = extent / per_page;
- Uint32 extent_no = extent % per_page;
-
+ struct req val = lookup_extent(key->m_page_no, file_ptr.p);
+
Page_cache_client::Request preq;
- preq.m_page.m_page_no = page_no;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = key->m_file_no;
/**
@@ -1793,7 +1774,7 @@ Tsman::restart_undo_page_free_bits(Signal* signal,
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
File_formats::Datafile::Extent_header* header =
- page->get_header(extent_no, size);
+ page->get_header(val.m_extent_no, val.m_extent_size);
Uint64 lsn = 0;
lsn += page->m_page_header.m_page_lsn_hi; lsn <<= 32;
@@ -1816,7 +1797,7 @@ Tsman::restart_undo_page_free_bits(Signal* signal,
return 0;
}
- Uint32 page_no_in_extent = (key->m_page_no - data_off) % size;
+ Uint32 page_no_in_extent = calc_page_no_in_extent(key->m_page_no, &val);
Uint32 src = header->get_free_bits(page_no_in_extent);
ndbrequire(header->m_table == tableId);
@@ -1862,17 +1843,11 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal)
Datafile file_key;
file_key.m_file_no = req.key.m_file_no;
ndbrequire(m_file_hash.find(file_ptr, file_key));
-
- Uint32 size = file_ptr.p->m_extent_size;
- Uint32 data_off = file_ptr.p->m_online.m_offset_data_pages;
- Uint32 eh_words = File_formats::Datafile::extent_header_words(size);
- Uint32 per_page = File_formats::Datafile::EXTENT_PAGE_WORDS/eh_words;
-
- Uint32 extent = (req.key.m_page_no - data_off) / size;
- Uint32 extent_no = extent % per_page;
+
+ struct req val = lookup_extent(req.key.m_page_no, file_ptr.p);
Page_cache_client::Request preq;
- preq.m_page.m_page_no = 1 /* zero */ + extent / per_page;
+ preq.m_page.m_page_no = val.m_extent_page_no;
preq.m_page.m_file_no = req.key.m_file_no;
Uint32 SZ= File_formats::Datafile::EXTENT_HEADER_BITMASK_BITS_PER_PAGE;
@@ -1891,11 +1866,11 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal)
File_formats::Datafile::Extent_page* page =
(File_formats::Datafile::Extent_page*)ptr_p;
- header= page->get_header(extent_no, size);
+ header= page->get_header(val.m_extent_no, val.m_extent_size);
ndbrequire(header->m_table == req.request.table_id);
- Uint32 page_no_in_extent = (req.key.m_page_no - data_off) % size;
+ Uint32 page_no_in_extent = calc_page_no_in_extent(req.key.m_page_no, &val);
Uint32 word = header->get_free_word_offset(page_no_in_extent);
Uint32 shift = SZ * (page_no_in_extent & 7);
@@ -1912,7 +1887,7 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal)
* Search
*/
Uint32 *src= header->m_page_bitmask + word;
- for(page_no= page_no_in_extent; page_no<size; page_no++)
+ for(page_no= page_no_in_extent; page_no<val.m_extent_size; page_no++)
{
src_bits= (* src >> shift) & ((1 << SZ) - 1);
if((src_bits & UNCOMMITTED_MASK) <= reqbits)
@@ -1955,15 +1930,26 @@ Tsman::execALLOC_PAGE_REQ(Signal* signal)
found:
header->update_free_bits(page_no, src_bits | UNCOMMITTED_MASK);
rep->bits= (src_bits & UNCOMMITTED_MASK) >> UNCOMMITTED_SHIFT;
- rep->key.m_page_no= data_off + extent * size + page_no;
+ rep->key.m_page_no=
+ val.m_extent_pages + val.m_extent_no * val.m_extent_size + page_no;
rep->reply.errorCode= 0;
return;
}
void
+Tsman::execLCP_FRAG_ORD(Signal* signal)
+{
+ jamEntry();
+ ndbrequire(!m_lcp_ongoing);
+ m_lcp_ongoing = true;
+}
+
+void
Tsman::execEND_LCP_REQ(Signal* signal)
{
jamEntry();
+ ndbrequire(m_lcp_ongoing);
+ m_lcp_ongoing = false;
/**
* Move extents from "lcp" free list to real free list
diff --git a/storage/ndb/src/kernel/blocks/tsman.hpp b/storage/ndb/src/kernel/blocks/tsman.hpp
index 7c92dfcb068..018d648de07 100644
--- a/storage/ndb/src/kernel/blocks/tsman.hpp
+++ b/storage/ndb/src/kernel/blocks/tsman.hpp
@@ -63,6 +63,7 @@ protected:
void execALLOC_PAGE_REQ(Signal* signal);
+ void execLCP_FRAG_ORD(Signal*);
void execEND_LCP_REQ(Signal*);
void end_lcp(Signal*, Uint32 tablespace, Uint32 list, Uint32 file);
@@ -108,6 +109,7 @@ public:
Uint32 m_offset_data_pages; // 1(zero) + extent header pages
Uint32 m_data_pages;
Uint32 m_used_extent_cnt;
+ Uint32 m_extent_headers_per_extent_page;
} m_online;
struct {
Uint32 m_senderData;
@@ -196,6 +198,7 @@ private:
Datafile_pool m_file_pool;
Tablespace_pool m_tablespace_pool;
+ bool m_lcp_ongoing;
Datafile_hash m_file_hash;
Tablespace_list m_tablespace_list;
Tablespace_hash m_tablespace_hash;
@@ -226,15 +229,52 @@ private:
void release_extent_pages(Signal* signal, Ptr<Datafile> ptr);
void release_extent_pages_callback(Signal*, Uint32, Uint32);
+
+ struct req
+ {
+ Uint32 m_extent_pages;
+ Uint32 m_extent_size;
+ Uint32 m_extent_no; // on extent page
+ Uint32 m_extent_page_no;
+ };
+
+ struct req lookup_extent(Uint32 page_no, const Datafile*) const;
+ Uint32 calc_page_no_in_extent(Uint32 page_no, const struct req* val) const;
};
+inline
+Tsman::req
+Tsman::lookup_extent(Uint32 page_no, const Datafile * filePtrP) const
+{
+ struct req val;
+ val.m_extent_size = filePtrP->m_extent_size;
+ val.m_extent_pages = filePtrP->m_online.m_offset_data_pages;
+ Uint32 per_page = filePtrP->m_online.m_extent_headers_per_extent_page;
+
+ Uint32 extent =
+ (page_no - val.m_extent_pages) / val.m_extent_size + per_page;
+
+ val.m_extent_page_no = extent / per_page;
+ val.m_extent_no = extent % per_page;
+ return val;
+}
+
+inline
+Uint32
+Tsman::calc_page_no_in_extent(Uint32 page_no, const Tsman::req* val) const
+{
+ return (page_no - val->m_extent_pages) % val->m_extent_size;
+}
+
class Tablespace_client
{
+public:
Tsman * m_tsman;
Signal* m_signal;
Uint32 m_table_id;
Uint32 m_fragment_id;
Uint32 m_tablespace_id;
+
public:
Tablespace_client(Signal* signal, Tsman* tsman,
Uint32 table, Uint32 fragment, Uint32 tablespaceId) {
@@ -244,6 +284,8 @@ public:
m_fragment_id= fragment;
m_tablespace_id= tablespaceId;
}
+
+ Tablespace_client(Signal* signal, Tsman* tsman, Local_key* key);
/**
* Return >0 if success, no of pages in extent, sets key
@@ -274,7 +316,7 @@ public:
/**
* Free extent
*/
- int free_extent(Local_key* key);
+ int free_extent(Local_key* key, Uint64 lsn);
/**
* Update page free bits
@@ -307,6 +349,11 @@ public:
* <0 - on error
*/
int get_tablespace_info(CreateFilegroupImplReq* rep);
+
+ /**
+ * Update lsn of page corresponing to key
+ */
+ int update_lsn(Local_key* key, Uint64 lsn);
};
#include <signaldata/Extent.hpp>
@@ -351,12 +398,14 @@ Tablespace_client::alloc_page_from_extent(Local_key* key, Uint32 bits)
inline
int
-Tablespace_client::free_extent(Local_key* key)
+Tablespace_client::free_extent(Local_key* key, Uint64 lsn)
{
FreeExtentReq* req = (FreeExtentReq*)m_signal->theData;
req->request.key = *key;
req->request.table_id = m_table_id;
req->request.tablespace_id = m_tablespace_id;
+ req->request.lsn_hi = (Uint32)(lsn >> 32);
+ req->request.lsn_lo = (Uint32)(lsn & 0xFFFFFFFF);
m_tsman->execFREE_EXTENT_REQ(m_signal);
if(req->reply.errorCode == 0){
@@ -407,5 +456,4 @@ Tablespace_client::restart_undo_page_free_bits(Local_key* key,
page_lsn);
}
-
#endif
diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
index 0a5700cd5b2..c61288e5b7c 100644
--- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -1288,6 +1288,18 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
"0",
"0",
STR_VALUE(MAX_INT_RNIL) },
+
+ {
+ CFG_DB_MEMREPORT_FREQUENCY,
+ "MemReportFrequency",
+ DB_TOKEN,
+ "Frequency of mem reports in seconds, 0 = only when passing %-limits",
+ ConfigInfo::CI_USED,
+ false,
+ ConfigInfo::CI_INT,
+ "0",
+ "0",
+ STR_VALUE(MAX_INT_RNIL) },
/***************************************************************************
* API
diff --git a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
index 0a849f6e00e..29cf869d7bf 100644
--- a/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/storage/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -1921,7 +1921,7 @@ MgmtSrvr::handleStatus(NodeId nodeId, bool alive, bool nfComplete)
m_started_nodes.push_back(nodeId);
rep->setEventType(NDB_LE_Connected);
} else {
- rep->setEventType(NDB_LE_Connected);
+ rep->setEventType(NDB_LE_Disconnected);
if(nfComplete)
{
DBUG_VOID_RETURN;
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index cbf2b1f5525..ba2329888d2 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -2190,9 +2190,14 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
impl->m_replicaCount = replicaCount;
impl->m_fragmentCount = fragCount;
DBUG_PRINT("info", ("replicaCount=%x , fragCount=%x",replicaCount,fragCount));
- for(i = 0; i < (Uint32) (fragCount*replicaCount); i++)
+ Uint32 pos = 2;
+ for(i = 0; i < (Uint32) fragCount;i++)
{
- impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[i+2]));
+ pos++; // skip logpart
+ for (Uint32 j = 0; j<(Uint32)replicaCount; j++)
+ {
+ impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[pos++]));
+ }
}
Uint32 topBit = (1 << 31);
@@ -2296,7 +2301,7 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t)
}
// blob tables - use "t2" to get values set by kernel
- if (t2->m_noOfBlobs != 0 && createBlobTables(*t2) != 0) {
+ if (t2->m_noOfBlobs != 0 && createBlobTables(t, *t2) != 0) {
int save_code = m_error.code;
(void)dropTableGlobal(*t2);
m_error.code = save_code;
@@ -2310,7 +2315,7 @@ NdbDictionaryImpl::createTable(NdbTableImpl &t)
}
int
-NdbDictionaryImpl::createBlobTables(NdbTableImpl &t)
+NdbDictionaryImpl::createBlobTables(NdbTableImpl& orig, NdbTableImpl &t)
{
DBUG_ENTER("NdbDictionaryImpl::createBlobTables");
for (unsigned i = 0; i < t.m_columns.size(); i++) {
@@ -2319,6 +2324,10 @@ NdbDictionaryImpl::createBlobTables(NdbTableImpl &t)
continue;
NdbTableImpl bt;
NdbBlob::getBlobTable(bt, &t, &c);
+ NdbDictionary::Column::StorageType
+ d = NdbDictionary::Column::StorageTypeDisk;
+ if (orig.m_columns[i]->getStorageType() == d)
+ bt.getColumn("DATA")->setStorageType(d);
if (createTable(bt) != 0) {
DBUG_RETURN(-1);
}
diff --git a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index c6f6e431fba..26d7c13f968 100644
--- a/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/storage/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -581,7 +581,7 @@ public:
bool setTransporter(class TransporterFacade * tf);
int createTable(NdbTableImpl &t);
- int createBlobTables(NdbTableImpl& t);
+ int createBlobTables(NdbTableImpl& org, NdbTableImpl& created);
int alterTable(NdbTableImpl &t);
int dropTable(const char * name);
int dropTable(NdbTableImpl &);
diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp
index 7d7040a6b74..5e3738823d3 100644
--- a/storage/ndb/src/ndbapi/NdbTransaction.cpp
+++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp
@@ -476,6 +476,7 @@ NdbTransaction::executeNoBlobs(ExecType aTypeOfExec,
* This timeout situation can occur if NDB crashes.
*/
ndbout << "This timeout should never occur, execute(..)" << endl;
+ theError.code = 4012;
setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure"
DBUG_RETURN(-1);
}//if
@@ -1978,6 +1979,14 @@ NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf,
}
} else if ((tNoComp >= tNoSent) &&
(theLastExecOpInList->theCommitIndicator == 1)){
+
+ if (m_abortOption == AO_IgnoreError && theError.code != 0){
+ /**
+ * There's always a TCKEYCONF when using IgnoreError
+ */
+ return -1;
+ }
+
/**********************************************************************/
// We sent the transaction with Commit flag set and received a CONF with
// no Commit flag set. This is clearly an anomaly.
diff --git a/storage/ndb/src/ndbapi/Ndbif.cpp b/storage/ndb/src/ndbapi/Ndbif.cpp
index cd7e779d188..fba40659ec7 100644
--- a/storage/ndb/src/ndbapi/Ndbif.cpp
+++ b/storage/ndb/src/ndbapi/Ndbif.cpp
@@ -1088,6 +1088,7 @@ Ndb::check_send_timeout()
//abort();
#endif
a_con->theReleaseOnClose = true;
+ a_con->theError.code = 4012;
a_con->setOperationErrorCodeAbort(4012);
a_con->theCommitStatus = NdbTransaction::NeedAbort;
a_con->theCompletionStatus = NdbTransaction::CompletedFailure;
@@ -1275,9 +1276,9 @@ Ndb::waitCompletedTransactions(int aMilliSecondsToWait,
NDB_TICKS currTime = NdbTick_CurrentMillisecond();
NDB_TICKS maxTime = currTime + (NDB_TICKS)waitTime;
theMinNoOfEventsToWakeUp = noOfEventsToWaitFor;
+ const int maxsleep = aMilliSecondsToWait > 10 ? 10 : aMilliSecondsToWait;
do {
- if (waitTime < 1000) waitTime = 1000;
- poll_guard->wait_for_input(waitTime);
+ poll_guard->wait_for_input(maxsleep);
if (theNoOfCompletedTransactions >= (Uint32)noOfEventsToWaitFor) {
break;
}//if
diff --git a/storage/ndb/src/ndbapi/TransporterFacade.cpp b/storage/ndb/src/ndbapi/TransporterFacade.cpp
index 6e30e15a325..24bf6dbbc6a 100644
--- a/storage/ndb/src/ndbapi/TransporterFacade.cpp
+++ b/storage/ndb/src/ndbapi/TransporterFacade.cpp
@@ -1384,15 +1384,13 @@ int PollGuard::wait_for_input_in_loop(int wait_time, bool forceSend)
m_tp->forceSend(m_block_no);
else
m_tp->checkForceSend(m_block_no);
- if (wait_time == -1) //Means wait forever
- response_time= WAITFOR_RESPONSE_TIMEOUT;
- else
- response_time= wait_time;
+
NDB_TICKS curr_time = NdbTick_CurrentMillisecond();
NDB_TICKS max_time = curr_time + (NDB_TICKS)wait_time;
+ const int maxsleep = (wait_time == -1 || wait_time > 10) ? 10 : wait_time;
do
{
- wait_for_input(response_time);
+ wait_for_input(maxsleep);
Uint32 state= m_waiter->get_state();
if (state == NO_WAIT)
{
diff --git a/storage/ndb/test/ndbapi/testBasic.cpp b/storage/ndb/test/ndbapi/testBasic.cpp
index 450f1928ec3..e8e4548a91c 100644
--- a/storage/ndb/test/ndbapi/testBasic.cpp
+++ b/storage/ndb/test/ndbapi/testBasic.cpp
@@ -1249,6 +1249,29 @@ runInsertError2(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int
+runBug25090(NDBT_Context* ctx, NDBT_Step* step){
+
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary * dict = pNdb->getDictionary();
+
+ HugoOperations ops(*ctx->getTab());
+
+ int loops = ctx->getNumLoops();
+ const int rows = ctx->getNumRecords();
+
+ while (loops--)
+ {
+ ops.startTransaction(pNdb);
+ ops.pkReadRecord(pNdb, 1, 1);
+ ops.execute_Commit(pNdb, AO_IgnoreError);
+ sleep(10);
+ ops.closeTransaction(pNdb);
+ }
+
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testBasic);
TESTCASE("PkInsert",
"Verify that we can insert and delete from this table using PK"
@@ -1509,6 +1532,16 @@ TESTCASE("InsertError", "" ){
TESTCASE("InsertError2", "" ){
INITIALIZER(runInsertError2);
}
+TESTCASE("Fill",
+ "Verify what happens when we fill the db" ){
+ INITIALIZER(runFillTable);
+ INITIALIZER(runPkRead);
+ FINALIZER(runClearTable2);
+}
+TESTCASE("Bug25090",
+ "Verify what happens when we fill the db" ){
+ STEP(runBug25090);
+}
NDBT_TESTSUITE_END(testBasic);
#if 0
diff --git a/storage/ndb/test/ndbapi/testIndex.cpp b/storage/ndb/test/ndbapi/testIndex.cpp
index 68635a52289..7691f036a46 100644
--- a/storage/ndb/test/ndbapi/testIndex.cpp
+++ b/storage/ndb/test/ndbapi/testIndex.cpp
@@ -1238,7 +1238,65 @@ runBug21384(NDBT_Context* ctx, NDBT_Step* step)
return NDBT_OK;
}
+int
+runBug25059(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* pNdb = GETNDB(step);
+ NdbDictionary::Dictionary * dict = pNdb->getDictionary();
+ const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
+ ctx->getTab()->getName());
+ HugoOperations ops(*ctx->getTab(), idx);
+
+ int res = NDBT_OK;
+ int loops = ctx->getNumLoops();
+ const int rows = ctx->getNumRecords();
+
+ while (res == NDBT_OK && loops--)
+ {
+ ops.startTransaction(pNdb);
+ ops.pkReadRecord(pNdb, 10 + rand() % rows, rows);
+ int tmp;
+ if (tmp = ops.execute_Commit(pNdb, AO_IgnoreError))
+ {
+ if (tmp == 4012)
+ res = NDBT_FAILED;
+ else
+ if (ops.getTransaction()->getNdbError().code == 4012)
+ res = NDBT_FAILED;
+ }
+ ops.closeTransaction(pNdb);
+ }
+
+ loops = ctx->getNumLoops();
+ while (res == NDBT_OK && loops--)
+ {
+ ops.startTransaction(pNdb);
+ ops.pkUpdateRecord(pNdb, 10 + rand() % rows, rows);
+ int tmp;
+ int arg;
+ switch(rand() % 2){
+ case 0:
+ arg = AbortOnError;
+ break;
+ case 1:
+ arg = AO_IgnoreError;
+ ndbout_c("ignore error");
+ break;
+ }
+ if (tmp = ops.execute_Commit(pNdb, (AbortOption)arg))
+ {
+ if (tmp == 4012)
+ res = NDBT_FAILED;
+ else
+ if (ops.getTransaction()->getNdbError().code == 4012)
+ res = NDBT_FAILED;
+ }
+ ops.closeTransaction(pNdb);
+ }
+
+ return res;
+}
NDBT_TESTSUITE(testIndex);
TESTCASE("CreateAll",
@@ -1563,6 +1621,14 @@ TESTCASE("Bug21384",
FINALIZER(createPkIndex_Drop);
FINALIZER(runClearTable);
}
+TESTCASE("Bug25059",
+ "Test that unique indexes and nulls"){
+ TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ INITIALIZER(createPkIndex);
+ INITIALIZER(runLoadTable);
+ STEP(runBug25059);
+ FINALIZER(createPkIndex_Drop);
+}
NDBT_TESTSUITE_END(testIndex);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/ndbapi/testSystemRestart.cpp b/storage/ndb/test/ndbapi/testSystemRestart.cpp
index 026492d6afa..bd5cd3dd3c8 100644
--- a/storage/ndb/test/ndbapi/testSystemRestart.cpp
+++ b/storage/ndb/test/ndbapi/testSystemRestart.cpp
@@ -1161,6 +1161,64 @@ runBug21536(NDBT_Context* ctx, NDBT_Step* step)
return result;
}
+int
+runBug24664(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int result = NDBT_OK;
+ NdbRestarter restarter;
+ Ndb* pNdb = GETNDB(step);
+ const Uint32 nodeCount = restarter.getNumDbNodes();
+
+ int records = ctx->getNumRecords();
+ UtilTransactions utilTrans(*ctx->getTab());
+ HugoTransactions hugoTrans(*ctx->getTab());
+
+ int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP };
+ int dump[] = { DumpStateOrd::DihStartLcpImmediately };
+
+ int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };
+ NdbLogEventHandle handle =
+ ndb_mgm_create_logevent_handle(restarter.handle, filter);
+
+ struct ndb_logevent event;
+
+ do {
+ CHECK(restarter.dumpStateAllNodes(args, 1) == 0);
+ CHECK(restarter.dumpStateAllNodes(dump, 1) == 0);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointStarted);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointCompleted);
+
+ if (hugoTrans.loadTable(GETNDB(step), records) != 0){
+ return NDBT_FAILED;
+ }
+
+ restarter.insertErrorInAllNodes(10036); // Hang LCP
+ CHECK(restarter.dumpStateAllNodes(dump, 1) == 0);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointStarted);
+ NdbSleep_SecSleep(3);
+ CHECK(utilTrans.clearTable(pNdb, records) == 0);
+ if (hugoTrans.loadTable(GETNDB(step), records) != 0){
+ return NDBT_FAILED;
+ }
+
+ restarter.insertErrorInAllNodes(10037); // Resume LCP
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_LocalCheckpointCompleted);
+
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_GlobalCheckpointCompleted);
+ while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
+ event.type != NDB_LE_GlobalCheckpointCompleted);
+ restarter.restartAll(false, false, true);
+ CHECK(restarter.waitClusterStarted() == 0);
+ } while(false);
+
+ return result;
+}
+
NDBT_TESTSUITE(testSystemRestart);
TESTCASE("SR1",
"Basic system restart test. Focus on testing restart from REDO log.\n"
@@ -1333,6 +1391,14 @@ TESTCASE("Bug21536",
STEP(runBug21536);
FINALIZER(runClearTable);
}
+TESTCASE("Bug24664",
+ "Check handling of LCP skip/keep")
+{
+ INITIALIZER(runWaitStarted);
+ INITIALIZER(runClearTable);
+ STEP(runBug24664);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testSystemRestart);
int main(int argc, const char** argv){
diff --git a/storage/ndb/test/run-test/daily-basic-tests.txt b/storage/ndb/test/run-test/daily-basic-tests.txt
index ba4d9ece8d4..9fa6407b823 100644
--- a/storage/ndb/test/run-test/daily-basic-tests.txt
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt
@@ -231,6 +231,14 @@ max-time: 500
cmd: testTimeout
args: T1
+max-time: 500
+cmd: testBasic
+args: -n Bug25090 T1
+
+max-time: 500
+cmd: testIndex
+args: -n Bug25059 -r 3000 T1
+
# SCAN TESTS
#
max-time: 500
@@ -752,6 +760,10 @@ max-time: 300
cmd: testNodeRestart
args: -n Bug24543 T1
+max-time: 1500
+cmd: testSystemRestart
+args: -n Bug24664
+
# OLD FLEX
max-time: 500
cmd: flexBench