База данных репликатора
Изменено в версии 2.1.0: Добавлен планировщик репликации. Состояния репликации по умолчанию больше не записываются обратно в документы. Добавлены новые состояния заданий репликации и новые конечные точки API _scheduler/jobs и _scheduler/docs.
Изменено в версии 3.2.0: Добавлено планирование со справедливым распределением ресурсов. Несколько баз данных _replicator получают равные (настраиваемые) шансы на выполнение своих заданий. Ранее задания репликации планировались без учёта исходной базы данных.
Изменено в версии 3.3.0: Добавлен параметр репликатора winning_revs_only: true для репликации победивших ревизий документов.
База данных _replicator работает в CouchDB так же, как любая другая, но добавление в неё документов запускает репликацию. Создайте (PUT или POST) документ, чтобы начать репликацию. DELETE документ репликации, чтобы отменить выполняющуюся репликацию.
Эти документы имеют точно такое же содержимое, как объекты JSON, которые ранее использовались для POST в _replicate (поля source, target, create_target, create_target_params, continuous, doc_ids, filter, query_params, use_checkpoints, checkpoint_interval).
Документам репликации можно задать пользовательское значение _id (это удобно, чтобы позднее найти определённый запрос на репликацию). Документы дизайна (и документы _local), добавленные в базу данных репликатора, игнорируются.
База данных репликатора по умолчанию — _replicator. Можно создавать дополнительные базы данных репликатора. Чтобы система распознала их как таковые, их имена должны оканчиваться на /_replicator.
Основы
Предположим, что вы отправили POST-запрос со следующим документом в _replicator:
{
"_id": "my_rep",
"source": "http://user:password@myserver.com/foo",
"target": {
"url": "http://localhost:5984/bar",
"auth": {
"basic": {
"username": "adm",
"password": "pass"
}
}
},
"create_target": true,
"continuous": true
} В журнале CouchDB появятся две записи, похожие на следующие:
[notice] 2017-04-05T17:16:19.646716Z node1@127.0.0.1 <0.29432.0> -------- Replication `"a81a78e822837e66df423d54279c15fe+continuous+create_target"` is using:
4 worker processes
a worker batch size of 500
20 HTTP connections
a connection timeout of 30000 milliseconds
10 retries per request
socket options are: [{keepalive,true},{nodelay,false}]
[notice] 2017-04-05T17:16:19.646759Z node1@127.0.0.1 <0.29432.0> -------- Document `my_rep` triggered replication `a81a78e822837e66df423d54279c15fe+continuous+create_target` Затем состояние репликации этого документа можно запросить из http://adm:pass@localhost:5984/_scheduler/docs/_replicator/my_rep
{
"database": "_replicator",
"doc_id": "my_rep",
"error_count": 0,
"id": "a81a78e822837e66df423d54279c15fe+continuous+create_target",
"info": {
"revisions_checked": 113,
"missing_revisions_found": 113,
"docs_read": 113,
"docs_written": 113,
"changes_pending": 0,
"doc_write_failures": 0,
"checkpointed_source_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ",
"source_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ",
"through_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ"
},
"last_updated": "2017-04-05T19:18:15Z",
"node": "node1@127.0.0.1",
"source_proxy": null,
"target_proxy": null,
"source": "http://myserver.com/foo/",
"start_time": "2017-04-05T19:18:15Z",
"state": "running",
"target": "http://localhost:5984/bar/"
} Состояние — running. Это означает, что репликатор запланировал выполнение этого задания репликации. Содержимое документа репликации не меняется. Ранее, до версии 2.1, оно обновлялось и указывало состояние triggered.
Задание репликации также появится в
http://adm:pass@localhost:5984/_scheduler/jobs
{
"jobs": [
{
"database": "_replicator",
"doc_id": "my_rep",
"history": [
{
"timestamp": "2017-04-05T19:18:15Z",
"type": "started"
},
{
"timestamp": "2017-04-05T19:18:15Z",
"type": "added"
}
],
"id": "a81a78e822837e66df423d54279c15fe+continuous+create_target",
"info": {
"changes_pending": 0,
"checkpointed_source_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ",
"doc_write_failures": 0,
"docs_read": 113,
"docs_written": 113,
"missing_revisions_found": 113,
"revisions_checked": 113,
"source_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ",
"through_seq": "113-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE01ygQLsZsYGqcamiZjKcRqRxwIkGRqA1H-oSbZgk1KMLCzTDE0wdWUBAF6HJIQ"
},
"node": "node1@127.0.0.1",
"pid": "<0.1174.0>",
"source": "http://myserver.com/foo/",
"start_time": "2017-04-05T19:18:15Z",
"target": "http://localhost:5984/bar/",
"user": null
}
],
"offset": 0,
"total_rows": 1
} _scheduler/jobs содержит больше сведений, например подробную историю изменений состояния. Если постоянная репликация ещё не началась, завершилась с ошибкой или выполнена, информацию о её состоянии можно найти только в _scheduler/docs. Помните, что некоторые документы репликации могут быть недействительными и не стать заданиями репликации. Выполнение других может задержаться из-за получения данных из медленной исходной базы данных.
При возникновении ошибки, например если исходная база данных отсутствует, задание репликации завершится сбоем и будет повторено после периода ожидания. После каждого последующего сбоя период ожидания будет увеличиваться.
Например, отправка POST-запроса с этим документом
{
"_id": "my_rep_crashing",
"source": "http://user:password@myserver.com/missing",
"target": {
"url": "http://localhost:5984/bar",
"auth": {
"basic": {
"username": "adm",
"password": "pass"
}
}
},
"create_target": true,
"continuous": true
} при отсутствии исходной базы данных приведёт к периодическим запускам и сбоям с постоянно увеличивающимся интервалом. Список history для этой репликации из _scheduler/jobs будет выглядеть примерно так:
[
{
"reason": "db_not_found: could not open http://adm:*****@localhost:5984/missing/",
"timestamp": "2017-04-05T20:55:10Z",
"type": "crashed"
},
{
"timestamp": "2017-04-05T20:55:10Z",
"type": "started"
},
{
"reason": "db_not_found: could not open http://adm:*****@localhost:5984/missing/",
"timestamp": "2017-04-05T20:47:10Z",
"type": "crashed"
},
{
"timestamp": "2017-04-05T20:47:10Z",
"type": "started"
}
] В _scheduler/docs приводится более краткая сводка:
{
"database": "_replicator",
"doc_id": "my_rep_crashing",
"error_count": 6,
"id": "cb78391640ed34e9578e638d9bb00e44+create_target",
"info": {
"error": "db_not_found: could not open http://myserver.com/missing/"
},
"last_updated": "2017-04-05T20:55:10Z",
"node": "node1@127.0.0.1",
"source_proxy": null,
"target_proxy": null,
"source": "http://myserver.com/missing/",
"start_time": "2017-04-05T20:38:34Z",
"state": "crashing",
"target": "http://localhost:5984/bar/"
} Повторяющиеся сбои обозначаются состоянием crashing. Суффикс -ing указывает, что это временное состояние. Пользователь может в любой момент создать отсутствующую базу данных, после чего задание репликации сможет вернуться к нормальной работе.
Документы, описывающие одну и ту же репликацию
Предположим, что в базу данных _replicator добавлены два документа в следующем порядке:
{
"_id": "my_rep",
"source": "http://user:password@myserver.com/foo",
"target": "http://adm:pass@localhost:5984/bar",
"create_target": true,
"continuous": true
} и
{
"_id": "my_rep_dup",
"source": "http://user:password@myserver.com/foo",
"target": "http://adm:pass@localhost:5984/bar",
"create_target": true,
"continuous": true
} Оба описывают одну и ту же репликацию (различаются только их _ids). В этом случае документ my_rep запускает репликацию, а my_rep_dup` завершится с ошибкой. Изучив _scheduler/docs, можно точно понять причину ошибки:
{
"database": "_replicator",
"doc_id": "my_rep_dup",
"error_count": 1,
"id": null,
"info": {
"error": "Replication `a81a78e822837e66df423d54279c15fe+continuous+create_target` specified by document `my_rep_dup` already started, triggered by document `my_rep` from db `_replicator`"
},
"last_updated": "2017-04-05T21:41:51Z",
"source": "http://myserver.com/foo/",
"start_time": "2017-04-05T21:41:51Z",
"state": "failed",
"target": "http://user:****@localhost:5984/bar",
} Обратите внимание, что состояние этой репликации — failed. В отличие от crashing, состояние failed является конечным. Пока присутствуют оба документа, репликатор не будет повторно запускать репликацию my_rep_dup. Ещё одной причиной могут быть некорректно сформированные документы. Например, если количество рабочих процессов задано строкой ("worker_processes": "a
few"), а не целым числом, произойдёт сбой.
Планировщик репликации
После создания заданиями репликации управляет планировщик. Планировщик — это компонент репликации, который периодически останавливает одни задания и запускает другие. Благодаря этому количество заданий может превышать число тех, которые кластер способен выполнять одновременно. Для заданий репликации, которые продолжают завершаться с ошибкой, вводятся штрафы и ожидание. Время ожидания экспоненциально увеличивается с каждым последующим сбоем.
Решая, какие задания остановить, а какие запустить, планировщик использует алгоритм циклического перебора, обеспечивающий справедливость. Останавливаются задания, которые выполняются дольше всего, а запускаются те, которые ожидают дольше всего.
Примечание
К обычной (не непрерывной) репликации после начала выполнения применяется особая обработка. Подробнее см. раздел Обычная и непрерывная репликация.
Поведение планировщика можно настроить с помощью параметров max_jobs, interval и max_churn. Дополнительные сведения см. в разделе Конфигурация репликатора.
Состояния репликации
В течение жизненного цикла задания репликации проходят через различные состояния. На этой диаграмме показаны все состояния и переходы между ними:
Диаграмма состояний репликации
Синие и жёлтые фигуры обозначают состояния задания репликации.
Трапециевидные фигуры обозначают внешние API — именно с их помощью пользователи взаимодействуют с репликатором. Предпочтительный способ создания репликаций — запись документов в _replicator, однако также поддерживается отправка запросов к конечной точке HTTP _replicate.
Шестиугольники обозначают границы внутренних API. Для этой диаграммы они необязательны и показаны только для большей наглядности работы репликатора. Обработка проходит в два этапа: на первом документы репликации разбираются и преобразуются в задания репликации, а на втором работает сам планировщик. Планировщик запускает задания репликации, периодически останавливая и запуская некоторые из них. Задания, отправленные через конечную точку _replicate, минуют первый компонент и сразу поступают планировщику.
Описание состояний
Прежде чем разбирать каждое состояние, обратите внимание на цвет и форму состояний на диаграмме:
Синий и жёлтый цвета разделяют состояния на «нормальные» и «проблемные» соответственно. Проблемные состояния указывают на возникшую неполадку, которая может потребовать внимания пользователя.
Прямоугольник и овал разделяют состояния на «конечные» и «неконечные». Конечные состояния — это состояния, из которых больше нельзя перейти в другие. Проще говоря, задания в конечном состоянии не будут запущены повторно и не потребляют ресурсы памяти или процессора.
Initializing: означает, что репликатор обнаружил изменение документа репликации. Задания должны быстро пройти через это состояние. Если задание надолго застряло в этом состоянии, это может свидетельствовать о внутренней ошибке.
Failed: документ репликации не удалось обработать и преобразовать в допустимое задание для планировщика. Это конечное состояние, и для устранения проблемы требуется вмешательство пользователя. Типичная причина перехода в это состояние — некорректно сформированный документ. Например, для параметра, принимающего логическое значение, указано целое число. Другой причиной сбоя может быть указание дублирующей репликации. Дублирующая репликация — это репликация с теми же параметрами, но с другим идентификатором документа.
Error: обновлённый документ репликации не удалось преобразовать в задание репликации. В отличие от состоянияFailed, это состояние временное, и репликатор будет периодически повторять попытки. При последовательных сбоях применяется экспоненциальная задержка. Это состояние существует главным образом для обработки отфильтрованных репликаций с пользовательскими функциями. Для вычисления идентификатора репликации необходимо содержимое функции фильтра. Задание репликации нельзя создать, пока не будет получен код функции. Поскольку получение происходит по сети, необходимо обрабатывать временные сбои.
Running: задание репликации выполняется штатно. Это означает, что может быть открыт канал изменений и все обнаруженные изменения будут обработаны и отправлены в целевую базу данных. Задание по-прежнему считаетсяRunning, даже если его рабочие процессы в данный момент не передают изменения из источника в целевую базу данных, а просто ожидают их в канале изменений. Непрерывная репликация, скорее всего, перейдёт в это состояние.
Pending: задание репликации не выполняется и ожидает своей очереди. Это состояние достигается, когда число заданий репликации, добавленных в планировщик, превышаетreplicator.max_jobs. В этом случае планировщик будет периодически останавливать и запускать группы заданий, стараясь предоставить каждому из них справедливую возможность продвинуться.
Crashing: задание репликации успешно добавлено в планировщик репликации. Однако при последнем запуске произошла ошибка. Это может быть сбой сети, отсутствие исходной базы данных, ошибка прав доступа и т. д. Последовательные сбои приводят к экспоненциальному увеличению времени ожидания. Это состояние считается временным (неконечным), и задания репликации будут периодически запускаться повторно.
Completed: конечное состояние успешного завершения обычной репликации. В этом состоянии планировщик «забывает» о репликации, и она больше не потребляет ресурсы процессора и памяти. Задания непрерывной репликации никогда не переходят в это состояние.
Примечание
Максимальный интервал задержки для состояний Error и Crashing вычисляется на основе параметра replicator.max_history. Дополнительные сведения см. в разделе Конфигурация репликатора.
Обычная и непрерывная репликация
Обычной (непрерывной) репликации после запуска будет позволено выполниться до конца. Такое поведение необходимо для сохранения её семантики: реплицируется снимок исходной базы данных в целевую. Например, если после начала репликации в исходную базу данных добавляются новые документы, эти изменения не должны появиться в целевой базе данных. Остановка и повторный запуск обычной репликации нарушили бы это условие.
Предупреждение
Если одновременно выполняются непрерывные и обычные репликации, запланированные обычные репликации могут временно лишить заданий непрерывной репликации ресурсов.
Тем не менее обычные репликации будут остановлены и запланированы повторно, если оператор уменьшит максимальное число репликаций. Это позволяет оператору восстановить работу узла, если репликации создают на нём чрезмерную нагрузку. Все остановленные репликации будут повторно помещены в очередь для планирования.
Режим совместимости
Предыдущие версии репликатора CouchDB записывали обновления состояния обратно в документы репликации. Для совместимости с пользовательским кодом, который программно считывал эти состояния, предусмотрен режим совместимости, включаемый параметром конфигурации:
[replicator] update_docs = true
В этом режиме репликатор продолжит записывать обновления состояния в документы.
Чтобы фактически отключить планирование, при котором задания периодически останавливаются и запускаются, задайте для параметра конфигурации max_jobs большое значение. Например:
[replicator] max_jobs = 9999999
Другие параметры конфигурации репликатора см. в разделе Конфигурация репликатора.
Отмена репликации
Чтобы отменить репликацию, просто DELETE документ, который её запустил. Чтобы изменить репликацию, например поменять число рабочих процессов или источник, обновите документ, указав новые данные. Репликатор игнорирует дополнительные данные в документах репликации, относящиеся к конкретному приложению.
Перезапуск сервера
При перезапуске CouchDB проверяет базы данных _replicator и перезапускает репликации, описанные в документах, если они ещё не находятся в состоянии completed или failed. Если находятся, они игнорируются.
Кластеризация
В кластере задания репликации равномерно распределяются между всеми узлами, так что в каждый момент времени задание репликации выполняется только на одном узле.
При каждом изменении состава кластера — например, при добавлении или удалении узлов во время последовательной перезагрузки — приложение репликатора обнаруживает это изменение, повторно сканирует все документы и выполняющиеся репликации и пересматривает их размещение в кластере с учётом нового набора активных узлов. Этот механизм также обеспечивает переключение репликации на другой узел в случае сбоя. Задания репликации, запущенные с помощью документов репликации (но не через конечную точку HTTP _replicate), автоматически перемещаются на один из активных узлов.
Дополнительные базы данных репликатора
Предположим, что в базе данных репликатора (_replicator) есть два следующих документа, описывающих репликацию с серверов A и B:
{
"_id": "rep_from_A",
"source": "http://user:password@aserver.com:5984/foo",
"target": {
"url": "http://localhost:5984/foo_a",
"auth": {
"basic": {
"username": "adm",
"password": "pass"
}
}
},
"continuous": true
} {
"_id": "rep_from_B",
"source": "http://user:password@bserver.com:5984/foo",
"target": {
"url": "http://localhost:5984/foo_b",
"auth": {
"basic": {
"username": "adm",
"password": "pass"
}
}
},
"continuous": true
} Теперь, не останавливая и не перезапуская CouchDB, добавьте ещё одну базу данных репликатора. Например, another/_replicator:
$ curl -X PUT http://adm:pass@localhost:5984/another%2F_replicator/
{"ok":true} Примечание
При использовании символа / (%2F) в имени базы данных в URL его необходимо экранировать.
Затем добавьте документ репликации в новую базу данных репликатора:
{
"_id": "rep_from_X",
"source": "http://user:password@xserver.com:5984/foo",
"target": "http://adm:pass@localhost:5984/foo_x",
"continuous": true
} Теперь в системе активны три репликации: две репликации с серверов A и B и новая — с сервера X.
Затем удалите дополнительную базу данных репликатора:
$ curl -X DELETE http://adm:pass@localhost:5984/another%2F_replicator/
{"ok":true} После этой операции репликация с сервера X будет остановлена, а репликации в базе данных _replicator (с серверов A и B) продолжатся.
Репликация базы данных репликатора
Предположим, что на сервере C есть база данных репликатора со следующими двумя документами, описывающими репликацию с источника:
{
"_id": "rep_from_A",
"source": "http://user:password@aserver.com:5984/foo",
"target": "http://adm:pass@localhost:5984/foo_a",
"continuous": true
} {
"_id": "rep_from_B",
"source": "http://user:password@bserver.com:5984/foo",
"target": "http://adm:pass@localhost:5984/foo_b",
"continuous": true
} Теперь необходимо запустить такую же репликацию с источника на сервере D, то есть сервер D должен получать реплики с серверов A и B. Есть два варианта:
Явно добавить два документа в базу данных репликатора сервера D
Реплицировать базу данных репликатора сервера C в базу данных репликатора сервера D
Оба варианта дают один и тот же результат.
Делегирование
Документам репликации можно задать пользовательское свойство user_ctx. Это свойство определяет контекст пользователя, от имени которого выполняется репликация. При использовании старого способа запуска репликации (отправки POST-запроса в /_replicate/) это свойство не требуется. В этом случае информация об аутентифицированном пользователе доступна непосредственно во время репликации, которая не является постоянной. При использовании базы данных репликатора проблема состоит в том, что информация о пользователе, запускающем конкретную репликацию, доступна только в момент записи документа репликации. Однако сведения в документе репликации и сама репликация сохраняются. Из этой особенности реализации следует, что для пользователя, не являющегося администратором, в документе репликации необходимо определить свойство user_ctx, содержащее имя пользователя и часть его ролей. Это требование обеспечивается функцией проверки обновления документов, которая находится в документе дизайна базы данных репликатора по умолчанию. Функция проверки также гарантирует, что пользователи без прав администратора не смогут задать для свойства name контекста пользователя значение, отличное от собственного имени. То же правило применяется к ролям.
Для администраторов свойство user_ctx необязательно. Если оно отсутствует, используется контекст пользователя с именем null и пустым списком ролей, а это означает, что документы дизайна не будут записываться в локальные целевые базы данных. Чтобы разрешить запись документов дизайна в локальные целевые базы данных, в список ролей контекста пользователя необходимо включить роль _admin.
Администраторы также могут использовать свойство user_ctx, чтобы запустить репликацию от имени другого пользователя. Этот контекст пользователя будет передан функциям проверки документов локальной целевой базы данных.
Примечание
Свойство user_ctx действует только для локальных конечных точек.
Пример документа делегированной репликации:
{
"_id": "my_rep",
"source": "http://user:password@bserver.com:5984/foo",
"target": "http://adm:pass@localhost:5984/bar",
"continuous": true,
"user_ctx": {
"name": "joe",
"roles": ["erlanger", "researcher"]
}
} Как упоминалось ранее, свойство user_ctx необязательно для администраторов, но обязательно для обычных пользователей (не администраторов). Если свойство roles в user_ctx отсутствует, по умолчанию используется пустой список [].
Объекты селектора
Добавив объект селектора в документ репликации, вы сможете использовать выражение запроса, чтобы определить, следует ли включать документ в репликацию.
Селектор указывает поля документа и задаёт выражение для вычисления с учётом содержимого полей или других данных. Если результатом выражения является true, документ реплицируется.
Объект селектора должен:
иметь структуру допустимого JSON;
содержать допустимое выражение запроса.
Синтаксис селектора совпадает с синтаксисом селекторов, используемым для _find.
Использование селектора значительно эффективнее функции фильтрации на JavaScript и рекомендуется, если фильтрация выполняется только по атрибутам документа.
Указание имён пользователей и паролей
Есть несколько способов указать имена пользователей и пароли для конечных точек репликации:
В объекте
{"auth": {"basic": ...}}:Добавлено в версии 3.2.0.
{ "target": { "url": "http://someurl.com/mydb", "auth": { "basic": { "username": "$username", "password": "$password" } } }, ... }Это предпочтительный формат, поскольку он позволяет включать в поля имени пользователя и пароля такие символы, как
@,:и другие.В части userinfo URL конечной точки. Такой способ позволяет сделать представление конечной точки более компактным, но не позволяет использовать в именах пользователей или паролях такие символы, как
@и::{ "target": "http://adm:pass@localhost:5984/bar" ... }Согласно RFC3986, указание учётных данных в части userinfo URL считается устаревшим. CouchDB по-прежнему поддерживает этот способ указания учётных данных, и пока нет целевого выпуска, в котором эта поддержка будет удалена.
В заголовке
"Authorization: Basic $b64encoded_username_and_password":{ "target": { "url": "http://someurl.com/mydb", "headers": { "Authorization": "Basic dXNlcjpwYXNz" } }, ... }Недостаток этого способа заключается в необходимости дополнительного шага — кодирования Base64. Кроме того, может сложиться впечатление, что этот способ шифрует или скрывает учётные данные, что может привести к их случайной передаче или утечке.
Если учётные данные указаны несколькими способами, они выбираются в следующем порядке:
объект
"auth": {"basic": {...}}userinfo URL
заголовок
"Authorization: Basic ...".
Сначала проверяется объект auth, и если в нём указаны учётные данные, используются они. Если нет, проверяется userinfo URL. Если там найдены учётные данные, используются они; в противном случае используется заголовок базовой аутентификации.
Репликация только победивших ревизий
Используйте параметр winning_revs_only: true, чтобы реплицировать только «победившие» ревизии документов. По умолчанию именно эти ревизии возвращаются конечной точкой API GET
db/doc или отображаются в ленте _changes с параметрами по умолчанию.
POST http://couchdb:5984/_replicate HTTP/1.1
Accept: application/json
Content-Type: application/json
{
"winning_revs_only" : true
"source" : "http://source:5984/recipes",
"target" : "http://target:5984/recipes",
} При таком режиме репликации конфликтующие ревизии отбрасываются, поэтому с его помощью можно устранять конфликты посредством репликации.
Идентификаторы репликации и контрольных точек, созданные репликациями winning_revs_only: true, будут отличаться от идентификаторов, создаваемых по умолчанию. Поэтому сначала можно реплицировать победившие ревизии, а позднее — «добавить» остальные ревизии с помощью обычного задания репликации.
Параметр winning_revs_only: true можно сочетать с фильтрами и другими параметрами, например continuous: true или create_target: true.
Copyright © 2025 The Apache Software Foundation — Licensed under the Apache License 2.0
https://docs.couchdb.org/en/3.5.1/replication/replicator.html