Fixed page acquire during checkpoint
@@ -803,9 +803,14 @@ public class PageMemoryImpl implements PageMemoryEx {
int tag;
+ boolean tmpBuffer = false;
+
seg.readLock().lock();
try {
+ if (!isInCheckpoint(fullId))
+ return null;
+
tag = seg.partTag(fullId.groupId(), PageIdUtils.partId(fullId.pageId()));
relPtr = seg.loadedPages.get(
@@ -826,6 +831,8 @@ public class PageMemoryImpl implements PageMemoryEx {
// Pin the page until page will not be copied.
if (PageHeader.tempBufferPointer(absPtr) == INVALID_REL_PTR)
PageHeader.acquirePage(absPtr);
+ else
+ tmpBuffer = true;
}
}
finally {
@@ -869,7 +876,7 @@ public class PageMemoryImpl implements PageMemoryEx {
}
}
else
- return copyPageForCheckpoint(absPtr, fullId, tmpBuf, tracker) ? tag : null;
+ return copyPageForCheckpoint(absPtr, fullId, tmpBuf, tmpBuffer, tracker) ? tag : null;
}
/**
@@ -877,19 +884,24 @@ public class PageMemoryImpl implements PageMemoryEx {
* @param fullId Full id.
* @param tmpBuf Tmp buffer.
*/
- private boolean copyPageForCheckpoint(long absPtr, FullPageId fullId, ByteBuffer tmpBuf, CheckpointMetricsTracker tracker) {
+ private boolean copyPageForCheckpoint(
+ long absPtr,
+ FullPageId fullId,
+ ByteBuffer tmpBuf,
+ boolean tmpBuffer,
+ CheckpointMetricsTracker tracker
+ ) {
assert absPtr != 0;
+ assert PageHeader.isAcquired(absPtr);
rwLock.writeLock(absPtr + PAGE_LOCK_OFFSET, OffheapReadWriteLock.TAG_LOCK_ALWAYS);
try {
long tmpRelPtr = PageHeader.tempBufferPointer(absPtr);
- if (!clearCheckpoint(fullId)){
- assert tmpRelPtr == INVALID_REL_PTR;
+ boolean success = clearCheckpoint(fullId);
- return false;
- }
+ assert success : "Page was pin when we resolve abs pointer, it can not be evicted";
if (tmpRelPtr != INVALID_REL_PTR){
PageHeader.tempBufferPointer(absPtr, INVALID_REL_PTR);
@@ -907,6 +919,12 @@ public class PageMemoryImpl implements PageMemoryEx {
// We pinned the page when allocated the temp buffer, release it now.
PageHeader.releasePage(absPtr);
+
+ // Need release again because we pin page when resolve abs pointer,
+ // and page did not have tmp buffer page.
+ if (!tmpBuffer)
+ PageHeader.releasePage(absPtr);
+
}
else {
copyInBuffer(absPtr, tmpBuf);
