summaryrefslogtreecommitdiff
path: root/sql/ha_innodb.cc
diff options
context:
space:
mode:
authormonty@mashka.mysql.fi <>2003-01-18 03:13:37 +0200
committermonty@mashka.mysql.fi <>2003-01-18 03:13:37 +0200
commit76f146a17551e218727ee4a5544edb62d3cbe56e (patch)
treeb24bce166fd5affbcc506bbc7d70c2c7ef00f561 /sql/ha_innodb.cc
parent1b03f007101aa5123a7e55add3db5139a47bddc6 (diff)
parentc1d614192ee6930aed50f0cf64bf60abf6c1acb0 (diff)
downloadmariadb-git-76f146a17551e218727ee4a5544edb62d3cbe56e.tar.gz
Merge with 4.0.9
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r--sql/ha_innodb.cc196
1 files changed, 147 insertions, 49 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index cb012d33572..86544542613 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -2272,19 +2272,7 @@ convert_search_mode_to_innobase(
case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
case HA_READ_PREFIX: return(PAGE_CUR_GE);
- case HA_READ_PREFIX_LAST:
- /* ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Warning: Using HA_READ_PREFIX_LAST\n"); */
- return(PAGE_CUR_LE);
-
- /* InnoDB does not yet support ..PREFIX_LAST!
- We have to add a new search flag
- PAGE_CUR_LE_OR_PREFIX to InnoDB. */
-
- /* the above PREFIX flags mean that the last
- field in the key value may just be a prefix
- of the complete fixed length field */
+ case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE_OR_EXTENDS);
default: assert(0);
}
@@ -2489,6 +2477,9 @@ ha_innobase::change_active_index(
(trx_t*) current_thd->transaction.all.innobase_tid);
ut_a(user_thd == current_thd);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->transaction.all.innobase_tid);
+
active_index = keynr;
if (keynr != MAX_KEY && table->keys > 0) {
@@ -2520,6 +2511,11 @@ ha_innobase::change_active_index(
the flag ROW_MYSQL_WHOLE_ROW below, but that caused unnecessary
copying. Starting from MySQL-4.1 we use a more efficient flag here. */
+ /*
+ TODO: In 4.0 the below user_thd was changed to NULL.
+ Heikki, please delete this comment after you have read this and may
+ acted upon it.
+ */
build_template(prebuilt, user_thd, table, ROW_MYSQL_REC_FIELDS);
DBUG_RETURN(0);
@@ -3025,6 +3021,7 @@ ha_innobase::create(
{
int error;
dict_table_t* innobase_table;
+ trx_t* parent_trx;
trx_t* trx;
int primary_key_no;
uint i;
@@ -3036,6 +3033,16 @@ ha_innobase::create(
DBUG_ASSERT(thd != NULL);
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
trx = trx_allocate_for_mysql();
if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) {
@@ -3196,11 +3203,22 @@ ha_innobase::delete_table(
{
ulint name_len;
int error;
+ trx_t* parent_trx;
trx_t* trx;
char norm_name[1000];
DBUG_ENTER("ha_innobase::delete_table");
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
if (lower_case_table_names) {
srv_lower_case_table_names = TRUE;
} else {
@@ -3255,11 +3273,22 @@ innobase_drop_database(
the database name is 'test' */
{
ulint len = 0;
+ trx_t* parent_trx;
trx_t* trx;
char* ptr;
int error;
char namebuf[10000];
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
ptr = strend(path) - 2;
while (ptr >= path && *ptr != '\\' && *ptr != '/') {
@@ -3311,12 +3340,23 @@ ha_innobase::rename_table(
ulint name_len1;
ulint name_len2;
int error;
+ trx_t* parent_trx;
trx_t* trx;
char norm_from[1000];
char norm_to[1000];
DBUG_ENTER("ha_innobase::rename_table");
+ /* Get the transaction associated with the current thd, or create one
+ if not yet created */
+
+ parent_trx = check_trx_exists(current_thd);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(parent_trx);
+
if (lower_case_table_names) {
srv_lower_case_table_names = TRUE;
} else {
@@ -3363,8 +3403,8 @@ Estimates the number of index records in a range. */
ha_rows
ha_innobase::records_in_range(
/*==========================*/
- /* out: estimated number of rows,
- currently 32-bit int or uint */
+ /* 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 */
@@ -3395,9 +3435,18 @@ ha_innobase::records_in_range(
DBUG_ENTER("records_in_range");
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
+ /* 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
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
active_index = keynr;
@@ -3431,6 +3480,8 @@ ha_innobase::records_in_range(
my_free((char*) key_val_buff2, MYF(0));
+ prebuilt->trx->op_info = (char*)"";
+
DBUG_RETURN((ha_rows) n_rows);
}
@@ -3451,11 +3502,21 @@ ha_innobase::estimate_number_of_rows(void)
ulonglong estimate;
ulonglong local_data_file_length;
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
+ DBUG_ENTER("estimate_number_of_rows");
- DBUG_ENTER("info");
+ /* 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*)
+ "calculating upper bound for table rows";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
index = dict_table_get_first_index_noninline(prebuilt->table);
@@ -3470,6 +3531,8 @@ ha_innobase::estimate_number_of_rows(void)
estimate = 2 * local_data_file_length / dict_index_calc_min_rec_len(index);
+ prebuilt->trx->op_info = (char*)"";
+
DBUG_RETURN((ha_rows) estimate);
}
@@ -3520,9 +3583,18 @@ ha_innobase::info(
return;
}
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
+ /* 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);
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ prebuilt->trx->op_info = (char*)"returning various info to MySQL";
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
ib_table = prebuilt->table;
@@ -3530,7 +3602,12 @@ ha_innobase::info(
/* In sql_show we call with this flag: update then statistics
so that they are up-to-date */
+ prebuilt->trx->op_info = (char*)"updating table statistics";
+
dict_update_statistics(ib_table);
+
+ prebuilt->trx->op_info = (char*)
+ "returning various info to MySQL";
}
if (flag & HA_STATUS_VARIABLE) {
@@ -3590,12 +3667,6 @@ ha_innobase::info(
}
}
- /* The trx struct in InnoDB contains a pthread mutex embedded:
- in the debug version of MySQL that it replaced by a 'safe mutex'
- which is of a different size. We have to use a function to access
- trx fields. Otherwise trx->error_info will be a random
- pointer and cause a seg fault. */
-
if (flag & HA_STATUS_ERRKEY) {
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
@@ -3604,6 +3675,8 @@ ha_innobase::info(
trx_get_error_info(prebuilt->trx));
}
+ prebuilt->trx->op_info = (char*)"";
+
DBUG_VOID_RETURN;
}
@@ -3661,11 +3734,22 @@ ha_innobase::update_table_comment(
char* str = my_malloc(length + 16500, MYF(0));
char* pos;
- /* Warning: since it is not sure that MySQL calls external_lock
- before calling this function, the trx field in prebuilt can be
- obsolete! */
+ /* 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*)"returning table comment";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
if (!str) {
+ prebuilt->trx->op_info = (char*)"";
+
return((char*)comment);
}
@@ -3689,6 +3773,8 @@ ha_innobase::update_table_comment(
prebuilt->table);
}
+ prebuilt->trx->op_info = (char*)"";
+
return(str);
}
@@ -3704,20 +3790,30 @@ ha_innobase::get_foreign_key_create_info(void)
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
char* str;
-
- if (prebuilt == NULL) {
- fprintf(stderr,
-"InnoDB: Error: cannot get create info for foreign keys\n");
- return(NULL);
- }
+ ut_a(prebuilt != NULL);
+ /* 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*)"getting info on foreign keys";
+
+ /* In case MySQL calls this in the middle of a SELECT query, release
+ possible adaptive hash latch to avoid deadlocks of threads */
+
+ trx_search_latch_release_if_reserved(prebuilt->trx);
+
str = (char*)ut_malloc(10000);
str[0] = '\0';
dict_print_info_on_foreign_keys(TRUE, str, 9000, prebuilt->table);
+ prebuilt->trx->op_info = (char*)"";
+
return(str);
}
@@ -3793,9 +3889,10 @@ ha_innobase::reset(void)
}
/**********************************************************************
-When we create a temporary table inside MySQL LOCK TABLES, MySQL will
-not call external_lock for the temporary table when it uses it. Instead,
-it will call this function. */
+Inside LOCK TABLES MySQL will not call external_lock() between SQL
+statements. It will call this function at the start of each SQL statement.
+Note also a spacial case: if a temporary table is created inside LOCK
+TABLES, MySQL has not called external_lock() at all on that table. */
int
ha_innobase::start_stmt(
@@ -3933,8 +4030,8 @@ ha_innobase::external_lock(
trx->mysql_n_tables_locked = 0;
- /* Here we release the search latch, auto_inc_lock,
- and InnoDB thread FIFO ticket if they were reserved. */
+ /* Here we release the search latch and InnoDB
+ thread FIFO ticket if they were reserved. */
innobase_release_stat_resources(trx);
@@ -3978,12 +4075,12 @@ innodb_show_status(
DBUG_RETURN(-1);
}
- /* We let the InnoDB Monitor to output at most 100 kB of text, add
+ /* We let the InnoDB Monitor to output at most 200 kB of text, add
a safety margin of 10 kB for buffer overruns */
- buf = (char*)ut_malloc(110 * 1024);
+ buf = (char*)ut_malloc(210 * 1024);
- srv_sprintf_innodb_monitor(buf, 100 * 1024);
+ srv_sprintf_innodb_monitor(buf, 200 * 1024);
List<Item> field_list;
@@ -3991,6 +4088,7 @@ innodb_show_status(
if (protocol->send_fields(&field_list, 1))
{
+ ut_free(buf);
DBUG_RETURN(-1);
}
@@ -4241,4 +4339,4 @@ ha_innobase::get_auto_increment()
}
#endif /* HAVE_INNOBASE_DB */
-
+