/** * Call {@link #begin(Runnable)} with an empty {@link Runnable}. */ public WriteEntry begin() { return begin(() -> {}); }
/** * Wait until the read point catches up to the write point; i.e. wait on all outstanding mvccs * to complete. */ public void await() { // Add a write and then wait on reads to catch up to it. completeAndWait(begin()); }
/** * Method to safely get the next sequence number. * @return Next sequence number unassociated with any actual edit. * @throws IOException */ @VisibleForTesting protected long getNextSequenceId(final WAL wal) throws IOException { WriteEntry we = mvcc.begin(); mvcc.completeAndWait(we); return we.getWriteNumber(); }
@Override public WriteEntry writeMiniBatchOperationsToMemStore( final MiniBatchOperationInProgress<Mutation> miniBatchOp, @Nullable WriteEntry writeEntry) throws IOException { if (writeEntry == null) { writeEntry = region.mvcc.begin(); } super.writeMiniBatchOperationsToMemStore(miniBatchOp, writeEntry.getWriteNumber()); return writeEntry; }
@Override public Object answer(InvocationOnMock invocation) { WALKeyImpl walKey = invocation.getArgument(1); MultiVersionConcurrencyControl mvcc = walKey.getMvcc(); if (mvcc != null) { MultiVersionConcurrencyControl.WriteEntry we = mvcc.begin(); walKey.setWriteEntry(we); } return 01L; } });
@Override public Object answer(InvocationOnMock invocation) { WALKeyImpl walKey = invocation.getArgument(1); MultiVersionConcurrencyControl mvcc = walKey.getMvcc(); if (mvcc != null) { MultiVersionConcurrencyControl.WriteEntry we = mvcc.begin(); walKey.setWriteEntry(we); } return 01L; } });
@Override public Object answer(InvocationOnMock invocation) { WALKeyImpl walKey = invocation.getArgument(1); MultiVersionConcurrencyControl mvcc = walKey.getMvcc(); if (mvcc != null) { MultiVersionConcurrencyControl.WriteEntry we = mvcc.begin(); walKey.setWriteEntry(we); } return 01L; } });
@Override public Object answer(InvocationOnMock invocation) { WALKeyImpl walKey = invocation.getArgument(1); MultiVersionConcurrencyControl mvcc = walKey.getMvcc(); if (mvcc != null) { MultiVersionConcurrencyControl.WriteEntry we = mvcc.begin(); walKey.setWriteEntry(we); } return 01L; } });
@Override public void run() { while (!finished.get()) { MultiVersionConcurrencyControl.WriteEntry e = mvcc.begin(); // System.out.println("Begin write: " + e.getWriteNumber()); // 10 usec - 500usec (including 0) int sleepTime = rnd.nextInt(500); // 500 * 1000 = 500,000ns = 500 usec // 1 * 100 = 100ns = 1usec try { if (sleepTime > 0) Thread.sleep(0, sleepTime * 1000); } catch (InterruptedException e1) { } try { mvcc.completeAndWait(e); } catch (RuntimeException ex) { // got failure System.out.println(ex.toString()); ex.printStackTrace(); status.set(false); return; // Report failure if possible. } } } }
@Override public long append(RegionInfo info, WALKeyImpl key, WALEdit edits, boolean inMemstore) throws IOException { WriteEntry writeEntry = key.getMvcc().begin(); if (!edits.isReplay()) { for (Cell cell : edits.getCells()) { PrivateCellUtil.setSequenceId(cell, writeEntry.getWriteNumber()); } } key.setWriteEntry(writeEntry); if (!this.listeners.isEmpty()) { final long start = System.nanoTime(); long len = 0; for (Cell cell : edits.getCells()) { len += PrivateCellUtil.estimatedSerializedSizeOf(cell); } final long elapsed = (System.nanoTime() - start) / 1000000L; for (WALActionsListener listener : this.listeners) { listener.postAppend(len, elapsed, key, edits); } } return -1; }
@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()); } }
protected final long stampSequenceIdAndPublishToRingBuffer(RegionInfo hri, WALKeyImpl key, WALEdit edits, boolean inMemstore, RingBuffer<RingBufferTruck> ringBuffer) throws IOException { if (this.closed) { throw new IOException( "Cannot append; log is closed, regionName = " + hri.getRegionNameAsString()); } MutableLong txidHolder = new MutableLong(); MultiVersionConcurrencyControl.WriteEntry we = key.getMvcc().begin(() -> { txidHolder.setValue(ringBuffer.next()); }); long txid = txidHolder.longValue(); try (TraceScope scope = TraceUtil.createTrace(implClassName + ".append")) { FSWALEntry entry = new FSWALEntry(txid, key, edits, hri, inMemstore); entry.stampRegionSequenceId(we); ringBuffer.get(txid).load(entry); } finally { ringBuffer.publish(txid); } return txid; }
private FSWALEntry createFSWALEntry(HTableDescriptor htd, HRegionInfo hri, long sequence, byte[] rowName, byte[] family, EnvironmentEdge ee, MultiVersionConcurrencyControl mvcc, int index, NavigableMap<byte[], Integer> scopes) throws IOException { FSWALEntry entry = new FSWALEntry(sequence, createWALKey(htd.getTableName(), hri, mvcc, scopes), createWALEdit( rowName, family, ee, index), hri, true); entry.stampRegionSequenceId(mvcc.begin()); return entry; }
writeEntry = mvcc.begin(); long flushOpSeqId = writeEntry.getWriteNumber(); FlushResultImpl flushResult =
@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}); }
writeEntry = mvcc.begin(); updateSequenceId(forMemStore.values(), writeEntry.getWriteNumber());
} else { writeEntry = this.mvcc.begin();
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()); } } }