use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class BaseContainer method addPage.
/**
* Add a page to this container.
*
* <BR> MT - thread aware -
*
* The add page operation involves 2 transactions, one is the user
* transaction (the transaction which owns the passed in handle), the
* other one is a NestedTopTransaction created by this BaseContainer.
*
* The nestedTopTransaction is used by the underlying container to change
* high contention structures, such as link list anchor or bit map pages.
* The nestedTopTransaction commits or aborts before this routine returns.
*
* The user transaction is used to latch the newly created page.
*
* @exception StandardException Standard Derby error policy
*/
public Page addPage(BaseContainerHandle handle, boolean isOverflow) 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());
}
// Latch this container, the commit will release the latch
CompatibilitySpace cs = ntt.getCompatibilitySpace();
ntt.getLockFactory().lockObject(cs, ntt, this, null, C_LockFactory.WAIT_FOREVER);
BasePage newPage = null;
try {
newPage = newPage(handle, ntt, allocHandle, isOverflow);
} finally {
if (newPage != null) {
// it is ok to commit without syncing, as it is ok if this
// transaction never makes it to the db, if no subsequent
// log record makes it to the log. If any subsequent log
// record is sync'd then this transaction will be sync'd
// as well.
ntt.commitNoSync(Transaction.RELEASE_LOCKS);
} else {
ntt.abort();
}
ntt.close();
}
if (SanityManager.DEBUG) {
SanityManager.ASSERT(newPage.isLatched());
}
if (!this.identity.equals(newPage.getPageId().getContainerId())) {
if (SanityManager.DEBUG) {
SanityManager.THROWASSERT("BaseContainer.addPage(), just got a new page from a different container" + "\n this.identity = " + this.identity + "\n newPage.getPageId().getContainerId() = " + newPage.getPageId().getContainerId() + "\n handle is: " + handle + "\n allocHandle is: " + allocHandle + "\n this container is: " + this);
}
throw StandardException.newException(SQLState.DATA_DIFFERENT_CONTAINER, this.identity, newPage.getPageId().getContainerId());
}
return newPage;
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class LogicalPageOperation method findLogicalPage.
/*
* method specific to this class
*/
/**
* Find the page that the rollback operation should be applied to.
*
* <P>The actual logical log operation is expected to implement
* Undoable.generateUndo. This utility function findLogicalPage is provided
* for the common case scenario of using a LogicalUndo interface to find the
* undo page. The subclass that implements Undoable.generateUndo can use
* this function to find the logical page with its LogicalUndo callback function.
* This method can be used with the default releaseResource().
*
* <P>During recovery redo, the logging system is page oriented and will use
* the pageID stored in the PageUndoOperation to find the page. The
* page will be latched and released using the default findpage and
* releaseResource - this.releaseResource() will still be called so it has
* to know not to release any resource it did not acquire.
*
* @param xact the transaction doing the compensating
* @param in optional input
*
* @return the compensation operation that will rollback this change
*
* @exception StandardException Standard Derby error policy
* @exception IOException Method may read from ObjectInput
*
* @see PageBasicOperation
* @see Undoable#generateUndo
* @see org.apache.derby.iapi.store.raw.Loggable#releaseResource
*/
private BasePage findLogicalPage(Transaction xact, LogicalUndo undo, LimitObjectInput in) throws StandardException, IOException {
releaseResource(xact);
if (SanityManager.DEBUG) {
// the try,finally code makes these assumptions.
SanityManager.ASSERT(containerHdl == null);
SanityManager.ASSERT(page == null);
}
boolean okExit = false;
try {
// open the container
RawTransaction rtran = (RawTransaction) xact;
containerHdl = rtran.openDroppedContainer(getPageId().getContainerId(), (LockingPolicy) null);
if (SanityManager.DEBUG) {
SanityManager.ASSERT(containerHdl != null, "cannot open container");
SanityManager.ASSERT(containerHdl.getContainerStatus() != RawContainerHandle.COMMITTED_DROP, "finding a page for undo in a committed dropped container");
}
page = (BasePage) (undo.findUndo(xact, this, in));
if (SanityManager.DEBUG) {
SanityManager.ASSERT(page != null, "findUndo returns null page");
SanityManager.ASSERT(page.getPageNumber() == getPageId().getPageNumber(), "undo.findUndo did not reset the log op's recordHandle");
}
// if you add code here then ensure that you handle page unlatching in the
// backout code.
okExit = true;
} finally {
if (!okExit) {
if (containerHdl != null) {
containerHdl.close();
containerHdl = null;
}
}
// no need to unlatch page here because is page is valid no
// exceptions can be thrown, until some adds code after the findUndo.
}
foundHere = true;
return page;
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class ReclaimSpaceHelper method reclaimContainer.
private static int reclaimContainer(BaseDataFileFactory dataFactory, RawTransaction tran, ReclaimSpace work) throws StandardException {
// when we want to reclaim the whole container, gets an exclusive
// XLock on the container, wait for the lock.
LockingPolicy container_xlock = tran.newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true);
if (SanityManager.DEBUG)
SanityManager.ASSERT(container_xlock != null);
// Try to just get the container thru the transaction.
// Need to do this to transition the transaction to active state.
RawContainerHandle containerHdl = tran.openDroppedContainer(work.getContainerId(), container_xlock);
// deleted, done work
if (containerHdl == null || containerHdl.getContainerStatus() == RawContainerHandle.NORMAL || containerHdl.getContainerStatus() == RawContainerHandle.COMMITTED_DROP) {
if (containerHdl != null)
containerHdl.close();
// release xlock, if any
tran.abort();
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, " aborted " + work);
}
}
} else {
// we got an xlock on a dropped container. Must be committed.
// Get rid of the container now.
ContainerOperation lop = new ContainerOperation(containerHdl, ContainerOperation.REMOVE);
// mark the container as pre-dirtied so that if a checkpoint
// happens after the log record is sent to the log stream, the
// cache cleaning will wait for this change.
containerHdl.preDirty(true);
try {
tran.logAndDo(lop);
} finally {
// in case logAndDo fail, make sure the container is not
// stuck in preDirty state.
containerHdl.preDirty(false);
}
containerHdl.close();
tran.commit();
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, " committed " + work);
}
}
}
return Serviceable.DONE;
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class EncryptOrDecryptData method encryptOrDecryptContainer.
/**
* Encrypts or decrypts the specified container.
*
* @param t transaction that used to perform the cryptographic operation
* @param ckey the key of the container that is being encrypted/decrypted
* @param doEncrypt tells whether to encrypt or decrypt
* @exception StandardException Standard Derby error policy
*/
private void encryptOrDecryptContainer(RawTransaction t, ContainerKey ckey, boolean doEncrypt) throws StandardException {
LockingPolicy cl = t.newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true);
if (SanityManager.DEBUG)
SanityManager.ASSERT(cl != null);
RawContainerHandle containerHdl = (RawContainerHandle) t.openContainer(ckey, cl, ContainerHandle.MODE_FORUPDATE);
if (SanityManager.DEBUG)
SanityManager.ASSERT(containerHdl != null);
EncryptContainerOperation lop = new EncryptContainerOperation(containerHdl);
t.logAndDo(lop);
// flush the log to reduce the window between where
// the encrypted container is created & synced and the
// log record for it makes it to disk. if we fail during
// encryption of the container, log record will make sure
// container is restored to the original state and
// any temporary files are cleaned up.
dataFactory.flush(t.getLastLogInstant());
// encrypt the container.
String newFilePath = getFilePath(ckey, false);
StorageFile newFile = storageFactory.newStorageFile(newFilePath);
containerHdl.encryptOrDecryptContainer(newFilePath, doEncrypt);
containerHdl.close();
// discard pages in the cache related to this container.
if (!dataFactory.getPageCache().discard(ckey)) {
if (SanityManager.DEBUG)
SanityManager.THROWASSERT("unable to discard pages releated to " + "container " + ckey + " from the page cache");
}
// get rid of the container entry from conatainer cache
if (!dataFactory.getContainerCache().discard(ckey)) {
if (SanityManager.DEBUG)
SanityManager.THROWASSERT("unable to discard a container " + ckey + " from the container cache");
}
StorageFile currentFile = dataFactory.getContainerPath(ckey, false);
StorageFile oldFile = getFile(ckey, true);
if (!privRename(currentFile, oldFile)) {
throw StandardException.newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, currentFile, oldFile);
}
// now replace current container file with the new file.
if (!privRename(newFile, currentFile)) {
throw StandardException.newException(SQLState.RAWSTORE_ERROR_RENAMING_FILE, newFile, currentFile);
}
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class OverflowInputStream method initStream.
/**
************************************************************************
* Public Methods of Resetable Interface
**************************************************************************
*/
/**
* Initialize a Resetable stream.
* <p>
* InitStream() must be called first before using any other of the
* Resetable interfaces.
* <p>
* Reopens the container. This gets a separate intent shared locked on
* the table and a read lock on the appropriate row. These locks remain
* until the enclosing blob/clob object is closed, or until the end of
* the transaction in which initStream() was first called. This locking
* behavior protects the row while the stream is being accessed. Otherwise
* for instance in the case of read committed the original row lock on
* the row would be released when the scan went to the next row, and there
* would be nothing to stop another transaction from deleting the row while
* the client read through the stream.
*
* @exception StandardException Standard exception policy.
*/
public void initStream() throws StandardException {
// only one initStream() required.
if (initialized)
return;
// instead throw error that container was not opened
if (owner.getTransaction() == null) {
throw StandardException.newException(SQLState.DATA_CONTAINER_CLOSED);
}
// Use isolation level READ_COMMITTED and reopen the container to
// get a new container handle to use for locking. This way, the lock
// will be freed when the container handle is closed. This will
// happen in closeStream() or when the transaction commits.
// Hence, locks will be released before the end of transaction if
// blobs/clobs are explicitly released.
LockingPolicy lp = owner.getTransaction().newLockingPolicy(LockingPolicy.MODE_RECORD, TransactionController.ISOLATION_READ_COMMITTED, true);
// reopen the container
owner = (BaseContainerHandle) owner.getTransaction().openContainer(owner.getId(), lp, owner.getMode());
// get a read lock on the appropriate row this will wait until either
// the lock is granted or an exception is thrown
owner.getLockingPolicy().lockRecordForRead(owner.getTransaction(), owner, recordToLock, true, false);
initialized = true;
}
Aggregations