Cassandra
  1. Cassandra
  2. CASSANDRA-3706

Back up configuration files on startup

    Details

    • Type: New Feature New Feature
    • Status: Resolved
    • Priority: Minor Minor
    • Resolution: Won't Fix
    • Fix Version/s: None
    • Component/s: Tools
    • Labels:

      Description

      Snapshot can backup user data, but it's also nice to be able to have known-good configurations saved as well in case of accidental snafus or even catastrophic loss of a cluster. If we check for changes to cassandra.yaml, cassandra-env.sh, and maybe log4j-server.properties on startup, we can back them up to a columnfamily that can then be handled by normal snapshot/backup procedures.

      1. save_configuration_2.diff
        11 kB
        Dave Brosius
      2. save_configuration_3.diff
        11 kB
        Dave Brosius
      3. save_configuration_4.diff
        13 kB
        Dave Brosius
      4. save_configuration_6.diff
        31 kB
        Dave Brosius
      5. save_configuration_7.diff
        31 kB
        Dave Brosius
      6. save_configuration_8.diff
        22 kB
        Dave Brosius
      7. save_configuration_9.diff
        22 kB
        Dave Brosius
      8. save_configuration.diff
        11 kB
        Dave Brosius

        Activity

        Hide
        Dave Brosius added a comment -

        patch to save the yaml file in a 'configuration' column family in the system keyspace. Updates each time the server is started if the file has changed. Uses digests to track changes.

        Show
        Dave Brosius added a comment - patch to save the yaml file in a 'configuration' column family in the system keyspace. Updates each time the server is started if the file has changed. Uses digests to track changes.
        Hide
        Brandon Williams added a comment -

        Can we do this without org.apache.hadoop.io.IOUtils?

        Show
        Brandon Williams added a comment - Can we do this without org.apache.hadoop.io.IOUtils?
        Hide
        Dave Brosius added a comment -

        switch to use FileUtils.closeQuietly.

        Show
        Dave Brosius added a comment - switch to use FileUtils.closeQuietly.
        Hide
        Brandon Williams added a comment -

        Both git and patch say v2 is corrupt at line 184 and it does not apply.

        Show
        Brandon Williams added a comment - Both git and patch say v2 is corrupt at line 184 and it does not apply.
        Hide
        Dave Brosius added a comment -

        hmmm. sorry, trying again

        Show
        Dave Brosius added a comment - hmmm. sorry, trying again
        Hide
        Brandon Williams added a comment -

        This looks good, but a couple of things: using the IP address as the row key can make things a bit painful if the machine changes IPs. Is there any reason not to use a hardcoded, predictable key such as "CONFIG" or something similar?

        In a similar vein, a column for both the digest and the content seems like a bit much, couldn't we store the digest as the column name and the contents at the value?

        Finally, if we do use a static row key, an entire new CF for this seems like overkill, we could just stuff this into the STATUS_CF.

        Show
        Brandon Williams added a comment - This looks good, but a couple of things: using the IP address as the row key can make things a bit painful if the machine changes IPs. Is there any reason not to use a hardcoded, predictable key such as "CONFIG" or something similar? In a similar vein, a column for both the digest and the content seems like a bit much, couldn't we store the digest as the column name and the contents at the value? Finally, if we do use a static row key, an entire new CF for this seems like overkill, we could just stuff this into the STATUS_CF.
        Hide
        Dave Brosius added a comment - - edited

        I was assuming that there would be n rows in this CF, one per cluster member, each with it's own yaml. This calls for a non hard coded key, unless you want to make n columns representing each machine.

        As for the digest as the column name, when the yaml changes and you want to update the contents in the row, you would want to remove the old column, but you don't really know what the old column name is now. Perhaps you could just delete columns that you don't know what they are but that seems a little iffy to me.

        Show
        Dave Brosius added a comment - - edited I was assuming that there would be n rows in this CF, one per cluster member, each with it's own yaml. This calls for a non hard coded key, unless you want to make n columns representing each machine. As for the digest as the column name, when the yaml changes and you want to update the contents in the row, you would want to remove the old column, but you don't really know what the old column name is now. Perhaps you could just delete columns that you don't know what they are but that seems a little iffy to me.
        Hide
        Jonathan Ellis added a comment -

        system keyspace is local-only. We should probably add another ("cluster_system"?) that is reserved for internal use but is replicated normally.

        Show
        Jonathan Ellis added a comment - system keyspace is local-only. We should probably add another ("cluster_system"?) that is reserved for internal use but is replicated normally.
        Hide
        Brandon Williams added a comment -

        I was assuming that there would be n rows in this CF, one per cluster member, each with it's own yaml. This calls for a non hard coded key, unless you want to make n columns representing each machine.

        The system keyspace isn't replicated, though, and if we did store them all, IP would still be a bad choice. Since there's really no point in having every machine's config stored on every machine, a static key name seems fine.

        As for the digest as the column name, when the yaml changes and you want to update the contents in the row, you would want to remove the old column, but you don't really know what the old column name is now. Perhaps you could just delete columns that you don't know what they are but that seems a little iffy to me.

        I don't think a config will ever see so much churn this becomes an issue (in other words, we don't delete old configs, we just check that a column exists for the current digest and move on.) If somehow it does, this is where a static key can be handy, because opening up the cli and deleting LocationInfo['CONFIG'] is pretty simple.

        Show
        Brandon Williams added a comment - I was assuming that there would be n rows in this CF, one per cluster member, each with it's own yaml. This calls for a non hard coded key, unless you want to make n columns representing each machine. The system keyspace isn't replicated, though, and if we did store them all, IP would still be a bad choice. Since there's really no point in having every machine's config stored on every machine, a static key name seems fine. As for the digest as the column name, when the yaml changes and you want to update the contents in the row, you would want to remove the old column, but you don't really know what the old column name is now. Perhaps you could just delete columns that you don't know what they are but that seems a little iffy to me. I don't think a config will ever see so much churn this becomes an issue (in other words, we don't delete old configs, we just check that a column exists for the current digest and move on.) If somehow it does, this is where a static key can be handy, because opening up the cli and deleting LocationInfo ['CONFIG'] is pretty simple.
        Hide
        Dave Brosius added a comment - - edited

        Ah, the fact that system was local-only had escaped me, this makes your original comments (brandon) make alot more sense to me.

        As Jonathan points out, it makes no sense to save this information in the system keyspace then, as the point of this storage is for easing disaster recovery, and if the node goes down, the yaml as depicted in the keyspace is no more likely to survive than the yaml file in the conf directory. If this feature is to have value at all, it must be replicated, so a secondary quasi-system keyspace that is replicated would be needed.

        I planned to add support for the cassandra-env and log4j files as well, but wanted to get feed back first before proceeding with those as those files are not first class files in cassandra as the yaml file is, and thus marginally more tricky. Glad I did

        As for an IP being a poor choice for key, I agree it's sub-optimal, however it was used to ensure uniqueness, and have some tie back to the original machine (albeit not absolute). The only other choice I could think of is an added field in the yaml file such as cluster-node-id that had to be set by the administrator, but then we need to rely on the administrator to choose a unique one which is far less likely. To enforce this uniqueness that id would need to be added to the gossip protocol, and nodes need to be rejected with conflicting unique ids. All of that seems like overkill. While IPs seem problematic, I don't know how problematic they really are in practice. While these cluster nodes use gossip for communication, I still would wonder whether the standard deployment would use dhcp for these machines, as they still would need to be administered remotely. Thus for static ips, the changing ip problem wouldn't be one. But perhaps i'm talking out my ear.

        Let me know what you want to do, and i'll be glad to go forward, or cancel whatever is appropriate.

        Show
        Dave Brosius added a comment - - edited Ah, the fact that system was local-only had escaped me, this makes your original comments (brandon) make alot more sense to me. As Jonathan points out, it makes no sense to save this information in the system keyspace then, as the point of this storage is for easing disaster recovery, and if the node goes down, the yaml as depicted in the keyspace is no more likely to survive than the yaml file in the conf directory. If this feature is to have value at all, it must be replicated, so a secondary quasi-system keyspace that is replicated would be needed. I planned to add support for the cassandra-env and log4j files as well, but wanted to get feed back first before proceeding with those as those files are not first class files in cassandra as the yaml file is, and thus marginally more tricky. Glad I did As for an IP being a poor choice for key, I agree it's sub-optimal, however it was used to ensure uniqueness, and have some tie back to the original machine (albeit not absolute). The only other choice I could think of is an added field in the yaml file such as cluster-node-id that had to be set by the administrator, but then we need to rely on the administrator to choose a unique one which is far less likely. To enforce this uniqueness that id would need to be added to the gossip protocol, and nodes need to be rejected with conflicting unique ids. All of that seems like overkill. While IPs seem problematic, I don't know how problematic they really are in practice. While these cluster nodes use gossip for communication, I still would wonder whether the standard deployment would use dhcp for these machines, as they still would need to be administered remotely. Thus for static ips, the changing ip problem wouldn't be one. But perhaps i'm talking out my ear. Let me know what you want to do, and i'll be glad to go forward, or cancel whatever is appropriate.
        Hide
        Brandon Williams added a comment -

        We should probably add another ("cluster_system"?) that is reserved for internal use but is replicated normally.

        The wrinkle in this is something we've encountered before... what do we set the RF to when we don't know how many nodes there will be?

        Show
        Brandon Williams added a comment - We should probably add another ("cluster_system"?) that is reserved for internal use but is replicated normally. The wrinkle in this is something we've encountered before... what do we set the RF to when we don't know how many nodes there will be?
        Hide
        Dave Brosius added a comment -

        added saving of cassandra-env and log4j files. Patch not ready due to need for replicated storage.

        Show
        Dave Brosius added a comment - added saving of cassandra-env and log4j files. Patch not ready due to need for replicated storage.
        Hide
        Dave Brosius added a comment -

        Would it be possible to create dynamic RF values based on live endpoints, that would work sort of similar to how consistency specifications work?, ie

        RFs

        ALL -> equal to the number of live endpoints
        QUORUM -> equal to more than have of the live endpoints,
        -perhaps other constants-

        these constants could be mapped to negative value constants, i suppose, but would be calculated at the time they were needed, and not at startup.

        Show
        Dave Brosius added a comment - Would it be possible to create dynamic RF values based on live endpoints, that would work sort of similar to how consistency specifications work?, ie RFs ALL -> equal to the number of live endpoints QUORUM -> equal to more than have of the live endpoints, - perhaps other constants - these constants could be mapped to negative value constants, i suppose, but would be calculated at the time they were needed, and not at startup.
        Hide
        Jonathan Ellis added a comment -

        Especially if we're using it for "nice to have but not critical" data, I don't see a problem with going with SimpleStrategy/RF=1 and allowing admins to change that if they want.

        Show
        Jonathan Ellis added a comment - Especially if we're using it for "nice to have but not critical" data, I don't see a problem with going with SimpleStrategy/RF=1 and allowing admins to change that if they want.
        Hide
        Dave Brosius added a comment -

        Move the Configuration column family to a separate system_configuration keyspace that uses SimpleStrategy and RF=1.

        Added a Schema.instance.getSystemTables() method and use that for filtering out client queries.

        de-emphasize the use of Table.SYSTEM_TABLE where possible, use the inferred keyspace name.

        Very possible i missed something here due to ignorance, so a thorough review would be appreciated.

        Show
        Dave Brosius added a comment - Move the Configuration column family to a separate system_configuration keyspace that uses SimpleStrategy and RF=1. Added a Schema.instance.getSystemTables() method and use that for filtering out client queries. de-emphasize the use of Table.SYSTEM_TABLE where possible, use the inferred keyspace name. Very possible i missed something here due to ignorance, so a thorough review would be appreciated.
        Hide
        Dave Brosius added a comment -

        re-baseline patch

        Show
        Dave Brosius added a comment - re-baseline patch
        Hide
        Brandon Williams added a comment -

        As Jonathan points out, it makes no sense to save this information in the system keyspace then, as the point of this storage is for easing disaster recovery, and if the node goes down, the yaml as depicted in the keyspace is no more likely to survive than the yaml file in the conf directory. If this feature is to have value at all, it must be replicated, so a secondary quasi-system keyspace that is replicated would be needed.

        I'm not convinced this is necessarily true. If each node only stores its own config and you backup a snapshot of the node, you can restore it. If all data is lost and you have nothing to restore from, another node having a copy of the dead node's config is hardly useful; configs only diverge by initial_token in practice, and copying the config files directly from another node and changing the initial_token is more practical than extracting the files from a CF and then copying them (there is no way for the 'restored' node to do this automatically without a config to start with.)

        Show
        Brandon Williams added a comment - As Jonathan points out, it makes no sense to save this information in the system keyspace then, as the point of this storage is for easing disaster recovery, and if the node goes down, the yaml as depicted in the keyspace is no more likely to survive than the yaml file in the conf directory. If this feature is to have value at all, it must be replicated, so a secondary quasi-system keyspace that is replicated would be needed. I'm not convinced this is necessarily true. If each node only stores its own config and you backup a snapshot of the node, you can restore it. If all data is lost and you have nothing to restore from, another node having a copy of the dead node's config is hardly useful; configs only diverge by initial_token in practice, and copying the config files directly from another node and changing the initial_token is more practical than extracting the files from a CF and then copying them (there is no way for the 'restored' node to do this automatically without a config to start with.)
        Hide
        Jonathan Ellis added a comment -

        If each node only stores its own config and you backup a snapshot of the node, you can restore it

        The reason I think this probably doesn't belong node-local is, using a standard replicated CF makes it trivial for any normal client to connect to the cluster and say, "show me the config for node X," or, "query all backed-up config files, and make sure they are in sync."

        The first, single-node query is only a little harder with node-local storage (you need to defeat your client's connection pool, and connect to the right node), but this second is much more difficult: first you need to load a list of cluster members somehow, then connect to each and query in turn. Vs just doing a seq scan on a normal, non-node-local config CF to grab them all at once.

        Show
        Jonathan Ellis added a comment - If each node only stores its own config and you backup a snapshot of the node, you can restore it The reason I think this probably doesn't belong node-local is, using a standard replicated CF makes it trivial for any normal client to connect to the cluster and say, "show me the config for node X," or, "query all backed-up config files, and make sure they are in sync." The first, single-node query is only a little harder with node-local storage (you need to defeat your client's connection pool, and connect to the right node), but this second is much more difficult: first you need to load a list of cluster members somehow, then connect to each and query in turn. Vs just doing a seq scan on a normal, non-node-local config CF to grab them all at once.
        Hide
        Brandon Williams added a comment -

        Vs just doing a seq scan on a normal, non-node-local config CF to grab them all at once.

        But you still need a mechanism (local file access to each node, etc) to see if they are in sync.

        Show
        Brandon Williams added a comment - Vs just doing a seq scan on a normal, non-node-local config CF to grab them all at once. But you still need a mechanism (local file access to each node, etc) to see if they are in sync.
        Hide
        Jonathan Ellis added a comment -

        I don't follow, all I need is "for yaml in select yaml from backups: if yaml != last_yaml raise"

        Show
        Jonathan Ellis added a comment - I don't follow, all I need is "for yaml in select yaml from backups: if yaml != last_yaml raise"
        Hide
        Brandon Williams added a comment -

        Maybe I misunderstand what 'in sync' meant, but I'm not sure what last_yaml is if we're storing by digest (or why they'd every be the same, in that case.)

        (also we're backing up 3 different files, not just yaml, but that's not a big deal)

        Show
        Brandon Williams added a comment - Maybe I misunderstand what 'in sync' meant, but I'm not sure what last_yaml is if we're storing by digest (or why they'd every be the same, in that case.) (also we're backing up 3 different files, not just yaml, but that's not a big deal)
        Hide
        Jonathan Ellis added a comment -

        I'm not sure what last_yaml is if we're storing by digest

        Why would we do that? Just store the file raw. Then you don't need FS access, is my point.

        also we're backing up 3 different files, not just yaml, but that's not a big deal

        Yeah, I was kind of hoping the extrapolation would be obvious.

        Show
        Jonathan Ellis added a comment - I'm not sure what last_yaml is if we're storing by digest Why would we do that? Just store the file raw. Then you don't need FS access, is my point. also we're backing up 3 different files, not just yaml, but that's not a big deal Yeah, I was kind of hoping the extrapolation would be obvious.
        Hide
        Brandon Williams added a comment - - edited

        Ok, well, the patch as-is has no of finding the last_yaml since columns are keyed by digest.

        Show
        Brandon Williams added a comment - - edited Ok, well, the patch as-is has no of finding the last_yaml since columns are keyed by digest.
        Hide
        Jonathan Ellis added a comment -

        Okay, let me spell it out a bit more:

        last_yaml = None
        for yaml in query("select yaml from backups"):
          if last_yaml != None and yaml != last_yaml:
            raise 'cluster yaml out of sync'
          last_yaml = yaml
        

        ... that said, it would make sense to me to to use a data model like this:

        CREATE TABLE config_backups (
          peer inetaddress,
          backed_up_at datetime,
          cassandra_yaml text,
          cassandra_env text,
          PRIMARY KEY (peer, backed_up_at)
        )
        

        which would allow you to query history for a given node (at the cost of making my example loop for "compare current versions" more complex, since CQL isn't powerful enough to say "give me the most recent version for each node" – although you could do that with Hive).

        (could this use our new-fangled gossip node id instead of the ip?)

        Show
        Jonathan Ellis added a comment - Okay, let me spell it out a bit more: last_yaml = None for yaml in query( "select yaml from backups" ): if last_yaml != None and yaml != last_yaml: raise 'cluster yaml out of sync' last_yaml = yaml ... that said, it would make sense to me to to use a data model like this: CREATE TABLE config_backups ( peer inetaddress, backed_up_at datetime, cassandra_yaml text, cassandra_env text, PRIMARY KEY (peer, backed_up_at) ) which would allow you to query history for a given node (at the cost of making my example loop for "compare current versions" more complex, since CQL isn't powerful enough to say "give me the most recent version for each node" – although you could do that with Hive). (could this use our new-fangled gossip node id instead of the ip?)
        Hide
        Dave Brosius added a comment -

        currently the rows are keyed by ip address, and have columns

        YAMLDIGEST, YAMLCONTENTS, LOG4JDIGEST, LOG4JCONTENTS, ENVDIGEST, ENVCONTENTS

        the digest columns are so you don't constantly write duplicate 'blobs' into the database if nothing has changed. perhaps that's not much of a concern and i may be biased by the fact that i constant start and stop instances for debugging.

        In any case, i can change it to whatever you like.

        Show
        Dave Brosius added a comment - currently the rows are keyed by ip address, and have columns YAMLDIGEST, YAMLCONTENTS, LOG4JDIGEST, LOG4JCONTENTS, ENVDIGEST, ENVCONTENTS the digest columns are so you don't constantly write duplicate 'blobs' into the database if nothing has changed. perhaps that's not much of a concern and i may be biased by the fact that i constant start and stop instances for debugging. In any case, i can change it to whatever you like.
        Hide
        Brandon Williams added a comment -

        could this use our new-fangled gossip node id instead of the ip?

        For 1.2, that would be best, but complicates backward-compatibility if we put this in 1.1

        Show
        Brandon Williams added a comment - could this use our new-fangled gossip node id instead of the ip? For 1.2, that would be best, but complicates backward-compatibility if we put this in 1.1
        Hide
        Brandon Williams added a comment -

        i may be biased by the fact that i constant start and stop instances for debugging

        An option to disable this would be nice, as personally I would never use it.

        Show
        Brandon Williams added a comment - i may be biased by the fact that i constant start and stop instances for debugging An option to disable this would be nice, as personally I would never use it.
        Hide
        Jonathan Ellis added a comment -

        you can compare the raw text just as easily as the digest... it's a bit more cpu, but still negilible, and same amount of code.

        don't think it's worth the trouble to create an option to disable, if you don't need it just ignore it.

        Show
        Jonathan Ellis added a comment - you can compare the raw text just as easily as the digest... it's a bit more cpu, but still negilible, and same amount of code. don't think it's worth the trouble to create an option to disable, if you don't need it just ignore it.
        Hide
        Dave Brosius added a comment -

        rebase against latest (trunk) and also remove digest columns and just compare the in database blobs to the local files.

        Show
        Dave Brosius added a comment - rebase against latest (trunk) and also remove digest columns and just compare the in database blobs to the local files.
        Hide
        Brandon Williams added a comment -

        If we're going to push this to 1.2 (since your patch is against trunk) then using the new node id instead of the broadcast address would be nice, otherwise can you rebase to 1.1? Between the two, I think I'd rather put this in 1.2, since node id seems like the optimal way to do this, as changing all the IPs in a cluster is actually not all that uncommon.

        Show
        Brandon Williams added a comment - If we're going to push this to 1.2 (since your patch is against trunk) then using the new node id instead of the broadcast address would be nice, otherwise can you rebase to 1.1? Between the two, I think I'd rather put this in 1.2, since node id seems like the optimal way to do this, as changing all the IPs in a cluster is actually not all that uncommon.
        Hide
        Jonathan Ellis added a comment -

        another vote for 1.2

        Show
        Jonathan Ellis added a comment - another vote for 1.2
        Hide
        Dave Brosius added a comment -

        switch to using Node Ids as keys

        Show
        Dave Brosius added a comment - switch to using Node Ids as keys
        Hide
        Brandon Williams added a comment -

        I'm getting the following exception upon modifying a config and restarting:

         INFO 15:26:57,770 Opening /var/lib/cassandra/data/system_configuration/Configuration/system_configuration-Configuration-ia-1 (23286 bytes)
        ERROR 15:26:57,788 Exception encountered during startup
        java.lang.AssertionError
                at org.apache.cassandra.db.SystemTable.getCurrentLocalNodeId(SystemTable.java:582)
                at org.apache.cassandra.utils.NodeId$LocalNodeIdHistory.<init>(NodeId.java:194)
                at org.apache.cassandra.utils.NodeId$LocalIds.<clinit>(NodeId.java:42)
                at org.apache.cassandra.utils.NodeId.localIds(NodeId.java:49)
                at org.apache.cassandra.utils.NodeId.getLocalId(NodeId.java:54)
                at org.apache.cassandra.db.SystemTable.saveConfiguration(SystemTable.java:340)
                at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:184)
                at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:355)
                at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:105)
        java.lang.AssertionError
                at org.apache.cassandra.db.SystemTable.getCurrentLocalNodeId(SystemTable.java:582)
                at org.apache.cassandra.utils.NodeId$LocalNodeIdHistory.<init>(NodeId.java:194)
                at org.apache.cassandra.utils.NodeId$LocalIds.<clinit>(NodeId.java:42)
                at org.apache.cassandra.utils.NodeId.localIds(NodeId.java:49)
                at org.apache.cassandra.utils.NodeId.getLocalId(NodeId.java:54)
                at org.apache.cassandra.db.SystemTable.saveConfiguration(SystemTable.java:340)
                at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:184)
                at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:355)
                at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:105)
        Exception encountered during startup: null
        

        Also, it would be nice to log at INFO when a new config is being saved.

        Show
        Brandon Williams added a comment - I'm getting the following exception upon modifying a config and restarting: INFO 15:26:57,770 Opening /var/lib/cassandra/data/system_configuration/Configuration/system_configuration-Configuration-ia-1 (23286 bytes) ERROR 15:26:57,788 Exception encountered during startup java.lang.AssertionError at org.apache.cassandra.db.SystemTable.getCurrentLocalNodeId(SystemTable.java:582) at org.apache.cassandra.utils.NodeId$LocalNodeIdHistory.<init>(NodeId.java:194) at org.apache.cassandra.utils.NodeId$LocalIds.<clinit>(NodeId.java:42) at org.apache.cassandra.utils.NodeId.localIds(NodeId.java:49) at org.apache.cassandra.utils.NodeId.getLocalId(NodeId.java:54) at org.apache.cassandra.db.SystemTable.saveConfiguration(SystemTable.java:340) at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:184) at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:355) at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:105) java.lang.AssertionError at org.apache.cassandra.db.SystemTable.getCurrentLocalNodeId(SystemTable.java:582) at org.apache.cassandra.utils.NodeId$LocalNodeIdHistory.<init>(NodeId.java:194) at org.apache.cassandra.utils.NodeId$LocalIds.<clinit>(NodeId.java:42) at org.apache.cassandra.utils.NodeId.localIds(NodeId.java:49) at org.apache.cassandra.utils.NodeId.getLocalId(NodeId.java:54) at org.apache.cassandra.db.SystemTable.saveConfiguration(SystemTable.java:340) at org.apache.cassandra.service.AbstractCassandraDaemon.setup(AbstractCassandraDaemon.java:184) at org.apache.cassandra.service.AbstractCassandraDaemon.activate(AbstractCassandraDaemon.java:355) at org.apache.cassandra.thrift.CassandraDaemon.main(CassandraDaemon.java:105) Exception encountered during startup: null Also, it would be nice to log at INFO when a new config is being saved.
        Hide
        Jonathan Ellis added a comment -

        let me see if i can get CASSANDRA-4018 done today... would be nice to build on that

        Show
        Jonathan Ellis added a comment - let me see if i can get CASSANDRA-4018 done today... would be nice to build on that
        Hide
        Jonathan Ellis added a comment -

        let me see if i can get CASSANDRA-4018 done today... would be nice to build on that

        I was thinking in terms of using a composite column to keep multiple versions around, but re-thinking that, if people want multiple versions they should be responsible for snapshot + backup themselves. So, never mind.

        Show
        Jonathan Ellis added a comment - let me see if i can get CASSANDRA-4018 done today... would be nice to build on that I was thinking in terms of using a composite column to keep multiple versions around, but re-thinking that, if people want multiple versions they should be responsible for snapshot + backup themselves. So, never mind.
        Hide
        David Alves added a comment -

        How far is this from going in? Any thing I can do to help? CASSANDRA-1123 will also need distributed system tables and I'd like to minimize duplicate code.

        I can split the patch into generic dist system tables and specific configuration backup + rebase and use the common part in 1123.

        wdyt?

        Show
        David Alves added a comment - How far is this from going in? Any thing I can do to help? CASSANDRA-1123 will also need distributed system tables and I'd like to minimize duplicate code. I can split the patch into generic dist system tables and specific configuration backup + rebase and use the common part in 1123. wdyt?
        Hide
        Jonathan Ellis added a comment -

        I'd just go ahead and build the generic distributed system keyspace in 1123 and we'll rebase this on top.

        Show
        Jonathan Ellis added a comment - I'd just go ahead and build the generic distributed system keyspace in 1123 and we'll rebase this on top.
        Hide
        Jonathan Ellis added a comment -

        I think the discomfort we ran into here is a good sign that this is something better managed outside of C*.

        Show
        Jonathan Ellis added a comment - I think the discomfort we ran into here is a good sign that this is something better managed outside of C*.

          People

          • Assignee:
            Dave Brosius
            Reporter:
            Jonathan Ellis
          • Votes:
            1 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development