Dear wiki user, You have subscribed to a wiki page "Couchdb Wiki" for change notification.
The page "How_to_replicate_a_database" has been deleted by JoanTouzet: https://wiki.apache.org/couchdb/How_to_replicate_a_database?action=diff&rev1=13&rev2=14 Comment: See http://docs.couchdb.org/en/stable/replication/index.html - <<Include(EditTheWiki)>> - The documented way to do replication is available at this URL [[http://wiki.apache.org/couchdb/Frequently_asked_questions#how_replication|here]] - - == Expanded explanation == - - Fire up Futon and head over to the replication option. The URL is http://localhost:5984/_utils/replicator.html - - The replication option prompts you to either specify a CouchDB instance to push towards or a CouchDB instance to pull from. If the replication is not within the same CouchDB instance you will need to specific a URI. - The correct format for the URI is: http://<address>:<port>/<database name> - - ''remote database:'' http://192.168.197.132:5984/test_suite_db_b to ''local database:'' test_suite_db_b - - This will replicate the information at the remote database URI to the local database test_suite_db_b. - - It is important to specific the database name in the URL as Futon does not assume anything with respect to the source or destination database based upon the originating or destination database. - - == Operational Hints == - - Replication is one-way. In a multi-master scenario you have to issue one replication from A to B, and a separate one from B to A. - - Currently it seems that "pull" replication where you have a remote source and and a local target is much more reliable than "push" where you have it the other way around. - - == Playing with Replication == - - You may replicate between two databases in the same couchdb instance. - - However if you prefer a more realistic test, you can also set up two test couchdb instances on the same machine and replicate between them. Here is local1.ini: - - {{{ - ; Remember to create the directories: - ; mkdir -p /var/tmp/couchdb1/{data,log} - ; - ; Start using: - ; couchdb -n -a /usr/local/etc/couchdb/default.ini -a local1.ini - - [couchdb] - database_dir = /var/tmp/couchdb1/data - - [log] - file = /var/tmp/couchdb1/log/couch.log - - [httpd] - port = 5001 - }}} - - Similarly local2.ini: - - {{{ - ; Remember to create the directories: - ; mkdir -p /var/tmp/couchdb2/{data,log} - ; - ; Start using: - ; couchdb -n -a /usr/local/etc/couchdb/default.ini -a local2.ini - - [couchdb] - database_dir = /var/tmp/couchdb2/data - - [log] - file = /var/tmp/couchdb2/log/couch.log - - [httpd] - port = 5002 - }}} - - Test they are both running: - - {{{ - $ curl http://localhost:5001/ - {"couchdb":"Welcome","version":"0.9.0a738034-incubating"} - $ curl http://localhost:5002/ - {"couchdb":"Welcome","version":"0.9.0a738034-incubating"} - }}} - - === Create and replicate a document === - - {{{ - $ curl -X PUT http://localhost:5001/sampledb - {"ok":true} - $ curl -X PUT http://localhost:5002/sampledb - {"ok":true} - - $ curl -X PUT -d '{"hello":"world"}' http://localhost:5001/sampledb/doc1 - {"ok":true,"id":"doc1","rev":"3851869530"} - - $ curl -X POST -d '{"source":"http://127.0.0.1:5001/sampledb","target":"sampledb"}' \ - http://localhost:5002/_replicate - { - "ok":true, - "session_id":"7118d54c40761eba83454aabae8ea91b", - "source_last_seq":0, - "history": - [ - { - "start_time":"Wed, 28 Jan 2009 16:26:09 GMT", - "end_time":"Wed, 28 Jan 2009 16:26:09 GMT", - "start_last_seq":0, - "end_last_seq":1, - "missing_checked":1, - "missing_found":1, - "docs_read":1, - "docs_written":1 - } - ] - } - }}} - - ''POST response has been reformatted for clarity'' - - {{{ - $ curl http://127.0.0.1:5001/sampledb/doc1 - {"_id":"doc1","_rev":"3851869530","hello":"world"} - $ curl http://127.0.0.1:5002/sampledb/doc1 - {"_id":"doc1","_rev":"3851869530","hello":"world"} - }}} - - === Introduce conflicting updates === - - ''Note: the updates have to be made on separate databases. Update conflicts can't occur within a single database; because you provide the original _rev, if someone else has already changed the document, the second update is rejected.'' - - {{{ - $ curl -X PUT -d '{"_rev":"3851869530","hello":"fred"}' http://localhost:5001/sampledb/doc1 - {"ok":true,"id":"doc1","rev":"132006080"} - $ curl -X PUT -d '{"_rev":"3851869530","hello":"jim"}' http://localhost:5002/sampledb/doc1 - {"ok":true,"id":"doc1","rev":"2575525432"} - - $ curl -X POST -d '{"source":"http://127.0.0.1:5001/sampledb","target":"sampledb"}' \ - http://localhost:5002/_replicate - {"ok":true,"session_id":"fe1ec1c66b0b916e7e87dd635b4dc572","source_last_seq":0,"history": - [{"start_time":"Wed, 28 Jan 2009 16:28:36 GMT","end_time":"Wed, 28 Jan 2009 16:28:36 GMT", - "start_last_seq":0,"end_last_seq":2,"missing_checked":1,"missing_found":1,"docs_read":1,"docs_written":1}]} - - $ curl http://127.0.0.1:5001/sampledb/doc1 - {"_id":"doc1","_rev":"132006080","hello":"fred"} - $ curl http://127.0.0.1:5002/sampledb/doc1 - {"_id":"doc1","_rev":"2575525432","hello":"jim"} - }}} - - At this point you can see the two databases still have different ideas about this document. You need to replicate back the other way as well: - - {{{ - $ curl -X POST -d '{"target":"http://127.0.0.1:5001/sampledb","source":"sampledb"}' \ - http://localhost:5002/_replicate - - {"ok":true,"session_id":"da0a07a0f9c9fb5c2d2e2769229257df","source_last_seq":0,"history": - [{"start_time":"Wed, 28 Jan 2009 16:30:23 GMT","end_time":"Wed, 28 Jan 2009 16:30:23 GMT", - "start_last_seq":0,"end_last_seq":3,"missing_checked":2,"missing_found":1,"docs_read":1,"docs_written":1}]} - - $ curl http://127.0.0.1:5001/sampledb/doc1?revs=true - {"_id":"doc1","_rev":"2575525432","hello":"jim","_revs":["2575525432","3851869530"]} - 3$ curl http://127.0.0.1:5002/sampledb/doc1?revs=true - {"_id":"doc1","_rev":"2575525432","hello":"jim","_revs":["2575525432","3851869530"]} - }}} - - The two machines now agree on one document and revision history, but the conflict (and conflicting version) is not shown. You have to ask for this explicitly with ''conflicts=true'' - - {{{ - $ curl http://127.0.0.1:5001/sampledb/doc1?conflicts=true - {"_id":"doc1","_rev":"2575525432","hello":"jim","_conflicts":["132006080"]} - $ curl http://127.0.0.1:5002/sampledb/doc1?conflicts=true - {"_id":"doc1","_rev":"2575525432","hello":"jim","_conflicts":["132006080"]} - }}} - - === Compaction === - - The conflict status, and the conflicting versions, remain even after compaction. However the very original version, which was not in conflict, does not. - - {{{ - $ curl -X POST http://localhost:5001/sampledb/_compact - {"ok":true} - $ curl -X POST http://localhost:5002/sampledb/_compact - {"ok":true} - $ curl http://127.0.0.1:5001/sampledb/doc1?conflicts=true - {"_id":"doc1","_rev":"2575525432","hello":"jim","_conflicts":["132006080"]} - $ curl http://127.0.0.1:5001/sampledb/doc1?rev=132006080 - {"_id":"doc1","_rev":"132006080","hello":"fred"} - $ curl http://127.0.0.1:5001/sampledb/doc1?rev=2575525432 - {"_id":"doc1","_rev":"2575525432","hello":"jim"} - $ curl http://127.0.0.1:5001/sampledb/doc1?rev=3851869530 - {"error":"{not_found,missing}","reason":"3851869530"} - }}} - - === Conflict Resolution === - - All nodes see the same conflict state and history, so any of them can resolve the conflict. - - Nodes can continue to add new versions, but conflict remains: - - {{{ - $ curl -X PUT -d '{"_rev":"2575525432","hello":"resolved"}' http://localhost:5001/sampledb/doc1 - {"ok":true,"id":"doc1","rev":"923422654"} - $ curl http://127.0.0.1:5001/sampledb/doc1?conflicts=true - {"_id":"doc1","_rev":"923422654","hello":"resolved","_conflicts":["132006080"]} - }}} - - Once the application is satisfied that it has resolved the conflict, it simply has to DELETE the conflicting revision. Couch actually keeps a separate list of deleted conflict revisions that you can view with "deleted_conflicts=true" - - {{{ - $ curl -X DELETE http://127.0.0.1:5001/sampledb/doc1?rev=132006080 - {"ok":true,"id":"doc1","rev":"3699698383"} - $ curl http://127.0.0.1:5001/sampledb/doc1?conflicts=true - {"_id":"doc1","_rev":"804871722","hello":"resolved"} - $ curl http://127.0.0.1:5001/sampledb/doc1?deleted_conflicts=true - {"_id":"doc1","_rev":"804871722","hello":"resolved","_deleted_conflicts":["3699698383"]} - }}} - - === Sample shell script === - - Running this script gives an easy way to set up a replication conflict so you can examine it and resolve it. - - {{{ - #!/bin/sh - set -xe - - HOST1=http://localhost:5001 - HOST2=http://localhost:5002 - LOCAL1=sampledb - LOCAL2=sampledb - DB1="$HOST1/$LOCAL1" - DB2="$HOST2/$LOCAL2" - - curl -X DELETE "$DB1" - curl -X DELETE "$DB2" - curl -X PUT "$DB1" - curl -X PUT "$DB2" - - resp=`curl -sX PUT -d "{\"hello\":\"world\"}" "${DB1}/doc1"` - echo "$resp" - rev=`expr "$resp" : '.*"rev":"\([^"]*\)"'` - - # Replicate - curl -X POST -d "{\"source\":\"$DB1\",\"target\":\"$LOCAL2\"}" "$HOST2/_replicate" - curl -s "$DB1/doc1" | grep world - curl -s "$DB2/doc1" | grep world - - # Now make conflicting changes - curl -sX PUT -d "{\"_rev\":\"$rev\",\"hello\":\"fred\"}" "${DB1}/doc1" - curl -sX PUT -d "{\"_rev\":\"$rev\",\"hello\":\"jim\"}" "${DB2}/doc1" - curl -s "$DB1/doc1" | grep fred - curl -s "$DB2/doc1" | grep jim - - # Replicate again, A->B. Conflict seen on B side only. - curl -X POST -d "{\"source\":\"$DB1\",\"target\":\"$LOCAL2\"}" "$HOST2/_replicate" - echo "*** On first DB ***" - curl -s "$DB1/doc1?conflicts=true" - echo "*** On second DB ***" - curl -s "$DB2/doc1?conflicts=true" - - # Replicate again, B->A. Identical conflict on both sides. - curl -X POST -d "{\"target\":\"$DB1\",\"source\":\"$LOCAL2\"}" "$HOST2/_replicate" - echo "*** On first DB ***" - curl -s "$DB1/doc1?conflicts=true" - echo "*** On second DB ***" - curl -s "$DB2/doc1?conflicts=true" - }}} - - === Further reading === - - * [[http://blogs.23.nu/c0re/2009/12/running-a-couchdb-cluster-on-amazon-ec2/|Running a CouchDB cluster on Amazon EC2]] explains how to do password protected Replication over the Internet. - * [[http://code.google.com/p/couchdb-python/source/browse/couchdb/tools/manual_replication.py| manual_replication]] is a script to trigger various replication scenarios. -