maria-developers team mailing list archive
-
maria-developers team
-
Mailing list archive
-
Message #11119
Re: [Commit] MDEV-12746 out-of-order retry
andrei.elkin@xxxxxxxxxx writes:
> First the parent errros out goes to `finish_event_group()' but it's
> possible it does not have yet the child in its `subsequent_commits_list'
> So I understood so far that the retrying worker needs to check
> `stop_on_error_sub_id' that effectively reflects the error status.
Agree, the basic fix looks correct, of checking stop_on_error_sub_id.
And yes, there are probably cases where after stop_on_error_sub_id is set,
earlier transactions are aborted early without setting up the
subsequent-transaction-chain, so that wait_for_prior_commit cannot be relied
upon, and stop_on_error_sub_id must be checked.
So again, nice catch, this would be nasty to try and debug from errors seen
only in a user's setup.
I am only wondering about two points, if there is something that needs to be
adjusted in the patch around the error exit after stop_on_error_sub_id, or
perhaps something else not yet understood going on:
Number one:
>>> + if (!rgi->worker_error)
>>> + rgi->worker_error= 1;
>>> + }
>>
>> I would have expected an abort (goto err) here (or well just below, after
>> unlocking the mutex). Is this not needed, and if so, why not?
>
> I left it to upcoming (in 2 lines) THD::wait_for_prior_commit(). It
> takes care to check out `worker_error'.
>
> int wait_for_prior_commit(THD *thd)
> {
> /*
> Quick inline check, to avoid function call and locking in the common case
> where no wakeup is registered, or a registered wait was already signalled.
> */
> if (waitee)
> return wait_for_prior_commit2(thd);
> else
> {
> if (wakeup_error)
> my_error(ER_PRIOR_COMMIT_FAILED, MYF(0));
> return wakeup_error;
> }
> }
>
> No waitee is guaranteed as this worker skipped `register_wait_for_prior_event_group_commit()'.
Sorry, I don't get it. wait_for_prior_commit() checks
thd->wait_for_commit_ptr->wakeup_error, not rgi->worker_error?
wait_for_prior_commit() doesn't have access to rgi.
> list. And that's how the parent's `wakeup_error' never reaches the
> child. This is certainly the case when a child retries after a temp
> failure. In the test condition the child's `worker_error' is zero, but
> if a non-zero case `worker_error' gets cleared anyway through
> `unregister_wait_for_prior_commit()'.
Isn't there some confusion here? Between "wakeup_error", which sits inside
struct wait_for_commit, and indicates that a prior event group failed. And
"worker_error" in rpl_group_info, which indicates that _this_ event group
failed, and is used to remember to do proper error cleanup inside the worker
thread?
Number two:
> You must mean the retrying worker stops doing it optimistically. I saw that.
> But I saw through logs that at times a worker
> could re-try about the number of worker pool size.
> Perhaps this unrestrained behaviour was caused by lack of a check of the
> current patch.
Yes, that is what I mean. And yes, the underlying bug with missing check on
stop_on_error_sub_id might have caused this as a secondary effect.
My point was just that users should not need to set a high retry count just
from using parallel replication (remember, several thousand worker threads
have been used with success on production data). So if this is necessary in
a test case, it might indicate a problem with the code...
- Kristian.
Follow ups
References