You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@couchdb.apache.org by Matt Goodall <ma...@gmail.com> on 2009/11/18 23:56:02 UTC

Deleted docs can be accidentally resurrected

Hi,

I swear I've reported this odd behaviour before but I can't find any
mention of it now ...

I have some code with a race condition that is caused by what I
believe is a bug in CouchDB - a deleted document can be updated using
an old, valid rev.

If a document has not been deleted then CouchDB correctly returns a
conflict error if the latest rev is not sent. However, once deleted,
any rev in the docs history can be sent as the update and, as long as
the doc is changed in some way, the document will be resurrected with
a rev whose sequence is 1 more than that sent in the update.

Create new doc ...
$ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
{"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}

Update a couple of times to move the rev on ...
$ curl -X "PUT" -d '{"_id": "foo", "_rev":
"1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
{"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
$ curl -X "PUT" -d '{"_id": "foo", "_rev":
"2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
{"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}

Delete the doc ...
$ curl -X "DELETE"
"http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}

Update using an old rev, changing something ...
$ curl -X "PUT" -d '{"_id": "foo", "_rev":
"1-967a00dff5e02add41819138abb3284d", "num": 1}'
http://localhost:15984/test/foo
{"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}

Now, I can sort of understand how something like that might happen
during replication but there's no replication going on here and
there's no conflict created in the database.

I can't think of a way around the problem at the moment, other than
marking the document for deletion and then sweeping it later when
something else is hopefully not going to be touching the document.
But, frankly, that's horrible,

- Matt

Re: Deleted docs can be accidentally resurrected

Posted by Adam Kocoloski <ko...@apache.org>.
On Nov 20, 2009, at 5:01 AM, Matt Goodall wrote:

> 2009/11/20 Matt Goodall <ma...@gmail.com>:
>> 2009/11/19 Adam Kocoloski <ko...@apache.org>:
>>> On Nov 18, 2009, at 6:51 PM, Matt Goodall wrote:
>>> 
>>>> 2009/11/18 Sebastian Cohnen <se...@googlemail.com>:
>>>>> afaik, this behavior is normal. you just created another (and new) resource/document.
>>>>> 
>>>>> have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):
>>>>> 
>>>>> $ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
>>>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>>> 
>>>>> $ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
>>>>> {"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}
>>>> 
>>>> Hmm, seems wrong to me although I can imagine that's useful during
>>>> replication (which doesn't mean it should work for a PUT). However,
>>>> why does the following fail then:
>>>> 
>>>> $ curl -X "PUT" -d '{}' "http://localhost:15984/test/foo"
>>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>> "1-967a00dff5e02add41819138abb3284d"}'
>>>> "http://localhost:15984/test/foo"
>>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>>> $ curl -X "DELETE"
>>>> "http://localhost:15984/test/foo?rev=2-7051cbe5c8faecd085a3fa619e6e6337"
>>>> {"ok":true,"id":"foo","rev":"3-7379b9e515b161226c6559d90c4dc49f"}
>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>> "1-967a00dff5e02add41819138abb3284d"}'
>>>> "http://localhost:15984/test/foo"
>>>> {"error":"conflict","reason":"Document update conflict."}
>>>> 
>>>> - Matt
>>>> 
>>>>> 
>>>>> 
>>>>> cheers,
>>>>> 
>>>>> tisba / Sebastian
>>>>> 
>>>>> On 18.11.2009, at 23:56, Matt Goodall wrote:
>>>>> 
>>>>>> Hi,
>>>>>> 
>>>>>> I swear I've reported this odd behaviour before but I can't find any
>>>>>> mention of it now ...
>>>>>> 
>>>>>> I have some code with a race condition that is caused by what I
>>>>>> believe is a bug in CouchDB - a deleted document can be updated using
>>>>>> an old, valid rev.
>>>>>> 
>>>>>> If a document has not been deleted then CouchDB correctly returns a
>>>>>> conflict error if the latest rev is not sent. However, once deleted,
>>>>>> any rev in the docs history can be sent as the update and, as long as
>>>>>> the doc is changed in some way, the document will be resurrected with
>>>>>> a rev whose sequence is 1 more than that sent in the update.
>>>>>> 
>>>>>> Create new doc ...
>>>>>> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
>>>>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>>>>> 
>>>>>> Update a couple of times to move the rev on ...
>>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>>> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
>>>>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>>> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
>>>>>> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
>>>>>> 
>>>>>> Delete the doc ...
>>>>>> $ curl -X "DELETE"
>>>>>> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
>>>>>> 
>>>>>> Update using an old rev, changing something ...
>>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>>> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
>>>>>> http://localhost:15984/test/foo
>>>>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>>>> 
>>>>>> Now, I can sort of understand how something like that might happen
>>>>>> during replication but there's no replication going on here and
>>>>>> there's no conflict created in the database.
>>>>>> 
>>>>>> I can't think of a way around the problem at the moment, other than
>>>>>> marking the document for deletion and then sweeping it later when
>>>>>> something else is hopefully not going to be touching the document.
>>>>>> But, frankly, that's horrible,
>>>>>> 
>>>>>> - Matt
>>> 
>>> Hi Matt, bizarre.  Your latest email shows the behavior I expect -- you tried to PUT a document using an incorrect MVCC revision, and you got a conflict as a result.  A successful PUT of a new document with an _id that corresponds to a previously deleted document should omit the MVCC rev.
>> 
>> Yep, I only posted that (it's what I would expect too) to demonstrate
>> how weird the problem is.
>> 
>>> 
>>> Your first email is the weird one -- you supplied an old MVCC _rev, but changed the body to something different than the body at the time the doc was deleted, and it worked.  I can confirm this.  Can you file a JIRA ticket?  Best,
>> 
>> Exactly. If there's a rev then it should match the current rev of the
>> doc or fail.
>> 
>> I'll file a ticket tomorrow morning.
> 
> There's a ticket for it already actually,
> https://issues.apache.org/jira/browse/COUCHDB-292. The ticket also
> contains a still failing test.
> 
> - Matt

A test submitted by you over 6 months ago, no less!  I need to spend more time looking at the JIRA backlog.  Thanks,

Adam


Re: Deleted docs can be accidentally resurrected

Posted by Matt Goodall <ma...@gmail.com>.
2009/11/20 Matt Goodall <ma...@gmail.com>:
> 2009/11/19 Adam Kocoloski <ko...@apache.org>:
>> On Nov 18, 2009, at 6:51 PM, Matt Goodall wrote:
>>
>>> 2009/11/18 Sebastian Cohnen <se...@googlemail.com>:
>>>> afaik, this behavior is normal. you just created another (and new) resource/document.
>>>>
>>>> have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):
>>>>
>>>> $ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
>>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>>
>>>> $ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
>>>> {"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}
>>>
>>> Hmm, seems wrong to me although I can imagine that's useful during
>>> replication (which doesn't mean it should work for a PUT). However,
>>> why does the following fail then:
>>>
>>> $ curl -X "PUT" -d '{}' "http://localhost:15984/test/foo"
>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>> "1-967a00dff5e02add41819138abb3284d"}'
>>> "http://localhost:15984/test/foo"
>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>> $ curl -X "DELETE"
>>> "http://localhost:15984/test/foo?rev=2-7051cbe5c8faecd085a3fa619e6e6337"
>>> {"ok":true,"id":"foo","rev":"3-7379b9e515b161226c6559d90c4dc49f"}
>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>> "1-967a00dff5e02add41819138abb3284d"}'
>>> "http://localhost:15984/test/foo"
>>> {"error":"conflict","reason":"Document update conflict."}
>>>
>>> - Matt
>>>
>>>>
>>>>
>>>> cheers,
>>>>
>>>> tisba / Sebastian
>>>>
>>>> On 18.11.2009, at 23:56, Matt Goodall wrote:
>>>>
>>>>> Hi,
>>>>>
>>>>> I swear I've reported this odd behaviour before but I can't find any
>>>>> mention of it now ...
>>>>>
>>>>> I have some code with a race condition that is caused by what I
>>>>> believe is a bug in CouchDB - a deleted document can be updated using
>>>>> an old, valid rev.
>>>>>
>>>>> If a document has not been deleted then CouchDB correctly returns a
>>>>> conflict error if the latest rev is not sent. However, once deleted,
>>>>> any rev in the docs history can be sent as the update and, as long as
>>>>> the doc is changed in some way, the document will be resurrected with
>>>>> a rev whose sequence is 1 more than that sent in the update.
>>>>>
>>>>> Create new doc ...
>>>>> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
>>>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>>>>
>>>>> Update a couple of times to move the rev on ...
>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
>>>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
>>>>> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
>>>>>
>>>>> Delete the doc ...
>>>>> $ curl -X "DELETE"
>>>>> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
>>>>>
>>>>> Update using an old rev, changing something ...
>>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>>> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
>>>>> http://localhost:15984/test/foo
>>>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>>>
>>>>> Now, I can sort of understand how something like that might happen
>>>>> during replication but there's no replication going on here and
>>>>> there's no conflict created in the database.
>>>>>
>>>>> I can't think of a way around the problem at the moment, other than
>>>>> marking the document for deletion and then sweeping it later when
>>>>> something else is hopefully not going to be touching the document.
>>>>> But, frankly, that's horrible,
>>>>>
>>>>> - Matt
>>
>> Hi Matt, bizarre.  Your latest email shows the behavior I expect -- you tried to PUT a document using an incorrect MVCC revision, and you got a conflict as a result.  A successful PUT of a new document with an _id that corresponds to a previously deleted document should omit the MVCC rev.
>
> Yep, I only posted that (it's what I would expect too) to demonstrate
> how weird the problem is.
>
>>
>> Your first email is the weird one -- you supplied an old MVCC _rev, but changed the body to something different than the body at the time the doc was deleted, and it worked.  I can confirm this.  Can you file a JIRA ticket?  Best,
>
> Exactly. If there's a rev then it should match the current rev of the
> doc or fail.
>
> I'll file a ticket tomorrow morning.

There's a ticket for it already actually,
https://issues.apache.org/jira/browse/COUCHDB-292. The ticket also
contains a still failing test.

- Matt

Re: Deleted docs can be accidentally resurrected

Posted by Matt Goodall <ma...@gmail.com>.
2009/11/19 Adam Kocoloski <ko...@apache.org>:
> On Nov 18, 2009, at 6:51 PM, Matt Goodall wrote:
>
>> 2009/11/18 Sebastian Cohnen <se...@googlemail.com>:
>>> afaik, this behavior is normal. you just created another (and new) resource/document.
>>>
>>> have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):
>>>
>>> $ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>
>>> $ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
>>> {"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}
>>
>> Hmm, seems wrong to me although I can imagine that's useful during
>> replication (which doesn't mean it should work for a PUT). However,
>> why does the following fail then:
>>
>> $ curl -X "PUT" -d '{}' "http://localhost:15984/test/foo"
>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>> "1-967a00dff5e02add41819138abb3284d"}'
>> "http://localhost:15984/test/foo"
>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>> $ curl -X "DELETE"
>> "http://localhost:15984/test/foo?rev=2-7051cbe5c8faecd085a3fa619e6e6337"
>> {"ok":true,"id":"foo","rev":"3-7379b9e515b161226c6559d90c4dc49f"}
>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>> "1-967a00dff5e02add41819138abb3284d"}'
>> "http://localhost:15984/test/foo"
>> {"error":"conflict","reason":"Document update conflict."}
>>
>> - Matt
>>
>>>
>>>
>>> cheers,
>>>
>>> tisba / Sebastian
>>>
>>> On 18.11.2009, at 23:56, Matt Goodall wrote:
>>>
>>>> Hi,
>>>>
>>>> I swear I've reported this odd behaviour before but I can't find any
>>>> mention of it now ...
>>>>
>>>> I have some code with a race condition that is caused by what I
>>>> believe is a bug in CouchDB - a deleted document can be updated using
>>>> an old, valid rev.
>>>>
>>>> If a document has not been deleted then CouchDB correctly returns a
>>>> conflict error if the latest rev is not sent. However, once deleted,
>>>> any rev in the docs history can be sent as the update and, as long as
>>>> the doc is changed in some way, the document will be resurrected with
>>>> a rev whose sequence is 1 more than that sent in the update.
>>>>
>>>> Create new doc ...
>>>> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
>>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>>>
>>>> Update a couple of times to move the rev on ...
>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
>>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
>>>> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
>>>>
>>>> Delete the doc ...
>>>> $ curl -X "DELETE"
>>>> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
>>>>
>>>> Update using an old rev, changing something ...
>>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>>> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
>>>> http://localhost:15984/test/foo
>>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>>>
>>>> Now, I can sort of understand how something like that might happen
>>>> during replication but there's no replication going on here and
>>>> there's no conflict created in the database.
>>>>
>>>> I can't think of a way around the problem at the moment, other than
>>>> marking the document for deletion and then sweeping it later when
>>>> something else is hopefully not going to be touching the document.
>>>> But, frankly, that's horrible,
>>>>
>>>> - Matt
>
> Hi Matt, bizarre.  Your latest email shows the behavior I expect -- you tried to PUT a document using an incorrect MVCC revision, and you got a conflict as a result.  A successful PUT of a new document with an _id that corresponds to a previously deleted document should omit the MVCC rev.

Yep, I only posted that (it's what I would expect too) to demonstrate
how weird the problem is.

>
> Your first email is the weird one -- you supplied an old MVCC _rev, but changed the body to something different than the body at the time the doc was deleted, and it worked.  I can confirm this.  Can you file a JIRA ticket?  Best,

Exactly. If there's a rev then it should match the current rev of the
doc or fail.

I'll file a ticket tomorrow morning.

Thanks.

- Matt

>
> Adam

Re: Deleted docs can be accidentally resurrected

Posted by Adam Kocoloski <ko...@apache.org>.
On Nov 18, 2009, at 6:51 PM, Matt Goodall wrote:

> 2009/11/18 Sebastian Cohnen <se...@googlemail.com>:
>> afaik, this behavior is normal. you just created another (and new) resource/document.
>> 
>> have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):
>> 
>> $ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>> 
>> $ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
>> {"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}
> 
> Hmm, seems wrong to me although I can imagine that's useful during
> replication (which doesn't mean it should work for a PUT). However,
> why does the following fail then:
> 
> $ curl -X "PUT" -d '{}' "http://localhost:15984/test/foo"
> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
> "1-967a00dff5e02add41819138abb3284d"}'
> "http://localhost:15984/test/foo"
> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
> $ curl -X "DELETE"
> "http://localhost:15984/test/foo?rev=2-7051cbe5c8faecd085a3fa619e6e6337"
> {"ok":true,"id":"foo","rev":"3-7379b9e515b161226c6559d90c4dc49f"}
> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
> "1-967a00dff5e02add41819138abb3284d"}'
> "http://localhost:15984/test/foo"
> {"error":"conflict","reason":"Document update conflict."}
> 
> - Matt
> 
>> 
>> 
>> cheers,
>> 
>> tisba / Sebastian
>> 
>> On 18.11.2009, at 23:56, Matt Goodall wrote:
>> 
>>> Hi,
>>> 
>>> I swear I've reported this odd behaviour before but I can't find any
>>> mention of it now ...
>>> 
>>> I have some code with a race condition that is caused by what I
>>> believe is a bug in CouchDB - a deleted document can be updated using
>>> an old, valid rev.
>>> 
>>> If a document has not been deleted then CouchDB correctly returns a
>>> conflict error if the latest rev is not sent. However, once deleted,
>>> any rev in the docs history can be sent as the update and, as long as
>>> the doc is changed in some way, the document will be resurrected with
>>> a rev whose sequence is 1 more than that sent in the update.
>>> 
>>> Create new doc ...
>>> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
>>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>> 
>>> Update a couple of times to move the rev on ...
>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
>>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
>>> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
>>> 
>>> Delete the doc ...
>>> $ curl -X "DELETE"
>>> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
>>> 
>>> Update using an old rev, changing something ...
>>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>>> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
>>> http://localhost:15984/test/foo
>>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>> 
>>> Now, I can sort of understand how something like that might happen
>>> during replication but there's no replication going on here and
>>> there's no conflict created in the database.
>>> 
>>> I can't think of a way around the problem at the moment, other than
>>> marking the document for deletion and then sweeping it later when
>>> something else is hopefully not going to be touching the document.
>>> But, frankly, that's horrible,
>>> 
>>> - Matt

Hi Matt, bizarre.  Your latest email shows the behavior I expect -- you tried to PUT a document using an incorrect MVCC revision, and you got a conflict as a result.  A successful PUT of a new document with an _id that corresponds to a previously deleted document should omit the MVCC rev.

Your first email is the weird one -- you supplied an old MVCC _rev, but changed the body to something different than the body at the time the doc was deleted, and it worked.  I can confirm this.  Can you file a JIRA ticket?  Best,

Adam

Re: Deleted docs can be accidentally resurrected

Posted by Matt Goodall <ma...@gmail.com>.
2009/11/18 Sebastian Cohnen <se...@googlemail.com>:
> afaik, this behavior is normal. you just created another (and new) resource/document.
>
> have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):
>
> $ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>
> $ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
> {"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}

Hmm, seems wrong to me although I can imagine that's useful during
replication (which doesn't mean it should work for a PUT). However,
why does the following fail then:

$ curl -X "PUT" -d '{}' "http://localhost:15984/test/foo"
{"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
$ curl -X "PUT" -d '{"_id": "foo", "_rev":
"1-967a00dff5e02add41819138abb3284d"}'
"http://localhost:15984/test/foo"
{"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
$ curl -X "DELETE"
"http://localhost:15984/test/foo?rev=2-7051cbe5c8faecd085a3fa619e6e6337"
{"ok":true,"id":"foo","rev":"3-7379b9e515b161226c6559d90c4dc49f"}
$ curl -X "PUT" -d '{"_id": "foo", "_rev":
"1-967a00dff5e02add41819138abb3284d"}'
"http://localhost:15984/test/foo"
{"error":"conflict","reason":"Document update conflict."}

- Matt

>
>
> cheers,
>
> tisba / Sebastian
>
> On 18.11.2009, at 23:56, Matt Goodall wrote:
>
>> Hi,
>>
>> I swear I've reported this odd behaviour before but I can't find any
>> mention of it now ...
>>
>> I have some code with a race condition that is caused by what I
>> believe is a bug in CouchDB - a deleted document can be updated using
>> an old, valid rev.
>>
>> If a document has not been deleted then CouchDB correctly returns a
>> conflict error if the latest rev is not sent. However, once deleted,
>> any rev in the docs history can be sent as the update and, as long as
>> the doc is changed in some way, the document will be resurrected with
>> a rev whose sequence is 1 more than that sent in the update.
>>
>> Create new doc ...
>> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
>> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
>>
>> Update a couple of times to move the rev on ...
>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
>> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
>> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
>>
>> Delete the doc ...
>> $ curl -X "DELETE"
>> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
>>
>> Update using an old rev, changing something ...
>> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
>> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
>> http://localhost:15984/test/foo
>> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
>>
>> Now, I can sort of understand how something like that might happen
>> during replication but there's no replication going on here and
>> there's no conflict created in the database.
>>
>> I can't think of a way around the problem at the moment, other than
>> marking the document for deletion and then sweeping it later when
>> something else is hopefully not going to be touching the document.
>> But, frankly, that's horrible,
>>
>> - Matt
>
>

Re: Deleted docs can be accidentally resurrected

Posted by Sebastian Cohnen <se...@googlemail.com>.
afaik, this behavior is normal. you just created another (and new) resource/document.

have a look (the database test is new and never contained docs with id 'foo' or 'foobar'):

$ curl -X PUT -d '{"_id": "foo", "_rev": "1-967a00dff5e02add41819138abb3284d", "num": 1}' "http://localhost:5984/test/foo"
{"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}

$ curl -X PUT -d '{"_id": "foobar", "_rev": "4-anythingyouwant", "num": 1}' "http://localhost:5984/test/foobar"
{"ok":true,"id":"foobar","rev":"5-084106c9189a346875996e76c1833630"}


cheers,

tisba / Sebastian

On 18.11.2009, at 23:56, Matt Goodall wrote:

> Hi,
> 
> I swear I've reported this odd behaviour before but I can't find any
> mention of it now ...
> 
> I have some code with a race condition that is caused by what I
> believe is a bug in CouchDB - a deleted document can be updated using
> an old, valid rev.
> 
> If a document has not been deleted then CouchDB correctly returns a
> conflict error if the latest rev is not sent. However, once deleted,
> any rev in the docs history can be sent as the update and, as long as
> the doc is changed in some way, the document will be resurrected with
> a rev whose sequence is 1 more than that sent in the update.
> 
> Create new doc ...
> $ curl -X "PUT" -d '{"_id": "foo"}' http://localhost:15984/test/foo
> {"ok":true,"id":"foo","rev":"1-967a00dff5e02add41819138abb3284d"}
> 
> Update a couple of times to move the rev on ...
> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
> "1-967a00dff5e02add41819138abb3284d"}' http://localhost:15984/test/foo
> {"ok":true,"id":"foo","rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}
> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
> "2-7051cbe5c8faecd085a3fa619e6e6337"}' http://localhost:15984/test/foo
> {"ok":true,"id":"foo","rev":"3-825cb35de44c433bfb2df415563a19de"}
> 
> Delete the doc ...
> $ curl -X "DELETE"
> "http://localhost:15984/test/foo?rev=3-825cb35de44c433bfb2df415563a19de"{"ok":true,"id":"foo","rev":"4-1df13287548620bf858cf9d1b810972a"}
> 
> Update using an old rev, changing something ...
> $ curl -X "PUT" -d '{"_id": "foo", "_rev":
> "1-967a00dff5e02add41819138abb3284d", "num": 1}'
> http://localhost:15984/test/foo
> {"ok":true,"id":"foo","rev":"2-65371ad05fc99a9b794f68c6003bc8da"}
> 
> Now, I can sort of understand how something like that might happen
> during replication but there's no replication going on here and
> there's no conflict created in the database.
> 
> I can't think of a way around the problem at the moment, other than
> marking the document for deletion and then sweeping it later when
> something else is hopefully not going to be touching the document.
> But, frankly, that's horrible,
> 
> - Matt