diff options
author | Satya B <satya.bn@sun.com> | 2009-04-24 16:33:50 +0530 |
---|---|---|
committer | Satya B <satya.bn@sun.com> | 2009-04-24 16:33:50 +0530 |
commit | 97ae03bf526a0cef7c76739b9a583a0f6209aa7f (patch) | |
tree | dcc3ceab089d019567ded08d48e0f0a3ec090c07 /innobase | |
parent | 4783b2e196e4ed4c037194d74b99922e92deecd0 (diff) | |
download | mariadb-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.h | 6 | ||||
-rw-r--r-- | innobase/page/page0cur.c | 75 | ||||
-rw-r--r-- | innobase/srv/srv0srv.c | 6 |
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; |