List:Commits« Previous MessageNext Message »
From:Mats Kindahl Date:June 16 2006 7:30am
Subject:bk commit into 5.1 tree (mats:1.2162)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of mats. When mats 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
  1.2162 06/06/16 09:30:28 mats@stripped +22 -0
  WL#19221 (Performance regression of cluster replication):
  Introducing a THD Builder to create and destroy THD instances.

  sql/thd_builder.h
    1.1 06/06/16 09:30:21 mats@stripped +70 -0
    New BitKeeper file ``sql/thd_builder.h''

  sql/thd_builder.h
    1.0 06/06/16 09:30:21 mats@stripped +0 -0
    BitKeeper file /home/bk/b19221-mysql-5.1-new-rpl/sql/thd_builder.h

  sql/thd_builder.cc
    1.1 06/06/16 09:30:20 mats@stripped +69 -0
    New BitKeeper file ``sql/thd_builder.cc''

  sql/tztime.cc
    1.36 06/06/16 09:30:20 mats@stripped +3 -2
    Using THD_BUILDER function to create and destroy THD instance.

  sql/thd_builder.cc
    1.0 06/06/16 09:30:20 mats@stripped +0 -0
    BitKeeper file /home/bk/b19221-mysql-5.1-new-rpl/sql/thd_builder.cc

  sql/sql_udf.cc
    1.65 06/06/16 09:30:20 mats@stripped +4 -3
    Using THD_BUILDER function to create and destroy THD instance.

  sql/sql_table.cc
    1.335 06/06/16 09:30:20 mats@stripped +3 -2
    Using THD_BUILDER function to create and destroy THD instance.

  sql/sql_plugin.cc
    1.21 06/06/16 09:30:20 mats@stripped +4 -3
    Using THD_BUILDER function to create and destroy THD instance.

  sql/sql_parse.cc
    1.550 06/06/16 09:30:19 mats@stripped +4 -3
    Using THD_BUILDER function to create and destroy THD instance.

  sql/sql_list.h
    1.41 06/06/16 09:30:19 mats@stripped +11 -0
    Added missing placement new and placement delete for ilink class.

  sql/sql_insert.cc
    1.202 06/06/16 09:30:19 mats@stripped +76 -73
    Using THD_BUILDER to construct THD instances.

  sql/sql_class.h
    1.298 06/06/16 09:30:19 mats@stripped +9 -0
    Adding rows_event buffer to THD structure.
    Using THD_BUILDER to create and destroy THD instances; hiding default
    constructor and destructor to block incorrect usage.

  sql/sql_class.cc
    1.262 06/06/16 09:30:19 mats@stripped +23 -13
    Adding buffer for rows-event to THD structure to avoid
    frequent allocation/deallocation. Using placement new and calling
    destructor directly instead of using operator new and delete.

  sql/sql_acl.cc
    1.193 06/06/16 09:30:19 mats@stripped +5 -4
    Using THD_BUILDER function to create and destroy THD instance.

  sql/slave.cc
    1.271 06/06/16 09:30:19 mats@stripped +8 -5
    Using THD_BUILDER function to create and destroy THD instance.

  sql/repl_failsafe.cc
    1.66 06/06/16 09:30:19 mats@stripped +3 -2
    Using THD_BUILDER function to create and destroy THD instance.

  sql/mysqld.cc
    1.544 06/06/16 09:30:19 mats@stripped +7 -6
    Using THD_BUILDER function to create and destroy THD instance.

  sql/log.cc
    1.211 06/06/16 09:30:18 mats@stripped +11 -5
    Using THD_BUILDER function to create and destroy THD instance.

  sql/ha_ndbcluster_binlog.cc
    1.55 06/06/16 09:30:18 mats@stripped +4 -3
    Using THD_BUILDER function to create and destroy THD instance.

  sql/ha_ndbcluster.cc
    1.306 06/06/16 09:30:18 mats@stripped +4 -3
    Using THD_BUILDER function to create and destroy THD instance.

  sql/event_executor.cc
    1.44 06/06/16 09:30:18 mats@stripped +6 -5
    Using THD_BUILDER function to create and destroy THD instance.

  sql/Makefile.am
    1.139 06/06/16 09:30:18 mats@stripped +2 -2
    Adding thd_builder.{cc,h} files.

  libmysqld/lib_sql.cc
    1.115 06/06/16 09:30:18 mats@stripped +3 -3
    Using THD_BUILDER function to create and destroy THD instance.

  libmysqld/Makefile.am
    1.90 06/06/16 09:30:17 mats@stripped +1 -0
    Adding thd_builder.{cc,h} files.

# 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:	mats
# Host:	romeo.(none)
# Root:	/home/bk/b19221-mysql-5.1-new-rpl

--- 1.138/sql/Makefile.am	2006-05-12 10:51:01 +02:00
+++ 1.139/sql/Makefile.am	2006-06-16 09:30:18 +02:00
@@ -58,7 +58,7 @@
 			sql_select.h structs.h table.h sql_udf.h hash_filo.h \
 			lex.h lex_symbol.h sql_acl.h sql_crypt.h  \
 			log_event.h sql_repl.h slave.h rpl_filter.h \
-			rpl_injector.h \
+			rpl_injector.h thd_builder.h \
 			stacktrace.h sql_sort.h sql_cache.h set_var.h \
 			spatial.h gstream.h client_settings.h tzfile.h \
 			tztime.h my_decimal.h\
@@ -94,7 +94,7 @@
 			sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
 			sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
 			slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \
-			rpl_injector.cc \
+			rpl_injector.cc thd_builder.cc \
                         sql_union.cc sql_derived.cc \
 			client.c sql_client.cc mini_client_errors.c pack.c\
 			stacktrace.c repl_failsafe.h repl_failsafe.cc \

--- 1.210/sql/log.cc	2006-06-06 07:34:58 +02:00
+++ 1.211/sql/log.cc	2006-06-16 09:30:18 +02:00
@@ -21,6 +21,7 @@
 #include "mysql_priv.h"
 #include "sql_repl.h"
 #include "rpl_filter.h"
+#include "thd_builder.h"
 
 #include <my_dir.h>
 #include <stdarg.h>
@@ -225,12 +226,12 @@
 Log_to_csv_event_handler::Log_to_csv_event_handler()
 {
   /* init artificial THD's */
-  general_log_thd= new THD;
+  general_log_thd= THD_BUILDER::instance()->create();
   /* logger thread always works with mysql database */
   general_log_thd->db= my_strdup("mysql", MYF(0));
   general_log_thd->db_length= 5;
 
-  slow_log_thd= new THD;
+  slow_log_thd= THD_BUILDER::instance()->create();
   /* logger thread always works with mysql database */
   slow_log_thd->db= my_strdup("mysql", MYF(0));;
   slow_log_thd->db_length= 5;
@@ -242,13 +243,13 @@
   /* now cleanup the tables */
   if (general_log_thd)
   {
-    delete general_log_thd;
+    THD_BUILDER::instance()->destroy(general_log_thd);
     general_log_thd= NULL;
   }
 
   if (slow_log_thd)
   {
-    delete slow_log_thd;
+    THD_BUILDER::instance()->destroy(slow_log_thd);
     slow_log_thd= NULL;
   }
 }
@@ -1239,7 +1240,9 @@
 
   binlog_trx_data *const trx_data=
     (binlog_trx_data*) thd->ha_data[binlog_hton.slot];
+#ifdef HAVE_ROW_BASED_REPLICATION
   thd->binlog_delete_pending_rows_event();
+#endif
   reinit_io_cache(&trx_data->trans_log, WRITE_CACHE, pos, 0, 0);
   DBUG_VOID_RETURN;
 }
@@ -2839,7 +2842,10 @@
     if (pending->get_flags(Rows_log_event::STMT_END_F))
       ++m_table_map_version;
 
-    delete pending;
+    /*
+      Calling destructor explicitly since the memory is reused later.
+    */
+    pending->~Rows_log_event();
 
     if (file == &log_file)
     {

--- 1.543/sql/mysqld.cc	2006-05-16 10:21:25 +02:00
+++ 1.544/sql/mysqld.cc	2006-06-16 09:30:19 +02:00
@@ -20,6 +20,7 @@
 #include "slave.h"
 #include "sql_repl.h"
 #include "rpl_filter.h"
+#include "thd_builder.h"
 #include "repl_failsafe.h"
 #include "stacktrace.h"
 #include "mysqld_suffix.h"
@@ -1709,7 +1710,7 @@
   thd->cleanup();
   (void) pthread_mutex_lock(&LOCK_thread_count);
   thread_count--;
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
 
   if (put_in_cache && cached_thread_count < thread_cache_size &&
       ! abort_loop && !kill_cached_threads)
@@ -3879,7 +3880,7 @@
 {
   DBUG_ENTER("bootstrap");
 
-  THD *thd= new THD;
+  THD *thd= THD_BUILDER::instance()->create();
   thd->bootstrap=1;
   my_net_init(&thd->net,(st_vio*) 0);
   thd->max_client_packet_length= thd->net.max_packet;
@@ -3960,7 +3961,7 @@
   {
     DBUG_PRINT("error",("Too many connections"));
     close_connection(thd, ER_CON_COUNT_ERROR, 1);
-    delete thd;
+    THD_BUILDER::instance()->destroy(thd);
     DBUG_VOID_RETURN;
   }
   pthread_mutex_lock(&LOCK_thread_count);
@@ -4013,7 +4014,7 @@
 	net_printf_error(thd, ER_CANT_CREATE_THREAD, error);
 	(void) pthread_mutex_lock(&LOCK_thread_count);
 	close_connection(thd,0,0);
-	delete thd;
+	THD_BUILDER::instance()->destroy(thd);
 	(void) pthread_mutex_unlock(&LOCK_thread_count);
 	DBUG_VOID_RETURN;
       }
@@ -4221,7 +4222,7 @@
     ** Don't allow too many connections
     */
 
-    if (!(thd= new THD))
+    if (!(thd= THD_BUILDER::instance()->create()))
     {
       (void) shutdown(new_sock,2);
       VOID(closesocket(new_sock));
@@ -4240,7 +4241,7 @@
 	(void) shutdown(new_sock,2);
 	(void) closesocket(new_sock);
       }
-      delete thd;
+      THD_BUILDER::instance()->destroy(thd);
       continue;
     }
     if (sock == unix_sock)

--- 1.270/sql/slave.cc	2006-04-16 03:17:25 +02:00
+++ 1.271/sql/slave.cc	2006-06-16 09:30:19 +02:00
@@ -22,6 +22,7 @@
 #include "slave.h"
 #include "sql_repl.h"
 #include "rpl_filter.h"
+#include "thd_builder.h"
 #include "repl_failsafe.h"
 #include <thr_alarm.h>
 #include <my_dir.h>
@@ -2597,7 +2598,7 @@
   if (init_thr_lock() || thd->store_globals())
   {
     thd->cleanup();
-    delete thd;
+    THD_BUILDER::instance()->destroy(thd);
     DBUG_RETURN(-1);
   }
 
@@ -3172,7 +3173,8 @@
   mi->events_till_disconnect = disconnect_slave_event_count;
 #endif
 
-  thd= new THD; // note that contructor of THD uses DBUG_ !
+  // note that contructor of THD uses DBUG_ !
+  thd= THD_BUILDER::instance()->create(); 
   THD_CHECK_SENTRY(thd);
 
   pthread_detach_this_thread();
@@ -3445,7 +3447,7 @@
   close_thread_tables(thd, 0);
   pthread_mutex_lock(&LOCK_thread_count);
   THD_CHECK_SENTRY(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   pthread_mutex_unlock(&LOCK_thread_count);
   pthread_cond_broadcast(&mi->stop_cond);	// tell the world we are done
   pthread_mutex_unlock(&mi->run_lock);
@@ -3476,7 +3478,8 @@
   rli->events_till_abort = abort_slave_event_count;
 #endif  
 
-  thd = new THD; // note that contructor of THD uses DBUG_ !
+  // note that contructor of THD uses DBUG_ !
+  thd = THD_BUILDER::instance()->create();
   thd->thread_stack = (char*)&thd; // remember where our stack is
   
   /* Inform waiting threads that slave has started */
@@ -3691,7 +3694,7 @@
   rli->sql_thd= 0;
   pthread_mutex_lock(&LOCK_thread_count);
   THD_CHECK_SENTRY(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   pthread_mutex_unlock(&LOCK_thread_count);
   pthread_cond_broadcast(&rli->stop_cond);
   // tell the world we are done

--- 1.192/sql/sql_acl.cc	2006-05-12 12:32:00 +02:00
+++ 1.193/sql/sql_acl.cc	2006-06-16 09:30:19 +02:00
@@ -31,6 +31,7 @@
 #include <stdarg.h>
 #include "sp_head.h"
 #include "sp.h"
+#include "thd_builder.h"
 
 time_t mysql_db_table_last_check= 0L;
 
@@ -274,7 +275,7 @@
   /*
     To be able to run this from boot, we allocate a temporary THD
   */
-  if (!(thd=new THD))
+  if (!(thd= THD_BUILDER::instance()->create()))
     DBUG_RETURN(1); /* purecov: inspected */
   thd->thread_stack= (char*) &thd;
   thd->store_globals();
@@ -284,7 +285,7 @@
     by zeros at startup.
   */
   return_val= acl_reload(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD,  0);
   DBUG_RETURN(return_val);
@@ -3424,12 +3425,12 @@
   my_bool return_val;
   DBUG_ENTER("grant_init");
 
-  if (!(thd= new THD))
+  if (!(thd= THD_BUILDER::instance()->create()))
     DBUG_RETURN(1);				/* purecov: deadcode */
   thd->thread_stack= (char*) &thd;
   thd->store_globals();
   return_val=  grant_reload(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD,  0);
   DBUG_RETURN(return_val);

--- 1.261/sql/sql_class.cc	2006-05-31 19:21:41 +02:00
+++ 1.262/sql/sql_class.cc	2006-06-16 09:30:19 +02:00
@@ -199,7 +199,7 @@
    lock_id(&main_lock_id),
    user_time(0), in_sub_stmt(0),
 #ifdef HAVE_ROW_BASED_REPLICATION
-   binlog_table_maps(0),
+   rows_event_buffer(0), binlog_table_maps(0),
 #endif /*HAVE_ROW_BASED_REPLICATION*/
    global_read_lock(0), is_fatal_error(0),
    rand_used(0), time_zone_used(0),
@@ -2330,22 +2330,28 @@
       pending->get_width() != colcnt ||
       !bitmap_cmp(pending->get_cols(), cols)) 
   {
+    /*
+      Need to flush the pending event since the memory for the rows
+      event is occupied.  The flush will automatically call the
+      destructor for the pending event.
+     */
+    if (unlikely(binlog_flush_pending_rows_event(FALSE) != 0))
+      DBUG_RETURN(NULL);
+
     /* Create a new RowsEventT... */
     Rows_log_event* const
-	ev= new RowsEventT(this, table, table->s->table_map_id, cols,
-                           is_transactional);
-    if (unlikely(!ev))
-      DBUG_RETURN(NULL);
+      ev= new(rows_event_buffer) RowsEventT(this, table,
+                                            table->s->table_map_id, cols,
+                                            is_transactional);
     ev->server_id= serv_id; // I don't like this, it's too easy to forget.
+
     /*
-      flush the pending event and replace it with the newly created
-      event...
+      Placement new cannot fail unless the constructor fail. In either
+      case, NULL will not be returned.
     */
-    if (unlikely(mysql_bin_log.flush_and_set_pending_rows_event(this, ev)))
-    {
-      delete ev;
-      DBUG_RETURN(NULL);
-    }
+    DBUG_ASSERT(ev != NULL);
+
+    binlog_set_pending_rows_event(ev);
 
     DBUG_RETURN(ev);               /* This is the new pending event */
   }
@@ -2633,7 +2639,11 @@
 {
   if (Rows_log_event *pending= binlog_get_pending_rows_event())
   {
-    delete pending;
+    /*
+      Call destructor directly, we are not releasing the memory for
+      this one.
+    */
+    pending->~Rows_log_event();
     binlog_set_pending_rows_event(0);
   }
 }

--- 1.297/sql/sql_class.h	2006-06-06 07:34:58 +02:00
+++ 1.298/sql/sql_class.h	2006-06-16 09:30:19 +02:00
@@ -912,6 +912,11 @@
   void set_server_id(uint32 sid) { server_id = sid; }
 
   /*
+    A pointer to a buffer for storing rows event in
+   */
+  unsigned char *rows_event_buffer;
+
+  /*
     Member functions to handle pending event for row-level logging.
   */
   template <class RowsEventT> Rows_log_event*
@@ -1193,9 +1198,13 @@
   partition_info *work_part_info;
 #endif
   
+private:
+  friend class THD_BUILDER;
+
   THD();
   ~THD();
 
+public:
   void init(void);
   /*
     Initialize memory roots necessary for query processing and (!)

--- 1.201/sql/sql_insert.cc	2006-06-06 07:34:58 +02:00
+++ 1.202/sql/sql_insert.cc	2006-06-16 09:30:19 +02:00
@@ -22,6 +22,7 @@
 #include "sql_trigger.h"
 #include "sql_select.h"
 #include "sql_show.h"
+#include "thd_builder.h"
 
 static int check_null_fields(THD *thd,TABLE *entry);
 #ifndef EMBEDDED_LIBRARY
@@ -1236,7 +1237,7 @@
   ulong query_length;
   ulong query_allocated;
 public:
-  THD thd;
+  THD_BUILDER::THD_POINTER thd;
   TABLE *table;
   pthread_mutex_t mutex;
   pthread_cond_t cond,cond_client;
@@ -1252,18 +1253,19 @@
      table(0),tables_in_use(0),stacked_inserts(0), status(0), dead(0),
      group_count(0)
   {
-    thd.security_ctx->user=thd.security_ctx->priv_user=(char*) delayed_user;
-    thd.security_ctx->host=(char*) my_localhost;
-    thd.current_tablenr=0;
-    thd.version=refresh_version;
-    thd.command=COM_DELAYED_INSERT;
-    thd.lex->current_select= 0; 		// for my_message_sql
-    thd.lex->sql_command= SQLCOM_INSERT;        // For innodb::store_lock()
+    thd= THD_BUILDER::instance()->create();
+    thd->security_ctx->user= thd->security_ctx->priv_user= (char*) delayed_user;
+    thd->security_ctx->host= (char*) my_localhost;
+    thd->current_tablenr= 0;
+    thd->version= refresh_version;
+    thd->command= COM_DELAYED_INSERT;
+    thd->lex->current_select= 0; 		// for my_message_sql
+    thd->lex->sql_command= SQLCOM_INSERT;        // For innodb::store_lock()
 
-    bzero((char*) &thd.net, sizeof(thd.net));		// Safety
+    bzero((char*) &thd->net, sizeof(thd->net));		// Safety
     bzero((char*) &table_list, sizeof(table_list));	// Safety
-    thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT;
-    thd.security_ctx->host_or_ip= "";
+    thd->system_thread= SYSTEM_THREAD_DELAYED_INSERT;
+    thd->security_ctx->host_or_ip= "";
     bzero((char*) &info,sizeof(info));
     pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST);
     pthread_cond_init(&cond,NULL);
@@ -1280,16 +1282,17 @@
     while ((row=rows.get()))
       delete row;
     if (table)
-      close_thread_tables(&thd);
+      close_thread_tables(thd);
     VOID(pthread_mutex_lock(&LOCK_thread_count));
     pthread_mutex_destroy(&mutex);
     pthread_cond_destroy(&cond);
     pthread_cond_destroy(&cond_client);
-    thd.unlink();				// Must be unlinked under lock
-    x_free(thd.query);
-    thd.security_ctx->user= thd.security_ctx->host=0;
+    thd->unlink();				// Must be unlinked under lock
+    x_free(thd->query);
+    thd->security_ctx->user= thd->security_ctx->host=0;
     thread_count--;
     delayed_insert_threads--;
+    THD_BUILDER::instance()->destroy(thd);
     VOID(pthread_mutex_unlock(&LOCK_thread_count));
     VOID(pthread_cond_broadcast(&COND_thread_count)); /* Tell main we are ready */
   }
@@ -1324,7 +1327,7 @@
     if (!--locks_in_memory)
     {
       pthread_mutex_lock(&mutex);
-      if (thd.killed && ! stacked_inserts && ! tables_in_use)
+      if (thd->killed && ! stacked_inserts && ! tables_in_use)
       {
 	pthread_cond_signal(&cond);
 	status=1;
@@ -1351,7 +1354,7 @@
   delayed_insert *tmp;
   while ((tmp=it++))
   {
-    if (!strcmp(tmp->thd.db, table_list->db) &&
+    if (!strcmp(tmp->thd->db, table_list->db) &&
 	!strcmp(table_list->table_name, tmp->table->s->table_name.str))
     {
       tmp->lock();
@@ -1410,19 +1413,19 @@
       pthread_mutex_lock(&LOCK_thread_count);
       thread_count++;
       pthread_mutex_unlock(&LOCK_thread_count);
-      if (!(tmp->thd.db=my_strdup(table_list->db,MYF(MY_WME))) ||
-	  !(tmp->thd.query=my_strdup(table_list->table_name,MYF(MY_WME))))
+      if (!(tmp->thd->db=my_strdup(table_list->db,MYF(MY_WME))) ||
+	  !(tmp->thd->query=my_strdup(table_list->table_name,MYF(MY_WME))))
       {
 	delete tmp;
 	my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
 	goto err1;
       }
       tmp->table_list= *table_list;			// Needed to open table
-      tmp->table_list.db= tmp->thd.db;
-      tmp->table_list.alias= tmp->table_list.table_name= tmp->thd.query;
+      tmp->table_list.db= tmp->thd->db;
+      tmp->table_list.alias= tmp->table_list.table_name= tmp->thd->query;
       tmp->lock();
       pthread_mutex_lock(&tmp->mutex);
-      if ((error=pthread_create(&tmp->thd.real_id,&connection_attrib,
+      if ((error=pthread_create(&tmp->thd->real_id,&connection_attrib,
 				handle_delayed_insert,(void*) tmp)))
       {
 	DBUG_PRINT("error",
@@ -1437,7 +1440,7 @@
 
       /* Wait until table is open */
       thd->proc_info="waiting for handler open";
-      while (!tmp->thd.killed && !tmp->table && !thd->killed)
+      while (!tmp->thd->killed && !tmp->table && !thd->killed)
       {
 	pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
       }
@@ -1448,14 +1451,14 @@
       */
       start_waiting_global_read_lock(thd);
       thd->proc_info="got old table";
-      if (tmp->thd.killed)
+      if (tmp->thd->killed)
       {
-	if (tmp->thd.is_fatal_error)
+	if (tmp->thd->is_fatal_error)
 	{
 	  /* Copy error message and abort */
 	  thd->fatal_error();
-	  strmov(thd->net.last_error,tmp->thd.net.last_error);
-	  thd->net.last_errno=tmp->thd.net.last_errno;
+	  strmov(thd->net.last_error,tmp->thd->net.last_error);
+	  thd->net.last_errno=tmp->thd->net.last_errno;
 	}
 	tmp->unlock();
 	goto err;
@@ -1474,7 +1477,7 @@
   pthread_mutex_unlock(&tmp->mutex);
   if (table)
     thd->di=tmp;
-  else if (tmp->thd.is_fatal_error)
+  else if (tmp->thd->is_fatal_error)
     thd->fatal_error();
   /* Unlock the delayed insert object after its last access. */
   tmp->unlock();
@@ -1510,11 +1513,11 @@
   /* First request insert thread to get a lock */
   status=1;
   tables_in_use++;
-  if (!thd.lock)				// Table is not locked
+  if (!thd->lock)				// Table is not locked
   {
     client_thd->proc_info="waiting for handler lock";
     pthread_cond_signal(&cond);			// Tell handler to lock table
-    while (!dead && !thd.lock && ! client_thd->killed)
+    while (!dead && !thd->lock && ! client_thd->killed)
     {
       pthread_cond_wait(&cond_client,&mutex);
     }
@@ -1523,8 +1526,8 @@
       goto error;
     if (dead)
     {
-      strmov(client_thd->net.last_error,thd.net.last_error);
-      client_thd->net.last_errno=thd.net.last_errno;
+      strmov(client_thd->net.last_error,thd->net.last_error);
+      client_thd->net.last_errno=thd->net.last_errno;
       goto error;
     }
   }
@@ -1640,7 +1643,7 @@
   delayed_insert *di=thd->di;
   pthread_mutex_lock(&di->mutex);
   DBUG_PRINT("info",("tables in use: %d",di->tables_in_use));
-  if (!--di->tables_in_use || di->thd.killed)
+  if (!--di->tables_in_use || di->thd->killed)
   {						// Unlock table
     di->status=1;
     pthread_cond_signal(&di->cond);
@@ -1662,23 +1665,23 @@
   {
     /* Ensure that the thread doesn't kill itself while we are looking at it */
     pthread_mutex_lock(&tmp->mutex);
-    tmp->thd.killed= THD::KILL_CONNECTION;
-    if (tmp->thd.mysys_var)
+    tmp->thd->killed= THD::KILL_CONNECTION;
+    if (tmp->thd->mysys_var)
     {
-      pthread_mutex_lock(&tmp->thd.mysys_var->mutex);
-      if (tmp->thd.mysys_var->current_cond)
+      pthread_mutex_lock(&tmp->thd->mysys_var->mutex);
+      if (tmp->thd->mysys_var->current_cond)
       {
 	/*
 	  We need the following test because the main mutex may be locked
 	  in handle_delayed_insert()
 	*/
-	if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
-	  pthread_mutex_lock(tmp->thd.mysys_var->current_mutex);
-	pthread_cond_broadcast(tmp->thd.mysys_var->current_cond);
-	if (&tmp->mutex != tmp->thd.mysys_var->current_mutex)
-	  pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex);
+	if (&tmp->mutex != tmp->thd->mysys_var->current_mutex)
+	  pthread_mutex_lock(tmp->thd->mysys_var->current_mutex);
+	pthread_cond_broadcast(tmp->thd->mysys_var->current_cond);
+	if (&tmp->mutex != tmp->thd->mysys_var->current_mutex)
+	  pthread_mutex_unlock(tmp->thd->mysys_var->current_mutex);
       }
-      pthread_mutex_unlock(&tmp->thd.mysys_var->mutex);
+      pthread_mutex_unlock(&tmp->thd->mysys_var->mutex);
     }
     pthread_mutex_unlock(&tmp->mutex);
   }
@@ -1693,7 +1696,7 @@
 pthread_handler_t handle_delayed_insert(void *arg)
 {
   delayed_insert *di=(delayed_insert*) arg;
-  THD *thd= &di->thd;
+  THD_BUILDER::THD_POINTER thd= di->thd;
 
   pthread_detach_this_thread();
   /* Add thread to THD list so that's it's visible in 'show processlist' */
@@ -1786,9 +1789,9 @@
       set_timespec(abstime, delayed_insert_timeout);
 
       /* Information for pthread_kill */
-      di->thd.mysys_var->current_mutex= &di->mutex;
-      di->thd.mysys_var->current_cond= &di->cond;
-      di->thd.proc_info="Waiting for INSERT";
+      di->thd->mysys_var->current_mutex= &di->mutex;
+      di->thd->mysys_var->current_cond= &di->cond;
+      di->thd->proc_info="Waiting for INSERT";
 
       DBUG_PRINT("info",("Waiting for someone to insert rows"));
       while (!thd->killed)
@@ -1817,13 +1820,13 @@
       }
       /* We can't lock di->mutex and mysys_var->mutex at the same time */
       pthread_mutex_unlock(&di->mutex);
-      pthread_mutex_lock(&di->thd.mysys_var->mutex);
-      di->thd.mysys_var->current_mutex= 0;
-      di->thd.mysys_var->current_cond= 0;
-      pthread_mutex_unlock(&di->thd.mysys_var->mutex);
+      pthread_mutex_lock(&di->thd->mysys_var->mutex);
+      di->thd->mysys_var->current_mutex= 0;
+      di->thd->mysys_var->current_cond= 0;
+      pthread_mutex_unlock(&di->thd->mysys_var->mutex);
       pthread_mutex_lock(&di->mutex);
     }
-    di->thd.proc_info=0;
+    di->thd->proc_info=0;
 
     if (di->tables_in_use && ! thd->lock)
     {
@@ -1957,19 +1960,19 @@
 
   table->next_number_field=table->found_next_number_field;
 
-  thd.proc_info="upgrading lock";
-  if (thr_upgrade_write_delay_lock(*thd.lock->locks))
+  thd->proc_info="upgrading lock";
+  if (thr_upgrade_write_delay_lock(*thd->lock->locks))
   {
     /* This can only happen if thread is killed by shutdown */
     sql_print_error(ER(ER_DELAYED_CANT_CHANGE_LOCK),table->s->table_name.str);
     goto err;
   }
 
-  thd.proc_info="insert";
+  thd->proc_info="insert";
   max_rows= delayed_insert_limit;
-  if (thd.killed || table->s->version != refresh_version)
+  if (thd->killed || table->s->version != refresh_version)
   {
-    thd.killed= THD::KILL_CONNECTION;
+    thd->killed= THD::KILL_CONNECTION;
     max_rows= ~(ulong)0;                        // Do as much as possible
   }
 
@@ -1987,11 +1990,11 @@
     pthread_mutex_unlock(&mutex);
     memcpy(table->record[0],row->record,table->s->reclength);
 
-    thd.start_time=row->start_time;
-    thd.query_start_used=row->query_start_used;
-    thd.last_insert_id=row->last_insert_id;
-    thd.last_insert_id_used=row->last_insert_id_used;
-    thd.insert_id_used=row->insert_id_used;
+    thd->start_time=row->start_time;
+    thd->query_start_used=row->query_start_used;
+    thd->last_insert_id=row->last_insert_id;
+    thd->last_insert_id_used=row->last_insert_id_used;
+    thd->insert_id_used=row->insert_id_used;
     table->timestamp_field_type= row->timestamp_field_type;
 
     info.ignore= row->ignore;
@@ -2002,8 +2005,8 @@
       table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
       using_ignore=1;
     }
-    thd.clear_error(); // reset error for binlog
-    if (write_record(&thd, table, &info))
+    thd->clear_error(); // reset error for binlog
+    if (write_record(thd, table, &info))
     {
       info.error_count++;				// Ignore errors
       thread_safe_increment(delayed_insert_errors,&LOCK_delayed_status);
@@ -2035,17 +2038,17 @@
       {
 	if (tables_in_use)
 	  pthread_cond_broadcast(&cond_client); // If waiting clients
-	thd.proc_info="reschedule";
+	thd->proc_info="reschedule";
 	pthread_mutex_unlock(&mutex);
 	if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
 	{
 	  /* This should never happen */
 	  table->file->print_error(error,MYF(0));
-	  sql_print_error("%s",thd.net.last_error);
+	  sql_print_error("%s",thd->net.last_error);
 	  goto err;
 	}
-	query_cache_invalidate3(&thd, table, 1);
-	if (thr_reschedule_write_lock(*thd.lock->locks))
+	query_cache_invalidate3(thd, table, 1);
+	if (thr_reschedule_write_lock(*thd->lock->locks))
 	{
 	  /* This should never happen */
 	  sql_print_error(ER(ER_DELAYED_CANT_CHANGE_LOCK),
@@ -2054,28 +2057,28 @@
 	if (!using_bin_log)
 	  table->file->extra(HA_EXTRA_WRITE_CACHE);
 	pthread_mutex_lock(&mutex);
-	thd.proc_info="insert";
+	thd->proc_info="insert";
       }
       if (tables_in_use)
 	pthread_cond_broadcast(&cond_client);	// If waiting clients
     }
   }
 
-  thd.proc_info=0;
+  thd->proc_info=0;
   table->next_number_field=0;
   pthread_mutex_unlock(&mutex);
 
   /* After releasing the mutex, to prevent deadlocks. */
   if (mysql_bin_log.is_open())
-    thd.binlog_query(THD::ROW_QUERY_TYPE, query, query_length, FALSE, FALSE);
+    thd->binlog_query(THD::ROW_QUERY_TYPE, query, query_length, FALSE, FALSE);
 
   if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
   {						// This shouldn't happen
     table->file->print_error(error,MYF(0));
-    sql_print_error("%s",thd.net.last_error);
+    sql_print_error("%s",thd->net.last_error);
     goto err;
   }
-  query_cache_invalidate3(&thd, table, 1);
+  query_cache_invalidate3(thd, table, 1);
   pthread_mutex_lock(&mutex);
   DBUG_RETURN(0);
 

--- 1.40/sql/sql_list.h	2005-12-22 05:10:54 +01:00
+++ 1.41/sql/sql_list.h	2006-06-16 09:30:19 +02:00
@@ -426,6 +426,17 @@
      my_free((gptr)ptr_arg, MYF(MY_WME|MY_ALLOW_ZERO_PTR));
   }
 
+  /* Placement new version of the above */
+  static void *operator new(size_t size, void *ptr)
+  {
+    return ptr;
+  }
+
+  /* Placement delete version of the above */
+  static void operator delete(void* ptr_arg, size_t size, void* ptr)
+  {
+  }
+
   inline ilink()
   {
     prev=0; next=0;

--- 1.549/sql/sql_parse.cc	2006-05-17 15:13:49 +02:00
+++ 1.550/sql/sql_parse.cc	2006-06-16 09:30:19 +02:00
@@ -19,6 +19,7 @@
 #include "sql_repl.h"
 #include "rpl_filter.h"
 #include "repl_failsafe.h"
+#include "thd_builder.h"
 #include <m_ctype.h>
 #include <myisam.h>
 #include <my_dir.h>
@@ -1320,7 +1321,7 @@
 
   net_end(&thd->net);
   thd->cleanup();
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
 
 #ifndef EMBEDDED_LIBRARY
   (void) pthread_mutex_lock(&LOCK_thread_count);
@@ -6767,7 +6768,7 @@
       If reload_acl_and_cache() is called from SIGHUP handler we have to
       allocate temporary THD for execution of acl_reload()/grant_reload().
     */
-    if (!thd && (thd= (tmp_thd= new THD)))
+    if (!thd && (thd= (tmp_thd= THD_BUILDER::instance()->create())))
     {
       thd->thread_stack= (char*) &tmp_thd;
       thd->store_globals();
@@ -6779,7 +6780,7 @@
     }
     if (tmp_thd)
     {
-      delete tmp_thd;
+      THD_BUILDER::instance()->destroy(tmp_thd);
       /* Remember that we don't have a THD */
       my_pthread_setspecific_ptr(THR_THD,  0);
       thd= 0;

--- 1.334/sql/sql_table.cc	2006-05-17 15:02:32 +02:00
+++ 1.335/sql/sql_table.cc	2006-06-16 09:30:20 +02:00
@@ -23,6 +23,7 @@
 #include "sp_head.h"
 #include "sql_trigger.h"
 #include "sql_show.h"
+#include "thd_builder.h"
 
 #ifdef __WIN__
 #include <io.h>
@@ -1078,7 +1079,7 @@
   /*
     To be able to run this from boot, we allocate a temporary THD
   */
-  if (!(thd=new THD))
+  if (!(thd= THD_BUILDER::instance()->create()))
     DBUG_VOID_RETURN;
   thd->thread_stack= (char*) &thd;
   thd->store_globals();
@@ -1104,7 +1105,7 @@
   create_ddl_log_file_name(file_name);
   VOID(my_delete(file_name, MYF(0)));
   global_ddl_log.recovery_phase= FALSE;
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD,  0);
   DBUG_VOID_RETURN;

--- 1.64/sql/sql_udf.cc	2006-03-22 07:59:49 +01:00
+++ 1.65/sql/sql_udf.cc	2006-06-16 09:30:20 +02:00
@@ -33,6 +33,7 @@
 #endif
 
 #include "mysql_priv.h"
+#include "thd_builder.h"
 #include <my_pthread.h>
 
 #ifdef HAVE_DLOPEN
@@ -122,14 +123,14 @@
   my_rwlock_init(&THR_LOCK_udf,NULL);
   
   init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0);
-  THD *new_thd = new THD;
+  THD *new_thd = THD_BUILDER::instance()->create();
   if (!new_thd ||
       hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0))
   {
     sql_print_error("Can't allocate memory for udf structures");
     hash_free(&udf_hash);
     free_root(&mem,MYF(0));
-    delete new_thd;
+    THD_BUILDER::instance()->destroy(new_thd);
     DBUG_VOID_RETURN;
   }
   initialized = 1;
@@ -215,7 +216,7 @@
 
 end:
   close_thread_tables(new_thd);
-  delete new_thd;
+  THD_BUILDER::instance()->destroy(new_thd);
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD,  0);
   DBUG_VOID_RETURN;

--- 1.43/sql/event_executor.cc	2006-04-16 03:17:25 +02:00
+++ 1.44/sql/event_executor.cc	2006-06-16 09:30:18 +02:00
@@ -17,6 +17,7 @@
 #include "event_priv.h"
 #include "event.h"
 #include "sp.h"
+#include "thd_builder.h"
 
 #define WAIT_STATUS_READY         0
 #define WAIT_STATUS_EMPTY_QUEUE   1
@@ -287,7 +288,7 @@
   if (init_thr_lock() || thd->store_globals())
   {
     thd->cleanup();
-    delete thd;
+    THD_BUILDER::instance()->destroy(thd);
     DBUG_RETURN(-1);
   }
 
@@ -445,7 +446,7 @@
   }
   
   /* note that contructor of THD uses DBUG_ ! */
-  if (!(thd = new THD))                         
+  if (!(thd = THD_BUILDER::instance()->create()))                         
   {
     sql_print_error("SCHEDULER: Cannot create THD for the main thread.");
     goto err_no_thd;
@@ -662,7 +663,7 @@
   thread_running--;
 #ifndef DBUG_FAULTY_THR
   THD_CHECK_SENTRY(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
 #endif
   pthread_mutex_unlock(&LOCK_thread_count);
 
@@ -711,7 +712,7 @@
 #ifndef DBUG_FAULTY_THR
   my_thread_init();
 
-  if (!(thd = new THD)) /* note that contructor of THD uses DBUG_ ! */
+  if (!(thd = THD_BUILDER::instance()->create())) /* note that contructor of THD uses DBUG_ ! */
   {
     sql_print_error("SCHEDULER: Cannot create a THD structure in an worker.");
     goto err_no_thd;
@@ -780,7 +781,7 @@
 
   VOID(pthread_mutex_lock(&LOCK_thread_count));
   THD_CHECK_SENTRY(thd);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
 #endif
   VOID(pthread_mutex_unlock(&LOCK_thread_count));
 

--- 1.35/sql/tztime.cc	2006-05-03 16:03:58 +02:00
+++ 1.36/sql/tztime.cc	2006-06-16 09:30:20 +02:00
@@ -41,6 +41,7 @@
 #include "tzfile.h"
 #include <m_string.h>
 #include <my_dir.h>
+#include "thd_builder.h"
 
 /*
   Now we don't use abbreviations in server but we will do this in future.
@@ -1566,7 +1567,7 @@
   /*
     To be able to run this from boot, we allocate a temporary THD
   */
-  if (!(thd= new THD))
+  if (!(thd= THD_BUILDER::instance()->create()))
     DBUG_RETURN(1);
   thd->thread_stack= (char*) &thd;
   thd->store_globals();
@@ -1727,7 +1728,7 @@
   if (return_val)
     my_tz_free();
 end:
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   if (org_thd)
     org_thd->store_globals();			/* purecov: inspected */
   else

--- 1.305/sql/ha_ndbcluster.cc	2006-05-16 10:37:33 +02:00
+++ 1.306/sql/ha_ndbcluster.cc	2006-06-16 09:30:18 +02:00
@@ -36,6 +36,7 @@
 
 #include "ha_ndbcluster_binlog.h"
 #include "ha_ndbcluster_tables.h"
+#include "thd_builder.h"
 
 #include <mysql/plugin.h>
 
@@ -7746,7 +7747,7 @@
   DBUG_ENTER("ndb_util_thread");
   DBUG_PRINT("enter", ("ndb_cache_check_time: %d", ndb_cache_check_time));
 
-  thd= new THD; /* note that contructor of THD uses DBUG_ */
+  thd= THD_BUILDER::instance()->create(); /* note that contructor of THD uses DBUG_ */
   THD_CHECK_SENTRY(thd);
   ndb= new Ndb(g_ndb_cluster_connection, "");
 
@@ -7757,7 +7758,7 @@
   if (thd->store_globals() || (ndb->init() != 0))
   {
     thd->cleanup();
-    delete thd;
+    THD_BUILDER::instance()->destroy(thd);
     delete ndb;
     DBUG_RETURN(NULL);
   }
@@ -7958,7 +7959,7 @@
   sql_print_information("Stopping Cluster Utility thread");
   net_end(&thd->net);
   thd->cleanup();
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   delete ndb;
   DBUG_PRINT("exit", ("ndb_util_thread"));
   my_thread_end();
--- New file ---
+++ sql/thd_builder.cc	06/06/16 09:30:20

#include "thd_builder.h"

#include "mysql_priv.h"
#include "log_event.h"

THD_BUILDER::THD_BUILDER()
{
}


static THD_BUILDER *s_builder= 0;

THD_BUILDER *
THD_BUILDER::instance()
{
  if (s_builder == 0)
    s_builder= new THD_BUILDER;
  return s_builder;
}


THD_BUILDER::THD_POINTER
THD_BUILDER::create()
{
#ifdef HAVE_ROW_BASED_REPLICATION
  my_size_t const max_size= max(sizeof(Delete_rows_log_event),
                                max(sizeof(Write_rows_log_event),
                                    sizeof(Update_rows_log_event)));

  THD_POINTER thd_buf;

  /*
    Creating THD instance and rows event buffer in one go, since the
    rows-event buffer will be used a lot during the lifetime of the
    THD.
   */
  unsigned char *re_buf;                        // Rows Event Buffer

  void *memory= my_multi_malloc(MYF(MY_WME),
                                &thd_buf, sizeof(THD),
                                &re_buf, max_size,
                                NullS);
  if (memory)
  {
    THD_POINTER thd= new(thd_buf) THD;
    thd->rows_event_buffer= re_buf;
    return thd;
  }
  else
  {
    return NULL;
  }
#else
  return new THD;
#endif
}


void
THD_BUILDER::destroy(THD_BUILDER::THD_POINTER thd) 
{
#ifdef HAVE_ROW_BASED_REPLICATION
  delete thd;
#else
  thd->~THD();
  my_free(reinterpret_cast<char*>(thd), MYF(MY_WME));
#endif
}

--- New file ---
+++ sql/thd_builder.h	06/06/16 09:30:21
#ifndef THD_BUILDER_H
#define THD_BUILDER_H

// Forward declarations
class THD;

/*
  Builder for the construction of THD instances.

  NOTE

    This class uses the Builder and Singleton design patterns.  The
    purpose of the Builder is to separate the construction method from
    the representation and the purpose of the Singleton is to limit
    the number of available instances to one.
 */
class THD_BUILDER {
public:
  /*
    Convenience typedef for the return value of create() below.

    NOTE

      Please use this type and not THD* since the return value of
      create() might change.
  */
  typedef THD *THD_POINTER;


  /**
     Return the singleton instance of the builder.

     @return A pointer to an THD builder instance.
   */
  static THD_BUILDER *instance();

  /**
     Create a THD instance.

     The instance is allocated internally and destroy() should be
     called below to free the memory.

     @return A pointer to a THD instance. 
   */
  THD_POINTER create();

  /**
     Destroy a THD instance previosly allocated using
     THD_BUILDER::create().

     @param thd  A pointer to a THD instance.
   */
  void destroy(THD_POINTER thd);

private:
  /**
     Private constructor.

     We will use the Singleton pattern, so the constructor is
     hidden. Instead, use the THD_BUILDER::instance() above.

     @see THD_BUILDER::instance()
  */
  THD_BUILDER();

  THD_BUILDER(THD_BUILDER const&);
};


#endif // THD_BUILDER_H


--- 1.20/sql/sql_plugin.cc	2006-04-24 23:32:40 +02:00
+++ 1.21/sql/sql_plugin.cc	2006-06-16 09:30:20 +02:00
@@ -16,6 +16,7 @@
 
 #include "mysql_priv.h"
 #include <my_pthread.h>
+#include "thd_builder.h"
 #define REPORT_TO_LOG  1
 #define REPORT_TO_USER 2
 
@@ -735,10 +736,10 @@
 
   DBUG_ASSERT(initialized);
 
-  if (!(new_thd= new THD))
+  if (!(new_thd= THD_BUILDER::instance()->create()))
   {
     sql_print_error("Can't allocate memory for plugin structures");
-    delete new_thd;
+    THD_BUILDER::instance()->destroy(new_thd);
     DBUG_VOID_RETURN;
   }
   init_sql_alloc(&mem, 1024, 0);
@@ -778,7 +779,7 @@
 end:
   free_root(&mem, MYF(0));
   close_thread_tables(new_thd);
-  delete new_thd;
+  THD_BUILDER::instance()->destroy(new_thd);
   /* Remember that we don't have a THD */
   my_pthread_setspecific_ptr(THR_THD, 0);
   DBUG_VOID_RETURN;

--- 1.89/libmysqld/Makefile.am	2006-05-09 00:49:10 +02:00
+++ 1.90/libmysqld/Makefile.am	2006-06-16 09:30:17 +02:00
@@ -71,6 +71,7 @@
 	event_executor.cc event.cc event_timed.cc \
 	rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
 	sql_tablespace.cc \
+	thd_builder.cc \
 	rpl_injector.cc my_user.c partition_info.cc
 
 libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources)

--- 1.114/libmysqld/lib_sql.cc	2006-04-10 18:34:07 +02:00
+++ 1.115/libmysqld/lib_sql.cc	2006-06-16 09:30:18 +02:00
@@ -366,7 +366,7 @@
   thd->clear_data_list();
   thread_count--;
   thd->store_globals();
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   mysql->thd=0;
 }
 
@@ -562,7 +562,7 @@
 
 void *create_embedded_thd(int client_flag, char *db)
 {
-  THD * thd= new THD;
+  THD * thd= THD_BUILDER::instance()->create();
   thd->thread_id= thread_id++;
 
   thd->thread_stack= (char*) &thd;
@@ -600,7 +600,7 @@
   thread_count++;
   return thd;
 err:
-  delete(thd);
+  THD_BUILDER::instance()->destroy(thd);
   return NULL;
 }
 

--- 1.65/sql/repl_failsafe.cc	2006-05-01 20:38:11 +02:00
+++ 1.66/sql/repl_failsafe.cc	2006-06-16 09:30:19 +02:00
@@ -21,6 +21,7 @@
 #include "sql_repl.h"
 #include "slave.h"
 #include "rpl_filter.h"
+#include "thd_builder.h"
 #include "log_event.h"
 #include <mysql.h>
 
@@ -581,7 +582,7 @@
 pthread_handler_t handle_failsafe_rpl(void *arg)
 {
   DBUG_ENTER("handle_failsafe_rpl");
-  THD *thd = new THD;
+  THD *thd = THD_BUILDER::instance()->create();
   thd->thread_stack = (char*)&thd;
   MYSQL* recovery_captain = 0;
   const char* msg;
@@ -620,7 +621,7 @@
 err:
   if (recovery_captain)
     mysql_close(recovery_captain);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
   my_thread_end();
   pthread_exit(0);
   DBUG_RETURN(0);

--- 1.54/sql/ha_ndbcluster_binlog.cc	2006-05-17 08:34:41 +02:00
+++ 1.55/sql/ha_ndbcluster_binlog.cc	2006-06-16 09:30:18 +02:00
@@ -22,6 +22,7 @@
 #ifdef HAVE_NDB_BINLOG
 #include "rpl_injector.h"
 #include "rpl_filter.h"
+#include "thd_builder.h"
 #include "slave.h"
 #include "ha_ndbcluster_binlog.h"
 #include "NdbDictionary.hpp"
@@ -3176,14 +3177,14 @@
   my_thread_init();
   DBUG_ENTER("ndb_binlog_thread");
 
-  thd= new THD; /* note that contructor of THD uses DBUG_ */
+  thd= THD_BUILDER::instance()->create(); /* note that contructor of THD uses DBUG_ */
   THD_CHECK_SENTRY(thd);
 
   thd->thread_stack= (char*) &thd; /* remember where our stack is */
   if (thd->store_globals())
   {
     thd->cleanup();
-    delete thd;
+    THD_BUILDER::instance()->destroy(thd);
     ndb_binlog_thread_running= -1;
     pthread_mutex_unlock(&injector_mutex);
     pthread_cond_signal(&injector_cond);
@@ -3754,7 +3755,7 @@
 
   // Placed here to avoid a memory leak; TODO: check if needed
   net_end(&thd->net);
-  delete thd;
+  THD_BUILDER::instance()->destroy(thd);
 
   ndb_binlog_thread_running= -1;
   ndb_binlog_running= FALSE;
Thread
bk commit into 5.1 tree (mats:1.2162)Mats Kindahl20 Jun