Search in sources :

Example 1 with MergeState

use of org.apache.accumulo.server.master.state.MergeState in project accumulo by apache.

the class MergeStats method nextMergeState.

public MergeState nextMergeState(Connector connector, CurrentState master) throws Exception {
    MergeState state = info.getState();
    if (state == MergeState.NONE)
        return state;
    if (total == 0) {
        log.trace("failed to see any tablets for this range, ignoring {}", info.getExtent());
        return state;
    }
    log.info("Computing next merge state for {} which is presently {} isDelete : {}", info.getExtent(), state, info.isDelete());
    if (state == MergeState.STARTED) {
        state = MergeState.SPLITTING;
    }
    if (state == MergeState.SPLITTING) {
        log.info("{} are hosted, total {}", hosted, total);
        if (!info.isDelete() && total == 1) {
            log.info("Merge range is already contained in a single tablet {}", info.getExtent());
            state = MergeState.COMPLETE;
        } else if (hosted == total) {
            if (info.isDelete()) {
                if (!lowerSplit)
                    log.info("Waiting for {} lower split to occur {}", info, info.getExtent());
                else if (!upperSplit)
                    log.info("Waiting for {} upper split to occur {}", info, info.getExtent());
                else
                    state = MergeState.WAITING_FOR_CHOPPED;
            } else {
                state = MergeState.WAITING_FOR_CHOPPED;
            }
        } else {
            log.info("Waiting for {} hosted tablets to be {} {}", hosted, total, info.getExtent());
        }
    }
    if (state == MergeState.WAITING_FOR_CHOPPED) {
        log.info("{} tablets are chopped {}", chopped, info.getExtent());
        if (chopped == needsToBeChopped) {
            state = MergeState.WAITING_FOR_OFFLINE;
        } else {
            log.info("Waiting for {} chopped tablets to be {} {}", chopped, needsToBeChopped, info.getExtent());
        }
    }
    if (state == MergeState.WAITING_FOR_OFFLINE) {
        if (chopped != needsToBeChopped) {
            log.warn("Unexpected state: chopped tablets should be {} was {} merge {}", needsToBeChopped, chopped, info.getExtent());
            // Perhaps a split occurred after we chopped, but before we went offline: start over
            state = MergeState.WAITING_FOR_CHOPPED;
        } else {
            log.info("{} tablets are chopped, {} are offline {}", chopped, unassigned, info.getExtent());
            if (unassigned == total && chopped == needsToBeChopped) {
                if (verifyMergeConsistency(connector, master))
                    state = MergeState.MERGING;
                else
                    log.info("Merge consistency check failed {}", info.getExtent());
            } else {
                log.info("Waiting for {} unassigned tablets to be {} {}", unassigned, total, info.getExtent());
            }
        }
    }
    if (state == MergeState.MERGING) {
        if (hosted != 0) {
            // Shouldn't happen
            log.error("Unexpected state: hosted tablets should be zero {} merge {}", hosted, info.getExtent());
            state = MergeState.WAITING_FOR_OFFLINE;
        }
        if (unassigned != total) {
            // Shouldn't happen
            log.error("Unexpected state: unassigned tablets should be {} was {} merge {}", total, unassigned, info.getExtent());
            state = MergeState.WAITING_FOR_CHOPPED;
        }
        log.info("{} tablets are unassigned {}", unassigned, info.getExtent());
    }
    return state;
}
Also used : MergeState(org.apache.accumulo.server.master.state.MergeState)

Example 2 with MergeState

use of org.apache.accumulo.server.master.state.MergeState in project accumulo by apache.

the class MergeStateIT method test.

@Test
public void test() throws Exception {
    AccumuloServerContext context = EasyMock.createMock(AccumuloServerContext.class);
    Connector connector = getConnector();
    EasyMock.expect(context.getConnector()).andReturn(connector).anyTimes();
    EasyMock.replay(context);
    connector.securityOperations().grantTablePermission(connector.whoami(), MetadataTable.NAME, TablePermission.WRITE);
    BatchWriter bw = connector.createBatchWriter(MetadataTable.NAME, new BatchWriterConfig());
    // 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
    Table.ID tableId = Table.ID.of("t");
    Text pr = null;
    for (String s : splits) {
        Text split = new Text(s);
        Mutation prevRow = KeyExtent.getPrevRowUpdateMutation(new KeyExtent(tableId, split, pr));
        prevRow.put(TabletsSection.CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234".getBytes()));
        ChoppedColumnFamily.CHOPPED_COLUMN.put(prevRow, new Value("junk".getBytes()));
        bw.addMutation(prevRow);
        pr = split;
    }
    // Add the default tablet
    Mutation defaultTablet = KeyExtent.getPrevRowUpdateMutation(new KeyExtent(tableId, null, pr));
    defaultTablet.put(TabletsSection.CurrentLocationColumnFamily.NAME, new Text("123456"), new Value("127.0.0.1:1234".getBytes()));
    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
    MetaDataStateStore metaDataStateStore = new MetaDataStateStore(context, state);
    int count = 0;
    for (TabletLocationState tss : metaDataStateStore) {
        if (tss != null)
            count++;
    }
    // the normal case is to skip tablets in a good state
    Assert.assertEquals(0, count);
    // Create the hole
    // Split the tablet at one end of the range
    Mutation m = new KeyExtent(tableId, new Text("t"), new Text("p")).getPrevRowUpdateMutation();
    TabletsSection.TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5".getBytes()));
    TabletsSection.TabletColumnFamily.OLD_PREV_ROW_COLUMN.put(m, KeyExtent.encodePrevEndRow(new Text("o")));
    update(connector, m);
    // do the state check
    MergeStats stats = scan(state, metaDataStateStore);
    MergeState newState = stats.nextMergeState(connector, state);
    Assert.assertEquals(MergeState.WAITING_FOR_OFFLINE, newState);
    // unassign the tablets
    BatchDeleter deleter = connector.createBatchDeleter(MetadataTable.NAME, Authorizations.EMPTY, 1000, new BatchWriterConfig());
    deleter.fetchColumnFamily(TabletsSection.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);
    Assert.assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(connector, state));
    // finish the split
    KeyExtent tablet = new KeyExtent(tableId, new Text("p"), new Text("o"));
    m = tablet.getPrevRowUpdateMutation();
    TabletsSection.TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5".getBytes()));
    update(connector, m);
    metaDataStateStore.setLocations(Collections.singletonList(new Assignment(tablet, state.someTServer)));
    // onos... there's a new tablet online
    stats = scan(state, metaDataStateStore);
    Assert.assertEquals(MergeState.WAITING_FOR_CHOPPED, stats.nextMergeState(connector, state));
    // chop it
    m = tablet.getPrevRowUpdateMutation();
    ChoppedColumnFamily.CHOPPED_COLUMN.put(m, new Value("junk".getBytes()));
    update(connector, m);
    stats = scan(state, metaDataStateStore);
    Assert.assertEquals(MergeState.WAITING_FOR_OFFLINE, stats.nextMergeState(connector, state));
    // take it offline
    m = tablet.getPrevRowUpdateMutation();
    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);
    Assert.assertEquals(MergeState.MERGING, stats.nextMergeState(connector, state));
}
Also used : Connector(org.apache.accumulo.core.client.Connector) MergeInfo(org.apache.accumulo.server.master.state.MergeInfo) BatchDeleter(org.apache.accumulo.core.client.BatchDeleter) AccumuloServerContext(org.apache.accumulo.server.AccumuloServerContext) MetadataTable(org.apache.accumulo.core.metadata.MetadataTable) Table(org.apache.accumulo.core.client.impl.Table) MergeState(org.apache.accumulo.server.master.state.MergeState) Text(org.apache.hadoop.io.Text) Range(org.apache.accumulo.core.data.Range) KeyExtent(org.apache.accumulo.core.data.impl.KeyExtent) MetaDataStateStore(org.apache.accumulo.server.master.state.MetaDataStateStore) Assignment(org.apache.accumulo.server.master.state.Assignment) Value(org.apache.accumulo.core.data.Value) MergeStats(org.apache.accumulo.master.state.MergeStats) BatchWriterConfig(org.apache.accumulo.core.client.BatchWriterConfig) TabletLocationState(org.apache.accumulo.server.master.state.TabletLocationState) Collection(java.util.Collection) BatchWriter(org.apache.accumulo.core.client.BatchWriter) Mutation(org.apache.accumulo.core.data.Mutation) Test(org.junit.Test)

Aggregations

MergeState (org.apache.accumulo.server.master.state.MergeState)2 Collection (java.util.Collection)1 BatchDeleter (org.apache.accumulo.core.client.BatchDeleter)1 BatchWriter (org.apache.accumulo.core.client.BatchWriter)1 BatchWriterConfig (org.apache.accumulo.core.client.BatchWriterConfig)1 Connector (org.apache.accumulo.core.client.Connector)1 Table (org.apache.accumulo.core.client.impl.Table)1 Mutation (org.apache.accumulo.core.data.Mutation)1 Range (org.apache.accumulo.core.data.Range)1 Value (org.apache.accumulo.core.data.Value)1 KeyExtent (org.apache.accumulo.core.data.impl.KeyExtent)1 MetadataTable (org.apache.accumulo.core.metadata.MetadataTable)1 MergeStats (org.apache.accumulo.master.state.MergeStats)1 AccumuloServerContext (org.apache.accumulo.server.AccumuloServerContext)1 Assignment (org.apache.accumulo.server.master.state.Assignment)1 MergeInfo (org.apache.accumulo.server.master.state.MergeInfo)1 MetaDataStateStore (org.apache.accumulo.server.master.state.MetaDataStateStore)1 TabletLocationState (org.apache.accumulo.server.master.state.TabletLocationState)1 Text (org.apache.hadoop.io.Text)1 Test (org.junit.Test)1