Hi Kevin,
I have started looking into your suggestions. Here is one initial result:
Kevin Lewis wrote:
> Kevin Lewis wrote:
>>
>>
>> In other words, if a record no longer had a transaction pointer, it
>> ended before any transaction that would be calling getRelativeState()
>> ever started.
>
> This implies that the code you are worried about is no longer used or
> needed;
>
> // Be sure it was not active when we started.
>
> for (int n = 0; n < numberStates; ++n)
> if (states [n].transactionId == transId)
> return CommittedInvisible;
>
> Can you run a test to see if that return is EVER hit in the current code?
I have done a clean branch of mysql-6.0-falcon-team and run some tests,
and Yes, I am able to hit the return statement in the above code. With
the following extra print statement added:
for (int n = 0; n < numberStates; ++n)
if (states [n].transactionId == transId)
{
fprintf(stderr, "Transaction::getRelativeState:
mytid=%d mystate=%d transId=%d otherTransId=%d otherState=%d
dependencies=%d\n", transactionId, state, transId,
states[n].transaction->transactionId,
states[n].transaction->state,states[n].transaction->dependencies );
FATAL("Transaction::getRelativeState");
return CommittedInvisible;
}
}
I get the following written out:
Transaction::getRelativeState: mytid=1953 mystate=0 transId=1952
otherTransId=1952 otherState=0 dependencies=1
[Falcon] Error: Transaction::getRelativeState
It seems like this code is not "quite dead" and it seems like the
transaction that the RecordVersion object is referring to (but have no
pointer too) is not deleted but in Active state with one existing
dependency (if reading what the transaction pointer points to is valid
data).
It is possible to reproduce this by running falcon_bug_22165 repeatable
on a multi-CPU server (you get the crash easier if you add some extra
printout each time Transaction::getRelativeState() is called).
So I am still "worried" about this code, and I think I need to try to
figure out what is the answers to the follow questions:
>>> 2) Comments in the code above seems to suggest that the reason for
>>> not having the pointer to the transaction object is due to that the
>>> transaction object has been deleted and it assumes that the
>>> transaction has been committed. In my testing this seems not like it
>>> is an correct assumption, in most cases when the transaction pointer
>>> is NULL the transaction is actually still in Active state. Questions:
>>>
>>> a) Are the comments in the code wrong? Or
>>> b) The code is wrong? And
>>> c) Why do we not have the transaction pointer pointing to the
>>> transaction if it is still active
>>>
>>> or (d) I have I introduced some error that causes this?
>>
>> You have introduced an error that causes Transaction::commitRecords()
>> to be called while dependencies still exist.
Kevin might still be right about that I have introduced an error but it
seems like something is also not quite correct when using the existing
dependency manager.
Olav