Commit 66a31433 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi
Browse files

Fixed bug when joining with caching.

Fixed race condition when using the binary log and INSERT DELAYED which could cause the binary log to have rows that was not yet written to MyISAM tables.
parent 50b43f85
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -46785,7 +46785,7 @@ users use this code as the rest of the code and because of this we are
not yet 100% confident in this code.
@menu
* News-3.23.46::                
* News-3.23.46::                Changes in release 3.23.46
* News-3.23.45::                Changes in release 3.23.45
* News-3.23.44::                Changes in release 3.23.44
* News-3.23.43::                Changes in release 3.23.43
@@ -46846,6 +46846,12 @@ One can now kill @code{ANALYZE},@code{REPAIR} and @code{OPTIMIZE TABLE} when
the thread is waiting to get a lock on the table.
@item
Fixed race condition in @code{ANALYZE TABLE}.
@item
Fixed bug when joining with caching (unlikely to happen).
@item
Fixed race condition when using the binary log and @code{INSERT DELAYED}
which could cause the binary log to have rows that was not yet written
to MyISAM tables.
@end itemize
@node News-3.23.45, News-3.23.44, News-3.23.46, News-3.23.x
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@ t1 index NULL a 9 NULL 12 where used; Using index
table	type	possible_keys	key	key_len	ref	rows	Extra
t1	range	a,b	a	9	NULL	3	where used; Using index
table	type	possible_keys	key	key_len	ref	rows	Extra
t1	range	a,b	a	9	NULL	2	where used; Using index
t1	ref	a,b	b	4	const	2	where used
table	type	possible_keys	key	key_len	ref	rows	Extra
t1	ref	a,b	a	5	const	3	where used; Using index
table	type	possible_keys	key	key_len	ref	rows	Extra
+11 −4
Original line number Diff line number Diff line
@@ -1099,7 +1099,7 @@ bool delayed_insert::handle_inserts(void)
{
  int error;
  uint max_rows;
  bool using_ignore=0;
  bool using_ignore=0, using_bin_log=mysql_bin_log.is_open();
  delayed_row *row;
  DBUG_ENTER("handle_inserts");

@@ -1124,6 +1124,12 @@ bool delayed_insert::handle_inserts(void)
    max_rows= ~0;				// Do as much as possible
  }

  /*
    We can't use row caching when using the binary log because if
    we get a crash, then binary log will contain rows that are not yet
    written to disk, which will cause problems in replication.
  */
  if (!using_bin_log)
    table->file->extra(HA_EXTRA_WRITE_CACHE);
  pthread_mutex_lock(&mutex);
  while ((row=rows.get()))
@@ -1161,7 +1167,7 @@ bool delayed_insert::handle_inserts(void)
    if (row->query && row->log_query)
    {
      mysql_update_log.write(&thd,row->query, row->query_length);
      if (mysql_bin_log.is_open())
      if (using_bin_log)
      {
	thd.query_length = row->query_length;
	Query_log_event qinfo(&thd, row->query);
@@ -1197,6 +1203,7 @@ bool delayed_insert::handle_inserts(void)
	  /* This should never happen */
	  sql_print_error(ER(ER_DELAYED_CANT_CHANGE_LOCK),table->real_name);
	}
	if (!using_bin_log)
	  table->file->extra(HA_EXTRA_WRITE_CACHE);
	pthread_mutex_lock(&mutex);
	thd.proc_info="insert";
+46 −38
Original line number Diff line number Diff line
@@ -1881,21 +1881,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
** Find how much space the prevous read not const tables takes in cache
*/

static uint
cache_record_length(JOIN *join,uint idx)
{
  uint length;
  JOIN_TAB **pos,**end;
  THD *thd=join->thd;

  length=0;
  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
       pos != end ;
       pos++)
static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
{
    JOIN_TAB *join_tab= *pos;
    if (!join_tab->used_fieldlength)
    {					/* Not calced yet */
  uint null_fields,blobs,fields,rec_length;
  null_fields=blobs=fields=rec_length=0;

@@ -1927,6 +1914,22 @@ cache_record_length(JOIN *join,uint idx)
  join_tab->used_fieldlength=rec_length;
  join_tab->used_blobs=blobs;
}


static uint
cache_record_length(JOIN *join,uint idx)
{
  uint length=0;
  JOIN_TAB **pos,**end;
  THD *thd=join->thd;

  for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
       pos != end ;
       pos++)
  {
    JOIN_TAB *join_tab= *pos;
    if (!join_tab->used_fieldlength)		/* Not calced yet */
      calc_used_field_length(thd, join_tab);
    length+=join_tab->used_fieldlength;
  }
  return length;
@@ -2248,6 +2251,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
      used_tables|=current_map;

      if (tab->type == JT_REF && tab->quick &&
	  tab->ref.key == tab->quick->index &&
	  tab->ref.key_length < tab->quick->max_used_key_length)
      {
	/* Range uses longer key;  Use this instead of ref on key */
@@ -5631,15 +5635,19 @@ join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
  uint length,blobs,size;
  CACHE_FIELD *copy,**blob_ptr;
  JOIN_CACHE  *cache;
  JOIN_TAB *join_tab;
  DBUG_ENTER("join_init_cache");

  cache= &tables[table_count].cache;
  cache->fields=blobs=0;

  for (i=0 ; i < table_count ; i++)
  join_tab=tables;
  for (i=0 ; i < table_count ; i++,join_tab++)
  {
    cache->fields+=tables[i].used_fields;
    blobs+=tables[i].used_blobs;
    if (!join_tab->used_fieldlength)		/* Not calced yet */
      calc_used_field_length(thd, join_tab);
    cache->fields+=join_tab->used_fields;
    blobs+=join_tab->used_blobs;
  }
  if (!(cache->field=(CACHE_FIELD*)
	sql_alloc(sizeof(CACHE_FIELD)*(cache->fields+table_count*2)+(blobs+1)*