From: magnus.blaudd Date: May 7 2012 8:52am Subject: bzr push into mysql-5.5-cluster-7.3 branch (magnus.blaudd:3885 to 3886) List-Archive: http://lists.mysql.com/commits/144208 Message-Id: <201205070852.q478qMuL022077@acsmt357.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3886 magnus.blaudd@stripped 2012-05-07 [merge] Merge 7.2 -> 7.3 modified: storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordDeleteOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordIndexScanOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordKeyOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordScanOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordTableScanOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordUniqueKeyOperationImpl.java storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java storage/ndb/include/kernel/signaldata/ScanFrag.hpp storage/ndb/include/util/SocketAuthenticator.hpp storage/ndb/src/common/transporter/Transporter.cpp storage/ndb/src/common/transporter/Transporter.hpp storage/ndb/src/common/util/SocketAuthenticator.cpp storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp storage/ndb/test/include/HugoTransactions.hpp storage/ndb/test/include/NdbTimer.hpp storage/ndb/test/ndbapi/testUpgrade.cpp storage/ndb/test/src/HugoTransactions.cpp storage/ndb/test/tools/connect.cpp 3885 Ole John Aske 2012-05-04 [merge] Merge cluster-7.2 -> cluster-7.3 modified: sql/ha_ndbcluster.cc === modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java' --- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java 2012-04-11 09:56:27 +0000 +++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/query/QueryDomainTypeImpl.java 2012-05-07 07:51:09 +0000 @@ -198,89 +198,104 @@ public class QueryDomainTypeImpl impl context.setExplain(explain); ResultData result = null; Index storeIndex; + Operation op = null; - switch (scanType) { + try { + switch (scanType) { - case PRIMARY_KEY: { - if (logger.isDetailEnabled()) logger.detail("Using primary key find for query."); - // perform a select operation - Operation op = session.getSelectOperation(domainTypeHandler.getStoreTable()); - op.beginDefinition(); - // set key values into the operation - index.operationSetKeys(context, op); - // set the expected columns into the operation - domainTypeHandler.operationGetValues(op); - op.endDefinition(); - // execute the select and get results - result = op.resultData(); - break; - } + case PRIMARY_KEY: { + if (logger.isDetailEnabled()) logger.detail("Using primary key find for query."); + // perform a select operation + op = session.getSelectOperation(domainTypeHandler.getStoreTable()); + op.beginDefinition(); + // set key values into the operation + index.operationSetKeys(context, op); + // set the expected columns into the operation + domainTypeHandler.operationGetValues(op); + op.endDefinition(); + // execute the select and get results + result = op.resultData(); + break; + } - case INDEX_SCAN: { - storeIndex = index.getStoreIndex(); - if (logger.isDetailEnabled()) logger.detail("Using index scan with ordered index " + index.getIndexName() + " for query."); - IndexScanOperation op; - // perform an index scan operation - if (index.isMultiRange()) { - op = session.getIndexScanOperationMultiRange(storeIndex, domainTypeHandler.getStoreTable()); - - } else { - op = session.getIndexScanOperation(storeIndex, domainTypeHandler.getStoreTable()); - - } - op.beginDefinition(); - // set the expected columns into the operation - domainTypeHandler.operationGetValues(op); - // set the bounds into the operation - index.operationSetBounds(context, op); - // set additional filter conditions - where.filterCmpValue(context, op); - op.endDefinition(); - // execute the scan and get results - result = op.resultData(); - break; - } + case INDEX_SCAN: { + storeIndex = index.getStoreIndex(); + if (logger.isDetailEnabled()) logger.detail("Using index scan with ordered index " + index.getIndexName() + " for query."); + // perform an index scan operation + if (index.isMultiRange()) { + op = session.getIndexScanOperationMultiRange(storeIndex, domainTypeHandler.getStoreTable()); + + } else { + op = session.getIndexScanOperation(storeIndex, domainTypeHandler.getStoreTable()); + + } + op.beginDefinition(); + // set the expected columns into the operation + domainTypeHandler.operationGetValues(op); + // set the bounds into the operation + index.operationSetBounds(context, (IndexScanOperation)op); + // set additional filter conditions + where.filterCmpValue(context, (IndexScanOperation)op); + op.endDefinition(); + // execute the scan and get results + result = op.resultData(); + break; + } - case TABLE_SCAN: { - if (logger.isDetailEnabled()) logger.detail("Using table scan for query."); - // perform a table scan operation - ScanOperation op = session.getTableScanOperation(domainTypeHandler.getStoreTable()); - op.beginDefinition(); - // set the expected columns into the operation - domainTypeHandler.operationGetValues(op); - // set filter conditions into the operation - if (where != null) { - where.filterCmpValue(context, op); - } - op.endDefinition(); - // execute the scan and get results - result = op.resultData(); - break; - } + case TABLE_SCAN: { + if (logger.isDetailEnabled()) logger.detail("Using table scan for query."); + // perform a table scan operation + op = session.getTableScanOperation(domainTypeHandler.getStoreTable()); + op.beginDefinition(); + // set the expected columns into the operation + domainTypeHandler.operationGetValues(op); + // set filter conditions into the operation + if (where != null) { + where.filterCmpValue(context, (ScanOperation)op); + } + op.endDefinition(); + // execute the scan and get results + result = op.resultData(); + break; + } - case UNIQUE_KEY: { - storeIndex = index.getStoreIndex(); - if (logger.isDetailEnabled()) logger.detail("Using lookup with unique index " + index.getIndexName() + " for query."); - // perform a unique lookup operation - IndexOperation op = session.getUniqueIndexOperation(storeIndex, domainTypeHandler.getStoreTable()); - op.beginDefinition(); - // set the keys of the indexName into the operation - where.operationEqual(context, op); - // set the expected columns into the operation - //domainTypeHandler.operationGetValuesExcept(op, indexName); - domainTypeHandler.operationGetValues(op); - op.endDefinition(); - // execute the select and get results - result = op.resultData(); - break; - } + case UNIQUE_KEY: { + storeIndex = index.getStoreIndex(); + if (logger.isDetailEnabled()) logger.detail("Using lookup with unique index " + index.getIndexName() + " for query."); + // perform a unique lookup operation + op = session.getUniqueIndexOperation(storeIndex, domainTypeHandler.getStoreTable()); + op.beginDefinition(); + // set the keys of the indexName into the operation + where.operationEqual(context, op); + // set the expected columns into the operation + //domainTypeHandler.operationGetValuesExcept(op, indexName); + domainTypeHandler.operationGetValues(op); + op.endDefinition(); + // execute the select and get results + result = op.resultData(); + break; + } - default: - session.failAutoTransaction(); - throw new ClusterJFatalInternalException( - local.message("ERR_Illegal_Scan_Type", scanType)); + default: + session.failAutoTransaction(); + throw new ClusterJFatalInternalException( + local.message("ERR_Illegal_Scan_Type", scanType)); + } + } + catch (ClusterJException ex) { + if (op != null) { + op.freeResourcesAfterExecute(); + } + session.failAutoTransaction(); + throw ex; + } catch (Exception ex) { + if (op != null) { + op.freeResourcesAfterExecute(); + } + session.failAutoTransaction(); + throw new ClusterJException( + local.message("ERR_Exception_On_Query"), ex); } - context.deleteFilters(); return result; } @@ -307,6 +322,7 @@ public class QueryDomainTypeImpl impl int errorCode = 0; Index storeIndex; session.startAutoTransaction(); + Operation op = null; try { switch (scanType) { @@ -314,7 +330,7 @@ public class QueryDomainTypeImpl impl case PRIMARY_KEY: { // perform a delete by primary key operation if (logger.isDetailEnabled()) logger.detail("Using delete by primary key."); - Operation op = session.getDeleteOperation(domainTypeHandler.getStoreTable()); + op = session.getDeleteOperation(domainTypeHandler.getStoreTable()); op.beginDefinition(); // set key values into the operation index.operationSetKeys(context, op); @@ -332,7 +348,7 @@ public class QueryDomainTypeImpl impl if (logger.isDetailEnabled()) logger.detail( "Using delete by unique key " + index.getIndexName()); // perform a delete by unique key operation - IndexOperation op = session.getUniqueIndexDeleteOperation(storeIndex, + op = session.getUniqueIndexDeleteOperation(storeIndex, domainTypeHandler.getStoreTable()); // set the keys of the indexName into the operation where.operationEqual(context, op); @@ -349,31 +365,31 @@ public class QueryDomainTypeImpl impl if (logger.isDetailEnabled()) logger.detail( "Using delete by index scan with index " + index.getIndexName()); // perform an index scan operation - IndexScanOperation op = session.getIndexScanDeleteOperation(storeIndex, + op = session.getIndexScanDeleteOperation(storeIndex, domainTypeHandler.getStoreTable()); // set the expected columns into the operation domainTypeHandler.operationGetValues(op); // set the bounds into the operation - index.operationSetBounds(context, op); + index.operationSetBounds(context, (IndexScanOperation)op); // set additional filter conditions - where.filterCmpValue(context, op); + where.filterCmpValue(context, (IndexScanOperation)op); // delete results of the scan; don't abort if no row found - result = session.deletePersistentAll(op, false); + result = session.deletePersistentAll((IndexScanOperation)op, false); break; } case TABLE_SCAN: { if (logger.isDetailEnabled()) logger.detail("Using delete by table scan"); // perform a table scan operation - ScanOperation op = session.getTableScanDeleteOperation(domainTypeHandler.getStoreTable()); + op = session.getTableScanDeleteOperation(domainTypeHandler.getStoreTable()); // set the expected columns into the operation domainTypeHandler.operationGetValues(op); // set the bounds into the operation if (where != null) { - where.filterCmpValue(context, op); + where.filterCmpValue(context, (ScanOperation)op); } // delete results of the scan; don't abort if no row found - result = session.deletePersistentAll(op, false); + result = session.deletePersistentAll((ScanOperation)op, false); break; } @@ -381,13 +397,18 @@ public class QueryDomainTypeImpl impl throw new ClusterJFatalInternalException( local.message("ERR_Illegal_Scan_Type", scanType)); } - context.deleteFilters(); session.endAutoTransaction(); return result; } catch (ClusterJException e) { + if (op != null) { + op.freeResourcesAfterExecute(); + } session.failAutoTransaction(); throw e; } catch (Exception e) { + if (op != null) { + op.freeResourcesAfterExecute(); + } session.failAutoTransaction(); throw new ClusterJException(local.message("ERR_Exception_On_Query"), e); } @@ -492,12 +513,17 @@ public class QueryDomainTypeImpl impl throw new ClusterJFatalInternalException( local.message("ERR_Illegal_Scan_Type", scanType)); } - context.deleteFilters(); return result; } catch (ClusterJException e) { + for (Operation op: ops) { + op.freeResourcesAfterExecute(); + } session.failAutoTransaction(); throw e; } catch (Exception e) { + for (Operation op: ops) { + op.freeResourcesAfterExecute(); + } session.failAutoTransaction(); throw new ClusterJException(local.message("ERR_Exception_On_Query"), e); } === modified file 'storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java' --- a/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java 2012-03-05 22:28:15 +0000 +++ b/storage/ndb/clusterj/clusterj-core/src/main/java/com/mysql/clusterj/core/store/Operation.java 2012-05-06 13:55:09 +0000 @@ -97,4 +97,6 @@ public interface Operation { public int getClassification(); + public void freeResourcesAfterExecute(); + } === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java 2012-04-02 20:43:14 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/DbImpl.java 2012-05-06 13:55:09 +0000 @@ -26,9 +26,13 @@ import com.mysql.ndbjtie.ndbapi.Ndb.Key_ import com.mysql.ndbjtie.ndbapi.Ndb.Key_part_ptrArray; import com.mysql.ndbjtie.ndbapi.NdbErrorConst; +import com.mysql.ndbjtie.ndbapi.NdbInterpretedCode; +import com.mysql.ndbjtie.ndbapi.NdbScanFilter; import com.mysql.ndbjtie.ndbapi.NdbTransaction; import com.mysql.ndbjtie.ndbapi.NdbDictionary.Dictionary; import com.mysql.ndbjtie.ndbapi.NdbDictionary.TableConst; +import com.mysql.ndbjtie.ndbapi.NdbIndexScanOperation.IndexBound; +import com.mysql.ndbjtie.ndbapi.NdbScanOperation.ScanOptions; import com.mysql.clusterj.ClusterJDatastoreException; import com.mysql.clusterj.ClusterJFatalInternalException; @@ -84,6 +88,30 @@ class DbImpl implements com.mysql.cluste /** The ClusterConnection */ private ClusterConnectionImpl clusterConnection; + /** The number of IndexBound created */ + private int numberOfIndexBoundCreated; + + /** The number of IndexBound deleted */ + private int numberOfIndexBoundDeleted; + + /** The number of InterpretedCode created */ + private int numberOfInterpretedCodeCreated; + + /** The number of InterpretedCode deleted */ + private int numberOfInterpretedCodeDeleted; + + /** The number of NdbScanFilters created */ + private int numberOfNdbScanFilterCreated; + + /** The number of NdbScanFilters deleted */ + private int numberOfNdbScanFilterDeleted; + + /** The number of ScanOptions created */ + private int numberOfScanOptionsCreated; + + /** The number of ScanOptions deleted */ + private int numberOfScanOptionsDeleted; + public DbImpl(ClusterConnectionImpl clusterConnection, Ndb ndb, int maxTransactions) { this.clusterConnection = clusterConnection; this.ndb = ndb; @@ -95,6 +123,23 @@ class DbImpl implements com.mysql.cluste } public void close() { + // check the counts of interface objects created versus deleted + if (numberOfIndexBoundCreated != numberOfIndexBoundDeleted) { + logger.warn("numberOfIndexBoundCreated " + numberOfIndexBoundCreated + + " != numberOfIndexBoundDeleted " + numberOfIndexBoundDeleted); + } + if (numberOfInterpretedCodeCreated != numberOfInterpretedCodeDeleted) { + logger.warn("numberOfInterpretedCodeCreated " + numberOfInterpretedCodeCreated + + " != numberOfInterpretedCodeDeleted " + numberOfInterpretedCodeDeleted); + } + if (numberOfNdbScanFilterCreated != numberOfNdbScanFilterDeleted) { + logger.warn("numberOfNdbScanFilterCreated " + numberOfNdbScanFilterCreated + + " != numberOfNdbScanFilterDeleted " + numberOfNdbScanFilterDeleted); + } + if (numberOfScanOptionsCreated != numberOfScanOptionsDeleted) { + logger.warn("numberOfScanOptionsCreated " + numberOfScanOptionsCreated + + " != numberOfScanOptionsDeleted " + numberOfScanOptionsDeleted); + } if (ndb != null) { Ndb.delete(ndb); ndb = null; @@ -376,4 +421,44 @@ class DbImpl implements com.mysql.cluste return clusterConnection.newNdbRecordOperationImpl(this, storeTable); } + public IndexBound createIndexBound() { + ++numberOfIndexBoundCreated; + return IndexBound.create(); + } + + public void delete(IndexBound ndbIndexBound) { + ++numberOfIndexBoundDeleted; + IndexBound.delete(ndbIndexBound); + } + + public NdbInterpretedCode createInterpretedCode(TableConst ndbTable, int[] buffer, int i) { + ++numberOfInterpretedCodeCreated; + return NdbInterpretedCode.create(ndbTable, buffer, i); + } + + public void delete(NdbInterpretedCode ndbInterpretedCode) { + ++numberOfInterpretedCodeDeleted; + NdbInterpretedCode.delete(ndbInterpretedCode); + } + + public NdbScanFilter createScanFilter(NdbInterpretedCode ndbInterpretedCode) { + ++numberOfNdbScanFilterCreated; + return NdbScanFilter.create(ndbInterpretedCode); + } + + public void delete(NdbScanFilter ndbScanFilter) { + ++numberOfNdbScanFilterDeleted; + NdbScanFilter.delete(ndbScanFilter); + } + + public ScanOptions createScanOptions() { + ++numberOfScanOptionsCreated; + return ScanOptions.create(); + } + + public void delete(ScanOptions scanOptions) { + ++numberOfScanOptionsDeleted; + ScanOptions.delete(scanOptions); + } + } === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordDeleteOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordDeleteOperationImpl.java 2012-03-05 22:28:15 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordDeleteOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -43,6 +43,11 @@ public class NdbRecordDeleteOperationImp public void endDefinition() { // create the delete operation ndbOperation = delete(clusterTransaction); + clusterTransaction.postExecuteCallback(new Runnable() { + public void run() { + freeResourcesAfterExecute(); + } + }); } @Override === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordIndexScanOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordIndexScanOperationImpl.java 2012-04-05 15:12:21 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordIndexScanOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -90,6 +90,9 @@ public class NdbRecordIndexScanOperation /** The list of index bounds already defined; null for a single range */ List ndbIndexBoundList = null; + /** The single index bound for a single range scan */ + NdbIndexScanOperation.IndexBound ndbIndexBound = null; + public NdbRecordIndexScanOperationImpl(ClusterTransactionImpl clusterTransaction, Index storeIndex, Table storeTable, int lockMode) { this(clusterTransaction, storeIndex, storeTable, false, lockMode); @@ -128,10 +131,16 @@ public class NdbRecordIndexScanOperation } } else { // only one range defined - NdbIndexScanOperation.IndexBound ndbIndexBound = getNdbIndexBound(); + ndbIndexBound = getNdbIndexBound(); int returnCode = ndbIndexScanOperation.setBound(ndbRecordKeys.getNdbRecord(), ndbIndexBound); handleError(returnCode, ndbIndexScanOperation); } + clusterTransaction.postExecuteCallback(new Runnable() { + // free structures used to define operation + public void run() { + freeResourcesAfterExecute(); + } + }); } public void setBoundBigInteger(Column storeColumn, BoundType type, BigInteger value) { @@ -321,8 +330,8 @@ public class NdbRecordIndexScanOperation reclaimed = indexBoundLowBuffer; indexBoundLowBuffer = indexBoundHighBuffer; } - // set the index bound - NdbIndexScanOperation.IndexBound ndbindexBound = NdbIndexScanOperation.IndexBound.create(); + // create the index bound; use a local variable that will be used for either the single or list of bounds + NdbIndexScanOperation.IndexBound ndbindexBound = db.createIndexBound(); ndbindexBound.low_key(indexBoundLowBuffer); ndbindexBound.high_key(indexBoundHighBuffer); ndbindexBound.low_key_count(indexBoundLowCount); @@ -356,4 +365,21 @@ public class NdbRecordIndexScanOperation } } + /** Free resources used by this scan after the scan is executed. + * + */ + public void freeResourcesAfterExecute() { + super.freeResourcesAfterExecute(); + if (ndbIndexBound != null) { + db.delete(ndbIndexBound); + ndbIndexBound = null; + } + if (ndbIndexBoundList != null) { + for (NdbIndexScanOperation.IndexBound ndbindexBound: ndbIndexBoundList) { + db.delete(ndbindexBound); + } + ndbIndexBoundList = null; + } + } + } === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordKeyOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordKeyOperationImpl.java 2012-04-02 20:43:14 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordKeyOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -37,6 +37,11 @@ public class NdbRecordKeyOperationImpl e ndbRecordValues.getNdbRecord(), valueBuffer, mask, null); // set the NdbBlob for all active blob columns activateBlobs(); + clusterTransaction.postExecuteCallback(new Runnable() { + public void run() { + freeResourcesAfterExecute(); + } + }); } @Override === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java 2012-04-05 05:45:15 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -110,6 +110,9 @@ public class NdbRecordOperationImpl impl /** The number of columns */ int numberOfColumns; + /** The db for this operation */ + protected DbImpl db; + /** Constructor used for smart value handler for new instances, * and the cluster transaction is not yet known. There is only one * NdbRecord and one buffer, so all operations result in using @@ -120,6 +123,7 @@ public class NdbRecordOperationImpl impl * @param storeTable the store table */ public NdbRecordOperationImpl(ClusterConnectionImpl clusterConnection, Db db, Table storeTable) { + this.db = (DbImpl)db; this.storeTable = storeTable; this.tableName = storeTable.getName(); this.ndbRecordValues = clusterConnection.getCachedNdbRecordImpl(storeTable); @@ -141,6 +145,7 @@ public class NdbRecordOperationImpl impl */ public NdbRecordOperationImpl(ClusterTransactionImpl clusterTransaction, Table storeTable) { this.clusterTransaction = clusterTransaction; + this.db = clusterTransaction.db; this.bufferManager = clusterTransaction.getBufferManager(); this.tableName = storeTable.getName(); this.ndbRecordValues = clusterTransaction.getCachedNdbRecordImpl(storeTable); @@ -768,6 +773,10 @@ public class NdbRecordOperationImpl impl // by default, nothing to do } + public void freeResourcesAfterExecute() { + // by default, nothing to do + } + public String dumpValues() { return ndbRecordValues.dumpValues(valueBuffer, mask); } === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordScanOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordScanOperationImpl.java 2012-04-02 20:43:14 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordScanOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -82,20 +82,25 @@ public abstract class NdbRecordScanOpera return " scan " + tableName; } - /** Deallocate resources used in by this scan after the scan is complete. + /** Close the ndbOperation used by this scan after the scan is complete. * */ public void close() { + ((NdbScanOperation)ndbOperation).close(true, true); + } + + /** Deallocate resources used by this scan after the scan is executed */ + public void freeResourcesAfterExecute() { + super.freeResourcesAfterExecute(); if (ndbInterpretedCode != null) { - NdbInterpretedCode.delete(ndbInterpretedCode); + db.delete(ndbInterpretedCode); } if (ndbScanFilter != null) { - NdbScanFilter.delete(ndbScanFilter); + db.delete(ndbScanFilter); } if (scanOptions != null) { - ScanOptions.delete(scanOptions); + db.delete(scanOptions); } - ((NdbScanOperation)ndbOperation).close(true, true); } public void deleteCurrentTuple() { @@ -113,7 +118,7 @@ public abstract class NdbRecordScanOpera if (multiRange | (ndbScanFilter != null) | (lockMode != com.mysql.ndbjtie.ndbapi.NdbOperationConst.LockMode.LM_CommittedRead)) { - scanOptions = ScanOptions.create(); + scanOptions = db.createScanOptions(); if (multiRange) { flags |= ScanFlag.SF_MultiRange; options |= (long)Type.SO_SCANFLAGS; @@ -162,8 +167,9 @@ public abstract class NdbRecordScanOpera */ public ScanFilter getScanFilter(QueryExecutionContext context) { - ndbInterpretedCode = NdbInterpretedCode.create(ndbRecordValues.getNdbTable(), null, 0); - ndbScanFilter = NdbScanFilter.create(ndbInterpretedCode); + ndbInterpretedCode = db.createInterpretedCode(ndbRecordValues.getNdbTable(), null, 0); + handleError(ndbInterpretedCode, ndbOperation); + ndbScanFilter = db.createScanFilter(ndbInterpretedCode); handleError(ndbScanFilter, ndbOperation); ScanFilter scanFilter = new ScanFilterImpl(ndbScanFilter); context.addFilter(scanFilter); === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordTableScanOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordTableScanOperationImpl.java 2012-04-02 20:43:14 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordTableScanOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -35,6 +35,11 @@ public class NdbRecordTableScanOperation getScanOptions(); // create the ndb scan operation ndbOperation = clusterTransaction.scanTable(ndbRecordValues.getNdbRecord(), mask, scanOptions); + clusterTransaction.postExecuteCallback(new Runnable() { + public void run() { + freeResourcesAfterExecute(); + } + }); } } === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordUniqueKeyOperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordUniqueKeyOperationImpl.java 2012-04-02 20:43:14 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/NdbRecordUniqueKeyOperationImpl.java 2012-05-06 13:55:09 +0000 @@ -43,6 +43,11 @@ public class NdbRecordUniqueKeyOperation ndbRecordValues.getNdbRecord(), valueBuffer, mask, null); // set the NdbBlob for all active blob columns activateBlobs(); + clusterTransaction.postExecuteCallback(new Runnable() { + public void run() { + freeResourcesAfterExecute(); + } + }); } @Override === modified file 'storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java' --- a/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java 2012-03-29 00:25:53 +0000 +++ b/storage/ndb/clusterj/clusterj-tie/src/main/java/com/mysql/clusterj/tie/OperationImpl.java 2012-05-06 13:55:09 +0000 @@ -340,4 +340,8 @@ class OperationImpl implements Operation return ndbOperation.getNdbError().status(); } + public void freeResourcesAfterExecute() { + + } + } === modified file 'storage/ndb/include/kernel/signaldata/ScanFrag.hpp' --- a/storage/ndb/include/kernel/signaldata/ScanFrag.hpp 2011-11-16 08:17:17 +0000 +++ b/storage/ndb/include/kernel/signaldata/ScanFrag.hpp 2012-05-07 07:51:09 +0000 @@ -89,6 +89,7 @@ public: static void setDescendingFlag(Uint32 & requestInfo, Uint32 descending); static void setTupScanFlag(Uint32 & requestInfo, Uint32 tupScan); static void setAttrLen(Uint32 & requestInfo, Uint32 attrLen); + static void clearAttrLen(Uint32 & requestInfo); static void setScanPrio(Uint32& requestInfo, Uint32 prio); static void setNoDiskFlag(Uint32& requestInfo, Uint32 val); static void setLcpScanFlag(Uint32 & requestInfo, Uint32 val); @@ -277,7 +278,7 @@ public: * 1111111111222222222233 * 01234567890123456789012345678901 * rrcdlxhkrztppppaaaaaaaaaaaaaaaa Short variant ( < 6.4.0) - * rrcdlxhkrztppppAs Long variant (6.4.0 +) + * rrcdlxhkrztppppCs Long variant (6.4.0 +) */ #define SF_LOCK_MODE_SHIFT (5) #define SF_LOCK_MODE_MASK (1) @@ -422,6 +423,13 @@ ScanFragReq::setAttrLen(UintR & requestI } inline +void +ScanFragReq::clearAttrLen(Uint32 & requestInfo) +{ + requestInfo &= ~((Uint32)SF_ATTR_LEN_MASK << SF_ATTR_LEN_SHIFT); +} + +inline Uint32 ScanFragReq::getNoDiskFlag(const Uint32 & requestInfo){ return (requestInfo >> SF_NO_DISK_SHIFT) & 1; === modified file 'storage/ndb/include/util/SocketAuthenticator.hpp' --- a/storage/ndb/include/util/SocketAuthenticator.hpp 2011-06-30 15:59:25 +0000 +++ b/storage/ndb/include/util/SocketAuthenticator.hpp 2012-05-07 07:38:13 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -18,6 +18,8 @@ #ifndef SOCKET_AUTHENTICATOR_HPP #define SOCKET_AUTHENTICATOR_HPP +#include + class SocketAuthenticator { public: @@ -29,8 +31,8 @@ public: class SocketAuthSimple : public SocketAuthenticator { - const char *m_passwd; - const char *m_username; + char *m_passwd; + char *m_username; public: SocketAuthSimple(const char *username, const char *passwd); virtual ~SocketAuthSimple(); === modified file 'storage/ndb/src/common/transporter/Transporter.cpp' --- a/storage/ndb/src/common/transporter/Transporter.cpp 2012-03-21 17:28:20 +0000 +++ b/storage/ndb/src/common/transporter/Transporter.cpp 2012-05-07 07:51:09 +0000 @@ -51,7 +51,6 @@ Transporter::Transporter(TransporterRegi DBUG_ENTER("Transporter::Transporter"); if (rHostName && strlen(rHostName) > 0){ strncpy(remoteHostName, rHostName, sizeof(remoteHostName)); - Ndb_getInAddr(&remoteHostAddress, rHostName); } else { === modified file 'storage/ndb/src/common/transporter/Transporter.hpp' --- a/storage/ndb/src/common/transporter/Transporter.hpp 2011-12-10 19:02:03 +0000 +++ b/storage/ndb/src/common/transporter/Transporter.hpp 2012-05-07 07:51:09 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -139,8 +139,6 @@ protected: */ char remoteHostName[256]; char localHostName[256]; - struct in_addr remoteHostAddress; - struct in_addr localHostAddress; int m_s_port; @@ -149,8 +147,6 @@ protected: const bool isServer; - unsigned createIndex; - int byteOrder; bool compressionUsed; bool checksumUsed; === modified file 'storage/ndb/src/common/util/SocketAuthenticator.cpp' --- a/storage/ndb/src/common/util/SocketAuthenticator.cpp 2011-06-30 15:59:25 +0000 +++ b/storage/ndb/src/common/util/SocketAuthenticator.cpp 2012-05-07 07:38:13 +0000 @@ -1,5 +1,5 @@ /* - Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,15 +15,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - #include - -#include #include #include #include -#include - SocketAuthSimple::SocketAuthSimple(const char *username, const char *passwd) { if (username) m_username= strdup(username); @@ -38,9 +33,9 @@ SocketAuthSimple::SocketAuthSimple(const SocketAuthSimple::~SocketAuthSimple() { if (m_passwd) - free((void*)m_passwd); + free(m_passwd); if (m_username) - free((void*)m_username); + free(m_username); } bool SocketAuthSimple::client_authenticate(NDB_SOCKET_TYPE sockfd) @@ -48,11 +43,18 @@ bool SocketAuthSimple::client_authentica SocketOutputStream s_output(sockfd); SocketInputStream s_input(sockfd); + // Write username and password s_output.println("%s", m_username ? m_username : ""); s_output.println("%s", m_passwd ? m_passwd : ""); char buf[16]; - if (s_input.gets(buf, 16) == 0) return false; + + // Read authentication result + if (s_input.gets(buf, sizeof(buf)) == 0) + return false; + buf[sizeof(buf)-1]= 0; + + // Verify authentication result if (strncmp("ok", buf, 2) == 0) return true; @@ -61,25 +63,24 @@ bool SocketAuthSimple::client_authentica bool SocketAuthSimple::server_authenticate(NDB_SOCKET_TYPE sockfd) { - SocketOutputStream s_output(sockfd); SocketInputStream s_input(sockfd); char buf[256]; - if (s_input.gets(buf, 256) == 0) return false; - buf[255]= 0; - if (m_username) - free((void*)m_username); - m_username= strdup(buf); - - if (s_input.gets(buf, 256) == 0) return false; - buf[255]= 0; - if (m_passwd) - free((void*)m_passwd); - m_passwd= strdup(buf); + // Read username + if (s_input.gets(buf, sizeof(buf)) == 0) + return false; + buf[sizeof(buf)-1]= 0; + + // Read password + if (s_input.gets(buf, sizeof(buf)) == 0) + return false; + buf[sizeof(buf)-1]= 0; + // Write authentication result s_output.println("ok"); return true; } + === modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp' --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-04-24 15:17:46 +0000 +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2012-05-07 07:51:09 +0000 @@ -9777,6 +9777,10 @@ void Dblqh::execSCAN_NEXTREQ(Signal* sig const Uint32 transid2 = nextReq->transId2; const Uint32 senderData = nextReq->senderData; Uint32 hashHi = signal->getSendersBlockRef(); + // bug#13834481 hashHi!=0 caused timeout (tx not found) + const NodeInfo& senderInfo = getNodeInfo(refToNode(hashHi)); + if (unlikely(senderInfo.m_version < NDBD_LONG_SCANFRAGREQ)) + hashHi = 0; if (findTransaction(transid1, transid2, senderData, hashHi) != ZOK){ jam(); @@ -10291,8 +10295,10 @@ void Dblqh::execSCAN_FRAGREQ(Signal* sig Uint32 hashIndex; TcConnectionrecPtr nextHashptr; Uint32 senderHi = signal->getSendersBlockRef(); - - const Uint32 reqinfo = scanFragReq->requestInfo; + // bug#13834481 hashHi!=0 caused timeout (tx not found) + const NodeInfo& senderInfo = getNodeInfo(refToNode(senderHi)); + if (unlikely(senderInfo.m_version < NDBD_LONG_SCANFRAGREQ)) + senderHi = 0; /* Short SCANFRAGREQ has no sections, Long SCANFRAGREQ has 1 or 2 * Section 0 : Mandatory ATTRINFO section @@ -10322,9 +10328,17 @@ void Dblqh::execSCAN_FRAGREQ(Signal* sig else { /* Short request, get Attr + Key len from signal */ - aiLen= ScanFragReq::getAttrLen(reqinfo); + aiLen= ScanFragReq::getAttrLen(scanFragReq->requestInfo); keyLen= (scanFragReq->fragmentNoKeyLen >> 16); + /* + * bug#13834481. Clear attribute length so that it is not + * re-interpreted as new 7.x bits. initScanrec() uses signal + * data so we must modify signal data. + */ + ScanFragReq::clearAttrLen(scanFragReq->requestInfo); } + + const Uint32 reqinfo = scanFragReq->requestInfo; const Uint32 fragId = (scanFragReq->fragmentNoKeyLen & 0xFFFF); tabptr.i = scanFragReq->tableId; === modified file 'storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp' --- a/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2012-04-25 09:22:21 +0000 +++ b/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp 2012-05-07 07:51:09 +0000 @@ -12039,7 +12039,11 @@ void Dbtc::sendScanFragReq(Signal* signa */ Uint32 reqAttrLen = sections.m_ptr[0].sz; ScanFragReq::setAttrLen(req->requestInfo, reqAttrLen); - req->fragmentNoKeyLen |= reqKeyLen; + /* + * bug#13834481 missing shift, causing fragment not found + * (error 1231) on 6.3 node. + */ + req->fragmentNoKeyLen |= (reqKeyLen << 16); sendSignal(scanFragP->lqhBlockref, GSN_SCAN_FRAGREQ, signal, ScanFragReq::SignalLength, JBB); if(reqKeyLen > 0) === modified file 'storage/ndb/test/include/HugoTransactions.hpp' --- a/storage/ndb/test/include/HugoTransactions.hpp 2011-07-05 12:46:07 +0000 +++ b/storage/ndb/test/include/HugoTransactions.hpp 2012-05-07 07:51:09 +0000 @@ -27,6 +27,8 @@ class NDBT_Stats; class HugoTransactions : public HugoOperations { public: + struct HugoBound { int attr; int type; const void* value; }; + HugoTransactions(const NdbDictionary::Table&, const NdbDictionary::Index* idx = 0); ~HugoTransactions(); @@ -62,7 +64,8 @@ public: int abort = 0, int parallelism = 0, NdbOperation::LockMode = NdbOperation::LM_Read, - int scan_flags = 0); + int scan_flags = 0, + int bound_cnt = 0, const HugoBound* bound_arr = 0); int pkReadRecords(Ndb*, int records, === modified file 'storage/ndb/test/include/NdbTimer.hpp' --- a/storage/ndb/test/include/NdbTimer.hpp 2011-02-02 00:40:07 +0000 +++ b/storage/ndb/test/include/NdbTimer.hpp 2012-04-23 19:00:46 +0000 @@ -23,7 +23,7 @@ #include // -// Class used for measuring time and priting the results +// Class used for measuring time and printing the results // // Currently measures time in milliseconds // === modified file 'storage/ndb/test/ndbapi/testUpgrade.cpp' --- a/storage/ndb/test/ndbapi/testUpgrade.cpp 2011-06-30 15:59:25 +0000 +++ b/storage/ndb/test/ndbapi/testUpgrade.cpp 2012-05-03 09:54:05 +0000 @@ -592,9 +592,38 @@ int runCheckStarted(NDBT_Context* ctx, N return NDBT_OK; } +int +runCreateIndexT1(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb* pNdb = GETNDB(step); + NdbDictionary::Dictionary* pDict = pNdb->getDictionary(); + const NdbDictionary::Table* pTab = pDict->getTable("T1"); + if (pTab == 0) + { + g_err << "getTable(T1) error: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + NdbDictionary::Index ind; + ind.setName("T1X1"); + ind.setTable("T1"); + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + ind.addColumn("KOL2"); + ind.addColumn("KOL3"); + ind.addColumn("KOL4"); + if (pDict->createIndex(ind, *pTab) != 0) + { + g_err << "createIndex(T1X1) error: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + return NDBT_OK; +} + int runCreateAllTables(NDBT_Context* ctx, NDBT_Step* step) { + Uint32 useRangeScanT1 = ctx->getProperty("UseRangeScanT1", (Uint32)0); + ndbout_c("createAllTables"); if (NDBT_Tables::createAllTables(GETNDB(step), false, true)) return NDBT_FAILED; @@ -602,6 +631,10 @@ runCreateAllTables(NDBT_Context* ctx, ND for (int i = 0; igetName())); + if (useRangeScanT1) + if (runCreateIndexT1(ctx, step) != NDBT_OK) + return NDBT_FAILED; + return NDBT_OK; } @@ -680,6 +713,8 @@ runClearAll(NDBT_Context* ctx, NDBT_Step int runBasic(NDBT_Context* ctx, NDBT_Step* step) { + Uint32 useRangeScanT1 = ctx->getProperty("UseRangeScanT1", (uint32)0); + Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary * pDict = pNdb->getDictionary(); int records = ctx->getNumRecords(); @@ -705,6 +740,32 @@ runBasic(NDBT_Context* ctx, NDBT_Step* s // (or check if it does) if (strcmp(tab->getName(), "T1") == 0) trans.pkInterpretedUpdateRecords(pNdb, records); + if (strcmp(tab->getName(), "T1") == 0 && + useRangeScanT1) + { + const NdbDictionary::Index* pInd = pDict->getIndex("T1X1", "T1"); + if (pInd == 0) + { + g_err << "getIndex(T1X1) error: " << pDict->getNdbError() << endl; + return NDBT_FAILED; + } + // bug#13834481 - bound values do not matter + const Uint32 lo = 0x11110000; + const Uint32 hi = 0xaaaa0000; + HugoTransactions::HugoBound bound_arr[6]; + int bound_cnt = 0; + for (int j = 0; j <= 1; j++) { + int n = rand() % 4; + for (int i = 0; i < n; i++) { + HugoTransactions::HugoBound& b = bound_arr[bound_cnt++]; + b.attr = i; + b.type = (j == 0 ? 0 : 2); // LE/GE + b.value = (j == 0 ? &lo : &hi); + } + } + g_info << "range scan T1 with " << bound_cnt << " bounds" << endl; + trans.scanReadRecords(pNdb, pInd, records, 0, 0, NdbOperation::LM_Read, 0, bound_cnt, bound_arr); + } trans.clearTable(pNdb, records/2); trans.loadTable(pNdb, records/2); break; @@ -1063,6 +1124,7 @@ POSTUPGRADE("Upgrade_FS") TESTCASE("Upgrade_Traffic", "Test upgrade with traffic, all tables and restart --initial") { + TC_PROPERTY("UseRangeScanT1", (Uint32)1); INITIALIZER(runCheckStarted); INITIALIZER(runCreateAllTables); STEP(runUpgrade_Traffic); @@ -1077,6 +1139,7 @@ POSTUPGRADE("Upgrade_Traffic") TESTCASE("Upgrade_Traffic_FS", "Test upgrade with traffic, all tables and restart using FS") { + TC_PROPERTY("UseRangeScanT1", (Uint32)1); TC_PROPERTY("KeepFS", 1); INITIALIZER(runCheckStarted); INITIALIZER(runCreateAllTables); === modified file 'storage/ndb/test/src/HugoTransactions.cpp' --- a/storage/ndb/test/src/HugoTransactions.cpp 2011-11-28 14:16:15 +0000 +++ b/storage/ndb/test/src/HugoTransactions.cpp 2012-05-07 07:51:09 +0000 @@ -200,7 +200,8 @@ HugoTransactions::scanReadRecords(Ndb* p int abortPercent, int parallelism, NdbOperation::LockMode lm, - int scan_flags) + int scan_flags, + int bound_cnt, const HugoBound* bound_arr) { int retryAttempt = 0; @@ -243,6 +244,14 @@ HugoTransactions::scanReadRecords(Ndb* p closeTransaction(pNdb); return NDBT_FAILED; } + + for (int i = 0; i < bound_cnt; i++) { + const HugoBound& b = bound_arr[i]; + if (pOp->setBound(b.attr, b.type, b.value) != 0) { + ERR(pOp->getNdbError()); + return NDBT_FAILED; + } + } for(a = 0; a