summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorSatya B <satya.bn@sun.com>2009-04-24 16:33:50 +0530
committerSatya B <satya.bn@sun.com>2009-04-24 16:33:50 +0530
commit97ae03bf526a0cef7c76739b9a583a0f6209aa7f (patch)
treedcc3ceab089d019567ded08d48e0f0a3ec090c07 /innobase
parent4783b2e196e4ed4c037194d74b99922e92deecd0 (diff)
downloadmariadb-git-97ae03bf526a0cef7c76739b9a583a0f6209aa7f.tar.gz
Fix for BUG#43660- SHOW INDEXES/ANALYZE does NOT update cardinality
for indexes of InnoDB table Fixes by replacing the PRNG that is used to pick random pages with a better one. Also adds a configuration option "innodb_use_legacy_cardinality_algorithm" to enable the fix only when the option is set. This patch is from http://bugs.mysql.com/file.php?id=11789
Diffstat (limited to 'innobase')
-rw-r--r--innobase/include/srv0srv.h6
-rw-r--r--innobase/page/page0cur.c75
-rw-r--r--innobase/srv/srv0srv.c6
3 files changed, 85 insertions, 2 deletions
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index 97e9136040d..ece6b1d763f 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -253,6 +253,12 @@ extern ulint srv_read_ahead_seq;
/* variable to count the number of random read-aheads were done */
extern ulint srv_read_ahead_rnd;
+/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
+NOT update cardinality for indexes of InnoDB table". By default we are
+running with the fix disabled because MySQL 5.1 is frozen for such
+behavioral changes. */
+extern char srv_use_legacy_cardinality_algorithm;
+
/* In this structure we store status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index d0b89e81787..93082560001 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -15,6 +15,8 @@ Created 10/4/1994 Heikki Tuuri
#include "mtr0log.h"
#include "log0recv.h"
#include "rem0cmp.h"
+#include "srv0srv.h"
+#include "ut0ut.h"
static ulint page_rnd = 976722341;
@@ -23,6 +25,44 @@ static ulint page_rnd = 976722341;
ulint page_cur_short_succ = 0;
# endif /* UNIV_SEARCH_PERF_STAT */
+/***********************************************************************
+This is a linear congruential generator PRNG. Returns a pseudo random
+number between 0 and 2^64-1 inclusive. The formula and the constants
+being used are:
+X[n+1] = (a * X[n] + c) mod m
+where:
+X[0] = ut_usectime()
+a = 1103515245 (3^5 * 5 * 7 * 129749)
+c = 12345 (3 * 5 * 823)
+m = 18446744073709551616 (2^64)
+*/
+#define LCG_a 1103515245
+#define LCG_c 12345
+static
+unsigned long long
+page_cur_lcg_prng()
+/*===============*/
+ /* out: number between 0 and 2^64-1 */
+{
+ static unsigned long long lcg_current = 0;
+ static ibool initialized = FALSE;
+ ulint time_sec;
+ ulint time_ms;
+
+ if (!initialized) {
+ ut_usectime(&time_sec, &time_ms);
+ lcg_current = (unsigned long long) (time_sec * 1000000
+ + time_ms);
+ initialized = TRUE;
+ }
+
+ /* no need to "% 2^64" explicitly because lcg_current is
+ 64 bit and this will be done anyway */
+ lcg_current = LCG_a * lcg_current + LCG_c;
+
+ return(lcg_current);
+}
+
/********************************************************************
Tries a search shortcut based on the last insert. */
UNIV_INLINE
@@ -489,9 +529,13 @@ page_cur_open_on_rnd_user_rec(
return;
}
- page_rnd += 87584577;
+ if (srv_use_legacy_cardinality_algorithm) {
+ page_rnd += 87584577;
- rnd = page_rnd % page_get_n_recs(page);
+ rnd = page_rnd % page_get_n_recs(page);
+ } else {
+ rnd = (ulint) page_cur_lcg_prng() % page_get_n_recs(page);
+ }
rec = page_get_infimum_rec(page);
@@ -1419,3 +1463,30 @@ page_cur_delete_rec(
page_dir_balance_slot(page, cur_slot_no);
}
}
+
+#ifdef UNIV_COMPILE_TEST_FUNCS
+
+/***********************************************************************
+Print the first n numbers, generated by page_cur_lcg_prng() to make sure
+(visually) that it works properly. */
+void
+test_page_cur_lcg_prng(
+/*===================*/
+ int n) /* in: print first n numbers */
+{
+ int i;
+ unsigned long long rnd;
+
+ for (i = 0; i < n; i++) {
+ rnd = page_cur_lcg_prng();
+ printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n",
+ rnd,
+ rnd % 2,
+ rnd % 3,
+ rnd % 5,
+ rnd % 7,
+ rnd % 11);
+ }
+}
+
+#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 6b755ae9816..0974c616db3 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -239,6 +239,12 @@ ulint srv_read_ahead_seq = 0;
/* variable to count the number of random read-aheads */
ulint srv_read_ahead_rnd = 0;
+/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
+NOT update cardinality for indexes of InnoDB table". By default we are
+running with the fix disabled because MySQL 5.1 is frozen for such
+behavioral changes. */
+char srv_use_legacy_cardinality_algorithm = TRUE;
+
/* structure to pass status variables to MySQL */
export_struc export_vars;