use of org.apache.accumulo.core.metadata.schema.TabletDeletedException in project accumulo by apache.
the class ManagerClientServiceHandler method waitForFlush.
@Override
public void waitForFlush(TInfo tinfo, TCredentials c, String tableIdStr, ByteBuffer startRowBB, ByteBuffer endRowBB, long flushID, long maxLoops) throws ThriftSecurityException, ThriftTableOperationException {
TableId tableId = TableId.of(tableIdStr);
NamespaceId namespaceId = getNamespaceIdFromTableId(TableOperation.FLUSH, tableId);
if (!manager.security.canFlush(c, tableId, namespaceId))
throw new ThriftSecurityException(c.getPrincipal(), SecurityErrorCode.PERMISSION_DENIED);
Text startRow = ByteBufferUtil.toText(startRowBB);
Text endRow = ByteBufferUtil.toText(endRowBB);
if (endRow != null && startRow != null && startRow.compareTo(endRow) >= 0)
throw new ThriftTableOperationException(tableId.canonical(), null, TableOperation.FLUSH, TableOperationExceptionType.BAD_RANGE, "start row must be less than end row");
Set<TServerInstance> serversToFlush = new HashSet<>(manager.tserverSet.getCurrentServers());
for (long l = 0; l < maxLoops; l++) {
for (TServerInstance instance : serversToFlush) {
try {
final TServerConnection server = manager.tserverSet.getConnection(instance);
if (server != null)
server.flush(manager.managerLock, tableId, ByteBufferUtil.toBytes(startRowBB), ByteBufferUtil.toBytes(endRowBB));
} catch (TException ex) {
Manager.log.error(ex.toString());
}
}
if (tableId.equals(RootTable.ID))
// this code does not properly handle the root tablet. See #798
break;
if (l == maxLoops - 1)
break;
sleepUninterruptibly(50, TimeUnit.MILLISECONDS);
serversToFlush.clear();
try (TabletsMetadata tablets = TabletsMetadata.builder(manager.getContext()).forTable(tableId).overlapping(startRow, endRow).fetch(FLUSH_ID, LOCATION, LOGS, PREV_ROW).build()) {
int tabletsToWaitFor = 0;
int tabletCount = 0;
for (TabletMetadata tablet : tablets) {
int logs = tablet.getLogs().size();
// when tablet is not online and has no logs, there is no reason to wait for it
if ((tablet.hasCurrent() || logs > 0) && tablet.getFlushId().orElse(-1) < flushID) {
tabletsToWaitFor++;
if (tablet.hasCurrent())
serversToFlush.add(tablet.getLocation());
}
tabletCount++;
}
if (tabletsToWaitFor == 0)
break;
if (tabletCount == 0 && !manager.getContext().tableNodeExists(tableId))
throw new ThriftTableOperationException(tableId.canonical(), null, TableOperation.FLUSH, TableOperationExceptionType.NOTFOUND, null);
} catch (TabletDeletedException e) {
Manager.log.debug("Failed to scan {} table to wait for flush {}", MetadataTable.NAME, tableId, e);
}
}
}
use of org.apache.accumulo.core.metadata.schema.TabletDeletedException in project accumulo by apache.
the class MetadataTableUtil method checkClone.
@VisibleForTesting
public static int checkClone(String testTableName, TableId srcTableId, TableId tableId, AccumuloClient client, BatchWriter bw) throws TableNotFoundException, MutationsRejectedException {
Iterator<TabletMetadata> srcIter = createCloneScanner(testTableName, srcTableId, client).iterator();
Iterator<TabletMetadata> cloneIter = createCloneScanner(testTableName, tableId, client).iterator();
if (!cloneIter.hasNext() || !srcIter.hasNext())
throw new RuntimeException(" table deleted during clone? srcTableId = " + srcTableId + " tableId=" + tableId);
int rewrites = 0;
while (cloneIter.hasNext()) {
TabletMetadata cloneTablet = cloneIter.next();
Text cloneEndRow = cloneTablet.getEndRow();
HashSet<TabletFile> cloneFiles = new HashSet<>();
boolean cloneSuccessful = cloneTablet.getCloned() != null;
if (!cloneSuccessful)
cloneFiles.addAll(cloneTablet.getFiles());
List<TabletMetadata> srcTablets = new ArrayList<>();
TabletMetadata srcTablet = srcIter.next();
srcTablets.add(srcTablet);
Text srcEndRow = srcTablet.getEndRow();
int cmp = compareEndRows(cloneEndRow, srcEndRow);
if (cmp < 0)
throw new TabletDeletedException("Tablets deleted from src during clone : " + cloneEndRow + " " + srcEndRow);
HashSet<TabletFile> srcFiles = new HashSet<>();
if (!cloneSuccessful)
srcFiles.addAll(srcTablet.getFiles());
while (cmp > 0) {
srcTablet = srcIter.next();
srcTablets.add(srcTablet);
srcEndRow = srcTablet.getEndRow();
cmp = compareEndRows(cloneEndRow, srcEndRow);
if (cmp < 0)
throw new TabletDeletedException("Tablets deleted from src during clone : " + cloneEndRow + " " + srcEndRow);
if (!cloneSuccessful)
srcFiles.addAll(srcTablet.getFiles());
}
if (cloneSuccessful)
continue;
if (srcFiles.containsAll(cloneFiles)) {
// write out marker that this tablet was successfully cloned
Mutation m = new Mutation(cloneTablet.getExtent().toMetaRow());
m.put(ClonedColumnFamily.NAME, new Text(""), new Value("OK"));
bw.addMutation(m);
} else {
// delete existing cloned tablet entry
Mutation m = new Mutation(cloneTablet.getExtent().toMetaRow());
for (Entry<Key, Value> entry : cloneTablet.getKeyValues().entrySet()) {
Key k = entry.getKey();
m.putDelete(k.getColumnFamily(), k.getColumnQualifier(), k.getTimestamp());
}
bw.addMutation(m);
for (TabletMetadata st : srcTablets) bw.addMutation(createCloneMutation(srcTableId, tableId, st.getKeyValues()));
rewrites++;
}
}
bw.flush();
return rewrites;
}
use of org.apache.accumulo.core.metadata.schema.TabletDeletedException in project accumulo by apache.
the class MetadataTableUtil method cloneTable.
public static void cloneTable(ServerContext context, TableId srcTableId, TableId tableId) throws Exception {
try (BatchWriter bw = context.createBatchWriter(MetadataTable.NAME)) {
while (true) {
try {
initializeClone(null, srcTableId, tableId, context, bw);
while (true) {
int rewrites = checkClone(null, srcTableId, tableId, context, bw);
if (rewrites == 0)
break;
}
bw.flush();
break;
} catch (TabletDeletedException tde) {
// tablets were merged in the src table
bw.flush();
// delete what we have cloned and try again
deleteTable(tableId, false, context, null);
log.debug("Tablets merged in table {} while attempting to clone, trying again", srcTableId);
sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
}
}
// delete the clone markers and create directory entries
Scanner mscanner = context.createScanner(MetadataTable.NAME, Authorizations.EMPTY);
mscanner.setRange(new KeyExtent(tableId, null, null).toMetaRange());
mscanner.fetchColumnFamily(ClonedColumnFamily.NAME);
int dirCount = 0;
for (Entry<Key, Value> entry : mscanner) {
Key k = entry.getKey();
Mutation m = new Mutation(k.getRow());
m.putDelete(k.getColumnFamily(), k.getColumnQualifier());
byte[] dirName = FastFormat.toZeroPaddedString(dirCount++, 8, 16, Constants.CLONE_PREFIX_BYTES);
ServerColumnFamily.DIRECTORY_COLUMN.put(m, new Value(dirName));
bw.addMutation(m);
}
}
}
Aggregations