Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Joshua
wendelin.core
Commits
3406b26d
Commit
3406b26d
authored
Dec 10, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
eb53b7aa
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
56 additions
and
26 deletions
+56
-26
zrace.py
zrace.py
+56
-26
No files found.
zrace.py
View file @
3406b26d
#!/usr/bin/env python
#!/usr/bin/env python
"""Program zopenrace.py demonstrates race-condition bug in ZODB
"""Program zopenrace.py demonstrates concurrency bug in ZODB Connection.open()
Connection.open() that leads to stale live cache and wrong data provided by
that leads to stale live cache and wrong data provided by database to users.
database to users.
The bug is that when a connection is opened, it syncs to storage and processes
invalidations received from the storage in two _separate_ steps, potentially
newTransaction
leading to situation where invalidations for transactions _past_ opened
._storage.sync()
connection's view of the database are included into opened connection's cache
invalidated = ._storage.poll_invalidations():
invalidation. This leads to stale connection cache and old data provided by
ZODB.Connection when it is reopened next time.
._storage._start = ._storage._storage.lastTrasaction() + 1:
s = ._storage._storage
That in turn can lead to loose of Consistency of the database if mix of current
s._lock.acquire()
and old data is used to process a transaction. A classic example would be bank
head = s._ltid
accounts A, B and C with A<-B and A<-C transfer transactions. If transaction
s._lock.release()
that handles A<-C sees stale data for A when starting its processing, it
return head
results in A loosing what it should have received from B.
XXX T2 commits here: objX
Below is timing diagram on how the bug happens on ZODB5:
._storage._lock.acquire()
r = _storage._invalidations ; T1 receives invalidations for some transactions after head
Client1 or Thread1 Client2 or Thread2
._storage._lock.release()
return r
# T1 begins transaction and opens zodb connection
newTransaction():
# T1 processes invalidates for [... head] _and_ some next transactions.
# implementation in Connection.py[1]
# T1 thus will _not_ process invalidations for those next transactions when
._storage.sync()
# opening zconn _next_ time. The next opened zconn will thus see _stale_ data.
invalidated = ._storage.poll_invalidations():
._cache.invalidate(invalidated)
# implementation in MVCCAdapterInstance [2]
# T1 settles on as of which particular database state it will be
# viewing the database.
._storage._start = ._storage._storage.lastTrasaction() + 1:
s = ._storage._storage
s._lock.acquire()
head = s._ltid
s._lock.release()
return head
# T2 commits here.
# Time goes by and storage server sends
# corresponding invalidation message to T1,
# which T1 queues in its _storage._invalidations
# T1 retrieves queued invalidations which _includes_
# invalidation for transaction that T2 just has committed,
# that goes past @head.
._storage._lock.acquire()
r = _storage._invalidations
._storage._lock.release()
return r
# T1 processes invalidations for [... head] _and_ invalidations for past-@head transaction.
# T1 thus will _not_ process invalidations for that next transaction when
# opening zconn _next_ time. The next opened zconn will thus see _stale_ data.
._cache.invalidate(invalidated)
[1] https://github.com/zopefoundation/ZODB/blob/5.5.1-29-g0b3db5aee/src/ZODB/Connection.py#L734-L742
[2] https://github.com/zopefoundation/ZODB/blob/5.5.1-29-g0b3db5aee/src/ZODB/mvccadapter.py#L130-L139
"""
"""
from
ZODB
import
DB
from
ZODB
import
DB
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment