#At file:///home/marko/innobase/dev/mysql2a/5.6-innodb/ based on revid:marko.makela@stripped7zxr3u8ni0uc
3254 Marko Mäkelä 2010-10-19 [merge]
Merge from mysql-5.5-innodb to mysql-trunk-innodb
added:
mysql-test/suite/innodb/r/innodb_bug57252.result
mysql-test/suite/innodb/t/innodb_bug57252.test
modified:
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/os/os0sync.c
=== added file 'mysql-test/suite/innodb/r/innodb_bug57252.result'
--- a/mysql-test/suite/innodb/r/innodb_bug57252.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/r/innodb_bug57252.result revid:marko.makela@strippedzsy
@@ -0,0 +1,6 @@
+cardinality
+10
+Table Op Msg_type Msg_text
+test.bug57252 analyze status OK
+cardinality
+10
=== added file 'mysql-test/suite/innodb/t/innodb_bug57252.test'
--- a/mysql-test/suite/innodb/t/innodb_bug57252.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb/t/innodb_bug57252.test revid:marko.makela@stripped20101019095321-hbahtzixj7spezsy
@@ -0,0 +1,46 @@
+#
+# Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE
+# http://bugs.mysql.com/57252
+#
+
+-- source include/have_innodb.inc
+
+-- disable_query_log
+-- disable_result_log
+
+SET @innodb_stats_on_metadata_orig = @@innodb_stats_on_metadata;
+
+CREATE TABLE bug57252 (a INT, KEY akey (a)) ENGINE=INNODB;
+
+BEGIN;
+let $i = 10;
+while ($i) {
+ eval INSERT INTO bug57252 VALUES ($i);
+ dec $i;
+}
+COMMIT;
+
+-- enable_result_log
+
+SET GLOBAL innodb_stats_on_metadata=0;
+
+# this calls ::info() without HA_STATUS_CONST and so
+# index->stat_n_diff_key_vals[] is not copied to the mysql-visible
+# rec_per_key
+SELECT cardinality FROM information_schema.statistics
+WHERE table_name='bug57252' AND index_name='akey';
+
+# this calls ::info() with HA_STATUS_CONST and so
+# index->stat_n_diff_key_vals[] is copied to the mysql-visible
+# rec_per_key at the end; when the bug is present dict_update_statistics()
+# is not called beforehand and so index->stat_n_diff_key_vals[] contains
+# an outdated data and thus we get an outdated data in the result when the
+# bug is present
+ANALYZE TABLE bug57252;
+
+SELECT cardinality FROM information_schema.statistics
+WHERE table_name='bug57252' AND index_name='akey';
+
+DROP TABLE bug57252;
+
+SET GLOBAL innodb_stats_on_metadata = @innodb_stats_on_metadata_orig;
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:marko.makela@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:marko.makela@stripped
@@ -7703,9 +7703,12 @@ Returns statistics information of the ta
in various fields of the handle object. */
UNIV_INTERN
int
-ha_innobase::info(
-/*==============*/
- uint flag) /*!< in: what information MySQL requests */
+ha_innobase::info_low(
+/*==================*/
+ uint flag, /*!< in: what information MySQL
+ requests */
+ bool called_from_analyze) /* in: TRUE if called from
+ ::analyze() */
{
dict_table_t* ib_table;
dict_index_t* index;
@@ -7736,7 +7739,7 @@ ha_innobase::info(
ib_table = prebuilt->table;
if (flag & HA_STATUS_TIME) {
- if (innobase_stats_on_metadata) {
+ if (called_from_analyze || innobase_stats_on_metadata) {
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
@@ -7984,6 +7987,18 @@ func_exit:
DBUG_RETURN(0);
}
+/*********************************************************************//**
+Returns statistics information of the table to the MySQL interpreter,
+in various fields of the handle object. */
+UNIV_INTERN
+int
+ha_innobase::info(
+/*==============*/
+ uint flag) /*!< in: what information MySQL requests */
+{
+ return(info_low(flag, false /* not called from analyze */));
+}
+
/**********************************************************************//**
Updates index cardinalities of the table, based on 8 random dives into
each index tree. This does NOT calculate exact statistics on the table.
@@ -7996,7 +8011,8 @@ ha_innobase::analyze(
HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
{
/* Simply call ::info() with all the flags */
- info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
+ info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
+ true /* called from analyze */);
return(0);
}
=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h revid:marko.makela@stripped20101019093014-ns3g7zxr3u8ni0uc
+++ b/storage/innobase/handler/ha_innodb.h revid:marko.makela@stripped95321-hbahtzixj7spezsy
@@ -109,6 +109,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, bool called_from_analyze);
/* Init values for the class: */
public:
=== modified file 'storage/innobase/os/os0sync.c'
--- a/storage/innobase/os/os0sync.c revid:marko.makela@stripped3u8ni0uc
+++ b/storage/innobase/os/os0sync.c revid:marko.makela@stripped
@@ -137,7 +137,7 @@ os_cond_wait_timed(
const struct timespec* abstime /*!< in: timeout */
#else
ulint time_in_ms /*!< in: timeout in
- milliseconds */
+ milliseconds*/
#endif /* !__WIN__ */
)
{
@@ -160,7 +160,17 @@ os_cond_wait_timed(
ret = pthread_cond_timedwait(cond, mutex, abstime);
- ut_a(ret == 0 || ret == ETIMEDOUT);
+ switch (ret) {
+ case 0:
+ case ETIMEDOUT:
+ break;
+
+ default:
+ fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: "
+ "%d: abstime={%lu,%lu}\n",
+ ret, abstime->tv_sec, abstime->tv_nsec);
+ ut_error;
+ }
return(ret == ETIMEDOUT);
#endif
@@ -637,14 +647,15 @@ os_event_wait_time_low(
ib_int64_t old_signal_count;
#ifdef __WIN__
- DWORD time_in_ms = time_in_usec / 1000;
+ DWORD time_in_ms;
if (!srv_use_native_conditions) {
DWORD err;
ut_a(event);
- if (time_in_ms != OS_SYNC_INFINITE_TIME) {
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_ms / 1000;
err = WaitForSingleObject(event->handle, time_in_ms);
} else {
err = WaitForSingleObject(event->handle, INFINITE);
@@ -661,30 +672,44 @@ os_event_wait_time_low(
return(42);
} else {
ut_a(sleep_condition_variable != NULL);
+
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ time_in_ms = time_in_usec / 1000;
+ } else {
+ time_in_ms = INFINITE;
+ }
}
#else
- struct timeval tv;
- ulint sec;
- ulint usec;
- int ret;
struct timespec abstime;
- ret = ut_usectime(&sec, &usec);
- ut_a(ret == 0);
-
- tv.tv_sec = sec;
- tv.tv_usec = usec;
-
- tv.tv_usec += time_in_usec;
+ if (time_in_usec != OS_SYNC_INFINITE_TIME) {
+ struct timeval tv;
+ int ret;
+ ulint sec;
+ ulint usec;
+
+ ret = ut_usectime(&sec, &usec);
+ ut_a(ret == 0);
+
+ tv.tv_sec = sec;
+ tv.tv_usec = usec;
+
+ tv.tv_usec += time_in_usec;
+
+ if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
+ tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
+ tv.tv_usec %= MICROSECS_IN_A_SECOND;
+ }
- if ((ulint) tv.tv_usec > MICROSECS_IN_A_SECOND) {
- tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
- tv.tv_usec %= MICROSECS_IN_A_SECOND;
+ abstime.tv_sec = tv.tv_sec;
+ abstime.tv_nsec = tv.tv_usec * 1000;
+ } else {
+ abstime.tv_nsec = 999999999;
+ abstime.tv_sec = (time_t) ULINT_MAX;
}
- /* Convert to nano seconds. We ignore overflow. */
- abstime.tv_sec = tv.tv_sec;
- abstime.tv_nsec = tv.tv_usec * 1000;
+ ut_a(abstime.tv_nsec <= 999999999);
+
#endif /* __WIN__ */
os_fast_mutex_lock(&event->os_mutex);
Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20101019095321-hbahtzixj7spezsy.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-innodb branch (marko.makela:3254) | marko.makela | 19 Oct |