/** * @return readpoint considering given IsolationLevel. Pass {@code null} for default */ public long getReadPoint(IsolationLevel isolationLevel) { if (isolationLevel != null && isolationLevel == IsolationLevel.READ_UNCOMMITTED) { // This scan can read even uncommitted transactions return Long.MAX_VALUE; } return mvcc.getReadPoint(); }
/** * @return The smallest mvcc readPoint across all the scanners in this * region. Writes older than this readPoint, are included in every * read operation. */ public long getSmallestReadPoint() { long minimumReadPoint; // We need to ensure that while we are calculating the smallestReadPoint // no new RegionScanners can grab a readPoint that we are unaware of. // We achieve this by synchronizing on the scannerReadPoints object. synchronized (scannerReadPoints) { minimumReadPoint = mvcc.getReadPoint(); for (Long readPoint : this.scannerReadPoints.values()) { if (readPoint < minimumReadPoint) { minimumReadPoint = readPoint; } } } return minimumReadPoint; }
@Override public void run() { long prev = mvcc.getReadPoint(); while (!finished.get()) { long newPrev = mvcc.getReadPoint(); if (newPrev < prev) { // serious problem. System.out.println("Reader got out of order, prev: " + prev + " next was: " + newPrev); readerFailed.set(true); // might as well give up failedAt.set(newPrev); return; } } } };
try { long currentSeqId = mvcc.getReadPoint(); if (seqId >= currentSeqId) {
&& (this.maxFlushedSeqId + this.flushPerChanges < this.mvcc.getReadPoint())) { whyFlush.append("more than max edits, " + this.flushPerChanges + ", since last flush"); return true;
private void writeRegionCloseMarker(WAL wal) throws IOException { Map<byte[], List<Path>> storeFiles = getStoreFiles(); RegionEventDescriptor regionEventDesc = ProtobufUtil.toRegionEventDescriptor( RegionEventDescriptor.EventType.REGION_CLOSE, getRegionInfo(), mvcc.getReadPoint(), getRegionServerServices().getServerName(), storeFiles); WALUtil.writeRegionEventMarker(wal, getReplicationScope(), getRegionInfo(), regionEventDesc, mvcc); // Store SeqId in WAL FileSystem when a region closes // checking region folder exists is due to many tests which delete the table folder while a // table is still online if (getWalFileSystem().exists(getWALRegionDir())) { WALSplitter.writeRegionSequenceIdFile(getWalFileSystem(), getWALRegionDir(), mvcc.getReadPoint()); } }
long earliest = this.wal.getEarliestMemStoreSeqNum(getRegionInfo().getEncodedNameAsBytes(), store.getColumnFamilyDescriptor().getName()) - 1; if (earliest > 0 && earliest + flushPerChanges < mvcc.getReadPoint()) { if (LOG.isDebugEnabled()) { LOG.debug("Flush column family " + store.getColumnFamilyName() + " of " + getRegionInfo().getEncodedName() + " because unflushed sequenceid=" + earliest + " is > " + this.flushPerChanges + " from current=" + mvcc.getReadPoint());
@Test public void testMemstoreConcurrentControl() throws IOException { final byte[] row = Bytes.toBytes(1); final byte[] f = Bytes.toBytes("family"); final byte[] q1 = Bytes.toBytes("q1"); final byte[] q2 = Bytes.toBytes("q2"); final byte[] v = Bytes.toBytes("value"); MultiVersionConcurrencyControl.WriteEntry w = mvcc.begin(); KeyValue kv1 = new KeyValue(row, f, q1, v); kv1.setSequenceId(w.getWriteNumber()); memstore.add(kv1, null); KeyValueScanner s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{}); mvcc.completeAndWait(w); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv1}); w = mvcc.begin(); KeyValue kv2 = new KeyValue(row, f, q2, v); kv2.setSequenceId(w.getWriteNumber()); memstore.add(kv2, null); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv1}); mvcc.completeAndWait(w); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv1, kv2}); }
@Test public void testSimpleMvccOps() { MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl(); long readPoint = mvcc.getReadPoint(); MultiVersionConcurrencyControl.WriteEntry writeEntry = mvcc.begin(); mvcc.completeAndWait(writeEntry); assertEquals(readPoint + 1, mvcc.getReadPoint()); writeEntry = mvcc.begin(); // The write point advances even though we may have 'failed'... call complete on fail. mvcc.complete(writeEntry); assertEquals(readPoint + 2, mvcc.getWritePoint()); } }
memstorescanners = this.memstore.getScanners(mvcc.getReadPoint()); scanner.close(); memstorescanners = this.memstore.getScanners(mvcc.getReadPoint());
KeyValueScanner s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv11, kv12}); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv11, kv12}); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv11, kvDel, kv12});
KeyValueScanner s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv11, kv12}); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv11, kv12}); s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); assertScannerResults(s, new KeyValue[]{kv21, kv11, kv22, kv12});
private void internalRun() throws IOException { for (long i = 0; i < NUM_TRIES && caughtException.get() == null; i++) { MultiVersionConcurrencyControl.WriteEntry w = mvcc.begin(); // Insert the sequence value (i) byte[] v = Bytes.toBytes(i); KeyValue kv = new KeyValue(row, f, q1, i, v); kv.setSequenceId(w.getWriteNumber()); memstore.add(kv, null); mvcc.completeAndWait(w); // Assert that we can read back KeyValueScanner s = this.memstore.getScanners(mvcc.getReadPoint()).get(0); s.seek(kv); Cell ret = s.next(); assertNotNull("Didnt find own write at all", ret); assertEquals("Didnt read own writes", kv.getTimestamp(), ret.getTimestamp()); } } }
@Test public void testSeqIdsFromReplay() throws IOException { // test the case where seqId's coming from replayed WALEdits are made persisted with their // original seqIds and they are made visible through mvcc read point upon replay String method = name.getMethodName(); byte[] tableName = Bytes.toBytes(method); byte[] family = Bytes.toBytes("family"); HRegion region = initHRegion(tableName, method, family); try { // replay an entry that is bigger than current read point long readPoint = region.getMVCC().getReadPoint(); long origSeqId = readPoint + 100; Put put = new Put(row).addColumn(family, row, row); put.setDurability(Durability.SKIP_WAL); // we replay with skip wal replay(region, put, origSeqId); // read point should have advanced to this seqId assertGet(region, family, row); // region seqId should have advanced at least to this seqId assertEquals(origSeqId, region.getReadPoint(null)); // replay an entry that is smaller than current read point // caution: adding an entry below current read point might cause partial dirty reads. Normal // replay does not allow reads while replay is going on. put = new Put(row2).addColumn(family, row2, row2); put.setDurability(Durability.SKIP_WAL); replay(region, put, origSeqId - 50); assertGet(region, family, row2); } finally { region.close(); } }
long readPoint = secondaryRegion.getMVCC().getReadPoint(); assertEquals(flushSeqId, readPoint);
protected void verifyScanAcrossSnapshot2(KeyValue kv1, KeyValue kv2) throws IOException { List<KeyValueScanner> memstorescanners = this.memstore.getScanners(mvcc.getReadPoint()); assertEquals(2, memstorescanners.size()); final KeyValueScanner scanner0 = memstorescanners.get(0); final KeyValueScanner scanner1 = memstorescanners.get(1); scanner0.seek(KeyValueUtil.createFirstOnRow(HConstants.EMPTY_START_ROW)); scanner1.seek(KeyValueUtil.createFirstOnRow(HConstants.EMPTY_START_ROW)); Cell n0 = scanner0.next(); Cell n1 = scanner1.next(); assertTrue(kv1.equals(n0) || kv1.equals(n1)); assertTrue(kv2.equals(n0) || kv2.equals(n1) || kv2.equals(scanner0.next()) || kv2.equals(scanner1.next())); assertNull(scanner0.next()); assertNull(scanner1.next()); }
assertEquals(seqid - 1, mvcc.getWritePoint()); LOG.debug("region.getOpenSeqNum(): " + region.getOpenSeqNum() + ", wal3.id: " + mvcc.getReadPoint());
@Override public long getReadpoint(IsolationLevel isolationLevel) { if (isolationLevel == IsolationLevel.READ_UNCOMMITTED) { // This scan can read even uncommitted transactions return Long.MAX_VALUE; } return mvcc.getReadPoint(); }
/** * Do not change this sequence id. * @return sequenceId */ @VisibleForTesting public long getSequenceId() { return this.mvcc.getReadPoint(); }
@Test public void testSimpleMvccOps() { MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl(); long readPoint = mvcc.getReadPoint(); MultiVersionConcurrencyControl.WriteEntry writeEntry = mvcc.begin(); mvcc.completeAndWait(writeEntry); assertEquals(readPoint + 1, mvcc.getReadPoint()); writeEntry = mvcc.begin(); // The write point advances even though we may have 'failed'... call complete on fail. mvcc.complete(writeEntry); assertEquals(readPoint + 2, mvcc.getWritePoint()); } }