List:Commits« Previous MessageNext Message »
From:Michael Widenius Date:August 12 2008 10:59am
Subject:bzr commit into mysql-6.0 branch (monty:2682)
View as plain text  
#At file:///home/my/mysql-6.0-maria/

 2682 Michael Widenius	2008-08-12 [merge]
      Merge with 5-1-Maria
      Fixed that test sute now works for all Maria tests
modified:
  mysql-test/r/maria2.result
  mysql-test/t/maria2.test
  mysql-test/valgrind.supp
  sql/mdl.cc
  sql/sql_base.cc
  sql/sql_table.cc
  storage/maria/ha_maria.cc
  storage/maria/ma_extra.c
  storage/maria/ma_recovery.c
  storage/maria/ma_state.c
  storage/maria/ma_state.h

per-file messages:
  mysql-test/r/maria2.result
    New test case
  mysql-test/t/maria2.test
    New test case
  mysql-test/valgrind.supp
    Removed duplicated code
    Fixed suppression to be more general to avoid warning on x32
  sql/mdl.cc
    Fixed crashing bug when mysqld didn't start
  sql/sql_base.cc
    Fixed old wrong merge; extra() should be called when we are the only one that is using the table
  sql/sql_table.cc
    Changed extra() call to rename to tell storage engine that we don't need to keep any versioning information about the table anymore
  storage/maria/ha_maria.cc
    Automatic merge
  storage/maria/ma_extra.c
    Automatic merge
    Ensure that info->state_start is reset as part of EXTRA_RENAME
  storage/maria/ma_recovery.c
    Automatic merge
  storage/maria/ma_state.c
    Automatic merge
  storage/maria/ma_state.h
    Automatic merge
=== modified file 'mysql-test/r/maria2.result'
--- a/mysql-test/r/maria2.result	2008-06-10 14:44:44 +0000
+++ b/mysql-test/r/maria2.result	2008-08-12 10:59:30 +0000
@@ -1,3 +1,4 @@
+drop table if exists t1,t2;
 CREATE TABLE t1 (
 line BLOB,
 kind ENUM('po', 'pp', 'rr', 'dr', 'rd', 'ts', 'cl') NOT NULL DEFAULT 'po',
@@ -16,3 +17,44 @@ check table t1 extended;
 Table	Op	Msg_type	Msg_text
 test.t1	check	status	OK
 drop table t1;
+create table t1 (i int) engine=maria;
+create table t2 (j int) engine=maria;
+lock table t1 write, t2 read;
+alter table t1 modify i int default 1;
+insert into t1 values (2);
+alter table t1 modify i bigint default 1;
+select count(*) from t1;
+count(*)
+1
+select * from t1;
+i
+2
+unlock tables;
+drop table t1,t2;
+create table t1(id int, s char(1), unique(s)) engine=maria;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1;
+select * from t1;
+id	s
+3	a
+replace into t1 select 1,"a";
+select * from t1;
+id	s
+1	a
+drop table t1;
+create table t1 (pk int primary key, apk int unique, data int) engine=maria;
+insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6);
+load data concurrent infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;
+pk	apk	data
+1	1	1
+3	4	NULL
+5	6	NULL
+load data infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;
+pk	apk	data
+1	1	1
+3	4	NULL
+5	6	NULL
+drop table t1;

=== modified file 'mysql-test/t/maria2.test'
--- a/mysql-test/t/maria2.test	2008-06-10 14:44:44 +0000
+++ b/mysql-test/t/maria2.test	2008-08-12 10:59:30 +0000
@@ -1,5 +1,10 @@
 --source include/have_maria.inc
 
+# Initialise
+--disable_warnings
+drop table if exists t1,t2;
+--enable_warnings
+
 # Test for BUG#36319
 # "Maria: table is not empty but DELETE and SELECT find no rows"
 
@@ -64,3 +69,43 @@ select count(*) from t1;
 select name from t1;
 check table t1 extended;
 drop table t1;
+
+#
+# Testing of ALTER TABLE under lock tables
+#
+
+create table t1 (i int) engine=maria;
+create table t2 (j int) engine=maria;
+lock table t1 write, t2 read;
+alter table t1 modify i int default 1;
+insert into t1 values (2);
+# This caused a core dump
+alter table t1 modify i bigint default 1;
+select count(*) from t1;
+select * from t1;
+unlock tables;
+drop table t1,t2;
+
+#
+# test INSERT ON DUPLICATE KEY UPDATE
+#
+
+create table t1(id int, s char(1), unique(s)) engine=maria;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 values(1,"a") on duplicate key update t1.id=t1.id+1;
+insert into t1 select 1,"a" on duplicate key update t1.id=t1.id+1;
+select * from t1;
+
+# test REPLACE SELECT
+replace into t1 select 1,"a";
+select * from t1;
+drop table t1;
+
+# test LOAD DATA INFILE REPLACE
+create table t1 (pk int primary key, apk int unique, data int) engine=maria;
+insert into t1 values (1, 1, 1), (4, 4, 4), (6, 6, 6);
+load data concurrent infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;
+load data infile '../std_data_ln/loaddata5.dat' replace into table t1 fields terminated by '' enclosed by '' ignore 1 lines (pk, apk);
+select * from t1 order by pk;
+drop table t1;

=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp	2008-06-05 17:16:32 +0000
+++ b/mysql-test/valgrind.supp	2008-08-12 10:59:30 +0000
@@ -27,7 +27,7 @@
    pthread allocate_tls memory loss
    Memcheck:Leak
    fun:calloc
-   obj:/lib64/ld*.so
+   obj:/lib*/ld*.so
    fun:_dl_allocate_tls
    fun:pthread_create*
 }
@@ -388,40 +388,58 @@
 }
 
 {
-   dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
+   dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit
    Memcheck:Leak
    fun:*alloc
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/libc-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/libc-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
    fun:__libc_dlopen_mode
    fun:pthread_cancel_init
    fun:_Unwind_ForcedUnwind
-
 }
 
 {
-   dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 64 bit
+   dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit
    Memcheck:Leak
    fun:*alloc
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/libc-*.so
-   obj:/lib64/ld-*.so
-   obj:/lib64/libc-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
    fun:__libc_dlopen_mode
    fun:pthread_cancel_init
    fun:_Unwind_ForcedUnwind
 }
 
+#
+# Reading wrong addresses on SuSe Linux 10.3 32 bit
+#
+
+{
+   Reading wrong data in libc_dlopen
+   Memcheck:Addr4
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
+   obj:/lib*/ld-*.so
+   obj:/lib*/libc-*.so
+   fun:__libc_dlopen_mode
+   fun:pthread_cancel_init
+}
 
 #
 # These seem to be libc threading stuff, not related to MySQL code (allocations

=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2008-06-20 13:11:20 +0000
+++ b/sql/mdl.cc	2008-08-12 10:59:30 +0000
@@ -19,6 +19,7 @@
 #include <hash.h>
 #include <mysqld_error.h>
 
+static bool mdl_initialized= 0;
 
 /**
    The lock context. Created internally for an acquired lock.
@@ -115,6 +116,7 @@ extern "C" uchar *mdl_locks_key(const uc
 
 void mdl_init()
 {
+  mdl_initialized= 1;
   pthread_mutex_init(&LOCK_mdl, NULL);
   pthread_cond_init(&COND_mdl, NULL);
   hash_init(&mdl_locks, &my_charset_bin, 16 /* FIXME */, 0, 0,
@@ -133,10 +135,14 @@ void mdl_init()
 
 void mdl_destroy()
 {
-  DBUG_ASSERT(!mdl_locks.records);
-  pthread_mutex_destroy(&LOCK_mdl);
-  pthread_cond_destroy(&COND_mdl);
-  hash_free(&mdl_locks);
+  if (mdl_initialized)
+  {
+    mdl_initialized= 0;
+    DBUG_ASSERT(!mdl_locks.records);
+    pthread_mutex_destroy(&LOCK_mdl);
+    pthread_cond_destroy(&COND_mdl);
+    hash_free(&mdl_locks);
+  }
 }
 
 

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2008-06-28 11:00:59 +0000
+++ b/sql/sql_base.cc	2008-08-12 10:59:30 +0000
@@ -2029,8 +2029,6 @@ bool wait_while_table_is_used(THD *thd, 
                        table->s->table_name.str, table->s,
                        table->db_stat, table->s->version));
 
-  (void) table->file->extra(function);
-
   old_lock_type= table->reginfo.lock_type;
   mysql_lock_abort(thd, table, TRUE);	/* end threads waiting on lock */
 
@@ -2045,6 +2043,8 @@ bool wait_while_table_is_used(THD *thd, 
   tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN,
                    table->s->db.str, table->s->table_name.str);
   pthread_mutex_unlock(&LOCK_open);
+  /* extra() call must come only after all instances above are closed */
+  (void) table->file->extra(function);
   DBUG_RETURN(FALSE);
 }
 

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2008-06-30 09:59:59 +0000
+++ b/sql/sql_table.cc	2008-08-12 10:59:30 +0000
@@ -5787,7 +5787,7 @@ mysql_fast_or_online_alter_table(THD *th
     Upgrade the shared metadata lock to exclusive and close all
     instances of the table in the TDC except those used in this thread.
   */
-  if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
+  if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
     DBUG_RETURN(1);
 
   alter_table_manage_keys(table, table->file->indexes_are_disabled(),
@@ -7011,7 +7011,6 @@ view_err:
   if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
     goto err_new_table_cleanup;
 
-
   close_all_tables_for_name(thd, table->s,
                             new_name != table_name || new_db != db);
 

=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc	2008-07-10 14:58:31 +0000
+++ b/storage/maria/ha_maria.cc	2008-08-12 10:59:30 +0000
@@ -1847,6 +1847,7 @@ bool ha_maria::is_crashed() const
 
 int ha_maria::update_row(const uchar * old_data, uchar * new_data)
 {
+  DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
   ha_statistic_increment(&SSV::ha_update_count);
   if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
     table->timestamp_field->set_time();
@@ -1856,6 +1857,7 @@ int ha_maria::update_row(const uchar * o
 
 int ha_maria::delete_row(const uchar * buf)
 {
+  DBUG_ASSERT(file->lock.type != TL_WRITE_CONCURRENT_INSERT);
   ha_statistic_increment(&SSV::ha_delete_count);
   return maria_delete(file, buf);
 }
@@ -2389,6 +2391,7 @@ THR_LOCK_DATA **ha_maria::store_lock(THD
               (lock_type == TL_IGNORE || file->lock.type == TL_UNLOCK));
   if (lock_type != TL_IGNORE && file->lock.type == TL_UNLOCK)
   {
+    const enum enum_sql_command sql_command= thd->lex->sql_command;
     /*
       We have to disable concurrent inserts for INSERT ... SELECT or
       INSERT/UPDATE/DELETE with sub queries if we are using statement based
@@ -2397,24 +2400,33 @@ THR_LOCK_DATA **ha_maria::store_lock(THD
     */
     if (lock_type <= TL_READ_HIGH_PRIORITY &&
         !thd->current_stmt_binlog_row_based &&
-        (thd->lex->sql_command != SQLCOM_SELECT &&
-         thd->lex->sql_command != SQLCOM_LOCK_TABLES) &&
+        (sql_command != SQLCOM_SELECT &&
+         sql_command != SQLCOM_LOCK_TABLES) &&
         (thd->options & OPTION_BIN_LOG) &&
         mysql_bin_log.is_open())
       lock_type= TL_READ_NO_INSERT;
-    else if (lock_type == TL_WRITE_CONCURRENT_INSERT &&
-             (file->state->records == 0))
+    else if (lock_type == TL_WRITE_CONCURRENT_INSERT)
     {
+      const enum enum_duplicates duplicates= thd->lex->duplicates;
       /*
-        Bulk insert may use repair, which will cause problems if other
+        Explanation for the 3 conditions below, in order:
+
+        - Bulk insert may use repair, which will cause problems if other
         threads try to read/insert to the table: disable versioning.
         Note that our read of file->state->records is incorrect, as such
         variable may have changed when we come to start_bulk_insert() (worse
         case: we see != 0 so allow versioning, start_bulk_insert() sees 0 and
         uses repair). This is prevented because start_bulk_insert() will not
         try repair if we enabled versioning.
+        - INSERT SELECT ON DUPLICATE KEY UPDATE comes here with
+        TL_WRITE_CONCURRENT_INSERT but shouldn't because it can do
+        update/delete of a row and versioning doesn't support that
+        - same for LOAD DATA CONCURRENT REPLACE.
       */
-      lock_type= TL_WRITE;
+      if ((file->state->records == 0) ||
+          (sql_command == SQLCOM_INSERT_SELECT && duplicates == DUP_UPDATE) ||
+          (sql_command == SQLCOM_LOAD && duplicates == DUP_REPLACE))
+        lock_type= TL_WRITE;
     }
     file->lock.type= lock_type;
   }

=== modified file 'storage/maria/ma_extra.c'
--- a/storage/maria/ma_extra.c	2008-06-26 05:18:28 +0000
+++ b/storage/maria/ma_extra.c	2008-08-12 10:59:30 +0000
@@ -322,6 +322,13 @@ int maria_extra(MARIA_HA *info, enum ha_
     if (share->kfile.file >= 0)
       _ma_decrement_open_count(info);
     pthread_mutex_lock(&share->intern_lock);
+    if (info->trn)
+    {
+      _ma_remove_table_from_trnman(share, info->trn);
+      /* Ensure we don't point to the deleted data in trn */
+      info->state= info->state_start= &share->state.state;
+    }
+
     type= do_flush ? FLUSH_RELEASE : FLUSH_IGNORE_CHANGED;
     if (_ma_flush_table_files(info, MARIA_FLUSH_DATA | MARIA_FLUSH_INDEX,
                               type, type))

=== modified file 'storage/maria/ma_recovery.c'
--- a/storage/maria/ma_recovery.c	2008-07-09 21:25:29 +0000
+++ b/storage/maria/ma_recovery.c	2008-08-12 10:59:30 +0000
@@ -3234,6 +3234,16 @@ void _ma_tmp_disable_logging_for_table(M
 
   /* if we disabled before writing the record, record wouldn't reach log */
   share->now_transactional= FALSE;
+
+  /*
+    Reset state pointers. This is needed as in ALTER table we may do
+    commit fllowed by _ma_renable_logging_for_table and then
+    info->state may point to a state that was deleted by
+    _ma_trnman_end_trans_hook()
+   */
+  share->state.common= *info->state;
+  info->state= &share->state.common;
+
   /*
     Some code in ma_blockrec.c assumes a trn even if !now_transactional but in
     this case it only reads trn->rec_lsn, which has to be LSN_IMPOSSIBLE and
@@ -3275,6 +3285,7 @@ my_bool _ma_reenable_logging_for_table(M
       in not transactional mode
     */
     _ma_copy_nontrans_state_information(info);
+    _ma_reset_history(info->s);
 
     if (flush_pages)
     {

=== modified file 'storage/maria/ma_state.c'
--- a/storage/maria/ma_state.c	2008-07-05 11:03:21 +0000
+++ b/storage/maria/ma_state.c	2008-07-12 14:14:28 +0000
@@ -371,7 +371,7 @@ my_bool _ma_trnman_end_trans_hook(TRN *t
       MARIA_STATE_HISTORY *history;
 
       pthread_mutex_lock(&share->intern_lock);
-      if (active_transactions &&
+      if (active_transactions && share->now_transactional &&
           trnman_exists_active_transactions(share->state_history->trid,
                                             trn->commit_trid, 1))
       {
@@ -415,6 +415,35 @@ my_bool _ma_trnman_end_trans_hook(TRN *t
 }
 
 
+/**
+   Remove table from trnman_list
+
+   @notes
+     This is used when we unlock a table from a group of locked tables
+     just before doing a rename or drop table.
+*/
+
+void _ma_remove_table_from_trnman(MARIA_SHARE *share, TRN *trn)
+{
+  MARIA_USED_TABLES *tables, **prev;
+  
+  for (prev= (MARIA_USED_TABLES**) &trn->used_tables, tables= *prev;
+       tables;
+       tables= *prev)
+  {
+    if (tables->share == share)
+    {
+      *prev= tables->next;
+      my_free(tables, MYF(0));
+    }
+    else
+      prev= &tables->next;
+  }
+}
+
+
+
+
 /****************************************************************************
   The following functions are called by thr_lock() in threaded applications
   for transactional tables.
@@ -509,6 +538,23 @@ void _ma_copy_nontrans_state_information
 }
 
 
+void _ma_reset_history(MARIA_SHARE *share)
+{
+  MARIA_STATE_HISTORY *history, *next;
+
+  share->state_history->trid= 0;          /* Visibly by all */
+  share->state_history->state= share->state.state;
+  history= share->state_history->next;
+  share->state_history->next= 0;
+
+  for (; history; history= next)
+  {
+    next= history->next;
+    my_free(history, MYF(0));
+  }
+}
+
+
 /****************************************************************************
   Virtual functions to check if row is visible
 ****************************************************************************/

=== modified file 'storage/maria/ma_state.h'
--- a/storage/maria/ma_state.h	2008-07-05 11:03:21 +0000
+++ b/storage/maria/ma_state.h	2008-07-12 14:14:28 +0000
@@ -77,3 +77,5 @@ my_bool _ma_row_visible_always(MARIA_HA 
 my_bool _ma_row_visible_non_transactional_table(MARIA_HA *info);
 my_bool _ma_row_visible_transactional_table(MARIA_HA *info);
 void _ma_remove_not_visible_states_with_lock(struct st_maria_share *share);
+void _ma_remove_table_from_trnman(struct st_maria_share *share, TRN *trn);
+void _ma_reset_history(struct st_maria_share *share);

Thread
bzr commit into mysql-6.0 branch (monty:2682) Michael Widenius12 Aug