I posted some questions about how the delete/update is done, those
answers would help me understand better what is needed for a solution.

I am going to start a separate thread concentrating on RowLocation
guarantees from store.

Some other answers below.

Andreas Korneliussen wrote:

> Mike Matrigali wrote:
> 
>> There are very few cross thread dependencies not managed by locks
>> currently.  These things add extra complications to current and
>> future code.  Also I want to understand clearly the new restrictions
>> be imposted on the access methods (both current and possible
>> future).  In the future we would like to do more automatic space
>> reclamation as part of the zero-admin goal, the ability to do this
>> in the future internal to access methods is probably affected by
>> the proposals here.
>>
> 
> I think the complexities are there already. It seems very hard to know
> under exactly which conditions, a RowLocation remains valid.  We have
> assumed that the RowLocation will remain valid as long as we hold a
> table intent lock (valid means that it either points to the same row or
> to a deleted row).
> 
> That is what we concluded from the previous discusssion about validity
> of RowLocation. If you in the future need to make code, or there already
> is code, which breaks this assumption, we would need to know which other
> mechanisms we should use to either verify that the RowLocation is valid,
> or to block the system to make it invalid.
There is already code that breaks this assumption, the in place compress
table.  It currently is only executed as a call to a system procedure:
http://db.apache.org/derby/docs/dev/ref/rrefproceduresinplacecompress.html

But the hope was in the future to do the same kind of work that this
procedure does, internally in background.

As you have already determined that off-line compress is even more of a
problem, but it does run under an exclusive table lock.  After it runs
the container you were connected to does not even exist any more.

> 
> Locks can be used to manage cross thread dependencies, however they are
> bound to the transaction, and therefore does not help very much for
> cursors held across commits. So if the only mechanism we can have to
> ensure that the RowLocations are valid, is by the means of locks, I
> doubt we can support the feature of scrollable insensitive *holdable*
> updatable resultset.

I agree, I don't believe derby is currently architected to correctly
implement "holdable" SUR.  I don't think the outside event driven
approach is the right way to go.
> 
>> It is true that the current access methods don't reuse row locations
>> until a table level lock is granted.  But your project would be the
>> first dependency on this outside of the access method implementations
>> themselves.  It is very clear the contract that the access methods
>> have with their clients while locks are held on the data they are
>> looking at, what you are proposing is a contract on unlocked data.
>>
> 
> I guess we are the first to use RowLocation without holding a lock on
> the row. This is necessary, unless we simply make SUR cursors set locks
> for all rows in the cursor independent from isolation level.
> 
>> Note that the current "in-place" compress will MOVE rows from one
>> row location to another if one does not have a row lock on the row.
>> This is done in the 2nd phase and only holds an intent lock, and
>> exclusive row locks on the rows being moved.
>> The off-line compress only does work under an X table lock.
>> So the row that you are updating actually will exist in the table,
>> but currently you will request the old location and will get back
>> a delete row indicator.  I think because of this option 1 does not
>> work.
>>
> Are you saing that RowLocations can be invalidated by "in-place"
> compress even if we hold a Table intent lock ?
The "in-place" compress will do the following take a row a row location
N and do the
following:
    insert row at new row location M
    delete row at old row location N
    possibly purge old row location

I don't understand how this will affect your code, it depends how you
search for the row, and what errors are ok to throw.
> 
> How do you call "in-place" compress today ? Does the system use it
> automatically, or do the user have to call it manually ?
> 
>> The state of held cursors across commits is very murky in the standards.
>> We looked very carefully at forward only held cursors, and the standards
>> there are carefully worded to basically not promise anything about the
>> rows that were viewed that preceded the commit (clearly since the
>> standard says the only thing you can do after the commit is a next to
>> get a new row or close - never can access rows looked at before the
>> commit).  What options are legal
>> implementations of updatable scrollable result sets for held cursors
>> across commits?  Do the standards guarantee anything about data in the
>> cursor looked at before the commit?
>>
> 
> I looked at the SQL standard, and for cursors held over commit, it says:
> 
> "If the cursor is insensitive, then significant changes are not visible"
> 
> Andreas
> 
>>
>>
>> Andreas Korneliussen wrote:
>>
>>> Mike Matrigali wrote:
>>> ..
>>>
>>>> If possible I would like to see a solution that does not require
>>>> special
>>>> messages sent back and forth between modules about state.
>>>>
>>>
>>> I am not entirely sure what restrictions you want to put on the
>>> design, it is a bit unclear to me.
>>>
>>> I have considered some other solutions:
>>>
>>> 1. Change the locking behaviour, so that a table intent lock which is
>>> set by an updatable cursor, is kept as long as the cursor is open -
>>> this will ensure that the RowLocations are valid.
>>>
>>> 2. After a commit, we could clear all data in the internal table in
>>> the SUR. The problem with this approach is that the resultset would
>>> not necessarily be repopulated with the same data - it would be
>>> sensitive for changes across its own transactions commits, it would
>>> be highly ineffecient.
>>>
>>> 3. Let the cursors notify the OnlineCompress module that it should
>>> fail any attempt to compress/defragment or purge the table.
>>>
>>> More details on what I suggested yesterday:
>>>
>>> The OnlineCompress class could provide an event mechanism, where
>>> subscribers (OnlineCompressListener) register themselves to listen to
>>> OnlineCompressEvents. The ScrollInsensitiveResultSet class could then
>>> implement the OnlineCompressListener interface, and register itself
>>> once it starts populating the table with RowLocations. The
>>> OnlineCompress class then simply notifies all listeners once it is
>>> doing defragment / compress.
>>> The listeners should unregister themselves (i.e
>>> ScrollInsensitiveResultSet class could do it once it closes). The
>>> OnlineCompress class could use a WeakHashMap to put the listeners
>>> into, in case they are not well-behaved. I have not checked if derby
>>> already has event manager type of modules, if it does, I would
>>> attempt to reuse them.
>>>
>>> Please also let me know if any of the other alternatives seems better.
>>>
>>>
>>> Andreas
>>>
>>>
>>>> Andreas Korneliussen wrote:
>>>>
>>>>
>>>>> Some context: In scrollable updatable resultsets, we populate an
>>>>> internal table with the following data:
>>>>>
>>>>> <Position> <RowLocation> <RowUpdated> <RowDeleted> [<DataColumn>]+
>>>>>
>>>>> Example layeout:
>>>>>
>>>>>  1         <1,10>         false        false        1,"a",3
>>>>>  2         <1,11>         false        false        2,"b",2
>>>>>  3         <1,12>         false        false        3,"c",9
>>>>>
>>>>>
>>>>> When doing updateRow(), or deleteRow(), we use the RowLocation to
>>>>> navigate to the row being updated.
>>>>>
>>>>> Problem:
>>>>> For holdable cursors, we will release the table intent lock when doing
>>>>> commit on the transaction for the cursor.
>>>>>
>>>>> The table intent lock, prevents the system from doing a compress of
>>>>> the
>>>>> table, causing all RowLocations to be invalid. In addition, it
>>>>> prevents
>>>>> reuse of RowLocation for deleted + purged rows.
>>>>>
>>>>> In order to support holdable scrollable updatable cursors, we consider
>>>>> having a service which allows the system to notify subscribers (i.e
>>>>> cursors) that it has executed i.e a compress.
>>>>>
>>>>> If the user then calls updateRow() or deleteRow(), we can then give an
>>>>> exception like:
>>>>>
>>>>> "The row could not be updated, because its location has been
>>>>> updated by
>>>>> the system"
>>>>>
>>>>> In addition, we consider having a reclaim of locks, so that immediatly
>>>>> after a commit, the new transaction with the holdable cursor, may
>>>>> reclaim the table intent lock.  This will reduce the time period which
>>>>> the system may compress the table, however not completely remove the
>>>>> possibility of a compress.
>>>>>
>>>>> Any comments on implementing such strategy ?
>>>>>
>>>>> An alternative to this strategy, could be to go the other way: cursors
>>>>> notify the system that it should not do compress.
>>>>>
>>>>> I would appreciate feedback on this topic, especially if you find any
>>>>> pitfalls with the proposed strategies, or have better alternatives.
>>>>>
>>>>> Andreas
>>>>>
>>>
>>>
>>>
>>
> 
> 

Reply via email to