Skip to content
This repository was archived by the owner on Aug 10, 2025. It is now read-only.

Commit 90efa79

Browse files
committed
Fix the race condition between readEvictedBlock and mergeUnevictedTuples.
1 parent ac7c2a9 commit 90efa79

File tree

6 files changed

+49
-9
lines changed

6 files changed

+49
-9
lines changed

properties/benchmarks/ycsb.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,4 @@ fixed_size = false
1010
num_records = 100000
1111

1212
# Zipfian skew factor for tuple access
13-
skew_factor = 1.25
13+
skew_factor = 0.8

src/ee/anticache/AntiCacheEvictionManager.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,12 +1169,22 @@ Table* AntiCacheEvictionManager::evictBlockInBatch(PersistentTable *table, Persi
11691169

11701170
bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t block_id, int32_t tuple_offset) {
11711171

1172-
bool already_unevicted = table->isAlreadyUnEvicted(block_id);
1172+
int already_unevicted = table->isAlreadyUnEvicted(block_id);
11731173
if (already_unevicted && table->mergeStrategy()) { // this block has already been read
11741174
VOLT_WARN("Block 0x%x has already been read.", block_id);
11751175
return true;
11761176
}
11771177

1178+
if (already_unevicted) { // this block has already been read, but it is tuple-merge strategy
1179+
table->insertUnevictedBlock(table->getUnevictedBlocks(already_unevicted - 1));
1180+
table->insertTupleOffset(tuple_offset);
1181+
1182+
VOLT_DEBUG("BLOCK %u TUPLE %d - unevicted blocks size is %d",
1183+
block_id, tuple_offset, already_unevicted);
1184+
1185+
return true;
1186+
}
1187+
11781188
/*
11791189
* Finds the AntiCacheDB* instance associated with the needed block_id
11801190
*/
@@ -1239,8 +1249,11 @@ bool AntiCacheEvictionManager::readEvictedBlock(PersistentTable *table, int32_t
12391249
table->insertTupleOffset(tuple_offset);
12401250

12411251

1242-
table->insertUnevictedBlockID(std::pair<int32_t,int16_t>(block_id, 0));
1252+
table->insertUnevictedBlockID(std::pair<int32_t,int32_t>(block_id, table->unevictedBlocksSize()));
12431253

1254+
VOLT_DEBUG("BLOCK %u TUPLE %d - unevicted blocks size is %d",
1255+
block_id, tuple_offset, static_cast<int>(table->unevictedBlocksSize()));
1256+
12441257
delete value;
12451258
} catch (UnknownBlockAccessException e) {
12461259
throw e;
@@ -1642,11 +1655,22 @@ bool AntiCacheEvictionManager::mergeUnevictedTuples(PersistentTable *table) {
16421655

16431656

16441657

1645-
delete [] table->getUnevictedBlocks(i);
1658+
if (table->mergeStrategy())
1659+
delete [] table->getUnevictedBlocks(i);
16461660
//table->clearUnevictedBlocks(i);
16471661
}
16481662

1663+
VOLT_DEBUG("unevicted blockIDs size %d", static_cast<int>(table->getUnevictedBlockIDs().size()));
16491664
VOLT_DEBUG("unevicted blocks size %d", static_cast<int>(table->unevictedBlocksSize()));
1665+
if (!table->mergeStrategy()) {
1666+
map <int32_t, int32_t> unevictedBlockIDs = table->getUnevictedBlockIDs();
1667+
for (map <int32_t, int32_t>::iterator itr = unevictedBlockIDs.begin(); itr != unevictedBlockIDs.end();
1668+
itr++) {
1669+
//printf("bid:%d idx:%d\n", itr->first, itr->second);
1670+
delete [] table->getUnevictedBlocks(itr->second - 1);
1671+
}
1672+
table->clearUnevictedBlockIDs();
1673+
}
16501674
table->clearUnevictedBlocks();
16511675
table->clearMergeTupleOffsets();
16521676

src/ee/storage/persistenttable.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,15 +317,18 @@ std::map<int32_t, int32_t> PersistentTable::getUnevictedBlockIDs()
317317
return m_unevictedBlockIDs;
318318
}
319319

320-
bool PersistentTable::isAlreadyUnEvicted(int32_t blockId)
320+
int PersistentTable::isAlreadyUnEvicted(int32_t blockId)
321321
{
322-
return m_unevictedBlockIDs.find(blockId) != m_unevictedBlockIDs.end();
322+
if (m_unevictedBlockIDs.find(blockId) != m_unevictedBlockIDs.end())
323+
return m_unevictedBlockIDs[blockId];
324+
else
325+
return 0;
323326
}
324327

325328
void PersistentTable::insertUnevictedBlockID(std::pair<int32_t,int32_t> pair)
326329
{
327330
VOLT_INFO("Unevicted pair is %d", pair.first);
328-
m_unevictedBlockIDs.insert(pair);
331+
m_unevictedBlockIDs[pair.first] = pair.second;
329332
}
330333

331334
bool PersistentTable::removeUnevictedBlockID(int32_t blockId) {
@@ -388,6 +391,10 @@ void PersistentTable::clearUnevictedBlocks()
388391
{
389392
m_unevictedBlocks.clear();
390393
}
394+
void PersistentTable::clearUnevictedBlockIDs()
395+
{
396+
m_unevictedBlockIDs.clear();
397+
}
391398
void PersistentTable::clearUnevictedBlocks(int i)
392399
{
393400
m_unevictedBlocks.erase(m_unevictedBlocks.begin()+i);

src/ee/storage/persistenttable.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -300,15 +300,16 @@ class PersistentTable : public Table {
300300
bool removeUnevictedBlockID(int32_t blockId);
301301
void insertUnevictedBlock(char* unevicted_tuples);
302302
void insertTupleOffset(int32_t tuple_offset);
303-
bool isAlreadyUnEvicted(int32_t blockId);
303+
int isAlreadyUnEvicted(int32_t blockId);
304304
int32_t getTuplesRead();
305305
void setTuplesRead(int32_t tuplesRead);
306306
void setBatchEvicted(bool batchEvicted);
307307
bool isBatchEvicted();
308308
void clearUnevictedBlocks();
309309
void clearMergeTupleOffsets();
310310
int64_t unevictTuple(ReferenceSerializeInput * in, int j, int merge_tuple_offset, bool blockMerge);
311-
void clearUnevictedBlocks(int i);
311+
void clearUnevictedBlocks(int i);
312+
void clearUnevictedBlockIDs();
312313
char* getUnevictedBlocks(int i);
313314
int unevictedBlocksSize();
314315

src/frontend/edu/brown/hstore/AntiCacheManager.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import java.util.Map;
1515
import java.util.Set;
1616
import java.util.concurrent.LinkedBlockingQueue;
17+
import java.util.concurrent.locks.ReentrantLock;
1718

1819
import org.apache.log4j.Logger;
1920
import org.voltdb.CatalogContext;
@@ -63,6 +64,8 @@ public class AntiCacheManager extends AbstractProcessingRunnable<AntiCacheManage
6364
private static final Logger LOG = Logger.getLogger(AntiCacheManager.class);
6465
private static final LoggerBoolean debug = new LoggerBoolean();
6566
private static final LoggerBoolean trace = new LoggerBoolean();
67+
public static final ReentrantLock lock = new ReentrantLock();
68+
6669
static {
6770
LoggerUtil.attachObserver(LOG, debug, trace);
6871
}
@@ -305,6 +308,7 @@ protected void processingCallback(QueueEntry next) {
305308
// block the AntiCacheManager until each of the requests are finished
306309
if (hstore_conf.site.anticache_profiling)
307310
this.profilers[next.partition].retrieval_time.start();
311+
lock.lock();
308312
try {
309313
if (debug.val)
310314
LOG.debug(String.format("Asking EE to read in evicted blocks from table %s on partition %d: %s",
@@ -320,6 +324,7 @@ protected void processingCallback(QueueEntry next) {
320324

321325
// merge_needed = false;
322326
} finally {
327+
lock.unlock();
323328
if (hstore_conf.site.anticache_profiling)
324329
this.profilers[next.partition].retrieval_time.stopIfStarted();
325330
}

src/frontend/org/voltdb/VoltProcedure.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import edu.brown.hstore.conf.HStoreConf;
6161
import edu.brown.hstore.txns.LocalTransaction;
6262
import edu.brown.hstore.util.ParameterSetArrayCache;
63+
import edu.brown.hstore.AntiCacheManager;
6364
import edu.brown.interfaces.DebugContext;
6465
import edu.brown.logging.LoggerUtil;
6566
import edu.brown.logging.LoggerUtil.LoggerBoolean;
@@ -585,10 +586,12 @@ public final ClientResponseImpl call(LocalTransaction txnState, Object... paramL
585586

586587
// Note that I decided to put this in here because we already
587588
// have the logic down below for handling various errors from the EE
589+
AntiCacheManager.lock.lock();
588590
try {
589591
Table catalog_tbl = txnState.getAntiCacheMergeTable();
590592
this.executor.getExecutionEngine().antiCacheMergeBlocks(catalog_tbl);
591593
} finally {
594+
AntiCacheManager.lock.unlock();
592595
if (hstore_conf.site.anticache_profiling) {
593596
this.hstore_site.getAntiCacheManager()
594597
.getDebugContext()

0 commit comments

Comments
 (0)