Search in sources :

Example 6 with RawTransaction

use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.

the class BasePage method insertAllowOverflow.

/**
 *		Insert a row allowing overflow.
 *
 *		If handle is supplied then the record at that hanlde will be updated
 *		to indicate it is a partial row and it has an overflow portion.
 *
 *		@exception StandardException	Standard Derby error policy
 */
public RecordHandle insertAllowOverflow(int slot, Object[] row, FormatableBitSet validColumns, int startColumn, byte insertFlag, int overflowThreshold, RecordHandle nextPortionHandle) throws StandardException {
    BasePage curPage = this;
    if (!curPage.owner.updateOK()) {
        throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
    }
    // Handle of the first portion of the chain
    RecordHandle headHandle = null;
    RecordHandle handleToUpdate = null;
    RawTransaction t = curPage.owner.getTransaction();
    for (; ; ) {
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(curPage.isLatched());
        }
        if (!curPage.allowInsert())
            return null;
        // 'this' is the head page
        if (curPage != this)
            slot = curPage.recordCount;
        boolean isLongColumns = false;
        int realStartColumn = -1;
        int realSpaceOnPage = -1;
        DynamicByteArrayOutputStream logBuffer = null;
        // allocate new record id and handle
        int recordId = curPage.newRecordIdAndBump();
        RecordHandle handle = new RecordId(curPage.getPageId(), recordId, slot);
        if (curPage == this) {
            // Lock the row, if it is the very first portion of the record.
            if (handleToUpdate == null) {
                while (!owner.getLockingPolicy().lockRecordForWrite(t, handle, true, /* lock is for insert */
                false)) {
                    // loop until we get a new record id we can get a lock
                    // on.  If we can't get the lock without waiting then
                    // assume the record id is owned by another xact.  The
                    // current heap overflow algorithm makes this likely,
                    // as it first try's to insert a row telling raw store
                    // to fail if it doesn't fit on the page getting a lock
                    // on an id that never makes it to disk.   The
                    // inserting transaction will hold a lock on this
                    // "unused" record id until it commits.  The page can
                    // leave the cache at this point, and the inserting
                    // transaction has not dirtied the page (it failed
                    // after getting the lock but before logging anything),
                    // another inserting transaction will then get the
                    // same id as the previous inserter - thus the loop on
                    // lock waits.
                    // 
                    // The lock we request indicates that this is a lock
                    // for insert, which the locking policy may use to
                    // perform locking concurrency optimizations.
                    // allocate new record id and handle
                    recordId = curPage.newRecordIdAndBump();
                    handle = new RecordId(curPage.getPageId(), recordId, slot);
                }
            }
            headHandle = handle;
        }
        do {
            // then, we redo the insert with saved logBuffer.
            try {
                startColumn = owner.getActionSet().actionInsert(t, curPage, slot, recordId, row, validColumns, (LogicalUndo) null, insertFlag, startColumn, false, realStartColumn, logBuffer, realSpaceOnPage, overflowThreshold);
                isLongColumns = false;
            } catch (LongColumnException lce) {
                // we caught a long column exception
                // three things should happen here:
                // 1. insert the long column into overflow pages.
                // 2. append the overflow field header in the main chain.
                // 3. continue the insert in the main data chain.
                logBuffer = new DynamicByteArrayOutputStream(lce.getLogBuffer());
                // step 1: insert the long column ... use the same
                // insertFlag as the rest of the row.
                RecordHandle longColumnHandle = insertLongColumn(curPage, lce, insertFlag);
                // step 2: append the overflow field header to the log buffer
                int overflowFieldLen = 0;
                try {
                    overflowFieldLen += appendOverflowFieldHeader((DynamicByteArrayOutputStream) logBuffer, longColumnHandle);
                } catch (IOException ioe) {
                    // YYZ: revisit...  ioexception, insert failed...
                    return null;
                }
                // step 3: continue the insert in the main data chain
                // need to pass the log buffer, and start column to the next insert.
                realStartColumn = lce.getNextColumn() + 1;
                realSpaceOnPage = lce.getRealSpaceOnPage() - overflowFieldLen;
                isLongColumns = true;
            }
        } while (isLongColumns);
        if (handleToUpdate != null) {
            // update the recordheader on the previous page
            updateOverflowDetails(handleToUpdate, handle);
        }
        // all done
        if (startColumn == -1) {
            if (curPage != this)
                curPage.unlatch();
            if (nextPortionHandle != null) {
                // need to update the overflow details of the last portion
                // to point to the existing portion
                updateOverflowDetails(handle, nextPortionHandle);
            }
            return headHandle;
        }
        handleToUpdate = handle;
        BasePage nextPage = curPage.getOverflowPageForInsert(slot, row, validColumns, startColumn);
        if (curPage != this)
            curPage.unlatch();
        curPage = nextPage;
    }
}
Also used : DynamicByteArrayOutputStream(org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream) LogicalUndo(org.apache.derby.iapi.store.access.conglomerate.LogicalUndo) RawTransaction(org.apache.derby.iapi.store.raw.xact.RawTransaction) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) IOException(java.io.IOException)

Example 7 with RawTransaction

use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.

the class BasePage method deallocatePage.

/**
 *		Mark this page as being deallocated
 *
 *		@exception StandardException Derby Standard error policy
 */
public void deallocatePage() throws StandardException {
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT(isLatched());
    }
    if (!owner.updateOK()) {
        throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
    }
    RawTransaction t = owner.getTransaction();
    owner.getActionSet().actionInvalidatePage(t, this);
}
Also used : RawTransaction(org.apache.derby.iapi.store.raw.xact.RawTransaction)

Example 8 with RawTransaction

use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.

the class BasePage method insertLongColumn.

/**
 * Routine to insert a long column.
 * <p>
 * This code inserts a long column as a linked list of rows on overflow
 * pages.  This list is pointed to by a small pointer in the main page
 * row column.  The operation does the following:
 *     allocate new overflow page
 *     insert single row filling overflow page
 *     while (more of column exists)
 *         allocate new overflow page
 *         insert single row with next piece of row
 *         update previous piece to point to this new piece of row
 *
 * Same code is called both from an initial insert of a long column and
 * from a subsequent update that results in a long column.
 *
 * @return The recordHandle of the first piece of the long column chain.
 *
 * @param mainChainPage The parent page with row piece containing column
 *                      that will eventually point to this long column
 *                      chain.
 * @param lce           The LongColumnException thrown when we recognized
 *                      that the column being inserted was "long", this
 *                      structure is used to cache the info that we have
 *                      read so far about column.  In the case of an insert
 *                      of the stream it will have a copy of just the first
 *                      page of the stream that has already been read once.
 * @param insertFlag    flags for insert operation.
 *
 * @exception  StandardException  Standard exception policy.
 */
protected RecordHandle insertLongColumn(BasePage mainChainPage, LongColumnException lce, byte insertFlag) throws StandardException {
    Object[] row = new Object[1];
    row[0] = lce.getColumn();
    RecordHandle firstHandle = null;
    RecordHandle handle = null;
    RecordHandle prevHandle = null;
    BasePage curPage = mainChainPage;
    BasePage prevPage = null;
    boolean isFirstPage = true;
    // undo inserts as purges of all pieces of the overflow column
    // except for the 1st overflow page pointed at by the main row.
    // 
    // Consider a row with one column which is a long column
    // that takes 2 pages for itself plus an entry in main parent page.
    // the log records in order for this look something like:
    // insert overflow page 1
    // insert overflow page 2
    // update overflow page 1 record to have pointer to overflow page 2
    // insert main row (which has pointer to overflow page 1)
    // 
    // If this insert gets aborted then something like the following
    // happens:
    // main row is marked deleted (but ptr to overflow 1 still exists)
    // update is aborted so link on page 2 to page 1 is lost
    // overflow row on page 2 is marked deleted
    // overflow row on page 1 is marked deleted
    // 
    // There is no way to reclaim page 2 later as the abort of the update
    // has now lost the link from overflow page 1 to overflow 2, so
    // the system has to do it as part of the abort of the insert.  But,
    // it can't for page 1 as the main page will attempt to follow
    // it's link in the deleted row during it's space reclamation and it
    // can't tell the difference
    // between a row that has been marked deleted as part of an aborted
    // insert or as part of a committed delete.  When it follows the link
    // it could find no page and that could be coded against, but it could
    // be that the page is now used by some other overflow row which would
    // lead to lots of different kinds of problems.
    // 
    // So the code leaves the 1st overflow page to be cleaned up with the
    // main page row is purged, but goes ahead and immediately purges all
    // the segments that will be lost as part of the links being lost due
    // to aborted updates.
    byte after_first_page_insertFlag = (byte) (insertFlag | Page.INSERT_UNDO_WITH_PURGE);
    // when inserting a long column startColumn is just used
    // as a flag. -1 means the insert is complete, != -1 indicates
    // more inserts are required.
    int startColumn = 0;
    RawTransaction t = curPage.owner.getTransaction();
    do {
        if (!isFirstPage) {
            prevPage = curPage;
            prevHandle = handle;
        }
        // step 1. get a new overflow page
        curPage = (BasePage) getNewOverflowPage();
        if (SanityManager.DEBUG) {
            SanityManager.ASSERT(curPage.isLatched());
            SanityManager.ASSERT(curPage.allowInsert());
        }
        int slot = curPage.recordCount;
        int recordId = curPage.newRecordId();
        handle = new RecordId(curPage.getPageId(), recordId, slot);
        if (isFirstPage)
            firstHandle = handle;
        // step 2: insert column portion
        startColumn = owner.getActionSet().actionInsert(t, curPage, slot, recordId, row, (FormatableBitSet) null, (LogicalUndo) null, (isFirstPage ? insertFlag : after_first_page_insertFlag), startColumn, true, -1, (DynamicByteArrayOutputStream) null, -1, 100);
        // then release latch on prevPage
        if (!isFirstPage) {
            // for the previous page, add an overflow field header,
            // and update the record header to show 2 fields
            prevPage.updateFieldOverflowDetails(prevHandle, handle);
            prevPage.unlatch();
            prevPage = null;
        } else {
            isFirstPage = false;
        }
    } while (startColumn != (-1));
    if (curPage != null) {
        curPage.unlatch();
        curPage = null;
    }
    return (firstHandle);
}
Also used : DynamicByteArrayOutputStream(org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream) LogicalUndo(org.apache.derby.iapi.store.access.conglomerate.LogicalUndo) RawTransaction(org.apache.derby.iapi.store.raw.xact.RawTransaction) RecordHandle(org.apache.derby.iapi.store.raw.RecordHandle) AuxObject(org.apache.derby.iapi.store.raw.AuxObject) FormatableBitSet(org.apache.derby.iapi.services.io.FormatableBitSet)

Example 9 with RawTransaction

use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.

the class RawStore method startReplicationMaster.

/**
 * Start the replication master role for this database
 * @param dbmaster The master database that is being replicated.
 * @param host The hostname for the slave
 * @param port The port the slave is listening on
 * @param replicationMode The type of replication contract.
 * Currently only asynchronous replication is supported, but
 * 1-safe/2-safe/very-safe modes may be added later.
 * @exception StandardException 1) If replication is started on a read-only
 *                                 database
 *                              2) If replication is started when unlogged
 *                                 operations are running
 *                              3) If an error occurs while trying to boot
 *                                 the master.
 */
public void startReplicationMaster(String dbmaster, String host, int port, String replicationMode) throws StandardException {
    if (isReadOnly()) {
        throw StandardException.newException(SQLState.LOGMODULE_DOES_NOT_SUPPORT_REPLICATION);
    }
    RawTransaction t = xactFactory.findUserTransaction(this, getContextService().getCurrentContextManager(), AccessFactoryGlobals.USER_TRANS_NAME);
    // yes do not allow replication to start.
    if (t.isBlockingBackup()) {
        throw StandardException.newException(SQLState.REPLICATION_UNLOGGED_OPERATIONS_IN_PROGRESS);
    }
    Properties replicationProps = new Properties();
    replicationProps.setProperty(MasterFactory.REPLICATION_MODE, replicationMode);
    MasterFactory masterFactory = (MasterFactory) bootServiceModule(true, this, getMasterFactoryModule(), replicationProps);
    masterFactory.startMaster(this, dataFactory, logFactory, host, port, dbmaster);
}
Also used : RawTransaction(org.apache.derby.iapi.store.raw.xact.RawTransaction) UpdateServiceProperties(org.apache.derby.impl.services.monitor.UpdateServiceProperties) Properties(java.util.Properties) MasterFactory(org.apache.derby.iapi.store.replication.master.MasterFactory)

Example 10 with RawTransaction

use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.

the class BaseContainer method compressContainer.

/*
	** Implementation specific methods
	*/
/**
 *		Release free space to the OS.
 *		<P>
 *        As is possible release any free space to the operating system.  This
 *        will usually mean releasing any free pages located at the end of the
 *        file using the java truncate() interface.
 *
 *		@exception StandardException	Standard Derby error policy
 */
public void compressContainer(BaseContainerHandle handle) throws StandardException {
    RawTransaction ntt = handle.getTransaction().startNestedTopTransaction();
    int mode = handle.getMode();
    if (SanityManager.DEBUG) {
        SanityManager.ASSERT((mode & ContainerHandle.MODE_FORUPDATE) == ContainerHandle.MODE_FORUPDATE, "addPage handle not for update");
    }
    // crashed.
    if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) == 0 && (mode & ContainerHandle.MODE_UNLOGGED) == ContainerHandle.MODE_UNLOGGED)
        mode &= ~ContainerHandle.MODE_UNLOGGED;
    // make a handle which is tied to the ntt, not to the user transaction
    // this handle is tied to.  The container is already locked by the
    // user transaction, open it nolock
    BaseContainerHandle allocHandle = (BaseContainerHandle) ntt.openContainer(identity, (LockingPolicy) null, mode);
    if (allocHandle == null) {
        throw StandardException.newException(SQLState.DATA_ALLOC_NTT_CANT_OPEN, getSegmentId(), getContainerId());
    }
    CompatibilitySpace cs = ntt.getCompatibilitySpace();
    // Latch this container, the commit will release the latch
    ntt.getLockFactory().lockObject(cs, ntt, this, null, C_LockFactory.WAIT_FOREVER);
    try {
        incrementReusableRecordIdSequenceNumber();
        compressContainer(ntt, allocHandle);
    } finally {
        ntt.commit();
        ntt.close();
    }
}
Also used : RawTransaction(org.apache.derby.iapi.store.raw.xact.RawTransaction) CompatibilitySpace(org.apache.derby.iapi.services.locks.CompatibilitySpace) LockingPolicy(org.apache.derby.iapi.store.raw.LockingPolicy)

Aggregations

RawTransaction (org.apache.derby.iapi.store.raw.xact.RawTransaction)40 RecordHandle (org.apache.derby.iapi.store.raw.RecordHandle)10 LockingPolicy (org.apache.derby.iapi.store.raw.LockingPolicy)6 PageKey (org.apache.derby.iapi.store.raw.PageKey)6 StandardException (org.apache.derby.shared.common.error.StandardException)6 ContextManager (org.apache.derby.iapi.services.context.ContextManager)5 StorageFile (org.apache.derby.io.StorageFile)5 IOException (java.io.IOException)4 DynamicByteArrayOutputStream (org.apache.derby.iapi.services.io.DynamicByteArrayOutputStream)3 RawContainerHandle (org.apache.derby.iapi.store.raw.data.RawContainerHandle)3 Serviceable (org.apache.derby.iapi.services.daemon.Serviceable)2 FormatableBitSet (org.apache.derby.iapi.services.io.FormatableBitSet)2 CompatibilitySpace (org.apache.derby.iapi.services.locks.CompatibilitySpace)2 LogicalUndo (org.apache.derby.iapi.store.access.conglomerate.LogicalUndo)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 File (java.io.File)1 OutputStream (java.io.OutputStream)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 Properties (java.util.Properties)1