summaryrefslogtreecommitdiff
path: root/sql/ha_innodb.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r--sql/ha_innodb.cc103
1 files changed, 71 insertions, 32 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 4c4c32691e5..601536ab27e 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -325,6 +325,35 @@ convert_error_code_to_mysql(
}
/*****************************************************************
+If you want to print a thd that is not associated with the current thread,
+you must call this function before reserving the InnoDB kernel_mutex, to
+protect MySQL from setting thd->query NULL. If you print a thd of the current
+thread, we know that MySQL cannot modify thd->query, and it is not necessary
+to call this. Call innobase_mysql_end_print_arbitrary_thd() after you release
+the kernel_mutex.
+NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
+function! */
+extern "C"
+void
+innobase_mysql_prepare_print_arbitrary_thd(void)
+/*============================================*/
+{
+ VOID(pthread_mutex_lock(&LOCK_thread_count));
+}
+
+/*****************************************************************
+Relases the mutex reserved by innobase_mysql_prepare_print_arbitrary_thd().
+NOTE that /mysql/innobase/lock/lock0lock.c must contain the prototype for this
+function! */
+extern "C"
+void
+innobase_mysql_end_print_arbitrary_thd(void)
+/*========================================*/
+{
+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
+}
+
+/*****************************************************************
Prints info of a THD object (== user session thread) to the
standard output. NOTE that /mysql/innobase/trx/trx0trx.c must contain
the prototype for this function! */
@@ -335,9 +364,11 @@ innobase_mysql_print_thd(
FILE* f, /* in: output stream */
void* input_thd)/* in: pointer to a MySQL THD object */
{
- THD* thd;
+ const THD* thd;
+ const char* s;
+ char buf[301];
- thd = (THD*) input_thd;
+ thd = (const THD*) input_thd;
fprintf(f, "MySQL thread id %lu, query id %lu",
thd->thread_id, thd->query_id);
@@ -356,14 +387,31 @@ innobase_mysql_print_thd(
fputs(thd->user, f);
}
- if (thd->proc_info) {
+ if ((s = thd->proc_info)) {
putc(' ', f);
- fputs(thd->proc_info, f);
+ fputs(s, f);
}
- if (thd->query) {
- putc(' ', f);
- fputs(thd->query, f);
+ if ((s = thd->query)) {
+ /* determine the length of the query string */
+ uint32 i, len;
+
+ len = thd->query_length;
+
+ if (len > 300) {
+ len = 300; /* ADDITIONAL SAFETY: print at most
+ 300 chars to reduce the probability of
+ a seg fault if there is a race in
+ thd->query_length in MySQL; after
+ May 14, 2004 probably no race any more,
+ but better be safe */
+ }
+
+ /* Use strmake to reduce the timeframe
+ for a race, compared to fwrite() */
+ i= (uint) (strmake(buf, s, len) - buf);
+ putc('\n', f);
+ fwrite(buf, 1, i, f);
}
putc('\n', f);
@@ -3928,18 +3976,11 @@ ha_innobase::records_in_range(
/*==========================*/
/* out: estimated number of
rows */
- int keynr, /* in: index number */
- const mysql_byte* start_key, /* in: start key value of the
- range, may also be empty */
- uint start_key_len, /* in: start key val len, may
- also be 0 */
- enum ha_rkey_function start_search_flag,/* in: start search condition
- e.g., 'greater than' */
- const mysql_byte* end_key, /* in: range end key val, may
- also be empty */
- uint end_key_len, /* in: range end key val len,
- may also be 0 */
- enum ha_rkey_function end_search_flag)/* in: range end search cond */
+ uint keynr, /* in: index number */
+ key_range *min_key, /* in: start key value of the
+ range, may also be 0 */
+ key_range *max_key) /* in: range end key val, may
+ also be 0 */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
KEY* key;
@@ -3960,12 +4001,6 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range");
- /* We do not know if MySQL can call this function before calling
- external_lock(). To be safe, update the thd of the current table
- handle. */
-
- update_thd(current_thd);
-
prebuilt->trx->op_info = (char*)"estimating records in index range";
/* In case MySQL calls this in the middle of a SELECT query, release
@@ -3989,17 +4024,21 @@ ha_innobase::records_in_range(
range_start, (byte*) key_val_buff,
(ulint)upd_and_key_val_buff_len,
index,
- (byte*) start_key,
- (ulint) start_key_len);
+ (byte*) (min_key ? min_key->key :
+ (const mysql_byte*) 0),
+ (ulint) (min_key ? min_key->length : 0));
row_sel_convert_mysql_key_to_innobase(
range_end, (byte*) key_val_buff2,
buff2_len, index,
- (byte*) end_key,
- (ulint) end_key_len);
-
- mode1 = convert_search_mode_to_innobase(start_search_flag);
- mode2 = convert_search_mode_to_innobase(end_search_flag);
+ (byte*) (max_key ? max_key->key :
+ (const mysql_byte*) 0),
+ (ulint) (max_key ? max_key->length : 0));
+
+ mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
+ HA_READ_KEY_EXACT);
+ mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag :
+ HA_READ_KEY_EXACT);
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end, mode2);