List:Maria Storage Engine« Previous MessageNext Message »
From:Michael Widenius Date:January 15 2009 10:26pm
Subject:bzr commit into MySQL/Maria:mysql-maria branch (monty:2720)
View as plain text  
#At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-maria/ based on revid:guilhem@stripped

 2720 Michael Widenius	2009-01-16
      Log queries to maria_log if compiled with EXTRA_DEBUG
      Added DBUG_ASSERT() to unlikely error senario
      Don't use errno == 0 in maria_create() / myisam_create()
modified:
  sql/sql_insert.cc
  storage/maria/ha_maria.cc
  storage/maria/ma_create.c
  storage/maria/ma_loghandler.c
  storage/maria/ma_loghandler.h
  storage/maria/ma_recovery.c
  storage/maria/trnman.c
  storage/maria/trnman.h
  storage/maria/trnman_public.h
  storage/myisam/mi_create.c

per-file messages:
  sql/sql_insert.cc
    Added DBUG_ASSERT() for case that should never happen in real life
    Added my_error() to avoid assert if mysql_lock() or postlock() doesn't call my_error()
  storage/maria/ha_maria.cc
    Log queries to maria_log if compiled with EXTRA_DEBUG
  storage/maria/ma_create.c
    Don't use errno == 0
  storage/maria/ma_loghandler.c
    Added logging of debug info to maria_log
  storage/maria/ma_loghandler.h
    Added logging of debug info to maria_log
  storage/maria/ma_recovery.c
    Added printing of debug info from maria_log
  storage/maria/trnman.c
    Added functions to read/store state in TRN
  storage/maria/trnman.h
    Added functions to read/store state in TRN
  storage/maria/trnman_public.h
    Added state in TRN to remmeber if we have already logged the query
  storage/myisam/mi_create.c
    Don't use errno == 0
=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-01-09 04:11:37 +0000
+++ b/sql/sql_insert.cc	2009-01-15 22:25:53 +0000
@@ -3493,6 +3493,9 @@ static TABLE *create_table_from_items(TH
                                     MYSQL_LOCK_IGNORE_FLUSH, &not_used)) ||
         hooks->postlock(&table, 1))
   {
+    DBUG_ASSERT(0);                             // This should never happen
+    /* purecov: begin tested */
+    my_error(ER_CANT_LOCK, MYF(0), my_errno);
     if (*lock)
     {
       mysql_unlock_tables(thd, *lock);
@@ -3502,6 +3505,7 @@ static TABLE *create_table_from_items(TH
     if (!create_info->table_existed)
       drop_open_table(thd, table, create_table->db, create_table->table_name);
     DBUG_RETURN(0);
+    /* purecov: end */
   }
   DBUG_RETURN(table);
 }

=== modified file 'storage/maria/ha_maria.cc'
--- a/storage/maria/ha_maria.cc	2008-12-22 00:17:37 +0000
+++ b/storage/maria/ha_maria.cc	2009-01-15 22:25:53 +0000
@@ -2261,6 +2261,9 @@ int ha_maria::extra_opt(enum ha_extra_fu
 
 int ha_maria::delete_all_rows()
 {
+  THD *thd= current_thd;
+  (void) translog_log_debug_info(file->trn, LOGREC_DEBUG_INFO_QUERY,
+                                 (uchar*) thd->query, thd->query_length);
   if (file->s->now_transactional &&
       ((table->in_use->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) ||
        table->in_use->locked_tables))
@@ -2277,6 +2280,9 @@ int ha_maria::delete_all_rows()
 
 int ha_maria::delete_table(const char *name)
 {
+  THD *thd= current_thd;
+  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
+                                 (uchar*) thd->query, thd->query_length);
   return maria_delete_table(name);
 }
 
@@ -2350,6 +2356,16 @@ int ha_maria::external_lock(THD *thd, in
         DBUG_PRINT("info", ("Disabling logging for table"));
         _ma_tmp_disable_logging_for_table(file, TRUE);
       }
+#ifdef EXTRA_DEBUG
+      if (lock_type == F_WRLCK &&
+          ! (trnman_get_state(trn) & TRN_STATE_INFO_LOGGED))
+      {
+        trnman_set_state(trn, trnman_get_state(trn) | TRN_STATE_INFO_LOGGED |
+                         TRN_STATE_TABLES_CAN_CHANGE);
+        (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
+                                       (uchar*) thd->query, thd->query_length);
+      }
+#endif
     }
     else
     {
@@ -2374,9 +2390,10 @@ int ha_maria::external_lock(THD *thd, in
         external lock of the table
       */
       file->state= &file->s->state.state;
-      if (trn && trnman_has_locked_tables(trn))
+      if (trn)
       {
-        if (!trnman_decrement_locked_tables(trn))
+        if (trnman_has_locked_tables(trn) &&
+            !trnman_decrement_locked_tables(trn))
         {
           /*
             OK should not have been sent to client yet (ACID).
@@ -2399,6 +2416,7 @@ int ha_maria::external_lock(THD *thd, in
           }
 #endif
         }
+        trnman_set_state(trn, trnman_get_state(trn) & ~ TRN_STATE_INFO_LOGGED);
       }
     }
   } /* if transactional table */
@@ -2433,6 +2451,16 @@ int ha_maria::start_stmt(THD *thd, thr_l
       call to start_stmt().
     */
     trnman_new_statement(trn);
+
+#ifdef EXTRA_DEBUG
+    if (!(trnman_get_state(trn) & TRN_STATE_INFO_LOGGED) &&
+        trnman_get_state(trn) & TRN_STATE_TABLES_CAN_CHANGE)
+    {
+      trnman_set_state(trn, trnman_get_state(trn) | TRN_STATE_INFO_LOGGED);
+      (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY,
+                                     (uchar*) thd->query, thd->query_length);
+    }
+#endif
   }
   return 0;
 }
@@ -2645,6 +2673,7 @@ int ha_maria::create(const char *name, r
   TABLE_SHARE *share= table_arg->s;
   uint options= share->db_options_in_use;
   enum data_file_type row_type;
+  THD *thd= current_thd;
   DBUG_ENTER("ha_maria::create");
 
   for (i= 0; i < share->keys; i++)
@@ -2709,6 +2738,9 @@ int ha_maria::create(const char *name, r
        ha_create_info->page_checksum ==  HA_CHOICE_YES)
     create_flags|= HA_CREATE_PAGE_CHECKSUM;
 
+  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
+                                 (uchar*) thd->query, thd->query_length);
+
   /* TODO: Check that the following fn_format is really needed */
   error=
     maria_create(fn_format(buff, name, "", "",
@@ -2725,6 +2757,9 @@ int ha_maria::create(const char *name, r
 
 int ha_maria::rename_table(const char *from, const char *to)
 {
+  THD *thd= current_thd;
+  (void) translog_log_debug_info(0, LOGREC_DEBUG_INFO_QUERY,
+                                 (uchar*) thd->query, thd->query_length);
   return maria_rename(from, to);
 }
 
@@ -2869,6 +2904,8 @@ static int maria_commit(handlerton *hton
   TRN *trn= THD_TRN;
   DBUG_ENTER("maria_commit");
   trnman_reset_locked_tables(trn, 0);
+  trnman_set_state(trn, trnman_get_state(trn) & ~TRN_STATE_INFO_LOGGED);
+
   /* statement or transaction ? */
   if ((thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !all)
     DBUG_RETURN(0); // end of statement

=== modified file 'storage/maria/ma_create.c'
--- a/storage/maria/ma_create.c	2008-10-15 20:00:35 +0000
+++ b/storage/maria/ma_create.c	2009-01-15 22:25:53 +0000
@@ -652,7 +652,8 @@ int maria_create(const char *name, enum 
   /* There are only 16 bits for the total header length. */
   if (info_length > 65535)
   {
-    my_printf_error(0, "Maria table '%s' has too many columns and/or "
+    my_printf_error(HA_WRONG_CREATE_OPTION,
+                    "Maria table '%s' has too many columns and/or "
                     "indexes and/or unique constraints.",
                     MYF(0), name + dirname_length(name));
     my_errno= HA_WRONG_CREATE_OPTION;

=== modified file 'storage/maria/ma_loghandler.c'
--- a/storage/maria/ma_loghandler.c	2008-12-08 10:06:08 +0000
+++ b/storage/maria/ma_loghandler.c	2009-01-15 22:25:53 +0000
@@ -685,6 +685,10 @@ static LOG_DESC INIT_LOGREC_IMPORTED_TAB
 {LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
  "imported_table", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
 
+static LOG_DESC INIT_LOGREC_DEBUG_INFO=
+{LOGRECTYPE_VARIABLE_LENGTH, 0, 0, NULL, NULL, NULL, 0,
+ "info", LOGREC_IS_GROUP_ITSELF, NULL, NULL};
+
 const myf log_write_flags= MY_WME | MY_NABP | MY_WAIT_IF_FULL;
 
 void translog_table_init()
@@ -774,6 +778,9 @@ void translog_table_init()
     INIT_LOGREC_REDO_BITMAP_NEW_PAGE;
   log_record_type_descriptor[LOGREC_IMPORTED_TABLE]=
     INIT_LOGREC_IMPORTED_TABLE;
+  log_record_type_descriptor[LOGREC_DEBUG_INFO]=
+    INIT_LOGREC_DEBUG_INFO;
+
   for (i= LOGREC_FIRST_FREE; i < LOGREC_NUMBER_OF_TYPES; i++)
     log_record_type_descriptor[i].rclass= LOGRECTYPE_NOT_ALLOWED;
 #ifndef DBUG_OFF
@@ -8299,6 +8306,43 @@ void translog_set_file_size(uint32 size)
   DBUG_VOID_RETURN;
 }
 
+
+/**
+   Write debug information to log if we EXTRA_DEBUG is enabled
+*/
+
+my_bool translog_log_debug_info(TRN *trn, enum translog_debug_info_type type,
+                                uchar *info, size_t length)
+{
+#ifdef EXTRA_DEBUG
+  LEX_CUSTRING log_array[TRANSLOG_INTERNAL_PARTS + 2];
+  uchar debug_type;
+  LSN lsn;
+
+  if (!trn)
+  {
+    /*
+      We can't log the current transaction because we don't have
+      an active transaction. Use a temporary transaction object instead
+    */
+    trn= &dummy_transaction_object;
+  }
+  debug_type= (uchar) type;
+  log_array[TRANSLOG_INTERNAL_PARTS + 0].str= &debug_type;
+  log_array[TRANSLOG_INTERNAL_PARTS + 0].length= 1;
+  log_array[TRANSLOG_INTERNAL_PARTS + 1].str= info;
+  log_array[TRANSLOG_INTERNAL_PARTS + 1].length= length;
+  return translog_write_record(&lsn, LOGREC_DEBUG_INFO,
+                               trn, NULL,
+                               (translog_size_t) (1+ length),
+                               sizeof(log_array)/sizeof(log_array[0]),
+                               log_array, NULL, NULL);
+#else
+  return 0;
+#endif
+}
+
+
 #ifdef MARIA_DUMP_LOG
 #include <my_getopt.h>
 extern void translog_example_table_init();

=== modified file 'storage/maria/ma_loghandler.h'
--- a/storage/maria/ma_loghandler.h	2008-07-09 09:02:27 +0000
+++ b/storage/maria/ma_loghandler.h	2009-01-15 22:25:53 +0000
@@ -144,6 +144,7 @@ enum translog_record_type
   LOGREC_UNDO_BULK_INSERT,
   LOGREC_REDO_BITMAP_NEW_PAGE,
   LOGREC_IMPORTED_TABLE,
+  LOGREC_DEBUG_INFO,
   LOGREC_FIRST_FREE,
   LOGREC_RESERVED_FUTURE_EXTENSION= 63
 };
@@ -167,6 +168,12 @@ enum en_key_op
   KEY_OP_COMPACT_PAGE   /* Compact key page */
 };
 
+
+enum translog_debug_info_type
+{
+  LOGREC_DEBUG_INFO_QUERY
+};
+
 /* Size of log file; One log file is restricted to 4G */
 typedef uint32 translog_size_t;
 
@@ -323,6 +330,9 @@ translog_assign_id_to_share_from_recover
 extern my_bool translog_walk_filenames(const char *directory,
                                        my_bool (*callback)(const char *,
                                                            const char *));
+extern my_bool translog_log_debug_info(TRN *trn,
+                                       enum translog_debug_info_type type,
+                                       uchar *info, size_t length);
 
 enum enum_translog_status
 {

=== modified file 'storage/maria/ma_recovery.c'
--- a/storage/maria/ma_recovery.c	2009-01-15 15:14:47 +0000
+++ b/storage/maria/ma_recovery.c	2009-01-15 22:25:53 +0000
@@ -98,6 +98,7 @@ prototype_redo_exec_hook(UNDO_KEY_DELETE
 prototype_redo_exec_hook(UNDO_KEY_DELETE_WITH_ROOT);
 prototype_redo_exec_hook(COMMIT);
 prototype_redo_exec_hook(CLR_END);
+prototype_redo_exec_hook(DEBUG_INFO);
 prototype_undo_exec_hook(UNDO_ROW_INSERT);
 prototype_undo_exec_hook(UNDO_ROW_DELETE);
 prototype_undo_exec_hook(UNDO_ROW_UPDATE);
@@ -488,6 +489,11 @@ static void display_record_position(cons
          number ? "" : "   ", number, LSN_IN_PARTS(rec->lsn),
          rec->short_trid, log_desc->name, rec->type,
          (ulong)rec->record_length);
+  if (rec->type == LOGREC_DEBUG_INFO)
+  {
+    /* Print some extra information */
+    (*log_desc->record_execute_in_redo_phase)(rec);
+  }
 }
 
 
@@ -2004,6 +2010,37 @@ prototype_redo_exec_hook(CLR_END)
 
 
 /**
+   Hock to print debug information (like MySQL query)
+*/
+
+prototype_redo_exec_hook(DEBUG_INFO)
+{
+  uchar *data;
+  enum translog_debug_info_type debug_info;
+
+  enlarge_buffer(rec);
+  if (log_record_buffer.str == NULL ||
+      translog_read_record(rec->lsn, 0, rec->record_length,
+                           log_record_buffer.str, NULL) !=
+      rec->record_length)
+  {
+    eprint(tracef, "Failed to read record debug record");
+    return 1;
+  }
+  debug_info= (enum translog_debug_info_type) log_record_buffer.str[0];
+  data= log_record_buffer.str + 1;
+  switch (debug_info) {
+  case LOGREC_DEBUG_INFO_QUERY:
+    tprint(tracef, "Query: %s\n", (char*) data);
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+  return 0;
+}
+
+
+/**
   In some cases we have to skip execution of an UNDO record during the UNDO
   phase.
 */
@@ -2361,6 +2398,7 @@ static int run_redo_phase(LSN lsn, enum 
   install_redo_exec_hook(UNDO_BULK_INSERT);
   install_undo_exec_hook(UNDO_BULK_INSERT);
   install_redo_exec_hook(IMPORTED_TABLE);
+  install_redo_exec_hook(DEBUG_INFO);
 
   current_group_end_lsn= LSN_IMPOSSIBLE;
 #ifndef DBUG_OFF
@@ -3403,6 +3441,7 @@ static void print_redo_phase_progress(TR
   }
 }
 
+
 #ifdef MARIA_EXTERNAL_LOCKING
 #error Marias Checkpoint and Recovery are really not ready for it
 #endif

=== modified file 'storage/maria/trnman.c'
--- a/storage/maria/trnman.c	2008-12-22 00:17:37 +0000
+++ b/storage/maria/trnman.c	2009-01-15 22:25:53 +0000
@@ -88,6 +88,19 @@ void trnman_reset_locked_tables(TRN *trn
   trn->locked_tables= locked_tables;
 }
 
+#ifdef EXTRA_DEBUG
+uint16 trnman_get_state(TRN *trn)
+{
+  return trn->state;
+}
+
+void trnman_set_state(TRN *trn, uint16 state)
+{
+  trn->state= state;
+}
+#endif
+
+
 static void wt_thd_release_self(TRN *trn)
 {
   if (trn->wt)

=== modified file 'storage/maria/trnman.h'
--- a/storage/maria/trnman.h	2008-08-07 20:57:25 +0000
+++ b/storage/maria/trnman.h	2009-01-15 22:25:53 +0000
@@ -53,6 +53,7 @@ struct st_ma_transaction
   LSN_WITH_FLAGS       first_undo_lsn;
   uint                 locked_tables;
   uint16               short_id;
+  uint16               state;                   /* Internal flags */
 };
 
 #define TRANSACTION_LOGGED_LONG_ID ULL(0x8000000000000000)

=== modified file 'storage/maria/trnman_public.h'
--- a/storage/maria/trnman_public.h	2008-12-08 20:09:59 +0000
+++ b/storage/maria/trnman_public.h	2009-01-15 22:25:53 +0000
@@ -70,5 +70,17 @@ my_bool trnman_exists_active_transaction
 void trnman_lock();
 void trnman_unlock();
 my_bool trman_is_inited();
+#ifdef EXTRA_DEBUG
+uint16 trnman_get_state(TRN *);
+void trnman_set_state(TRN *, uint16 state_bit);
+#else
+#define trnman_get_state(A) 0
+uint16 trnman_set_state(A, B) do { } while (0)
+#endif
+
+/* Bits for 'state' */
+#define TRN_STATE_INFO_LOGGED       1  /* Query is logged */
+#define TRN_STATE_TABLES_CAN_CHANGE 2  /* Things can change during trans. */
+
 C_MODE_END
 #endif

=== modified file 'storage/myisam/mi_create.c'
--- a/storage/myisam/mi_create.c	2008-10-10 15:28:41 +0000
+++ b/storage/myisam/mi_create.c	2009-01-15 22:25:53 +0000
@@ -496,7 +496,8 @@ int mi_create(const char *name,uint keys
   /* There are only 16 bits for the total header length. */
   if (info_length > 65535)
   {
-    my_printf_error(0, "MyISAM table '%s' has too many columns and/or "
+    my_printf_error(HA_WRONG_CREATE_OPTION,
+                    "MyISAM table '%s' has too many columns and/or "
                     "indexes and/or unique constraints.",
                     MYF(0), name + dirname_length(name));
     my_errno= HA_WRONG_CREATE_OPTION;

Thread
bzr commit into MySQL/Maria:mysql-maria branch (monty:2720) Michael Widenius15 Jan