use of org.apache.accumulo.core.metadata.TabletLocationState in project accumulo by apache.
the class NullTserver method main.
public static void main(String[] args) throws Exception {
Opts opts = new Opts();
opts.parseArgs(NullTserver.class.getName(), args);
// modify metadata
int zkTimeOut = (int) DefaultConfiguration.getInstance().getTimeInMillis(Property.INSTANCE_ZK_TIMEOUT);
var siteConfig = SiteConfiguration.auto();
ServerContext context = ServerContext.override(siteConfig, opts.iname, opts.keepers, zkTimeOut);
TransactionWatcher watcher = new TransactionWatcher(context);
ThriftClientHandler tch = new ThriftClientHandler(context, watcher);
Processor<Iface> processor = new Processor<>(tch);
TServerUtils.startTServer(context.getConfiguration(), ThriftServerType.CUSTOM_HS_HA, processor, "NullTServer", "null tserver", 2, ThreadPools.DEFAULT_TIMEOUT_MILLISECS, 1000, 10 * 1024 * 1024, null, null, -1, HostAndPort.fromParts("0.0.0.0", opts.port));
HostAndPort addr = HostAndPort.fromParts(InetAddress.getLocalHost().getHostName(), opts.port);
TableId tableId = context.getTableId(opts.tableName);
// read the locations for the table
Range tableRange = new KeyExtent(tableId, null, null).toMetaRange();
List<Assignment> assignments = new ArrayList<>();
try (var s = new MetaDataTableScanner(context, tableRange, MetadataTable.NAME)) {
long randomSessionID = opts.port;
TServerInstance instance = new TServerInstance(addr, randomSessionID);
while (s.hasNext()) {
TabletLocationState next = s.next();
assignments.add(new Assignment(next.extent, instance));
}
}
// point them to this server
TabletStateStore store = TabletStateStore.getStoreForLevel(DataLevel.USER, context);
store.setLocations(assignments);
while (true) {
sleepUninterruptibly(10, TimeUnit.SECONDS);
}
}
use of org.apache.accumulo.core.metadata.TabletLocationState in project accumulo by apache.
the class MergeStateIT method test.
@Test
public void test() throws Exception {
ServerContext context = getServerContext();
try (AccumuloClient accumuloClient = Accumulo.newClient().from(getClientProperties()).build()) {
accumuloClient.securityOperations().grantTablePermission(accumuloClient.whoami(), MetadataTable.NAME, TablePermission.WRITE);
BatchWriter bw = accumuloClient.createBatchWriter(MetadataTable.NAME);
// Create a fake METADATA table with these splits
String[] splits = { "a", "e", "j", "o", "t", "z" };
// create metadata for a table "t" with the splits above
TableId tableId = TableId.of("t");
Text pr = null;
for (String s : splits) {
Text split = new Text(s);
Mutation prevRow = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, split, pr));
prevRow.put(CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234"));
ChoppedColumnFamily.CHOPPED_COLUMN.put(prevRow, new Value("junk"));
bw.addMutation(prevRow);
pr = split;
}
// Add the default tablet
Mutation defaultTablet = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, null, pr));
defaultTablet.put(CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234"));
bw.addMutation(defaultTablet);
bw.close();
// Read out the TabletLocationStates
MockCurrentState state = new MockCurrentState(new MergeInfo(new KeyExtent(tableId, new Text("p"), new Text("e")), MergeInfo.Operation.MERGE));
// Verify the tablet state: hosted, and count
TabletStateStore metaDataStateStore = TabletStateStore.getStoreForLevel(DataLevel.USER, context, state);
int count = 0;
for (TabletLocationState tss : metaDataStateStore) {
if (tss != null)
count++;
}
// the normal case is to skip tablets in a good state
assertEquals(0, count);
// Create the hole
// Split the tablet at one end of the range
Mutation m = TabletColumnFamily.createPrevRowMutation(new KeyExtent(tableId, new Text("t"), new Text("p")));
TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5"));
TabletColumnFamily.OLD_PREV_ROW_COLUMN.put(m, TabletColumnFamily.encodePrevEndRow(new Text("o")));
update(accumuloClient, m);
// do the state check
MergeStats stats = scan(state, metaDataStateStore);
MergeState newState = stats.nextMergeState(accumuloClient, state);
assertEquals(MergeState.WAITING_FOR_OFFLINE, newState);
// unassign the tablets
try (BatchDeleter deleter = accumuloClient.createBatchDeleter(MetadataTable.NAME, Authorizations.EMPTY, 1000)) {
deleter.fetchColumnFamily(CurrentLocationColumnFamily.NAME);
deleter.setRanges(Collections.singletonList(new Range()));
deleter.delete();
}
// now we should be ready to merge but, we have inconsistent metadata
stats = scan(state, metaDataStateStore);
assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(accumuloClient, state));
// finish the split
KeyExtent tablet = new KeyExtent(tableId, new Text("p"), new Text("o"));
m = TabletColumnFamily.createPrevRowMutation(tablet);
TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5"));
update(accumuloClient, m);
metaDataStateStore.setLocations(Collections.singletonList(new Assignment(tablet, state.someTServer)));
// onos... there's a new tablet online
stats = scan(state, metaDataStateStore);
assertEquals(MergeState.WAITING_FOR_CHOPPED, stats.nextMergeState(accumuloClient, state));
// chop it
m = TabletColumnFamily.createPrevRowMutation(tablet);
ChoppedColumnFamily.CHOPPED_COLUMN.put(m, new Value("junk"));
update(accumuloClient, m);
stats = scan(state, metaDataStateStore);
assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(accumuloClient, state));
// take it offline
m = TabletColumnFamily.createPrevRowMutation(tablet);
Collection<Collection<String>> walogs = Collections.emptyList();
metaDataStateStore.unassign(Collections.singletonList(new TabletLocationState(tablet, null, state.someTServer, null, null, walogs, false)), null);
// now we can split
stats = scan(state, metaDataStateStore);
assertEquals(MergeState.MERGING, stats.nextMergeState(accumuloClient, state));
}
}
use of org.apache.accumulo.core.metadata.TabletLocationState in project accumulo by apache.
the class MetaDataStateStore method unassign.
private void unassign(Collection<TabletLocationState> tablets, Map<TServerInstance, List<Path>> logsForDeadServers, long suspensionTimestamp) throws DistributedStoreException {
try (var tabletsMutator = ample.mutateTablets()) {
for (TabletLocationState tls : tablets) {
TabletMutator tabletMutator = tabletsMutator.mutateTablet(tls.extent);
if (tls.current != null) {
tabletMutator.deleteLocation(tls.current, LocationType.CURRENT);
if (logsForDeadServers != null) {
List<Path> logs = logsForDeadServers.get(tls.current);
if (logs != null) {
for (Path log : logs) {
LogEntry entry = new LogEntry(tls.extent, 0, log.toString());
tabletMutator.putWal(entry);
}
}
}
if (suspensionTimestamp >= 0) {
tabletMutator.putSuspension(tls.current, suspensionTimestamp);
}
}
if (tls.suspend != null && suspensionTimestamp < 0) {
tabletMutator.deleteSuspension();
}
if (tls.future != null) {
tabletMutator.deleteLocation(tls.future, LocationType.FUTURE);
}
tabletMutator.mutate();
}
} catch (RuntimeException ex) {
throw new DistributedStoreException(ex);
}
}
use of org.apache.accumulo.core.metadata.TabletLocationState in project accumulo by apache.
the class ZooTabletStateStore method iterator.
@Override
public ClosableIterator<TabletLocationState> iterator() {
return new ClosableIterator<>() {
boolean finished = false;
@Override
public boolean hasNext() {
return !finished;
}
@Override
public TabletLocationState next() {
finished = true;
try {
TabletMetadata rootMeta = ample.readTablet(RootTable.EXTENT, ReadConsistency.EVENTUAL);
TServerInstance currentSession = null;
TServerInstance futureSession = null;
TServerInstance lastSession = null;
Location loc = rootMeta.getLocation();
if (loc != null && loc.getType() == LocationType.FUTURE)
futureSession = loc;
if (rootMeta.getLast() != null)
lastSession = rootMeta.getLast();
if (loc != null && loc.getType() == LocationType.CURRENT) {
currentSession = loc;
}
List<Collection<String>> logs = new ArrayList<>();
rootMeta.getLogs().forEach(logEntry -> {
logs.add(Collections.singleton(logEntry.filename));
log.debug("root tablet log {}", logEntry.filename);
});
return new TabletLocationState(RootTable.EXTENT, futureSession, currentSession, lastSession, null, logs, false);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
@Override
public void close() {
}
};
}
use of org.apache.accumulo.core.metadata.TabletLocationState in project accumulo by apache.
the class MetaDataTableScanner method createTabletLocationState.
public static TabletLocationState createTabletLocationState(Key k, Value v) throws IOException, BadLocationStateException {
final SortedMap<Key, Value> decodedRow = WholeRowIterator.decodeRow(k, v);
KeyExtent extent = null;
TServerInstance future = null;
TServerInstance current = null;
TServerInstance last = null;
SuspendingTServer suspend = null;
long lastTimestamp = 0;
List<Collection<String>> walogs = new ArrayList<>();
boolean chopped = false;
for (Entry<Key, Value> entry : decodedRow.entrySet()) {
Key key = entry.getKey();
Text row = key.getRow();
Text cf = key.getColumnFamily();
Text cq = key.getColumnQualifier();
if (cf.compareTo(FutureLocationColumnFamily.NAME) == 0) {
TServerInstance location = new TServerInstance(entry.getValue(), cq);
if (future != null) {
throw new BadLocationStateException("found two assignments for the same extent " + row + ": " + future + " and " + location, row);
}
future = location;
} else if (cf.compareTo(CurrentLocationColumnFamily.NAME) == 0) {
TServerInstance location = new TServerInstance(entry.getValue(), cq);
if (current != null) {
throw new BadLocationStateException("found two locations for the same extent " + row + ": " + current + " and " + location, row);
}
current = location;
} else if (cf.compareTo(LogColumnFamily.NAME) == 0) {
String[] split = entry.getValue().toString().split("\\|")[0].split(";");
walogs.add(Arrays.asList(split));
} else if (cf.compareTo(LastLocationColumnFamily.NAME) == 0) {
if (lastTimestamp < entry.getKey().getTimestamp()) {
last = new TServerInstance(entry.getValue(), cq);
}
} else if (cf.compareTo(ChoppedColumnFamily.NAME) == 0) {
chopped = true;
} else if (TabletColumnFamily.PREV_ROW_COLUMN.equals(cf, cq)) {
extent = KeyExtent.fromMetaPrevRow(entry);
} else if (SuspendLocationColumn.SUSPEND_COLUMN.equals(cf, cq)) {
suspend = SuspendingTServer.fromValue(entry.getValue());
}
}
if (extent == null) {
String msg = "No prev-row for key extent " + decodedRow;
log.error(msg);
throw new BadLocationStateException(msg, k.getRow());
}
return new TabletLocationState(extent, future, current, last, suspend, walogs, chopped);
}
Aggregations