[dev] IStorage.lastOID() proposal (was Re: [dev] RFC IMVCCStorage everywhere (Move ZODB's MVCC to storage layer))

Jim Fulton <[email protected]>
Newsgroups gmane.comp.web.zope.zodb
Message-ID <CAPDm-FgR82=cSQ138EmBrSni_Ri5xM0v=8+c1qW4UouyPUGH2Q@mail.gmail.com>
On Thu, Jun 16, 2016 at 10:43 AM, Julien Muchembled <[email protected]> wrote:
> Le 06/16/16 14:46, Jim Fulton a écrit :
...
>>> 2. IStorage.lastOID() ?
>>
>> You need to be more specific. This doesn't exist, so I guess you're
>> proposing this.
>
> Yes.
>
>>> We'd use it to migrate databases to NEO. Currently, we hack by calling new_oid(), without actually modifying the DB, which prevent us from opening a ZODB in read-only.
>>>
>>> I know you suggested a different way to implement transparent migration, but the memory cost is in O(number of oids) and it is quite a lot of non-trivial changes in NEO whereas the current implementation has already been well-tested.
>>>
>>> In ZODB, this would very little change, which I'm ready to do. Same for RelStorage (3 simple methods in adapters + 1 relstorage.py). For ZEO, a new simple rpc is needed.
>>
>> I don't know what you're proposing exactly or what problem it's
>> solving. You need to be more specific.
>
> In order to migrate transparently several ZODB into a single NEO DB, we need the greatest committed oid of each source, so we easily stack oids range (then pickles are transformed on the fly to map oids). The oids from the first source DB don't change (except for mount points), those are other source DBs are shifted. The sum of all last_oid is the new last_oid, and new oids are allocated from there.

Is anything else is writing to the destination database?

(Apologies, you explained this to me before, but it's been a while...)

>
> For example, the BaseStorage implementation (which applies to FileStorage) would be:
>
>   def lastOID(self): # or last_oid ?
>     return self._oid

So, the problem I have with  lastOID is that it assumes that OIDs are
allocated sequentially.  This is what is mostly done now, but it has
issues, in particular, clients have to reserve oids by calling
new_oid()

- ZEO (and I assume NEO and RelStorage) have to make server calls. ZEO
mitigates this by
  requesting multiple reservations in a single server call.

- If clients don't commit, the reserved oids are wasted. There are
1<<64 possible IDs, so this is OK.

And of course, sequentially allocating IODs makes merging storages difficult.

An alternative I've been considering us to allocate OIDs randomly:

- With 1<<64 possible values, collisions are wildly unlikely, even
when merging databases

- Collisions are easily detected.  When store is called with a serial
of None or z64 (maybe we should pick one), then we know we're adding a
new object and we can check that the oid isn't being used.

- When we detect a collision, we can raise a transient error causing
the request to be retried.

Storages actually do the collision check today by accident.  If you
create an object with an oid that's in use, the serial you pass won't
match the stored serial and you'll get a conflict error.  This could
be refined by providing a more specific exception.

This would greatly simplify your database merging problem as well as a
similar problem in DemoStorage.  It would allow some storages to stop
making server calls to allocate oids.  You might not even have to
reallocate oids, or reallocate oids only be exception. You could even
merge to a database that was being written to.

Ane issue might be with the restore method. It doesn't check for oid
collisions, even by accident and would need to if you were merging
multiple databases.

Man, I've 97% talked myself into allocating oids randomly in ZEO. :)

Jim

P.S. When I first started thinking about this some time ago, I was
thinking of using UUIDs, but given that detecting and handling
collisions is easy, I think we can get by with 64 bits. :)

-- 
Jim Fulton
http://jimfulton.info

-- 
You received this message because you are subscribed to the Google Groups "zodb" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
For more options, visit https://groups.google.com/d/optout.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.