mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
row0ins.c, dict0dict.c, dict0dict.h, srv0srv.c:
Let SHOW INNODB STATUS print detailed info of the latest unique key violation, note that REPLACE and INSERT IGNORE mask the error from the user
This commit is contained in:
@ -185,10 +185,12 @@ dict_foreign_free(
|
||||
/*==============*/
|
||||
dict_foreign_t* foreign); /* in, own: foreign key struct */
|
||||
|
||||
/* Buffer for storing detailed information about the latest foreig key
|
||||
error */
|
||||
/* Buffers for storing detailed information about the latest foreign key
|
||||
and unique key errors */
|
||||
char* dict_foreign_err_buf = NULL;
|
||||
mutex_t dict_foreign_err_mutex; /* mutex protecting the buffer */
|
||||
char* dict_unique_err_buf = NULL;
|
||||
mutex_t dict_foreign_err_mutex; /* mutex protecting the foreign
|
||||
and unique error buffers */
|
||||
|
||||
|
||||
/************************************************************************
|
||||
@ -582,6 +584,8 @@ dict_init(void)
|
||||
|
||||
dict_foreign_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN);
|
||||
dict_foreign_err_buf[0] = '\0';
|
||||
dict_unique_err_buf = mem_alloc(DICT_FOREIGN_ERR_BUF_LEN);
|
||||
dict_unique_err_buf[0] = '\0';
|
||||
mutex_create(&dict_foreign_err_mutex);
|
||||
mutex_set_level(&dict_foreign_err_mutex, SYNC_ANY_LATCH);
|
||||
}
|
||||
|
@ -839,10 +839,11 @@ dict_mutex_exit_for_mysql(void);
|
||||
/* The following len must be at least 10000 bytes! */
|
||||
#define DICT_FOREIGN_ERR_BUF_LEN 10000
|
||||
|
||||
/* Buffer for storing detailed information about the latest foreig key
|
||||
error */
|
||||
/* Buffers for storing detailed information about the latest foreign key
|
||||
and unique key errors */
|
||||
extern char* dict_foreign_err_buf;
|
||||
extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffer */
|
||||
extern char* dict_unique_err_buf;
|
||||
extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */
|
||||
|
||||
extern dict_sys_t* dict_sys; /* the dictionary system */
|
||||
extern rw_lock_t dict_operation_lock;
|
||||
|
@ -1263,6 +1263,48 @@ row_ins_check_foreign_constraints(
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Reports a UNIQUE key error to dict_unique_err_buf so that SHOW INNODB
|
||||
STATUS can print it. */
|
||||
static
|
||||
void
|
||||
row_ins_unique_report_err(
|
||||
/*======================*/
|
||||
que_thr_t* thr, /* in: query thread */
|
||||
rec_t* rec, /* in: a record in the index */
|
||||
dtuple_t* entry, /* in: index entry to insert in the index */
|
||||
dict_index_t* index) /* in: index */
|
||||
{
|
||||
char* buf = dict_unique_err_buf;
|
||||
|
||||
/* The foreign err mutex protects also dict_unique_err_buf */
|
||||
|
||||
mutex_enter(&dict_foreign_err_mutex);
|
||||
|
||||
ut_sprintf_timestamp(buf);
|
||||
sprintf(buf + strlen(buf), " Transaction:\n");
|
||||
trx_print(buf + strlen(buf), thr_get_trx(thr));
|
||||
|
||||
sprintf(buf + strlen(buf),
|
||||
"Unique key constraint fails for table %.500s.\n", index->table_name);
|
||||
sprintf(buf + strlen(buf),
|
||||
"Trying to add in index %.500s (%lu fields unique) tuple:\n", index->name,
|
||||
dict_index_get_n_unique(index));
|
||||
|
||||
dtuple_sprintf(buf + strlen(buf), 1000, entry);
|
||||
|
||||
sprintf(buf + strlen(buf),
|
||||
"\nBut there is already a record:\n");
|
||||
|
||||
rec_sprintf(buf + strlen(buf), 1000, rec);
|
||||
|
||||
sprintf(buf + strlen(buf), "\n");
|
||||
|
||||
ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
|
||||
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Checks if a unique key violation to rec would occur at the index entry
|
||||
insert. */
|
||||
@ -1393,10 +1435,8 @@ row_ins_scan_sec_index_for_duplicate(
|
||||
|
||||
if (cmp == 0) {
|
||||
if (row_ins_dupl_error_with_rec(rec, entry, index)) {
|
||||
/* printf("Duplicate key in index %s\n",
|
||||
index->name);
|
||||
dtuple_print(entry); */
|
||||
|
||||
row_ins_unique_report_err(thr, rec, entry,
|
||||
index);
|
||||
err = DB_DUPLICATE_KEY;
|
||||
|
||||
thr_get_trx(thr)->error_info = index;
|
||||
@ -1491,7 +1531,8 @@ row_ins_duplicate_error_in_clust(
|
||||
if (row_ins_dupl_error_with_rec(rec, entry,
|
||||
cursor->index)) {
|
||||
trx->error_info = cursor->index;
|
||||
|
||||
row_ins_unique_report_err(thr, rec, entry,
|
||||
cursor->index);
|
||||
return(DB_DUPLICATE_KEY);
|
||||
}
|
||||
}
|
||||
@ -1515,6 +1556,8 @@ row_ins_duplicate_error_in_clust(
|
||||
cursor->index)) {
|
||||
trx->error_info = cursor->index;
|
||||
|
||||
row_ins_unique_report_err(thr, rec, entry,
|
||||
cursor->index);
|
||||
return(DB_DUPLICATE_KEY);
|
||||
}
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ in the buffer pool to all database pages in the buffer pool smaller than
|
||||
the following number. But it is not guaranteed that the value stays below
|
||||
that during a time of heavy update/insert activity. */
|
||||
|
||||
ulint srv_max_buf_pool_modified_pct = 100;
|
||||
ulint srv_max_buf_pool_modified_pct = 90;
|
||||
|
||||
/* If the following is != 0 we do not allow inserts etc. This protects
|
||||
the user from forgetting the innodb_force_recovery keyword to my.cnf */
|
||||
@ -2366,6 +2366,19 @@ srv_sprintf_innodb_monitor(
|
||||
|
||||
ut_a(buf < buf_end + 1500);
|
||||
|
||||
if (*dict_unique_err_buf != '\0') {
|
||||
buf += sprintf(buf,
|
||||
"---------------------------------------------------------------\n"
|
||||
"LATEST UNIQUE KEY ERROR (is masked in REPLACE or INSERT IGNORE)\n"
|
||||
"---------------------------------------------------------------\n");
|
||||
|
||||
if (buf_end - buf > 6000) {
|
||||
buf+= sprintf(buf, "%.4000s", dict_unique_err_buf);
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(buf < buf_end + 1500);
|
||||
|
||||
lock_print_info(buf, buf_end);
|
||||
buf = buf + strlen(buf);
|
||||
|
||||
|
Reference in New Issue
Block a user