From f6cd0148b8401694fc0d532e35f86dd350947611 Mon Sep 17 00:00:00 2001 From: "patg@krsna.patg.net" <> Date: Fri, 18 Nov 2005 17:02:27 -0800 Subject: [PATCH 1/2] BUG #14524 Patch that fixes crashing when partition uses blackole for underlying tables. --- mysql-test/r/partition.result | 8 ++++++++ mysql-test/t/partition.test | 10 ++++++++++ sql/ha_partition.cc | 12 ++++++++++-- sql/ha_partition.h | 1 + sql/lock.cc | 15 +++++++++++---- sql/sql_partition.cc | 2 +- 6 files changed, 41 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index eefa45a9e0c..4ceb802a448 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -108,3 +108,11 @@ insert into t1 values (3); insert into t1 values (4); UNLOCK TABLES; drop table t1; +DROP TABLE IF EXISTS `t1`; +Warnings: +Note 1051 Unknown table 't1' +CREATE TABLE `t1` ( +`id` int(11) default NULL +) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ; +SELECT * FROM t1; +id diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 21b24dfe4f2..e56c31ad82c 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -162,3 +162,13 @@ UNLOCK TABLES; drop table t1; +# +# BUG 14524 +# +--disable-warnings +DROP TABLE IF EXISTS `t1`; +--enable-warnings +CREATE TABLE `t1` ( + `id` int(11) default NULL +) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ; +SELECT * FROM t1; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 7a0678d6f84..c42ce2ed3d5 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* - This handler was developed by Mikael Ronström for version 5.1 of MySQL. + This handler was developed by Mikael Ronstrom for version 5.1 of MySQL. It is an abstraction layer on top of other handlers such as MyISAM, InnoDB, Federated, Berkeley DB and so forth. Partitioned tables can also be handled by a storage engine. The current example of this is NDB @@ -167,6 +167,10 @@ void ha_partition::init_handler_variables() m_last_part= 0; m_rec0= 0; m_curr_key_info= 0; + /* + this allows blackhole to work properly + */ + m_no_locks= 0; #ifdef DONT_HAVE_TO_BE_INITALIZED m_start_key.flag= 0; @@ -912,6 +916,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked) if ((error= (*file)->ha_open((const char*) name_buff, mode, test_if_locked))) goto err_handler; + m_no_locks+= (*file)->lock_count(); name_buffer_ptr+= strlen(name_buffer_ptr) + 1; set_if_bigger(ref_length, ((*file)->ref_length)); } while (*(++file)); @@ -1098,6 +1103,9 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type) uint ha_partition::lock_count() const { DBUG_ENTER("ha_partition::lock_count"); + if (m_no_locks == 0) + DBUG_RETURN(0); + DBUG_RETURN(m_tot_parts); } @@ -1143,7 +1151,7 @@ void ha_partition::unlock_row() ADDITIONAL INFO: Most handlers set timestamp when calling write row if any such fields - exists. Since we are calling an underlying handler we assume the´ + exists. Since we are calling an underlying handler we assume the underlying handler will assume this responsibility. Underlying handlers will also call update_auto_increment to calculate diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 841719bddf4..fb180fdf666 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -67,6 +67,7 @@ private: u_long m_low_byte_first; uint m_tot_parts; // Total number of partitions; + uint m_no_locks; // For engines like ha_blackhole, which needs no locks uint m_last_part; // Last file that we update,write int m_lock_type; // Remembers type of last // external_lock diff --git a/sql/lock.cc b/sql/lock.cc index 0af22cac399..00277f3bdd8 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -146,6 +146,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, } thd->proc_info="System lock"; + DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); if (lock_external(thd, tables, count)) { my_free((gptr) sql_lock,MYF(0)); @@ -153,6 +154,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count, break; } thd->proc_info="Table lock"; + DBUG_PRINT("info", ("thd->proc_info %s", thd->proc_info)); thd->locked=1; rc= thr_lock_errno_to_mysql[(int) thr_multi_lock(sql_lock->locks, sql_lock->lock_count, @@ -218,6 +220,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count) int lock_type,error; DBUG_ENTER("lock_external"); + DBUG_PRINT("info", ("count %d", count)); for (i=1 ; i <= count ; i++, tables++) { DBUG_ASSERT((*tables)->reginfo.lock_type >= TL_READ); @@ -460,6 +463,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, THR_LOCK_DATA **locks; TABLE **to; + DBUG_ENTER("get_lock_data"); + DBUG_PRINT("info", ("count %d", count)); *write_lock_used=0; for (i=tables=lock_count=0 ; i < count ; i++) { @@ -479,7 +484,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, { my_error(ER_WRONG_LOCK_OF_SYSTEM_TABLE, MYF(0), table_ptr[i]->s->db, table_ptr[i]->s->table_name); - return 0; + DBUG_RETURN(0); } } @@ -487,11 +492,13 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, my_malloc(sizeof(*sql_lock)+ sizeof(THR_LOCK_DATA*)*tables+sizeof(table_ptr)*lock_count, MYF(0)))) - return 0; + DBUG_RETURN(0); locks=sql_lock->locks=(THR_LOCK_DATA**) (sql_lock+1); to=sql_lock->table=(TABLE**) (locks+tables); sql_lock->table_count=lock_count; sql_lock->lock_count=tables; + DBUG_PRINT("info", ("sql_lock->table_count %d sql_lock->lock_count %d", + sql_lock->table_count, sql_lock->lock_count)); for (i=0 ; i < count ; i++) { @@ -507,7 +514,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, { my_error(ER_OPEN_AS_READONLY, MYF(0), table->alias); my_free((gptr) sql_lock,MYF(0)); - return 0; + DBUG_RETURN(0); } } THR_LOCK_DATA **org_locks = locks; @@ -517,7 +524,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, for ( ; org_locks != locks ; org_locks++) (*org_locks)->debug_print_param= (void *) table; } - return sql_lock; + DBUG_RETURN(sql_lock); } diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index e57753dd0bd..202c747cf8c 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -20,7 +20,7 @@ used by all handlers that support partitioning, which in the first version is the partitioning handler itself and the NDB handler. - The first version was written by Mikael Ronström. + The first version was written by Mikael Ronstrom. This version supports RANGE partitioning, LIST partitioning, HASH partitioning and composite partitioning (hereafter called subpartitioning) From 88776a8244534b47784d125fc5ea2a86955f0b70 Mon Sep 17 00:00:00 2001 From: "patg@krsna.patg.net" <> Date: Mon, 21 Nov 2005 15:21:04 -0800 Subject: [PATCH 2/2] BUG #14524 Post-review fixes to original changeset http://lists.mysql.com/internals/32422 --- BUILD/SETUP.sh | 2 +- mysql-test/r/partition.result | 4 +--- mysql-test/t/partition.test | 6 +++--- sql/ha_partition.cc | 5 +---- 4 files changed, 6 insertions(+), 11 deletions(-) diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index cd1a348dfbc..eece41d72e6 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -57,7 +57,7 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch c_warnings="$global_warnings -Wunused" cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor" base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-partition $SSL_LIBRARY" -base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine $SSL_LIBRARY" +base_max_no_ndb_configs="--with-innodb --with-berkeley-db --without-ndbcluster --with-archive-storage-engine --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine --with-csv-storage-engine --with-partition $SSL_LIBRARY" max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-csv-storage-engine --with-embedded-server --with-big-tables --with-partition $SSL_LIBRARY" max_configs="$base_max_configs --with-embedded-server" max_no_ndb_configs="$base_max_no_ndb_configs --with-embedded-server" diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 4ceb802a448..f0500c639a3 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -108,11 +108,9 @@ insert into t1 values (3); insert into t1 values (4); UNLOCK TABLES; drop table t1; -DROP TABLE IF EXISTS `t1`; -Warnings: -Note 1051 Unknown table 't1' CREATE TABLE `t1` ( `id` int(11) default NULL ) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ; SELECT * FROM t1; id +drop table t1; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index e56c31ad82c..8f20f7be536 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -165,10 +165,10 @@ drop table t1; # # BUG 14524 # ---disable-warnings -DROP TABLE IF EXISTS `t1`; ---enable-warnings CREATE TABLE `t1` ( `id` int(11) default NULL ) ENGINE=BLACKHOLE DEFAULT CHARSET=latin1 PARTITION BY HASH (id) ; SELECT * FROM t1; + +drop table t1; + diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index c42ce2ed3d5..14dab7f1248 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1103,10 +1103,7 @@ int ha_partition::start_stmt(THD *thd, thr_lock_type lock_type) uint ha_partition::lock_count() const { DBUG_ENTER("ha_partition::lock_count"); - if (m_no_locks == 0) - DBUG_RETURN(0); - - DBUG_RETURN(m_tot_parts); + DBUG_RETURN(m_no_locks); }