2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

21 Commits

Author SHA1 Message Date
Mike Pattrick
0add983b38 ovsdb: Use table indexes if available for ovsdb_query().
Currently all OVSDB database queries except for UUID lookups all result
in linear lookups over the entire table, even if an index is present.

This patch modifies ovsdb_query() to attempt an index lookup first, if
possible. If no matching indexes are present then a linear index is
still conducted.

To test this, I set up an ovsdb database with a variable number of rows
and timed the average of how long ovsdb-client took to query a single
row. The first two tests involved a linear scan that didn't match any
rows, so there was no overhead associated with sending or encoding
output. The post-patch linear scan was a worst case scenario where the
table did have an appropriate index but the conditions made its usage
impossible. The indexed lookup test was for a matching row, which did
also include overhead associated with a match. The results are included
in the table below.

Rows                   | 100k | 200k | 300k | 400k | 500k
-----------------------+------+------+------+------+-----
Pre-patch linear scan  |  9ms | 24ms | 37ms | 49ms | 61ms
Post-patch linear scan |  9ms | 24ms | 38ms | 49ms | 61ms
Indexed lookup         |  3ms |  3ms |  3ms |  3ms |  3ms

I also tested the performance of ovsdb_query() by wrapping it in a loop
and measuring the time it took to perform 1000 linear scans on 1, 10,
100k, and 200k rows. This test showed that the new index checking code
did not slow down worst case lookups to a statistically detectable
degree.

Reported-at: https://issues.redhat.com/browse/FDP-590
Signed-off-by: Mike Pattrick <mkp@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2025-07-15 18:05:32 +02:00
Ilya Maximets
d51d4f42d3 ovsdb: Fix incorrect sharing of UUID and _version columns.
Datum of UUID and _version columns is accessed directly via
ovsdb_row_get_uuid_rw() and ovsdb_row_get_version_rw() functions
instead of ovsdb_data_* functions.  Meaning, the data will be
directly modified even if it is shared between rows.

Fix that by unsharing the data whenever RW pointer is taken.

The issue was mostly hidden because weak reference assessment
code always called ovsdb_datum_subtract() even if not needed.
This way all the new transaction rows were always implicitly
unshared.

Also making ovsdb_datum_subtract() call conditional, so the
issue can be hit by existing unit tests.

Fixes: 485ac63d10f8 ("ovsdb: Add lazy-copy support for ovsdb_datum objects.")
Acked-by: Mike Pattrick <mkp@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2024-01-08 22:41:11 +01:00
Ilya Maximets
2f1b430645 ovsdb: relay: Fix handling of XOR updates with size constraints.
Relay servers apply updates via ovsdb_table_execute_update().  XOR
updates contain datum diffs, and datum diffs can be larger than the
type constraints.  Currently, relay will fail to parse such update
into ovsdb row triggering a syntax error and a re-connection.

Fix that by relaxing the size constraints for this kind of updates.

Fixes: 026c77c58ddb ("ovsdb: New ovsdb 'relay' service model.")
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2023-08-03 14:19:32 +02:00
Ilya Maximets
3cd2cbd684 ovsdb: Prepare snapshot JSON in a separate thread.
Conversion of the database data into JSON object, serialization
and destruction of that object are the most heavy operations
during the database compaction.  If these operations are moved
to a separate thread, the main thread can continue processing
database requests in the meantime.

With this change, the compaction is split in 3 phases:

1. Initialization:
   - Create a copy of the database.
   - Remember current database index.
   - Start a separate thread to convert a copy of the database
     into serialized JSON object.

2. Wait:
   - Continue normal operation until compaction thread is done.
   - Meanwhile, compaction thread:
     * Convert database copy to JSON.
     * Serialize resulted JSON.
     * Destroy original JSON object.

3. Finish:
   - Destroy the database copy.
   - Take the snapshot created by the thread.
   - Write on disk.

The key for this schema to be fast is the ability to create
a shallow copy of the database.  This doesn't take too much
time allowing the thread to do most of work.

Database copy is created and destroyed only by the main thread,
so there is no need for synchronization.

Such solution allows to reduce the time main thread is blocked
by compaction by 80-90%.  For example, in ovn-heater tests
with 120 node density-heavy scenario, where compaction normally
takes 5-6 seconds at the end of a test, measured compaction
times was all below 1 second with the change applied.  Also,
note that these measured times are the sum of phases 1 and 3,
so actual poll intervals are about half a second in this case.

Only implemented for raft storage for now.  The implementation
for standalone databases can be added later by using a file
offset as a database index and copying newly added changes
from the old file to a new one during ovsdb_log_replace().

Reported-at: https://bugzilla.redhat.com/2069108
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2022-07-13 20:33:14 +02:00
Dumitru Ceara
a9ec4e3be3 ovsdb-server: Log database transactions for user requested tables.
Add a new command, 'ovsdb-server/tlog-set DB:TABLE on|off', which
allows the user to enable/disable transaction logging for specific
databases and tables.

By default, logging is disabled.  Once enabled, logs are generated
with level INFO and are also rate limited.

If used with care, this command can be useful in analyzing production
deployment performance issues, allowing the user to pin point
bottlenecks without the need to enable wider debug logs, e.g., jsonrpc.

A command to inspect the logging state is also added:
'ovsdb-server/tlog-list'.

Signed-off-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2022-06-28 13:45:36 +02:00
Ilya Maximets
4dbff9f0a6 ovsdb: transaction: Incremental reassessment of weak refs.
The main idea is to not store list of weak references in the source
row, so they all don't need to be re-checked/updated on every
modification of that source row.  The point is that source row already
knows UUIDs of all destination rows stored in the data, so there is no
much profit in storing this information somewhere else.  If needed,
destination row can be looked up and reference can be looked up in the
destination row.  For the fast lookup, destination row now stores
references in a hash map.

Weak reference structure now contains the table and uuid of a source
row instead of a direct pointer.  This allows to replace/update the
source row without breaking any weak references stored in destination
rows.

Structure also now contains the key-value pair of atoms that triggered
creation of this reference.  These atoms can be used to quickly
subtract removed references from a source row.  During reassessment,
ovsdb now only needs to care about new added or removed atoms, and
atoms that got removed due to removal of the destination rows, but
these are marked for reassessment by the destination row.

ovsdb_datum_subtract() is used to remove atoms that points to removed
or incorrect rows, so there is no need to re-sort datum in the end.

Results of an OVN load-balancer benchmark that adds 3K load-balancers
to each of 120 logical switches and 120 logical routers in the OVN
sandbox with clustered Northbound database and then removes them:

Before:

  %CPU  CPU Time  CMD
  86.8  00:16:05  ovsdb-server nb1.db
  44.1  00:08:11  ovsdb-server nb2.db
  43.2  00:08:00  ovsdb-server nb3.db

After:

  %CPU  CPU Time  CMD
  54.9  00:02:58  ovsdb-server nb1.db
  33.3  00:01:48  ovsdb-server nb2.db
  32.2  00:01:44  ovsdb-server nb3.db

So, on a cluster leader the processing time dropped by 5.4x, on
followers - by 4.5x.  More load-balancers - larger the performance
difference.  There is a slight increase of memory usage, because new
reference structure is larger, but the difference is not significant.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Acked-by: Dumitru Ceara <dceara@redhat.com>
2021-11-04 23:20:01 +01:00
Ilya Maximets
b4cef64c83 ovsdb: row: Add support for xor-based row updates.
This will be used to apply update3 type updates to ovsdb tables
while processing updates for future ovsdb 'relay' service model.

'ovsdb_datum_apply_diff' is allowed to fail, so adding support
to return this error.

Acked-by: Mark D. Gray <mark.d.gray@redhat.com>
Acked-by: Dumitru Ceara <dceara@redhat.com>
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
2021-07-15 22:37:46 +02:00
Ben Pfaff
3b3bad07f7 osvdb: Add some helpful comments.
Signed-off-by: Ben Pfaff <blp@ovn.org>
Acked-by: Justin Pettit <jpettit@ovn.org>
2018-12-03 12:57:48 -08:00
Rodriguez Betancourt, Esteban
aa1fc8017f ovsdb: Weak references performance fix
Prevents the cloning of rows with outgoing or incoming weak references when
those rows aren't being modified.

It improves the OVSDB Server performance when many rows with weak references
are involved in a transaction.

In the original code (dst_refs is created from scratch):

old->dst_refs = all the rows that weak referenced old

new->dst_refs = all the rows that weak referenced old and are still weak
+referencing new + rows in the transaction that weak referenced new

In the patch (dst_refs incrementally built):
Old->dst_refs = all the rows that weak referenced old

Ideally, but expansive to calculate:
New->dst_refs = old->dst_refs - "weak references removed within this TXN" +
+"weak references created within this TXN"

What this patch implements:
New->dst_refs = old->dst_refs - "weak references in old rows in TXN" + "weak
+references in new rows in TXN"

The resulting sets should be equal in both cases.

We do some more optimizations:

- If we know that the transactions must be successful at some point then,
  instead of cloning dst_refs we could just move the elements between
  the lists.

- At that point we lost the rollback feature, but we aren't going to need
  it anyway (note that we didn't really touch the src_refs part).

- The references in dst_refs must point to new instead than old.
  Previously we iterated over all the weak references in dst_refs
  to change that pointer, but using an UUID is easier, and prevents
  that iteration completely.

For some more commentary, see:
http://openvswitch.org/pipermail/dev/2016-July/074840.html

Signed-off-by: Esteban Rodriguez Betancourt <estebarb@hpe.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-07-26 10:44:08 -07:00
Terry Wilson
ee89ea7b47 json: Move from lib to include/openvswitch.
To easily allow both in- and out-of-tree building of the Python
wrapper for the OVS JSON parser (e.g. w/ pip), move json.h to
include/openvswitch. This also requires moving lib/{hmap,shash}.h.

Both hmap.h and shash.h were #include-ing "util.h" even though the
headers themselves did not use anything from there, but rather from
include/openvswitch/util.h. Fixing that required including util.h
in several C files mostly due to OVS_NOT_REACHED and things like
xmalloc.

Signed-off-by: Terry Wilson <twilson@redhat.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-07-22 17:09:17 -07:00
Ben Warren
b19bab5b20 list: Remove lib/list.h completely.
All code is now in include/openvswitch/list.h.

Signed-off-by: Ben Warren <ben@skyportsystems.com>
Acked-by: Ryan Moats <rmoats@us.ibm.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
2016-03-30 13:01:21 -07:00
Thomas Graf
ca6ba70092 list: Rename struct list to struct ovs_list
struct list is a common name and can't be used in public headers.

Signed-off-by: Thomas Graf <tgraf@noironetworks.com>
Acked-by: Ben Pfaff <blp@nicira.com>
2014-12-15 14:15:12 +01:00
Thomas Graf
cab5044987 lib: Move compiler.h to <openvswitch/compiler.h>
The following macros are renamed to avoid conflicts with other headers:
 * WARN_UNUSED_RESULT to OVS_WARN_UNUSED_RESULT
 * PRINTF_FORMAT to OVS_PRINTF_FORMAT
 * NO_RETURN to OVS_NO_RETURN

Signed-off-by: Thomas Graf <tgraf@noironetworks.com>
Acked-by: Ben Pfaff <blp@nicira.com>
2014-12-15 14:14:47 +01:00
Raju Subramanian
e0edde6fee Global replace of Nicira Networks.
Replaced all instances of Nicira Networks(, Inc) to Nicira, Inc.

Feature #10593
Signed-off-by: Raju Subramanian <rsubramanian@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
2012-05-02 17:08:02 -07:00
Ben Pfaff
6e492d8145 Rearrange structures to better fit valgrind's memory leak heuristics.
valgrind's memory leak detector considers a pointer to the head of a memory
block to be "definitely" a pointer to that memory block but a pointer to
the interior of a memory block only "possibly" a pointer to that memory
block.  Open vSwitch hmap_node and list data structures can go anywhere
inside a structure; if they are in the middle of a structure then valgrind
considers pointers to them to be possible leaks.  Therefore, this commit
moves some of these from the middle of data structures to the head, to
reduce valgrind's uncertainty.

Signed-off-by: Ben Pfaff <blp@nicira.com>
2012-03-28 14:55:27 -07:00
Ben Pfaff
6910a6e6f2 ovsdb: Implement table uniqueness constraints ("indexes"). 2011-06-06 09:09:10 -07:00
Ben Pfaff
25d4983554 ovsdb: Add functions for formatting column sets and data in columns sets.
These will be used for formatting error messages in an upcoming commit.
2011-06-06 09:02:01 -07:00
Ben Pfaff
7360012bdf ovsdb: Add support for weak references. 2010-03-17 14:24:56 -07:00
Ben Pfaff
fbf925e45d ovsdb: Get rid of "declare" operation.
It's more elegant, and just as easy to implement, if we allow a
"named-uuid" to be a forward reference to a "uuid-name" in a later
"insert" operation.
2010-02-08 16:03:21 -08:00
Ben Pfaff
0d0f05b909 ovsdb: Add support for referential integrity in the database itself. 2010-02-08 14:16:19 -08:00
Ben Pfaff
f85f8ebbfa Initial implementation of OVSDB. 2009-11-04 17:12:10 -08:00