listen parameter from box.cfg{} defines a URI
(port 3301 in our example), on which the master can accept connections from
replicas.

replication parameter defines the URIs at
which all instances in the replica set can accept connections. It includes the
replica’s URI as well, although the replica is not a replication source right
now.

Примечание

For security reasons, we recommend to prevent unauthorized replication
sources by associating a password with every user that has a replication
role. That way, the URI
for replication parameter must have the long form
username:password@host:port.

read_only parameter enables data-change
operations on the instance and makes this Tarantool instance act as a master,
not as a replica. That’s the only parameter in our instance files that will
differ.

box.once() function contains database initialization logic
that should be executed only once during the replica set lifetime.

In this example, we create a space with a primary index, and a user for
replication purposes. We also say print('box.onceexecutedonmaster') to
see later in console whether box.once() is executed.

Примечание

Replication requires privileges. We can grant privileges for accessing spaces
directly to the user who will start the instance. However, it is more usual
to grant privileges for accessing spaces to a
role, and then grant the role to the user who
will start the replica.

Here we use Tarantool’s predefined role named «replication» which by default
grants «read» privileges for all database objects («universe»), and we can
further set up privileges for this role as required.

In the replica’s instance file, we only set read-only parameter to «true», and
say print('box.onceexecutedonreplica') to make sure that box.once() is
not executed more than once. Otherwise the replica’s instance file is fully
identical to the master’s instance file.

The replica does not inherit the master’s configuration parameters, such as
those making the checkpoint daemon run on
the master. To get the same behavior, please set the relevant parameters
explicitly so that they are the same on both master and replica.

To perform a controlled failover, that is, swap the roles of the master and
replica, all we need to do is to set read_only=true at the master, and
read_only=false at the replica. The order of actions is important here.
If a system is running in production, we don’t want concurrent writes happen
both at the replica and the master. Nor do we want the new replica to accept
any writes until it has finished fetching all replication data from the old
master. To compare replica and master state, we can use
box.info.signature.

Set read_only=true at the master.

# at the mastertarantool> box.cfg{read_only=true}

Record the master’s current position with box.info.signature, containing
the sum of all LSNs in the master’s vector clock.

# at the mastertarantool> box.info.signature

Wait until the replica’s signature is the same as the master’s.

# at the replicatarantool> box.info.signature

Set read_only=false at the replica to enable write operations.

# at the replicatarantool> box.cfg{read_only=false}

These 4 steps ensure that the replica doesn’t accept new writes until it’s done
fetching writes from the master.