use of org.apache.accumulo.server.manager.state.TabletStateStore 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.server.manager.state.TabletStateStore 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.server.manager.state.TabletStateStore in project accumulo by apache.
the class ManagerRepairsDualAssignmentIT method test.
@Test
public void test() throws Exception {
// make some tablets, spread 'em around
try (AccumuloClient c = Accumulo.newClient().from(getClientProperties()).build()) {
ClientContext context = (ClientContext) c;
ServerContext serverContext = cluster.getServerContext();
String table = this.getUniqueNames(1)[0];
c.securityOperations().grantTablePermission("root", MetadataTable.NAME, TablePermission.WRITE);
c.securityOperations().grantTablePermission("root", RootTable.NAME, TablePermission.WRITE);
SortedSet<Text> partitions = new TreeSet<>();
for (String part : "a b c d e f g h i j k l m n o p q r s t u v w x y z".split(" ")) {
partitions.add(new Text(part));
}
NewTableConfiguration ntc = new NewTableConfiguration().withSplits(partitions);
c.tableOperations().create(table, ntc);
// scan the metadata table and get the two table location states
Set<TServerInstance> states = new HashSet<>();
Set<TabletLocationState> oldLocations = new HashSet<>();
TabletStateStore store = TabletStateStore.getStoreForLevel(DataLevel.USER, context);
while (states.size() < 2) {
UtilWaitThread.sleep(250);
oldLocations.clear();
for (TabletLocationState tls : store) {
if (tls.current != null) {
states.add(tls.current);
oldLocations.add(tls);
}
}
}
assertEquals(2, states.size());
// Kill a tablet server... we don't care which one... wait for everything to be reassigned
cluster.killProcess(ServerType.TABLET_SERVER, cluster.getProcesses().get(ServerType.TABLET_SERVER).iterator().next());
Set<TServerInstance> replStates = new HashSet<>();
@SuppressWarnings("deprecation") TableId repTable = org.apache.accumulo.core.replication.ReplicationTable.ID;
// Find out which tablet server remains
while (true) {
UtilWaitThread.sleep(1000);
states.clear();
replStates.clear();
boolean allAssigned = true;
for (TabletLocationState tls : store) {
if (tls != null && tls.current != null) {
states.add(tls.current);
} else if (tls != null && tls.extent.equals(new KeyExtent(repTable, null, null))) {
replStates.add(tls.current);
} else {
allAssigned = false;
}
}
System.out.println(states + " size " + states.size() + " allAssigned " + allAssigned);
if (states.size() != 2 && allAssigned)
break;
}
assertEquals(1, replStates.size());
assertEquals(1, states.size());
// pick an assigned tablet and assign it to the old tablet
TabletLocationState moved = null;
for (TabletLocationState old : oldLocations) {
if (!states.contains(old.current)) {
moved = old;
}
}
assertNotEquals(null, moved);
// throw a mutation in as if we were the dying tablet
TabletMutator tabletMutator = serverContext.getAmple().mutateTablet(moved.extent);
tabletMutator.putLocation(moved.current, LocationType.CURRENT);
tabletMutator.mutate();
// wait for the manager to fix the problem
waitForCleanStore(store);
// now jam up the metadata table
tabletMutator = serverContext.getAmple().mutateTablet(new KeyExtent(MetadataTable.ID, null, null));
tabletMutator.putLocation(moved.current, LocationType.CURRENT);
tabletMutator.mutate();
waitForCleanStore(TabletStateStore.getStoreForLevel(DataLevel.METADATA, context));
}
}
Aggregations