List:Commits« Previous MessageNext Message »
From:Kristofer Pettersson Date:August 22 2007 7:52am
Subject:Re: #30201 [Com]: crash with query cache when killing a select
View as plain text  
Hi,

> --- a/sql/sql_cache.cc	2007-05-10 17:54:53 +05:00
> +++ b/sql/sql_cache.cc	2007-08-22 11:07:03 +05:00
> @@ -706,6 +706,12 @@ void query_cache_end_of_result(THD *thd)
>    Query_cache_block *query_block;
>    DBUG_ENTER("query_cache_end_of_result");
>  
> +  if (thd->killed)
> +  {
> +    query_cache_abort(&thd->net);
> +    DBUG_VOID_RETURN;
> +  }
> +

Ok, query_cache_abort checks null-pointers and removes query cache blocks from store.

>    /* See the comment on double-check locking usage above. */
>      DBUG_VOID_RETURN;
> @@ -727,13 +733,10 @@ void query_cache_end_of_result(THD *thd)
>      DUMP(&query_cache);
>      BLOCK_LOCK_WR(query_block);
> -    Query_cache_block *last_result_block= header->result()->prev;
> -    ulong allign_size= ALIGN_SIZE(last_result_block->used);
> -    ulong len= max(query_cache.min_allocation_unit, allign_size);
> -    if (last_result_block->length >= query_cache.min_allocation_unit + len)
> -      query_cache.split_block(last_result_block,len);
> +    Query_cache_block *last_result_block;
> +    ulong allign_size;
> +    ulong len;
>  
> -#ifndef DBUG_OFF
>      if (header->result() == 0)
>      {
>        DBUG_PRINT("error", ("end of data whith no result. query '%s'",
> @@ -747,7 +750,13 @@ void query_cache_end_of_result(THD *thd)
>        */
>        goto end;
>      }
> -#endif
> +
> +    last_result_block= header->result()->prev;
> +    allign_size= ALIGN_SIZE(last_result_block->used);
> +    len= max(query_cache.min_allocation_unit, allign_size);
> +    if (last_result_block->length >= query_cache.min_allocation_unit + len)
> +      query_cache.split_block(last_result_block,len);
> +
>      header->found_rows(current_thd->limit_found_rows);
>      header->result()->type= Query_cache_block::RESULT;
>      header->writer(0);

Ok: check if we have a result block before we reference it. But if there is a query cache
block
in the store which doesn't have any result set this is inconvenient later on in
send_result_to_client:
.
.
.
  query = query_block->query();
  result_block= first_result_block= query->result();

  if (result_block == 0 || result_block->type != Query_cache_block::RESULT)
  {
    /* The query is probably yet processed */
    DBUG_PRINT("qcache", ("query found, but no data or data incomplete"));
    BLOCK_UNLOCK_RD(query_block);
    goto err_unlock;
  }
.
.
.

Better to remove this query block at once when we detected the error. Please change from:
    if (header->result() == 0)
    {
      DBUG_PRINT("error", ("end of data whith no result. query '%s'",
                           header->query()));
      query_cache.wreck(__LINE__, "");  <-- disables the query cache which is a bit
unnecessary

      /*
        We do not need call of BLOCK_UNLOCK_WR(query_block); here because
        query_cache.wreck() switched query cache off but left content
        untouched for investigation (it is debugging method).
      */
      goto end;
    }

Change to:

    if (header->result() == 0)
    {
      DBUG_PRINT("error", ("End of data with no result blocks; Query '%s' removed from
cache.",
                           header->query()));
	
      BLOCK_UNLOCK_WR(query_block);
      query_cache.free_query(query);
      
      goto end;
    }

Cheers,

Kristofer


Thread
Re: #30201 [Com]: crash with query cache when killing a selectKristofer Pettersson22 Aug