use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class PageBasicOperation method findpage.
/**
* Find the page the operation applies to and latch it, this only
* uses the segmentId, containerId, and pageId stored in this log
* record to find the page.
*
* @return null if container is dropped and committed (possibly
* stubbified), else return the latched page
*
* @exception StandardException Standard Derby policy.
*/
public final BasePage findpage(Transaction xact) throws StandardException {
releaseResource(xact);
RawTransaction rtran = (RawTransaction) xact;
containerHdl = rtran.openDroppedContainer(pageId.getContainerId(), (LockingPolicy) null);
if (containerHdl == null) {
throw StandardException.newException(SQLState.DATA_CONTAINER_VANISHED, pageId.getContainerId());
}
foundHere = true;
// it may be a container stub
if (containerHdl.getContainerStatus() == RawContainerHandle.COMMITTED_DROP) {
releaseResource(xact);
return null;
}
StandardException getPageException = null;
try {
// get and latch page - we don't know the status of the page or what
// kind of page we are looking for, get any type of page
page = (BasePage) (containerHdl.getAnyPage(pageId.getPageNumber()));
} catch (StandardException se) {
getPageException = se;
}
// We do this if derby.storage.patchInitPageRecoverError is set.
if (page == null && getPageException != null && pageVersion == 0)
if (PropertyUtil.getSystemBoolean(RawStoreFactory.PATCH_INITPAGE_RECOVER_ERROR))
page = getPageForRedoRecovery(xact);
// give subclass a chance to create the page
if (page == null && getPageException != null) {
if (rtran.inRollForwardRecovery()) {
if (SanityManager.DEBUG)
if (SanityManager.DEBUG_ON("LoadTran"))
SanityManager.DEBUG_PRINT("Trace", "got null page " + pageId + " and getPageException, attempt last ditch effort");
page = getPageForRedoRecovery(xact);
if (SanityManager.DEBUG)
if (SanityManager.DEBUG_ON("LoadTran"))
SanityManager.DEBUG_PRINT("Trace", " getPageForRedoRecovery, got page=" + (page != null));
}
}
if (page == null) {
if (getPageException != null) {
// that is the original error
throw getPageException;
} else {
throw StandardException.newException(SQLState.DATA_MISSING_PAGE, pageId);
}
}
return page;
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class ContainerBasicOperation method findContainer.
/**
* Methods specific to this class
*/
/**
* Open the container with this segmentId and containerId.
* This method should only be called if the container has already been
* created.
*
* @exception StandardException the container cannot be found or cannot be
* opened.
*/
protected RawContainerHandle findContainer(Transaction tran) throws StandardException {
releaseResource(tran);
RawTransaction rtran = (RawTransaction) tran;
containerHdl = rtran.openDroppedContainer(containerId, (LockingPolicy) null);
// reused the container id that was dropped earlier.
if (rtran.inRollForwardRecovery()) {
if (containerHdl == null) {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("LoadTran")) {
SanityManager.DEBUG_PRINT("Trace", "cannot find container " + containerId + ", now attempt last ditch effort");
}
}
containerHdl = findContainerForRedoRecovery(rtran);
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON("LoadTran")) {
SanityManager.DEBUG_PRINT("Trace", " findContainerForRedoRecovery, got container=" + (containerHdl != null));
}
}
}
}
if (containerHdl == null) {
throw StandardException.newException(SQLState.DATA_CONTAINER_VANISHED, containerId);
}
foundHere = true;
return containerHdl;
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class ReclaimSpaceHelper method reclaimSpace.
/**
* Reclaim space based on work.
*/
public static int reclaimSpace(BaseDataFileFactory dataFactory, RawTransaction tran, ReclaimSpace work) throws StandardException {
if (work.reclaimWhat() == ReclaimSpace.CONTAINER)
return reclaimContainer(dataFactory, tran, work);
// Else, not reclaiming container. Get a no-wait shared lock on the
// container regardless of how the user transaction had the
// container opened.
LockingPolicy container_rlock = tran.newLockingPolicy(LockingPolicy.MODE_RECORD, TransactionController.ISOLATION_SERIALIZABLE, true);
if (SanityManager.DEBUG)
SanityManager.ASSERT(container_rlock != null);
ContainerHandle containerHdl = openContainerNW(tran, container_rlock, work.getContainerId());
if (containerHdl == null) {
tran.abort();
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, " aborted " + work + " because container is locked or dropped");
}
}
if (// retry this for serveral times
work.incrAttempts() < 3) // it is however, unlikely that three tries will be
// enough because there is no delay between retries.
// See DERBY-4059 and DERBY-4055 for details.
{
return Serviceable.REQUEUE;
} else {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, " gave up after 3 tries to get container lock " + work);
}
}
return Serviceable.DONE;
}
}
if (work.reclaimWhat() == ReclaimSpace.PAGE) {
// Reclaiming a page - called by undo of insert which purged the
// last row off an overflow page. It is safe to reclaim the page
// without first locking the head row because unlike post commit
// work, this is post abort work. Abort is guarenteed to happen
// and to happen only once, if at all.
Page p = containerHdl.getPageNoWait(work.getPageId().getPageNumber());
if (p != null)
containerHdl.removePage(p);
tran.commit();
return Serviceable.DONE;
}
// We are reclaiming row space or long column.
// First get an xlock on the head row piece.
RecordHandle headRecord = work.getHeadRowHandle();
if (!container_rlock.lockRecordForWrite(tran, headRecord, false, /* not insert */
false)) {
// cannot get the row lock, retry
tran.abort();
if (work.incrAttempts() < 3) {
return Serviceable.REQUEUE;
} else {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, " gave up after 3 tries to get row lock " + work);
}
}
return Serviceable.DONE;
}
}
if (work.reclaimWhat() == ReclaimSpace.ROW_RESERVE) {
// This row may benefit from compaction.
containerHdl.compactRecord(headRecord);
// This work is being done - post commit, there is no user
// transaction that depends on the commit being sync'd. It is safe
// to commitNoSync() This do as one of 2 things will happen:
//
// 1) if any data page associated with this transaction is
// moved from cache to disk, then the transaction log
// must be sync'd to the log record for that change and
// all log records including the commit of this xact must
// be sync'd before returning.
//
// 2) if the data page is never written then the log record
// for the commit may never be written, and the xact will
// never make to disk. This is ok as no subsequent action
// depends on this operation being committed.
//
tran.commitNoSync(Transaction.RELEASE_LOCKS);
return Serviceable.DONE;
} else {
if (SanityManager.DEBUG)
SanityManager.ASSERT(work.reclaimWhat() == ReclaimSpace.COLUMN_CHAIN);
// Reclaiming a long column chain due to update. The long column
// chain being reclaimed is the before image of the update
// operation.
//
long headPageId = ((PageKey) headRecord.getPageId()).getPageNumber();
// DERBY-4050 - we wait for the page so we don't have to retry.
// prior to the 4050 fix, we called getPageNoWait and just
// retried 3 times. This left unreclaimed space if we were
// not successful after three tries.
StoredPage headRowPage = (StoredPage) containerHdl.getPage(headPageId);
if (headRowPage == null) {
if (SanityManager.DEBUG) {
if (SanityManager.DEBUG_ON(DaemonService.DaemonTrace)) {
SanityManager.DEBUG(DaemonService.DaemonTrace, "gave up because hadRowPage was null" + work);
}
}
tran.abort();
return Serviceable.DONE;
}
try {
headRowPage.removeOrphanedColumnChain(work, containerHdl);
} finally {
headRowPage.unlatch();
}
// This work is being done - post commit, there is no user
// transaction that depends on the commit being sync'd. It is safe
// to commitNoSync() This do as one of 2 things will happen:
//
// 1) if any data page associated with this transaction is
// moved from cache to disk, then the transaction log
// must be sync'd to the log record for that change and
// all log records including the commit of this xact must
// be sync'd before returning.
//
// 2) if the data page is never written then the log record
// for the commit may never be written, and the xact will
// never make to disk. This is ok as no subsequent action
// depends on this operation being committed.
//
tran.commitNoSync(Transaction.RELEASE_LOCKS);
return Serviceable.DONE;
}
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class BaseDataFileFactory method backupDataFiles.
/*
* Find all the all the containers stored in the seg0 directory and
* backup each container to the specified backup location.
*/
public void backupDataFiles(Transaction rt, File backupDir) throws StandardException {
/*
* List of containers that needs to be backed up are identified by
* simply reading the list of files in seg0.
* All container that are created after the container list is created
* when backup is in progress are recreated on restore using the
* transaction log.
*/
String[] files = getContainerNames();
if (files != null) {
// No user visible locks are acquired to backup the database. A stable backup
// is made by latching the pages and internal synchronization
// mechanisms.
LockingPolicy lockPolicy = rt.newLockingPolicy(LockingPolicy.MODE_NONE, TransactionController.ISOLATION_NOLOCK, false);
long segmentId = 0;
// loop through all the files in seg0 and backup all valid containers.
for (int f = files.length - 1; f >= 0; f--) {
long containerId;
try {
containerId = Long.parseLong(files[f].substring(1, (files[f].length() - 4)), 16);
} catch (Throwable t) {
// next one.
continue;
}
ContainerKey identity = new ContainerKey(segmentId, containerId);
/* Not necessary to get the container thru the transaction.
* Backup opens in container in read only mode , No need to
* transition the transaction to active state.
*
* dropped container stubs also has to be backed up
* for restore to work correctly. That is
* why we are using a open call that let us
* open dropped containers.
*/
ContainerHandle containerHdl = openDroppedContainer((RawTransaction) rt, identity, lockPolicy, ContainerHandle.MODE_READONLY);
if (containerHdl != null) {
containerHdl.backupContainer(backupDir.getPath());
containerHdl.close();
}
}
} else {
if (SanityManager.DEBUG)
SanityManager.THROWASSERT("backup process is unable to read container names in seg0");
}
}
use of org.apache.derby.iapi.store.raw.LockingPolicy in project derby by apache.
the class BaseDataFileFactory method addContainer.
/**
* Add a container with a specified page size to a segment.
* @exception StandardException Standard Derby error policy
*/
public long addContainer(RawTransaction t, long segmentId, long input_containerid, int mode, Properties tableProperties, int temporaryFlag) throws StandardException {
if (SanityManager.DEBUG) {
if ((mode & ContainerHandle.MODE_CREATE_UNLOGGED) != 0)
SanityManager.ASSERT((mode & ContainerHandle.MODE_UNLOGGED) != 0, "cannot have CREATE_UNLOGGED set but UNLOGGED not set");
}
// If client has provided a containerid then use it, else use the
// internally generated one from getNextId().
long containerId = ((input_containerid != ContainerHandle.DEFAULT_ASSIGN_ID) ? input_containerid : getNextId());
ContainerKey identity = new ContainerKey(segmentId, containerId);
boolean tmpContainer = (segmentId == ContainerHandle.TEMPORARY_SEGMENT);
ContainerHandle ch = null;
LockingPolicy cl = null;
if (!tmpContainer) {
if (isReadOnly()) {
throw StandardException.newException(SQLState.DATA_CONTAINER_READ_ONLY);
}
cl = t.newLockingPolicy(LockingPolicy.MODE_CONTAINER, TransactionController.ISOLATION_SERIALIZABLE, true);
if (SanityManager.DEBUG)
SanityManager.ASSERT(cl != null);
ch = t.openContainer(identity, cl, (ContainerHandle.MODE_FORUPDATE | ContainerHandle.MODE_OPEN_FOR_LOCK_ONLY));
}
FileContainer container = (FileContainer) containerCache.create(identity, tableProperties);
// create the first alloc page and the first user page,
// if this fails for any reason the transaction
// will roll back and the container will be dropped (removed)
ContainerHandle containerHdl = null;
Page firstPage = null;
try {
// make sure to open it with IS_KEPT too.
if (tmpContainer && ((temporaryFlag & TransactionController.IS_KEPT) == TransactionController.IS_KEPT)) {
mode |= ContainerHandle.MODE_TEMP_IS_KEPT;
}
// open no-locking as we already have the container locked
containerHdl = t.openContainer(identity, null, (ContainerHandle.MODE_FORUPDATE | mode));
// we just added it, containerHdl should not be null
if (SanityManager.DEBUG)
SanityManager.ASSERT(containerHdl != null);
if (!tmpContainer) {
// make it persistent (in concept if not in reality)
RawContainerHandle rch = (RawContainerHandle) containerHdl;
ContainerOperation lop = new ContainerOperation(rch, ContainerOperation.CREATE);
// 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.
rch.preDirty(true);
try {
t.logAndDo(lop);
// flush the log to reduce the window between where
// the container is created & synced and the log record
// for it makes it to disk. If we fail in this
// window we will leave a stranded container file.
flush(t.getLastLogInstant());
} finally {
// in case logAndDo fail, make sure the container is not
// stuck in preDirty state.
rch.preDirty(false);
}
}
firstPage = containerHdl.addPage();
} finally {
if (firstPage != null) {
firstPage.unlatch();
firstPage = null;
}
containerCache.release(container);
if (containerHdl != null) {
containerHdl.close();
containerHdl = null;
}
if (!tmpContainer) {
// this should do nothing, since we requested isolation 3
// but we can't assume that, so call the policy correctly.
cl.unlockContainer(t, ch);
}
}
return containerId;
}
Aggregations