Commit 9deb000536e0 ("northd: Remove potential duplicates in SB Load_Balancer table.") added code to northd to ensure that SB duplicates get removed. Quoting from that commit message:
The Southbound Load_Balancer table (like the Northbound one) doesn't define an index (e.g., by name). This essentially means that there can be duplicate records in the database. Moreover, the OVSDB RAFT implementation ensures "at-least-once" consistency [0] making it possible for such duplicates to "spontaneously" appear. That is still the case, however, since then ovn-northd started to incrementally process (NB) load balancer updates and self-created SB.Load_Balancer records trigger a recompute of the "en_sync_to_sb_lb" node. At scale (e.g., an OpenShift cluster with 750 nodes and 64K load balancers) this is significant: inc_proc_eng|INFO|node: sync_to_sb_lb, recompute (missing handler for input SB_load_balancer) took 524ms All we actually care about is whether the transaction to create the SB record created a spurious clone. Instead of triggering a recompute, add a new handler for this type of SB update and check for duplicates. With the database from the same scale test as above the duplicate check is almost instantaneous. Signed-off-by: Dumitru Ceara <dce...@redhat.com> --- northd/en-sync-sb.c | 17 +++++++++++++++++ northd/en-sync-sb.h | 2 ++ northd/inc-proc-northd.c | 3 ++- northd/northd.c | 21 +++++++++++++++++++++ northd/northd.h | 1 + 5 files changed, 43 insertions(+), 1 deletion(-) diff --git a/northd/en-sync-sb.c b/northd/en-sync-sb.c index aae396a43d..8c07a71ee8 100644 --- a/northd/en-sync-sb.c +++ b/northd/en-sync-sb.c @@ -248,6 +248,23 @@ sync_to_sb_lb_northd_handler(struct engine_node *node, void *data OVS_UNUSED) return true; } +bool +sync_to_sb_lb_sb_load_balancer(struct engine_node *node, void *data OVS_UNUSED) +{ + const struct sbrec_load_balancer_table *sb_load_balancer_table = + EN_OVSDB_GET(engine_get_input("SB_load_balancer", node)); + + /* The only reason to handle SB.Load_Balancer updates is to detect + * spurious records being created in clustered databases due to + * lack of indexing on the SB.Load_Balancer table. All other changes + * are valid and performed by northd, the only write-client for + * this table. */ + if (check_sb_lb_duplicates(sb_load_balancer_table)) { + return false; + } + return true; +} + /* sync_to_sb_pb engine node functions. * This engine node syncs the SB Port Bindings (partly). * en_northd engine create the SB Port binding rows and diff --git a/northd/en-sync-sb.h b/northd/en-sync-sb.h index f08565eee1..3bcbb82594 100644 --- a/northd/en-sync-sb.h +++ b/northd/en-sync-sb.h @@ -21,6 +21,8 @@ void *en_sync_to_sb_lb_init(struct engine_node *, struct engine_arg *); void en_sync_to_sb_lb_run(struct engine_node *, void *data); void en_sync_to_sb_lb_cleanup(void *data); bool sync_to_sb_lb_northd_handler(struct engine_node *, void *data OVS_UNUSED); +bool sync_to_sb_lb_sb_load_balancer(struct engine_node *, + void *data OVS_UNUSED); void *en_sync_to_sb_pb_init(struct engine_node *, struct engine_arg *); void en_sync_to_sb_pb_run(struct engine_node *, void *data); diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c index 8b08171179..04df0b06c2 100644 --- a/northd/inc-proc-northd.c +++ b/northd/inc-proc-northd.c @@ -230,7 +230,8 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb, engine_add_input(&en_sync_to_sb_lb, &en_northd, sync_to_sb_lb_northd_handler); - engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer, NULL); + engine_add_input(&en_sync_to_sb_lb, &en_sb_load_balancer, + sync_to_sb_lb_sb_load_balancer); engine_add_input(&en_sync_to_sb_pb, &en_northd, sync_to_sb_pb_northd_handler); diff --git a/northd/northd.c b/northd/northd.c index 528027d07b..ead337219d 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -4660,6 +4660,27 @@ sync_lbs(struct ovsdb_idl_txn *ovnsb_txn, } } +bool +check_sb_lb_duplicates(const struct sbrec_load_balancer_table *table) +{ + struct sset existing_nb_lb_uuids = + SSET_INITIALIZER(&existing_nb_lb_uuids); + const struct sbrec_load_balancer *sbrec_lb; + bool duplicates = false; + + SBREC_LOAD_BALANCER_TABLE_FOR_EACH (sbrec_lb, table) { + const char *nb_lb_uuid = smap_get(&sbrec_lb->external_ids, "lb_id"); + if (nb_lb_uuid && !sset_add(&existing_nb_lb_uuids, + CONST_CAST(void *, nb_lb_uuid))) { + duplicates = true; + break; + } + } + + sset_destroy(&existing_nb_lb_uuids); + return duplicates; +} + /* Syncs the SB port binding for the ovn_port 'op'. Caller should make sure * that the OVN SB IDL txn is not NULL. Presently it only syncs the nat * column of port binding corresponding to the 'op->nbsp' */ diff --git a/northd/northd.h b/northd/northd.h index 05f4140d77..b30e005cf1 100644 --- a/northd/northd.h +++ b/northd/northd.h @@ -365,6 +365,7 @@ const struct ovn_datapath *northd_get_datapath_for_port( const struct hmap *ls_ports, const char *port_name); void sync_lbs(struct ovsdb_idl_txn *, const struct sbrec_load_balancer_table *, struct ovn_datapaths *ls_datapaths, struct hmap *lbs); +bool check_sb_lb_duplicates(const struct sbrec_load_balancer_table *); void sync_pbs(struct ovsdb_idl_txn *, struct hmap *ls_ports); bool sync_pbs_for_northd_ls_changes(struct tracked_ls_changes *); -- 2.39.3 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev