Search in sources :

Example 11 with ConglomerateController

use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.

the class TabInfoImpl method insertRowListImpl.

/**
 *	  Insert logic to insert a list of rows into a table. This logic has two
 *	  odd features.
 *
 *	  <OL>
 *	  <LI>Returns an indication if any returned row was a duplicate.
 *	  <LI>Returns the RowLocation of the last row inserted.
 *	  </OL>
 *	  @param rowList the list of rows to insert
 *	  @param tc	transaction controller
 *	  @param rowLocationOut on output rowLocationOut[0] is set to the
 *	         last RowLocation inserted.
 *	  @return row number (&gt;= 0) if duplicate row inserted into an index
 *	  			ROWNOTDUPLICATE otherwise
 */
private int insertRowListImpl(ExecRow[] rowList, TransactionController tc, RowLocation[] rowLocationOut) throws StandardException {
    ConglomerateController heapController;
    RowLocation heapLocation;
    ExecIndexRow indexableRow;
    int insertRetCode;
    int retCode = ROWNOTDUPLICATE;
    int indexCount = crf.getNumIndexes();
    ConglomerateController[] indexControllers = new ConglomerateController[indexCount];
    // Open the conglomerates
    heapController = tc.openConglomerate(getHeapConglomerate(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
    for (int ictr = 0; ictr < indexCount; ictr++) {
        long conglomNumber = getIndexConglomerate(ictr);
        if (conglomNumber > -1) {
            indexControllers[ictr] = tc.openConglomerate(conglomNumber, false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_RECORD, TransactionController.ISOLATION_REPEATABLE_READ);
        }
    }
    heapLocation = heapController.newRowLocationTemplate();
    rowLocationOut[0] = heapLocation;
    // loop through rows on this list, inserting them into system table
    for (int rowNumber = 0; rowNumber < rowList.length; rowNumber++) {
        ExecRow row = rowList[rowNumber];
        // insert the base row and get its new location
        heapController.insertAndFetchLocation(row.getRowArray(), heapLocation);
        for (int ictr = 0; ictr < indexCount; ictr++) {
            if (indexControllers[ictr] == null) {
                continue;
            }
            // Get an index row based on the base row
            indexableRow = getIndexRowFromHeapRow(getIndexRowGenerator(ictr), heapLocation, row);
            insertRetCode = indexControllers[ictr].insert(indexableRow.getRowArray());
            if (insertRetCode == ConglomerateController.ROWISDUPLICATE) {
                retCode = rowNumber;
            }
        }
    }
    // Close the open conglomerates
    for (int ictr = 0; ictr < indexCount; ictr++) {
        if (indexControllers[ictr] == null) {
            continue;
        }
        indexControllers[ictr].close();
    }
    heapController.close();
    return retCode;
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) ExecRow(org.apache.derby.iapi.sql.execute.ExecRow) RowLocation(org.apache.derby.iapi.types.RowLocation) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow)

Example 12 with ConglomerateController

use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.

the class IndexStatisticsDaemonImpl method updateIndexStatsMinion.

/**
 * Updates the index statistics for the given table and the specified
 * indexes.
 * <p>
 * <strong>API note</strong>: Using {@code null} to update the statistics
 * for all conglomerates is preferred over explicitly passing an array with
 * all the conglomerates for the table. Doing so allows for some
 * optimizations, and will cause a disposable statistics check to be
 * performed.
 *
 * @param lcc language connection context used to perform the work
 * @param td the table to update index stats for
 * @param cds the conglomerates to update statistics for (non-index
 *      conglomerates will be ignored), {@code null} means all indexes
 * @param asBackgroundTask whether the updates are done automatically as
 *      part of a background task or if explicitly invoked by the user
 * @throws StandardException if something goes wrong
 */
private void updateIndexStatsMinion(LanguageConnectionContext lcc, TableDescriptor td, ConglomerateDescriptor[] cds, boolean asBackgroundTask) throws StandardException {
    // can only properly identify disposable stats if cds == null,
    // which means we are processing all indexes on the conglomerate.
    final boolean identifyDisposableStats = (cds == null);
    // Fetch descriptors if we're updating statistics for all indexes.
    if (cds == null) {
        cds = td.getConglomerateDescriptors();
    }
    // Extract/derive information from the table descriptor
    long[] conglomerateNumber = new long[cds.length];
    ExecIndexRow[] indexRow = new ExecIndexRow[cds.length];
    TransactionController tc = lcc.getTransactionExecute();
    ConglomerateController heapCC = tc.openConglomerate(td.getHeapConglomerateId(), false, 0, TransactionController.MODE_RECORD, asBackgroundTask ? TransactionController.ISOLATION_READ_UNCOMMITTED : TransactionController.ISOLATION_REPEATABLE_READ);
    // create a list of indexes that should have statistics, by looking
    // at all indexes on the conglomerate, and conditionally skipping
    // unique single column indexes.  This set is the "non disposable
    // stat list".
    UUID[] non_disposable_objectUUID = new UUID[cds.length];
    try {
        for (int i = 0; i < cds.length; i++) {
            // Skip non-index conglomerates
            if (!cds[i].isIndex()) {
                conglomerateNumber[i] = -1;
                continue;
            }
            IndexRowGenerator irg = cds[i].getIndexDescriptor();
            // or we are running in soft-upgrade-mode on a pre 10.9 db.
            if (skipDisposableStats) {
                if (irg.isUnique() && irg.numberOfOrderedColumns() == 1) {
                    conglomerateNumber[i] = -1;
                    continue;
                }
            }
            // at this point have found a stat for an existing
            // index which is not a single column unique index, add it
            // to the list of "non disposable stats"
            conglomerateNumber[i] = cds[i].getConglomerateNumber();
            non_disposable_objectUUID[i] = cds[i].getUUID();
            indexRow[i] = irg.getNullIndexRow(td.getColumnDescriptorList(), heapCC.newRowLocationTemplate());
        }
    } finally {
        heapCC.close();
    }
    if (identifyDisposableStats) {
        // Note this loop is not controlled by the skipDisposableStats
        // flag.  The above loop controls if we drop single column unique
        // index stats or not.  In all cases we are going to drop
        // stats with no associated index (orphaned stats).
        List<StatisticsDescriptor> existingStats = td.getStatistics();
        StatisticsDescriptor[] stats = (StatisticsDescriptor[]) existingStats.toArray(new StatisticsDescriptor[existingStats.size()]);
        // those entries that don't have a matching conglomerate in the
        for (int si = 0; si < stats.length; si++) {
            UUID referencedIndex = stats[si].getReferenceID();
            boolean isValid = false;
            for (int ci = 0; ci < conglomerateNumber.length; ci++) {
                if (referencedIndex.equals(non_disposable_objectUUID[ci])) {
                    isValid = true;
                    break;
                }
            }
            // mechanism in case of another bug like DERBY-5681 in Derby.
            if (!isValid) {
                String msg = "dropping disposable statistics entry " + stats[si].getUUID() + " for index " + stats[si].getReferenceID() + " (cols=" + stats[si].getColumnCount() + ")";
                logAlways(td, null, msg);
                trace(1, msg + " on table " + stats[si].getTableUUID());
                DataDictionary dd = lcc.getDataDictionary();
                if (!lcc.dataDictionaryInWriteMode()) {
                    dd.startWriting(lcc);
                }
                dd.dropStatisticsDescriptors(td.getUUID(), stats[si].getReferenceID(), tc);
                if (asBackgroundTask) {
                    lcc.internalCommit(true);
                }
            }
        }
    }
    // [x][0] = conglomerate number, [x][1] = start time, [x][2] = stop time
    long[][] scanTimes = new long[conglomerateNumber.length][3];
    int sci = 0;
    for (int indexNumber = 0; indexNumber < conglomerateNumber.length; indexNumber++) {
        if (conglomerateNumber[indexNumber] == -1)
            continue;
        // Check if daemon has been disabled.
        if (asBackgroundTask) {
            if (isShuttingDown()) {
                break;
            }
        }
        scanTimes[sci][0] = conglomerateNumber[indexNumber];
        scanTimes[sci][1] = System.currentTimeMillis();
        // Subtract one for the RowLocation added for indexes.
        int numCols = indexRow[indexNumber].nColumns() - 1;
        long[] cardinality = new long[numCols];
        KeyComparator cmp = new KeyComparator(indexRow[indexNumber]);
        /* Read uncommitted, with record locking. Actually CS store may
               not hold record locks */
        GroupFetchScanController gsc = tc.openGroupFetchScan(conglomerateNumber[indexNumber], // hold
        false, 0, // locking
        TransactionController.MODE_RECORD, TransactionController.ISOLATION_READ_UNCOMMITTED, // scancolumnlist-- want everything.
        null, // startkeyvalue-- start from the beginning.
        null, 0, // qualifiers, none!
        null, // stopkeyvalue,
        null, 0);
        try {
            int rowsFetched = 0;
            boolean giving_up_on_shutdown = false;
            while ((rowsFetched = cmp.fetchRows(gsc)) > 0) {
                // I/O that is processed as a convenient point.
                if (asBackgroundTask) {
                    if (isShuttingDown()) {
                        giving_up_on_shutdown = true;
                        break;
                    }
                }
                for (int i = 0; i < rowsFetched; i++) {
                    int whichPositionChanged = cmp.compareWithPrevKey(i);
                    if (whichPositionChanged >= 0) {
                        for (int j = whichPositionChanged; j < numCols; j++) cardinality[j]++;
                    }
                }
            }
            if (giving_up_on_shutdown)
                break;
            gsc.setEstimatedRowCount(cmp.getRowCount());
        } finally // try
        {
            gsc.close();
            gsc = null;
        }
        scanTimes[sci++][2] = System.currentTimeMillis();
        // We have scanned the indexes, so let's give this a few attempts
        // before giving up.
        int retries = 0;
        while (true) {
            try {
                writeUpdatedStats(lcc, td, non_disposable_objectUUID[indexNumber], cmp.getRowCount(), cardinality, asBackgroundTask);
                break;
            } catch (StandardException se) {
                retries++;
                if (se.isLockTimeout() && retries < 3) {
                    trace(2, "lock timeout when writing stats, retrying");
                    sleep(100 * retries);
                } else {
                    // o too many lock timeouts
                    throw se;
                }
            }
        }
    }
    log(asBackgroundTask, td, fmtScanTimes(scanTimes));
}
Also used : StatisticsDescriptor(org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) DataDictionary(org.apache.derby.iapi.sql.dictionary.DataDictionary) GroupFetchScanController(org.apache.derby.iapi.store.access.GroupFetchScanController) ExecIndexRow(org.apache.derby.iapi.sql.execute.ExecIndexRow) StandardException(org.apache.derby.shared.common.error.StandardException) IndexRowGenerator(org.apache.derby.iapi.sql.dictionary.IndexRowGenerator) TransactionController(org.apache.derby.iapi.store.access.TransactionController) UUID(org.apache.derby.catalog.UUID)

Example 13 with ConglomerateController

use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.

the class AlterTableConstantAction method updateIndex.

private void updateIndex(long newHeapConglom, DataDictionary dd, int index, long[] newIndexCongloms) throws StandardException {
    Properties properties = new Properties();
    // Get the ConglomerateDescriptor for the index
    ConglomerateDescriptor cd = td.getConglomerateDescriptor(indexConglomerateNumbers[index]);
    // Build the properties list for the new conglomerate
    ConglomerateController indexCC = tc.openConglomerate(indexConglomerateNumbers[index], false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
    // Get the properties on the old index
    indexCC.getInternalTablePropertySet(properties);
    /* Create the properties that language supplies when creating the
		 * the index.  (The store doesn't preserve these.)
		 */
    int indexRowLength = indexRows[index].nColumns();
    properties.put("baseConglomerateId", Long.toString(newHeapConglom));
    if (cd.getIndexDescriptor().isUnique()) {
        properties.put("nUniqueColumns", Integer.toString(indexRowLength - 1));
    } else {
        properties.put("nUniqueColumns", Integer.toString(indexRowLength));
    }
    if (cd.getIndexDescriptor().isUniqueWithDuplicateNulls() && !cd.getIndexDescriptor().hasDeferrableChecking()) {
        properties.put("uniqueWithDuplicateNulls", Boolean.toString(true));
    }
    properties.put("rowLocationColumn", Integer.toString(indexRowLength - 1));
    properties.put("nKeyFields", Integer.toString(indexRowLength));
    indexCC.close();
    // We can finally drain the sorter and rebuild the index
    // Populate the index.
    RowLocationRetRowSource cCount;
    boolean statisticsExist = false;
    if (!truncateTable) {
        sorters[index].completedInserts();
        sorters[index] = null;
        if (td.statisticsExist(cd)) {
            cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
            statisticsExist = true;
        } else {
            cCount = new CardinalityCounter(tc.openSortRowSource(sortIds[index]));
        }
        newIndexCongloms[index] = tc.createAndLoadConglomerate("BTREE", indexRows[index].getRowArray(), ordering[index], collation[index], properties, TransactionController.IS_DEFAULT, cCount, (long[]) null);
        // is not empty.
        if (statisticsExist)
            dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc);
        long numRows;
        if ((numRows = ((CardinalityCounter) cCount).getRowCount()) > 0) {
            long[] c = ((CardinalityCounter) cCount).getCardinality();
            for (int i = 0; i < c.length; i++) {
                StatisticsDescriptor statDesc = new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(), cd.getUUID(), td.getUUID(), "I", new StatisticsImpl(numRows, c[i]), i + 1);
                dd.addDescriptor(statDesc, // no parent descriptor
                null, DataDictionary.SYSSTATISTICS_CATALOG_NUM, // no error on duplicate.
                true, tc);
            }
        }
    } else {
        newIndexCongloms[index] = tc.createConglomerate("BTREE", indexRows[index].getRowArray(), ordering[index], collation[index], properties, TransactionController.IS_DEFAULT);
        // rowscount is zero and existing statistic will be invalid.
        if (td.statisticsExist(cd))
            dd.dropStatisticsDescriptors(td.getUUID(), cd.getUUID(), tc);
    }
    /* Update the DataDictionary
		 *
		 * Update sys.sysconglomerates with new conglomerate #, we need to
		 * update all (if any) duplicate index entries sharing this same
		 * conglomerate.
		 */
    dd.updateConglomerateDescriptor(td.getConglomerateDescriptors(indexConglomerateNumbers[index]), newIndexCongloms[index], tc);
    // Drop the old conglomerate
    tc.dropConglomerate(indexConglomerateNumbers[index]);
}
Also used : StatisticsImpl(org.apache.derby.catalog.types.StatisticsImpl) StatisticsDescriptor(org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor) ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController) Properties(java.util.Properties) ConglomerateDescriptor(org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor) RowLocationRetRowSource(org.apache.derby.iapi.store.access.RowLocationRetRowSource)

Example 14 with ConglomerateController

use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.

the class DDLConstantAction method lockTableForDDL.

/**
 * Lock the table in exclusive or share mode to prevent deadlocks.
 *
 * @param tc						The TransactionController
 * @param heapConglomerateNumber	The conglomerate number for the heap.
 * @param exclusiveMode				Whether or not to lock the table in exclusive mode.
 *
 * @exception StandardException if schema is system schema
 */
final void lockTableForDDL(TransactionController tc, long heapConglomerateNumber, boolean exclusiveMode) throws StandardException {
    ConglomerateController cc;
    cc = tc.openConglomerate(heapConglomerateNumber, false, (exclusiveMode) ? (TransactionController.OPENMODE_FORUPDATE | TransactionController.OPENMODE_FOR_LOCK_ONLY) : TransactionController.OPENMODE_FOR_LOCK_ONLY, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
    cc.close();
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController)

Example 15 with ConglomerateController

use of org.apache.derby.iapi.store.access.ConglomerateController in project derby by apache.

the class DDLSingleTableConstantAction method loadIndexProperties.

/**
 * Get any table properties that exist for the received
 * index descriptor.
 */
private void loadIndexProperties(LanguageConnectionContext lcc, ConglomerateDescriptor congDesc, Properties ixProps) throws StandardException {
    ConglomerateController cc = lcc.getTransactionExecute().openConglomerate(congDesc.getConglomerateNumber(), false, TransactionController.OPENMODE_FORUPDATE, TransactionController.MODE_TABLE, TransactionController.ISOLATION_SERIALIZABLE);
    cc.getInternalTablePropertySet(ixProps);
    cc.close();
    return;
}
Also used : ConglomerateController(org.apache.derby.iapi.store.access.ConglomerateController)

Aggregations

ConglomerateController (org.apache.derby.iapi.store.access.ConglomerateController)73 RowLocation (org.apache.derby.iapi.types.RowLocation)40 ScanController (org.apache.derby.iapi.store.access.ScanController)32 DataValueDescriptor (org.apache.derby.iapi.types.DataValueDescriptor)32 SQLLongint (org.apache.derby.iapi.types.SQLLongint)24 ExecRow (org.apache.derby.iapi.sql.execute.ExecRow)22 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)18 Properties (java.util.Properties)14 ExecIndexRow (org.apache.derby.iapi.sql.execute.ExecIndexRow)14 StandardException (org.apache.derby.shared.common.error.StandardException)12 TransactionController (org.apache.derby.iapi.store.access.TransactionController)11 SQLChar (org.apache.derby.iapi.types.SQLChar)9 ConglomerateDescriptor (org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor)8 DataDictionary (org.apache.derby.iapi.sql.dictionary.DataDictionary)6 LanguageConnectionContext (org.apache.derby.iapi.sql.conn.LanguageConnectionContext)5 ColumnOrdering (org.apache.derby.iapi.store.access.ColumnOrdering)5 UUID (org.apache.derby.catalog.UUID)4 ColumnDescriptor (org.apache.derby.iapi.sql.dictionary.ColumnDescriptor)4 ConstraintDescriptor (org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor)4 IndexRowGenerator (org.apache.derby.iapi.sql.dictionary.IndexRowGenerator)4