On 12/8/20 1:56 PM, Ilya Maximets wrote: > Northbound database has many tables that could contain columns with > very large sets. For example 'ports' column of the 'Logical_Switch' > table could contain thousands of ports in a set. > > Current strategy of nbctl while adding a new port to the set is to > copy all existing ports, add one and set the new set of ports. > Similar behavior is for deletion too. > > If we have 1000 ports and want to add one more, resulted transaction > in current code will look like this: > > {transact, > < wait operation > > < create new lsp in Logical_Switch_Port table > > > where: _uuid == 'logical switch row uuid' > op : update > rows : ports ['< list of current 1000 ports + 1 new >'] > } > > The code was written before support for partial updates for sets was > implemented. Now we have it and can replace the old strategy. > With this change resulted transaction will be: > > {transact, > < wait operation > > < create new lsp in Logical_Switch_Port table > > > where: _uuid == 'logical switch row uuid' > op : mutate > mutations : ports insert ['< 1 uuid of a new lsp >'] > } > > Unfortunately, for now, this only decreases transaction size in half, > because '<wait operation>', that is still in the transaction, contains > the full current list of ports: > > where: _uuid == 'logical switch row uuid' > op : wait > until: == > rows : ports ['< list of current 1000 ports >'] > > But anyway, beside the overall code cleanup, this reduces transaction > size in half and should reduce pressure on the ovsdb-server since it > will not need to parse and process all 1000 ports twice. > > This change doesn't affect 'append_request' messages within the raft > cluster, because ovsdb-server is not smart enough to use mutations > there, and this will also not affect 'update' messages from the > ovsdb-server to its clients, because it is smart enough to construct > 'modify' updates regardless of the original transaction. > > One difference between full updates and partial is that partial > changes are not visible for the idl client until transaction is > committed and the update received from the server. New switch ports > are not visible while iterating over 'ports' of the logical switch and > removed ports are still there. For this reason, we have to maintain > runtime cache of the mapping between ports and routers/switches they > attached to. > > Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> > --- > utilities/ovn-nbctl.c | 348 +++++++++++------------------------------- > 1 file changed, 87 insertions(+), 261 deletions(-) >
Oops. I missed one unused variable during rebase, so there is a build warning with this patch on gcc. It could be fixed by applying this on top: diff --git a/utilities/ovn-nbctl.c b/utilities/ovn-nbctl.c index 812e8afab..942dcdb45 100644 --- a/utilities/ovn-nbctl.c +++ b/utilities/ovn-nbctl.c @@ -5944,11 +5944,9 @@ cmd_ha_ch_grp_remove_chassis(struct ctl_context *ctx) const char *chassis_name = ctx->argv[2]; struct nbrec_ha_chassis *ha_chassis = NULL; - size_t idx = 0; for (size_t i = 0; i < ha_ch_grp->n_ha_chassis; i++) { if (!strcmp(ha_ch_grp->ha_chassis[i]->chassis_name, chassis_name)) { ha_chassis = ha_ch_grp->ha_chassis[i]; - idx = i; break; } } --- I'd wait for some comments before re-spinning the series. Best regards, Ilya Maximets. _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev