3251 Vasil Dimov 2010-07-06
Tell low-level functions whether the caller owns the dict mutex
Low-level persistent stats functions that call que_eval_sql()
need to know whether the caller owns or not dict_sys->mutex.
Thus add a boolean parameter caller_has_dict_sys_mutex to each such
function and pass either TRUE or FALSE from the callers.
Also when requested to fetch stats - check whether this is SYS_* table
and if so, then always use the transient stats because we know that
persistent stats storage does not contain stats about SYS_* tables.
modified:
storage/innobase/dict/dict0dict.c
storage/innobase/dict/dict0load.c
storage/innobase/dict/dict0stats.c
storage/innobase/handler/ha_innodb.cc
storage/innobase/include/dict0stats.h
storage/innobase/row/row0mysql.c
3250 Vasil Dimov 2010-06-30
Copy records only when we are about to jump to the next page
Previously we were copying rec to prev_rec always, but we can do
this copying only when we are on the last record on the page and
thus we know that on the next iteration the latch on the current
page will be released.
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3249 Vasil Dimov 2010-06-30
s/persistent storage/persistent statistics storage/
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3248 Vasil Dimov 2010-06-29
Print a human readable column type/flags on error
For this purpose implement a new function dtype_sql_name()
that converts mtype,prtype,len to a human readable (SQL) name.
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
storage/innobase/include/data0type.h
storage/innobase/include/data0type.ic
3247 Vasil Dimov 2010-06-29
Fix typo in comment.
modified:
storage/innobase/dict/dict0stats.c
3246 Vasil Dimov 2010-06-29
Do not emit warnings if persistent storage is not present.
This code is executed during open table and if the persistent storage
is not present this would cause many warnings to be printed.
This change reverts the following and adds an explanatory comment.
------------------------------------------------------------
revno: 3243
revision-id: vasil.dimov@stripped
parent: vasil.dimov@stripped
committer: Vasil Dimov <vasil.dimov@stripped>
branch nick: mysql-next-mr-persistent-stats
timestamp: Tue 2010-06-29 10:48:04 +0300
message:
Emit a message before returning error if table does not exist
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3245 Vasil Dimov 2010-06-29
Use innobase_strcasecmp() instead of strcasecmp()
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3244 Vasil Dimov 2010-06-29
Fix the number of columns that is printed
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3243 Vasil Dimov 2010-06-29
Emit a message before returning error if table does not exist
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3242 Vasil Dimov 2010-06-29
Rename column_data_t and table_schema_t
Change the names of those structs to conform with the InnoDB convention
foo0bar.c -> foo_bar_...
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3241 Vasil Dimov 2010-06-29
Clarify comment in dict/dict0load.c
modified:
storage/innobase/dict/dict0load.c
3240 Vasil Dimov 2010-06-29
Add a new mysql-test to test DROPping locked stats
DROP TABLE and ALTER TABLE DROP INDEX are supposed to remove rows
from the user-visible stats tables. If those corresponding rows
are locked by the user, then the behavior should be to emit an
explanatory warning and skip the removal of those rows.
added:
mysql-test/suite/innodb/r/innodb_stats_drop_locked.result
mysql-test/suite/innodb/t/innodb_stats_drop_locked.test
3239 Vasil Dimov 2010-06-29
Move "SET SESSION innodb_analyze_is_persistent=1" to .test
Better to make it obvious that this variable is set.
modified:
mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc
mysql-test/suite/innodb/t/innodb_stats.test
3238 Vasil Dimov 2010-06-25
Move the test_innodb_stats table creation to innodb_stats.test
That table is specific for this test.
modified:
mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc
mysql-test/suite/innodb/t/innodb_stats.test
3237 Vasil Dimov 2010-06-25
Move the stats table creation from innodb_stats.test to an include file.
To be included in other tests too.
added:
mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc
modified:
mysql-test/suite/innodb/t/innodb_stats.test
3236 Vasil Dimov 2010-06-25
Improve comment
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
storage/innobase/include/dict0stats.h
3235 Vasil Dimov 2010-06-25
Remove non-existent function's prototype.
This function was removed but the prototype was forgotten.
modified:
storage/innobase/include/lock0lock.h
3234 Vasil Dimov 2010-06-25
Remove a trailing whitespace and print a message if table definition is corrupt
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
3233 Vasil Dimov 2010-06-25
Rename enum dict_stats_upd_how to dict_stats_upd_option and define
a type for it.
Suggested by: Jimmy (rb://373)
modified:
storage/innobase/dict/dict0stats.c
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/include/dict0stats.h
3232 Vasil Dimov 2010-06-17
Fix possible waits when dropping an index
Fix possible waits when dropping an index similarly to the way they
were fixed in DROP TABLE - set trx->allowed_to_wait to FALSE during
que_eval_sql() so it does not wait on possible user locks but returns
DB_LOCK_WAIT_TIMEOUT immediately.
Also push the error message to the client in addition to printing it
to the server error log and change DROP TABLE not to fail if stats
cannot be deleted.
modified:
storage/innobase/dict/dict0stats.c
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/handler0alter.cc
storage/innobase/include/dict0stats.h
=== added file 'mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc'
--- a/mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/include/innodb_stats_bootstrap.inc revid:vasil.dimov@stripped
@@ -0,0 +1,35 @@
+-- disable_warnings
+-- disable_query_log
+DROP DATABASE IF EXISTS innodb;
+CREATE DATABASE innodb;
+
+CREATE TABLE innodb.table_stats (
+ database_name VARCHAR(512) NOT NULL,
+ table_name VARCHAR(512) NOT NULL,
+ stats_timestamp TIMESTAMP NOT NULL,
+ n_rows BIGINT UNSIGNED NOT NULL,
+ clustered_index_size BIGINT UNSIGNED NOT NULL,
+ sum_of_other_index_sizes BIGINT UNSIGNED NOT NULL,
+ PRIMARY KEY (database_name, table_name)
+) ENGINE=INNODB;
+
+CREATE TABLE innodb.index_stats (
+ database_name VARCHAR(512) NOT NULL,
+ table_name VARCHAR(512) NOT NULL,
+ index_name VARCHAR(512) NOT NULL,
+ stat_timestamp TIMESTAMP NOT NULL,
+ /* there are at least:
+ stat_name='index_size'
+ stat_name='n_leaf_pages'
+ stat_name='n_diff_pfx%' */
+ stat_name VARCHAR(64) NOT NULL,
+ stat_value BIGINT UNSIGNED NOT NULL,
+ sample_size BIGINT UNSIGNED,
+ stat_description VARCHAR(1024) NOT NULL,
+ PRIMARY KEY (database_name, table_name, index_name, stat_name),
+ FOREIGN KEY (database_name, table_name)
+ REFERENCES table_stats (database_name, table_name)
+) ENGINE=INNODB;
+
+-- enable_warnings
+-- enable_query_log
=== added file 'mysql-test/suite/innodb/r/innodb_stats_drop_locked.result'
--- a/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_stats_drop_locked.result revid:vasil.dimov@stripped
@@ -0,0 +1,47 @@
+Table Op Msg_type Msg_text
+test.innodb_stats_drop_locked analyze status OK
+SET autocommit=0;
+SELECT table_name FROM innodb.table_stats
+WHERE table_name='innodb_stats_drop_locked'
+FOR UPDATE;
+table_name
+innodb_stats_drop_locked
+SELECT table_name FROM innodb.index_stats
+WHERE table_name='innodb_stats_drop_locked'
+FOR UPDATE;
+table_name
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
+Warnings:
+Warning 1205 Unable to instantly delete statistics for index c_key from innodb.index_stats because the rows are locked. They can be deleted later using DELETE FROM innodb.index_stats WHERE database_name = 'test' AND table_name = 'innodb_stats_drop_locked' AND index_name = 'c_key';
+SHOW CREATE TABLE innodb_stats_drop_locked;
+Table Create Table
+innodb_stats_drop_locked CREATE TABLE `innodb_stats_drop_locked` (
+ `c` int(11) DEFAULT NULL
+) ENGINE=InnoDB DEFAULT CHARSET=latin1
+DROP TABLE innodb_stats_drop_locked;
+Warnings:
+Warning 1205 Unable to instantly delete statistics for table test.innodb_stats_drop_locked from innodb.table_stats or innodb.index_stats because the rows are locked. They can be deleted later using DELETE FROM innodb.index_stats WHERE database_name = 'test' AND table_name = 'innodb_stats_drop_locked'; DELETE FROM innodb.table_stats WHERE database_name = 'test' AND table_name = 'innodb_stats_drop_locked';
+SHOW TABLES;
+Tables_in_test
+COMMIT;
+SELECT table_name FROM innodb.table_stats
+WHERE table_name='innodb_stats_drop_locked';
+table_name
+innodb_stats_drop_locked
+SELECT table_name FROM innodb.index_stats
+WHERE table_name='innodb_stats_drop_locked';
+table_name
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
+innodb_stats_drop_locked
=== modified file 'mysql-test/suite/innodb/t/innodb_stats.test'
--- a/mysql-test/suite/innodb/t/innodb_stats.test revid:vasil.dimov@stripped
+++ b/mysql-test/suite/innodb/t/innodb_stats.test revid:vasil.dimov@stripped
@@ -3,39 +3,12 @@
#
-- source include/have_innodb.inc
+-- source suite/innodb/include/innodb_stats_bootstrap.inc
-- disable_warnings
-- disable_query_log
-DROP DATABASE IF EXISTS innodb;
-CREATE DATABASE innodb;
-CREATE TABLE innodb.table_stats (
- database_name VARCHAR(512) NOT NULL,
- table_name VARCHAR(512) NOT NULL,
- stats_timestamp TIMESTAMP NOT NULL,
- n_rows BIGINT UNSIGNED NOT NULL,
- clustered_index_size BIGINT UNSIGNED NOT NULL,
- sum_of_other_index_sizes BIGINT UNSIGNED NOT NULL,
- PRIMARY KEY (database_name, table_name)
-) ENGINE=INNODB;
-
-CREATE TABLE innodb.index_stats (
- database_name VARCHAR(512) NOT NULL,
- table_name VARCHAR(512) NOT NULL,
- index_name VARCHAR(512) NOT NULL,
- stat_timestamp TIMESTAMP NOT NULL,
- /* there are at least:
- stat_name='index_size'
- stat_name='n_leaf_pages'
- stat_name='n_diff_pfx%' */
- stat_name VARCHAR(64) NOT NULL,
- stat_value BIGINT UNSIGNED NOT NULL,
- sample_size BIGINT UNSIGNED,
- stat_description VARCHAR(1024) NOT NULL,
- PRIMARY KEY (database_name, table_name, index_name, stat_name),
- FOREIGN KEY (database_name, table_name)
- REFERENCES table_stats (database_name, table_name)
-) ENGINE=INNODB;
+SET SESSION innodb_analyze_is_persistent=1;
DROP TABLE IF EXISTS test_innodb_stats;
@@ -44,8 +17,6 @@ CREATE TABLE test_innodb_stats (
KEY a_key (a)
) ENGINE=INNODB;
-SET SESSION innodb_analyze_is_persistent=1;
-
-- enable_warnings
-- enable_query_log
=== added file 'mysql-test/suite/innodb/t/innodb_stats_drop_locked.test'
--- a/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_stats_drop_locked.test revid:vasil.dimov@stripped
@@ -0,0 +1,62 @@
+#
+# Test the persistent stats feature when DROPping a table or an
+# index when the corresponding rows in the stats tables are locked
+#
+
+-- source include/have_innodb.inc
+-- source suite/innodb/include/innodb_stats_bootstrap.inc
+
+-- disable_warnings
+-- disable_query_log
+
+SET SESSION innodb_analyze_is_persistent=1;
+
+DROP TABLE IF EXISTS innodb_stats_drop_locked;
+
+CREATE TABLE innodb_stats_drop_locked (c INT, KEY c_key (c)) ENGINE=INNODB;
+
+ANALYZE TABLE innodb_stats_drop_locked;
+
+-- enable_warnings
+-- enable_query_log
+
+SET autocommit=0;
+
+SELECT table_name FROM innodb.table_stats
+WHERE table_name='innodb_stats_drop_locked'
+FOR UPDATE;
+
+SELECT table_name FROM innodb.index_stats
+WHERE table_name='innodb_stats_drop_locked'
+FOR UPDATE;
+
+-- connect (con1,localhost,root,,)
+
+-- connection con1
+
+ALTER TABLE innodb_stats_drop_locked DROP INDEX c_key;
+
+# the index should be gone
+SHOW CREATE TABLE innodb_stats_drop_locked;
+
+DROP TABLE innodb_stats_drop_locked;
+
+# the table should be gone
+SHOW TABLES;
+
+-- connection default
+
+-- disconnect con1
+
+COMMIT;
+
+# the stats should be there
+
+SELECT table_name FROM innodb.table_stats
+WHERE table_name='innodb_stats_drop_locked';
+
+SELECT table_name FROM innodb.index_stats
+WHERE table_name='innodb_stats_drop_locked';
+
+-- disable_query_log
+DROP DATABASE innodb;
=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped
+++ b/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped
@@ -727,7 +727,9 @@ dict_table_get(
/* If table->ibd_file_missing == TRUE, this will
print an error message and return without doing
anything. */
- dict_stats_update(table, DICT_STATS_UPD_FETCH);
+ ut_ad(!mutex_own(&dict_sys->mutex));
+ dict_stats_update(table, DICT_STATS_UPD_FETCH,
+ FALSE);
}
}
@@ -4268,7 +4270,7 @@ dict_table_print_low(
ut_ad(mutex_own(&(dict_sys->mutex)));
- dict_stats_update(table, DICT_STATS_UPD_FETCH);
+ dict_stats_update(table, DICT_STATS_UPD_FETCH, TRUE);
fprintf(stderr,
"--------------------------------------\n"
=== modified file 'storage/innobase/dict/dict0load.c'
--- a/storage/innobase/dict/dict0load.c revid:vasil.dimov@stripped
+++ b/storage/innobase/dict/dict0load.c revid:vasil.dimov@stripped
@@ -345,9 +345,10 @@ dict_process_sys_tables_rec(
if ((status & DICT_TABLE_UPDATE_STATS)
&& dict_table_get_first_index(*table)) {
- /* Update statistics if DICT_TABLE_UPDATE_STATS
- is set */
- dict_stats_update(*table, DICT_STATS_UPD_FETCH);
+ /* Update statistics member fields in *table if
+ DICT_TABLE_UPDATE_STATS is set */
+ ut_ad(mutex_own(&dict_sys->mutex));
+ dict_stats_update(*table, DICT_STATS_UPD_FETCH, TRUE);
}
return(NULL);
=== modified file 'storage/innobase/dict/dict0stats.c'
--- a/storage/innobase/dict/dict0stats.c revid:vasil.dimov@stripped
+++ b/storage/innobase/dict/dict0stats.c revid:vasil.dimov@stripped
@@ -48,7 +48,9 @@ Created Jan 06, 2010 Vasil Dimov
#include "usr0types.h" /* sess_t */
#include "ut0rnd.h" /* ut_rnd_interval() */
-/* names of the tables from the persistent storage */
+#include "ha_prototypes.h" /* innobase_strcasecmp() */
+
+/* names of the tables from the persistent statistics storage */
#define TABLE_STATS_NAME "innodb/table_stats"
#define TABLE_STATS_NAME_PRINT "innodb.table_stats"
#define INDEX_STATS_NAME "innodb/index_stats"
@@ -60,7 +62,7 @@ Created Jan 06, 2010 Vasil Dimov
#define DEBUG_PRINTF(fmt, ...) /* noop */
#endif
-/* number of distinct records on a given level that are required to stop
+/* number of distinct records on a given level that are required to stop
descending to lower levels and fetch
srv_stats_persistent_sample_pages records from that level */
#define N_DIFF_REQUIRED (srv_stats_persistent_sample_pages * 10)
@@ -87,7 +89,9 @@ dict_stats_update_transient(
if (index == NULL) {
/* Table definition is corrupt */
-
+ ut_print_timestamp(stderr);
+ fprintf(stderr, "InnoDB: table %s has no indexes. "
+ "Cannot calculate statistics.\n", table->name);
return;
}
@@ -133,22 +137,22 @@ dict_stats_update_transient(
/* @} */
/* auxiliary structs for checking a table definition @{ */
-struct column_data_struct {
+struct dict_stats_chk_column_struct {
const char* name;
ulint mtype;
ulint prtype_mask;
ulint len;
};
-typedef struct column_data_struct column_data_t;
+typedef struct dict_stats_chk_column_struct dict_stats_chk_column_t;
-struct table_schema_struct {
- const char* table_name;
- ulint n_cols;
- column_data_t* columns;
+struct dict_stats_chk_table_struct {
+ const char* table_name;
+ ulint n_cols;
+ dict_stats_chk_column_t* columns;
};
-typedef struct table_schema_struct table_schema_t;
+typedef struct dict_stats_chk_table_struct dict_stats_chk_table_t;
/* @} */
/*********************************************************************//**
@@ -160,7 +164,8 @@ static
ibool
dict_stats_table_check(
/*===================*/
- table_schema_t* req_schema) /*!< in/out: required table schema */
+ dict_stats_chk_table_t* req_schema)/*!< in/out: required table
+ schema */
{
dict_table_t* table;
ulint i;
@@ -172,6 +177,13 @@ dict_stats_table_check(
if (table == NULL || table->ibd_file_missing) {
/* no such table or missing tablespace */
+ /* We return silently here because this code is
+ executed during open table. By design we check if the
+ persistent statistics storage is present and whether there
+ are stats for the table being opened and if so, then
+ we use them, otherwise we silently switch back to using
+ the transient stats. */
+
return(FALSE);
}
@@ -183,7 +195,7 @@ dict_stats_table_check(
fprintf(stderr,
" InnoDB: %s has %d columns but should have %lu.\n",
req_schema->table_name,
- table->n_def,
+ table->n_def - DATA_N_SYS_COLS,
req_schema->n_cols);
goto err_exit;
@@ -197,8 +209,11 @@ dict_stats_table_check(
for (i = 0; i < req_schema->n_cols; i++) {
ulint j;
+ char req_type[64];
+ char actual_type[64];
+
/* check if i'th column is the same in both arrays */
- if (strcasecmp(req_schema->columns[i].name,
+ if (innobase_strcasecmp(req_schema->columns[i].name,
dict_table_get_col_name(table, i)) == 0) {
/* we found the column in table->cols[] quickly */
@@ -212,8 +227,8 @@ dict_stats_table_check(
name = dict_table_get_col_name(table, j);
- if (strcasecmp(req_schema->columns[i].name,
- name) == 0) {
+ if (innobase_strcasecmp(name,
+ req_schema->columns[i].name) == 0) {
/* found the column on j'th
position */
@@ -237,17 +252,26 @@ dict_stats_table_check(
/* we found a column with the same name on j'th position,
compare column types and flags */
+ dtype_sql_name(req_schema->columns[i].mtype,
+ req_schema->columns[i].prtype_mask,
+ req_schema->columns[i].len,
+ req_type, sizeof(req_type));
+
+ dtype_sql_name(table->cols[j].mtype,
+ table->cols[j].prtype,
+ table->cols[j].len,
+ actual_type, sizeof(actual_type));
+
/* check length for exact match */
if (req_schema->columns[i].len != table->cols[j].len) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Column %s.%s has length %d "
- "but should have length %lu.\n",
+ " InnoDB: Column %s.%s is %s "
+ "but should be %s (length mismatch).\n",
req_schema->table_name,
req_schema->columns[i].name,
- table->cols[j].len,
- req_schema->columns[i].len);
+ actual_type, req_type);
goto err_exit;
}
@@ -257,12 +281,11 @@ dict_stats_table_check(
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Column %s.%s is of type %d "
- "but should be of type %lu.\n",
+ " InnoDB: Column %s.%s is %s "
+ "but should be %s (type mismatch).\n",
req_schema->table_name,
req_schema->columns[i].name,
- table->cols[j].mtype,
- req_schema->columns[i].mtype);
+ actual_type, req_type);
goto err_exit;
}
@@ -273,14 +296,26 @@ dict_stats_table_check(
& req_schema->columns[i].prtype_mask)
!= req_schema->columns[i].prtype_mask) {
+ char req_type[64];
+ char actual_type[64];
+
+ dtype_sql_name(req_schema->columns[i].mtype,
+ req_schema->columns[i].prtype_mask,
+ req_schema->columns[i].len,
+ req_type, sizeof(req_type));
+
+ dtype_sql_name(table->cols[j].mtype,
+ table->cols[j].prtype,
+ table->cols[j].len,
+ actual_type, sizeof(actual_type));
+
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Column %s.%s flag %#lx "
- "is not set in column's flags %#x.\n",
+ " InnoDB: Column %s.%s is %s "
+ "but should be %s (flags mismatch).\n",
req_schema->table_name,
req_schema->columns[i].name,
- req_schema->columns[i].prtype_mask,
- table->cols[j].prtype);
+ actual_type, req_type);
goto err_exit;
}
@@ -301,17 +336,19 @@ err_exit:
/* @} */
/*********************************************************************//**
-Checks whether the persistent storage exists and that all tables have the
-proper structure.
+Checks whether the persistent statistics storage exists and that all
+tables have the proper structure.
dict_stats_persistent_storage_check() @{
@return TRUE if exists and all tables are ok */
static
ibool
-dict_stats_persistent_storage_check()
-/*=================================*/
+dict_stats_persistent_storage_check(
+/*================================*/
+ ibool caller_has_dict_sys_mutex) /*!< in: TRUE if the caller
+ owns dict_sys->mutex */
{
/* definition for the table TABLE_STATS_NAME */
- column_data_t table_stats_columns[] = {
+ dict_stats_chk_column_t table_stats_columns[] = {
{"database_name", DATA_VARCHAR,
DATA_NOT_NULL, 512},
@@ -330,14 +367,14 @@ dict_stats_persistent_storage_check()
{"sum_of_other_index_sizes", DATA_INT,
DATA_NOT_NULL | DATA_UNSIGNED, 8}
};
- table_schema_t table_stats_schema = {
+ dict_stats_chk_table_t table_stats_schema = {
TABLE_STATS_NAME,
UT_ARR_SIZE(table_stats_columns),
table_stats_columns
};
/* definition for the table INDEX_STATS_NAME */
- column_data_t index_stats_columns[] = {
+ dict_stats_chk_column_t index_stats_columns[] = {
{"database_name", DATA_VARCHAR,
DATA_NOT_NULL, 512},
@@ -362,17 +399,14 @@ dict_stats_persistent_storage_check()
{"stat_description", DATA_VARCHAR,
DATA_NOT_NULL, 1024}
};
- table_schema_t index_stats_schema = {
+ dict_stats_chk_table_t index_stats_schema = {
INDEX_STATS_NAME,
UT_ARR_SIZE(index_stats_columns),
index_stats_columns
};
- ibool caller_has_dict_sys_mutex;
ibool ret;
- caller_has_dict_sys_mutex = mutex_own(&dict_sys->mutex);
-
if (!caller_has_dict_sys_mutex) {
mutex_enter(&(dict_sys->mutex));
}
@@ -590,20 +624,31 @@ dict_stats_analyze_index_level(
}
}
- /* we need to copy the record instead of assigning like
- prev_rec = rec; because when we traverse the records
- on this level at some point we will jump from one page
- to the next and then rec and prev_rec will be on different
- pages and btr_pcur_move_to_next_user_rec() will release
- the latch on the page that prev_rec is on */
- prev_rec = rec_copy_prefix_to_buf(
- rec, index, rec_offs_n_fields(offsets_rec),
- &prev_rec_buf, &prev_rec_buf_size);
-
- /* increment the pages counter at the end of each page */
if (page_rec_is_supremum(page_rec_get_next(rec))) {
+ /* end of a page has been reached */
+ /* increment the pages counter at the end of
+ each page */
(*total_pages)++;
+
+ /* we need to copy the record instead of assigning
+ like prev_rec = rec; because when we traverse the
+ records on this level at some point we will jump from
+ one page to the next and then rec and prev_rec will
+ be on different pages and
+ btr_pcur_move_to_next_user_rec() will release the
+ latch on the page that prev_rec is on */
+ prev_rec = rec_copy_prefix_to_buf(
+ rec, index, rec_offs_n_fields(offsets_rec),
+ &prev_rec_buf, &prev_rec_buf_size);
+
+ } else {
+ /* still on the same page, the next call to
+ btr_pcur_move_to_next_user_rec() will not jump
+ on the next page, we can simply assign pointers
+ instead of copying the records like above */
+
+ prev_rec = rec;
}
}
@@ -1387,7 +1432,8 @@ dict_stats_update_persistent(
/* @} */
/*********************************************************************//**
-Save an individual index's statistic into the persistent storage.
+Save an individual index's statistic into the persistent statistics
+storage.
dict_stats_save_index_stat() @{
@return DB_SUCCESS or error code */
static
@@ -1400,7 +1446,9 @@ dict_stats_save_index_stat(
ib_uint64_t stat_value, /*!< in: value of the stat */
ib_uint64_t* sample_size, /*!< in: n pages sampled or NULL */
const char* stat_description,/*!< in: description of the stat */
- trx_t* trx) /*!< in/out: transaction to use */
+ trx_t* trx, /*!< in/out: transaction to use */
+ ibool caller_has_dict_sys_mutex)/*!< in: TRUE if the caller
+ owns dict_sys->mutex */
{
pars_info_t* pinfo;
ulint ret;
@@ -1476,7 +1524,7 @@ dict_stats_save_index_stat(
" stat_name = :stat_name;\n"
"END IF;\n"
"END;",
- TRUE, trx);
+ !caller_has_dict_sys_mutex, trx);
/* pinfo is freed by que_eval_sql() */
@@ -1495,14 +1543,16 @@ dict_stats_save_index_stat(
/* @} */
/*********************************************************************//**
-Save the table's statistics into the persistent storage.
+Save the table's statistics into the persistent statistics storage.
dict_stats_save() @{
@return DB_SUCCESS or error code */
static
enum db_err
dict_stats_save(
/*============*/
- dict_table_t* table) /*!< in: table */
+ dict_table_t* table, /*!< in: table */
+ ibool caller_has_dict_sys_mutex)/*!< in: TRUE if the caller
+ owns dict_sys->mutex */
{
trx_t* trx;
pars_info_t* pinfo;
@@ -1581,7 +1631,7 @@ dict_stats_save(
" table_name = :table_name;\n"
"END IF;\n"
"END;",
- TRUE, trx);
+ !caller_has_dict_sys_mutex, trx);
/* pinfo is freed by que_eval_sql() */
@@ -1613,7 +1663,8 @@ dict_stats_save(
NULL,
"Number of pages "
"in the index",
- trx);
+ trx,
+ caller_has_dict_sys_mutex);
if (ret != DB_SUCCESS) {
goto end_rollback;
}
@@ -1623,7 +1674,8 @@ dict_stats_save(
NULL,
"Number of leaf pages "
"in the index",
- trx);
+ trx,
+ caller_has_dict_sys_mutex);
if (ret != DB_SUCCESS) {
goto end_rollback;
}
@@ -1671,7 +1723,8 @@ dict_stats_save(
index, now, stat_name,
stat_n_diff_key_vals[i],
&stat_n_sample_sizes[i],
- stat_description, trx);
+ stat_description, trx,
+ caller_has_dict_sys_mutex);
if (ret != DB_SUCCESS) {
goto end_rollback;
@@ -2016,14 +2069,16 @@ dict_stats_fetch_index_stats_step(
/* @} */
/*********************************************************************//**
-Read table's statistics from the persistent storage.
+Read table's statistics from the persistent statistics storage.
dict_stats_fetch_from_ps() @{
@return DB_SUCCESS or error code */
static
enum db_err
dict_stats_fetch_from_ps(
/*=====================*/
- dict_table_t* table) /*!< in/out: table */
+ dict_table_t* table, /*!< in/out: table */
+ ibool caller_has_dict_sys_mutex)/*!< in: TRUE if the caller
+ owns dict_sys->mutex */
{
trx_t* trx;
pars_info_t* pinfo;
@@ -2115,7 +2170,7 @@ dict_stats_fetch_from_ps(
"CLOSE index_stats_cur;\n"
"END;",
- TRUE, trx);
+ !caller_has_dict_sys_mutex, trx);
/* pinfo is freed by que_eval_sql() */
@@ -2148,13 +2203,24 @@ enum db_err
dict_stats_update(
/*==============*/
dict_table_t* table, /*!< in/out: table */
- enum dict_stats_upd_how stats_upd_how)
+ dict_stats_upd_option_t stats_upd_option,
/*!< in: whether to (re)calc
the stats or to fetch them from
- the persistent storage */
+ the persistent statistics
+ storage */
+ ibool caller_has_dict_sys_mutex)
+ /*!< in: TRUE if the caller
+ owns dict_sys->mutex */
{
enum db_err ret;
+ /* check whether caller_has_dict_sys_mutex is set correctly;
+ note that mutex_own() is not implemented in non-debug code so
+ we cannot avoid having this extra param to the current function */
+ ut_ad(caller_has_dict_sys_mutex
+ ? mutex_own(&dict_sys->mutex)
+ : !mutex_own(&dict_sys->mutex));
+
if (table->ibd_file_missing) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -2175,29 +2241,32 @@ dict_stats_update(
return(DB_SUCCESS);
}
- switch (stats_upd_how) {
+ switch (stats_upd_option) {
case DICT_STATS_UPD_RECALC_PERSISTENT_VERBOSE:
case DICT_STATS_UPD_RECALC_PERSISTENT_SILENT:
- /* Persistent recalculation requested, probably called from
- ANALYZE TABLE */
+ /* Persistent recalculation requested, called from
+ ANALYZE TABLE or from TRUNCATE TABLE */
- /* check if the persistent storage exists before calling
- the potentially slow function
+ /* check if the persistent statistics storage exists
+ before calling the potentially slow function
dict_stats_update_persistent(); that is a
prerequisite for dict_stats_save() succeeding */
- if (dict_stats_persistent_storage_check()) {
+ if (dict_stats_persistent_storage_check(
+ caller_has_dict_sys_mutex)) {
ret = dict_stats_update_persistent(table);
if (ret == DB_SUCCESS) {
- ret = dict_stats_save(table);
+ ret = dict_stats_save(
+ table,
+ caller_has_dict_sys_mutex);
}
} else {
/* Fall back to transient stats since the persistent
storage is not present or is corrupted */
- if (stats_upd_how
+ if (stats_upd_option
== DICT_STATS_UPD_RECALC_PERSISTENT_VERBOSE) {
ut_print_timestamp(stderr);
@@ -2206,8 +2275,8 @@ dict_stats_update(
fprintf(stderr,
" InnoDB: Recalculation of persistent "
"statistics requested but the required "
- "persistent storage is not present "
- "or is corrupted. "
+ "persistent statistics storage is not "
+ "present or is corrupted. "
"Using quick transient stats "
"instead.\n");
}
@@ -2227,24 +2296,34 @@ dict_stats_update(
break;
case DICT_STATS_UPD_FETCH:
- /* fetch requested, either fetch from persistent storage
- or use the old method */
+ /* fetch requested, either fetch from persistent statistics
+ storage or use the old method */
- if (dict_stats_persistent_storage_check()) {
+ if (strchr(table->name, '/') == NULL) {
+ /* Use the quick transient stats method for
+ SYS_* tables because we know the persistent
+ stats storage does not contain data for SYS_*
+ tables */
+ dict_stats_update_transient(table);
+ ret = DB_SUCCESS;
+ } else if (dict_stats_persistent_storage_check(
+ caller_has_dict_sys_mutex)) {
- ret = dict_stats_fetch_from_ps(table);
+ ret = dict_stats_fetch_from_ps(
+ table,
+ caller_has_dict_sys_mutex);
} else {
- /* if persistent storage does not exist, then
- force the following code to calculate the
+ /* if persistent statistics storage does not exist,
+ then force the following code to calculate the
transient stats */
ret = DB_STATS_DO_NOT_EXIST;
}
if (ret == DB_STATS_DO_NOT_EXIST) {
- /* The persistent storage does not exist or stats
- for this particular table do not exist, then
+ /* The persistent statistics storage does not exist
+ or stats for this particular table do not exist, then
calculate the quick transient statistics */
dict_stats_update_transient(table);
ret = DB_SUCCESS;
@@ -2263,7 +2342,7 @@ dict_stats_update(
/* @} */
/*********************************************************************//**
-Removes the information for a particular index from the persistent
+Removes the information for a particular index's stats from the persistent
storage if it exists and if there is data stored for this index.
The transaction is not committed, it must not be committed in this
function because this is the user trx that is running DROP INDEX.
@@ -2321,10 +2400,10 @@ dict_stats_drop_index(
row_mysql_unlock_data_dictionary(trx);
- /* If the persistent storage does not exist or is corrupted,
- then do not attempt to DELETE from its tables because the
- internal parser will crash. */
- if (!dict_stats_persistent_storage_check()) {
+ /* If the persistent statistics storage does not exist or is
+ corrupted, then do not attempt to DELETE from its tables because
+ the internal parser will crash. */
+ if (!dict_stats_persistent_storage_check(FALSE)) {
dict_table_decrement_handle_count(table_stats, FALSE);
dict_table_decrement_handle_count(index_stats, FALSE);
@@ -2399,8 +2478,8 @@ dict_stats_drop_index(
/*********************************************************************//**
Removes the statistics for a table and all of its indexes from the
-persistent storage if it exists and if there is data stored for the table.
-This function creates its own transaction and commits it.
+persistent statistics storage if it exists and if there is data stored for
+the table. This function creates its own transaction and commits it.
dict_stats_drop_table() @{
@return DB_SUCCESS or error code */
UNIV_INTERN
@@ -2469,10 +2548,10 @@ dict_stats_drop_table(
row_mysql_unlock_data_dictionary(trx);
- /* If the persistent storage does not exist or is corrupted,
- then do not attempt to DELETE from its tables because the
- internal SQL parser will crash. */
- if (!dict_stats_persistent_storage_check()) {
+ /* If the persistent statistics storage does not exist or is
+ corrupted, then do not attempt to DELETE from its tables because
+ the internal SQL parser will crash. */
+ if (!dict_stats_persistent_storage_check(FALSE)) {
ret = DB_SUCCESS;
goto decrement_ref_count_commit_and_return;
@@ -2580,7 +2659,7 @@ test_dict_stats_table_check()
) ENGINE=INNODB;
*/
/* definition for the table 'test/tcheck' */
- column_data_t columns[] = {
+ dict_stats_chk_column_t columns[] = {
{"c01", DATA_VARCHAR, 0, 123},
{"c02", DATA_INT, 0, 4},
{"c03", DATA_INT, DATA_NOT_NULL, 4},
@@ -2590,7 +2669,7 @@ test_dict_stats_table_check()
{"c07", DATA_INT, 0, 4},
{"c_extra", DATA_INT, 0, 4}
};
- table_schema_t schema = {
+ dict_stats_chk_table_t schema = {
"test/tcheck",
0 /* will be set individually for each test below */,
columns
@@ -2777,7 +2856,7 @@ test_dict_stats_save()
index2_stat_n_sample_sizes[3] = TEST_IDX2_N_DIFF3_SAMPLE_SIZE;
index2_stat_n_sample_sizes[4] = TEST_IDX2_N_DIFF4_SAMPLE_SIZE;
- ret = dict_stats_save(&table);
+ ret = dict_stats_save(&table, FALSE);
ut_a(ret == DB_SUCCESS);
@@ -2904,7 +2983,7 @@ test_dict_stats_fetch_from_ps()
index2.stat_n_diff_key_vals = index2_stat_n_diff_key_vals;
index2.stat_n_sample_sizes = index2_stat_n_sample_sizes;
- ret = dict_stats_fetch_from_ps(&table);
+ ret = dict_stats_fetch_from_ps(&table, FALSE);
ut_a(ret == DB_SUCCESS);
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped
@@ -7699,7 +7699,7 @@ ha_innobase::info_low(
/*!< out: HA_ERR_* error code */
uint flag, /*!< in: what information MySQL
requests */
- enum dict_stats_upd_how stats_upd_how)
+ dict_stats_upd_option_t stats_upd_option)
/*!< in: whether to (re)calc
the stats or to fetch them from
the persistent storage */
@@ -7753,7 +7753,9 @@ ha_innobase::info_low(
prebuilt->trx->op_info = "updating table statistics";
- ret = dict_stats_update(ib_table, stats_upd_how);
+ ut_ad(!mutex_own(&dict_sys->mutex));
+ ret = dict_stats_update(ib_table, stats_upd_option,
+ FALSE);
if (ret != DB_SUCCESS) {
prebuilt->trx->op_info = "";
@@ -8010,19 +8012,19 @@ ha_innobase::analyze(
THD* thd, /*!< in: connection thread handle */
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
- enum dict_stats_upd_how upd_how;
+ dict_stats_upd_option_t upd_option;
int ret;
if (THDVAR(thd, analyze_is_persistent)) {
- upd_how = DICT_STATS_UPD_RECALC_PERSISTENT_VERBOSE;
+ upd_option = DICT_STATS_UPD_RECALC_PERSISTENT_VERBOSE;
} else {
- upd_how = DICT_STATS_UPD_RECALC_TRANSIENT;
+ upd_option = DICT_STATS_UPD_RECALC_TRANSIENT;
}
/* Simply call ::info_low() with all the flags
and request recalculation of the statistics */
ret = info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
- upd_how);
+ upd_option);
if (ret != 0) {
return(HA_ADMIN_FAILED);
=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h revid:vasil.dimov@stripped
+++ b/storage/innobase/handler/ha_innodb.h revid:vasil.dimov@stripped
@@ -111,7 +111,7 @@ class ha_innobase: public handler
ulint innobase_update_autoinc(ulonglong auto_inc);
void innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr);
- int info_low(uint flag, enum dict_stats_upd_how stats_upd_how);
+ int info_low(uint flag, dict_stats_upd_option_t stats_upd_option);
/* Init values for the class: */
public:
=== modified file 'storage/innobase/include/data0type.h'
--- a/storage/innobase/include/data0type.h revid:vasil.dimov@stripped
+++ b/storage/innobase/include/data0type.h revid:vasil.dimov@stripped
@@ -425,6 +425,19 @@ dtype_new_read_for_order_and_null_size(
/*===================================*/
dtype_t* type, /*!< in: type struct */
const byte* buf); /*!< in: buffer for stored type order info */
+
+/*********************************************************************//**
+Returns the type's SQL name (e.g. BIGINT UNSIGNED) from mtype,prtype,len */
+UNIV_INTERN
+char*
+dtype_sql_name(
+/*===========*/
+ unsigned mtype, /*!< in: mtype */
+ unsigned prtype, /*!< in: prtype */
+ unsigned len, /*!< in: len */
+ char* name, /*!< out: SQL name */
+ unsigned name_sz);/*!< in: size of the name buffer */
+
#endif /* !UNIV_HOTBACKUP */
/*********************************************************************//**
=== modified file 'storage/innobase/include/data0type.ic'
--- a/storage/innobase/include/data0type.ic revid:vasil.dimov@stripped
+++ b/storage/innobase/include/data0type.ic revid:vasil.dimov@stripped
@@ -23,6 +23,8 @@ Data types
Created 1/16/1996 Heikki Tuuri
*******************************************************/
+#include <string.h> /* strlen() */
+
#include "mach0data.h"
#ifndef UNIV_HOTBACKUP
# include "ha_prototypes.h"
@@ -392,6 +394,98 @@ dtype_new_read_for_order_and_null_size(
}
dtype_set_mblen(type);
}
+
+/*********************************************************************//**
+Returns the type's SQL name (e.g. BIGINT UNSIGNED) from mtype,prtype,len */
+UNIV_INTERN
+char*
+dtype_sql_name(
+/*===========*/
+ unsigned mtype, /*!< in: mtype */
+ unsigned prtype, /*!< in: prtype */
+ unsigned len, /*!< in: len */
+ char* name, /*!< out: SQL name */
+ unsigned name_sz)/*!< in: size of the name buffer */
+{
+
+#define APPEND_UNSIGNED() \
+ do { \
+ if (prtype & DATA_UNSIGNED) { \
+ ut_snprintf(name + strlen(name), \
+ name_sz - strlen(name), \
+ " UNSIGNED"); \
+ } \
+ } while (0)
+
+ ut_snprintf(name, name_sz, "UNKNOWN");
+
+ switch (mtype) {
+ case DATA_INT:
+ switch (len) {
+ case 1:
+ ut_snprintf(name, name_sz, "TINYINT");
+ break;
+ case 2:
+ ut_snprintf(name, name_sz, "SMALLINT");
+ break;
+ case 3:
+ ut_snprintf(name, name_sz, "MEDIUMINT");
+ break;
+ case 4:
+ ut_snprintf(name, name_sz, "INT");
+ break;
+ case 8:
+ ut_snprintf(name, name_sz, "BIGINT");
+ break;
+ }
+ APPEND_UNSIGNED();
+ break;
+ case DATA_FLOAT:
+ ut_snprintf(name, name_sz, "FLOAT");
+ APPEND_UNSIGNED();
+ break;
+ case DATA_DOUBLE:
+ ut_snprintf(name, name_sz, "DOUBLE");
+ APPEND_UNSIGNED();
+ break;
+ case DATA_FIXBINARY:
+ ut_snprintf(name, name_sz, "BINARY(%u)", len);
+ break;
+ case DATA_CHAR:
+ ut_snprintf(name, name_sz, "CHAR(%u)", len);
+ break;
+ case DATA_VARCHAR:
+ ut_snprintf(name, name_sz, "VARCHAR(%u)", len);
+ break;
+ case DATA_BINARY:
+ ut_snprintf(name, name_sz, "VARBINARY(%u)", len);
+ break;
+ case DATA_BLOB:
+ switch (len) {
+ case 9:
+ ut_snprintf(name, name_sz, "TINYBLOB");
+ break;
+ case 10:
+ ut_snprintf(name, name_sz, "BLOB");
+ break;
+ case 11:
+ ut_snprintf(name, name_sz, "MEDIUMBLOB");
+ break;
+ case 12:
+ ut_snprintf(name, name_sz, "LONGBLOB");
+ break;
+ }
+ }
+
+ if (prtype & DATA_NOT_NULL) {
+ ut_snprintf(name + strlen(name),
+ name_sz - strlen(name),
+ " NOT NULL");
+ }
+
+ return(name);
+}
+
#endif /* !UNIV_HOTBACKUP */
/***********************************************************************//**
=== modified file 'storage/innobase/include/dict0stats.h'
--- a/storage/innobase/include/dict0stats.h revid:vasil.dimov@stripped
+++ b/storage/innobase/include/dict0stats.h revid:vasil.dimov@stripped
@@ -32,7 +32,7 @@ Created Jan 06, 2010 Vasil Dimov
#include "dict0types.h"
#include "trx0types.h"
-enum dict_stats_upd_how {
+enum dict_stats_upd_option {
DICT_STATS_UPD_RECALC_PERSISTENT_VERBOSE,/* (re)calculate the
statistics using a precise and slow
algo and save them to the persistent
@@ -50,6 +50,8 @@ enum dict_stats_upd_how {
persistent storage */
};
+typedef enum dict_stats_upd_option dict_stats_upd_option_t;
+
/*********************************************************************//**
Calculates new estimates for table and index statistics. The statistics
are used in query optimization.
@@ -59,13 +61,16 @@ enum db_err
dict_stats_update(
/*==============*/
dict_table_t* table, /*!< in/out: table */
- enum dict_stats_upd_how stats_upd_how);
+ dict_stats_upd_option_t stats_upd_option,
/*!< in: whether to (re)calc
the stats or to fetch them from
the persistent storage */
+ ibool caller_has_dict_sys_mutex);
+ /*!< in: TRUE if the caller
+ owns dict_sys->mutex */
/*********************************************************************//**
-Removes the information for a particular index from the persistent
+Removes the information for a particular index's stats from the persistent
storage if it exists and if there is data stored for this index.
The transaction is not committed, it must not be committed in this
function because this is the user trx that is running DROP INDEX.
=== modified file 'storage/innobase/include/lock0lock.h'
--- a/storage/innobase/include/lock0lock.h revid:vasil.dimov@stripped
+++ b/storage/innobase/include/lock0lock.h revid:vasil.dimov@stripped
@@ -469,20 +469,6 @@ lock_table(
dict_table_t* table, /*!< in: database table in dictionary cache */
enum lock_mode mode, /*!< in: lock mode */
que_thr_t* thr); /*!< in: query thread */
-/*********************************************************************//**
-Lock a given table with the given lock mode. This function may block the
-execution for some time, but will not wait infinitely if the table is
-already locked, it may return DB_LOCK_WAIT_TIMEOUT.
-The table is unlocked when the trx is committed.
-@return DB_SUCCESS or error code */
-UNIV_INTERN
-enum db_err
-lock_table_by_name(
-/*===============*/
- const char* table_name, /*!< in: table name */
- enum lock_mode mode, /*!< in: lock mode */
- trx_t* trx); /*!< in/out: transaction into which to
- lock the table */
/*************************************************************//**
Removes a granted record lock of a transaction from the queue and grants
locks to other transactions waiting in the queue if they now are entitled
=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c revid:vasil.dimov@stripped
+++ b/storage/innobase/row/row0mysql.c revid:vasil.dimov@stripped
@@ -865,7 +865,8 @@ row_update_statistics_if_needed(
if (counter > 2000000000
|| ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {
- dict_stats_update(table, DICT_STATS_UPD_FETCH);
+ ut_ad(!mutex_own(&dict_sys->mutex));
+ dict_stats_update(table, DICT_STATS_UPD_FETCH, FALSE);
}
}
@@ -2922,7 +2923,8 @@ funct_exit:
/* We are supposed to recalc and save the stats only
on ANALYZE, but it also makes sense to do so on TRUNCATE */
- dict_stats_update(table, DICT_STATS_UPD_RECALC_PERSISTENT_SILENT);
+ dict_stats_update(table, DICT_STATS_UPD_RECALC_PERSISTENT_SILENT,
+ FALSE);
trx->op_info = "";
Attachment: [text/bzr-bundle] bzr/vasil.dimov@oracle.com-20100706134658-i8fkddy9eg4r0v9s.bundle
Thread |
---|
• bzr push into mysql-next-mr-persistent-stats branch (vasil.dimov:3232 to3251) | vasil.dimov | 6 Jul |