summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Lindström <jplindst@mariadb.org>2014-11-25 08:31:03 +0200
committerJan Lindström <jplindst@mariadb.org>2014-11-25 08:31:03 +0200
commitb62c4c6586435ed0b1428145acac5e648d63f8bb (patch)
tree7eb78c1d4511083a9f15557bec001ead3991b901
parent77a6abf31141f227202c78e88c7989e5946fa470 (diff)
parente5802c38f9fc9329276ac9096c10a8176a283cf9 (diff)
downloadmariadb-git-b62c4c6586435ed0b1428145acac5e648d63f8bb.tar.gz
Better comments and add a test case.
-rw-r--r--mysql-test/suite/innodb/r/innodb-stats-sample.result4
-rw-r--r--mysql-test/suite/innodb/t/innodb-stats-sample.test78
-rw-r--r--storage/innobase/btr/btr0cur.cc19
-rw-r--r--storage/xtradb/btr/btr0cur.cc20
4 files changed, 109 insertions, 12 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-stats-sample.result b/mysql-test/suite/innodb/r/innodb-stats-sample.result
new file mode 100644
index 00000000000..a049a1d82c1
--- /dev/null
+++ b/mysql-test/suite/innodb/r/innodb-stats-sample.result
@@ -0,0 +1,4 @@
+Variable_name Value
+innodb_stats_sample_pages 1
+Variable_name Value
+innodb_stats_traditional OFF
diff --git a/mysql-test/suite/innodb/t/innodb-stats-sample.test b/mysql-test/suite/innodb/t/innodb-stats-sample.test
new file mode 100644
index 00000000000..35d35bfa382
--- /dev/null
+++ b/mysql-test/suite/innodb/t/innodb-stats-sample.test
@@ -0,0 +1,78 @@
+--source include/have_innodb.inc
+#
+# Test that mysqld does not crash when running ANALYZE TABLE with
+# different values of the parameter innodb_stats_sample_pages.
+#
+
+# we care only that the following SQL commands do not produce errors
+# and do not crash the server
+-- disable_query_log
+-- disable_result_log
+-- enable_warnings
+
+let $sample_pages=`select @@innodb_stats_sample_pages`;
+let $traditional=`select @@innodb_stats_traditional`;
+SET GLOBAL innodb_stats_sample_pages=0;
+#use new method to calculate statistics
+SET GLOBAL innodb_stats_traditional=0;
+
+# check that the value has been adjusted to 1
+-- enable_result_log
+SHOW VARIABLES LIKE 'innodb_stats_sample_pages';
+SHOW VARIABLES LIKE 'innodb_stats_traditional';
+-- disable_result_log
+
+CREATE TABLE innodb_analyze (
+ a INT,
+ b INT,
+ c char(50),
+ KEY(a),
+ KEY(b,a)
+) ENGINE=InnoDB;
+
+# test with empty table
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=2;
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=1;
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=8000;
+ANALYZE TABLE innodb_analyze;
+
+delimiter //;
+create procedure innodb_insert_proc (repeat_count int)
+begin
+ declare current_num int;
+ set current_num = 0;
+ while current_num < repeat_count do
+ insert into innodb_analyze values(current_num, current_num*100,substring(MD5(RAND()), -44));
+ set current_num = current_num + 1;
+ end while;
+end//
+delimiter ;//
+commit;
+
+set autocommit=0;
+call innodb_insert_proc(7000);
+commit;
+set autocommit=1;
+
+SET GLOBAL innodb_stats_sample_pages=1;
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=8;
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=16;
+ANALYZE TABLE innodb_analyze;
+
+SET GLOBAL innodb_stats_sample_pages=8000;
+ANALYZE TABLE innodb_analyze;
+
+DROP PROCEDURE innodb_insert_proc;
+DROP TABLE innodb_analyze;
+EVAL SET GLOBAL innodb_stats_sample_pages=$sample_pages;
+EVAL SET GLOBAL innodb_stats_traditional=$traditional; \ No newline at end of file
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 195b37d6814..ea97468a8f1 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -3904,18 +3904,25 @@ btr_estimate_number_of_different_key_vals(
n_sample_pages = srv_stats_transient_sample_pages;
}
} else {
- /* New logaritmic number of pages that are estimated. We
- first pick minimun from srv_stats_transient_sample_pages and number of
- pages on index. Then we pick maximum from previous number of
- pages and log2(number of index pages) * srv_stats_transient_sample_pages. */
+ /* New logaritmic number of pages that are estimated.
+ Number of pages estimated should be between 1 and
+ index->stat_index_size. We pick index->stat_index_size
+ as maximum and log2(index->stat_index_size)*sr_stats_transient_sample_pages
+ if between range as minimum.*/
if (index->stat_index_size > 0) {
- n_sample_pages = ut_max(ut_min(srv_stats_transient_sample_pages, index->stat_index_size),
- log2(index->stat_index_size)*srv_stats_transient_sample_pages);
+ n_sample_pages = ut_min(index->stat_index_size,
+ ut_max(ut_min(srv_stats_transient_sample_pages,
+ index->stat_index_size),
+ log2(index->stat_index_size)
+ *srv_stats_transient_sample_pages));
} else {
n_sample_pages = 1;
}
}
+ /* Sanity check */
+ ut_ad(n_sample_pages > 0 && n_sample_pages <= (index->stat_index_size <= 1 ? 1 : index->stat_index_size));
+
/* We sample some pages in the index to get an estimate */
for (i = 0; i < n_sample_pages; i++) {
diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc
index 64f813f282d..2bc1a7de13c 100644
--- a/storage/xtradb/btr/btr0cur.cc
+++ b/storage/xtradb/btr/btr0cur.cc
@@ -4095,18 +4095,26 @@ btr_estimate_number_of_different_key_vals(
n_sample_pages = srv_stats_transient_sample_pages;
}
} else {
- /* New logaritmic number of pages that are estimated. We
- first pick minimun from srv_stats_transient_sample_pages and number of
- pages on index. Then we pick maximum from previous number of
- pages and log2(number of index pages) * srv_stats_transient_sample_pages. */
+ /* New logaritmic number of pages that are estimated.
+ Number of pages estimated should be between 1 and
+ index->stat_index_size. We pick index->stat_index_size
+ as maximum and log2(index->stat_index_size)*sr_stats_transient_sample_pages
+ if between range as minimum.*/
+
if (index->stat_index_size > 0) {
- n_sample_pages = ut_max(ut_min(srv_stats_transient_sample_pages, index->stat_index_size),
- log2(index->stat_index_size)*srv_stats_transient_sample_pages);
+ n_sample_pages = ut_min(index->stat_index_size,
+ ut_max(ut_min(srv_stats_transient_sample_pages,
+ index->stat_index_size),
+ log2(index->stat_index_size)
+ *srv_stats_transient_sample_pages));
} else {
n_sample_pages = 1;
}
}
+ /* Sanity check */
+ ut_ad(n_sample_pages > 0 && n_sample_pages <= (index->stat_index_size < 1 ? 1 : index->stat_index_size));
+
/* We sample some pages in the index to get an estimate */
for (i = 0; i < n_sample_pages; i++) {