use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.
the class FileContainer method reCreatePageForRedoRecovery.
/**
* ReCreate a page for rollforward recovery.
* <p>
* During redo recovery it is possible for the system to try to redo
* the creation of a page (ie. going from non-existence to version 0).
* It first trys to read the page from disk, but a few different types
* of errors can occur:
* o the page does not exist at all on disk, this can happen during
* rollforward recovery applied to a backup where the file was
* copied and the page was added to the file during the time frame
* of the backup but after the physical file was copied.
* o space in the file exists, but it was never initalized. This
* can happen if you happen to crash at just the right moment during
* the allocation process. Also
* on some OS's it is possible to read from a part of the file that
* was not ever written - resulting in garbage from the store's
* point of view (often the result is all 0's).
*
* All these errors are easy to recover from as the system can easily
* create a version 0 from scratch and write it to disk.
*
* Because the system does not sync allocation of data pages, it is also
* possible at this point that whlie writing the version 0 to disk to
* create it we may encounter an out of disk space error (caught in this
* routine as a StandardException from the create() call. We can't
* recovery from this without help from outside, so the caught exception
* is nested and a new exception thrown which the recovery system will
* output to the user asking them to check their disk for space/errors.
*
* @exception StandardException Standard exception policy.
*/
protected BasePage reCreatePageForRedoRecovery(BaseContainerHandle handle, int pageFormat, long pageNumber, long pageOffset) throws StandardException {
// recreating a page should be done only if are in the middle of
// rollforward recovery or if derby.storage.patchInitPageRecoverError
// is set to true.
// check if we are in rollforward recovery
boolean rollForwardRecovery = ((RawTransaction) handle.getTransaction()).inRollForwardRecovery();
if (!rollForwardRecovery && !(PropertyUtil.getSystemBoolean(RawStoreFactory.PATCH_INITPAGE_RECOVER_ERROR))) {
return null;
}
// RESOLVE: first need to verify that the page is really NOT in the
// container!
// no address translation necessary
PageKey pkey = new PageKey(identity, pageNumber);
PageCreationArgs reCreatePageArgs;
if (pageFormat == StoredPage.FORMAT_NUMBER) {
reCreatePageArgs = new PageCreationArgs(pageFormat, CachedPage.WRITE_SYNC, pageSize, spareSpace, minimumRecordSize, 0);
} else if (pageFormat == AllocPage.FORMAT_NUMBER) {
// only the first allocation page have borrowed space for the
// container info
int containerInfoSize = 0;
if (pageNumber == FIRST_ALLOC_PAGE_NUMBER) {
containerInfoSize = CONTAINER_INFO_SIZE;
firstAllocPageNumber = pageNumber;
firstAllocPageOffset = pageOffset;
}
reCreatePageArgs = new PageCreationArgs(pageFormat, CachedPage.WRITE_SYNC, pageSize, // allocation page has no need for spare
0, minimumRecordSize, containerInfoSize);
} else {
throw StandardException.newException(SQLState.DATA_UNKNOWN_PAGE_FORMAT, pkey);
}
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("LoadTran"))
SanityManager.DEBUG_PRINT("Trace", "recreating page " + pkey + " for load tran");
}
// Can't just call initPage because that wants to log an initPage
// operation, whereas we are here because of an initPage operation in
// the log already.
BasePage page = null;
boolean releasePage = true;
try {
try {
// a brand new page, initialize a new page in cache
page = (BasePage) pageCache.create(pkey, reCreatePageArgs);
} catch (StandardException se) {
throw StandardException.newException(SQLState.FILE_NEW_PAGE_DURING_RECOVERY, se, pkey);
}
if (page != null) {
releasePage = false;
page = latchPage(handle, page, false);
if (page == null) {
throw StandardException.newException(SQLState.FILE_NEW_PAGE_NOT_LATCHED, pkey);
}
} else {
throw StandardException.newException(SQLState.FILE_NEW_PAGE_DURING_RECOVERY, pkey);
}
} finally {
if (releasePage && page != null) {
// release the new page from cache if it errors out before
// the exclusive lock is set error in roll forward recovery.
// , we are doomed anyway
pageCache.release((Cacheable) page);
page = null;
}
}
return page;
}
use of org.apache.derby.iapi.store.raw.xact.RawTransaction 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.xact.RawTransaction in project derby by apache.
the class RemoveFile method add.
/**
* @see FileResource#add
* @exception StandardException Oops
*/
public long add(String name, InputStream source) throws StandardException {
OutputStream os = null;
if (factory.isReadOnly()) {
throw StandardException.newException(SQLState.FILE_READ_ONLY);
}
long generationId = factory.getNextId();
try {
StorageFile file = getAsFile(name, generationId);
if (file.exists()) {
throw StandardException.newException(SQLState.FILE_EXISTS, file);
}
ContextManager cm = FileContainer.getContextService().getCurrentContextManager();
RawTransaction tran = factory.getRawStoreFactory().getXactFactory().findUserTransaction(factory.getRawStoreFactory(), cm, AccessFactoryGlobals.USER_TRANS_NAME);
// Block the backup, If backup is already in progress wait
// for the backup to finish. Jar files are unlogged but the
// changes to the references to the jar file in the catalogs
// is logged. A consistent backup can not be made when jar file
// is being added.
tran.blockBackup(true);
StorageFile directory = file.getParentDir();
StorageFile parentDir = directory.getParentDir();
boolean pdExisted = parentDir.exists();
if (!directory.exists()) {
if (!directory.mkdirs()) {
throw StandardException.newException(SQLState.FILE_CANNOT_CREATE_SEGMENT, directory);
}
directory.limitAccessToOwner();
if (!pdExisted) {
parentDir.limitAccessToOwner();
}
}
os = file.getOutputStream();
byte[] data = new byte[4096];
int len;
factory.writeInProgress();
try {
while ((len = source.read(data)) != -1) {
os.write(data, 0, len);
}
factory.writableStorageFactory.sync(os, false);
} finally {
factory.writeFinished();
}
} catch (IOException ioe) {
throw StandardException.newException(SQLState.FILE_UNEXPECTED_EXCEPTION, ioe);
} finally {
try {
if (os != null) {
os.close();
}
} catch (IOException ioe2) {
/*RESOLVE: Why ignore this?*/
}
try {
if (source != null)
source.close();
} catch (IOException ioe2) {
/* RESOLVE: Why ignore this?*/
}
}
return generationId;
}
use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.
the class RemoveFile method removeJarDir.
/**
* @see FileResource#removeJarDir
*/
public void removeJarDir(String f) throws StandardException {
if (factory.isReadOnly())
throw StandardException.newException(SQLState.FILE_READ_ONLY);
ContextManager cm = FileContainer.getContextService().getCurrentContextManager();
RawTransaction tran = factory.getRawStoreFactory().getXactFactory().findUserTransaction(factory.getRawStoreFactory(), cm, AccessFactoryGlobals.USER_TRANS_NAME);
StorageFile ff = factory.storageFactory.newStorageFile(f);
Serviceable s = new RemoveFile(ff);
// Since this code is only used during upgrade to post-10.8 databases
// we do no bother to build code for a special RemoveDirOperation and
// do tran.logAndDo (cf. logic in #remove). If the post-commit removal
// doesn't get completed, that is no big issue, the dirs can be removed
// by hand if need be. A prudent DBA will rerun the upgrade from a
// backup if something crashes anyway..
tran.addPostCommitWork(s);
}
use of org.apache.derby.iapi.store.raw.xact.RawTransaction in project derby by apache.
the class DropOnCommit method update.
/**
* Called when the transaction is about to complete.
*
* @see java.util.Observer#update
*/
public void update(DerbyObservable obj, Object arg) {
if (SanityManager.DEBUG) {
if (arg == null)
SanityManager.THROWASSERT("still on observer list " + this);
}
if (arg.equals(RawTransaction.COMMIT) || arg.equals(RawTransaction.ABORT)) {
RawTransaction xact = (RawTransaction) obj;
try {
if (this.isStreamContainer)
xact.dropStreamContainer(identity.getSegmentId(), identity.getContainerId());
else
xact.dropContainer(identity);
} catch (StandardException se) {
xact.setObserverException(se);
}
obj.deleteObserver(this);
}
}
Aggregations