Skip to content

Commit 8aedebc

Browse files
committed
3.0 configuration: update replication tutorials (resolving conflicts)
1 parent 39d7cba commit 8aedebc

File tree

3 files changed

+317
-12
lines changed

3 files changed

+317
-12
lines changed

doc/how-to/replication/repl_bootstrap.rst

+4
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,14 @@ To check that a replica (``instance002``) gets all updates from the master, foll
232232
- {1: 21}
233233
...
234234
235+
.. vclock_0th_component_note_start
236+
235237
.. NOTE::
236238

237239
Note that a ``vclock`` value might include the 0-th component that is related to local space operations and might differ for different instances in a replica set.
238240

241+
.. vclock_0th_component_note_end
242+
239243
240244
241245
.. _replication-add_instances:

doc/how-to/replication/repl_bootstrap_auto.rst

+3-3
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ To check that replicas (``instance001`` and ``instance003``) get all updates fro
270270
- {0: 1, 1: 32}
271271
...
272272
273-
.. NOTE::
274-
275-
The 0-th component of ``vclock`` is related to local space operations and might differ for different instances in a replica set.
273+
.. include:: /how-to/replication/repl_bootstrap.rst
274+
:start-after: vclock_0th_component_note_start
275+
:end-before: vclock_0th_component_note_end
276276

277277

278278

doc/how-to/replication/repl_bootstrap_master_master.rst

+310-9
Original file line numberDiff line numberDiff line change
@@ -207,9 +207,9 @@ Checking a replica set status
207207
name: instance001
208208
...
209209
210-
.. NOTE::
211-
212-
Note that a ``vclock`` value might include the 0-th component that is related to local space operations and might differ for different instances in a replica set.
210+
.. include:: /how-to/replication/repl_bootstrap.rst
211+
:start-after: vclock_0th_component_note_start
212+
:end-before: vclock_0th_component_note_end
213213

214214

215215

@@ -221,13 +221,41 @@ Adding data
221221

222222
To check that both instances get updates from each other, follow the steps below:
223223

224-
1. On ``instance001``, create a space and format it as described in :ref:`CRUD operation examples <box_space_examples>`. Add sample data to this space.
224+
1. On ``instance001``, create a space, format it, and create a primary index:
225+
226+
.. literalinclude:: /code_snippets/snippets/replication/instances.enabled/master_master/myapp.lua
227+
:start-at: box.schema.space.create
228+
:end-at: box.space.bands:create_index
229+
:language: lua
230+
:dedent:
231+
232+
Then, add sample data to this space:
233+
234+
.. literalinclude:: /code_snippets/snippets/replication/instances.enabled/master_master/myapp.lua
235+
:start-at: Roxette
236+
:end-at: Scorpions
237+
:language: lua
238+
:dedent:
239+
240+
2. On ``instance002``, use the ``select`` operation to make sure data is replicated:
241+
242+
.. code-block:: console
243+
244+
master_master:instance002> box.space.bands:select()
245+
---
246+
- - [1, 'Roxette', 1986]
247+
- [2, 'Scorpions', 1965]
248+
...
225249
226-
2. On ``instance002``, use the ``select`` operation to make sure data is replicated.
250+
3. Add more data to the created space on ``instance002``:
227251

228-
3. Add more data to the created space on ``instance002``.
252+
.. literalinclude:: /code_snippets/snippets/replication/instances.enabled/master_master/myapp.lua
253+
:start-at: Ace of Base
254+
:end-at: The Beatles
255+
:language: lua
256+
:dedent:
229257

230-
4. Get back to ``instance001`` and use ``select`` to make sure new data is replicated.
258+
4. Get back to ``instance001`` and use ``select`` to make sure new records are replicated.
231259

232260
5. Check that :ref:`box.info.vclock <box_introspection-box_info>` values are the same on both instances:
233261

@@ -237,7 +265,7 @@ To check that both instances get updates from each other, follow the steps below
237265
238266
master_master:instance001> box.info.vclock
239267
---
240-
- {2: 8, 1: 12}
268+
- {2: 5, 1: 9}
241269
...
242270
243271
- ``instance002``:
@@ -246,9 +274,282 @@ To check that both instances get updates from each other, follow the steps below
246274
247275
master_master:instance002> box.info.vclock
248276
---
249-
- {2: 8, 1: 12}
277+
- {2: 5, 1: 9}
278+
...
279+
280+
281+
282+
.. _replication-master-master-resolve-conflicts:
283+
284+
Resolving replication conflicts
285+
-------------------------------
286+
287+
.. NOTE::
288+
289+
To learn how to fix and prevent replication conflicts using trigger functions, see :ref:`Resolving replication conflicts <replication-problem_solving>`.
290+
291+
.. _replication-master-master_conflicting_records:
292+
293+
Inserting conflicting records
294+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295+
296+
To insert conflicting records to ``instance001`` and ``instance002``, follow the steps below:
297+
298+
1. Stop ``instance001`` using the ``tt stop`` command:
299+
300+
.. code-block:: console
301+
302+
$ tt stop master_master:instance001
303+
304+
2. On ``instance002``, insert a new record:
305+
306+
.. code-block:: lua
307+
308+
box.space.bands:insert { 5, 'incorrect data', 0 }
309+
310+
3. Stop ``instance002`` using ``tt stop``:
311+
312+
.. code-block:: console
313+
314+
$ tt stop master_master:instance002
315+
316+
4. Start ``instance001`` back:
317+
318+
.. code-block:: lua
319+
320+
$ tt start master_master:instance001
321+
322+
5. Connect to ``instance001`` and insert a record that should conflict with a record already inserted on ``instance002``:
323+
324+
.. literalinclude:: /code_snippets/snippets/replication/instances.enabled/master_master/myapp.lua
325+
:start-at: Pink Floyd
326+
:end-at: Pink Floyd
327+
:language: lua
328+
:dedent:
329+
330+
6. Start ``instance002`` back:
331+
332+
.. code-block:: console
333+
334+
$ tt start master_master:instance002
335+
336+
Then, check ``box.info.replication`` on ``instance001``.
337+
``upstream.status`` should be ``stopped`` because of the ``Duplicate key exists`` error:
338+
339+
.. code-block:: console
340+
341+
master_master:instance001> box.info.replication
342+
---
343+
- 1:
344+
id: 1
345+
uuid: 4cfa6e3c-625e-b027-00a7-29b2f2182f23
346+
lsn: 9
347+
upstream:
348+
peer: replicator@127.0.0.1:3302
349+
lag: 143.52251672745
350+
status: stopped
351+
idle: 3.9462469999999
352+
message: Duplicate key exists in unique index "primary" in space "bands" with
353+
old tuple - [5, "Pink Floyd", 1965] and new tuple - [5, "incorrect data", 0]
354+
name: instance002
355+
downstream:
356+
status: stopped
357+
message: 'unexpected EOF when reading from socket, called on fd 12, aka 127.0.0.1:3301,
358+
peer of 127.0.0.1:59258: Broken pipe'
359+
system_message: Broken pipe
360+
2:
361+
id: 2
362+
uuid: 9bb111c2-3ff5-36a7-00f4-2b9a573ea660
363+
lsn: 6
364+
name: instance001
365+
...
366+
367+
368+
.. _replication-master-master-reseed-replica:
369+
370+
Reseeding a replica
371+
~~~~~~~~~~~~~~~~~~~
372+
373+
To resolve a replication conflict, ``instance002`` should get the correct data from ``instance001`` first.
374+
To achieve this, ``instance002`` should be rebootstrapped:
375+
376+
1. In the ``config.yaml`` file, change ``database.mode`` of ``instance002`` to ``ro``:
377+
378+
.. code-block:: yaml
379+
380+
instance002:
381+
database:
382+
mode: ro
383+
384+
2. Reload configurations on both instances using the ``reload()`` function provided by the :ref:`config <config-module>` module:
385+
386+
- ``instance001``:
387+
388+
.. code-block:: console
389+
390+
master_master:instance001> require('config'):reload()
391+
---
392+
...
393+
394+
- ``instance002``:
395+
396+
.. code-block:: console
397+
398+
master_master:instance002> require('config'):reload()
399+
---
400+
...
401+
402+
3. Delete write-ahead logs and snapshots stored in the ``var/lib/instance002`` directory.
403+
404+
.. NOTE::
405+
406+
``var/lib`` is the default directory used by tt to store write-ahead logs and snapshots.
407+
Learn more from :ref:`Configuration <tt-config>`.
408+
409+
4. Restart ``instance002`` using the :ref:`tt restart <tt-restart>` command:
410+
411+
.. code-block:: console
412+
413+
$ tt restart master_master:instance002
414+
415+
5. Connect to ``instance002`` and make sure it received the correct data from ``instance001``:
416+
417+
.. code-block:: console
418+
419+
master_master:instance002> box.space.bands:select()
420+
---
421+
- - [1, 'Roxette', 1986]
422+
- [2, 'Scorpions', 1965]
423+
- [3, 'Ace of Base', 1987]
424+
- [4, 'The Beatles', 1960]
425+
- [5, 'Pink Floyd', 1965]
426+
...
427+
428+
429+
.. _replication-master-master-resolve-conflict:
430+
431+
Restarting replication
432+
~~~~~~~~~~~~~~~~~~~~~~
433+
434+
After :ref:`reseeding a replica <replication-master-master-reseed-replica>`, you need to resolve a replication conflict that keeps replication stopped:
435+
436+
1. Execute ``box.info.replication`` on ``instance001``.
437+
``upstream.status`` is still stopped:
438+
439+
.. code-block:: console
440+
441+
master_master:instance001> box.info.replication
442+
---
443+
- 1:
444+
id: 1
445+
uuid: 4cfa6e3c-625e-b027-00a7-29b2f2182f23
446+
lsn: 9
447+
upstream:
448+
peer: replicator@127.0.0.1:3302
449+
lag: 143.52251672745
450+
status: stopped
451+
idle: 1309.943383
452+
message: Duplicate key exists in unique index "primary" in space "bands" with
453+
old tuple - [5, "Pink Floyd", 1965] and new tuple - [5, "incorrect data",
454+
0]
455+
name: instance002
456+
downstream:
457+
status: follow
458+
idle: 0.47881799999959
459+
vclock: {2: 6, 1: 9}
460+
lag: 0
461+
2:
462+
id: 2
463+
uuid: 9bb111c2-3ff5-36a7-00f4-2b9a573ea660
464+
lsn: 6
465+
name: instance001
466+
...
467+
468+
469+
2. In the ``config.yaml`` file, clear the ``iproto`` option for ``instance001`` by setting its value to ``{}`` to disconnect this instance from ``instance002``.
470+
Set ``database.mode`` to ``ro``:
471+
472+
.. code-block:: yaml
473+
474+
instance001:
475+
database:
476+
mode: ro
477+
iproto: {}
478+
479+
3. Reload configuration on ``instance001`` only:
480+
481+
.. code-block:: console
482+
483+
master_master:instance001> require('config'):reload()
484+
---
485+
...
486+
487+
4. Change ``database.mode`` values back to ``rw`` for both instances and restore ``iproto.listen`` for ``instance001``:
488+
489+
.. literalinclude:: /code_snippets/snippets/replication/instances.enabled/master_master/config.yaml
490+
:language: yaml
491+
:start-at: instance001
492+
:end-at: listen: 127.0.0.1:3302
493+
:dedent:
494+
495+
5. Reload configurations on both instances one more time:
496+
497+
- ``instance001``:
498+
499+
.. code-block:: console
500+
501+
master_master:instance001> require('config'):reload()
502+
---
250503
...
251504
505+
- ``instance002``:
506+
507+
.. code-block:: console
508+
509+
master_master:instance002> require('config'):reload()
510+
---
511+
...
512+
513+
6. Check ``box.info.replication``.
514+
``upstream.status`` be ``follow`` now.
515+
516+
.. code-block:: console
517+
518+
master_master:instance001> box.info.replication
519+
---
520+
- 1:
521+
id: 1
522+
uuid: 4cfa6e3c-625e-b027-00a7-29b2f2182f23
523+
lsn: 9
524+
upstream:
525+
status: follow
526+
idle: 0.21281300000192
527+
peer: replicator@127.0.0.1:3302
528+
lag: 0.00031113624572754
529+
name: instance002
530+
downstream:
531+
status: follow
532+
idle: 0.035179000002245
533+
vclock: {2: 6, 1: 9}
534+
lag: 0
535+
2:
536+
id: 2
537+
uuid: 9bb111c2-3ff5-36a7-00f4-2b9a573ea660
538+
lsn: 6
539+
name: instance001
540+
...
541+
542+
543+
544+
.. _replication-master-master-add-remove-instances:
545+
546+
Adding and removing instances
547+
-----------------------------
252548

549+
The process of adding instances to a replica set and removing them is similar for all failover modes.
550+
Learn how to do this from the :ref:`Master-replica: manual failover <replication-bootstrap>` tutorial:
253551

552+
- :ref:`Adding instances <replication-add_instances>`
553+
- :ref:`Removing instances <replication-remove_instances>`
254554

555+
Before removing an instance from a replica set with :ref:`replication.failover <configuration_reference_replication_failover>` set to ``off``, make sure this instance is in read-only mode.

0 commit comments

Comments
 (0)