=== modified file 'mysql-test/suite/ndb/my.cnf' --- mysql-test/suite/ndb/my.cnf 2009-10-23 14:56:46 +0000 +++ mysql-test/suite/ndb/my.cnf 2009-11-17 19:48:24 +0000 @@ -41,6 +41,7 @@ ndb-wait-connected=20 ndb-wait-setup=60 ndb-cluster-connection-pool=3 ndb-extra-logging=99 +ndb-pool-size=10 [ENV] NDB_CONNECTSTRING= @mysql_cluster.1.ndb_connectstring === modified file 'sql/ha_ndbcluster.cc' --- sql/ha_ndbcluster.cc 2009-11-08 12:52:27 +0000 +++ sql/ha_ndbcluster.cc 2009-11-17 21:58:48 +0000 @@ -8534,17 +8534,34 @@ int ha_ndbcluster::close(void) } -/** - @todo - - Alt.1 If init fails because to many allocated Ndb - wait on condition for a Ndb object to be released. - - Alt.2 Seize/release from pool, wait until next release -*/ -Thd_ndb* ha_ndbcluster::seize_thd_ndb() +extern uint opt_ndb_poolsize; +static pthread_mutex_t LOCK_thd_ndb_pool; +//static List thd_ndb_pool; +static Thd_ndb* thd_ndb_pool[4700]; +static uint thd_ndb_pool_pos; + +Thd_ndb* ha_ndbcluster::seize_thd_ndb(bool use_pool) { Thd_ndb *thd_ndb; DBUG_ENTER("seize_thd_ndb"); + if (use_pool && opt_ndb_poolsize) + { + pthread_mutex_lock(&LOCK_thd_ndb_pool); + if (thd_ndb_pool_pos) + { + thd_ndb = thd_ndb_pool[--thd_ndb_pool_pos]; + fprintf(stderr, "pool: Took %p from pool, size: %d\n", + thd_ndb, thd_ndb_pool_pos); + DBUG_ASSERT(thd_ndb); + pthread_mutex_unlock(&LOCK_thd_ndb_pool); + DBUG_RETURN(thd_ndb); + } + pthread_mutex_unlock(&LOCK_thd_ndb_pool); + fprintf(stderr, "pool: Could not find thd_ndb in pool, size: %d\n", + thd_ndb_pool_pos); + } + thd_ndb= new Thd_ndb(); if (thd_ndb == NULL) { @@ -8567,9 +8584,25 @@ Thd_ndb* ha_ndbcluster::seize_thd_ndb() } -void ha_ndbcluster::release_thd_ndb(Thd_ndb* thd_ndb) +void ha_ndbcluster::release_thd_ndb(Thd_ndb* thd_ndb, bool use_pool) { DBUG_ENTER("release_thd_ndb"); + + if (use_pool && opt_ndb_poolsize) + { + pthread_mutex_lock(&LOCK_thd_ndb_pool); + if (thd_ndb_pool_pos < opt_ndb_poolsize) + { + thd_ndb_pool[thd_ndb_pool_pos++] = thd_ndb; + fprintf(stderr, "pool: Pushed %p to pool, size: %d\n", + thd_ndb, thd_ndb_pool_pos); + pthread_mutex_unlock(&LOCK_thd_ndb_pool); + DBUG_VOID_RETURN; + } + fprintf(stderr, "pool: Pool full, size: %d\n", thd_ndb_pool_pos); + pthread_mutex_unlock(&LOCK_thd_ndb_pool); + } + delete thd_ndb; DBUG_VOID_RETURN; } @@ -8637,7 +8670,7 @@ Ndb* check_ndb_in_thd(THD* thd, bool val Thd_ndb *thd_ndb= get_thd_ndb(thd); if (!thd_ndb) { - if (!(thd_ndb= ha_ndbcluster::seize_thd_ndb())) + if (!(thd_ndb= ha_ndbcluster::seize_thd_ndb(true))) return NULL; set_thd_ndb(thd, thd_ndb); } @@ -8674,7 +8707,7 @@ static int ndbcluster_close_connection(h DBUG_ENTER("ndbcluster_close_connection"); if (thd_ndb) { - ha_ndbcluster::release_thd_ndb(thd_ndb); + ha_ndbcluster::release_thd_ndb(thd_ndb, true); set_thd_ndb(thd, NULL); // not strictly required but does not hurt either } DBUG_RETURN(0); @@ -9411,6 +9444,7 @@ static int ndbcluster_init(void *p) pthread_mutex_init(&ndbcluster_mutex,MY_MUTEX_INIT_FAST); pthread_mutex_init(&LOCK_ndb_util_thread, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&LOCK_thd_ndb_pool, MY_MUTEX_INIT_FAST); pthread_cond_init(&COND_ndb_util_thread, NULL); pthread_cond_init(&COND_ndb_util_ready, NULL); pthread_cond_init(&COND_ndb_setup_complete, NULL); @@ -9551,6 +9585,7 @@ static int ndbcluster_end(handlerton *ht pthread_mutex_destroy(&ndbcluster_mutex); pthread_mutex_destroy(&LOCK_ndb_util_thread); + pthread_mutex_destroy(&LOCK_thd_ndb_pool); pthread_cond_destroy(&COND_ndb_util_thread); pthread_cond_destroy(&COND_ndb_util_ready); pthread_cond_destroy(&COND_ndb_setup_complete); === modified file 'sql/ha_ndbcluster.h' --- sql/ha_ndbcluster.h 2009-10-28 18:42:32 +0000 +++ sql/ha_ndbcluster.h 2009-11-17 21:57:43 +0000 @@ -486,8 +486,8 @@ class ha_ndbcluster: public handler int ndb_update_row(const uchar *old_data, uchar *new_data, int is_bulk_update); - static Thd_ndb* seize_thd_ndb(); - static void release_thd_ndb(Thd_ndb* thd_ndb); + static Thd_ndb* seize_thd_ndb(bool use_pool = false); + static void release_thd_ndb(Thd_ndb* thd_ndb, bool use_pool = false); static void set_dbname(const char *pathname, char *dbname); static void set_tabname(const char *pathname, char *tabname); === modified file 'sql/mysqld.cc' --- sql/mysqld.cc 2009-10-23 19:20:27 +0000 +++ sql/mysqld.cc 2009-11-17 19:46:48 +0000 @@ -471,6 +471,7 @@ my_bool opt_ndb_log_updated_only= FALSE; my_bool opt_ndb_log_orig= FALSE; my_bool opt_ndb_log_bin= FALSE; my_bool opt_ndb_log_empty_epochs= FALSE; +uint opt_ndb_poolsize = 0; extern "C" char opt_ndb_constrbuf[1024]; @@ -6297,6 +6298,11 @@ master-ssl", (uchar**) &opt_ndb_cluster_connection_pool, (uchar**) &opt_ndb_cluster_connection_pool, 0, GET_ULONG, REQUIRED_ARG, 1, 1, 63, 0, 0, 0}, + { "ndb-pool-size", 255, + "Maximum size for pool of Ndb object", + (uchar**) &opt_ndb_poolsize, + (uchar**) &opt_ndb_poolsize, + 0, GET_UINT, REQUIRED_ARG, 0, 0, 4700, 0, 0, 0}, #endif {"new", 'n', "Use very new possible 'unsafe' functions.", (uchar**) &global_system_variables.new_mode,