From 6e13565dd32fb2cf5517f51ca06956e2052c4bba Mon Sep 17 00:00:00 2001 From: Ilya Maximets Date: Sun, 19 Dec 2021 15:09:38 +0100 Subject: ovsdb: transaction: Keep one entry in the transaction history. If a single transaction exceeds the size of the whole database (e.g., a lot of rows got removed and new ones added), transaction history will be drained. This leads to sending UUID_ZERO to the clients as the last transaction id in the next monitor update, because monitor doesn't know what was the actual last transaction id. In case of a re-connect that will cause re-downloading of the whole database, since the client's last_id will be out of sync. One solution would be to store the last transaction ID separately from the actual transactions, but that will require a careful management in cases where database gets reset and the history needs to be cleared. Keeping the one last transaction instead to avoid the problem. That should not be a big concern in terms of memory consumption, because this last transaction will be removed from the history once the next transaction appeared. This is also not a concern for a fast re-sync, because this last transaction will not be used for the monitor reply; it's either client already has it, so no need to send, or it's a history miss. The test updated to not check the number of atoms if there is only one transaction in the history. Fixes: 317b1bfd7dd3 ("ovsdb: Don't let transaction history grow larger than the database.") Reported-at: https://bugzilla.redhat.com/2044621 Acked-by: Mike Pattrick Acked-by: Han Zhou Signed-off-by: Ilya Maximets --- ovsdb/transaction.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'ovsdb') diff --git a/ovsdb/transaction.c b/ovsdb/transaction.c index 88e052800..db86d847c 100644 --- a/ovsdb/transaction.c +++ b/ovsdb/transaction.c @@ -1595,8 +1595,10 @@ ovsdb_txn_history_run(struct ovsdb *db) /* Remove old histories to limit the size of the history. Removing until * the number of ovsdb atoms in history becomes less than the number of * atoms in the database, because it will be faster to just get a database - * snapshot than re-constructing changes from the history that big. */ - while (db->n_txn_history && + * snapshot than re-constructing changes from the history that big. + * Keeping at least one transaction to avoid sending UUID_ZERO as a last id + * if all entries got removed due to the size limit. */ + while (db->n_txn_history > 1 && (db->n_txn_history > 100 || db->n_txn_history_atoms > db->n_atoms)) { struct ovsdb_txn_history_node *txn_h_node = CONTAINER_OF( -- cgit v1.2.1