mirror of https://github.com/hashicorp/consul
58387fef0a
Previously config entries sharing a kind & name but in different namespaces could occasionally cause "stuck states" in replication because the namespace fields were ignored during the differential comparison phase. Example: Two config entries written to the primary: kind=A,name=web,namespace=bar kind=A,name=web,namespace=foo Under the covers these both get saved to memdb, so they are sorted by all 3 components (kind,name,namespace) during natural iteration. This means that before the replication code does it's own incomplete sort, the underlying data IS sorted by namespace ascending (bar comes before foo). After one pass of replication the primary and secondary datacenters have the same set of config entries present. If "kind=A,name=web,namespace=bar" were to be deleted, then things get weird. Before replication the two sides look like: primary: [ kind=A,name=web,namespace=foo ] secondary: [ kind=A,name=web,namespace=bar kind=A,name=web,namespace=foo ] The differential comparison phase walks these two lists in sorted order and first compares "kind=A,name=web,namespace=foo" vs "kind=A,name=web,namespace=bar" and falsely determines they are the SAME and are thus cause an update of "kind=A,name=web,namespace=foo". Then it compares "<nothing>" with "kind=A,name=web,namespace=foo" and falsely determines that the latter should be DELETED. During reconciliation the deletes are processed before updates, and so for a brief moment in the secondary "kind=A,name=web,namespace=foo" is erroneously deleted and then immediately restored. Unfortunately after this replication phase the final state is identical to the initial state, so when it loops around again (rate limited) it repeats the same set of operations indefinitely. |
||
---|---|---|
.. | ||
acl.go | ||
acl_cache.go | ||
acl_cache_test.go | ||
acl_legacy.go | ||
acl_legacy_test.go | ||
acl_oss.go | ||
acl_test.go | ||
auto_encrypt.go | ||
catalog.go | ||
check_definition.go | ||
check_definition_test.go | ||
check_type.go | ||
config_entry.go | ||
config_entry_discoverychain.go | ||
config_entry_discoverychain_oss.go | ||
config_entry_discoverychain_test.go | ||
config_entry_gateways.go | ||
config_entry_gateways_test.go | ||
config_entry_intentions.go | ||
config_entry_intentions_test.go | ||
config_entry_oss.go | ||
config_entry_oss_test.go | ||
config_entry_test.go | ||
connect.go | ||
connect_ca.go | ||
connect_ca_test.go | ||
connect_oss.go | ||
connect_proxy_config.go | ||
connect_proxy_config_oss.go | ||
connect_proxy_config_test.go | ||
discovery_chain.go | ||
discovery_chain_oss.go | ||
errors.go | ||
federation_state.go | ||
intention.go | ||
intention_oss.go | ||
intention_test.go | ||
operator.go | ||
prepared_query.go | ||
prepared_query_test.go | ||
protobuf_compat.go | ||
sanitize_oss.go | ||
service_definition.go | ||
service_definition_test.go | ||
snapshot.go | ||
structs.go | ||
structs_filtering_test.go | ||
structs_oss.go | ||
structs_test.go | ||
system_metadata.go | ||
testing.go | ||
testing_catalog.go | ||
testing_connect_proxy_config.go | ||
testing_intention.go | ||
testing_service_definition.go | ||
txn.go |