On Tue, Jul 26, 2011 at 09:42:58AM -0400, Zardosht Kasheff wrote:
> As best as I understand, a handler mostly does reads by performing the
> following sequence of operations (not including rnd_XXX functions):
> - call handler::index_init
> - perform a bunch of handler::index_XXX calls
> - call handler::index_end
>
> I am wondering what other handler operations may occur in between
> index_init and index_end that may block a handler::index_XXX call.
>
When SQL layer needs rowids for rows it is reading, it will call
handler->position() after each call that has returned a row.
There can also be unlock_row() call for each read row, about which I can't tell
much off the top of the head.
>
> For instance, in the case of deletes and updates, I know that the
> handler that performs an index_XXX call may then perform
> handler::delete_row or handler::update_row. So, a subsequent call to
> handler::index_XXX may not occur until the delete_row or update_row is
> complete.
>
> Are there any other cases where the sequence of index_XXX calls may be
> blocked? For instance, is there a chance that some other handler's
> work may block execution of and index_XXX call? Can joins or index
> merges do such a thing?
Join runtime does table scans (or index scans, or index lookups, depending
on the used access method) multiple times, so its handler call pattern will
be the same
> - call handler::index_init
> - perform a bunch of handler::index_XXX calls [idx-pattern]
> - call handler::index_end
repeated multiple times.
There are some cases where the above index_init() ... index_end() pattern will
alternate with "rnd_init(); while(..) {rnd_next();} rnd_end(); pattern, but
each of the pattern will remain un-broken.
index_merge/sort-union has this call pattern:
for each merged index I
{
run pattern [idx-pattern] for index I, with position() call after each
record read;
}
h->rnd_init();
while(...) {
h->rnd_pos();
h->rnd_end();
.. which is not that different from what other access methods do.
index_merge/intersection and index_merge/union (called as ROR-intersection an
ROR-union in the code) have a rather peculiar call patterns, as they need to run
multiple index scans simultaneously. They do it as follows:
for each merged index I except the first one
{
handlers[i]= handler->clone();
handlers[i]->index_init(I);
}
/*
Now, simultaneously run [idx-pattern] for each of handlers[i]. That is,
index_merge code will repeatedly call handlers[k]->index_XXX() where
k will change in a seemingly random fashion,e.g. you will see calls like
this:
handlers[0]->index_XXX();
handlers[1]->index_XXX();
handlers[2]->index_XXX();
handlers[0]->index_XXX();
handlers[0]->index_XXX();
handlers[1]->index_XXX();
...
*/
/* it all will end with: */
{
handlers[i]->index_end();
handlers[i]->close();
delete handlers[i];
}
Hope this makes it clear.
BR
Sergey
--
Sergey Petrunia, Software Developer
Monty Program AB, http://askmonty.org
Blog: http://s.petrunia.net/blog