diff mbox

[ovs-dev,RFC] ovsdb: Add aspirational documentation for clustering.

Message ID 20170218011028.18698-1-blp@ovn.org
State RFC
Headers show

Commit Message

Ben Pfaff Feb. 18, 2017, 1:10 a.m. UTC
I'm calling this "aspirational documentation" because it documents code
that is incompletely implemented and does not work yet.  I'd appreciate
feedback on the plan.  I suggest reading ovsdb.7.xml in particular, which
explains the overall design, goal, and use of OVSDB, with a lot of detail
on how clustering is meant to work from a user perspective.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 manpages.mk                  |  56 +---
 ovn/utilities/ovn-sbctl.8.in |  19 +-
 ovsdb/automake.mk            |   7 +-
 ovsdb/ovsdb-client.1.in      | 184 ++++++++---
 ovsdb/ovsdb-schemas.man      |  19 ++
 ovsdb/ovsdb-server.1.in      | 168 ++++++++--
 ovsdb/ovsdb-tool.1.in        | 186 +++++++----
 ovsdb/ovsdb.7.xml            | 725 +++++++++++++++++++++++++++++++++++++++++++
 ovsdb/remote-active.man      |  19 --
 ovsdb/remote-passive.man     |  26 --
 ovsdb/replication.man        |  23 --
 python/build/nroff.py        |  15 +-
 utilities/ovs-vsctl.8.in     |  21 +-
 vswitchd/ovs-vswitchd.8.in   |   7 +-
 vtep/vtep-ctl.8.in           |  23 +-
 15 files changed, 1204 insertions(+), 294 deletions(-)
 create mode 100644 ovsdb/ovsdb-schemas.man
 create mode 100644 ovsdb/ovsdb.7.xml
 delete mode 100644 ovsdb/remote-active.man
 delete mode 100644 ovsdb/remote-passive.man

Comments

Han Zhou Feb. 23, 2017, 8:02 p.m. UTC | #1
On Fri, Feb 17, 2017 at 5:10 PM, Ben Pfaff <blp@ovn.org> wrote:

> +  <p>
> +    Clusters larger than 5 servers will also work, with every 2 added
> +    servers allowing the cluster to tolerate 1 more failure, but
> +    performance decreases, especially write performance.

Should it be clear that read performance should never be impacted?
And is the performance drop supposed to be linear? If yes, then it might be
justified to add more nodes to satisfy super large deployments whenever
needed? Although I believe 5 nodes are good enough for most large
deployments :)

Thanks,
Han
Ben Pfaff Feb. 23, 2017, 8:21 p.m. UTC | #2
On Thu, Feb 23, 2017 at 12:02:04PM -0800, Han Zhou wrote:
> On Fri, Feb 17, 2017 at 5:10 PM, Ben Pfaff <blp@ovn.org> wrote:
> 
> > +  <p>
> > +    Clusters larger than 5 servers will also work, with every 2 added
> > +    servers allowing the cluster to tolerate 1 more failure, but
> > +    performance decreases, especially write performance.
> 
> Should it be clear that read performance should never be impacted?
> And is the performance drop supposed to be linear? If yes, then it might be
> justified to add more nodes to satisfy super large deployments whenever
> needed? Although I believe 5 nodes are good enough for most large
> deployments :)

It's a little early to speculate on the performance of the
implementation, since it isn't implemented yet, but I'll try to add more
about performance.

There's also some question about the ideal mix between clustering and
replication.
Han Zhou Feb. 23, 2017, 9:48 p.m. UTC | #3
On Thu, Feb 23, 2017 at 12:21 PM, Ben Pfaff <blp@ovn.org> wrote:
>
> On Thu, Feb 23, 2017 at 12:02:04PM -0800, Han Zhou wrote:
> > On Fri, Feb 17, 2017 at 5:10 PM, Ben Pfaff <blp@ovn.org> wrote:
> >
> > > +  <p>
> > > +    Clusters larger than 5 servers will also work, with every 2 added
> > > +    servers allowing the cluster to tolerate 1 more failure, but
> > > +    performance decreases, especially write performance.
> >
> > Should it be clear that read performance should never be impacted?
> > And is the performance drop supposed to be linear? If yes, then it
might be
> > justified to add more nodes to satisfy super large deployments whenever
> > needed? Although I believe 5 nodes are good enough for most large
> > deployments :)
>
> It's a little early to speculate on the performance of the
> implementation, since it isn't implemented yet, but I'll try to add more
> about performance.

Understood.

>
> There's also some question about the ideal mix between clustering and
> replication.

Combination of clustering and replication sounds good. So HVs can read from
a more flexible number of replications, and under circumstances where
occasional write is needed, HVs can use a separate channel to write to the
cluster. Is this a valid direction to take?
diff mbox

Patch

diff --git a/manpages.mk b/manpages.mk
index 742bd66..24fec7a 100644
--- a/manpages.mk
+++ b/manpages.mk
@@ -8,11 +8,7 @@  ovn/utilities/ovn-sbctl.8: \
 	lib/ssl-peer-ca-cert.man \
 	lib/ssl.man \
 	lib/table.man \
-	lib/vlog.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man \
-	ovsdb/remote-passive.man
+	lib/vlog.man
 ovn/utilities/ovn-sbctl.8.in:
 lib/common.man:
 lib/db-ctl-base.man:
@@ -21,10 +17,6 @@  lib/ssl-peer-ca-cert.man:
 lib/ssl.man:
 lib/table.man:
 lib/vlog.man:
-ovsdb/remote-active.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
-ovsdb/remote-passive.man:
 
 ovsdb/ovsdb-client.1: \
 	ovsdb/ovsdb-client.1.in \
@@ -41,8 +33,7 @@  ovsdb/ovsdb-client.1: \
 	lib/table.man \
 	lib/vlog-syn.man \
 	lib/vlog.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man
+	ovsdb/ovsdb-schemas.man
 ovsdb/ovsdb-client.1.in:
 lib/common-syn.man:
 lib/common.man:
@@ -57,8 +48,7 @@  lib/ssl.man:
 lib/table.man:
 lib/vlog-syn.man:
 lib/vlog.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
+ovsdb/ovsdb-schemas.man:
 
 ovsdb/ovsdb-server.1: \
 	ovsdb/ovsdb-server.1.in \
@@ -82,11 +72,7 @@  ovsdb/ovsdb-server.1: \
 	lib/unixctl.man \
 	lib/vlog-syn.man \
 	lib/vlog-unixctl.man \
-	lib/vlog.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man \
-	ovsdb/replication-syn.man \
-	ovsdb/replication.man
+	lib/vlog.man
 ovsdb/ovsdb-server.1.in:
 lib/common-syn.man:
 lib/common.man:
@@ -109,22 +95,20 @@  lib/unixctl.man:
 lib/vlog-syn.man:
 lib/vlog-unixctl.man:
 lib/vlog.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
-ovsdb/replication-syn.man:
-ovsdb/replication.man:
 
 ovsdb/ovsdb-tool.1: \
 	ovsdb/ovsdb-tool.1.in \
 	lib/common-syn.man \
 	lib/common.man \
 	lib/vlog-syn.man \
-	lib/vlog.man
+	lib/vlog.man \
+	ovsdb/ovsdb-schemas.man
 ovsdb/ovsdb-tool.1.in:
 lib/common-syn.man:
 lib/common.man:
 lib/vlog-syn.man:
 lib/vlog.man:
+ovsdb/ovsdb-schemas.man:
 
 utilities/bugtool/ovs-bugtool.8: \
 	utilities/bugtool/ovs-bugtool.8.in
@@ -264,11 +248,7 @@  utilities/ovs-vsctl.8: \
 	lib/table.man \
 	lib/vconn-active.man \
 	lib/vconn-passive.man \
-	lib/vlog.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man \
-	ovsdb/remote-passive.man
+	lib/vlog.man
 utilities/ovs-vsctl.8.in:
 lib/common.man:
 lib/db-ctl-base.man:
@@ -279,10 +259,6 @@  lib/table.man:
 lib/vconn-active.man:
 lib/vconn-passive.man:
 lib/vlog.man:
-ovsdb/remote-active.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
-ovsdb/remote-passive.man:
 
 vswitchd/ovs-vswitchd.8: \
 	vswitchd/ovs-vswitchd.8.in \
@@ -299,9 +275,7 @@  vswitchd/ovs-vswitchd.8: \
 	lib/vlog.man \
 	ofproto/ofproto-dpif-unixctl.man \
 	ofproto/ofproto-tnl-unixctl.man \
-	ofproto/ofproto-unixctl.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man
+	ofproto/ofproto-unixctl.man
 vswitchd/ovs-vswitchd.8.in:
 lib/common.man:
 lib/coverage-unixctl.man:
@@ -317,8 +291,6 @@  lib/vlog.man:
 ofproto/ofproto-dpif-unixctl.man:
 ofproto/ofproto-tnl-unixctl.man:
 ofproto/ofproto-unixctl.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
 
 vtep/vtep-ctl.8: \
 	vtep/vtep-ctl.8.in \
@@ -328,11 +300,7 @@  vtep/vtep-ctl.8: \
 	lib/ssl-peer-ca-cert.man \
 	lib/ssl.man \
 	lib/table.man \
-	lib/vlog.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man \
-	ovsdb/remote-passive.man
+	lib/vlog.man
 vtep/vtep-ctl.8.in:
 lib/common.man:
 lib/db-ctl-base.man:
@@ -341,7 +309,3 @@  lib/ssl-peer-ca-cert.man:
 lib/ssl.man:
 lib/table.man:
 lib/vlog.man:
-ovsdb/remote-active.man:
-ovsdb/remote-active.man:
-ovsdb/remote-passive.man:
-ovsdb/remote-passive.man:
diff --git a/ovn/utilities/ovn-sbctl.8.in b/ovn/utilities/ovn-sbctl.8.in
index a87635d..7b29b84 100644
--- a/ovn/utilities/ovn-sbctl.8.in
+++ b/ovn/utilities/ovn-sbctl.8.in
@@ -58,11 +58,8 @@  Otherwise, the default is \fBunix:@RUNDIR@/db.sock\fR, but this
 default is unlikely to be useful outside of single-machine OVN test
 environments.
 .IP
-\fIserver\fR must take one of the following forms:
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
+\fIserver\fR may be an OVSDB active or passive connection method,
+e.g. \fBssl:192.168.10.5:6640\fR, as described in \fBovsdb\fR(7).
 .
 .IP "\fB\-\-no\-syslog\fR"
 By default, \fBovn\-sbctl\fR logs its arguments and the details of any
@@ -197,14 +194,10 @@  Deletes the configured connection(s).
 .
 .IP "\fBset\-connection\fR [\fIaccess\-specifier\fR] \fItarget\fR\&..."
 Sets the configured manager target or targets.  Each \fItarget\fR may
-be preceded by an optional access-specifier (\fBread\-only\fR or
-\fBread\-write\fR) and may use any of the following forms:
-.
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
-
+may be an OVSDB active or passive connection method,
+e.g. \fBpssl:6640\fR, as described in \fBovsdb\fR(7),
+optionally preceded by an optional access-specifier (\fBread\-only\fR or
+\fBread\-write\fR).
 If provided, the effect of the access specifier persists for subsequent
 targets until changed by another access specifier.
 .
diff --git a/ovsdb/automake.mk b/ovsdb/automake.mk
index 33d04f8..e4edaa6 100644
--- a/ovsdb/automake.mk
+++ b/ovsdb/automake.mk
@@ -1,3 +1,7 @@ 
+# overview
+man_MANS += ovsdb/ovsdb.7
+EXTRA_DIST += ovsdb/ovsdb.7.xml
+
 # libovsdb
 lib_LTLIBRARIES += ovsdb/libovsdb.la
 ovsdb_libovsdb_la_LDFLAGS = \
@@ -43,8 +47,7 @@  pkgconfig_DATA += \
 	ovsdb/libovsdb.pc
 
 MAN_FRAGMENTS += \
-	ovsdb/remote-active.man \
-	ovsdb/remote-passive.man \
+	ovsdb/ovsdb-schemas.man \
 	ovsdb/replication.man \
 	ovsdb/replication-syn.man
 
diff --git a/ovsdb/ovsdb-client.1.in b/ovsdb/ovsdb-client.1.in
index 9658291..fd59524 100644
--- a/ovsdb/ovsdb-client.1.in
+++ b/ovsdb/ovsdb-client.1.in
@@ -13,21 +13,34 @@ 
 ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
 .
 .SH SYNOPSIS
+.IP "Server-Level Commands:"
 \fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-dbs \fR[\fIserver\fR]
-.br
+.IP "Database Schema Commands:"
 \fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema \fR[\fIserver\fR] \fR[\fIdatabase\fR]
 .br
-\fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema\-version\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]
-.br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-tables\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBlist\-columns\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] [\fItable\fR]
+.IP "Database Version Management Commands:"
+\fBovsdb\-client \fR[\fIoptions\fR] \fBconvert \fR[\fIserver\fR] \fIschema\fR
+.br
+\fBovsdb\-client \fR[\fIoptions\fR] \fBneeds\-conversion \fR[\fIserver\fR] \fIschema\fR
+.br
+\fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema\-version\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]
 .br
+\fBovsdb\-client \fR[\fIoptions\fR] \fBget\-schema\-cksum\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]
+.IP "Data Management Commands:"
 \fBovsdb\-client \fR[\fIoptions\fR] \fBtransact\fI \fR[\fIserver\fR] \fItransaction\fR
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBdump\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]\fR [\fItable\fR
 [\fIcolumn\fR...]]
 .br
+\fBovsdb\-client \fR[\fIoptions\fR]
+\fBbackup\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] > \fIsnapshot\fR
+.br
+\fBovsdb\-client \fR[\fIoptions\fR]
+\fBrestore\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] < \fIsnapshot\fR
+.br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fItable\fR
 [\fIcolumn\fR[\fB,\fIcolumn\fR]...]...
 .br
@@ -35,13 +48,14 @@  ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBmonitor-cond\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fIconditions
 \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]...
-.br
+.IP "Testing Commands:"
 \fBovsdb\-client \fR[\fIoptions\fR] \fBlock\fI \fR[\fIserver\fR] \fIlock\fR
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBsteal\fI \fR[\fIserver\fR] \fIlock\fR
 .br
 \fBovsdb\-client \fR[\fIoptions\fR] \fBunlock\fI \fR[\fIserver\fR] \fIlock\fR
 .br
+.IP "Other Commands:"
 \fBovsdb\-client help\fR
 .IP "Output formatting options:"
 [\fB\-\-format=\fIformat\fR]
@@ -61,40 +75,35 @@  ovsdb\-client \- command-line interface to \fBovsdb-server\fR(1)
 .SH DESCRIPTION
 The \fBovsdb\-client\fR program is a command-line client for
 interacting with a running \fBovsdb\-server\fR process.
-Each command connects to an OVSDB server, which is
-\fBunix:@RUNDIR@/db.sock\fR by default, or may be specified as
-\fIserver\fR in one of the following forms:
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
+Each command connects to the specified OVSDB \fIserver\fR, which may
+be an OVSDB active or passive connection method, as described in
+\fBovsdb\fR(7).  The default server is \fBunix:@RUNDIR@/db.sock\fR
+and
+the default \fIdatabase\fR is \fBOpen_vSwitch\fR.
+.PP
+For an introduction to OVSDB and its implementation in Open vSwitch,
+see \fBovsdb\fR(7).
 .PP
-The default \fIdatabase\fR is \fBOpen_vSwitch\fR.
+The following sections describe the commands that \fBovsdb\-client\fR
+supports.
+.SS "Server-Level Commands"
+Most \fBovsdb\-client\fR commands work with an individual database,
+but these commands apply to an entire database server.
 .
-.SS "Commands"
-The following commands are implemented:
 .IP "\fBlist\-dbs \fR[\fIserver\fR]"
 Connects to \fIserver\fR, retrieves the list of known databases, and
-prints them one per line.  These database names are the ones that may
-be used for \fIdatabase\fR in the following commands.
+prints them one per line.  These database names are the ones that
+other commands may use for \fIdatabase\fR.
+.
+.SS "Database Schema Commands"
+.PP
+These commands obtain the schema from a database and print it or part
+of it.
 .
 .IP "\fBget\-schema \fR[\fIserver\fR] \fR[\fIdatabase\fR]"
 Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
 prints it in JSON format.
 .
-.IP "\fBget\-schema\-version\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]"
-Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
-prints its version number on stdout.  A schema version number has the form
-\fIx\fB.\fIy\fB.\fIz\fR.  See \fBovs\-vswitchd.conf.db\fR(5) for
-details.
-.IP
-Schema version numbers and Open vSwitch version numbers are
-independent.
-.IP
-If \fIdatabase\fR was created before schema versioning was introduced,
-then it will not have a version number and this command will print a
-blank line.
-.
 .IP "\fBlist\-tables\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]"
 Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
 prints a table listing the name of each table
@@ -106,10 +115,77 @@  prints a table listing the name and type of each
 column.  If \fItable\fR is specified, only columns in that table are
 listed; otherwise, the tables include columns in all tables.
 .
+.SS "Database Version Management Commands"
+.so ovsdb/ovsdb-schemas.man
+.PP
+These commands work with different versions of OVSDB schemas and
+databases.
+.
+.IP "\fBconvert \fR[\fIserver\fR] \fIschema\fR"
+Reads an OVSDB schema in JSON format, as specified in the OVSDB
+specification, from \fIschema\fR, then connects to \fIserver\fR and
+requests the server to convert the database whose name is specified in
+\fIschema\fR to the schema also specified in \fIschema\fR.
+.IP
+The conversion is atomic, consistent, isolated, and durable.  The
+OVSDB protocol does not provide a way for the server to notify a
+client that a database's schema has changed, so currently
+\fBovsdb\-server\fR disconnects any clients connected when the
+conversion takes place.  Upon reconnction, clients will discover that
+the schema has changed.
+.IP
+This command can do simple ``upgrades'' and ``downgrades'' on a
+database's schema.  The data in the database must be valid when
+interpreted under \fIschema\fR, with only one exception: data for
+tables and columns that do not exist in \fIschema\fR are ignored.
+Columns that exist in \fIschema\fR but not in the database are set to
+their default values.  All of \fIschema\fR's constraints apply in
+full.
+.IP
+Some uses of this command can cause unrecoverable data loss.  For
+example, converting a database from a schema that has a given column
+or table to one that does not will delete all data in that column or
+table.  Back up critical databases before converting them.
+.IP
+This command works with clustered and standalone databases.
+Standalone databases may also be converted with \fBovsdb\-tool\fR's
+\fBconvert\fR command.
+.
+.IP "\fBneeds\-conversion \fR[\fIserver\fR] \fIschema\fR"
+Reads the schema from \fIschema\fR, then connects to \fIserver\fR and
+requests the schema from the database whose name is specified in
+\fIschema\fR.  If the two schemas are the same, prints \fBno\fR on
+stdout; if they differ, prints \fByes\fR.
+.
+.IP "\fBget\-schema\-version\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints its version number on stdout.
+If \fIdatabase\fR was created before schema versioning was introduced,
+then it will not have a version number and this command will print a
+blank line.
+.
+.IP "\fBget\-schema\-cksum\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]"
+Connects to \fIserver\fR, retrieves the schema for \fIdatabase\fR, and
+prints its checksum on stdout.  If \fIdatabase\fR does not include a
+checksum, prints a blank line.
+.
+.SS "Data Management Commands"
+.PP
+These commands read or modify the data in a database.
+.
 .IP "\fBtransact\fI \fR[\fIserver\fR] \fItransaction\fR"
 Connects to \fIserver\fR, sends it the specified \fItransaction\fR,
-which must be a JSON array containing one or more valid OVSDB
-operations, and prints the received reply on stdout.
+which must be a JSON array appropriate for use as the \fBparams\fR to
+a JSON-RPC \fBtransact\fR request, and prints the received reply on
+stdout.
+.
+.IP "\fBquery\fI \fR[\fIserver\fR] \fItransaction\fR"
+Connects to \fIserver\fR, sends it the specified \fItransaction\fR,
+which must be a JSON array appropriate for use as the \fBparams\fR to
+a JSON-RPC \fBtransact\fR request, and prints the received reply on
+stdout.  To ensure that the transaction does not modify the database,
+this command appends an \fBabort\fR operation to the set of operations
+included in \fItransaction\fR before sending it to the database.
 .
 .IP "\fBdump\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR]\fR [\fItable \fR[\fIcolumn\fR...]]"
 Connects to \fIserver\fR, retrieves all of the data in \fIdatabase\fR,
@@ -117,6 +193,38 @@  and prints it on stdout as a series of tables. If \fItable\fR is
 specified, only that table is retrieved.  If at least one \fIcolumn\fR
 is specified, only those columns are retrieved.
 .
+.IP "\fBbackup\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] > \fIsnapshot\fR"
+Connects to \fIserver\fR, retrieves a snapshot of the schema and data
+in \fIdatabase\fR, and prints it on stdout in the format used for
+OVSDB standalone and active-backup database.  This is an appropriate
+way to back up a remote database.  The database snapshot that it
+outputs is suitable to be served up directly by \fBovsdb\-server\fR or
+used as the input to \fBovsdb\-client restore\fR.
+.IP
+Another way to back up a standalone or active-backup database is to
+copy its database file, e.g. with \fBcp\fR.  This is safe even if the
+database is in use.
+.IP
+The output does not include ephemeral columns, which by design do not
+survive across restarts of \fBovsdb\-server\fR.
+.
+.IP "\fBrestore\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] < \fIsnapshot\fR"
+Reads \fIsnapshot\fR, which must be in the format used for OVSDB
+standalone and active-backup databases.  Then, connects to
+\fIserver\fR, verifies that \fIdatabase\fR and \fIsnapshot\fR have the
+same schema, then deletes all of the data in \fIdatabase\fR and
+replaces it by \fIsnapshot\fR.  The replacement happens atomically, in a
+single transaction.
+.IP
+UUIDs for rows in the restored database will differ from those in
+\fIsnapshot\fR, because the OVSDB protocol does not allow clients to
+specify row UUIDs.  Another way to restore a standalone or
+active-backup database, which does also restore row UUIDs, is to stop
+the server or servers, replace the database file by the snapshot, then
+restart the database.  Either way, ephemeral columns are not restored,
+since by design they do not survive across restarts of
+\fBovsdb\-server\fR.
+.
 .IP "\fBmonitor\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]..."
 .IQ "\fBmonitor-cond\fI \fR[\fIserver\fR] \fR[\fIdatabase\fR] \fIconditions\fR \fItable\fR [\fIcolumn\fR[\fB,\fIcolumn\fR]...]..."
 Connects to \fIserver\fR and monitors the contents of rows that match conditions in
@@ -162,13 +270,13 @@  prints the initial database contents.
 The \fBmonitor\fR command uses RFC 7047 "monitor" method to open a monitor
 session with the server.
 .
-.SH TESTING COMMANDS
-The following commands are mostly of interest for testing the correctness
+.SS "Testing commands"
+These commands are mostly of interest for testing the correctness
 of the OVSDB server.
 .
-.IP "\fBovsdb\-client\fR [\fIoptions\fR] \fBlock\fI \fR[\fIserver\fR] \fIlock\fR"
-.IQ "\fBovsdb\-client\fR [\fIoptions\fR] \fBsteal\fI \fR[\fIserver\fR] \fIlock\fR"
-.IQ "\fBovsdb\-client\fR [\fIoptions\fR] \fBunlock\fI \fR[\fIserver\fR] \fIlock\fR"
+.IP "\fBlock\fI \fR[\fIserver\fR] \fIlock\fR"
+.IQ "\fBsteal\fI \fR[\fIserver\fR] \fIlock\fR"
+.IQ "\fBunlock\fI \fR[\fIserver\fR] \fIlock\fR"
 Connects to \fIserver\fR and issues corresponding RFC 7047 lock operations
 on \fIlock\fR. Prints json reply or subsequent update messages.
 The \fB\-\-detach\fR option causes \fBovsdb\-client\fR to detach after it
@@ -212,6 +320,6 @@  With any other command, they have no effect.
 .so lib/common.man
 .SH "SEE ALSO"
 .
+\fBovsdb\fR(7),
 \fBovsdb\-server\fR(1),
-\fBovsdb\-client\fR(1),
-and the OVSDB specification.
+\fBovsdb\-client\fR(1).
diff --git a/ovsdb/ovsdb-schemas.man b/ovsdb/ovsdb-schemas.man
new file mode 100644
index 0000000..3630d5d
--- /dev/null
+++ b/ovsdb/ovsdb-schemas.man
@@ -0,0 +1,19 @@ 
+.PP
+An OVSDB schema has a schema version number, and an OVSDB database
+embeds a particular version of an OVSDB schema.  These version numbers
+take the form \fIx\fB.\fIy\fB.\fIz\fR, e.g. \fB1.2.3\fR.  The OVSDB
+implementation does not enforce a particular version numbering scheme,
+but schemas managed within the Open vSwitch project use the following
+approach.  Whenever the database schema is changed in a non-backward
+compatible way (e.g. deleting a column or a table), \fIx\fR is
+incremented (and \fIy\fR and \fIz\fR are reset to 0).  When the
+database schema is changed in a backward compatible way (e.g. adding a
+new column), \fIy\fR is incremented (and \fIz\fR is reset to 0).  When
+the database schema is changed cosmetically (e.g. reindenting its
+syntax), \fIz\fR is incremented.
+.PP
+Some OVSDB databases and schemas, especially very old ones, do not
+have a version number.
+.PP
+Schema version numbers and Open vSwitch version numbers are
+independent.
diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in
index 3c798dd..732df7d 100644
--- a/ovsdb/ovsdb-server.1.in
+++ b/ovsdb/ovsdb-server.1.in
@@ -19,7 +19,10 @@  ovsdb\-server \- Open vSwitch database server
 .so lib/daemon-syn.man
 .so lib/service-syn.man
 .so lib/vlog-syn.man
-.so ovsdb/replication-syn.man
+.IP "Active-backup options:"
+[\fB\-\-sync\-from=\fIserver\fR]
+[\fB\-\-sync\-exclude-tables=\fIdb\fB:\fItable\fR[\fB,\fIdb\fB:\fItable\fR]...\fR]
+[\fB\-\-active\fR] 
 .so lib/ssl-syn.man
 .so lib/ssl-bootstrap-syn.man
 .so lib/ssl-peer-ca-cert-syn.man
@@ -31,39 +34,26 @@  ovsdb\-server \- Open vSwitch database server
 The \fBovsdb\-server\fR program provides RPC interfaces to one or more
 Open vSwitch databases (OVSDBs).  It supports JSON-RPC client
 connections over active or passive TCP/IP or Unix domain sockets.
+For an introduction to OVSDB and its implementation in Open vSwitch,
+see \fBovsdb\fR(7).
 .PP
 Each OVSDB file may be specified on the command line as \fIdatabase\fR.
 If none is specified, the default is \fB@DBDIR@/conf.db\fR.  The database
 files must already have been created and initialized using, for
 example, \fBovsdb\-tool create\fR.
-.
-.SH "ACTIVE and BACKUP"
-\fBovsdb\-server\fR runs either as a backup server, or as an active server.
-When  \fBovsdb\-server\fR is running as a backup server, all transactions that
-can modify the database content, including the lock commands are rejected.
-Active server, on the other hand, accepts all ovsdb server transactions.
-When \fBovsdb\-server\fR role changes, all existing client connection are
-reset, requiring clients to reconnect to the server.
-.PP
-By default, \fBovsdb\-server\fR runs as an active server, except when the
-\fB\-\-sync\-from=\fIserver\fR command line option is specified and without
-the \fB\-\-no\-sync option\fR.  During runtime, \fBovsdb\-server\fR role can be switch by using appctl commands.
 .PP
-\fBovsdb-server/connect\-active\-ovsdb\-server\fR switches
-\fBovsdb\-server\fR into a backup server, Conversely,
-\fBovsdb-server/disconnect\-active\-ovsdb\-server\fR switches server into
-an active one.
-.
+This OVSDB implementation supports standalone, active-backup, and
+clustered database service models, as well as database replication.
+See the Service Models section of \fBovsdb\fR(7) for more information.
 .SH OPTIONS
 .
 .IP "\fB\-\-remote=\fIremote\fR"
 Adds \fIremote\fR as a connection method used by \fBovsdb\-server\fR.
-\fIremote\fR must take one of the following forms:
+The \fIremote\fR may be an OVSDB active or passive connection method,
+e.g. \fBpssl:6640\fR, as described in \fBovsdb\fR(7).  The following
+additional form is also supported:
 .
 .RS
-.so ovsdb/remote-passive.man
-.so ovsdb/remote-active.man
-.
 .IP "\fBdb:\fIdb\fB,\fItable\fB,\fIcolumn\fR"
 Reads additional connection methods from \fIcolumn\fR in all of the
 rows in \fItable\fR within \fIdb\fR.  As the contents of \fIcolumn\fR changes,
@@ -121,8 +111,52 @@  configured remotes.
 .so lib/service.man
 .SS "Logging Options"
 .so lib/vlog.man
-.SS "Syncing Options"
-.so ovsdb/replication.man
+.SS "Active-Backup Options"
+These options support the \fBovsdb\-server\fR active-backup service
+model and database replication.  These options apply only to databases
+in the format used for standalone and active-backup databases, which
+is the database format created by \fBovsdb\-tool create\fR.  By
+default, when it serves a database in this format, \fBovsdb\-server\fR
+runs as a standalone server.  These options can configure it for
+active-backup use:
+.IP \(bu
+Use \fB\-\-sync\-from=\fIserver\fR to start the server in the backup
+role, replicating data from \fIserver\fR.  When \fBovsdb\-server\fR is
+running as a backup server, it rejects all transactions that can
+modify the database content, including lock commands.  The same form
+can be used to configure the local database as a replica of
+\fIserver\fR.
+.IP \(bu
+Use \fB\-\-sync\-from=\fIserver\fB \-\-active\fR to start the server
+in the active role, but prepared to switch to the backup role in which
+it would replicate data from \fIserver\fR.  When \fBovsdb\-server\fR
+runs in active mode, it allows all transactions, including those that
+modify the database.
+.PP
+At runtime, management commands can change a server's role and otherwise
+manage active-backup features.  See \fBActive-Backup Commands\fR, below,
+for more information.
+.TP
+\fB\-\-sync\-from=\fIserver\fR
+Sets up \fBovsdb\-server\fR to synchronize its databases with the
+databases in \fIserver\fR, which must be an active connection method
+in one of the forms documented in \fBovsdb\-client\fR(1).  Every
+transaction committed by \fIserver\fR will be replicated to
+\fBovsdb\-server\fR.  This option makes \fBovsdb\-server\fR start
+as a backup server; add \fB\-\-active\fR to make it start as an
+active server.
+.TP
+\fB\-\-sync\-exclude-tables=\fIdb\fB:\fItable\fR[\fB,\fIdb\fB:\fItable\fR]...\fR
+Causes the specified tables to be excluded from replication.
+.TP
+\fB\-\-active\fR
+By default, \fB\-\-sync\-from\fR makes \fBovsdb\-server\fR start up as
+a backup for \fIserver\fR.  With \fB\-\-active\fR, however,
+\fBovsdb\-server\fR starts as an active server.  Use this option to
+allow the syncing options to be specified using command line options,
+yet start the server, as the default, active server.  To switch the
+running server to backup mode, use \fBovs-appctl(1)\fR to execute the
+\fBovsdb\-server/connect\-active\-ovsdb\-server\fR command.
 .SS "Public Key Infrastructure Options"
 The options described below for configuring the SSL public key
 infrastructure accept a special syntax for obtaining their
@@ -145,7 +179,7 @@  one row in \fItable\fR.)
 \fBovs\-appctl\fR(8) can send commands to a running
 \fBovsdb\-server\fR process.  The currently supported commands are
 described below.
-.SS "OVSDB\-SERVER COMMANDS"
+.SS "\fBovsdb\-server\fR Commands"
 These commands are specific to \fBovsdb\-server\fR.
 .IP "\fBexit\fR"
 Causes \fBovsdb\-server\fR to gracefully terminate.
@@ -210,23 +244,37 @@  again (with \fBovsdb\-server/add\-db\fR).
 Outputs a list of the currently configured databases added either through
 the command line or through the \fBovsdb\-server/add\-db\fR command.
 .
+.SS "Active-Backup Commands"
+.PP
+These commands query and update the role of \fBovsdb\-server\fR within
+an active-backup pair of servers.  See \fBActive-Backup Options\fR,
+above, and \fBActive-Backup Database Service Model\fR in
+\fBovsdb\fR(7) for more information.
+.
 .IP "\fBovsdb\-server/set\-active\-ovsdb\-server \fIserver"
 Sets  the active \fIserver\fR from which \fBovsdb\-server\fR connects through
 \fBovsdb\-server/connect\-active\-ovsdb\-server\fR.
+This overrides the \fB\-\-sync\-from\fR command-line option.
 .
 .IP "\fBovsdb\-server/get\-active\-ovsdb\-server"
 Gets the active server from which \fBovsdb\-server\fR is currently synchronizing
 its databases.
 .
 .IP "\fBovsdb\-server/connect\-active\-ovsdb\-server"
-Causes \fBovsdb\-server\fR to synchronize its databases with the server
-specified by \fBovsdb\-server/set\-active\-ovsdb\-server\fR.
+Switches the server to a backup role.  The server starts synchronizing
+its databases with the active server specified by
+\fBovsdb\-server/set\-active\-ovsdb\-server\fR (or the
+\fB\-\-sync\-from\fR command-line option) and closes all existing
+client connections, which requires clients to reconnect.
 .
 .IP "\fBovsdb\-server/disconnect\-active\-ovsdb\-server"
-Causes \fBovsdb\-server\fR to  stop  synchronizing  its  databases with a active server.
+Switches the server to an active role.  The server stops synchronizing
+its databases with an active server and closes all existing client
+connections, which requires clients to reconnect.
 .
 .IP "\fBovsdb\-server/set\-sync\-exclude\-tables \fIdb\fB:\fItable\fR[\fB,\fIdb\fB:\fItable\fR]..."
-Sets the \fItable\fR whitin \fIdb\fR that will be excluded from synchronization.
+Sets the \fItable\fR within \fIdb\fR that will be excluded from synchronization.
+This overrides the \fB\-\-sync\-exclude-tables\fR command-line option.
 .
 .IP "\fBovsdb\-server/get\-sync\-exclude\-tables"
 Gets  the  tables  that are currently excluded from synchronization.
@@ -241,6 +289,64 @@  When the connection is in \fIreplicating\fR state, further output shows
 the list of databases currently replicating, and the tables that are
 excluded.
 .
+.SS "Cluster Commands"
+These commands support the \fBovsdb\-server\fR clustered service model.
+They apply only to databases in the format used for clustered databases,
+which is the database format created by \fBovsdb\-tool create\-cluster\fR
+and \fBovsdb\-tool join\-cluster\fR.
+.
+.IP "\fBcluster/cid \fIdb\fR"
+Prints the cluster ID for \fIdb\fR, which is a UUID that identifies
+the cluster.  If \fIdb\fR is a database newly created by
+\fBovsdb\-tool cluster\-join\fR, that has not yet successfully joined
+its cluster, and \fB\-\-cid\fR was not specified on the
+\fBcluster\-join\fR command line, then this command will report an
+error because the cluster ID is not yet known.
+.
+.IP "\fBcluster/sid \fIdb\fR"
+Prints the server ID for \fIdb\fR, which is a UUID that identifies
+this server within the cluster.
+.
+.IP "\fBcluster/status \fIdb\fR"
+Prints this server's status within the cluster and the status of its
+connections to other servers in the cluster.
+.
+.IP "\fBcluster/leave \fR[\fB\-\-force\fR] \fIdb\fR"
+Causes this server to remove itself from the cluster that contains
+\fIdb\fR.
+.IP
+Without \fB\-\-force\fR, this command implements a graceful removal
+that succeeds only if the cluster contains at least two servers and it
+is healthy, that is, over half its servers are up.  This command waits
+for leaving the cluster to succeed or fail.  If it is successful, the
+response is empty; if it fails, it outputs an error message.  Given
+server failures, leaving a cluster takes an unbounded amount of time,
+so it is a good idea to use \fBovs\-appctl\fR's \fB\-\-timeout\fR
+option to limit its runtime.  When a timeout occurs, leaving the
+cluster may ultimately succeed.
+.IP
+With \fB\-\-force\fR, this command forces the server to leave its
+cluster and form a new single-node cluster that contains only itself.
+The data in the new cluster may be inconsistent with the former
+cluster: transactions not yet replicated to the server will be lost,
+and transactions not yet applied to the cluster may be committed.
+Afterward, any servers in its former cluster will regard the server to
+have failed.
+.IP
+When the server successfully leaves the cluster, it stops serving
+\fIdb\fR, as if \fBovsdb\-server/remove\-db \fIdb\fR had been
+executed.
+.
+.IP "\fBcluster/kick \fIdb server\fR"
+Gracefully removes \fIserver\fR from \fIdb\fR's cluster, like
+\fBcluster/leave\fR (without \fB\-\-force\fR) except that it can
+remove any server, not just this one.
+.IP
+\fIserver\fR may be a server ID, as printed by \fBcluster/sid\fR, or
+the server's local network address as passed to \fBovsdb-tool\fR's
+\fBcreate\-cluster\fR or \fBjoin\-cluster\fR command.  Use
+\fBcluster/status\fR to see a list of cluster members.
+.
 .so lib/vlog-unixctl.man
 .so lib/memory-unixctl.man
 .so lib/coverage-unixctl.man
@@ -650,5 +756,5 @@  treat a \fBmonitor\fR response with a \fBresult\fR that contains an
 being monitored does not contain a table named \fBerror\fR).
 .
 .SH "SEE ALSO"
-.
-.BR ovsdb\-tool (1).
+\fBovsdb\fR(7),
+\fBovsdb\-tool\fR(1).
diff --git a/ovsdb/ovsdb-tool.1.in b/ovsdb/ovsdb-tool.1.in
index d01531e..39116f5 100644
--- a/ovsdb/ovsdb-tool.1.in
+++ b/ovsdb/ovsdb-tool.1.in
@@ -12,10 +12,11 @@ 
 ovsdb\-tool \- Open vSwitch database management utility
 .
 .SH SYNOPSIS
+.IP "Database Creation Commands:"
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBcreate \fR[\fIdb\fR [\fIschema\fR]]
 .br
-\fBovsdb\-tool \fR[\fIoptions\fR] \fBcompact \fR[\fIdb\fR [\fItarget\fR]]
-.br
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBcreate\-cluster \fIdb schema address\fR
+.IP "Version Management Commands:"
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBconvert \fR[\fIdb\fR [\fIschema
 \fR[\fItarget\fR]]]
 .br
@@ -28,6 +29,8 @@  ovsdb\-tool \- Open vSwitch database management utility
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBdb\-cksum \fR[\fIdb\fR]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBschema\-cksum \fR[\fIschema\fR]
+.IP "Other commands:"
+\fBovsdb\-tool \fR[\fIoptions\fR] \fBcompact \fR[\fIdb\fR [\fItarget\fR]]
 .br
 \fBovsdb\-tool \fR[\fIoptions\fR] \fBquery \fR[\fIdb\fR] \fItransaction\fR
 .br
@@ -44,43 +47,85 @@  The \fBovsdb\-tool\fR program is a command-line tool for managing Open
 vSwitch database (OVSDB) files.  It does not interact directly with
 running Open vSwitch database servers (instead, use
 \fBovsdb\-client\fR).
+For an introduction to OVSDB and its implementation in Open vSwitch,
+see \fBovsdb\fR(7).
+.PP
+This OVSDB implementation supports standalone and active-backup
+database service models with one on-disk format and a clustered
+database service model with a different format.  \fBovsdb\-tool\fR
+supports both formats, but some commands are appropriate for only one
+format, as documented for individual commands below.  For more
+information on OVSDB service models, see the \fBService Models\fR
+section in \fBovsdb\fR(7).
 .
-.SS "Basic Commands"
-.IP "\fBcreate\fI db schema\fR"
-Reads an OVSDB schema from the file named \fIschema\fR and creates a
-new OVSDB database file named \fIdb\fR using that schema.  The new
-database is initially empty.  This command will not overwrite an
-existing \fIdb\fR.
-.IP
-\fIschema\fR must contain an OVSDB schema in JSON format.  Refer to
-the OVSDB specification for details.
+.SS "Database Creation Commands"
+These commands read an OVSDB schema in JSON format, as specified in
+the OVSDB specification, from a schema file and create a new OVSDB
+database file using that schema.  The new database is initially empty.
+.PP
+These commands will not overwrite an existing database file.  To
+replace an existing database with a new one, first delete the old one.
 .
-.IP "\fBcompact\fI db \fR[\fItarget\fR]"
-Reads \fIdb\fR and writes a compacted version.  If \fItarget\fR is
-specified, the compacted version is written as a new file named
-\fItarget\fR, which must not already exist.  If \fItarget\fR is
-omitted, then the compacted version of the database replaces \fIdb\fR
-in-place.
+.IP "\fBcreate\fI db schema\fR"
+Use this command to create the database for controlling
+\fBovs\-vswitchd\fR or another standalone or active-backup database.
+It creates database file \fIdb\fR with the given \fIschema\fR.
 .
-.SS "Version Management Commands"
-.PP
-An OVSDB schema has a schema version number, and an OVSDB database
-embeds a particular version of an OVSDB schema.  These version numbers
-take the form \fIx\fB.\fIy\fB.\fIz\fR, e.g. \fB1.2.3\fR.  The OVSDB
-implementation does not enforce a particular version numbering scheme,
-but schemas managed within the Open vSwitch project use the following
-approach.  Whenever the database schema is changed in a non-backward
-compatible way (e.g. deleting a column or a table), \fIx\fR is
-incremented (and \fIy\fR and \fIz\fR are reset to 0).  When the
-database schema is changed in a backward compatible way (e.g. adding a
-new column), \fIy\fR is incremented (and \fIz\fR is reset to 0).  When
-the database schema is changed cosmetically (e.g. reindenting its
-syntax), \fIz\fR is incremented.
+.IP "\fBcreate\-cluster\fI db schema local"
+Use this command to initialize the first server in a high-availability
+cluster of 3 (or more) database servers, e.g. for an OVN northbound or
+southbound database in an environment that cannot tolerate a single
+point of failure.  It creates clustered database file \fIdb\fR with
+the given \fIschema\fR and configures the server to listen on
+\fIlocal\fR, which must take the form
+\fIprotocol\fB:\fIip\fB:\fIport\fR, where \fIprotocol\fR is \fBtcp\fR
+or \fBssl\fR, \fIip\fR is the server's IP (either an IPv4 address or
+an IPv6 address enclosed in square brackets), and \fIport\fR is a TCP
+port number.
+Only one address is specified, for the first server in the cluster,
+ordinarily the one for the server running \fBcreate\-cluster\fR.
+The address is used for communication within the cluster, not for
+communicating with OVSDB clients, and must not use the same port used
+for the OVSDB protocol.
 .
-.PP
-Some OVSDB databases and schemas, especially very old ones, do not
-have a version number.
+.IP "[\fB\-\-cid=\fIuuid\fR] \fBjoin\-cluster\fI db schema local remote\fR..."
+Use this command to initialize each server after the first one in an
+OVSDB high-availability cluster.  It creates clustered database file
+\fIdb\fR, obtaining the database name from \fIschema\fR, and
+configures the server to listen on \fIlocal\fR and to initially
+connect to \fIremote\fR, which must be a server that already belongs
+to the cluster.  \fIlocal\fR and \fIremote\fR use the same
+\fIprotocol\fB:\fIip\fB:\fIport\fR syntax as \fBcreate\-cluster\fR.
+.IP
+This command reads \fIschema\fR only to obtain the name of the
+database.  The initial schema for the database is actually the one
+passed to \fBcreate\-cluster\fR, so there is no risk of version
+mismatch.
+.IP
+This command does not do any network access, which means that it
+cannot actually join the new server to the cluster.  Instead, the
+\fIdb\fR file that it creates prepares the server to join the cluster
+the first time that \fBovsdb\-server\fR serves it.  As part of joining
+the cluster, the new server retrieves the database schema and obtains
+the list of all cluster members.  Only after that does it become a
+full member of the cluster.
+.IP
+Optionally, more than one \fIremote\fR may be specified; for example,
+in a cluster that already contains multiple servers, one could specify
+all the existing servers.  This is beneficial if some of the existing
+servers are down while the new server joins, but it is not otherwise
+needed.
+.IP
+By default, the \fIdb\fR created by \fBjoin\-cluster\fR will join any
+clustered database with the name from \fIschema\fR that is available
+at a \fIremote\fR.  In theory, if machines go up and down and IP
+addresses change in the right way, it could join the wrong database
+cluster.  To avoid this possibility, specify \fB\-\-cid=\fIuuid\fR,
+where \fIuuid\fR is the cluster ID of the cluster to join, as printed
+by \fBovsdb\-tool get\-cid\fR.
 .
+.SS "Version Management Commands"
+.so ovsdb/ovsdb-schemas.man
 .PP
 These commands work with different versions of OVSDB schemas and
 databases.
@@ -91,7 +136,10 @@  Reads \fIdb\fR, translating it into to the schema specified in
 is specified, the translated version is written as a new file named
 \fItarget\fR, which must not already exist.  If \fItarget\fR is
 omitted, then the translated version of the database replaces \fIdb\fR
-in-place.
+in-place.  In-place conversion cannot take place if the database is
+currently being served by \fBovsdb\-server\fR (instead, either stop
+\fBovsdb\-server\fR first or use \fBovsdb\-client\fR's \fBconvert\fR
+command).
 .IP
 This command can do simple ``upgrades'' and ``downgrades'' on a
 database's schema.  The data in \fIdb\fR must be valid when
@@ -100,22 +148,25 @@  interpreted under \fIschema\fR, with only one exception: data in
 ignored.  Columns that exist in \fIschema\fR but not in \fIdb\fR are
 set to their default values.  All of \fIschema\fR's constraints apply
 in full.
+.IP
+Some uses of this command can cause unrecoverable data loss.  For
+example, converting a database from a schema that has a given column
+or table to one that does not will delete all data in that column or
+table.  Back up critical databases before converting them.
+.IP
+This command is for standalone and active-backup databases only.  For
+clustered databases, use \fBovsdb\-client\fR's \fBconvert\fR command
+to convert them online.
 .
 .IP "\fBneeds\-conversion\fI db schema\fR"
-Reads the schema embedded in \fIdb\fR and the standalone schema in
+Reads the schema embedded in \fIdb\fR and the JSON schema from
 \fIschema\fR and compares them.  If the schemas are the same, prints
-\fBno\fR on stdout; if they differ, print \fByes\fR.
+\fBno\fR on stdout; if they differ, prints \fByes\fR.
 .
 .IP "\fBdb\-version\fI db\fR"
 .IQ "\fBschema\-version\fI schema\fR"
 Prints the version number in the schema embedded within the database
-\fIdb\fR or in the standalone schema \fIschema\fR on stdout.  A schema
-version number has the form \fIx\fB.\fIy\fB.\fIz\fR.  See
-\fBovs\-vswitchd.conf.db\fR(5) for details.
-.IP
-Schema version numbers and Open vSwitch version numbers are
-independent.
-.IP
+\fIdb\fR or in the JSON schema \fIschema\fR on stdout.
 If \fIschema\fR or \fIdb\fR was created before schema versioning was
 introduced, then it will not have a version number and this command
 will print a blank line.
@@ -123,25 +174,44 @@  will print a blank line.
 .IP "\fBdb\-cksum\fI db\fR"
 .IQ "\fBschema\-cksum\fI schema\fR"
 Prints the checksum in the schema embedded within the database
-\fIdb\fR or of the standalone schema \fIschema\fR on stdout.
-.IP
+\fIdb\fR or of the JSON schema \fIschema\fR on stdout.
 If \fIschema\fR or \fIdb\fR was created before schema checksums were
 introduced, then it will not have a checksum and this command
 will print a blank line.
 .
 .SS "Other Commands"
 .
+.IP "\fBcompact\fI db \fR[\fItarget\fR]"
+Reads \fIdb\fR and writes a compacted version.  If \fItarget\fR is
+specified, the compacted version is written as a new file named
+\fItarget\fR, which must not already exist.  If \fItarget\fR is
+omitted, then the compacted version of the database replaces \fIdb\fR
+in-place.  This command is not needed in normal operation because
+\fBovsdb\-server\fR from time to time automatically compacts a
+database that grows much larger than its minimum size.
+.IP
+This command does not work if \fIdb\fR is currently being served by
+\fBovsdb\-server\fR, or if it is otherwise locked for writing by
+another process.  This command also does not work with clustered
+databases.  Instead, in either case, send the
+\fBovsdb\-server/compact\fR command to \fBovsdb\-server\fR, via
+\fBovs\-appctl\fR).
+.
 .IP "\fBquery\fI db transaction\fR"
 Opens \fIdb\fR, executes \fItransaction\fR on it, and prints the
 results.  The \fItransaction\fR must be a JSON array in the format of
 the \fBparams\fR array for the JSON-RPC \fBtransact\fR method, as
 described in the OVSDB specification.
 .IP
-The \fIdb\fR is opened for read-only access, so this command may
+This command opens \fIdb\fR for read-only access, so it may
 safely run concurrently with other database activity, including
 \fBovsdb\-server\fR and other database writers.  The \fItransaction\fR
 may specify database modifications, but these will have no effect on
 \fIdb\fR.
+.IP
+This command does not work with clustered databases.  Instead, use
+\fBovsdb-client\fR's \fBquery\fR command to send the query to
+\fBovsdb\-server\fR.
 .
 .IP "\fBtransact\fI db transaction\fR"
 Opens \fIdb\fR, executes \fItransaction\fR on it, prints the results,
@@ -149,11 +219,11 @@  and commits any changes to \fIdb\fR.  The \fItransaction\fR must be a
 JSON array in the format of the \fBparams\fR array for the JSON-RPC
 \fBtransact\fR method, as described in the OVSDB specification.
 .IP
-The \fIdb\fR is opened and locked for read/write access, so this
-command will fail if the database is opened for writing by any other
-process, including \fBovsdb\-server\fR(1).  Use \fBovsdb\-client\fR(1),
-instead, to write to a database that is served by
-\fBovsdb\-server\fR(1).
+This command does not work if \fIdb\fR is currently being served by
+\fBovsdb\-server\fR, or if it is otherwise locked for writing by
+another process.  This command also does not work with clustered
+databases.  Instead, in either case, use \fBovsdb\-client\fR's
+\fBtransact\fR command to send the query to \fBovsdb\-server\fR.
 .
 .IP "\fBshow\-log\fI db\fR"
 Prints a summary of the records in \fIdb\fR's log, including the time
@@ -167,6 +237,14 @@  modified by each transaction.  With two \fB\-m\fRs, \fBshow\-log\fR
 also prints the values of the columns modified by each change to a
 record.
 .
+.IP "\fBdb\-name\fI db\fR"
+.IQ "\fBschema\-name\fI schema\fR"
+Prints the name of the schema embedded within the database \fIdb\fR or
+in the JSON schema \fIschema\fR on stdout.
+.
+.IP "\fBdb\-cid\fI db\fR"
+Prints the cluster ID for the clustered database \fIdb\fR.
+.
 .SH OPTIONS
 .SS "Logging Options"
 .so lib/vlog.man
@@ -178,6 +256,6 @@  default \fIschema\fR is \fB@pkgdatadir@/vswitch.ovsschema\fR.  The
 \fBhelp\fR command also displays these defaults.
 .SH "SEE ALSO"
 .
+\fBovsdb\fR(7),
 \fBovsdb\-server\fR(1),
-\fBovsdb\-client\fR(1),
-and the OVSDB specification.
+\fBovsdb\-client\fR(1).
diff --git a/ovsdb/ovsdb.7.xml b/ovsdb/ovsdb.7.xml
new file mode 100644
index 0000000..5d248a8
--- /dev/null
+++ b/ovsdb/ovsdb.7.xml
@@ -0,0 +1,725 @@ 
+<?xml version="1.0" encoding="utf-8"?>
+<manpage program="ovsdb" section="7" title="OVSDB">
+  <h1>Name</h1>
+  <p>ovsdb -- Open vSwitch Database</p>
+
+  <h1>Description</h1>
+  <p>
+    OVSDB, the Open vSwitch Database, is a network database system.  Schemas in
+    OVSDB specify the tables in a database and their columns' types and can
+    include data, uniqueness, and referential integrity constraints.  OVSDB
+    offers atomic, consistent, isolated, durable transactions.  RFC 7047
+    specifies the JSON-RPC based protocol that OVSDB clients and servers use to
+    communicate.
+  </p>
+
+  <p>
+    The OVSDB protocol is well suited for state synchronization because it
+    allows each client to monitor the contents of a whole database or a subset
+    of it.  Whenever a monitored portion of the database changes, the server
+    tells the client what rows were added or modified (including the new
+    contents) or deleted.  Thus, OVSDB clients can easily keep track of the
+    newest contents of any part of the database.
+  </p>
+
+  <p>
+    While OVSDB is general-purpose and not particularly specialized for use
+    with Open vSwitch, Open vSwitch does use it for multiple purposes.  The
+    leading use of OVSDB is for configuring and monitoring
+    <code>ovs-vswitchd</code>(8), the Open vSwitch switch daemon, using the
+    schema documented in <code>ovs-vswitchd.conf.db</code>(5).  The Open
+    Virtual Network (OVN) sub-project of OVS uses two OVSDB schemas, documented
+    in <code>ovn-nb</code>(5) and <code>ovn-sb</code>(5).  Finally, Open
+    vSwitch includes the ``VTEP'' schema, documented in <code>vtep</code>(5)
+    that many third-party hardware switches support for configuring VXLAN,
+    although OVS itself does not directly use this schema.
+  </p>
+
+  <p>
+    The OVSDB protocol specification allows independent, interoperable
+    implementations of OVSDB to be developed.  Open vSwitch includes a OVSDB
+    server implementation named <code>ovsdb-server</code>(1), which supports
+    several protocol extensions documented in its manpage, and a basic
+    command-line OVSDB client named <code>ovsdb-client</code>(1), as well as
+    OVSDB client libraries for C and for Python.  Open vSwitch documentation
+    often speaks of these OVSDB implementations in Open vSwitch as simply
+    ``OVSDB,'' even though that is distinct from the OVSDB protocol; we make
+    the distinction explicit only when it might otherwise be unclear from the
+    context.
+  </p>
+
+  <p>
+    In addition to these generic OVSDB server and client tools, Open vSwitch
+    includes tools for working with databases that have specific schemas:
+    <code>ovs-vsctl</code> works with the <code>ovs-vswitchd</code>
+    configuration database, <code>vtep-ctl</code> works with the VTEP database,
+    <code>ovn-nbctl</code> works with the OVN Northbound database, and so on.
+  </p>
+
+  <p>
+    RFC 7047 specifies the OVSDB protocol but it does not specify an on-disk
+    storage format.  Open vSwitch includes <code>ovsdb-tool</code>(1) for
+    working with its own on-disk database format.  The most notable feature of
+    this format is that <code>ovsdb-tool</code>(1) makes it easy for users to
+    print the transactions that have changed a database since the last time it
+    was compacted.  This feature is often useful for troubleshooting.
+  </p>
+
+  <h1>Schemas</h1>
+
+  <p>
+    Schemas in OVSDB have a JSON format that is specified in RFC 7047.  They
+    are often stored in files with an extension <code>.ovsschema</code>.  An
+    on-disk database in OVSDB includes a schema and data, embedding both into a
+    single file.  The Open vSwitch utility <code>ovsdb-tool</code> has commands
+    that work with schema files and with the schemas embedded in database
+    files.
+  </p>
+
+  <p>
+    An Open vSwitch schema has three important identifiers.  The first is its
+    name, which is also the name used in JSON-RPC calls to identify a database
+    based on that schema.  For example, the schema used to configure Open
+    vSwitch has the name <code>Open_vSwitch</code>.  Schema names begin with a
+    letter or an underscore, followed by any number of letters, underscores, or
+    digits.  The <code>ovsdb-tool</code> commands <code>schema-name</code> and
+    <code>db-name</code> extract the schema name from a schema or database
+    file, respectively.
+  </p>
+
+  <p>
+    An OVSDB schema also has a version of the form
+    <code><var>x</var>.<var>y</var>.<var>z</var></code>,
+    e.g. <code>1.2.3</code>.  Schemas managed within the Open vSwitch project
+    manage version numbering in the following way (but OVSDB does not mandate
+    this approach).  Whenever we change the database schema in a non-backward
+    compatible way (e.g. when we a column or a table), we increment
+    <var>x</var> and set <var>y</var> and <var>z</var> to 0.  When we change
+    the database schema in a backward compatible way (e.g. when we add a new
+    column), we increment <var>y</var> and set <var>z</var> to 0.  When we
+    change the database schema cosmetically (e.g. we reindent its syntax), we
+    increment <var>z</var>.  The <code>ovsdb-tool</code> commands
+    <code>schema-version</code> and <code>db-version</code> extract the schema
+    version from a schema or database file, respectively.
+  </p>
+
+  <p>
+    Very old OVSDB schemas do not have a version, but RFC 7047 mandates it.
+  </p>
+
+  <p>
+    An OVSDB schema optionally has a ``checksum.''  RFC 7047 does not specify
+    the use of the checksum and recommends that clients ignore it.  Open
+    vSwitch uses the checksum to remind developers to update the version: at
+    build time, if the schema's embedded checksum, ignoring the checksum field
+    itself, does not match the schema's content, then it fails the build with a
+    recommendation to update the version and the checksum.  Thus, a developer
+    who changes the schema, but does not update the version, receives an
+    automatic reminder.  In practice this has been an effective way to ensure
+    compliance with the version number policy.  The <code>ovsdb-tool</code>
+    commands <code>schema-cksum</code> and <code>db-cksum</code> extract the
+    schema checksum from a schema or database file, respectively.
+  </p>
+
+  <h1>Service Models</h1>
+
+  <p>
+    OVSDB supports three service models for databases: <dfn>standalone</dfn>,
+    <dfn>active-backup</dfn>, and <dfn>clustered</dfn>.  The service models
+    provide different compromises among consistency, availability, and
+    partition tolerance.  They also differ in the number of servers required
+    and in terms of performance.  The standalone and active-backup database
+    service models share one on-disk format, and clustered databases use a
+    different format, but the OVSDB programs work with both formats.
+  </p>
+
+  <p>
+    RFC 7047, which specifies the OVSDB protocol, does not mandate or specify
+    any particular service model.
+  </p>
+
+  <p>
+    The following sections describe the individual service models.
+  </p>
+
+  <h3>Standalone Database Service Model</h3>
+
+  <p>
+    A <dfn>standalone</dfn> database runs a single server.  If the server stops
+    running, the database becomes inaccessible, and if the server's storage is
+    lost or corrupted, the database's content is lost.  This service model is
+    appropriate when the database controls a process or activity to which it is
+    linked via ``fate-sharing.''  For example, an OVSDB instance that controls
+    an Open vSwitch virtual switch daemon, <code>ovs-vswitchd</code>, is a
+    standalone database because a server failure would take out both the
+    database and the virtual switch.
+  </p>
+
+  <p>
+    To set up a standalone database, use <code>ovsdb-tool create</code> to
+    create a database file, then run <code>ovsdb-server</code> to start the
+    database service.
+  </p>
+
+  <h3>Active-Backup Database Service Model</h3>
+
+  <p>
+    An <dfn>active-backup</dfn> database runs two servers (on different hosts).
+    At any given time, one of the servers is designated with the
+    <dfn>active</dfn> role and the other the <dfn>backup</dfn> role.  An active
+    server behaves just like a standalone server.  A backup server makes
+    an OVSDB connection to the active server and uses it to continuously
+    replicate its content as it changes in real time.  OVSDB clients can
+    connect to either server but only the active server allows data
+    modification or lock transactions.
+  </p>
+
+  <p>
+    Setup for an active-backup database starts from a working standalone
+    database service, which is initially the active server.  On another node,
+    to set up a backup server, create a database file with the same schema as
+    the active server.  The initial contents of the database file do not
+    matter, as long as the schema is correct, so <code>ovsdb-tool create</code>
+    will work, as will copying the database file from the active server.  Then
+    use <code>ovsdb-server --sync-from=<var>active</var></code> to start the
+    backup server, where <var>active</var> is an OVSDB connection method (see
+    <ref section="Connection Methods"/>, below) that connects to the active
+    server.  At that point, the backup server will fetch a copy of the active
+    database and keep it up-to-date until it is killed.
+  </p>
+
+  <p>
+    When the active server in an active-backup server pair fails, an
+    administrator can switch the backup server to an active role with the
+    <code>ovs-appctl</code> command
+    <code>ovsdb-server/disconnect-active-ovsdb-server</code>.  Clients then
+    have read/write access to the now-active server.  Of course, administrators
+    are slow to respond compared to software, so in practice external
+    management software detects the active server's failure and changes the
+    backup server's role.  For example, the <cite>Integration Guide for
+    Centralized Control</cite> in the Open vSwitch documentation describes how
+    to use Pacemaker for this purpose in OVN.
+  </p>
+
+  <p>
+    Suppose an active server fails and its backup is promoted to active.
+    If the failed server is revived, it must be started as a backup
+    server.  Otherwise, if both servers are active, then they may start
+    out of sync, if the database changed while the server was done, and
+    they will continue to diverge over time.  This also happens if the
+    software managing the database servers cannot reach the active server
+    and therefore switches the backup to active, but other hosts can reach
+    both servers.  These ``split-brain'' problems are unsolvable in
+    general for server pairs.
+  </p>
+
+  <p>
+    Compared to a standalone server, the active-backup service model
+    somewhat increases availability, at a risk of split-brain.  It adds
+    generally insignificant performance overhead.  On the other hand, the
+    clustered service model, discussed below, requires at least 3 servers
+    and has greater performance overhead, but it avoids the need for
+    external management software and eliminates the possibility of
+    split-brain.
+  </p>
+
+  <p>
+    Open vSwitch 2.6 introduced support for the active-backup service model.
+  </p>
+
+  <h3>Clustered Database Service Model</h3>
+
+  <p>
+    A <dfn>clustered</dfn> database runs across 3 or 5 database servers (the
+    <dfn>cluster</dfn>) on different hosts.  Servers in a cluster automatically
+    synchronize writes within the cluster.  A 3-server cluster can remain
+    available in the face of at most 1 server failure; a 5-server cluster
+    tolerates up to 2 failures.
+  </p>
+
+  <p>
+    Clusters larger than 5 servers will also work, with every 2 added
+    servers allowing the cluster to tolerate 1 more failure, but
+    performance decreases, especially write performance.  The number of
+    servers should be odd: a 4- or 6-server cluster cannot tolerate more
+    failures than a 3- or 5-server cluster, respectively.
+  </p>
+
+  <p>
+    To set up a clustered database, first initialize it on a single node by
+    running <code>ovsdb-tool create-cluster</code> and starting
+    <code>ovsdb-server</code>.  To add a server to a cluster, run
+    <code>ovsdb-tool join-cluster</code> on the new server and start
+    <code>ovsdb-server</code>.  To remove a running server from a cluster, use
+    <code>ovs-appctl</code> to invoke the <code>cluster/leave</code> command.
+    When a server fails and cannot be recovered, e.g. because its hard disk
+    crashed, or to otherwise remove a server that is down from a cluster, use
+    <code>ovs-appctl</code> to invoke <code>cluster-kick</code> to make the
+    remaining servers kick it out of the cluster.
+  </p>
+
+  <p>
+    The above methods for adding and removing servers only work for healthy
+    clusters, that is, for clusters with no more failures than their maximum
+    tolerance.  For example, in a 3-server cluster, the failure of 2 servers
+    prevents servers joining or leaving the cluster (as well as database
+    access).  To prevent data loss or inconsistency, the preferred solution to
+    this problem is to bring up enough of the failed servers to make the
+    cluster healthy again, then if necessary remove any remaining failed
+    servers and add new ones.  If this cannot be done, though, use
+    <code>ovs-appctl</code> to invoke <code>cluster/leave --force</code> on a
+    running server.  This command forces the server to which it is directed to
+    leave its cluster and form a new single-node cluster that contains only
+    itself.  The data in the new cluster may be inconsistent with the former
+    cluster: transactions not yet replicated to the server will be lost, and
+    transactions not yet applied to the cluster may be committed.  Afterward,
+    any servers in its former cluster will regard the server to have failed.
+  </p>
+
+  <p>
+    The servers in a cluster synchronize data over a cluster management
+    protocol that is specific to Open vSwitch; it is not the same as the OVSDB
+    protocol specified in RFC 7047.  For this purpose, a server in a cluster is
+    tied to a particular IP address and TCP port, which is specified in the
+    <code>ovsdb-tool</code> command that creates or joins the cluster.  The TCP
+    port used for clustering must be different from that used for OVSDB
+    clients.  To change the port or address of a server in a cluster, first
+    remove it from the cluster, then add it back with the new address.
+  </p>
+
+  <p>
+    To upgrade the <code>ovsdb-server</code> processes in a cluster from one
+    version of Open vSwitch to another, upgrading them one at a time will keep
+    the cluster healthy during the upgrade process.  (This is different from
+    upgrading a database schema, which is covered later under <ref
+    section="Upgrading or Downgrading a Database"/>.)
+  </p>
+
+  <p>
+    Open vSwitch 2.8 introduced support for the clustered service model.
+  </p>
+
+  <h2>Database Replication</h2>
+
+  <p>
+    OVSDB can layer <dfn>replication</dfn> on top of any of its service models.
+    Replication, in this context, means to make, and keep up-to-date, a
+    read-only copy of the contents of a database (the <code>replica</code>).
+    One use of replication is to keep an up-to-date backup of a database.  A
+    replica used solely for backup would not need to support clients of its
+    own.  A set of replicas that do serve clients could be used to scale out
+    read access to the primary database.
+  </p>
+
+  <p>
+    A database replica is set up in the same way as a backup server in an
+    active-backup pair, with the difference that the replica is never promoted
+    to an active role.
+  </p>
+
+  <p>
+    Open vSwitch 2.6 introduced support for database replication.
+  </p>
+
+  <h1>Connection Methods</h1>
+
+  <p>
+    An OVSDB <dfn>connection method</dfn> is a string that specifies how to
+    make a JSON-RPC connection between an OVSDB client and server.  Connection
+    methods are part of the Open vSwitch implementation of OVSDB and not
+    specified by RFC 7047.  <code>ovsdb-server</code> uses connection methods
+    to specify how it should listen for connections from clients and
+    <code>ovsdb-client</code> uses them to specify how it should connect to a
+    server.  Connections in the opposite direction, where
+    <code>ovsdb-server</code> connects to a client that is configured to listen
+    for an incoming connection, are also possible.
+  </p>
+
+  <p>
+    Connection methods are classified as <dfn>active</dfn> or
+    <dfn>passive</dfn>.  An active connection method makes an outgoing
+    connection to a remote host; a passive connection method listens for
+    connection from remote hosts.  The most common arrangement is to configure
+    an an OVSDB server with passive connection methods and clients with active
+    ones, but the OVSDB implementation in Open vSwitch supports the opposite
+    arrangement as well.
+  </p>
+
+  <p>
+    OVSDB supports the following active connection methods:
+  </p>
+
+  <dl>
+    <dt><code>ssl:<var>ip</var>:<var>port</var></code></dt>
+    <dd>
+      <p>
+        The specified SSL or TLS <var>port</var> on the host at the given
+        <var>ip</var>.
+      </p>
+    </dd>
+
+    <dt><code>tcp:<var>ip</var>:<var>port</var></code></dt>
+    <dd>
+      <p>
+        The specified TCP <var>port</var> on the host at the given
+        <var>ip</var>.
+      </p>
+    </dd>
+
+    <dt><code>unix:<var>file</var></code></dt>
+    <dd>
+      <p>
+        On Unix-like systems, connect to the Unix domain server socket named
+        <var>file</var>.
+      </p>
+
+      <p>
+        On Windows, connect to a local named pipe that is represented by a file
+        created in the path <var>file</var> to mimic the behavior of a Unix
+        domain socket.
+      </p>
+    </dd>
+
+    <dt><var>method1</var><code>, </code><var>method2</var><code>, </code>...<code>, </code><var>methodN</var></dt>
+    <dd>
+      <p>
+        For a clustered database service to be highly available, a client must
+        be able to connect to any of the servers in the cluster.  To do so,
+        specify connection methods for each of the servers separated by commas
+        (and optional spaces).
+      </p>
+
+      <p>
+        In theory, if machines go up and down and IP addresses change in the
+        right way, a client could talk to the wrong instance of a database.  To
+        avoid this possibility, add <code>cid:<var>uuid</var></code> in the
+        list of connection methods, where <var>uuid</var> is the cluster ID of
+        the desired database cluster, as printed by <code>ovsdb-tool
+        get-cid</code>.  This feature is optional.
+      </p>
+    </dd>
+  </dl>
+
+  <p>
+    OVSDB supports the following passive connection methods:
+  </p>
+
+  <dl>
+    <dt><code>pssl:<var>port</var></code></dt>
+    <dt><code>pssl:<var>port</var>:<var>ip</var></code></dt>
+    <dd>
+      Listen on the given TCP <var>port</var> for SSL or TLS connections.  By
+      default, connections are not bound to a particular local IP address and
+      connections from IPv6 addresses are not accepted.  Specifying
+      <var>ip</var> limits connections to those from the given IP.
+    </dd>
+
+    <dt><code>ptcp:<var>port</var></code></dt>
+    <dt><code>ptcp:<var>port</var>:<var>ip</var></code></dt>
+    <dd>
+      Listen on the given TCP <var>port</var>.  By
+      default, connections are not bound to a particular local IP address and
+      connections from IPv6 addresses are not accepted.  Specifying
+      <var>ip</var> limits connections to those from the given IP.
+    </dd>
+
+    <dt><code>punix:<var>file</var></code></dt>
+    <dd>
+      <p>
+        On Unix-like systems, listens for connections on the Unix domain socket
+        named <var>file</var>.
+      </p>
+
+      <p>
+        On Windows, listens on a local named pipe, creating a named pipe
+        <var>file</var> to mimic the behavior of a Unix domain socket.
+      </p>
+    </dd>
+  </dl>
+
+  <p>
+    All IP-based connection methods accept IPv4 and IPv6 addresses.  DNS names
+    are not accepted.  To specify an IPv6 address, wrap it in square brackets,
+    e.g.  <code>ssl:[::1]:6640</code>.
+  </p>
+
+  <p>
+    The <var>port</var> may be omitted from connection methods that use a port
+    number.  The default <var>port</var> for TCP-based connection methods is
+    6640, e.g. <code>pssl:</code> is equivalent to <code>pssl:6640</code>.  In
+    Open vSwitch prior to version 2.4.0, the default port was 6632.  To avoid
+    incompatibility between older and newer versions, we encourage users to
+    specify a port number.
+  </p>
+
+  <p>
+    The <code>ssl</code> and <code>pssl</code> connection methods requires
+    additional configuration through <code>--private-key</code>,
+    <code>--certificate</code>, and <code>--ca-cert</code> command line
+    options.  Open vSwitch can be built without SSL support, in which case
+    these connection methods are not supported.
+  </p>
+
+  <h1>Database Life Cycle</h1>
+
+  <p>
+    This section describes how to handle various events in the life cycle of
+    a database using the Open vSwitch implementation of OVSDB.
+  </p>
+
+  <h2>Creating a Database</h2>
+
+  <p>
+    Creating and starting up the service for a new database was covered
+    separately for each database service model in the <ref section="Service
+    Models"/> section, above.
+  </p>
+
+  <h2>Backing Up and Restoring a Database</h2>
+
+  <p>
+    OVSDB is often used in contexts where the database contents are not
+    particularly valuable.  For example, in many systems, the database for
+    configuring <code>ovs-vswitchd</code> is essentially rebuilt from scratch
+    at boot time.  It is not worthwhile to back up these databases.
+  </p>
+
+  <p>
+    When OVSDB is used for valuable data, a backup strategy is worth
+    considering.  One way is to use database replication, discussed above in
+    <ref section="Database Replication"/>, which keeps an online, up-to-date
+    copy of a database, possibly on a remote system.  This works with all OVSDB
+    service models.
+  </p>
+
+  <p>
+    A more common backup strategy is to periodically take and store a snapshot.
+    For the standalone and active-backup service models, making a copy of the
+    database file, e.g. using <code>cp</code>, effectively makes a snapshot,
+    and because OVSDB database files are append-only, it works even if the
+    database is being modified when the snapshot takes place.  This approach
+    does not work for clustered databases (short of taking a snapshot of all
+    the servers' database files at the same time).
+  </p>
+
+  <p>
+    Another way to make a backup, which works with all OVSDB service models, is
+    to use <code>ovsdb-client backup</code>, which connects to a running
+    database server and outputs an atomic snapshot of its schema and content,
+    in the same format used for standalone and active-backup databases.
+  </p>
+
+  <p>
+    Multiple options are also available when the time comes to restore a
+    database from a backup.  For the standalone and active-backup service
+    models, one option is to stop the database server or servers, overwrite the
+    database file with the backup (e.g. with <code>cp</code>), and then restart
+    the servers.  Another way, which works with any service model, is to use
+    <code>ovsdb-client restore</code>, which connects to a running database
+    server and replaces the data in one of its databases by a provided
+    snapshot.  Using <code>ovsdb-client restore</code> has the disadvantage
+    that UUIDs of rows in the restored database will differ from those in the
+    snapshot the OVSDB protocol does not allow clients to specify row UUIDs.
+  </p>
+
+  <p>
+    None of these approaches save and restore data in columns that the schema
+    designates as ephemeral.  This is by design: the designer of a schema only
+    marks a column as ephemeral if it is acceptable for its data to be lost
+    when a database server restarts.
+  </p>
+
+  <p>
+    Clustering and backup serve different purposes.  Clustering increases
+    availability, but it does not protect against data loss if, for example, a
+    malicious or malfunctioning OVSDB client deletes or tampers with data.
+  </p>
+
+  <h2>Upgrading or Downgrading a Database</h2>
+
+  <p>
+    The evolution of a piece of software can require changes to the schemas of
+    the databases that it uses.  For example, new features might require new
+    tables or new columns in existing tables, or conceptual changes might
+    require a database to be reorganized in other ways.  In some cases, the
+    easiest way to deal with a change in a database schema is to delete the
+    existing database and start fresh with the new schema, especially if the
+    data in the database is easy to reconstruct.  But in many other cases, it
+    is better to convert the database from one schema to another.
+  </p>
+
+  <p>
+    The OVSDB implementation in Open vSwitch has built-in support for some
+    simple cases of converting a database from one schema to another.  This
+    support can handle changes that add or remove database columns or tables or
+    that eliminate constraints (for example, changing a column that must have
+    exactly one value into one that has one or more values).  It can also
+    handle changes that add constraints or make them stricter, but only if the
+    existing data in the database satisfies the new constraints (for example,
+    changing a column that has one or more values into a column with exactly
+    one value, if every row in the column has exactly one value).  The built-in
+    conversion can cause data loss in obvious ways, for example if the new
+    schema removes tables or columns, or indirectly, for example by deleting
+    unreferenced rows in tables that the new schema marks for garbage
+    collection.
+  </p>
+
+  <p>
+    Converting a database can lose data, so it is wise to make a backup
+    beforehand.
+  </p>
+
+  <p>
+    To use OVSDB's built-in support for schema conversion with a standalone or
+    active-backup database, first stop the database server or servers, then use
+    <code>ovsdb-tool convert</code> to convert it to the new schema, and then
+    restart the database server.
+  </p>
+
+  <p>
+    OVSDB also supports online database schema conversion, for any of its
+    database service models.  To convert a database online, use
+    <code>ovsdb-client convert</code>.  The conversion is atomic, consistent,
+    isolated, and durable.  The OVSDB protocol does not provide a way for the
+    server to notify a client that a database's schema has changed, so
+    currently <code>ovsdb-server</code> disconnects any clients connected when
+    the conversion takes place.  Upon reconnction, clients will discover that
+    the schema has changed.
+  </p>
+
+  <p>
+    Schema versions and checksums (see <ref section="Schemas"/>, above) can
+    give hints about whether a database needs to be converted to a new schema.
+    If there is any question, though, the <code>needs-conversion</code> command
+    on <code>ovsdb-tool</code> and <code>ovsdb-client</code> can provide a
+    definitive answer.
+  </p>
+
+  <h2>Working with Database History</h2>
+
+  <p>
+    Both on-disk database formats that OVSDB supports are organized as a stream
+    of transaction records.  Each record describes a change to the database as
+    a list of rows that were inserted or deleted or modified, along with the
+    details.  Therefore, in normal operation, a database file only grows, as
+    each change causes another record to be appended at the end.  Usually, a
+    user has no need to understand this file structure.  This section covers
+    some exceptions.
+  </p>
+
+  <h3>Compacting Databases</h3>
+
+  <p>
+    If OVSDB database files were truly append-only, then over time they would
+    grow without bound.  To avoid this problem, OVSDB can <dfn>compact</dfn> a
+    database file, that is, replace it by a new version that contains only the
+    current database contents, as if it had been inserted by a single
+    transaction.  From time to time, <code>ovsdb-server</code> automatically
+    compacts a database that grows much larger than its minimum size.
+  </p>
+
+  <p>
+    Because <code>ovsdb-server</code> automatically compacts databases, it is
+    usually not necessary to compact them manually, but OVSDB still offers a
+    few ways to do it.  First, <code>ovsdb-tool compact</code> can compact a
+    standalone or active-backup database that is not currently being served by
+    <code>ovsdb-server</code> (or otherwise locked for writing by another
+    process).  To compact any database that is currently being served by
+    <code>ovsdb-server</code>, use <code>ovs-appctl</code> to send the
+    <code>ovsdb-server/compact</code> command.  Each server in an active-backup
+    or clustered database maintains its database file independently, so to
+    compact all of them, issue this command separately on each server.
+  </p>
+
+  <h3>Viewing History</h3>
+
+  <p>
+    The <code>ovsdb-tool</code> utility's <code>show-log</code> command
+    displays the transaction records in an OVSDB database file in a
+    human-readable format.  By default, it shows minimal detail, but adding the
+    option <code>-m</code> once or twice increases the level of detail.  In
+    addition to the transaction data, it shows the time and date of each
+    transaction and any ``comment'' added to the transaction by the client.
+    The comments can be helpful for quickly understanding a transaction; for
+    example, <code>ovs-vsctl</code> adds its command line to the transactions
+    that it makes.
+  </p>
+
+  <p>
+    The <code>show-log</code> command works with both OVSDB file formats, but
+    the details of the output format differ.  For active-backup and clustered
+    databases, the sequence of transactions in each server's log will differ,
+    even at points when they reflect the same data.
+  </p>
+
+  <h3>Truncating History</h3>
+
+  <p>
+    It may occasionally be useful to ``roll back'' a database file to an
+    earlier point.  Because of the organization of OVSDB records, this is easy
+    to do.  Start by noting the record number <var>i</var> of the first record
+    to delete in <code>ovsdb-tool show-log</code> output.  Each record is two
+    lines of plain text, so trimming the log is as simple as running <code>head
+    -n <var>j</var></code>, where <var>j</var> = 2<var>i</var>.
+  </p>
+
+  <h2>Corruption</h2>
+
+  <p>
+    When <code>ovsdb-server</code> opens an OVSDB database file, of any kind,
+    it reads as many transaction records as it can from the file until it
+    reaches the end of the file or it encounters a corrupted record.  At that
+    point it stops reading and regards the data that it has read to this point
+    as the full contents of the database file, effectively rolling the database
+    back to an earlier point.
+  </p>
+
+  <p>
+    Each transaction record contains an embedded SHA-1 checksum, which the
+    server verifies as it reads a database file.  It detects corruption when a
+    checksum fails to verify.  Even though SHA-1 is no longer considered secure
+    for use in cryptography, it is acceptable for this purpose because it is
+    not used to defend against malicious attackers.
+  </p>
+
+  <p>
+    The first record in a standalone or active-backup database file specifies
+    the schema.  <code>ovsdb-server</code> will refuse to work with such a
+    database, or with a clustered database file with corruption in the first
+    few records.  Delete and recreate such a database, or restore it from a
+    backup.
+  </p>
+
+  <p>
+    When <code>ovsdb-server</code> adds records to a database file in which it
+    detected corruption, it first truncates the file just after the last good
+    record.
+  </p>
+
+  <h1>See Also</h1>
+
+  <p>RFC 7047, ``The Open vSwitch Database Management Protocol.''</p>
+
+  <p>
+    Open vSwitch implementations of generic OVSDB functionality:
+    <code>ovsdb-server</code>(1),
+    <code>ovsdb-client</code>(1),
+    <code>ovsdb-tool</code>(1).
+  </p>
+
+  <p>
+    Tools for working with databases that have specific OVSDB schemas:
+    <code>ovs-vsctl</code>(8),
+    <code>vtep-ctl</code>(8),
+    <code>ovn-nbctl</code>(8),
+    <code>ovn-sbctl</code>(8).
+  </p>
+
+  <p>
+    OVSDB schemas for Open vSwitch and related functionality:
+    <code>ovs-vswitchd.conf.db</code>(5),
+    <code>vtep</code>(5),
+    <code>ovn-nb</code>(5),
+    <code>ovn-sb</code>(5).
+  </p>
+</manpage>
diff --git a/ovsdb/remote-active.man b/ovsdb/remote-active.man
deleted file mode 100644
index 83d6465..0000000
--- a/ovsdb/remote-active.man
+++ /dev/null
@@ -1,19 +0,0 @@ 
-.IP "\fBssl:\fIip\fB:\fIport\fR"
-The specified SSL \fIport\fR on the host at the given \fIip\fR, which
-must be expressed as an IP address (not a DNS name) in IPv4 or IPv6 address
-format.  If \fIip\fR is an IPv6 address, then wrap \fIip\fR with square
-brackets, e.g.: \fBssl:[::1]:6640\fR.
-The \fB\-\-private\-key\fR, \fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR
-options are mandatory when this form is used.
-.
-.IP "\fBtcp:\fIip\fB:\fIport\fR"
-Connect to the given TCP \fIport\fR on \fIip\fR, where \fIip\fR can be IPv4
-or IPv6 address. If \fIip\fR is an IPv6 address, then wrap \fIip\fR with
-square brackets, e.g.: \fBtcp:[::1]:6640\fR.
-.
-.IP "\fBunix:\fIfile\fR"
-On POSIX, connect to the Unix domain server socket named \fIfile\fR.
-.IP
-On Windows, connect to a local named pipe that is represented by a file
-created in the path \fIfile\fR to mimic the behavior of a Unix domain
-socket.
diff --git a/ovsdb/remote-passive.man b/ovsdb/remote-passive.man
deleted file mode 100644
index 5da2de8..0000000
--- a/ovsdb/remote-passive.man
+++ /dev/null
@@ -1,26 +0,0 @@ 
-.IP "\fBpssl:\fIport\fR[\fB:\fIip\fR]"
-Listen on the given SSL \fIport\fR for a connection.  By default,
-connections are not bound to a particular local IP address and
-it listens only on IPv4 (but not IPv6) addresses, but
-specifying \fIip\fR limits connections to those from the given
-\fIip\fR, either IPv4 or IPv6 address.  If \fIip\fR is
-an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
-\fBpssl:6640:[::1]\fR.  The \fB\-\-private\-key\fR,
-\fB\-\-certificate\fR, and \fB\-\-ca\-cert\fR options are mandatory
-when this form is used.
-.
-.IP "\fBptcp:\fIport\fR[\fB:\fIip\fR]"
-Listen on the given TCP \fIport\fR for a connection.  By default,
-connections are not bound to a particular local IP address and
-it listens only on IPv4 (but not IPv6) addresses, but
-\fIip\fR may be specified to listen only for connections to the given
-\fIip\fR, either IPv4 or IPv6 address.  If \fIip\fR is
-an IPv6 address, then wrap \fIip\fR with square brackets, e.g.:
-\fBptcp:6640:[::1]\fR.
-.
-.IP "\fBpunix:\fIfile\fR"
-On POSIX, listen on the Unix domain server socket named \fIfile\fR for a
-connection.
-.IP
-On Windows, listen on a local named pipe.  A file is created in the
-path \fIfile\fR to mimic the behavior of a Unix domain socket.
diff --git a/ovsdb/replication.man b/ovsdb/replication.man
index a2ea665..e69de29 100644
--- a/ovsdb/replication.man
+++ b/ovsdb/replication.man
@@ -1,23 +0,0 @@ 
-The following options allow \fBovsdb\-server\fR to synchronize  its  databases
-with another running \fBovsdb\-server\fR.
-.TP
-\fB\-\-sync\-from=\fIserver\fR
-Sets up \fBovsdb\-server\fR to synchronize its databases with the
-databases in \fIserver\fR, which must be an active connection method
-in one of the forms documented in \fBovsdb\-client\fR(1).  Every
-transaction committed by \fIserver\fR will be replicated to
-\fBovsdb\-server\fR.  This option makes \fBovsdb\-server\fR start
-as a backup server; add \fB\-\-active\fR to make it start as an
-active server.
-.TP
-\fB\-\-sync\-exclude-tables=\fIdb:table[,db:table]...\fR
-Causes the specified tables to be excluded from replication.
-.TP
-\fB\-\-active\fR
-By default, \fB\-\-sync\-from\fR makes \fBovsdb\-server\fR start up as
-a backup for \fIserver\fR.  With \fB\-\-active\fR, however,
-\fBovsdb\-server\fR starts as an active server.  Use this option to
-allow the syncing options to be specified using command line options,
-yet start the server, as the default, active server.  To switch the
-running server to backup mode, use \fBovs-appctl(1)\fR to execute the
-\fBovsdb\-server/connect\-active\-ovsdb\-server\fR command.
diff --git a/python/build/nroff.py b/python/build/nroff.py
index c23837f..944a72a 100644
--- a/python/build/nroff.py
+++ b/python/build/nroff.py
@@ -80,23 +80,24 @@  def inline_xml_to_nroff(node, font, to_upper=False, newline='\n'):
                 s += inline_xml_to_nroff(child, r'\fB', to_upper, newline)
             return s + font
         elif node.tagName == 'ref':
-            s = r'\fB'
             if node.hasAttribute('column'):
-                s += node.attributes['column'].nodeValue
+                s = node.attributes['column'].nodeValue
                 if node.hasAttribute('key'):
                     s += ':' + node.attributes['key'].nodeValue
             elif node.hasAttribute('table'):
-                s += node.attributes['table'].nodeValue
+                s = node.attributes['table'].nodeValue
             elif node.hasAttribute('group'):
-                s += node.attributes['group'].nodeValue
+                s = node.attributes['group'].nodeValue
             elif node.hasAttribute('db'):
-                s += node.attributes['db'].nodeValue
+                s = node.attributes['db'].nodeValue
             elif node.hasAttribute('field'):
-                s += node.attributes['field'].nodeValue
+                s = node.attributes['field'].nodeValue
+            elif node.hasAttribute('section'):
+                s = node.attributes['section'].nodeValue
             else:
                 raise error.Error("'ref' lacks required attributes: %s"
                                   % list(node.attributes.keys()))
-            return s + font
+            return r'\fB' + re.sub(r'\s+', ' ', s) + font
         elif node.tagName in ['var', 'dfn', 'i', 'cite']:
             s = r'\fI'
             for child in node.childNodes:
diff --git a/utilities/ovs-vsctl.8.in b/utilities/ovs-vsctl.8.in
index 1917906..1e694e8 100644
--- a/utilities/ovs-vsctl.8.in
+++ b/utilities/ovs-vsctl.8.in
@@ -78,14 +78,9 @@  the global options by \fB\-\-\fR.
 .
 .IP "\fB\-\-db=\fIserver\fR"
 Sets \fIserver\fR as the database server that \fBovs\-vsctl\fR
-contacts to query or modify configuration.  The default is
-\fBunix:@RUNDIR@/db.sock\fR.  \fIserver\fR must take one of the
-following forms:
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
-.
+contacts to query or modify configuration.  \fIserver\fR may be an
+OVSDB active or passive connection method, as described in
+\fBovsdb\fR(7).  The default is \fBunix:@RUNDIR@/db.sock\fR.
 .IP "\fB\-\-no\-wait\fR"
 Prevents \fBovs\-vsctl\fR from waiting for \fBovs\-vswitchd\fR to
 reconfigure itself according to the modified database.  This
@@ -410,13 +405,9 @@  Prints the configured manager(s).
 Deletes the configured manager(s).
 .
 .IP "\fBset\-manager\fR \fItarget\fR\&..."
-Sets the configured manager target or targets.  Each \fItarget\fR may
-use any of the following forms:
-.
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
+Sets the configured manager target or targets.
+Each \fItarget\fR may be an OVSDB active or passive connection method,
+e.g. \fBpssl:6640\fR, as described in \fBovsdb\fR(7).
 .
 .SS "SSL Configuration"
 When \fBovs\-vswitchd\fR is configured to connect over SSL for management or
diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
index fc19f3b..32c755a 100644
--- a/vswitchd/ovs-vswitchd.8.in
+++ b/vswitchd/ovs-vswitchd.8.in
@@ -19,10 +19,9 @@  A daemon that manages and controls any number of Open vSwitch switches
 on the local machine.
 .PP
 The \fIdatabase\fR argument specifies how \fBovs\-vswitchd\fR connects
-to \fBovsdb\-server\fR.  The default is \fBunix:@RUNDIR@/db.sock\fR.
-The following forms are accepted:
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
+to \fBovsdb\-server\fR.  \fIdatabase\fR may be an OVSDB active or
+passive connection method, as described in \fBovsdb\fR(7).  The
+default is \fBunix:@RUNDIR@/db.sock\fR.
 .PP
 \fBovs\-vswitchd\fR retrieves its configuration from \fIdatabase\fR at
 startup.  It sets up Open vSwitch datapaths and then operates
diff --git a/vtep/vtep-ctl.8.in b/vtep/vtep-ctl.8.in
index 1901356..6ace592 100644
--- a/vtep/vtep-ctl.8.in
+++ b/vtep/vtep-ctl.8.in
@@ -52,15 +52,10 @@  command line has options, then those options must be separated from
 the global options by \fB\-\-\fR.
 .
 .IP "\fB\-\-db=\fIserver\fR"
-Sets \fIserver\fR as the database server that \fBvtep\-ctl\fR
-contacts to query or modify configuration.  The default is
-\fBunix:@RUNDIR@/db.sock\fR.  \fIserver\fR must take one of the
-following forms:
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
-.
+Sets \fIserver\fR as the database server that \fBvtep\-ctl\fR contacts
+to query or modify configuration.  \fIserver\fR may be an OVSDB active
+or passive connection method, as described in \fBovsdb\fR(7).  The
+default is \fBunix:@RUNDIR@/db.sock\fR.
 .IP "\fB\-\-no\-syslog\fR"
 By default, \fBvtep\-ctl\fR logs its arguments and the details of any
 changes that it makes to the system log.  This option disables this
@@ -336,13 +331,9 @@  Prints the configured manager(s).
 Deletes the configured manager(s).
 .
 .IP "\fBset\-manager\fR \fItarget\fR\&..."
-Sets the configured manager target or targets.  Each \fItarget\fR may
-use any of the following forms:
-.
-.RS
-.so ovsdb/remote-active.man
-.so ovsdb/remote-passive.man
-.RE
+Sets the configured manager target or targets.
+Each \fItarget\fR may be an OVSDB active or passive connection method,
+e.g. \fBpssl:6640\fR, as described in \fBovsdb\fR(7).
 .
 .SS "Database Commands"
 .