Search in sources :

Example 1 with Migration

use of org.apache.cassandra.db.migration.Migration in project eiger by wlloyd.

the class DefinitionsUpdateVerbHandler method doVerb.

/** someone sent me their data definitions */
public void doVerb(final Message message, String id) {
    try {
        // these are the serialized row mutations that I must apply.
        // check versions at every step along the way to make sure migrations are not applied out of order.
        Collection<Column> cols = MigrationManager.makeColumns(message);
        for (Column col : cols) {
            final UUID version = UUIDGen.getUUID(col.name());
            if (version.timestamp() > Schema.instance.getVersion().timestamp()) {
                final Migration m = Migration.deserialize(col.value(), message.getVersion());
                assert m.getVersion().equals(version);
                StageManager.getStage(Stage.MIGRATION).submit(new WrappedRunnable() {

                    protected void runMayThrow() throws Exception {
                        // check to make sure the current version is before this one.
                        if (Schema.instance.getVersion().timestamp() == version.timestamp())
                            logger.debug("Not appling (equal) " + version.toString());
                        else if (Schema.instance.getVersion().timestamp() > version.timestamp())
                            logger.debug("Not applying (before)" + version.toString());
                        else {
                            logger.debug("Applying {} from {}", m.getClass().getSimpleName(), message.getFrom());
                            try {
                                m.apply();
                                // update gossip, but don't contact nodes directly
                                m.passiveAnnounce();
                            } catch (ConfigurationException ex) {
                                // Trying to apply the same migration twice. This happens as a result of gossip.
                                logger.debug("Migration not applied " + ex.getMessage());
                            }
                        }
                    }
                });
            }
        }
    } catch (IOException ex) {
        throw new IOError(ex);
    }
}
Also used : WrappedRunnable(org.apache.cassandra.utils.WrappedRunnable) ConfigurationException(org.apache.cassandra.config.ConfigurationException) IOError(java.io.IOError) Migration(org.apache.cassandra.db.migration.Migration) IOException(java.io.IOException) UUID(java.util.UUID) IOException(java.io.IOException) ConfigurationException(org.apache.cassandra.config.ConfigurationException)

Example 2 with Migration

use of org.apache.cassandra.db.migration.Migration in project eiger by wlloyd.

the class DefsTest method testMigrations.

@Test
public void testMigrations() throws IOException, ConfigurationException {
    // do a save. make sure it doesn't mess with the defs version.
    UUID prior = Schema.instance.getVersion();
    UUID ver0 = UUIDGen.makeType1UUIDFromHost(FBUtilities.getBroadcastAddress());
    DefsTable.dumpToStorage(ver0);
    assert Schema.instance.getVersion().equals(prior);
    // add a cf.
    CFMetaData newCf1 = addTestCF("Keyspace1", "MigrationCf_1", "Migration CF");
    Migration m1 = new AddColumnFamily(newCf1);
    m1.apply();
    UUID ver1 = m1.getVersion();
    assert Schema.instance.getVersion().equals(ver1);
    // drop it.
    Migration m3 = new DropColumnFamily("Keyspace1", "MigrationCf_1");
    m3.apply();
    UUID ver3 = m3.getVersion();
    assert Schema.instance.getVersion().equals(ver3);
    // now lets load the older migrations to see if that code works.
    Collection<IColumn> serializedMigrations = Migration.getLocalMigrations(ver1, ver3);
    assert serializedMigrations.size() == 2;
    // test deserialization of the migrations.
    Migration[] reconstituded = new Migration[2];
    int i = 0;
    for (IColumn col : serializedMigrations) {
        UUID version = UUIDGen.getUUID(col.name());
        reconstituded[i] = Migration.deserialize(col.value(), MessagingService.version_);
        assert version.equals(reconstituded[i].getVersion());
        i++;
    }
    assert m1.getClass().equals(reconstituded[0].getClass());
    assert m3.getClass().equals(reconstituded[1].getClass());
    // verify that the row mutations are the same. rather than exposing the private fields, serialize and verify.
    assert m1.serialize().equals(reconstituded[0].serialize());
    assert m3.serialize().equals(reconstituded[1].serialize());
}
Also used : Migration(org.apache.cassandra.db.migration.Migration) AddColumnFamily(org.apache.cassandra.db.migration.AddColumnFamily) DropColumnFamily(org.apache.cassandra.db.migration.DropColumnFamily) Test(org.junit.Test)

Example 3 with Migration

use of org.apache.cassandra.db.migration.Migration in project eiger by wlloyd.

the class MigrationManager method applyMigrations.

/**
     * gets called during startup if we notice a mismatch between the current migration version and the one saved. This
     * can only happen as a result of the commit log recovering schema updates, which overwrites lastVersionId.
     * 
     * This method silently eats IOExceptions thrown by Migration.apply() as a result of applying a migration out of
     * order.
     */
public static void applyMigrations(final UUID from, final UUID to) throws IOException {
    List<Future<?>> updates = new ArrayList<Future<?>>();
    Collection<IColumn> migrations = Migration.getLocalMigrations(from, to);
    for (IColumn col : migrations) {
        // assuming MessagingService.version_ is a bit of a risk, but you're playing with fire if you purposefully
        // take down a node to upgrade it during the middle of a schema update.
        final Migration migration = Migration.deserialize(col.value(), MessagingService.version_);
        Future<?> update = StageManager.getStage(Stage.MIGRATION).submit(new Runnable() {

            public void run() {
                try {
                    migration.apply();
                } catch (ConfigurationException ex) {
                    // this happens if we try to apply something that's already been applied. ignore and proceed.
                    logger.debug("Migration not applied " + ex.getMessage());
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        });
        updates.add(update);
    }
    // wait on all the updates before proceeding.
    for (Future<?> f : updates) {
        try {
            f.get();
        } catch (InterruptedException e) {
            throw new IOException(e);
        } catch (ExecutionException e) {
            throw new IOException(e);
        }
    }
    // we don't need to send rpcs, but we need to update gossip
    passiveAnnounce(to);
}
Also used : Migration(org.apache.cassandra.db.migration.Migration) IColumn(org.apache.cassandra.db.IColumn) ConfigurationException(org.apache.cassandra.config.ConfigurationException) Future(java.util.concurrent.Future) ExecutionException(java.util.concurrent.ExecutionException)

Aggregations

Migration (org.apache.cassandra.db.migration.Migration)3 ConfigurationException (org.apache.cassandra.config.ConfigurationException)2 IOError (java.io.IOError)1 IOException (java.io.IOException)1 UUID (java.util.UUID)1 ExecutionException (java.util.concurrent.ExecutionException)1 Future (java.util.concurrent.Future)1 IColumn (org.apache.cassandra.db.IColumn)1 AddColumnFamily (org.apache.cassandra.db.migration.AddColumnFamily)1 DropColumnFamily (org.apache.cassandra.db.migration.DropColumnFamily)1 WrappedRunnable (org.apache.cassandra.utils.WrappedRunnable)1 Test (org.junit.Test)1