List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:September 22 2006 7:01pm
Subject:bk commit into 5.0 tree (cmiller:1.2230) BUG#14262
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-09-22 15:01:38-04:00, cmiller@stripped +8 -0
  Bug #14262: SP: DROP PROCEDURE|VIEW (maybe more) write to binlog too late \
  	(race cond)
  
  It was possible for one thread to interrupt a DDI statement and thereby get
  messages to the binlog out of order.  Consider:
  
  Connection 1: Drop table x
  Connection 2: Create or replace table x
  Connection 2: Log "Create or replace table x"
  Connection 1: Log "Drop table x"
  
  Local end would have table x, but the replicated slaves would not.
  
  The fix for this is to wrap all similar events in the same mutex.  Since we
  already use mutexes for the various parts of altering the server, this only
  entails moving the logging events down close to the action, inside the mutex
  protection.

  sql/sp.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +23 -0
    Move logging inside the routine drop and update functions, so it can be 
    protected by a LOCK_open mutex.  (The "create" function already had such 
    a LOCK_open protection.)

  sql/sql_acl.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +64 -5
    Move logging inside the grant functions, so that it can be protected by 
    LOCK_grant .

  sql/sql_db.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +5 -0
    Add comments that describe how each logging event is protected.

  sql/sql_parse.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +22 -92
    Move all logging statements about DDI statements close to the actual event, 
    so each can be protected by the same mutex.

  sql/sql_table.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +5 -7
    Widen the scope of the mutex so that logging events are also protected.

  sql/sql_trigger.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +2 -2
    Widen the scope of the mutex so that logging events are also protected.

  sql/sql_view.cc@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +48 -4
    Pass the head of the table linked-list so we can create a logging statement.
    
    Move the logging statement inside the worker function, and notably inside 
    the LOCK_open mutex.  Widen the same mutex a little to make room for logging.

  sql/sql_view.h@stripped, 2006-09-22 15:01:36-04:00, cmiller@stripped +1 -1
    Pass the head of the table linked-list so we can create a logging statement.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.cornsilk.net
# Root:	/home/cmiller/work/mysql/bug14262/my50-bug14262

--- 1.199/sql/sql_acl.cc	2006-09-22 15:01:43 -04:00
+++ 1.200/sql/sql_acl.cc	2006-09-22 15:01:43 -04:00
@@ -3005,9 +3005,20 @@ bool mysql_table_grant(THD *thd, TABLE_L
   grant_option=TRUE;
   thd->mem_root= old_root;
   pthread_mutex_unlock(&acl_cache->lock);
-  rw_unlock(&LOCK_grant);
-  if (!result)
+
+  if (!result) /* success */
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+      mysql_bin_log.write(&qinfo);
+    }
     send_ok(thd);
+  }
+
+  rw_unlock(&LOCK_grant);
+
   /* Tables are automatically closed */
   DBUG_RETURN(result);
 }
@@ -3168,9 +3179,19 @@ bool mysql_routine_grant(THD *thd, TABLE
   grant_option=TRUE;
   thd->mem_root= old_root;
   pthread_mutex_unlock(&acl_cache->lock);
-  rw_unlock(&LOCK_grant);
   if (!result && !no_error)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+      mysql_bin_log.write(&qinfo);
+    }
     send_ok(thd);
+  }
+
+  rw_unlock(&LOCK_grant);
+
   /* Tables are automatically closed */
   DBUG_RETURN(result);
 }
@@ -3276,11 +3297,21 @@ bool mysql_grant(THD *thd, const char *d
     }
   }
   VOID(pthread_mutex_unlock(&acl_cache->lock));
-  rw_unlock(&LOCK_grant);
-  close_thread_tables(thd);
 
   if (!result)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+      mysql_bin_log.write(&qinfo);
+    }
     send_ok(thd);
+  }
+
+  rw_unlock(&LOCK_grant);
+  close_thread_tables(thd);
+
   DBUG_RETURN(result);
 }
 
@@ -5241,6 +5272,13 @@ bool mysql_create_user(THD *thd, List <L
   }
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5297,6 +5335,13 @@ bool mysql_drop_user(THD *thd, List <LEX
   rebuild_check_host();
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5366,6 +5411,13 @@ bool mysql_rename_user(THD *thd, List <L
   rebuild_check_host();
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5541,6 +5593,13 @@ bool mysql_revoke_all(THD *thd,  List <L
   }
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
 

--- 1.130/sql/sql_db.cc	2006-09-22 15:01:43 -04:00
+++ 1.131/sql/sql_db.cc	2006-09-22 15:01:43 -04:00
@@ -542,6 +542,7 @@ bool mysql_create_db(THD *thd, char *db,
       qinfo.db     = db;
       qinfo.db_len = strlen(db);
 
+      /* All db DDI methods protected with LOCK_mysql_create_db */
       mysql_bin_log.write(&qinfo);
     }
     send_ok(thd, result);
@@ -613,6 +614,7 @@ bool mysql_alter_db(THD *thd, const char
     qinfo.db_len = strlen(db);
 
     thd->clear_error();
+    /* All db DDI methods protected with LOCK_mysql_create_db */
     mysql_bin_log.write(&qinfo);
   }
   send_ok(thd, result);
@@ -736,6 +738,7 @@ bool mysql_rm_db(THD *thd,char *db,bool 
       qinfo.db_len = strlen(db);
 
       thd->clear_error();
+      /* All db DDI methods protected with LOCK_mysql_create_db */
       mysql_bin_log.write(&qinfo);
     }
     thd->server_status|= SERVER_STATUS_DB_DROPPED;
@@ -762,6 +765,7 @@ bool mysql_rm_db(THD *thd,char *db,bool 
       tbl_name_len= strlen(tbl->table_name) + 3;
       if (query_pos + tbl_name_len + 1 >= query_end)
       {
+        /* All db DDI methods protected with LOCK_mysql_create_db */
         write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
         query_pos= query_data_start;
       }
@@ -774,6 +778,7 @@ bool mysql_rm_db(THD *thd,char *db,bool 
 
     if (query_pos != query_data_start)
     {
+      /* All db DDI methods protected with LOCK_mysql_create_db */
       write_to_binlog(thd, query, query_pos -1 - query, db, db_len);
     }
   }

--- 1.563/sql/sql_parse.cc	2006-09-22 15:01:43 -04:00
+++ 1.564/sql/sql_parse.cc	2006-09-22 15:01:43 -04:00
@@ -3195,6 +3195,7 @@ end_with_restore_list:
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, REPAIR and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3229,6 +3230,7 @@ end_with_restore_list:
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, ANALYZE and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3254,6 +3256,7 @@ end_with_restore_list:
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3542,6 +3545,7 @@ end_with_restore_list:
       /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
       thd->options|= OPTION_STATUS_NO_TRANS_UPDATE;
     }
+    /* DDL and binlog write order protected by LOCK_open */
     res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
 			lex->drop_temporary);
   }
@@ -3830,15 +3834,9 @@ end_with_restore_list:
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_create_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_DROP_USER:
@@ -3848,15 +3846,9 @@ end_with_restore_list:
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_drop_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_RENAME_USER:
@@ -3866,15 +3858,9 @@ end_with_restore_list:
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_rename_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_REVOKE_ALL:
@@ -3882,15 +3868,9 @@ end_with_restore_list:
     if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
+    /* Conditionally writes to binlog */
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-	Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-	mysql_bin_log.write(&qinfo);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_REVOKE:
@@ -3949,6 +3929,7 @@ end_with_restore_list:
 	    check_grant_routine(thd, grants | GRANT_ACL, all_tables,
                                 lex->type == TYPE_ENUM_PROCEDURE, 0))
 	  goto error;
+        /* Conditionally writes to binlog */
         res= mysql_routine_grant(thd, all_tables,
                                  lex->type == TYPE_ENUM_PROCEDURE, 
                                  lex->users_list, grants,
@@ -3961,16 +3942,11 @@ end_with_restore_list:
 					 GRANT_ACL),
 					all_tables, 0, UINT_MAX, 0))
 	  goto error;
+        /* Conditionally writes to binlog */
         res= mysql_table_grant(thd, all_tables, lex->users_list,
 			       lex->columns, lex->grant,
 			       lex->sql_command == SQLCOM_REVOKE);
       }
-      if (!res && mysql_bin_log.is_open())
-      {
-        thd->clear_error();
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
     }
     else
     {
@@ -3981,16 +3957,11 @@ end_with_restore_list:
         goto error;
       }
       else
+	/* Conditionally writes to binlog */
 	res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
 			  lex->sql_command == SQLCOM_REVOKE);
       if (!res)
       {
-	if (mysql_bin_log.is_open())
-	{
-          thd->clear_error();
-	  Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-	  mysql_bin_log.write(&qinfo);
-	}
 	if (lex->sql_command == SQLCOM_GRANT)
 	{
 	  List_iterator <LEX_USER> str_list(lex->users_list);
@@ -4028,6 +3999,7 @@ end_with_restore_list:
         We WANT to write and we CAN write.
         ! we write after unlocking the table.
       */
+      /* Presumably, RESET and binlog writing doesn't require synchronization */
       if (!lex->no_write_to_binlog && write_to_binlog)
       {
         if (mysql_bin_log.is_open())
@@ -4572,12 +4544,6 @@ end_with_restore_list:
       switch (result)
       {
       case SP_OK:
-        if (mysql_bin_log.is_open())
-        {
-          thd->clear_error();
-          Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-          mysql_bin_log.write(&qinfo);
-        }
 	send_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
@@ -4622,9 +4588,9 @@ end_with_restore_list:
 	}
 #endif
 	if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-	  result= sp_drop_procedure(thd, lex->spname);
+	  result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
 	else
-	  result= sp_drop_function(thd, lex->spname);
+	  result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
       }
       else
       {
@@ -4637,6 +4603,8 @@ end_with_restore_list:
           {
 	    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
 	      goto error;
+
+	    /* Conditionally writes to binlog */
 	    if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
 	    {
 	      send_ok(thd);
@@ -4657,12 +4625,6 @@ end_with_restore_list:
       switch (result)
       {
       case SP_OK:
-        if (mysql_bin_log.is_open())
-        {
-          thd->clear_error();
-          Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-          mysql_bin_log.write(&qinfo);
-        }
 	send_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
@@ -4758,37 +4720,8 @@ end_with_restore_list:
     {
       if (end_active_trans(thd))
         goto error;
-
-      if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
-          mysql_bin_log.is_open())
-      {
-        String buff;
-        const LEX_STRING command[3]=
-          {{(char *)STRING_WITH_LEN("CREATE ")},
-           {(char *)STRING_WITH_LEN("ALTER ")},
-           {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}};
-        thd->clear_error();
-
-        buff.append(command[thd->lex->create_view_mode].str,
-                    command[thd->lex->create_view_mode].length);
-        view_store_options(thd, first_table, &buff);
-        buff.append(STRING_WITH_LEN("VIEW "));
-        /* Test if user supplied a db (ie: we did not use thd->db) */
-        if (first_table->db && first_table->db[0] &&
-            (thd->db == NULL || strcmp(first_table->db, thd->db)))
-        {
-          append_identifier(thd, &buff, first_table->db,
-                            first_table->db_length);
-          buff.append('.');
-        }
-        append_identifier(thd, &buff, first_table->table_name,
-                          first_table->table_name_length);
-        buff.append(STRING_WITH_LEN(" AS "));
-        buff.append(first_table->source.str, first_table->source.length);
-
-        Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
+      /* Conditionally writes to binlog. */
+      res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
       break;
     }
   case SQLCOM_DROP_VIEW:
@@ -4796,13 +4729,8 @@ end_with_restore_list:
       if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
           end_active_trans(thd))
         goto error;
-      if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) &&
-          mysql_bin_log.is_open())
-      {
-        thd->clear_error();
-        Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
-        mysql_bin_log.write(&qinfo);
-      }
+      /* Conditionally writes to binlog. */
+      res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
       break;
     }
   case SQLCOM_CREATE_TRIGGER:
@@ -4810,6 +4738,7 @@ end_with_restore_list:
     if (end_active_trans(thd))
       goto error;
 
+    /* Conditionally writes to binlog. */
     res= mysql_create_or_drop_trigger(thd, all_tables, 1);
 
     /* We don't care about trigger body after this point */
@@ -4822,6 +4751,7 @@ end_with_restore_list:
     if (end_active_trans(thd))
       goto error;
 
+    /* Conditionally writes to binlog. */
     res= mysql_create_or_drop_trigger(thd, all_tables, 0);
     break;
   }

--- 1.319/sql/sql_table.cc	2006-09-22 15:01:43 -04:00
+++ 1.320/sql/sql_table.cc	2006-09-22 15:01:43 -04:00
@@ -3168,6 +3168,7 @@ bool mysql_alter_table(THD *thd,char *ne
 
   /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
   if (alter_info->tablespace_op != NO_TABLESPACE_OP)
+    /* Conditionally writes to binlog. */
     DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
 						   alter_info->tablespace_op));
   if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
@@ -3249,10 +3250,10 @@ bool mysql_alter_table(THD *thd,char *ne
       !table->s->tmp_table) // no need to touch frm
   {
     error=0;
+    VOID(pthread_mutex_lock(&LOCK_open));
     if (new_name != table_name || new_db != db)
     {
       thd->proc_info="rename";
-      VOID(pthread_mutex_lock(&LOCK_open));
       /* Then do a 'simple' rename of the table */
       error=0;
       if (!access(new_name_buff,F_OK))
@@ -3274,7 +3275,6 @@ bool mysql_alter_table(THD *thd,char *ne
           error= -1;
         }
       }
-      VOID(pthread_mutex_unlock(&LOCK_open));
     }
 
     if (!error)
@@ -3283,16 +3283,12 @@ bool mysql_alter_table(THD *thd,char *ne
       case LEAVE_AS_IS:
         break;
       case ENABLE:
-        VOID(pthread_mutex_lock(&LOCK_open));
         wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-        VOID(pthread_mutex_unlock(&LOCK_open));
         error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
         /* COND_refresh will be signaled in close_thread_tables() */
         break;
       case DISABLE:
-        VOID(pthread_mutex_lock(&LOCK_open));
         wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-        VOID(pthread_mutex_unlock(&LOCK_open));
         error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
         /* COND_refresh will be signaled in close_thread_tables() */
         break;
@@ -3322,6 +3318,7 @@ bool mysql_alter_table(THD *thd,char *ne
       table->file->print_error(error, MYF(0));
       error= -1;
     }
+    VOID(pthread_mutex_unlock(&LOCK_open));
     table_list->table=0;				// For query cache
     query_cache_invalidate3(thd, table_list, 0);
     DBUG_RETURN(error);
@@ -3768,6 +3765,7 @@ bool mysql_alter_table(THD *thd,char *ne
       my_free((gptr) new_table,MYF(0));
       goto err;
     }
+    /* FIXME!  Writing to the binlog does not need to be synchronized in this case? */
     if (mysql_bin_log.is_open())
     {
       thd->clear_error();

--- 1.89/sql/sql_view.cc	2006-09-22 15:01:43 -04:00
+++ 1.90/sql/sql_view.cc	2006-09-22 15:01:43 -04:00
@@ -162,6 +162,7 @@ err:
   SYNOPSIS
     mysql_create_view()
     thd		- thread handler
+    views	- views to create
     mode	- VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE
 
   RETURN VALUE
@@ -169,7 +170,7 @@ err:
      TRUE  Error
 */
 
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *views, 
                        enum_view_create_mode mode)
 {
   LEX *lex= thd->lex;
@@ -490,6 +491,42 @@ bool mysql_create_view(THD *thd,
   }
   VOID(pthread_mutex_lock(&LOCK_open));
   res= mysql_register_view(thd, view, mode);
+
+  if (mysql_bin_log.is_open())
+  {
+    String buff;
+    const LEX_STRING command[3]=
+      {{(char *)STRING_WITH_LEN("CREATE ")},
+       {(char *)STRING_WITH_LEN("ALTER ")},
+       {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}};
+
+#if 0
+    /* Including this causes the thread to freeze. */
+    thd->clear_error();
+#endif
+
+    buff.append(command[thd->lex->create_view_mode].str,
+                command[thd->lex->create_view_mode].length);
+    view_store_options(thd, views, &buff);
+    buff.append(STRING_WITH_LEN("VIEW "));
+
+    /* Test if user supplied a db (ie: we did not use thd->db) */
+    if (views->db && views->db[0] &&
+        (thd->db == NULL || strcmp(views->db, thd->db)))
+    {
+      append_identifier(thd, &buff, views->db,
+                        views->db_length);
+      buff.append('.');
+    }
+    append_identifier(thd, &buff, views->table_name,
+                      views->table_name_length);
+    buff.append(STRING_WITH_LEN(" AS "));
+    buff.append(views->source.str, views->source.length);
+
+    Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
   VOID(pthread_mutex_unlock(&LOCK_open));
   if (view->revision != 1)
     query_cache_invalidate3(thd, view, 0);
@@ -1229,12 +1266,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
   bool type= 0;
   db_type not_used;
 
+  VOID(pthread_mutex_lock(&LOCK_open));
   for (view= views; view; view= view->next_local)
   {
     strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/",
              view->table_name, reg_ext, NullS);
     (void) unpack_filename(path, path);
-    VOID(pthread_mutex_lock(&LOCK_open));
     if (access(path, F_OK) ||
 	(type= (mysql_frm_type(thd, path, &not_used) != FRMTYPE_VIEW)))
     {
@@ -1245,7 +1282,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
 	push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
 			    ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
 			    name);
-	VOID(pthread_mutex_unlock(&LOCK_open));
 	continue;
       }
       if (type)
@@ -1258,8 +1294,16 @@ bool mysql_drop_view(THD *thd, TABLE_LIS
       goto err;
     query_cache_invalidate3(thd, view, 0);
     sp_cache_invalidate();
-    VOID(pthread_mutex_unlock(&LOCK_open));
   }
+
+  if (mysql_bin_log.is_open())
+  {
+    thd->clear_error();
+    Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+    mysql_bin_log.write(&qinfo);
+  }
+
+  VOID(pthread_mutex_unlock(&LOCK_open));
   send_ok(thd);
   DBUG_RETURN(FALSE);
 

--- 1.11/sql/sql_view.h	2006-09-22 15:01:43 -04:00
+++ 1.12/sql/sql_view.h	2006-09-22 15:01:43 -04:00
@@ -16,7 +16,7 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
 
-bool mysql_create_view(THD *thd,
+bool mysql_create_view(THD *thd, TABLE_LIST *view,
                        enum_view_create_mode mode);
 
 bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table);

--- 1.52/sql/sql_trigger.cc	2006-09-22 15:01:43 -04:00
+++ 1.53/sql/sql_trigger.cc	2006-09-22 15:01:43 -04:00
@@ -268,8 +268,6 @@ bool mysql_create_or_drop_trigger(THD *t
            table->triggers->drop_trigger(thd, tables));
 
 end:
-  VOID(pthread_mutex_unlock(&LOCK_open));
-  start_waiting_global_read_lock(thd);
 
   if (!result)
   {
@@ -305,6 +303,8 @@ end:
 
     send_ok(thd);
   }
+  VOID(pthread_mutex_unlock(&LOCK_open));
+  start_waiting_global_read_lock(thd);
 
   DBUG_RETURN(result);
 }

--- 1.114/sql/sp.cc	2006-09-22 15:01:43 -04:00
+++ 1.115/sql/sp.cc	2006-09-22 15:01:43 -04:00
@@ -660,6 +660,17 @@ db_drop_routine(THD *thd, int type, sp_n
     if (table->file->delete_row(table->record[0]))
       ret= SP_DELETE_ROW_FAILED;
   }
+
+  if (ret == SP_OK)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+      mysql_bin_log.write(&qinfo);
+    }
+  }
+
   close_thread_tables(thd);
   DBUG_RETURN(ret);
 }
@@ -695,6 +706,17 @@ db_update_routine(THD *thd, int type, sp
     if ((table->file->update_row(table->record[1],table->record[0])))
       ret= SP_WRITE_ROW_FAILED;
   }
+
+  if (ret == SP_OK)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+      mysql_bin_log.write(&qinfo);
+    }
+  }
+
   close_thread_tables(thd);
   DBUG_RETURN(ret);
 }
@@ -773,6 +795,7 @@ print_field_values(THD *thd, TABLE *tabl
 	return SP_INTERNAL_ERROR;
     }
   }
+
   return SP_OK;
 }
 
Thread
bk commit into 5.0 tree (cmiller:1.2230) BUG#14262Chad MILLER22 Sep