diff options
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 9 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 6 | ||||
-rw-r--r-- | storage/innobase/page/page0cur.c | 75 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.c | 6 |
4 files changed, 94 insertions, 2 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d3a60b46dd8..e9c3f62c9dc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8260,6 +8260,14 @@ static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata, "Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)", NULL, NULL, TRUE); +static MYSQL_SYSVAR_BOOL(use_legacy_cardinality_algorithm, + srv_use_legacy_cardinality_algorithm, + PLUGIN_VAR_OPCMDARG, + "Use legacy algorithm for picking random pages during index cardinality " + "estimation. Disable this to use a better algorithm, but note that your " + "query plans may change (enabled by default).", + NULL, NULL, TRUE); + static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, "Enable InnoDB adaptive hash index (enabled by default). " @@ -8395,6 +8403,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(open_files), MYSQL_SYSVAR(rollback_on_timeout), MYSQL_SYSVAR(stats_on_metadata), + MYSQL_SYSVAR(use_legacy_cardinality_algorithm), MYSQL_SYSVAR(adaptive_hash_index), MYSQL_SYSVAR(status_file), MYSQL_SYSVAR(support_xa), diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 2516937565d..9ff3c225eb0 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -235,6 +235,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/storage/innobase/page/page0cur.c b/storage/innobase/page/page0cur.c index a297eb545a0..70b7de194fd 100644 --- a/storage/innobase/page/page0cur.c +++ b/storage/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 @@ -493,9 +533,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); @@ -1437,3 +1481,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/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index e2d8bd4c600..b8b63052394 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -256,6 +256,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; |