Commit 18edc55b authored by unknown's avatar unknown
Browse files

Bug#20789 Merge Subtable Rename Causes Crash

- When a MyISAM table which belongs to a merge table union and is 
  renamed the associated file descriptors are closed on windows.
  This causes a server crash next time an insert or update is 
  performed on the merge table.
- This patch prevents the system from crashing on windows by
  checking for bad file descriptors every time the MyISAM table
  is locked by associated the merge table.


myisam/mi_locking.c:
  - Added check for bad file descriptors when table is part of merge union.
  - This patch prevents the server from crash on windows.
myisam/myisamdef.h:
  Added boolean value to indicate that this myisam table is part of
  a merge union.
myisammrg/myrg_locking.c:
  Added paramter owned_by_merge=TRUE for mi_lock_database through MYRG_TABLE struct.
parent 2247a2ab
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -224,6 +224,21 @@ int mi_lock_database(MI_INFO *info, int lock_type)
      break;				/* Impossible */
    }
  }
#ifdef __WIN__
  else
  {
    /*
       Check for bad file descriptors if this table is part
       of a merge union. Failing to capture this may cause
       a crash on windows if the table is renamed and 
       later on referenced by the merge table.
     */
    if( info->owned_by_merge && (info->s)->kfile < 0 )
    {
      error = HA_ERR_NO_SUCH_TABLE;
    }
  }
#endif
  pthread_mutex_unlock(&share->intern_lock);
#if defined(FULL_LOG) || defined(_lint)
  lock_type|=(int) (flag << 8);		/* Set bit to set if real lock */
+3 −0
Original line number Diff line number Diff line
@@ -278,6 +278,9 @@ struct st_myisam_info {
  my_bool page_changed;		/* If info->buff can't be used for rnext */
  my_bool buff_used;		/* If info->buff has to be reread for rnext */
  my_bool once_flags;           /* For MYISAMMRG */
#ifdef __WIN__
  my_bool owned_by_merge;                       /* This MyISAM table is part of a merge union */
#endif
#ifdef THREAD
  THR_LOCK_DATA lock;
#endif
+12 −1
Original line number Diff line number Diff line
@@ -27,7 +27,18 @@ int myrg_lock_database(MYRG_INFO *info, int lock_type)

  error=0;
  for (file=info->open_tables ; file != info->end_table ; file++) 
  {
#ifdef __WIN__
    /*
      Make sure this table is marked as owned by a merge table.
      The semaphore is never released as long as table remains
      in memory. This should be refactored into a more generic
      approach (observer pattern)
     */
    (file->table)->owned_by_merge = TRUE;
#endif
    if ((new_error=mi_lock_database(file->table,lock_type)))
      error=new_error;
  }
  return(error);
}