summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--storage/maria/ha_maria.cc41
-rw-r--r--storage/maria/ma_create.c3
-rw-r--r--storage/maria/ma_loghandler.c44
-rw-r--r--storage/maria/ma_loghandler.h10
-rw-r--r--storage/maria/ma_recovery.c39
-rw-r--r--storage/maria/trnman.c13
-rw-r--r--storage/maria/trnman.h1
-rw-r--r--storage/maria/trnman_public.h12
-rw-r--r--storage/myisam/mi_create.c3
10 files changed, 166 insertions, 4 deletions
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 175358140e1..1831e13dcf2 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -3493,6 +3493,9 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
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(THD *thd, HA_CREATE_INFO *create_info,
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);
}
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 64105c2afb0..7ba346824de 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2261,6 +2261,9 @@ int ha_maria::extra_opt(enum ha_extra_function operation, ulong cache_size)
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, int lock_type)
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, int lock_type)
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, int lock_type)
}
#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_lock_type lock_type)
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, register TABLE *table_arg,
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, register TABLE *table_arg,
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, register TABLE *table_arg,
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 __attribute__ ((unused)),
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
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 5552fae6028..f9ea1dab67e 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -652,7 +652,8 @@ int maria_create(const char *name, enum data_file_type datafile_type,
/* 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;
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index a0c8d0e63a3..27d7460f7fb 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -685,6 +685,10 @@ static LOG_DESC INIT_LOGREC_IMPORTED_TABLE=
{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();
diff --git a/storage/maria/ma_loghandler.h b/storage/maria/ma_loghandler.h
index 95d711d3eee..dba6283e303 100644
--- a/storage/maria/ma_loghandler.h
+++ b/storage/maria/ma_loghandler.h
@@ -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_recovery(struct st_maria_share *share,
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
{
diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c
index ac0ff1051f3..a63df9c1b79 100644
--- a/storage/maria/ma_recovery.c
+++ b/storage/maria/ma_recovery.c
@@ -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(const LOG_DESC *log_desc,
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 maria_apply_log_way apply)
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(TRANSLOG_ADDRESS addr)
}
}
+
#ifdef MARIA_EXTERNAL_LOCKING
#error Marias Checkpoint and Recovery are really not ready for it
#endif
diff --git a/storage/maria/trnman.c b/storage/maria/trnman.c
index 660a8917b1e..95fe1a0d3f4 100644
--- a/storage/maria/trnman.c
+++ b/storage/maria/trnman.c
@@ -88,6 +88,19 @@ void trnman_reset_locked_tables(TRN *trn, uint locked_tables)
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)
diff --git a/storage/maria/trnman.h b/storage/maria/trnman.h
index 97fef57e618..2ad4addeb84 100644
--- a/storage/maria/trnman.h
+++ b/storage/maria/trnman.h
@@ -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)
diff --git a/storage/maria/trnman_public.h b/storage/maria/trnman_public.h
index d29ada159ac..1871f93b590 100644
--- a/storage/maria/trnman_public.h
+++ b/storage/maria/trnman_public.h
@@ -70,5 +70,17 @@ my_bool trnman_exists_active_transactions(TrID min_id, TrID max_id,
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
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 560a537e87c..1ad58bee3e3 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -496,7 +496,8 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
/* 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;