You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ja...@apache.org on 2012/12/06 12:34:41 UTC
[34/50] [abbrv] import Couchbase docs
http://git-wip-us.apache.org/repos/asf/couchdb/blob/fd643691/share/docs/couchdb-release-1.1/couchdb-release-1.1-ready.xml
----------------------------------------------------------------------
diff --git a/share/docs/couchdb-release-1.1/couchdb-release-1.1-ready.xml b/share/docs/couchdb-release-1.1/couchdb-release-1.1-ready.xml
new file mode 100644
index 0000000..208b978
--- /dev/null
+++ b/share/docs/couchdb-release-1.1/couchdb-release-1.1-ready.xml
@@ -0,0 +1,1154 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<article id="couchdb-release-1.1">
+
+ <title>CouchDB Release 1.1 Feature Guide</title>
+
+ <articleinfo>
+
+ <abstract>
+
+ <para>
+ This document provides details on the new features introduced in
+ the CouchDB 1.1 release from the CouchDB 1.0.x release series.
+ </para>
+
+ <para xml:base="../common/docbuilddate.xml">
+ <emphasis>Last document update</emphasis>: 25 Jan 2012 14:44;
+ <emphasis>Document built</emphasis>: 21 Feb 2012 20:8.
+</para>
+
+ </abstract>
+
+ </articleinfo>
+
+ <section id="couchdb-release-1.1-upgrading">
+
+ <title>Upgrading to CouchDB 1.1</title>
+
+ <para>
+ You can upgrade your existing CouchDB 1.0.x installation to
+ CouchDB 1.1 without any specific steps or migration. When you run
+ CouchDB 1.1 the existing data and index files will be opened and
+ used as normal.
+ </para>
+
+ <para>
+ The first time you run a compaction routine on your database
+ within CouchDB 1.1, the data structure and indexes will be updated
+ to the new version of the CouchDB database format that can only be
+ read by CouchDB 1.1 and later. This step is not reversable. Once
+ the data files have been updated and migrated to the new version
+ the data files will no longer work with a CouchDB 1.0.x release.
+ </para>
+
+ <warning>
+ <para>
+ If you want to retain support for openein gthe data files in
+ CouchDB 1.0.x you must back up your data files before performing
+ the upgrade and compaction process.
+ </para>
+ </warning>
+
+ </section>
+
+ <section id="couchb-release-1.1-replicatordb">
+
+ <title>Replicator Database</title>
+
+ <para>
+ A database where you
+ <literal>PUT</literal>/<literal>POST</literal> documents to
+ trigger replications and you <literal>DELETE</literal> to cancel
+ ongoing replications. These documents have exactly the same
+ content as the JSON objects we used to <literal>POST</literal> to
+ <literal>_replicate</literal> (fields <literal>source</literal>,
+ <literal>target</literal>, <literal>create_target</literal>,
+ <literal>continuous</literal>, <literal>doc_ids</literal>,
+ <literal>filter</literal>, <literal>query_params</literal>.
+ </para>
+
+ <para>
+ Replication documents can have a user defined
+ <literal>_id</literal>. Design documents (and
+ <literal>_local</literal> documents) added to the replicator
+ database are ignored.
+ </para>
+
+ <para>
+ The default name of this database is
+ <literal>_replicator</literal>. The name can be changed in the
+ <filename>local.ini</filename> configuration, section
+ <literal>[replicator]</literal>, parameter <literal>db</literal>.
+ </para>
+
+ <section id="couchdb-release-1.1-replicatordb-basics">
+
+ <title>Basics</title>
+
+ <para>
+ Let's say you PUT the following document into _replicator:
+ </para>
+
+<programlisting>{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true
+}</programlisting>
+
+ <para>
+ In the couch log you'll see 2 entries like these:
+ </para>
+
+<programlisting>[Thu, 17 Feb 2011 19:43:59 GMT] [info] [<0.291.0>] Document `my_rep` triggered replication `c0ebe9256695ff083347cbf95f93e280+create_target`
+[Thu, 17 Feb 2011 19:44:37 GMT] [info] [<0.124.0>] Replication `c0ebe9256695ff083347cbf95f93e280+create_target` finished (triggered by document `my_rep`)</programlisting>
+
+ <para>
+ As soon as the replication is triggered, the document will be
+ updated by CouchDB with 3 new fields:
+ </para>
+
+<programlisting>{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}</programlisting>
+
+ <para>
+ Special fields set by the replicator start with the prefix
+ <literal>_replication_</literal>.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ <literal>_replication_id</literal>
+ </para>
+
+ <para>
+ The ID internally assigned to the replication. This is also
+ the ID exposed by <literal>/_active_tasks</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>_replication_state</literal>
+ </para>
+
+ <para>
+ The current state of the replication.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>_replication_state_time</literal>
+ </para>
+
+ <para>
+ A Unix timestamp (number of seconds since 1 Jan 1970) that
+ tells us when the current replication state (marked in
+ <literal>_replication_state</literal>) was set.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ When the replication finishes, it will update the
+ <literal>_replication_state</literal> field (and
+ <literal>_replication_state_time</literal>) with the value
+ <literal>completed</literal>, so the document will look like:
+ </para>
+
+<programlisting>{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "completed",
+ "_replication_state_time": 1297974122
+}</programlisting>
+
+ <para>
+ When an error happens during replication, the
+ <literal>_replication_state</literal> field is set to
+ <literal>error</literal> (and
+ <literal>_replication_state</literal> gets updated of course).
+ </para>
+
+ <para>
+ When you PUT/POST a document to the
+ <literal>_replicator</literal> database, CouchDB will attempt to
+ start the replication up to 10 times (configurable under
+ <literal>[replicator]</literal>, parameter
+ <literal>max_replication_retry_count</literal>). If it fails on
+ the first attempt, it waits 5 seconds before doing a second
+ attempt. If the second attempt fails, it waits 10 seconds before
+ doing a third attempt. If the third attempt fails, it waits 20
+ seconds before doing a fourth attempt (each attempt doubles the
+ previous wait period). When an attempt fails, the Couch log will
+ show you something like:
+ </para>
+
+<programlisting>[error] [<0.149.0>] Error starting replication `67c1bb92010e7abe35d7d629635f18b6+create_target` (document `my_rep_2`): {db_not_found,<<"could not open http://myserver:5986/foo/">></programlisting>
+
+ <note>
+ <para>
+ The <literal>_replication_state</literal> field is only set to
+ <literal>error</literal> when all the attempts were
+ unsuccessful.
+ </para>
+ </note>
+
+ <para>
+ There are only 3 possible values for the
+ <literal>_replication_state</literal> field:
+ <literal>triggered</literal>, <literal>completed</literal> and
+ <literal>error</literal>. Continuous replications never get
+ their state set to <literal>completed</literal>.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-docsame">
+
+ <title>Documents describing the same replication</title>
+
+ <para>
+ Lets suppose 2 documents are added to the
+ <literal>_replicator</literal> database in the following order:
+ </para>
+
+<programlisting>{
+ "_id": "doc_A",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar"
+}</programlisting>
+
+ <para>
+ and
+ </para>
+
+<programlisting>{
+ "_id": "doc_B",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar"
+}</programlisting>
+
+ <para>
+ Both describe exactly the same replication (only their
+ <literal>_ids</literal> differ). In this case document
+ <literal>doc_A</literal> triggers the replication, getting
+ updated by CouchDB with the fields
+ <literal>_replication_state</literal>,
+ <literal>_replication_state_time</literal> and
+ <literal>_replication_id</literal>, just like it was described
+ before. Document <literal>doc_B</literal> however, is only
+ updated with one field, the <literal>_replication_id</literal>
+ so it will look like this:
+ </para>
+
+<programlisting>{
+ "_id": "doc_B",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280"
+}</programlisting>
+
+ <para>
+ While document <literal>doc_A</literal> will look like this:
+ </para>
+
+<programlisting>{
+ "_id": "doc_A",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}</programlisting>
+
+ <para>
+ Note that both document get exactly the same value for the
+ <literal>_replication_id</literal> field. This way you can
+ identify which documents refer to the same replication - you can
+ for example define a view which maps replication IDs to document
+ IDs.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-cancel">
+
+ <title>Canceling replications</title>
+
+ <para>
+ To cancel a replication simply <literal>DELETE</literal> the
+ document which triggered the replication. The Couch log will
+ show you an entry like the following:
+ </para>
+
+<programlisting>[Thu, 17 Feb 2011 20:16:29 GMT] [info] [<0.125.0>] Stopped replication `c0ebe9256695ff083347cbf95f93e280+continuous+create_target` because replication document `doc_A` was deleted</programlisting>
+
+ <note>
+ <para>
+ You need to <literal>DELETE</literal> the document that
+ triggered the replication. <literal>DELETE</literal>ing
+ another document that describes the same replication but did
+ not trigger it, will not cancel the replication.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-restart">
+
+ <title>Server restart</title>
+
+ <para>
+ When CouchDB is restarted, it checks its
+ <literal>_replicator</literal> database and restarts any
+ replication that is described by a document that either has its
+ <literal>_replication_state</literal> field set to
+ <literal>triggered</literal> or it doesn't have yet the
+ <literal>_replication_state</literal> field set.
+ </para>
+
+ <note>
+ <para>
+ Continuous replications always have a
+ <literal>_replication_state</literal> field with the value
+ <literal>triggered</literal>, therefore they're always
+ restarted when CouchDB is restarted.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-changing">
+
+ <title>Changing the Replicator Database</title>
+
+ <para>
+ Imagine your replicator database (default name is _replicator)
+ has the two following documents that represent pull replications
+ from servers A and B:
+ </para>
+
+<programlisting>{
+ "_id": "rep_from_A",
+ "source": "http://aserver.com:5984/foo",
+ "target": "foo_a",
+ "continuous": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297971311
+}
+{
+ "_id": "rep_from_B",
+ "source": "http://bserver.com:5984/foo",
+ "target": "foo_b",
+ "continuous": true,
+ "_replication_id": "231bb3cf9d48314eaa8d48a9170570d1",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}</programlisting>
+
+ <para>
+ Now without stopping and restarting CouchDB, you change the name
+ of the replicator database to
+ <literal>another_replicator_db</literal>:
+ </para>
+
+<programlisting>$ curl -X PUT http://localhost:5984/_config/replicator/db -d '"another_replicator_db"'
+"_replicator"</programlisting>
+
+ <para>
+ As soon as this is done, both pull replications defined before,
+ are stopped. This is explicitly mentioned in CouchDB's log:
+ </para>
+
+<programlisting>[Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.104.0>] Stopping all ongoing replications because the replicator database was deleted or changed
+[Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.127.0>] 127.0.0.1 - - PUT /_config/replicator/db 200</programlisting>
+
+ <para>
+ Imagine now you add a replication document to the new replicator
+ database named <literal>another_replicator_db</literal>:
+ </para>
+
+<programlisting>{
+ "_id": "rep_from_X",
+ "source": "http://xserver.com:5984/foo",
+ "target": "foo_x",
+ "continuous": true
+}</programlisting>
+
+ <para>
+ From now own you have a single replication going on in your
+ system: a pull replication pulling from server X. Now you change
+ back the replicator database to the original one
+ <literal>_replicator</literal>:
+ </para>
+
+<programlisting>$ curl -X PUT http://localhost:5984/_config/replicator/db -d '"_replicator"'
+"another_replicator_db"</programlisting>
+
+ <para>
+ Immediately after this operation, the replication pulling from
+ server X will be stopped and the replications defined in the
+ _replicator database (pulling from servers A and B) will be
+ resumed.
+ </para>
+
+ <para>
+ Changing again the replicator database to
+ <literal>another_replicator_db</literal> will stop the pull
+ replications pulling from servers A and B, and resume the pull
+ replication pulling from server X.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-replicating">
+
+ <title>Replicating the replicator database</title>
+
+ <para>
+ Imagine you have in server C a replicator database with the two
+ following pull replication documents in it:
+ </para>
+
+<programlisting>{
+ "_id": "rep_from_A",
+ "source": "http://aserver.com:5984/foo",
+ "target": "foo_a",
+ "continuous": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297971311
+}
+{
+ "_id": "rep_from_B",
+ "source": "http://bserver.com:5984/foo",
+ "target": "foo_b",
+ "continuous": true,
+ "_replication_id": "231bb3cf9d48314eaa8d48a9170570d1",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}</programlisting>
+
+ <para>
+ Now you would like to have the same pull replications going on
+ in server D, that is, you would like to have server D pull
+ replicating from servers A and B. You have two options:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Explicitly add two documents to server's D replicator
+ database
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replicate server's C replicator database into server's D
+ replicator database
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Both alternatives accomplish exactly the same goal.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-delegations">
+
+ <title>Delegations</title>
+
+ <para>
+ Replication documents can have a custom
+ <literal>user_ctx</literal> property. This property defines the
+ user context under which a replication runs. For the old way of
+ triggering replications (POSTing to
+ <literal>/_replicate/</literal>), this property was not needed
+ (it didn't exist in fact) - this is because at the moment of
+ triggering the replication it has information about the
+ authenticated user. With the replicator database, since it's a
+ regular database, the information about the authenticated user
+ is only present at the moment the replication document is
+ written to the database - the replicator database implementation
+ is like a _changes feed consumer (with
+ <literal>?include_docs=true</literal>) that reacts to what was
+ written to the replicator database - in fact this feature could
+ be implemented with an external script/program. This
+ implementation detail implies that for non admin users, a
+ <literal>user_ctx</literal> property, containing the user's name
+ and a subset of his/her roles, must be defined in the
+ replication document. This is ensured by the document update
+ validation function present in the default design document of
+ the replicator database. This validation function also ensure
+ that a non admin user can set a user name property in the
+ <literal>user_ctx</literal> property that doesn't match his/her
+ own name (same principle applies for the roles).
+ </para>
+
+ <para>
+ For admins, the <literal>user_ctx</literal> property is
+ optional, and if it's missing it defaults to a user context with
+ name null and an empty list of roles - this mean design
+ documents will not be written to local targets. If writing
+ design documents to local targets is desired, the a user context
+ with the roles <literal>_admin</literal> must be set explicitly.
+ </para>
+
+ <para>
+ Also, for admins the <literal>user_ctx</literal> property can be
+ used to trigger a replication on behalf of another user. This is
+ the user context that will be passed to local target database
+ document validation functions.
+ </para>
+
+ <note>
+ <para>
+ The <literal>user_ctx</literal> property only has effect for
+ local endpoints.
+ </para>
+ </note>
+
+ <para>
+ Example delegated replication document:
+ </para>
+
+<programlisting>{
+ "_id": "my_rep",
+ "source": "http://bserver.com:5984/foo",
+ "target": "bar",
+ "continuous": true,
+ "user_ctx": {
+ "name": "joe",
+ "roles": ["erlanger", "researcher"]
+ }
+}</programlisting>
+
+ <para>
+ As stated before, for admins the user_ctx property is optional,
+ while for regular (non admin) users it's mandatory. When the
+ roles property of <literal>user_ctx</literal> is missing, it
+ defaults to the empty list <literal>[ ]</literal>.
+ </para>
+
+ </section>
+
+ </section>
+
+ <section id="couchdb-release-1.1-ssl">
+
+ <title>Native SSL Support</title>
+
+ <para>
+ CouchDB 1.1 supports SSL natively. All your secure connection
+ needs can now be served without the need set and maintain a
+ separate proxy server that handles SSL.
+ </para>
+
+ <para>
+ SSL setup can be tricky, but the configuration in CouchDB was
+ designed to be as easy as possible. All you need is two files; a
+ certificate and a private key. If you bought an official SSL
+ certificate from a certificate authority, both should be in your
+ possession already.
+ </para>
+
+ <para>
+ If you just want to try this out and don't want to pay anything
+ upfront, you can create a self-signed certificate. Everything will
+ work the same, but clients will get a warning about an insecure
+ certificate.
+ </para>
+
+ <para>
+ You will need the OpenSSL command line tool installed. It probably
+ already is.
+ </para>
+
+<programlisting>shell> <userinput>mkdir cert && cd cert</userinput>
+shell> <userinput>openssl genrsa > privkey.pem</userinput>
+shell> <userinput>openssl req -new -x509 -key privkey.pem -out mycert.pem -days 1095</userinput>
+shell> <userinput>ls</userinput>
+mycert.pem privkey.pem</programlisting>
+
+ <para>
+ Now, you need to edit CouchDB's configuration, either by editing
+ your <filename>local.ini</filename> file or using the
+ <literal>/_config</literal> API calls or the configuration screen
+ in Futon. Here is what you need to do in
+ <filename>local.ini</filename>, you can infer what needs doing in
+ the other places.
+ </para>
+
+ <para>
+ Be sure to make these edits. Under <literal>[daemons]</literal>
+ you should see:
+ </para>
+
+<programlisting>; enable SSL support by uncommenting the following line and supply the PEM's below.
+; the default ssl port CouchDB listens on is 6984
+;httpsd = {couch_httpd, start_link, [https]}</programlisting>
+
+ <para>
+ Here uncomment the last line:
+ </para>
+
+<programlisting>httpsd = {couch_httpd, start_link, [https]}</programlisting>
+
+ <para>
+ Next, under <literal>[ssl]</literal> you will see:
+ </para>
+
+<programlisting>;cert_file = /full/path/to/server_cert.pem
+;key_file = /full/path/to/server_key.pem</programlisting>
+
+ <para>
+ Uncomment and adjust the paths so it matches your system's paths:
+ </para>
+
+<programlisting>cert_file = /home/jan/cert/mycert.pem
+key_file = /home/jan/cert/privkey.pem</programlisting>
+
+ <para>
+ For more information please read
+ <ulink url="http://www.openssl.org/docs/HOWTO/certificates.txt">http://www.openssl.org/docs/HOWTO/certificates.txt</ulink>.
+ </para>
+
+ <para>
+ Now start (or restart) CouchDB. You should be able to connect to
+ it using HTTPS on port 6984:
+ </para>
+
+<programlisting>shell> <userinput>curl https://127.0.0.1:6984/</userinput>
+curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
+error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
+More details here: http://curl.haxx.se/docs/sslcerts.html
+
+curl performs SSL certificate verification by default, using a "bundle"
+of Certificate Authority (CA) public keys (CA certs). If the default
+bundle file isn't adequate, you can specify an alternate file
+using the --cacert option.
+If this HTTPS server uses a certificate signed by a CA represented in
+the bundle, the certificate verification probably failed due to a
+problem with the certificate (it might be expired, or the name might
+not match the domain name in the URL).
+If you'd like to turn off curl's verification of the certificate, use
+the -k (or --insecure) option.</programlisting>
+
+ <para>
+ Oh no what happened?! — Remember, clients will notify their
+ users that your certificate is self signed.
+ <command>curl</command> is the client in this case and it notifies
+ you. Luckily you trust yourself (don't you?) and you can specify
+ the <option>-k</option> option as the message reads:
+ </para>
+
+<programlisting>shell> <userinput>curl -k https://127.0.0.1:6984/</userinput>
+{"couchdb":"Welcome","version":"1.1.0"}</programlisting>
+
+ <para>
+ All done.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-httprange">
+
+ <title>HTTP Range Requests</title>
+
+ <para>
+ HTTP allows you to specify byte ranges for requests. This allows
+ the implementation of resumable downloads and skippable audio and
+ video streams alike. Now this is available for all attachments
+ inside CouchDB.
+ </para>
+
+ <para>
+ This is just a real quick run through how this looks under the
+ hood. Usually, you will have larger binary files to serve from
+ CouchDB, like MP3s and videos, but to make things a little more
+ obvious, I use a text file here (Note that I use the
+ <literal>application/octet-stream</literal> Content-Type instead
+ of <literal>text/plain</literal>).
+ </para>
+
+<programlisting>shell> <userinput>cat file.txt </userinput>
+My hovercraft is full of eels!</programlisting>
+
+ <para>
+ Now lets store this text file as an attachment in CouchDB. First,
+ we create a database:
+ </para>
+
+<programlisting>shell> <userinput>curl -X PUT http://127.0.0.1:5984/test</userinput>
+{"ok":true}</programlisting>
+
+ <para>
+ Then we create a new document and the file attachment in one go:
+ </para>
+
+<programlisting>shell> <userinput>curl -X PUT http://127.0.0.1:5984/test/doc/file.txt -H "Content-Type: application/octet-stream" -d@file.txt</userinput>
+{"ok":true,"id":"doc","rev":"1-287a28fa680ae0c7fb4729bf0c6e0cf2"}</programlisting>
+
+ <para>
+ Now we can request the whole file easily:
+ </para>
+
+<programlisting>shell> <userinput>curl -X GET http://127.0.0.1:5984/test/doc/file.txt</userinput>
+My hovercraft is full of eels!</programlisting>
+
+ <para>
+ But say we only want the first 13 bytes:
+ </para>
+
+<programlisting>shell> <userinput>curl -X GET http://127.0.0.1:5984/test/doc/file.txt -H "Range: bytes=0-12"</userinput>
+My hovercraft</programlisting>
+
+ <para>
+ HTTP supports many ways to specify single and even multiple byte
+ rangers. Read all about it in
+ <ulink url="http://tools.ietf.org/html/rfc2616#section-14.27">RFC
+ 2616</ulink>.
+ </para>
+
+ <note>
+ <para>
+ Databases that have been created with CouchDB 1.0.2 or earlier
+ will support range requests in 1.1.0, but they are using a
+ less-optimal algorithm. If you plan to make heavy use of this
+ feature, make sure to compact your database with CouchDB 1.1.0
+ to take advantage of a better algorithm to find byte ranges.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-proxying">
+
+ <title>HTTP Proxying</title>
+
+ <para>
+ The HTTP proxy feature makes it easy to map and redirect different
+ content through your CouchDB URL. The proxy works by mapping a
+ pathname and passing all content after that prefix through to the
+ configured proxy address.
+ </para>
+
+ <para>
+ Configuration of the proxy redirect is handled through the
+ <literal>[httpd_global_handlers]</literal> section of the CouchDB
+ configuration file (typically <filename>local.ini</filename>). The
+ format is:
+ </para>
+
+<programlisting>[httpd_global_handlers]
+PREFIX = {couch_httpd_proxy, handle_proxy_req, <<"DESTINATION">>}</programlisting>
+
+ <para>
+ Where:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ <literal>PREFIX</literal>
+ </para>
+
+ <para>
+ Is the string that will be matched. The string can be any
+ valid qualifier, although to ensure that existing database
+ names are not overridden by a proxy configuration, you can use
+ an underscore prefix.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>DESTINATION</literal>
+ </para>
+
+ <para>
+ The fully-qualified URL to which the request should be sent.
+ The destination must include the <literal>http</literal>
+ prefix. The content is used verbatim in the original request,
+ so you can also forward to servers on different ports and to
+ specific paths on the target host.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ The proxy process then translates requests of the form:
+ </para>
+
+<programlisting>http://couchdb:5984/PREFIX/path</programlisting>
+
+ <para>
+ To:
+ </para>
+
+<programlisting>DESTINATION/path</programlisting>
+
+ <note>
+ <para>
+ Everything after <literal>PREFIX</literal> including the
+ required forward slash will be appended to the
+ <literal>DESTINATION</literal>.
+ </para>
+ </note>
+
+ <para>
+ The response is then communicated back to the original client.
+ </para>
+
+ <para>
+ For example, the following configuration:
+ </para>
+
+<programlisting>_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>}</programlisting>
+
+ <para>
+ Would forward all requests for
+ <literal>http://couchdb:5984/_google</literal> to the Google
+ website.
+ </para>
+
+ <para>
+ The service can also be used to forward to related CouchDB
+ services, such as Lucene:
+ </para>
+
+<programlisting>[httpd_global_handlers]
+_fti = {couch_httpd_proxy, handle_proxy_req, <<"http://127.0.0.1:5985">>}</programlisting>
+
+ <note>
+ <para>
+ The proxy service is basic. If the request is not identified by
+ the <literal>DESTINATION</literal>, or the remainder of the
+ <literal>PATH</literal> specification is incomplete, the
+ original request URL is interpreted as if the
+ <literal>PREFIX</literal> component of that URL does not exist.
+ </para>
+
+ <para>
+ For example, requesting
+ <literal>http://couchdb:5984/_intranet/media</literal> when
+ <filename>/media</filename> on the proxy destination does not
+ exist, will cause the request URL to be interpreted as
+ <literal>http://couchdb:5984/media</literal>. Care should be
+ taken to ensure that both requested URLs and destination URLs
+ are able to cope
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-commonjs">
+
+ <title>Added CommonJS support to map functions</title>
+
+ <para>
+ We didn't have CommonJS require in map functions because the
+ current CommonJS implementation is scoped to the whole design doc,
+ and giving views access to load code from anywhere in the design
+ doc would mean we'd have to blow away your view index any time you
+ changed anything. Having to rebuild views from scratch just
+ because you changed some CSS or a show function isn't fun, so we
+ avoided the issue by keeping CommonJS require out of map and
+ reduce altogether.
+ </para>
+
+ <para>
+ The solution we came up with is to allow CommonJS inside map and
+ reduce funs, but only of libraries that are stored inside the
+ views part of the design doc.
+ </para>
+
+ <para>
+ So you could continue to access CommonJS code in design_doc.foo,
+ from your list functions etc, but we'd add the ability to require
+ CommonJS modules within map and reduce, but only from
+ design_doc.views.lib
+ </para>
+
+ <para>
+ There's no worry here about namespace collisions, as Couch just
+ plucks <literal>views.*.map</literal> and
+ <literal>views.*.reduce</literal> out of the design doc. So you
+ could have a view called <literal>lib</literal> if you wanted, and
+ still have CommonJS stored in <literal>views.lib.sha1</literal>
+ and <literal>views.lib.stemmer</literal> if you wanted.
+ </para>
+
+ <para>
+ We simplified the implementation by enforcing that CommonJS
+ modules to be used in map functions be stored in views.lib.
+ </para>
+
+ <para>
+ A sample design doc (taken from the test suite in Futon) is below:
+ </para>
+
+<programlisting>{
+ "views" : {
+ "lib" : {
+ "baz" : "exports.baz = 'bam';",
+ "foo" : {
+ "zoom" : "exports.zoom = 'yeah';",
+ "boom" : "exports.boom = 'ok';",
+ "foo" : "exports.foo = 'bar';"
+ }
+ },
+ "commonjs" : {
+ "map" : "function(doc) { emit(null, require('views/lib/foo/boom').boom)}"
+ }
+ },
+ "_id" : "_design/test"
+}</programlisting>
+
+ <para>
+ The <literal>require()</literal> statement is relative to the
+ design document, but anything loaded form outside of
+ <literal>views/lib</literal> will fail.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-etag">
+
+ <title>More granular ETag support for views</title>
+
+ <para>
+ ETags have been assigned to a map/reduce group (the collection of
+ views in a single design document). Any change to any of the
+ indexes for those views would generate a new ETag for all view
+ URL's in a single design doc, even if that specific view's results
+ had not changed.
+ </para>
+
+ <para>
+ In CouchDB 1.1 each <literal>_view</literal> URL has it's own ETag
+ which only gets updated when changes are made to the database that
+ effect that index. If the index for that specific view does not
+ change, that view keeps the original ETag head (therefore sending
+ back 304 Not Modified more often).
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-filters">
+
+ <title>Added built-in filters for <literal>_changes</literal>:
+ <literal>_doc_ids</literal> and <literal>_design</literal>.</title>
+
+ <para>
+ The <literal>_changes</literal> feed can now be used to watch
+ changes to specific document ID's or the list of
+ <literal>_design</literal> documents in a database. If the
+ <literal>filters</literal> parameter is set to
+ <literal>_doc_ids</literal> a list of doc IDs can be passed in the
+ "doc_ids" as a JSON array.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-wildcards">
+
+ <title>Allow wildcards in vhosts definitions</title>
+
+ <para>
+ Similar to the rewrites section of a <literal>_design</literal>
+ document, the new <literal>vhosts</literal> system uses variables
+ in the form of :varname or wildcards in the form of asterisks. The
+ variable results can be output into the resulting path as they are
+ in the rewriter.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-osprocess">
+
+ <title>OS Daemons</title>
+
+ <para>
+ CouchDB now supports starting external processes. The support is
+ simple and enables CouchDB to start each configured OS daemon. If
+ the daemon stops at any point, CouchDB will restart it (with
+ protection to ensure regularly failing daemons are not repeatedly
+ restarted).
+ </para>
+
+ <para>
+ The daemon starting process is one-to-one; for each each
+ configured daemon in the configuration file, CouchDB will start
+ exactly one instance. If you need to run multiple instances, then
+ you must create separate individual configurations. Daemons are
+ configured within the <literal>[os_daemons]</literal> section of
+ your configuration file (<filename>local.ini</filename>). The
+ format of each configured daemon is:
+ </para>
+
+<programlisting>NAME = PATH ARGS</programlisting>
+
+ <para>
+ Where <literal>NAME</literal> is an arbitrary (and unique) name to
+ identify the daemon; <literal>PATH</literal> is the full path to
+ the daemon to be executed; <literal>ARGS</literal> are any
+ required arguments to the daemon.
+ </para>
+
+ <para>
+ For example:
+ </para>
+
+<programlisting>[os_daemons]
+basic_responder = /usr/local/bin/responsder.js</programlisting>
+
+ <para>
+ There is no interactivity between CouchDB and the running process,
+ but you can use the OS Daemons service to create new HTTP servers
+ and responders and then use the new proxy service to redirect
+ requests and output to the CouchDB managed service. For more
+ information on proxying, see
+ <xref linkend="couchdb-release-1.1-proxying"/>. For further
+ background on the OS Daemon service, see
+ <ulink url="http://davispj.com/2010/09/26/new-couchdb-externals-api.html">CouchDB
+ Externals API</ulink>
+ </para>
+
+ </section>
+
+ <section id="coudhdb-release-1.1-updateafter">
+
+ <title>Stale views and <literal>update_after</literal></title>
+
+ <para>
+ Currently a view request can include the
+ <literal>stale=ok</literal> query argument, which allows the
+ contents of a stale view index to be used to produce the view
+ output. In order to trigger a build of the outdated view index, a
+ second view request must be made.
+ </para>
+
+ <para>
+ To simplify this process, the <literal>update_after</literal>
+ value can be supplied to the <literal>stale</literal> query
+ argument. This triggers a rebuild of the view index after the
+ results of the view have been retrieved.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-socketoptions">
+
+ <title>Socket Options Configuration Setting</title>
+
+ <para>
+ The socket options for the listening socket in CouchDB can now be
+ set within the CouchDB configuration file. The setting should be
+ added to the <literal>[httpd]</literal> section of the file using
+ the option name <literal>socket_options</literal>. The
+ specification is as a list of tuples. For example:
+ </para>
+
+<programlisting>[httpd]
+socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]</programlisting>
+
+ <para>
+ The options supported are a subset of full options supported by
+ the TCP/IP stack. A list of the supported options are provided in
+ the
+ <ulink url="http://www.erlang.org/doc/man/inet.html#setopts-2">Erlang
+ inet</ulink> documentation.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-serveroptions">
+
+ <title>Server Options Configuration Setting</title>
+
+ <para>
+ Server options for the MochiWeb component of CouchDB can now be
+ added to the configuration file. Settings should be added to the
+ <literal>server_options</literal> option of the
+ <literal>[httpd]</literal> section of
+ <filename>local.ini</filename>. For example:
+ </para>
+
+<programlisting>[httpd]
+server_options = [{backlog, 128}, {acceptor_pool_size, 16}]</programlisting>
+
+ </section>
+
+ <section id="couchdb-release-1.1-errormessages">
+
+ <title>Improved Error Messages</title>
+
+ <para>
+ The errors reported when CouchDB is unable to read a required file
+ have been updated so that explicit information about the files and
+ problem can now be identified from the error message. The errors
+ report file permission access either when reading or writing to
+ configuration and database files.
+ </para>
+
+ <para>
+ The error is raised both through the log file and the error
+ message returned through the API call as a JSON error message. For
+ example, when setting configuration values:
+ </para>
+
+<programlisting>shell> <userinput>curl -H 'X-Couch-Persist: true' -X PUT http://couchdb:5984/_config/couchdb/delayed_commits -d '"false"'</userinput>
+{"error":"file_permission_error","reason":"/etc/couchdb/local.ini"}</programlisting>
+
+ <para>
+ Errors will always be reported using the
+ <literal>file_permission_error</literal> error type.
+ </para>
+
+ <para>
+ During startup permissions errors on key files are also reported
+ in the log with a descriptive error message and file location so
+ that permissions can be fixed before restart.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-microoptimizations">
+
+ <title>Multiple micro-optimizations when reading data.</title>
+
+ <para>
+ We found a number of places where CouchDB wouldn't do the absolute
+ optimal thing when reading data and got rid of quite a few
+ inefficiencies. The problem with small optimizations all over the
+ place is that you may not notice them with every use-case, but we
+ sure hope you can see an improvement overall.
+ </para>
+
+ </section>
+
+</article>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/fd643691/share/docs/couchdb-release-1.1/couchdb-release-1.1.xml
----------------------------------------------------------------------
diff --git a/share/docs/couchdb-release-1.1/couchdb-release-1.1.xml b/share/docs/couchdb-release-1.1/couchdb-release-1.1.xml
new file mode 100644
index 0000000..e70142a
--- /dev/null
+++ b/share/docs/couchdb-release-1.1/couchdb-release-1.1.xml
@@ -0,0 +1,1243 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE article PUBLIC '-//OASIS//DTD DocBook XML V4.5//EN'
+ 'http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd' [
+<!ENTITY % every.entities SYSTEM "entities.ent">
+%every.entities;
+]>
+<article id="couchdb-release-1.1">
+
+ <title>CouchDB Release 1.1 Feature Guide</title>
+
+ <articleinfo>
+
+ <abstract>
+
+ <para>
+ This document provides details on the new features introduced in
+ the CouchDB 1.1 release from the CouchDB 1.0.x release series.
+ </para>
+
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="../common/docbuilddate.xml"/>
+
+ </abstract>
+
+ </articleinfo>
+
+ <section id="couchdb-release-1.1-upgrading">
+
+ <title>Upgrading to CouchDB 1.1</title>
+
+ <para>
+ You can upgrade your existing CouchDB 1.0.x installation to
+ CouchDB 1.1 without any specific steps or migration. When you run
+ CouchDB 1.1 the existing data and index files will be opened and
+ used as normal.
+ </para>
+
+ <para>
+ The first time you run a compaction routine on your database
+ within CouchDB 1.1, the data structure and indexes will be updated
+ to the new version of the CouchDB database format that can only be
+ read by CouchDB 1.1 and later. This step is not reversable. Once
+ the data files have been updated and migrated to the new version
+ the data files will no longer work with a CouchDB 1.0.x release.
+ </para>
+
+ <warning>
+ <para>
+ If you want to retain support for openein gthe data files in
+ CouchDB 1.0.x you must back up your data files before performing
+ the upgrade and compaction process.
+ </para>
+ </warning>
+
+ </section>
+
+ <section id="couchb-release-1.1-replicatordb">
+
+ <title>Replicator Database</title>
+
+ <para>
+ A database where you
+ <literal>PUT</literal>/<literal>POST</literal> documents to
+ trigger replications and you <literal>DELETE</literal> to cancel
+ ongoing replications. These documents have exactly the same
+ content as the JSON objects we used to <literal>POST</literal> to
+ <literal>_replicate</literal> (fields <literal>source</literal>,
+ <literal>target</literal>, <literal>create_target</literal>,
+ <literal>continuous</literal>, <literal>doc_ids</literal>,
+ <literal>filter</literal>, <literal>query_params</literal>.
+ </para>
+
+ <para>
+ Replication documents can have a user defined
+ <literal>_id</literal>. Design documents (and
+ <literal>_local</literal> documents) added to the replicator
+ database are ignored.
+ </para>
+
+ <para>
+ The default name of this database is
+ <literal>_replicator</literal>. The name can be changed in the
+ <filename>local.ini</filename> configuration, section
+ <literal>[replicator]</literal>, parameter <literal>db</literal>.
+ </para>
+
+ <section id="couchdb-release-1.1-replicatordb-basics">
+
+ <title>Basics</title>
+
+ <para>
+ Let's say you PUT the following document into _replicator:
+ </para>
+
+<programlisting>
+{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true
+}
+</programlisting>
+
+ <para>
+ In the couch log you'll see 2 entries like these:
+ </para>
+
+<programlisting>
+[Thu, 17 Feb 2011 19:43:59 GMT] [info] [<0.291.0>] Document `my_rep` triggered replication `c0ebe9256695ff083347cbf95f93e280+create_target`
+[Thu, 17 Feb 2011 19:44:37 GMT] [info] [<0.124.0>] Replication `c0ebe9256695ff083347cbf95f93e280+create_target` finished (triggered by document `my_rep`)
+</programlisting>
+
+ <para>
+ As soon as the replication is triggered, the document will be
+ updated by CouchDB with 3 new fields:
+ </para>
+
+<programlisting>
+{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}
+</programlisting>
+
+ <para>
+ Special fields set by the replicator start with the prefix
+ <literal>_replication_</literal>.
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ <literal>_replication_id</literal>
+ </para>
+
+ <para>
+ The ID internally assigned to the replication. This is also
+ the ID exposed by <literal>/_active_tasks</literal>.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>_replication_state</literal>
+ </para>
+
+ <para>
+ The current state of the replication.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>_replication_state_time</literal>
+ </para>
+
+ <para>
+ A Unix timestamp (number of seconds since 1 Jan 1970) that
+ tells us when the current replication state (marked in
+ <literal>_replication_state</literal>) was set.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ When the replication finishes, it will update the
+ <literal>_replication_state</literal> field (and
+ <literal>_replication_state_time</literal>) with the value
+ <literal>completed</literal>, so the document will look like:
+ </para>
+
+<programlisting>
+{
+ "_id": "my_rep",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "create_target": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "completed",
+ "_replication_state_time": 1297974122
+}
+</programlisting>
+
+ <para>
+ When an error happens during replication, the
+ <literal>_replication_state</literal> field is set to
+ <literal>error</literal> (and
+ <literal>_replication_state</literal> gets updated of course).
+ </para>
+
+ <para>
+ When you PUT/POST a document to the
+ <literal>_replicator</literal> database, CouchDB will attempt to
+ start the replication up to 10 times (configurable under
+ <literal>[replicator]</literal>, parameter
+ <literal>max_replication_retry_count</literal>). If it fails on
+ the first attempt, it waits 5 seconds before doing a second
+ attempt. If the second attempt fails, it waits 10 seconds before
+ doing a third attempt. If the third attempt fails, it waits 20
+ seconds before doing a fourth attempt (each attempt doubles the
+ previous wait period). When an attempt fails, the Couch log will
+ show you something like:
+ </para>
+
+<programlisting>
+[error] [<0.149.0>] Error starting replication `67c1bb92010e7abe35d7d629635f18b6+create_target` (document `my_rep_2`): {db_not_found,<<"could not open http://myserver:5986/foo/">>
+</programlisting>
+
+ <note>
+ <para>
+ The <literal>_replication_state</literal> field is only set to
+ <literal>error</literal> when all the attempts were
+ unsuccessful.
+ </para>
+ </note>
+
+ <para>
+ There are only 3 possible values for the
+ <literal>_replication_state</literal> field:
+ <literal>triggered</literal>, <literal>completed</literal> and
+ <literal>error</literal>. Continuous replications never get
+ their state set to <literal>completed</literal>.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-docsame">
+
+ <title>Documents describing the same replication</title>
+
+ <para>
+ Lets suppose 2 documents are added to the
+ <literal>_replicator</literal> database in the following order:
+ </para>
+
+<programlisting>
+{
+ "_id": "doc_A",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar"
+}
+</programlisting>
+
+ <para>
+ and
+ </para>
+
+<programlisting>
+{
+ "_id": "doc_B",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar"
+}
+</programlisting>
+
+ <para>
+ Both describe exactly the same replication (only their
+ <literal>_ids</literal> differ). In this case document
+ <literal>doc_A</literal> triggers the replication, getting
+ updated by CouchDB with the fields
+ <literal>_replication_state</literal>,
+ <literal>_replication_state_time</literal> and
+ <literal>_replication_id</literal>, just like it was described
+ before. Document <literal>doc_B</literal> however, is only
+ updated with one field, the <literal>_replication_id</literal>
+ so it will look like this:
+ </para>
+
+<programlisting>
+{
+ "_id": "doc_B",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280"
+}
+</programlisting>
+
+ <para>
+ While document <literal>doc_A</literal> will look like this:
+ </para>
+
+<programlisting>
+{
+ "_id": "doc_A",
+ "source": "http://myserver.com:5984/foo",
+ "target": "bar",
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}
+</programlisting>
+
+ <para>
+ Note that both document get exactly the same value for the
+ <literal>_replication_id</literal> field. This way you can
+ identify which documents refer to the same replication - you can
+ for example define a view which maps replication IDs to document
+ IDs.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-cancel">
+
+ <title>Canceling replications</title>
+
+ <para>
+ To cancel a replication simply <literal>DELETE</literal> the
+ document which triggered the replication. The Couch log will
+ show you an entry like the following:
+ </para>
+
+<programlisting>
+[Thu, 17 Feb 2011 20:16:29 GMT] [info] [<0.125.0>] Stopped replication `c0ebe9256695ff083347cbf95f93e280+continuous+create_target` because replication document `doc_A` was deleted
+</programlisting>
+
+ <note>
+ <para>
+ You need to <literal>DELETE</literal> the document that
+ triggered the replication. <literal>DELETE</literal>ing
+ another document that describes the same replication but did
+ not trigger it, will not cancel the replication.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-restart">
+
+ <title>Server restart</title>
+
+ <para>
+ When CouchDB is restarted, it checks its
+ <literal>_replicator</literal> database and restarts any
+ replication that is described by a document that either has its
+ <literal>_replication_state</literal> field set to
+ <literal>triggered</literal> or it doesn't have yet the
+ <literal>_replication_state</literal> field set.
+ </para>
+
+ <note>
+ <para>
+ Continuous replications always have a
+ <literal>_replication_state</literal> field with the value
+ <literal>triggered</literal>, therefore they're always
+ restarted when CouchDB is restarted.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-changing">
+
+ <title>Changing the Replicator Database</title>
+
+ <para>
+ Imagine your replicator database (default name is _replicator)
+ has the two following documents that represent pull replications
+ from servers A and B:
+ </para>
+
+<programlisting>
+{
+ "_id": "rep_from_A",
+ "source": "http://aserver.com:5984/foo",
+ "target": "foo_a",
+ "continuous": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297971311
+}
+{
+ "_id": "rep_from_B",
+ "source": "http://bserver.com:5984/foo",
+ "target": "foo_b",
+ "continuous": true,
+ "_replication_id": "231bb3cf9d48314eaa8d48a9170570d1",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}
+</programlisting>
+
+ <para>
+ Now without stopping and restarting CouchDB, you change the name
+ of the replicator database to
+ <literal>another_replicator_db</literal>:
+ </para>
+
+<programlisting>
+$ curl -X PUT http://localhost:5984/_config/replicator/db -d '"another_replicator_db"'
+"_replicator"
+</programlisting>
+
+ <para>
+ As soon as this is done, both pull replications defined before,
+ are stopped. This is explicitly mentioned in CouchDB's log:
+ </para>
+
+<programlisting><![CDATA[
+[Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.104.0>] Stopping all ongoing replications because the replicator database was deleted or changed
+[Fri, 11 Mar 2011 07:44:20 GMT] [info] [<0.127.0>] 127.0.0.1 - - PUT /_config/replicator/db 200
+]]>
+</programlisting>
+
+ <para>
+ Imagine now you add a replication document to the new replicator
+ database named <literal>another_replicator_db</literal>:
+ </para>
+
+<programlisting>
+{
+ "_id": "rep_from_X",
+ "source": "http://xserver.com:5984/foo",
+ "target": "foo_x",
+ "continuous": true
+}
+</programlisting>
+
+ <para>
+ From now own you have a single replication going on in your
+ system: a pull replication pulling from server X. Now you change
+ back the replicator database to the original one
+ <literal>_replicator</literal>:
+ </para>
+
+<programlisting>
+$ curl -X PUT http://localhost:5984/_config/replicator/db -d '"_replicator"'
+"another_replicator_db"
+</programlisting>
+
+ <para>
+ Immediately after this operation, the replication pulling from
+ server X will be stopped and the replications defined in the
+ _replicator database (pulling from servers A and B) will be
+ resumed.
+ </para>
+
+ <para>
+ Changing again the replicator database to
+ <literal>another_replicator_db</literal> will stop the pull
+ replications pulling from servers A and B, and resume the pull
+ replication pulling from server X.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-replicating">
+
+ <title>Replicating the replicator database</title>
+
+ <para>
+ Imagine you have in server C a replicator database with the two
+ following pull replication documents in it:
+ </para>
+
+<programlisting>
+{
+ "_id": "rep_from_A",
+ "source": "http://aserver.com:5984/foo",
+ "target": "foo_a",
+ "continuous": true,
+ "_replication_id": "c0ebe9256695ff083347cbf95f93e280",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297971311
+}
+{
+ "_id": "rep_from_B",
+ "source": "http://bserver.com:5984/foo",
+ "target": "foo_b",
+ "continuous": true,
+ "_replication_id": "231bb3cf9d48314eaa8d48a9170570d1",
+ "_replication_state": "triggered",
+ "_replication_state_time": 1297974122
+}
+</programlisting>
+
+ <para>
+ Now you would like to have the same pull replications going on
+ in server D, that is, you would like to have server D pull
+ replicating from servers A and B. You have two options:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ Explicitly add two documents to server's D replicator
+ database
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ Replicate server's C replicator database into server's D
+ replicator database
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ Both alternatives accomplish exactly the same goal.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-replicatordb-delegations">
+
+ <title>Delegations</title>
+
+ <para>
+ Replication documents can have a custom
+ <literal>user_ctx</literal> property. This property defines the
+ user context under which a replication runs. For the old way of
+ triggering replications (POSTing to
+ <literal>/_replicate/</literal>), this property was not needed
+ (it didn't exist in fact) - this is because at the moment of
+ triggering the replication it has information about the
+ authenticated user. With the replicator database, since it's a
+ regular database, the information about the authenticated user
+ is only present at the moment the replication document is
+ written to the database - the replicator database implementation
+ is like a _changes feed consumer (with
+ <literal>?include_docs=true</literal>) that reacts to what was
+ written to the replicator database - in fact this feature could
+ be implemented with an external script/program. This
+ implementation detail implies that for non admin users, a
+ <literal>user_ctx</literal> property, containing the user's name
+ and a subset of his/her roles, must be defined in the
+ replication document. This is ensured by the document update
+ validation function present in the default design document of
+ the replicator database. This validation function also ensure
+ that a non admin user can set a user name property in the
+ <literal>user_ctx</literal> property that doesn't match his/her
+ own name (same principle applies for the roles).
+ </para>
+
+ <para>
+ For admins, the <literal>user_ctx</literal> property is
+ optional, and if it's missing it defaults to a user context with
+ name null and an empty list of roles - this mean design
+ documents will not be written to local targets. If writing
+ design documents to local targets is desired, the a user context
+ with the roles <literal>_admin</literal> must be set explicitly.
+ </para>
+
+ <para>
+ Also, for admins the <literal>user_ctx</literal> property can be
+ used to trigger a replication on behalf of another user. This is
+ the user context that will be passed to local target database
+ document validation functions.
+ </para>
+
+ <note>
+ <para>
+ The <literal>user_ctx</literal> property only has effect for
+ local endpoints.
+ </para>
+ </note>
+
+ <para>
+ Example delegated replication document:
+ </para>
+
+<programlisting>
+{
+ "_id": "my_rep",
+ "source": "http://bserver.com:5984/foo",
+ "target": "bar",
+ "continuous": true,
+ "user_ctx": {
+ "name": "joe",
+ "roles": ["erlanger", "researcher"]
+ }
+}
+</programlisting>
+
+ <para>
+ As stated before, for admins the user_ctx property is optional,
+ while for regular (non admin) users it's mandatory. When the
+ roles property of <literal>user_ctx</literal> is missing, it
+ defaults to the empty list <literal>[ ]</literal>.
+ </para>
+
+ </section>
+
+ </section>
+
+ <section id="couchdb-release-1.1-ssl">
+
+ <title>Native SSL Support</title>
+
+ <para>
+ CouchDB 1.1 supports SSL natively. All your secure connection
+ needs can now be served without the need set and maintain a
+ separate proxy server that handles SSL.
+ </para>
+
+ <para>
+ SSL setup can be tricky, but the configuration in CouchDB was
+ designed to be as easy as possible. All you need is two files; a
+ certificate and a private key. If you bought an official SSL
+ certificate from a certificate authority, both should be in your
+ possession already.
+ </para>
+
+ <para>
+ If you just want to try this out and don't want to pay anything
+ upfront, you can create a self-signed certificate. Everything will
+ work the same, but clients will get a warning about an insecure
+ certificate.
+ </para>
+
+ <para>
+ You will need the OpenSSL command line tool installed. It probably
+ already is.
+ </para>
+
+<programlisting>
+shell> <userinput>mkdir cert && cd cert</userinput>
+shell> <userinput>openssl genrsa > privkey.pem</userinput>
+shell> <userinput>openssl req -new -x509 -key privkey.pem -out mycert.pem -days 1095</userinput>
+shell> <userinput>ls</userinput>
+mycert.pem privkey.pem
+</programlisting>
+
+ <para>
+ Now, you need to edit CouchDB's configuration, either by editing
+ your <filename>local.ini</filename> file or using the
+ <literal>/_config</literal> API calls or the configuration screen
+ in Futon. Here is what you need to do in
+ <filename>local.ini</filename>, you can infer what needs doing in
+ the other places.
+ </para>
+
+ <para>
+ Be sure to make these edits. Under <literal>[daemons]</literal>
+ you should see:
+ </para>
+
+<programlisting>
+; enable SSL support by uncommenting the following line and supply the PEM's below.
+; the default ssl port CouchDB listens on is 6984
+;httpsd = {couch_httpd, start_link, [https]}
+</programlisting>
+
+ <para>
+ Here uncomment the last line:
+ </para>
+
+<programlisting>
+httpsd = {couch_httpd, start_link, [https]}
+</programlisting>
+
+ <para>
+ Next, under <literal>[ssl]</literal> you will see:
+ </para>
+
+<programlisting>
+;cert_file = /full/path/to/server_cert.pem
+;key_file = /full/path/to/server_key.pem
+</programlisting>
+
+ <para>
+ Uncomment and adjust the paths so it matches your system's paths:
+ </para>
+
+<programlisting>
+cert_file = /home/jan/cert/mycert.pem
+key_file = /home/jan/cert/privkey.pem
+</programlisting>
+
+ <para>
+ For more information please read
+ <ulink
+ url="http://www.openssl.org/docs/HOWTO/certificates.txt">http://www.openssl.org/docs/HOWTO/certificates.txt</ulink>.
+ </para>
+
+ <para>
+ Now start (or restart) CouchDB. You should be able to connect to
+ it using HTTPS on port 6984:
+ </para>
+
+<programlisting>
+shell> <userinput>curl https://127.0.0.1:6984/</userinput>
+curl: (60) SSL certificate problem, verify that the CA cert is OK. Details:
+error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
+More details here: http://curl.haxx.se/docs/sslcerts.html
+
+curl performs SSL certificate verification by default, using a "bundle"
+of Certificate Authority (CA) public keys (CA certs). If the default
+bundle file isn't adequate, you can specify an alternate file
+using the --cacert option.
+If this HTTPS server uses a certificate signed by a CA represented in
+the bundle, the certificate verification probably failed due to a
+problem with the certificate (it might be expired, or the name might
+not match the domain name in the URL).
+If you'd like to turn off curl's verification of the certificate, use
+the -k (or --insecure) option.
+</programlisting>
+
+ <para>
+ Oh no what happened?! — Remember, clients will notify their
+ users that your certificate is self signed.
+ <command>curl</command> is the client in this case and it notifies
+ you. Luckily you trust yourself (don't you?) and you can specify
+ the <option>-k</option> option as the message reads:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -k https://127.0.0.1:6984/</userinput>
+{"couchdb":"Welcome","version":"1.1.0"}
+</programlisting>
+
+ <para>
+ All done.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-httprange">
+
+ <title>HTTP Range Requests</title>
+
+ <para>
+ HTTP allows you to specify byte ranges for requests. This allows
+ the implementation of resumable downloads and skippable audio and
+ video streams alike. Now this is available for all attachments
+ inside CouchDB.
+ </para>
+
+ <para>
+ This is just a real quick run through how this looks under the
+ hood. Usually, you will have larger binary files to serve from
+ CouchDB, like MP3s and videos, but to make things a little more
+ obvious, I use a text file here (Note that I use the
+ <literal>application/octet-stream</literal> Content-Type instead
+ of <literal>text/plain</literal>).
+ </para>
+
+<programlisting>
+shell> <userinput>cat file.txt </userinput>
+My hovercraft is full of eels!
+</programlisting>
+
+ <para>
+ Now lets store this text file as an attachment in CouchDB. First,
+ we create a database:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -X PUT http://127.0.0.1:5984/test</userinput>
+{"ok":true}
+</programlisting>
+
+ <para>
+ Then we create a new document and the file attachment in one go:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -X PUT http://127.0.0.1:5984/test/doc/file.txt -H "Content-Type: application/octet-stream" -d@file.txt</userinput>
+{"ok":true,"id":"doc","rev":"1-287a28fa680ae0c7fb4729bf0c6e0cf2"}
+</programlisting>
+
+ <para>
+ Now we can request the whole file easily:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -X GET http://127.0.0.1:5984/test/doc/file.txt</userinput>
+My hovercraft is full of eels!
+</programlisting>
+
+ <para>
+ But say we only want the first 13 bytes:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -X GET http://127.0.0.1:5984/test/doc/file.txt -H "Range: bytes=0-12"</userinput>
+My hovercraft
+</programlisting>
+
+ <para>
+ HTTP supports many ways to specify single and even multiple byte
+ rangers. Read all about it in
+ <ulink
+ url="http://tools.ietf.org/html/rfc2616#section-14.27">RFC
+ 2616</ulink>.
+ </para>
+
+ <note>
+ <para>
+ Databases that have been created with CouchDB 1.0.2 or earlier
+ will support range requests in 1.1.0, but they are using a
+ less-optimal algorithm. If you plan to make heavy use of this
+ feature, make sure to compact your database with CouchDB 1.1.0
+ to take advantage of a better algorithm to find byte ranges.
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-proxying">
+
+ <title>HTTP Proxying</title>
+
+ <para>
+ The HTTP proxy feature makes it easy to map and redirect different
+ content through your CouchDB URL. The proxy works by mapping a
+ pathname and passing all content after that prefix through to the
+ configured proxy address.
+ </para>
+
+ <para>
+ Configuration of the proxy redirect is handled through the
+ <literal>[httpd_global_handlers]</literal> section of the CouchDB
+ configuration file (typically <filename>local.ini</filename>). The
+ format is:
+ </para>
+
+<programlisting>
+[httpd_global_handlers]
+PREFIX = {couch_httpd_proxy, handle_proxy_req, <<"DESTINATION">>}
+ </programlisting>
+
+ <para>
+ Where:
+ </para>
+
+ <itemizedlist>
+
+ <listitem>
+ <para>
+ <literal>PREFIX</literal>
+ </para>
+
+ <para>
+ Is the string that will be matched. The string can be any
+ valid qualifier, although to ensure that existing database
+ names are not overridden by a proxy configuration, you can use
+ an underscore prefix.
+ </para>
+ </listitem>
+
+ <listitem>
+ <para>
+ <literal>DESTINATION</literal>
+ </para>
+
+ <para>
+ The fully-qualified URL to which the request should be sent.
+ The destination must include the <literal>http</literal>
+ prefix. The content is used verbatim in the original request,
+ so you can also forward to servers on different ports and to
+ specific paths on the target host.
+ </para>
+ </listitem>
+
+ </itemizedlist>
+
+ <para>
+ The proxy process then translates requests of the form:
+ </para>
+
+<programlisting>
+http://couchdb:5984/PREFIX/path
+</programlisting>
+
+ <para>
+ To:
+ </para>
+
+<programlisting>
+DESTINATION/path
+</programlisting>
+
+ <note>
+ <para>
+ Everything after <literal>PREFIX</literal> including the
+ required forward slash will be appended to the
+ <literal>DESTINATION</literal>.
+ </para>
+ </note>
+
+ <para>
+ The response is then communicated back to the original client.
+ </para>
+
+ <para>
+ For example, the following configuration:
+ </para>
+
+<programlisting>
+<![CDATA[
+_google = {couch_httpd_proxy, handle_proxy_req, <<"http://www.google.com">>}]]>
+</programlisting>
+
+ <para>
+ Would forward all requests for
+ <literal>http://couchdb:5984/_google</literal> to the Google
+ website.
+ </para>
+
+ <para>
+ The service can also be used to forward to related CouchDB
+ services, such as Lucene:
+ </para>
+
+<programlisting>
+ <![CDATA[
+[httpd_global_handlers]
+_fti = {couch_httpd_proxy, handle_proxy_req, <<"http://127.0.0.1:5985">>}]]>
+</programlisting>
+
+ <note>
+ <para>
+ The proxy service is basic. If the request is not identified by
+ the <literal>DESTINATION</literal>, or the remainder of the
+ <literal>PATH</literal> specification is incomplete, the
+ original request URL is interpreted as if the
+ <literal>PREFIX</literal> component of that URL does not exist.
+ </para>
+
+ <para>
+ For example, requesting
+ <literal>http://couchdb:5984/_intranet/media</literal> when
+ <filename>/media</filename> on the proxy destination does not
+ exist, will cause the request URL to be interpreted as
+ <literal>http://couchdb:5984/media</literal>. Care should be
+ taken to ensure that both requested URLs and destination URLs
+ are able to cope
+ </para>
+ </note>
+
+ </section>
+
+ <section id="couchdb-release-1.1-commonjs">
+
+ <title>Added CommonJS support to map functions</title>
+
+ <para>
+ We didn't have CommonJS require in map functions because the
+ current CommonJS implementation is scoped to the whole design doc,
+ and giving views access to load code from anywhere in the design
+ doc would mean we'd have to blow away your view index any time you
+ changed anything. Having to rebuild views from scratch just
+ because you changed some CSS or a show function isn't fun, so we
+ avoided the issue by keeping CommonJS require out of map and
+ reduce altogether.
+ </para>
+
+ <para>
+ The solution we came up with is to allow CommonJS inside map and
+ reduce funs, but only of libraries that are stored inside the
+ views part of the design doc.
+ </para>
+
+ <para>
+ So you could continue to access CommonJS code in design_doc.foo,
+ from your list functions etc, but we'd add the ability to require
+ CommonJS modules within map and reduce, but only from
+ design_doc.views.lib
+ </para>
+
+ <para>
+ There's no worry here about namespace collisions, as Couch just
+ plucks <literal>views.*.map</literal> and
+ <literal>views.*.reduce</literal> out of the design doc. So you
+ could have a view called <literal>lib</literal> if you wanted, and
+ still have CommonJS stored in <literal>views.lib.sha1</literal>
+ and <literal>views.lib.stemmer</literal> if you wanted.
+ </para>
+
+ <para>
+ We simplified the implementation by enforcing that CommonJS
+ modules to be used in map functions be stored in views.lib.
+ </para>
+
+ <para>
+ A sample design doc (taken from the test suite in Futon) is below:
+ </para>
+
+<programlisting>
+{
+ "views" : {
+ "lib" : {
+ "baz" : "exports.baz = 'bam';",
+ "foo" : {
+ "zoom" : "exports.zoom = 'yeah';",
+ "boom" : "exports.boom = 'ok';",
+ "foo" : "exports.foo = 'bar';"
+ }
+ },
+ "commonjs" : {
+ "map" : "function(doc) { emit(null, require('views/lib/foo/boom').boom)}"
+ }
+ },
+ "_id" : "_design/test"
+}
+</programlisting>
+
+ <para>
+ The <literal>require()</literal> statement is relative to the
+ design document, but anything loaded form outside of
+ <literal>views/lib</literal> will fail.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-etag">
+
+ <title>More granular ETag support for views</title>
+
+ <para>
+ ETags have been assigned to a map/reduce group (the collection of
+ views in a single design document). Any change to any of the
+ indexes for those views would generate a new ETag for all view
+ URL's in a single design doc, even if that specific view's results
+ had not changed.
+ </para>
+
+ <para>
+ In CouchDB 1.1 each <literal>_view</literal> URL has it's own ETag
+ which only gets updated when changes are made to the database that
+ effect that index. If the index for that specific view does not
+ change, that view keeps the original ETag head (therefore sending
+ back 304 Not Modified more often).
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-filters">
+
+ <title>Added built-in filters for <literal>_changes</literal>:
+ <literal>_doc_ids</literal> and <literal>_design</literal>.</title>
+
+ <para>
+ The <literal>_changes</literal> feed can now be used to watch
+ changes to specific document ID's or the list of
+ <literal>_design</literal> documents in a database. If the
+ <literal>filters</literal> parameter is set to
+ <literal>_doc_ids</literal> a list of doc IDs can be passed in the
+ "doc_ids" as a JSON array.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-wildcards">
+
+ <title>Allow wildcards in vhosts definitions</title>
+
+ <para>
+ Similar to the rewrites section of a <literal>_design</literal>
+ document, the new <literal>vhosts</literal> system uses variables
+ in the form of :varname or wildcards in the form of asterisks. The
+ variable results can be output into the resulting path as they are
+ in the rewriter.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-osprocess">
+
+ <title>OS Daemons</title>
+
+ <para>
+ CouchDB now supports starting external processes. The support is
+ simple and enables CouchDB to start each configured OS daemon. If
+ the daemon stops at any point, CouchDB will restart it (with
+ protection to ensure regularly failing daemons are not repeatedly
+ restarted).
+ </para>
+
+ <para>
+ The daemon starting process is one-to-one; for each each
+ configured daemon in the configuration file, CouchDB will start
+ exactly one instance. If you need to run multiple instances, then
+ you must create separate individual configurations. Daemons are
+ configured within the <literal>[os_daemons]</literal> section of
+ your configuration file (<filename>local.ini</filename>). The
+ format of each configured daemon is:
+ </para>
+
+<programlisting>
+NAME = PATH ARGS
+ </programlisting>
+
+ <para>
+ Where <literal>NAME</literal> is an arbitrary (and unique) name to
+ identify the daemon; <literal>PATH</literal> is the full path to
+ the daemon to be executed; <literal>ARGS</literal> are any
+ required arguments to the daemon.
+ </para>
+
+ <para>
+ For example:
+ </para>
+
+<programlisting>
+[os_daemons]
+basic_responder = /usr/local/bin/responsder.js
+</programlisting>
+
+ <para>
+ There is no interactivity between CouchDB and the running process,
+ but you can use the OS Daemons service to create new HTTP servers
+ and responders and then use the new proxy service to redirect
+ requests and output to the CouchDB managed service. For more
+ information on proxying, see
+ <xref
+ linkend="couchdb-release-1.1-proxying"/>. For further
+ background on the OS Daemon service, see
+ <ulink url="http://davispj.com/2010/09/26/new-couchdb-externals-api.html">CouchDB
+ Externals API</ulink>
+ </para>
+
+ </section>
+
+ <section id="coudhdb-release-1.1-updateafter">
+
+ <title>Stale views and <literal>update_after</literal></title>
+
+ <para>
+ Currently a view request can include the
+ <literal>stale=ok</literal> query argument, which allows the
+ contents of a stale view index to be used to produce the view
+ output. In order to trigger a build of the outdated view index, a
+ second view request must be made.
+ </para>
+
+ <para>
+ To simplify this process, the <literal>update_after</literal>
+ value can be supplied to the <literal>stale</literal> query
+ argument. This triggers a rebuild of the view index after the
+ results of the view have been retrieved.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-socketoptions">
+
+ <title>Socket Options Configuration Setting</title>
+
+ <para>
+ The socket options for the listening socket in CouchDB can now be
+ set within the CouchDB configuration file. The setting should be
+ added to the <literal>[httpd]</literal> section of the file using
+ the option name <literal>socket_options</literal>. The
+ specification is as a list of tuples. For example:
+ </para>
+
+<programlisting>
+[httpd]
+socket_options = [{recbuf, 262144}, {sndbuf, 262144}, {nodelay, true}]
+</programlisting>
+
+ <para>
+ The options supported are a subset of full options supported by
+ the TCP/IP stack. A list of the supported options are provided in
+ the
+ <ulink
+ url="http://www.erlang.org/doc/man/inet.html#setopts-2">Erlang
+ inet</ulink> documentation.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-serveroptions">
+
+ <title>Server Options Configuration Setting</title>
+
+ <para>
+ Server options for the MochiWeb component of CouchDB can now be
+ added to the configuration file. Settings should be added to the
+ <literal>server_options</literal> option of the
+ <literal>[httpd]</literal> section of
+ <filename>local.ini</filename>. For example:
+ </para>
+
+<programlisting>
+[httpd]
+server_options = [{backlog, 128}, {acceptor_pool_size, 16}]
+ </programlisting>
+
+ </section>
+
+ <section id="couchdb-release-1.1-errormessages">
+
+ <title>Improved Error Messages</title>
+
+ <para>
+ The errors reported when CouchDB is unable to read a required file
+ have been updated so that explicit information about the files and
+ problem can now be identified from the error message. The errors
+ report file permission access either when reading or writing to
+ configuration and database files.
+ </para>
+
+ <para>
+ The error is raised both through the log file and the error
+ message returned through the API call as a JSON error message. For
+ example, when setting configuration values:
+ </para>
+
+<programlisting>
+shell> <userinput>curl -H 'X-Couch-Persist: true' -X PUT http://couchdb:5984/_config/couchdb/delayed_commits -d '"false"'</userinput>
+{"error":"file_permission_error","reason":"/etc/couchdb/local.ini"}
+ </programlisting>
+
+ <para>
+ Errors will always be reported using the
+ <literal>file_permission_error</literal> error type.
+ </para>
+
+ <para>
+ During startup permissions errors on key files are also reported
+ in the log with a descriptive error message and file location so
+ that permissions can be fixed before restart.
+ </para>
+
+ </section>
+
+ <section id="couchdb-release-1.1-microoptimizations">
+
+ <title>Multiple micro-optimizations when reading data.</title>
+
+ <para>
+ We found a number of places where CouchDB wouldn't do the absolute
+ optimal thing when reading data and got rid of quite a few
+ inefficiencies. The problem with small optimizations all over the
+ place is that you may not notice them with every use-case, but we
+ sure hope you can see an improvement overall.
+ </para>
+
+ </section>
+
+</article>