summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/keycache.h13
-rw-r--r--mysql-test/r/features.result16
-rw-r--r--mysql-test/r/key_cache.result33
-rw-r--r--mysql-test/r/mysqld--help.result6
-rw-r--r--mysql-test/suite/maria/maria3.result1
-rw-r--r--mysql-test/suite/sys_vars/r/aria_pagecache_file_hash_size_basic.result21
-rw-r--r--mysql-test/suite/sys_vars/r/key_cache_file_hash_size_basic.result114
-rw-r--r--mysql-test/suite/sys_vars/t/aria_pagecache_file_hash_size_basic.test22
-rw-r--r--mysql-test/suite/sys_vars/t/key_cache_file_hash_size_basic.test168
-rw-r--r--mysql-test/t/features.test19
-rw-r--r--mysql-test/t/key_cache.test32
-rw-r--r--mysys/mf_keycache.c155
-rw-r--r--sql/handler.cc8
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/mysqld.h1
-rw-r--r--sql/sql_class.h7
-rw-r--r--sql/sys_vars.cc11
-rw-r--r--storage/maria/ha_maria.cc23
-rw-r--r--storage/maria/ma_checkpoint.c2
-rw-r--r--storage/maria/ma_pagecache.c70
-rw-r--r--storage/maria/ma_pagecache.h14
-rw-r--r--storage/maria/ma_rt_test.c4
-rw-r--r--storage/maria/ma_test1.c4
-rw-r--r--storage/maria/ma_test2.c4
-rw-r--r--storage/maria/ma_test3.c2
-rw-r--r--storage/maria/maria_chk.c4
-rw-r--r--storage/maria/maria_ftdump.c2
-rw-r--r--storage/maria/maria_pack.c2
-rw-r--r--storage/maria/maria_read_log.c4
-rw-r--r--storage/maria/unittest/ma_pagecache_consist.c2
-rw-r--r--storage/maria/unittest/ma_pagecache_rwconsist.c2
-rw-r--r--storage/maria/unittest/ma_pagecache_rwconsist2.c2
-rw-r--r--storage/maria/unittest/ma_pagecache_single.c2
-rw-r--r--storage/maria/unittest/ma_test_loghandler-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_first_lsn-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_max_lsn-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multigroup-t.c9
-rw-r--r--storage/maria/unittest/ma_test_loghandler_multithread-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_noflush-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_nologs-t.c9
-rw-r--r--storage/maria/unittest/ma_test_loghandler_pagecache-t.c5
-rw-r--r--storage/maria/unittest/ma_test_loghandler_purge-t.c2
-rw-r--r--storage/myisam/ha_myisam.cc8
-rw-r--r--storage/myisam/mi_check.c2
-rw-r--r--storage/myisam/mi_test1.c2
-rw-r--r--storage/myisam/mi_test2.c7
-rw-r--r--storage/myisam/mi_test3.c2
-rwxr-xr-xstorage/myisam/mi_test_all.sh4
-rw-r--r--storage/myisam/myisam_ftdump.c2
-rw-r--r--storage/myisam/myisamchk.c4
-rw-r--r--storage/myisam/myisamlog.c2
51 files changed, 650 insertions, 208 deletions
diff --git a/include/keycache.h b/include/keycache.h
index 8fa9bf1cd18..85937ebefb9 100644
--- a/include/keycache.h
+++ b/include/keycache.h
@@ -67,11 +67,13 @@ typedef enum key_cache_type
typedef
int (*INIT_KEY_CACHE)
(void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
+ size_t use_mem, uint division_limit, uint age_threshold,
+ uint changed_blocks_hash_size);
typedef
int (*RESIZE_KEY_CACHE)
(void *, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold);
+ size_t use_mem, uint division_limit, uint age_threshold,
+ uint changed_blocks_hash_size);
typedef
void (*CHANGE_KEY_CACHE_PARAM)
(void *keycache_cb,
@@ -146,6 +148,7 @@ typedef struct st_key_cache
ulonglong param_division_limit;/* min. percentage of warm blocks */
ulonglong param_age_threshold; /* determines when hot block is downgraded */
ulonglong param_partitions; /* number of the key cache partitions */
+ ulonglong changed_blocks_hash_size; /* number of hash buckets for changed files */
my_bool key_cache_inited; /* <=> key cache has been created */
my_bool can_be_used; /* usage of cache for read/write is allowed */
my_bool in_init; /* set to 1 in MySQL during init/resize */
@@ -160,10 +163,11 @@ extern KEY_CACHE dflt_key_cache_var, *dflt_key_cache;
extern int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold, uint partitions);
+ uint age_threshold, uint changed_blocks_hash_size,
+ uint partitions);
extern int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold);
+ uint age_threshold, uint changed_blocks_hash_size);
extern void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
uint age_threshold);
extern uchar *key_cache_read(KEY_CACHE *keycache,
@@ -202,6 +206,7 @@ extern int repartition_key_cache(KEY_CACHE *keycache,
size_t use_mem,
uint division_limit,
uint age_threshold,
+ uint changed_blocks_hash_size,
uint partitions);
C_MODE_END
#endif /* _keycache_h */
diff --git a/mysql-test/r/features.result b/mysql-test/r/features.result
index 7b6a352ab0c..66d2c6bf71d 100644
--- a/mysql-test/r/features.result
+++ b/mysql-test/r/features.result
@@ -1,6 +1,8 @@
drop table if exists t1;
+flush status;
show status like "feature%";
Variable_name Value
+Feature_delay_key_write 0
Feature_dynamic_columns 0
Feature_fulltext 0
Feature_gis 0
@@ -138,3 +140,17 @@ upd1
show status like "feature_xml";
Variable_name Value
Feature_xml 2
+#
+# Feature delayed_keys
+#
+create table t1 (a int, key(a)) engine=myisam delay_key_write=1;
+insert into t1 values(1);
+insert into t1 values(2);
+drop table t1;
+create table t1 (a int, key(a)) engine=aria delay_key_write=1;
+insert into t1 values(1);
+insert into t1 values(2);
+drop table t1;
+show status like "feature_delay_key_write";
+Variable_name Value
+Feature_delay_key_write 2
diff --git a/mysql-test/r/key_cache.result b/mysql-test/r/key_cache.result
index fad980c810c..8634beb290f 100644
--- a/mysql-test/r/key_cache.result
+++ b/mysql-test/r/key_cache.result
@@ -2,6 +2,7 @@ drop table if exists t1, t2, t3;
SET @save_key_buffer_size=@@key_buffer_size;
SET @save_key_cache_block_size=@@key_cache_block_size;
SET @save_key_cache_segments=@@key_cache_segments;
+SET @save_key_cache_file_hash_size=@@key_cache_file_hash_size;
SELECT @@key_buffer_size, @@small.key_buffer_size;
@@key_buffer_size @@small.key_buffer_size
2097152 131072
@@ -84,15 +85,15 @@ select @@key_buffer_size;
select @@key_cache_block_size;
@@key_cache_block_size
1024
+select @@key_cache_file_hash_size;
+@@key_cache_file_hash_size
+512
set global keycache1.key_buffer_size=1024*1024;
create table t1 (p int primary key, a char(10)) delay_key_write=1;
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
-show status like 'key_blocks_used';
-Variable_name Value
-Key_blocks_used 0
-show status like 'key_blocks_unused';
-Variable_name Value
-Key_blocks_unused KEY_BLOCKS_UNUSED
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
+key_blocks_unused key_blocks_used
+0 0
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
(3, 1, 'yyyy'), (4, 3, 'zzzz');
@@ -108,12 +109,9 @@ p i a
4 3 zzzz
update t1 set p=2 where p=1;
update t2 set i=2 where i=1;
-show status like 'key_blocks_used';
-Variable_name Value
-Key_blocks_used 4
-show status like 'key_blocks_unused';
-Variable_name Value
-Key_blocks_unused KEY_BLOCKS_UNUSED
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
+key_blocks_unused key_blocks_used
+4 4
cache index t1 key (`primary`) in keycache1;
Table Op Msg_type Msg_text
test.t1 assign_to_keycache status OK
@@ -270,12 +268,9 @@ Table Op Msg_type Msg_text
test.t1 assign_to_keycache status OK
test.t2 assign_to_keycache status OK
drop table t1,t2,t3;
-show status like 'key_blocks_used';
-Variable_name Value
-Key_blocks_used 4
-show status like 'key_blocks_unused';
-Variable_name Value
-Key_blocks_unused KEY_BLOCKS_UNUSED
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
+key_blocks_unused key_blocks_used
+0 4
create table t1 (a int primary key);
cache index t1 in keycache2;
Table Op Msg_type Msg_text
@@ -558,6 +553,7 @@ KEY_CACHE_NAME SEGMENTS SEGMENT_NUMBER FULL_SIZE BLOCK_SIZE USED_BLOCKS UNUSED_B
default 1 NULL 2097152 1024 4 # 0 0 0 0 0
small NULL NULL 1048576 1024 1 # 0 0 0 0 0
set global key_buffer_size=32*1024;
+set global key_cache_file_hash_size=128;
select @@key_buffer_size;
@@key_buffer_size
32768
@@ -833,3 +829,4 @@ set global keycache1.key_buffer_size=0;
set global keycache2.key_buffer_size=0;
set global key_buffer_size=@save_key_buffer_size;
set global key_cache_segments=@save_key_cache_segments;
+set global key_cache_file_hash_size=@save_key_cache_file_hash_size;
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index 32d58304bd4..d39e50a991c 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -281,6 +281,11 @@ The following options may be given as the first argument:
The default size of key cache blocks
--key-cache-division-limit=#
The minimum percentage of warm blocks in key cache
+ --key-cache-file-hash-size=#
+ Number of hash buckets for open and changed files. If
+ you have a lot of MyISAM files open you should increase
+ this for faster flush of changes. A good value is
+ probably 1/10 of number of possible open MyISAM files.
--key-cache-segments=#
The number of segments in a key cache
-L, --language=name Client error messages in given language. May be given as
@@ -1129,6 +1134,7 @@ key-buffer-size 134217728
key-cache-age-threshold 300
key-cache-block-size 1024
key-cache-division-limit 100
+key-cache-file-hash-size 512
key-cache-segments 0
large-pages FALSE
lc-messages en_US
diff --git a/mysql-test/suite/maria/maria3.result b/mysql-test/suite/maria/maria3.result
index 021cc8fc357..74eed530bd9 100644
--- a/mysql-test/suite/maria/maria3.result
+++ b/mysql-test/suite/maria/maria3.result
@@ -314,6 +314,7 @@ aria_max_sort_file_size 9223372036853727232
aria_pagecache_age_threshold 300
aria_pagecache_buffer_size 8388608
aria_pagecache_division_limit 100
+aria_pagecache_file_hash_size 512
aria_page_checksum OFF
aria_recover NORMAL
aria_repair_threads 1
diff --git a/mysql-test/suite/sys_vars/r/aria_pagecache_file_hash_size_basic.result b/mysql-test/suite/sys_vars/r/aria_pagecache_file_hash_size_basic.result
new file mode 100644
index 00000000000..0bdd56c298f
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/aria_pagecache_file_hash_size_basic.result
@@ -0,0 +1,21 @@
+select @@global.aria_pagecache_file_hash_size;
+@@global.aria_pagecache_file_hash_size
+512
+select @@session.aria_pagecache_file_hash_size;
+ERROR HY000: Variable 'aria_pagecache_file_hash_size' is a GLOBAL variable
+show global variables like 'aria_pagecache_file_hash_size';
+Variable_name Value
+aria_pagecache_file_hash_size 512
+show session variables like 'aria_pagecache_file_hash_size';
+Variable_name Value
+aria_pagecache_file_hash_size 512
+select * from information_schema.global_variables where variable_name='aria_pagecache_file_hash_size';
+VARIABLE_NAME VARIABLE_VALUE
+ARIA_PAGECACHE_FILE_HASH_SIZE 512
+select * from information_schema.session_variables where variable_name='aria_pagecache_file_hash_size';
+VARIABLE_NAME VARIABLE_VALUE
+ARIA_PAGECACHE_FILE_HASH_SIZE 512
+set global aria_pagecache_file_hash_size=200;
+ERROR HY000: Variable 'aria_pagecache_file_hash_size' is a read only variable
+set session aria_pagecache_file_hash_size=200;
+ERROR HY000: Variable 'aria_pagecache_file_hash_size' is a read only variable
diff --git a/mysql-test/suite/sys_vars/r/key_cache_file_hash_size_basic.result b/mysql-test/suite/sys_vars/r/key_cache_file_hash_size_basic.result
new file mode 100644
index 00000000000..52ebfc98cdc
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/key_cache_file_hash_size_basic.result
@@ -0,0 +1,114 @@
+SET @start_value = @@global.key_cache_file_hash_size;
+SELECT @start_value;
+@start_value
+512
+'#--------------------FN_DYNVARS_056_01------------------------#'
+SET @@global.key_cache_file_hash_size = DEFAULT;
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+512
+'#---------------------FN_DYNVARS_056_02-------------------------#'
+SET @@global.key_cache_file_hash_size = @start_value;
+SELECT @@global.key_cache_file_hash_size = 300;
+@@global.key_cache_file_hash_size = 300
+0
+'#--------------------FN_DYNVARS_056_03------------------------#'
+SET @@global.key_cache_file_hash_size = 128;
+SET @@global.key_cache_file_hash_size = 16384;
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+16384
+'#--------------------FN_DYNVARS_056_04-------------------------#'
+SET @@global.key_cache_file_hash_size = -1;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '-1'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+SET @@global.key_cache_file_hash_size = 42949672951;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '42949672951'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+16384
+SET @@global.key_cache_file_hash_size = 10000.01;
+ERROR 42000: Incorrect argument type to variable 'key_cache_file_hash_size'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+16384
+SET @@global.key_cache_file_hash_size = -1024;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '-1024'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+SET @@global.key_cache_file_hash_size = 99;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '99'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+SET @@global.key_cache_file_hash_size = ON;
+ERROR 42000: Incorrect argument type to variable 'key_cache_file_hash_size'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+SET @@global.key_cache_file_hash_size = 'test';
+ERROR 42000: Incorrect argument type to variable 'key_cache_file_hash_size'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+'#-------------------FN_DYNVARS_056_05----------------------------#'
+SET @@session.key_cache_file_hash_size = 0;
+ERROR HY000: Variable 'key_cache_file_hash_size' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT @@session.key_cache_file_hash_size;
+ERROR HY000: Variable 'key_cache_file_hash_size' is a GLOBAL variable
+'#----------------------FN_DYNVARS_056_06------------------------#'
+SELECT @@global.key_cache_file_hash_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='key_cache_file_hash_size';
+@@global.key_cache_file_hash_size = VARIABLE_VALUE
+1
+SELECT @@key_cache_file_hash_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='key_cache_file_hash_size';
+@@key_cache_file_hash_size = VARIABLE_VALUE
+1
+'#---------------------FN_DYNVARS_056_07----------------------#'
+SET @@global.key_cache_file_hash_size = TRUE;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '1'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+SET @@global.key_cache_file_hash_size = FALSE;
+Warnings:
+Warning 1292 Truncated incorrect key_cache_file_hash_size value: '0'
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+128
+'#---------------------FN_DYNVARS_056_08----------------------#'
+SET @@global.key_cache_file_hash_size = 150;
+SELECT @@key_cache_file_hash_size = @@global.key_cache_file_hash_size;
+@@key_cache_file_hash_size = @@global.key_cache_file_hash_size
+1
+'#---------------------FN_DYNVARS_056_09----------------------#'
+SET key_cache_file_hash_size = 8000;
+ERROR HY000: Variable 'key_cache_file_hash_size' is a GLOBAL variable and should be set with SET GLOBAL
+SELECT @@key_cache_file_hash_size;
+@@key_cache_file_hash_size
+150
+SET local.key_cache_file_hash_size = 10;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key_cache_file_hash_size = 10' at line 1
+SELECT local.key_cache_file_hash_size;
+ERROR 42S02: Unknown table 'local' in field list
+SET global.key_cache_file_hash_size = 10;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'key_cache_file_hash_size = 10' at line 1
+SELECT global.key_cache_file_hash_size;
+ERROR 42S02: Unknown table 'global' in field list
+SELECT key_cache_file_hash_size = @@session.key_cache_file_hash_size;
+ERROR 42S22: Unknown column 'key_cache_file_hash_size' in 'field list'
+SET @@global.key_cache_file_hash_size = @start_value;
+SELECT @@global.key_cache_file_hash_size;
+@@global.key_cache_file_hash_size
+512
diff --git a/mysql-test/suite/sys_vars/t/aria_pagecache_file_hash_size_basic.test b/mysql-test/suite/sys_vars/t/aria_pagecache_file_hash_size_basic.test
new file mode 100644
index 00000000000..8bedb498e2c
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/aria_pagecache_file_hash_size_basic.test
@@ -0,0 +1,22 @@
+# ulong readonly
+
+--source include/have_maria.inc
+#
+# show the global and session values;
+#
+select @@global.aria_pagecache_file_hash_size;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+select @@session.aria_pagecache_file_hash_size;
+show global variables like 'aria_pagecache_file_hash_size';
+show session variables like 'aria_pagecache_file_hash_size';
+select * from information_schema.global_variables where variable_name='aria_pagecache_file_hash_size';
+select * from information_schema.session_variables where variable_name='aria_pagecache_file_hash_size';
+
+#
+# show that it's read-only
+#
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set global aria_pagecache_file_hash_size=200;
+--error ER_INCORRECT_GLOBAL_LOCAL_VAR
+set session aria_pagecache_file_hash_size=200;
+
diff --git a/mysql-test/suite/sys_vars/t/key_cache_file_hash_size_basic.test b/mysql-test/suite/sys_vars/t/key_cache_file_hash_size_basic.test
new file mode 100644
index 00000000000..deebe708d3d
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/key_cache_file_hash_size_basic.test
@@ -0,0 +1,168 @@
+################# mysql-test\t\key_cache_file_hash_size.test ##################
+# #
+# Variable Name: key_cache_file_hash_size #
+# Scope: GLOBAL #
+# Access Type: Dynamic #
+# Data Type: numeric #
+# Default Value: 300 #
+# Range: 100-4294967295 #
+# #
+# #
+# Creation Date: 2008-02-07 #
+# Author: Salman #
+# #
+# Description: Test Cases of Dynamic System Variable key_cache_file_hash_size #
+# that checks the behavior of this variable in the following ways#
+# * Default Value #
+# * Valid & Invalid values #
+# * Scope & Access method #
+# * Data Integrity #
+# #
+# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
+# server-system-variables.html #
+# #
+###############################################################################
+
+--source include/load_sysvars.inc
+
+########################################################################
+# START OF key_cache_file_hash_size TESTS #
+########################################################################
+
+
+#############################################################################
+# Saving initial value of key_cache_file_hash_size in a temporary variable #
+#############################################################################
+
+SET @start_value = @@global.key_cache_file_hash_size;
+SELECT @start_value;
+
+
+--echo '#--------------------FN_DYNVARS_056_01------------------------#'
+################################################################################
+# Display the DEFAULT value of key_cache_file_hash_size #
+################################################################################
+
+SET @@global.key_cache_file_hash_size = DEFAULT;
+SELECT @@global.key_cache_file_hash_size;
+
+
+--echo '#---------------------FN_DYNVARS_056_02-------------------------#'
+###############################################
+# Verify default value of variable #
+###############################################
+
+SET @@global.key_cache_file_hash_size = @start_value;
+SELECT @@global.key_cache_file_hash_size = 300;
+
+
+--echo '#--------------------FN_DYNVARS_056_03------------------------#'
+###############################################################################
+# Change the value of key_cache_file_hash_size to a valid value #
+###############################################################################
+
+SET @@global.key_cache_file_hash_size = 128;
+SET @@global.key_cache_file_hash_size = 16384;
+SELECT @@global.key_cache_file_hash_size;
+
+--echo '#--------------------FN_DYNVARS_056_04-------------------------#'
+###########################################################################
+# Change the value of key_cache_file_hash_size to invalid value #
+###########################################################################
+
+SET @@global.key_cache_file_hash_size = -1;
+SELECT @@global.key_cache_file_hash_size;
+SET @@global.key_cache_file_hash_size = 42949672951;
+SELECT @@global.key_cache_file_hash_size;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.key_cache_file_hash_size = 10000.01;
+SELECT @@global.key_cache_file_hash_size;
+SET @@global.key_cache_file_hash_size = -1024;
+SELECT @@global.key_cache_file_hash_size;
+SET @@global.key_cache_file_hash_size = 99;
+SELECT @@global.key_cache_file_hash_size;
+
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.key_cache_file_hash_size = ON;
+SELECT @@global.key_cache_file_hash_size;
+--Error ER_WRONG_TYPE_FOR_VAR
+SET @@global.key_cache_file_hash_size = 'test';
+SELECT @@global.key_cache_file_hash_size;
+
+
+--echo '#-------------------FN_DYNVARS_056_05----------------------------#'
+###########################################################################
+# Test if accessing session key_cache_file_hash_size gives error #
+###########################################################################
+
+--Error ER_GLOBAL_VARIABLE
+SET @@session.key_cache_file_hash_size = 0;
+--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
+SELECT @@session.key_cache_file_hash_size;
+
+
+--echo '#----------------------FN_DYNVARS_056_06------------------------#'
+##############################################################################
+# Check if the value in GLOBAL & SESSION Tables matches values in variable #
+##############################################################################
+
+SELECT @@global.key_cache_file_hash_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
+WHERE VARIABLE_NAME='key_cache_file_hash_size';
+
+SELECT @@key_cache_file_hash_size = VARIABLE_VALUE
+FROM INFORMATION_SCHEMA.SESSION_VARIABLES
+WHERE VARIABLE_NAME='key_cache_file_hash_size';
+
+
+--echo '#---------------------FN_DYNVARS_056_07----------------------#'
+###################################################################
+# Check if TRUE and FALSE values can be used on variable #
+###################################################################
+
+SET @@global.key_cache_file_hash_size = TRUE;
+SELECT @@global.key_cache_file_hash_size;
+SET @@global.key_cache_file_hash_size = FALSE;
+SELECT @@global.key_cache_file_hash_size;
+
+
+--echo '#---------------------FN_DYNVARS_056_08----------------------#'
+########################################################################################################
+# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable #
+########################################################################################################
+
+SET @@global.key_cache_file_hash_size = 150;
+SELECT @@key_cache_file_hash_size = @@global.key_cache_file_hash_size;
+
+
+--echo '#---------------------FN_DYNVARS_056_09----------------------#'
+########################################################################## #######
+# Check if key_cache_file_hash_size can be accessed with and without @@ sign #
+##################################################################################
+
+--Error ER_GLOBAL_VARIABLE
+SET key_cache_file_hash_size = 8000;
+SELECT @@key_cache_file_hash_size;
+--Error ER_PARSE_ERROR
+SET local.key_cache_file_hash_size = 10;
+--Error ER_UNKNOWN_TABLE
+SELECT local.key_cache_file_hash_size;
+--Error ER_PARSE_ERROR
+SET global.key_cache_file_hash_size = 10;
+--Error ER_UNKNOWN_TABLE
+SELECT global.key_cache_file_hash_size;
+--Error ER_BAD_FIELD_ERROR
+SELECT key_cache_file_hash_size = @@session.key_cache_file_hash_size;
+
+
+##############################
+# Restore initial value #
+##############################
+
+SET @@global.key_cache_file_hash_size = @start_value;
+SELECT @@global.key_cache_file_hash_size;
+
+
+########################################################################
+# END OF key_cache_file_hash_size TESTS #
+########################################################################
diff --git a/mysql-test/t/features.test b/mysql-test/t/features.test
index cdfc9413da5..f2ac5a5bba6 100644
--- a/mysql-test/t/features.test
+++ b/mysql-test/t/features.test
@@ -6,6 +6,8 @@
drop table if exists t1;
--enable_warnings
+flush status;
+
show status like "feature%";
--echo #
@@ -109,3 +111,20 @@ select updatexml('<div><div><span>1</span><span>2</span></div></div>',
'/','<tr><td>1</td><td>2</td></tr>') as upd1;
--replace_result 4 2
show status like "feature_xml";
+
+
+--echo #
+--echo # Feature delayed_keys
+--echo #
+
+create table t1 (a int, key(a)) engine=myisam delay_key_write=1;
+insert into t1 values(1);
+insert into t1 values(2);
+drop table t1;
+
+create table t1 (a int, key(a)) engine=aria delay_key_write=1;
+insert into t1 values(1);
+insert into t1 values(2);
+drop table t1;
+
+show status like "feature_delay_key_write";
diff --git a/mysql-test/t/key_cache.test b/mysql-test/t/key_cache.test
index 9098ca466b7..aca7a3ea487 100644
--- a/mysql-test/t/key_cache.test
+++ b/mysql-test/t/key_cache.test
@@ -8,6 +8,7 @@ drop table if exists t1, t2, t3;
SET @save_key_buffer_size=@@key_buffer_size;
SET @save_key_cache_block_size=@@key_cache_block_size;
SET @save_key_cache_segments=@@key_cache_segments;
+SET @save_key_cache_file_hash_size=@@key_cache_file_hash_size;
SELECT @@key_buffer_size, @@small.key_buffer_size;
@@ -62,19 +63,19 @@ select @@keycache1.key_buffer_size;
select @@keycache1.key_cache_block_size;
select @@key_buffer_size;
select @@key_cache_block_size;
+select @@key_cache_file_hash_size;
set global keycache1.key_buffer_size=1024*1024;
+let org_key_blocks_unused=`select unused_blocks as unused from information_schema.key_caches where key_cache_name="default"`;
+--disable_query_log
+eval set @org_key_blocks_unused=$org_key_blocks_unused;
+--enable_query_log
+
create table t1 (p int primary key, a char(10)) delay_key_write=1;
create table t2 (p int primary key, i int, a char(10), key k1(i), key k2(a));
-show status like 'key_blocks_used';
-
-# Following results differs on 64 and 32 bit systems because of different
-# pointer sizes, which takes up different amount of space in key cache
-
---replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
-show status like 'key_blocks_unused';
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
@@ -85,9 +86,7 @@ select * from t2;
update t1 set p=2 where p=1;
update t2 set i=2 where i=1;
-show status like 'key_blocks_used';
---replace_result 1808 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1814 KEY_BLOCKS_UNUSED 1820 KEY_BLOCKS_UNUSED
-show status like 'key_blocks_unused';
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
cache index t1 key (`primary`) in keycache1;
@@ -147,9 +146,7 @@ cache index t3 in keycache2;
cache index t1,t2 in default;
drop table t1,t2,t3;
-show status like 'key_blocks_used';
---replace_result 1812 KEY_BLOCKS_UNUSED 1793 KEY_BLOCKS_UNUSED 1674 KEY_BLOCKS_UNUSED 1818 KEY_BLOCKS_UNUSED 1824 KEY_BLOCKS_UNUSED
-show status like 'key_blocks_unused';
+select @org_key_blocks_unused-unused_blocks as key_blocks_unused, used_blocks as key_blocks_used from information_schema.key_caches where key_cache_name="default";
create table t1 (a int primary key);
cache index t1 in keycache2;
@@ -304,7 +301,7 @@ select * from t2;
update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
---replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED
+--replace_result 1801 KEY_BLOCKS_UNUSED 1663 KEY_BLOCKS_UNUSED 1782 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
select * from information_schema.key_caches where segment_number is null;
@@ -336,7 +333,8 @@ select * from t2;
update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
---replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1788 KEY_BLOCKS_UNUSED
+
+--replace_result 1794 KEY_BLOCKS_UNUSED 1656 KEY_BLOCKS_UNUSED 1775 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
select * from information_schema.key_caches where segment_number is null;
@@ -361,7 +359,7 @@ select * from t2;
update t1 set p=3 where p=1;
update t2 set i=2 where i=1;
---replace_result 1808 KEY_BLOCKS_UNUSED 1670 KEY_BLOCKS_UNUSED 1789 KEY_BLOCKS_UNUSED
+--replace_result 1801 KEY_BLOCKS_UNUSED 1663 KEY_BLOCKS_UNUSED 1782 KEY_BLOCKS_UNUSED
show status like 'key_%';
--replace_column 7 #
select * from information_schema.key_caches where segment_number is null;
@@ -378,6 +376,7 @@ select * from information_schema.key_caches where segment_number is null;
# Switch back to 2 segments
set global key_buffer_size=32*1024;
+set global key_cache_file_hash_size=128;
select @@key_buffer_size;
set global key_cache_segments=2;
select @@key_cache_segments;
@@ -536,5 +535,6 @@ set global keycache2.key_buffer_size=0;
set global key_buffer_size=@save_key_buffer_size;
set global key_cache_segments=@save_key_cache_segments;
+set global key_cache_file_hash_size=@save_key_cache_file_hash_size;
# End of 5.2 tests
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c
index d4c4f8c9997..5505693ce2c 100644
--- a/mysys/mf_keycache.c
+++ b/mysys/mf_keycache.c
@@ -149,7 +149,8 @@ typedef struct st_keycache_wqueue
struct st_my_thread_var *last_thread; /* circular list of waiting threads */
} KEYCACHE_WQUEUE;
-#define CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
+/* Default size of hash for changed files */
+#define MIN_CHANGED_BLOCKS_HASH_SIZE 128
/* Control block for a simple (non-partitioned) key cache */
@@ -165,6 +166,7 @@ typedef struct st_simple_key_cache_cb
ulong age_threshold; /* age threshold for hot blocks */
ulonglong keycache_time; /* total number of block link operations */
uint hash_entries; /* max number of entries in the hash table */
+ uint changed_blocks_hash_size; /* Number of hash buckets for file blocks */
int hash_links; /* max number of hash links */
int hash_links_used; /* number of hash links currently used */
int disk_blocks; /* max number of blocks in the cache */
@@ -191,8 +193,8 @@ typedef struct st_simple_key_cache_cb
KEYCACHE_WQUEUE waiting_for_resize_cnt;
KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */
KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */
- BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
- BLOCK_LINK *file_blocks[CHANGED_BLOCKS_HASH]; /* hash for other file bl.*/
+ BLOCK_LINK **changed_blocks; /* hash for dirty file bl.*/
+ BLOCK_LINK **file_blocks; /* hash for other file bl.*/
/* Statistics variables. These are reset in reset_key_cache_counters(). */
ulong global_blocks_changed; /* number of currently dirty blocks */
@@ -331,7 +333,7 @@ static void test_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
#define KEYCACHE_HASH(f, pos) \
((KEYCACHE_BASE_EXPR(f, pos) / keycache->hash_factor) & \
(keycache->hash_entries-1))
-#define FILE_HASH(f) ((uint) (f) & (CHANGED_BLOCKS_HASH-1))
+#define FILE_HASH(f, cache) ((uint) (f) & (cache->changed_blocks_hash_size-1))
#define DEFAULT_KEYCACHE_DEBUG_LOG "keycache_debug.log"
@@ -468,9 +470,10 @@ static inline uint next_power(uint value)
*/
static
-int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold)
+ uint age_threshold, uint changed_blocks_hash_size)
{
ulong blocks, hash_links;
size_t length;
@@ -515,6 +518,11 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
blocks= (ulong) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) +
sizeof(HASH_LINK*) * 5/4 + key_cache_block_size));
+
+ /* Changed blocks hash needs to be a power of 2 */
+ changed_blocks_hash_size= my_round_up_to_next_power(MY_MAX(changed_blocks_hash_size,
+ MIN_CHANGED_BLOCKS_HASH_SIZE));
+
/* It doesn't make sense to have too few blocks (less than 8) */
if (blocks >= 8)
{
@@ -531,8 +539,9 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
while ((length= (ALIGN_SIZE(blocks * sizeof(BLOCK_LINK)) +
ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
ALIGN_SIZE(sizeof(HASH_LINK*) *
- keycache->hash_entries))) +
- ((size_t) blocks * keycache->key_cache_block_size) > use_mem)
+ keycache->hash_entries) +
+ sizeof(BLOCK_LINK*)* (changed_blocks_hash_size*2))) +
+ ((size_t) blocks * keycache->key_cache_block_size) > use_mem && blocks > 8)
blocks--;
/* Allocate memory for cache page buffers */
if ((keycache->block_mem=
@@ -543,8 +552,17 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated
*/
- if ((keycache->block_root= (BLOCK_LINK*) my_malloc(length,
- MYF(0))))
+ if (my_multi_malloc(MYF(MY_ZEROFILL),
+ &keycache->block_root, blocks * sizeof(BLOCK_LINK),
+ &keycache->hash_root,
+ sizeof(HASH_LINK*) * keycache->hash_entries,
+ &keycache->hash_link_root,
+ hash_links * sizeof(HASH_LINK),
+ &keycache->changed_blocks,
+ sizeof(BLOCK_LINK*) * changed_blocks_hash_size,
+ &keycache->file_blocks,
+ sizeof(BLOCK_LINK*) * changed_blocks_hash_size,
+ NullS))
break;
my_large_free(keycache->block_mem);
keycache->block_mem= 0;
@@ -561,17 +579,6 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
keycache->blocks_unused= blocks;
keycache->disk_blocks= (int) blocks;
keycache->hash_links= hash_links;
- keycache->hash_root= (HASH_LINK**) ((char*) keycache->block_root +
- ALIGN_SIZE(blocks*sizeof(BLOCK_LINK)));
- keycache->hash_link_root= (HASH_LINK*) ((char*) keycache->hash_root +
- ALIGN_SIZE((sizeof(HASH_LINK*) *
- keycache->hash_entries)));
- bzero((uchar*) keycache->block_root,
- keycache->disk_blocks * sizeof(BLOCK_LINK));
- bzero((uchar*) keycache->hash_root,
- keycache->hash_entries * sizeof(HASH_LINK*));
- bzero((uchar*) keycache->hash_link_root,
- keycache->hash_links * sizeof(HASH_LINK));
keycache->hash_links_used= 0;
keycache->free_hash_list= NULL;
keycache->blocks_used= keycache->blocks_changed= 0;
@@ -591,7 +598,7 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
keycache->age_threshold= (age_threshold ?
blocks * age_threshold / 100 :
blocks);
-
+ keycache->changed_blocks_hash_size= changed_blocks_hash_size;
keycache->can_be_used= 1;
keycache->waiting_for_hash_link.last_thread= NULL;
@@ -602,10 +609,6 @@ int init_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_si
keycache->disk_blocks, (long) keycache->block_root,
keycache->hash_entries, (long) keycache->hash_root,
keycache->hash_links, (long) keycache->hash_link_root));
- bzero((uchar*) keycache->changed_blocks,
- sizeof(keycache->changed_blocks[0]) * CHANGED_BLOCKS_HASH);
- bzero((uchar*) keycache->file_blocks,
- sizeof(keycache->file_blocks[0]) * CHANGED_BLOCKS_HASH);
}
else
{
@@ -832,9 +835,10 @@ void finish_resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
*/
static
-int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_size,
+int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache,
+ uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold)
+ uint age_threshold, uint changed_blocks_hash_size)
{
int blocks= 0;
DBUG_ENTER("resize_simple_key_cache");
@@ -852,7 +856,8 @@ int resize_simple_key_cache(SIMPLE_KEY_CACHE_CB *keycache, uint key_cache_block_
/* The following will work even if use_mem is 0 */
blocks= init_simple_key_cache(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold);
+ division_limit, age_threshold,
+ changed_blocks_hash_size);
finish:
finish_resize_simple_key_cache(keycache, 0);
@@ -1248,7 +1253,7 @@ static void link_to_file_list(SIMPLE_KEY_CACHE_CB *keycache,
DBUG_ASSERT(block->hash_link->file == file);
if (unlink_block)
unlink_changed(block);
- link_changed(block, &keycache->file_blocks[FILE_HASH(file)]);
+ link_changed(block, &keycache->file_blocks[FILE_HASH(file, keycache)]);
if (block->status & BLOCK_CHANGED)
{
block->status&= ~BLOCK_CHANGED;
@@ -1289,7 +1294,7 @@ static void link_to_changed_list(SIMPLE_KEY_CACHE_CB *keycache,
unlink_changed(block);
link_changed(block,
- &keycache->changed_blocks[FILE_HASH(block->hash_link->file)]);
+ &keycache->changed_blocks[FILE_HASH(block->hash_link->file, keycache)]);
block->status|=BLOCK_CHANGED;
keycache->blocks_changed++;
keycache->global_blocks_changed++;
@@ -3901,7 +3906,7 @@ static int flush_key_blocks_int(SIMPLE_KEY_CACHE_CB *keycache,
to flush all dirty pages with minimum seek moves
*/
count= 0;
- for (block= keycache->changed_blocks[FILE_HASH(file)] ;
+ for (block= keycache->changed_blocks[FILE_HASH(file, keycache)] ;
block ;
block= block->next_changed)
{
@@ -3934,7 +3939,7 @@ restart:
last_in_flush= NULL;
last_for_update= NULL;
end= (pos= cache)+count;
- for (block= keycache->changed_blocks[FILE_HASH(file)] ;
+ for (block= keycache->changed_blocks[FILE_HASH(file, keycache)] ;
block ;
block= next)
{
@@ -4156,7 +4161,7 @@ restart:
do
{
found= 0;
- for (block= keycache->file_blocks[FILE_HASH(file)] ;
+ for (block= keycache->file_blocks[FILE_HASH(file, keycache)] ;
block ;
block= next)
{
@@ -4397,6 +4402,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
uint total_found;
uint found;
uint idx;
+ uint changed_blocks_hash_size= keycache->changed_blocks_hash_size;
DBUG_ENTER("flush_all_key_blocks");
do
@@ -4412,7 +4418,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
{
found= 0;
/* Step over the whole changed_blocks hash array. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
+ for (idx= 0; idx < changed_blocks_hash_size; idx++)
{
/*
If an array element is non-empty, use the first block from its
@@ -4423,7 +4429,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
same hash bucket, one of them will be flushed per iteration
of the outer loop of phase 1.
*/
- if ((block= keycache->changed_blocks[idx]))
+ while ((block= keycache->changed_blocks[idx]))
{
found++;
/*
@@ -4435,7 +4441,6 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
DBUG_RETURN(1);
}
}
-
} while (found);
/*
@@ -4450,7 +4455,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
{
found= 0;
/* Step over the whole file_blocks hash array. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
+ for (idx= 0; idx < changed_blocks_hash_size; idx++)
{
/*
If an array element is non-empty, use the first block from its
@@ -4460,7 +4465,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
same hash bucket, one of them will be flushed per iteration
of the outer loop of phase 2.
*/
- if ((block= keycache->file_blocks[idx]))
+ while ((block= keycache->file_blocks[idx]))
{
total_found++;
found++;
@@ -4469,7 +4474,6 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
DBUG_RETURN(1);
}
}
-
} while (found);
/*
@@ -4482,7 +4486,7 @@ static int flush_all_key_blocks(SIMPLE_KEY_CACHE_CB *keycache)
#ifndef DBUG_OFF
/* Now there should not exist any block any more. */
- for (idx= 0; idx < CHANGED_BLOCKS_HASH; idx++)
+ for (idx= 0; idx < changed_blocks_hash_size; idx++)
{
DBUG_ASSERT(!keycache->changed_blocks[idx]);
DBUG_ASSERT(!keycache->file_blocks[idx]);
@@ -5028,15 +5032,18 @@ static SIMPLE_KEY_CACHE_CB
age_threshold age threshold (may be zero)
DESCRIPTION
- This function is the implementation of the init_key_cache interface function
- that is employed by partitioned key caches.
- The function builds and initializes an array of simple key caches, and then
- initializes the control block structure of the type PARTITIONED_KEY_CACHE_CB
- that is used for a partitioned key cache. The parameter keycache is
- supposed to point to this structure. The number of partitions in the
- partitioned key cache to be built must be passed through the field
- 'partitions' of this structure. The parameter key_cache_block_size specifies
- the size of the blocks in the the simple key caches to be built.
+ This function is the implementation of the init_key_cache
+ interface function that is employed by partitioned key caches.
+
+ The function builds and initializes an array of simple key caches,
+ and then initializes the control block structure of the type
+ PARTITIONED_KEY_CACHE_CB that is used for a partitioned key
+ cache. The parameter keycache is supposed to point to this
+ structure. The number of partitions in the partitioned key cache
+ to be built must be passed through the field 'partitions' of this
+ structure.
+ The parameter key_cache_block_size specifies the size of the
+ blocks in the the simple key caches to be built.
The parameters division_limit and age_threshold determine the initial
values of those characteristics of the simple key caches that are used for
midpoint insertion strategy. The parameter use_mem specifies the total
@@ -5059,7 +5066,7 @@ static
int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold)
+ uint age_threshold, uint changed_blocks_hash_size)
{
int i;
size_t mem_per_cache;
@@ -5103,7 +5110,8 @@ int init_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
}
cnt= init_simple_key_cache(partition, key_cache_block_size, mem_per_cache,
- division_limit, age_threshold);
+ division_limit, age_threshold,
+ changed_blocks_hash_size);
if (cnt <= 0)
{
end_simple_key_cache(partition, 1);
@@ -5222,7 +5230,8 @@ static
int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold)
+ uint age_threshold,
+ uint changed_blocks_hash_size)
{
uint i;
uint partitions= keycache->partitions;
@@ -5241,7 +5250,8 @@ int resize_partitioned_key_cache(PARTITIONED_KEY_CACHE_CB *keycache,
}
if (!err)
blocks= init_partitioned_key_cache(keycache, key_cache_block_size,
- use_mem, division_limit, age_threshold);
+ use_mem, division_limit, age_threshold,
+ changed_blocks_hash_size);
if (blocks > 0)
{
for (i= 0; i < partitions; i++)
@@ -5816,6 +5826,7 @@ static
int repartition_key_cache_internal(KEY_CACHE *keycache,
uint key_cache_block_size, size_t use_mem,
uint division_limit, uint age_threshold,
+ uint changed_blocks_hash_size,
uint partitions, my_bool use_op_lock);
/*
@@ -5828,8 +5839,11 @@ int repartition_key_cache_internal(KEY_CACHE *keycache,
use_mem total memory to use for cache buffers/structures
division_limit division limit (may be zero)
age_threshold age threshold (may be zero)
- partitions number of partitions in the key cache
- use_op_lock if TRUE use keycache->op_lock, otherwise - ignore it
+ changed_blocks_hash_size Number of hash buckets to hold a link of different
+ files. Should be proportional to number of different
+ files sused.
+ partitions Number of partitions in the key cache
+ use_op_lock if TRUE use keycache->op_lock, otherwise - ignore it
DESCRIPTION
The function performs the actions required from init_key_cache().
@@ -5850,7 +5864,8 @@ int repartition_key_cache_internal(KEY_CACHE *keycache,
static
int init_key_cache_internal(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold, uint partitions,
+ uint age_threshold, uint changed_blocks_hash_size,
+ uint partitions,
my_bool use_op_lock)
{
void *keycache_cb;
@@ -5901,7 +5916,7 @@ int init_key_cache_internal(KEY_CACHE *keycache, uint key_cache_block_size,
keycache->can_be_used= 0;
blocks= keycache->interface_funcs->init(keycache_cb, key_cache_block_size,
use_mem, division_limit,
- age_threshold);
+ age_threshold, changed_blocks_hash_size);
keycache->partitions= partitions ?
((PARTITIONED_KEY_CACHE_CB *) keycache_cb)->partitions :
0;
@@ -5956,10 +5971,12 @@ int init_key_cache_internal(KEY_CACHE *keycache, uint key_cache_block_size,
int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold, uint partitions)
+ uint age_threshold, uint changed_blocks_hash_size,
+ uint partitions)
{
return init_key_cache_internal(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold, partitions, 1);
+ division_limit, age_threshold,
+ changed_blocks_hash_size, partitions, 1);
}
@@ -5998,7 +6015,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
*/
int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
- size_t use_mem, uint division_limit, uint age_threshold)
+ size_t use_mem, uint division_limit, uint age_threshold,
+ uint changed_blocks_hash_size)
{
int blocks= -1;
if (keycache->key_cache_inited)
@@ -6008,6 +6026,7 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
blocks= repartition_key_cache_internal(keycache,
key_cache_block_size, use_mem,
division_limit, age_threshold,
+ changed_blocks_hash_size,
(uint) keycache->param_partitions,
0);
else
@@ -6015,7 +6034,8 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
blocks= keycache->interface_funcs->resize(keycache->keycache_cb,
key_cache_block_size,
use_mem, division_limit,
- age_threshold);
+ age_threshold,
+ changed_blocks_hash_size);
if (keycache->partitions)
keycache->partitions=
@@ -6453,6 +6473,7 @@ static
int repartition_key_cache_internal(KEY_CACHE *keycache,
uint key_cache_block_size, size_t use_mem,
uint division_limit, uint age_threshold,
+ uint changed_blocks_hash_size,
uint partitions, my_bool use_op_lock)
{
uint blocks= -1;
@@ -6462,10 +6483,12 @@ int repartition_key_cache_internal(KEY_CACHE *keycache,
pthread_mutex_lock(&keycache->op_lock);
keycache->interface_funcs->resize(keycache->keycache_cb,
key_cache_block_size, 0,
- division_limit, age_threshold);
+ division_limit, age_threshold,
+ changed_blocks_hash_size);
end_key_cache_internal(keycache, 1, 0);
blocks= init_key_cache_internal(keycache, key_cache_block_size, use_mem,
- division_limit, age_threshold, partitions,
+ division_limit, age_threshold,
+ changed_blocks_hash_size, partitions,
0);
if (use_op_lock)
pthread_mutex_unlock(&keycache->op_lock);
@@ -6510,10 +6533,12 @@ int repartition_key_cache_internal(KEY_CACHE *keycache,
int repartition_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
size_t use_mem, uint division_limit,
- uint age_threshold, uint partitions)
+ uint age_threshold, uint changed_blocks_hash_size,
+ uint partitions)
{
return repartition_key_cache_internal(keycache, key_cache_block_size, use_mem,
division_limit, age_threshold,
+ changed_blocks_hash_size,
partitions, 1);
}
diff --git a/sql/handler.cc b/sql/handler.cc
index ac2512431ad..638723306fb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -4694,11 +4694,13 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache, void *unused
uint division_limit= (uint)key_cache->param_division_limit;
uint age_threshold= (uint)key_cache->param_age_threshold;
uint partitions= (uint)key_cache->param_partitions;
+ uint changed_blocks_hash_size= (uint)key_cache->changed_blocks_hash_size;
mysql_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(!init_key_cache(key_cache,
tmp_block_size,
tmp_buff_size,
division_limit, age_threshold,
+ changed_blocks_hash_size,
partitions));
}
DBUG_RETURN(0);
@@ -4719,10 +4721,12 @@ int ha_resize_key_cache(KEY_CACHE *key_cache)
long tmp_block_size= (long) key_cache->param_block_size;
uint division_limit= (uint)key_cache->param_division_limit;
uint age_threshold= (uint)key_cache->param_age_threshold;
+ uint changed_blocks_hash_size= (uint)key_cache->changed_blocks_hash_size;
mysql_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(!resize_key_cache(key_cache, tmp_block_size,
tmp_buff_size,
- division_limit, age_threshold));
+ division_limit, age_threshold,
+ changed_blocks_hash_size));
}
DBUG_RETURN(0);
}
@@ -4762,10 +4766,12 @@ int ha_repartition_key_cache(KEY_CACHE *key_cache)
uint division_limit= (uint)key_cache->param_division_limit;
uint age_threshold= (uint)key_cache->param_age_threshold;
uint partitions= (uint)key_cache->param_partitions;
+ uint changed_blocks_hash_size= (uint)key_cache->changed_blocks_hash_size;
mysql_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(!repartition_key_cache(key_cache, tmp_block_size,
tmp_buff_size,
division_limit, age_threshold,
+ changed_blocks_hash_size,
partitions));
}
DBUG_RETURN(0);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 431009110b8..e66b4896070 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -517,6 +517,7 @@ ulong binlog_stmt_cache_use= 0, binlog_stmt_cache_disk_use= 0;
ulong max_connections, max_connect_errors;
ulong extra_max_connections;
ulong slave_retried_transactions;
+ulong feature_files_opened_with_delayed_keys;
ulonglong denied_connections;
my_decimal decimal_zero;
@@ -7820,6 +7821,7 @@ SHOW_VAR status_vars[]= {
{"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS},
{"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS},
{"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS},
+ {"Feature_delay_key_write", (char*) &feature_files_opened_with_delayed_keys, SHOW_LONG },
{"Flush_commands", (char*) &show_flush_commands, SHOW_SIMPLE_FUNC},
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
@@ -8693,6 +8695,7 @@ mysql_getopt_value(const char *name, uint length,
case OPT_KEY_CACHE_DIVISION_LIMIT:
case OPT_KEY_CACHE_AGE_THRESHOLD:
case OPT_KEY_CACHE_PARTITIONS:
+ case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
{
KEY_CACHE *key_cache;
if (!(key_cache= get_or_create_key_cache(name, length)))
@@ -8712,6 +8715,8 @@ mysql_getopt_value(const char *name, uint length,
return &key_cache->param_age_threshold;
case OPT_KEY_CACHE_PARTITIONS:
return (uchar**) &key_cache->param_partitions;
+ case OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE:
+ return (uchar**) &key_cache->changed_blocks_hash_size;
}
}
case OPT_REPLICATE_DO_DB:
diff --git a/sql/mysqld.h b/sql/mysqld.h
index 6f7938443c5..a1ed4bdc716 100644
--- a/sql/mysqld.h
+++ b/sql/mysqld.h
@@ -568,6 +568,7 @@ enum options_mysqld
OPT_KEY_CACHE_BLOCK_SIZE,
OPT_KEY_CACHE_DIVISION_LIMIT,
OPT_KEY_CACHE_PARTITIONS,
+ OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE,
OPT_LOG_BASENAME,
OPT_LOG_ERROR,
OPT_LOWER_CASE_TABLE_NAMES,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 68c9f802171..40a24b5cd7f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -758,6 +758,13 @@ typedef struct system_status_var
#define last_system_status_var questions
#define last_cleared_system_status_var memory_used
+/*
+ Global status variables
+*/
+
+extern ulong feature_files_opened_with_delayed_keys;
+
+
void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var);
void add_diff_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var,
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index befea02b5ba..24e64ed5756 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -1060,6 +1060,17 @@ static Sys_var_keycache Sys_key_cache_age_threshold(
BLOCK_SIZE(100), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
ON_UPDATE(change_keycache_param));
+static Sys_var_keycache Sys_key_cache_file_hash_size(
+ "key_cache_file_hash_size",
+ "Number of hash buckets for open and changed files. If you have a lot of MyISAM "
+ "files open you should increase this for faster flush of changes. A good "
+ "value is probably 1/10 of number of possible open MyISAM files.",
+ KEYCACHE_VAR(changed_blocks_hash_size),
+ CMD_LINE(REQUIRED_ARG, OPT_KEY_CACHE_CHANGED_BLOCKS_HASH_SIZE),
+ VALID_RANGE(128, 16384), DEFAULT(512),
+ BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(resize_keycache));
+
static Sys_var_mybool Sys_large_files_support(
"large_files_support",
"Whether mysqld was compiled with options for large file support",
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 081e90f89f7..fd98166a19f 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -57,7 +57,7 @@ C_MODE_END
#endif
#define THD_TRN (*(TRN **)thd_ha_data(thd, maria_hton))
-ulong pagecache_division_limit, pagecache_age_threshold;
+ulong pagecache_division_limit, pagecache_age_threshold, pagecache_file_hash_size;
ulonglong pagecache_buffer_size;
const char *zerofill_error_msg=
"Table is from another system and must be zerofilled or repaired to be "
@@ -250,6 +250,13 @@ static MYSQL_SYSVAR_ULONG(pagecache_division_limit, pagecache_division_limit,
"The minimum percentage of warm blocks in key cache", 0, 0,
100, 1, 100, 1);
+static MYSQL_SYSVAR_ULONG(pagecache_file_hash_size, pagecache_file_hash_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "Number of hash buckets for open and changed files. If you have a lot of Aria "
+ "files open you should increase this for faster flush of changes. A good "
+ "value is probably 1/10 of number of possible open Aria files.", 0,0,
+ 512, 128, 16384, 1);
+
static MYSQL_SYSVAR_SET(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG,
"Specifies how corrupted tables should be automatically repaired."
" Possible values are one or more of \"NORMAL\" (the default), "
@@ -1236,6 +1243,14 @@ int ha_maria::open(const char *name, int mode, uint test_if_locked)
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
}
my_errno= 0;
+
+ /* Count statistics of usage for newly open normal files */
+ if (file->s->reopen == 1 && ! (test_if_locked & HA_OPEN_TMP_TABLE))
+ {
+ if (file->s->delay_key_write)
+ feature_files_opened_with_delayed_keys++;
+ }
+
return my_errno;
}
@@ -3520,10 +3535,11 @@ static int ha_maria_init(void *p)
mark_recovery_start(log_dir)) ||
!init_pagecache(maria_pagecache,
(size_t) pagecache_buffer_size, pagecache_division_limit,
- pagecache_age_threshold, maria_block_size, 0) ||
+ pagecache_age_threshold, maria_block_size, pagecache_file_hash_size,
+ 0) ||
!init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, 0) ||
+ TRANSLOG_PAGE_SIZE, 0, 0) ||
translog_init(maria_data_root, log_file_size,
MYSQL_VERSION_ID, server_id, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0) ||
@@ -3639,6 +3655,7 @@ struct st_mysql_sys_var* system_variables[]= {
MYSQL_SYSVAR(pagecache_age_threshold),
MYSQL_SYSVAR(pagecache_buffer_size),
MYSQL_SYSVAR(pagecache_division_limit),
+ MYSQL_SYSVAR(pagecache_file_hash_size),
MYSQL_SYSVAR(recover),
MYSQL_SYSVAR(repair_threads),
MYSQL_SYSVAR(sort_buffer_size),
diff --git a/storage/maria/ma_checkpoint.c b/storage/maria/ma_checkpoint.c
index e4adf5fbccd..de8a9610a64 100644
--- a/storage/maria/ma_checkpoint.c
+++ b/storage/maria/ma_checkpoint.c
@@ -230,7 +230,7 @@ static int really_execute_checkpoint(void)
sizeof(checkpoint_start_log_horizon_char);
for (i= 0; i < (sizeof(record_pieces)/sizeof(record_pieces[0])); i++)
{
- log_array[TRANSLOG_INTERNAL_PARTS + 1 + i].str= record_pieces[i].str;
+ log_array[TRANSLOG_INTERNAL_PARTS + 1 + i].str= (uchar*) record_pieces[i].str;
log_array[TRANSLOG_INTERNAL_PARTS + 1 + i].length= record_pieces[i].length;
total_rec_length+= (translog_size_t) record_pieces[i].length;
}
diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c
index 8e8ecf945f0..bb085bbdc7a 100644
--- a/storage/maria/ma_pagecache.c
+++ b/storage/maria/ma_pagecache.c
@@ -502,7 +502,7 @@ static void test_key_cache(PAGECACHE *pagecache,
#define PAGECACHE_HASH(p, f, pos) (((ulong) (pos) + \
(ulong) (f).file) & (p->hash_entries-1))
-#define FILE_HASH(f) ((uint) (f).file & (PAGECACHE_CHANGED_BLOCKS_HASH - 1))
+#define FILE_HASH(f,cache) ((uint) (f).file & (cache->changed_blocks_hash_size-1))
#define DEFAULT_PAGECACHE_DEBUG_LOG "pagecache_debug.log"
@@ -743,7 +743,8 @@ static inline uint next_power(uint value)
ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
uint division_limit, uint age_threshold,
- uint block_size, myf my_readwrite_flags)
+ uint block_size, uint changed_blocks_hash_size,
+ myf my_readwrite_flags)
{
ulong blocks, hash_links, length;
int error;
@@ -786,6 +787,10 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
2 * sizeof(PAGECACHE_HASH_LINK) +
sizeof(PAGECACHE_HASH_LINK*) *
5/4 + block_size));
+ /* Changed blocks hash needs to be a power of 2 */
+ changed_blocks_hash_size= my_round_up_to_next_power(MY_MAX(changed_blocks_hash_size,
+ MIN_PAGECACHE_CHANGED_BLOCKS_HASH_SIZE));
+
/*
We need to support page cache with just one block to be able to do
scanning of rows-in-block files
@@ -809,10 +814,11 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
hash_links= MAX_THREADS + blocks - 1;
#endif
while ((length= (ALIGN_SIZE(blocks * sizeof(PAGECACHE_BLOCK_LINK)) +
- ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) +
ALIGN_SIZE(sizeof(PAGECACHE_HASH_LINK*) *
- pagecache->hash_entries))) +
- (blocks << pagecache->shift) > use_mem)
+ pagecache->hash_entries) +
+ ALIGN_SIZE(hash_links * sizeof(PAGECACHE_HASH_LINK)) +
+ sizeof(PAGECACHE_BLOCK_LINK*)* (changed_blocks_hash_size*2))) +
+ (blocks << pagecache->shift) > use_mem && blocks > 8)
blocks--;
/* Allocate memory for cache page buffers */
if ((pagecache->block_mem=
@@ -823,8 +829,17 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
Allocate memory for blocks, hash_links and hash entries;
For each block 2 hash links are allocated
*/
- if ((pagecache->block_root=
- (PAGECACHE_BLOCK_LINK*) my_malloc((size_t) length, MYF(0))))
+ if (my_multi_malloc(MYF(MY_ZEROFILL),
+ &pagecache->block_root, blocks * sizeof(PAGECACHE_BLOCK_LINK),
+ &pagecache->hash_root,
+ sizeof(PAGECACHE_HASH_LINK*) * pagecache->hash_entries,
+ &pagecache->hash_link_root,
+ hash_links * sizeof(PAGECACHE_HASH_LINK),
+ &pagecache->changed_blocks,
+ sizeof(PAGECACHE_BLOCK_LINK*) * changed_blocks_hash_size,
+ &pagecache->file_blocks,
+ sizeof(PAGECACHE_BLOCK_LINK*) * changed_blocks_hash_size,
+ NullS))
break;
my_large_free(pagecache->block_mem);
pagecache->block_mem= 0;
@@ -834,19 +849,6 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
pagecache->blocks_unused= blocks;
pagecache->disk_blocks= (long) blocks;
pagecache->hash_links= hash_links;
- pagecache->hash_root=
- (PAGECACHE_HASH_LINK**) ((char*) pagecache->block_root +
- ALIGN_SIZE(blocks*sizeof(PAGECACHE_BLOCK_LINK)));
- pagecache->hash_link_root=
- (PAGECACHE_HASH_LINK*) ((char*) pagecache->hash_root +
- ALIGN_SIZE((sizeof(PAGECACHE_HASH_LINK*) *
- pagecache->hash_entries)));
- bzero((uchar*) pagecache->block_root,
- pagecache->disk_blocks * sizeof(PAGECACHE_BLOCK_LINK));
- bzero((uchar*) pagecache->hash_root,
- pagecache->hash_entries * sizeof(PAGECACHE_HASH_LINK*));
- bzero((uchar*) pagecache->hash_link_root,
- pagecache->hash_links * sizeof(PAGECACHE_HASH_LINK));
pagecache->hash_links_used= 0;
pagecache->free_hash_list= NULL;
pagecache->blocks_used= pagecache->blocks_changed= 0;
@@ -866,6 +868,7 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
pagecache->age_threshold= (age_threshold ?
blocks * age_threshold / 100 :
blocks);
+ pagecache->changed_blocks_hash_size= changed_blocks_hash_size;
pagecache->cnt_for_resize_op= 0;
pagecache->resize_in_flush= 0;
@@ -879,12 +882,6 @@ ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
pagecache->disk_blocks, (long) pagecache->block_root,
pagecache->hash_entries, (long) pagecache->hash_root,
pagecache->hash_links, (long) pagecache->hash_link_root));
- bzero((uchar*) pagecache->changed_blocks,
- sizeof(pagecache->changed_blocks[0]) *
- PAGECACHE_CHANGED_BLOCKS_HASH);
- bzero((uchar*) pagecache->file_blocks,
- sizeof(pagecache->file_blocks[0]) *
- PAGECACHE_CHANGED_BLOCKS_HASH);
pagecache->blocks= pagecache->disk_blocks > 0 ? pagecache->disk_blocks : 0;
DBUG_RETURN((ulong) pagecache->disk_blocks);
@@ -980,12 +977,11 @@ static int flush_all_key_blocks(PAGECACHE *pagecache)
#if NOT_USED /* keep disabled until code is fixed see above !! */
ulong resize_pagecache(PAGECACHE *pagecache,
size_t use_mem, uint division_limit,
- uint age_threshold)
+ uint age_threshold, uint changed_blocks_hash_size)
{
ulong blocks;
struct st_my_thread_var *thread;
WQUEUE *wqueue;
-
DBUG_ENTER("resize_pagecache");
if (!pagecache->inited)
@@ -1028,7 +1024,7 @@ ulong resize_pagecache(PAGECACHE *pagecache,
end_pagecache(pagecache, 0); /* Don't free mutex */
/* The following will work even if use_mem is 0 */
blocks= init_pagecache(pagecache, pagecache->block_size, use_mem,
- division_limit, age_threshold,
+ division_limit, age_threshold, changed_blocks_hash_size,
pagecache->readwrite_flags);
finish:
@@ -1237,7 +1233,7 @@ static void link_to_file_list(PAGECACHE *pagecache,
{
if (unlink_flag)
unlink_changed(block);
- link_changed(block, &pagecache->file_blocks[FILE_HASH(*file)]);
+ link_changed(block, &pagecache->file_blocks[FILE_HASH(*file, pagecache)]);
if (block->status & PCBLOCK_CHANGED)
{
block->status&= ~(PCBLOCK_CHANGED | PCBLOCK_DEL_WRITE);
@@ -1258,7 +1254,7 @@ static inline void link_to_changed_list(PAGECACHE *pagecache,
{
unlink_changed(block);
link_changed(block,
- &pagecache->changed_blocks[FILE_HASH(block->hash_link->file)]);
+ &pagecache->changed_blocks[FILE_HASH(block->hash_link->file, pagecache)]);
block->status|=PCBLOCK_CHANGED;
pagecache->blocks_changed++;
pagecache->global_blocks_changed++;
@@ -4578,7 +4574,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
Count how many key blocks we have to cache to be able
to flush all dirty pages with minimum seek moves.
*/
- for (block= pagecache->changed_blocks[FILE_HASH(*file)] ;
+ for (block= pagecache->changed_blocks[FILE_HASH(*file, pagecache)] ;
block;
block= block->next_changed)
{
@@ -4603,7 +4599,7 @@ static int flush_pagecache_blocks_int(PAGECACHE *pagecache,
/* Retrieve the blocks and write them to a buffer to be flushed */
restart:
end= (pos= cache)+count;
- for (block= pagecache->changed_blocks[FILE_HASH(*file)] ;
+ for (block= pagecache->changed_blocks[FILE_HASH(*file, pagecache)] ;
block;
block= next)
{
@@ -4729,7 +4725,7 @@ restart:
#if defined(PAGECACHE_DEBUG)
cnt=0;
#endif
- for (block= pagecache->file_blocks[FILE_HASH(*file)] ;
+ for (block= pagecache->file_blocks[FILE_HASH(*file, pagecache)] ;
block;
block= next)
{
@@ -4918,7 +4914,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
}
/* Count how many dirty pages are interesting */
- for (file_hash= 0; file_hash < PAGECACHE_CHANGED_BLOCKS_HASH; file_hash++)
+ for (file_hash= 0; file_hash < pagecache->changed_blocks_hash_size; file_hash++)
{
PAGECACHE_BLOCK_LINK *block;
for (block= pagecache->changed_blocks[file_hash] ;
@@ -4957,7 +4953,7 @@ my_bool pagecache_collect_changed_blocks_with_lsn(PAGECACHE *pagecache,
DBUG_PRINT("info", ("found %lu dirty pages", stored_list_size));
if (stored_list_size == 0)
goto end;
- for (file_hash= 0; file_hash < PAGECACHE_CHANGED_BLOCKS_HASH; file_hash++)
+ for (file_hash= 0; file_hash < pagecache->changed_blocks_hash_size; file_hash++)
{
PAGECACHE_BLOCK_LINK *block;
for (block= pagecache->changed_blocks[file_hash] ;
@@ -5008,7 +5004,7 @@ void pagecache_file_no_dirty_page(PAGECACHE *pagecache, PAGECACHE_FILE *file)
{
File fd= file->file;
PAGECACHE_BLOCK_LINK *block;
- for (block= pagecache->changed_blocks[FILE_HASH(*file)];
+ for (block= pagecache->changed_blocks[FILE_HASH(*file, pagecache)];
block != NULL;
block= block->next_changed)
if (block->hash_link->file.file == fd)
diff --git a/storage/maria/ma_pagecache.h b/storage/maria/ma_pagecache.h
index 8460eaddc57..f7ddb2fe716 100644
--- a/storage/maria/ma_pagecache.h
+++ b/storage/maria/ma_pagecache.h
@@ -104,7 +104,9 @@ typedef struct st_pagecache_hash_link PAGECACHE_HASH_LINK;
#include <wqueue.h>
-#define PAGECACHE_CHANGED_BLOCKS_HASH 128 /* must be power of 2 */
+/* Default size of hash for changed files */
+#define MIN_PAGECACHE_CHANGED_BLOCKS_HASH_SIZE 512
+
#define PAGECACHE_PRIORITY_LOW 0
#define PAGECACHE_PRIORITY_DEFAULT 3
#define PAGECACHE_PRIORITY_HIGH 6
@@ -121,6 +123,7 @@ typedef struct st_pagecache
ulong age_threshold; /* age threshold for hot blocks */
ulonglong time; /* total number of block link operations */
ulong hash_entries; /* max number of entries in the hash table */
+ ulong changed_blocks_hash_size; /* Number of hash buckets for file blocks */
long hash_links; /* max number of hash links */
long hash_links_used; /* number of hash links taken from free links pool */
long disk_blocks; /* max number of blocks in the cache */
@@ -145,9 +148,9 @@ typedef struct st_pagecache
WQUEUE waiting_for_hash_link;/* waiting for a free hash link */
WQUEUE waiting_for_block; /* requests waiting for a free block */
/* hash for dirty file bl.*/
- PAGECACHE_BLOCK_LINK *changed_blocks[PAGECACHE_CHANGED_BLOCKS_HASH];
+ PAGECACHE_BLOCK_LINK **changed_blocks;
/* hash for other file bl.*/
- PAGECACHE_BLOCK_LINK *file_blocks[PAGECACHE_CHANGED_BLOCKS_HASH];
+ PAGECACHE_BLOCK_LINK **file_blocks;
/*
The following variables are and variables used to hold parameters for
@@ -195,10 +198,11 @@ extern PAGECACHE dflt_pagecache_var, *dflt_pagecache;
extern ulong init_pagecache(PAGECACHE *pagecache, size_t use_mem,
uint division_limit, uint age_threshold,
- uint block_size, myf my_read_flags);
+ uint block_size, uint changed_blocks_hash_size,
+ myf my_read_flags);
extern ulong resize_pagecache(PAGECACHE *pagecache,
size_t use_mem, uint division_limit,
- uint age_threshold);
+ uint age_threshold, uint changed_blocks_hash_size);
extern void change_pagecache_param(PAGECACHE *pagecache, uint division_limit,
uint age_threshold);
diff --git a/storage/maria/ma_rt_test.c b/storage/maria/ma_rt_test.c
index 29244bab6ce..9d8574212ca 100644
--- a/storage/maria/ma_rt_test.c
+++ b/storage/maria/ma_rt_test.c
@@ -100,11 +100,11 @@ int main(int argc, char *argv[])
/* Maria requires that we always have a page cache */
if (maria_init() ||
(init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0,
- maria_block_size, MY_WME) == 0) ||
+ maria_block_size, 0, MY_WME) == 0) ||
ma_control_file_open(TRUE, TRUE) ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
+ TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0) ||
diff --git a/storage/maria/ma_test1.c b/storage/maria/ma_test1.c
index 595b87ef4d0..901a7ef06e3 100644
--- a/storage/maria/ma_test1.c
+++ b/storage/maria/ma_test1.c
@@ -79,11 +79,11 @@ int main(int argc,char *argv[])
/* Maria requires that we always have a page cache */
if (maria_init() ||
(init_pagecache(maria_pagecache, maria_block_size * 16, 0, 0,
- maria_block_size, MY_WME) == 0) ||
+ maria_block_size, 0, MY_WME) == 0) ||
ma_control_file_open(TRUE, TRUE) ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
+ TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0) ||
diff --git a/storage/maria/ma_test2.c b/storage/maria/ma_test2.c
index 52c0839cff6..709a190c1a7 100644
--- a/storage/maria/ma_test2.c
+++ b/storage/maria/ma_test2.c
@@ -91,11 +91,11 @@ int main(int argc, char *argv[])
/* Maria requires that we always have a page cache */
if (maria_init() ||
(init_pagecache(maria_pagecache, pagecache_size, 0, 0,
- maria_block_size, MY_WME) == 0) ||
+ maria_block_size, 0, MY_WME) == 0) ||
ma_control_file_open(TRUE, TRUE) ||
(init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, MY_WME) == 0) ||
+ TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0) ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0) ||
diff --git a/storage/maria/ma_test3.c b/storage/maria/ma_test3.c
index 64b22e45c1b..5d57bef8f9e 100644
--- a/storage/maria/ma_test3.c
+++ b/storage/maria/ma_test3.c
@@ -178,7 +178,7 @@ void start_test(int id)
exit(1);
}
if (pagecacheing && rnd(2) == 0)
- init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH,
+ init_pagecache(maria_pagecache, 65536L, 0, 0, MARIA_KEY_BLOCK_LENGTH, 0,
MY_WME);
printf("Process %d, pid: %ld\n",id,(long) getpid()); fflush(stdout);
diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c
index 9235d5ee96a..2ea647ea1f5 100644
--- a/storage/maria/maria_chk.c
+++ b/storage/maria/maria_chk.c
@@ -140,7 +140,7 @@ int main(int argc, char **argv)
{
if (init_pagecache(maria_log_pagecache,
TRANSLOG_PAGECACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
+ TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0 ||
translog_init(opt_log_dir, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache,
TRANSLOG_DEFAULT_FLAGS, 0))
@@ -1178,7 +1178,7 @@ static int maria_chk(HA_CHECK *param, char *filename)
maria_lock_database(info, F_EXTRA_LCK);
datafile= info->dfile.file;
if (init_pagecache(maria_pagecache, (size_t) param->use_buffers, 0, 0,
- maria_block_size, MY_WME) == 0)
+ maria_block_size, 0, MY_WME) == 0)
{
_ma_check_print_error(param, "Can't initialize page cache with %lu memory",
(ulong) param->use_buffers);
diff --git a/storage/maria/maria_ftdump.c b/storage/maria/maria_ftdump.c
index 68e13a8ddc4..4e34678c8f8 100644
--- a/storage/maria/maria_ftdump.c
+++ b/storage/maria/maria_ftdump.c
@@ -85,7 +85,7 @@ int main(int argc,char *argv[])
}
init_pagecache(maria_pagecache, PAGE_BUFFER_INIT, 0, 0,
- MARIA_KEY_BLOCK_LENGTH, MY_WME);
+ MARIA_KEY_BLOCK_LENGTH, 0, MY_WME);
if (!(info=maria_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))
diff --git a/storage/maria/maria_pack.c b/storage/maria/maria_pack.c
index 26d57ade59a..7eca9e14e93 100644
--- a/storage/maria/maria_pack.c
+++ b/storage/maria/maria_pack.c
@@ -511,7 +511,7 @@ static int compress(PACK_MRG_INFO *mrg,char *result_table)
fn_format(org_name,isam_file->s->open_file_name.str, "",MARIA_NAME_DEXT, 2+4+16);
if (init_pagecache(maria_pagecache, MARIA_MIN_PAGE_CACHE_SIZE, 0, 0,
- maria_block_size, MY_WME) == 0)
+ maria_block_size, 0, MY_WME) == 0)
{
fprintf(stderr, "Can't initialize page cache\n");
goto err;
diff --git a/storage/maria/maria_read_log.c b/storage/maria/maria_read_log.c
index f5b91f9628f..8fa6533bc46 100644
--- a/storage/maria/maria_read_log.c
+++ b/storage/maria/maria_read_log.c
@@ -70,7 +70,7 @@ int main(int argc, char **argv)
goto err;
}
if (init_pagecache(maria_pagecache, opt_page_buffer_size, 0, 0,
- maria_block_size, MY_WME) == 0)
+ maria_block_size, 0, MY_WME) == 0)
{
fprintf(stderr, "Got error in init_pagecache() (errno: %d)\n", errno);
goto err;
@@ -82,7 +82,7 @@ int main(int argc, char **argv)
which is useless. TODO: start log handler in read-only mode.
*/
if (init_pagecache(maria_log_pagecache, opt_translog_buffer_size,
- 0, 0, TRANSLOG_PAGE_SIZE, MY_WME) == 0 ||
+ 0, 0, TRANSLOG_PAGE_SIZE, 0, MY_WME) == 0 ||
translog_init(maria_data_root, TRANSLOG_FILE_SIZE,
0, 0, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS,
opt_display_only))
diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c
index 6a25a47591c..5f0e25b5bf4 100644
--- a/storage/maria/unittest/ma_pagecache_consist.c
+++ b/storage/maria/unittest/ma_pagecache_consist.c
@@ -431,7 +431,7 @@ int main(int argc __attribute__((unused)),
#endif
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TEST_PAGE_SIZE, 0)) == 0)
+ TEST_PAGE_SIZE, 0, 0)) == 0)
{
diag("Got error: init_pagecache() (errno: %d)\n",
errno);
diff --git a/storage/maria/unittest/ma_pagecache_rwconsist.c b/storage/maria/unittest/ma_pagecache_rwconsist.c
index 7afdbfd0ac1..1a268db6ad5 100644
--- a/storage/maria/unittest/ma_pagecache_rwconsist.c
+++ b/storage/maria/unittest/ma_pagecache_rwconsist.c
@@ -301,7 +301,7 @@ int main(int argc __attribute__((unused)),
#endif
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TEST_PAGE_SIZE, 0)) == 0)
+ TEST_PAGE_SIZE, 0, 0)) == 0)
{
diag("Got error: init_pagecache() (errno: %d)\n",
errno);
diff --git a/storage/maria/unittest/ma_pagecache_rwconsist2.c b/storage/maria/unittest/ma_pagecache_rwconsist2.c
index 917fddd0bcf..751c045a879 100644
--- a/storage/maria/unittest/ma_pagecache_rwconsist2.c
+++ b/storage/maria/unittest/ma_pagecache_rwconsist2.c
@@ -297,7 +297,7 @@ int main(int argc __attribute__((unused)),
#endif
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TEST_PAGE_SIZE, 0)) == 0)
+ TEST_PAGE_SIZE, 0, 0)) == 0)
{
diag("Got error: init_pagecache() (errno: %d)\n",
errno);
diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c
index 0031582589e..64f6782f20f 100644
--- a/storage/maria/unittest/ma_pagecache_single.c
+++ b/storage/maria/unittest/ma_pagecache_single.c
@@ -828,7 +828,7 @@ int main(int argc __attribute__((unused)),
#endif
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TEST_PAGE_SIZE, MYF(MY_WME))) == 0)
+ TEST_PAGE_SIZE, 0, MYF(MY_WME))) == 0)
{
fprintf(stderr,"Got error: init_pagecache() (errno: %d)\n",
errno);
diff --git a/storage/maria/unittest/ma_test_loghandler-t.c b/storage/maria/unittest/ma_test_loghandler-t.c
index abf2078ce8f..18650fa400d 100644
--- a/storage/maria/unittest/ma_test_loghandler-t.c
+++ b/storage/maria/unittest/ma_test_loghandler-t.c
@@ -147,7 +147,6 @@ int main(int argc __attribute__((unused)), char *argv[])
{
uint32 i;
uint32 rec_len;
- uint pagen;
uchar long_tr_id[6];
uchar lsn_buff[23]=
{
@@ -203,8 +202,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ TRANSLOG_PAGE_SIZE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c
index 9ebd56c754c..cf86b59da45 100644
--- a/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_first_lsn-t.c
@@ -35,7 +35,6 @@ static const char *default_dbug_option;
int main(int argc __attribute__((unused)), char *argv[])
{
- uint pagen;
uchar long_tr_id[6];
PAGECACHE pagecache;
LSN lsn, first_lsn, theor_lsn;
@@ -72,8 +71,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c
index 4ae9def8598..855135451c3 100644
--- a/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_max_lsn-t.c
@@ -36,7 +36,6 @@ static const char *default_dbug_option;
int main(int argc __attribute__((unused)), char *argv[])
{
ulong i;
- uint pagen;
uchar long_tr_id[6];
PAGECACHE pagecache;
LSN lsn, max_lsn, last_lsn= LSN_IMPOSSIBLE;
@@ -70,8 +69,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
index c8e63cb26ab..63d1f1c6977 100644
--- a/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_multigroup-t.c
@@ -226,7 +226,6 @@ int main(int argc __attribute__((unused)), char *argv[])
{
uint32 i;
uint32 rec_len;
- uint pagen;
uchar long_tr_id[6];
uchar lsn_buff[23]=
{
@@ -284,8 +283,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ TRANSLOG_PAGE_SIZE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
@@ -447,8 +446,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "pass2: Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ TRANSLOG_PAGE_SIZE, 0, 0) == 0)
{
fprintf(stderr, "pass2: Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c
index 18fbaeace5a..535f363048b 100644
--- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c
@@ -261,7 +261,6 @@ int main(int argc __attribute__((unused)),
char **argv __attribute__ ((unused)))
{
uint32 i;
- uint pagen;
PAGECACHE pagecache;
LSN first_lsn;
TRANSLOG_HEADER_BUFFER rec;
@@ -341,8 +340,8 @@ int main(int argc __attribute__((unused)),
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- TRANSLOG_PAGE_SIZE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ TRANSLOG_PAGE_SIZE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_noflush-t.c b/storage/maria/unittest/ma_test_loghandler_noflush-t.c
index c8c0f7d1873..8d0af947574 100644
--- a/storage/maria/unittest/ma_test_loghandler_noflush-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_noflush-t.c
@@ -34,7 +34,6 @@ static const char *default_dbug_option;
int main(int argc __attribute__((unused)), char *argv[])
{
- uint pagen;
int rc= 1;
uchar long_tr_id[6];
PAGECACHE pagecache;
@@ -71,8 +70,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_nologs-t.c b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
index 24c93e428e1..5d6db7355c2 100644
--- a/storage/maria/unittest/ma_test_loghandler_nologs-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_nologs-t.c
@@ -36,7 +36,6 @@ static const char *default_dbug_option;
int main(int argc __attribute__((unused)), char *argv[])
{
ulong i;
- uint pagen;
uchar long_tr_id[6];
PAGECACHE pagecache;
LSN lsn;
@@ -72,8 +71,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
@@ -145,8 +144,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c
index a939cef71a7..e634506628a 100644
--- a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c
@@ -64,7 +64,6 @@ dummy_fail_callback(uchar* data_ptr __attribute__((unused)))
int main(int argc __attribute__((unused)), char *argv[])
{
- uint pagen;
uchar long_tr_id[6];
PAGECACHE pagecache;
LSN lsn;
@@ -99,8 +98,8 @@ int main(int argc __attribute__((unused)), char *argv[])
fprintf(stderr, "Can't init control file (%d)\n", errno);
exit(1);
}
- if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ if (init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
+ PCACHE_PAGE, 0, 0) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/maria/unittest/ma_test_loghandler_purge-t.c b/storage/maria/unittest/ma_test_loghandler_purge-t.c
index 6ae0e7830ae..a13645f1bb8 100644
--- a/storage/maria/unittest/ma_test_loghandler_purge-t.c
+++ b/storage/maria/unittest/ma_test_loghandler_purge-t.c
@@ -73,7 +73,7 @@ int main(int argc __attribute__((unused)), char *argv[])
exit(1);
}
if ((pagen= init_pagecache(&pagecache, PCACHE_SIZE, 0, 0,
- PCACHE_PAGE, 0)) == 0)
+ PCACHE_PAGE, 0, 0)) == 0)
{
fprintf(stderr, "Got error: init_pagecache() (errno: %d)\n", errno);
exit(1);
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index bc4c5139810..ff3af8bac05 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -823,7 +823,15 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked)
table->key_info[i].block_size= file->s->keyinfo[i].block_length;
}
my_errno= 0;
+
+ /* Count statistics of usage for newly open normal files */
+ if (file->s->reopen == 1 && ! (test_if_locked & HA_OPEN_TMP_TABLE))
+ {
+ if (file->s->delay_key_write)
+ feature_files_opened_with_delayed_keys++;
+ }
goto end;
+
err:
this->close();
end:
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 3a2bdb2e899..b79d6c891f1 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -1536,7 +1536,7 @@ int mi_repair(HA_CHECK *param, register MI_INFO *info,
if (!param->using_global_keycache)
(void) init_key_cache(dflt_key_cache, param->key_cache_block_size,
- (size_t) param->use_buffers, 0, 0, 0);
+ (size_t) param->use_buffers, 0, 0, 0, 0);
if (init_io_cache(&param->read_cache,info->dfile,
(uint) param->read_buffer_length,
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index 87cea2e5566..d90a8549e1e 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -51,7 +51,7 @@ int main(int argc,char *argv[])
my_init();
if (key_cacheing)
init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0,0,
- DEFAULT_KEY_CACHE_PARTITIONS);
+ 0, DEFAULT_KEY_CACHE_PARTITIONS);
get_options(argc,argv);
exit(run_test("test1"));
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index e53c68874b2..be58b3c54d0 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -217,7 +217,7 @@ int main(int argc, char *argv[])
printf("- Writing key:s\n");
if (key_cacheing)
init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0,
- DEFAULT_KEY_CACHE_PARTITIONS);
+ 0, DEFAULT_KEY_CACHE_PARTITIONS);
if (do_locking)
mi_lock_database(file,F_WRLCK);
if (write_cacheing)
@@ -278,8 +278,9 @@ int main(int argc, char *argv[])
}
}
if (key_cacheing)
- resize_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size*2,0,0);
-
+ resize_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size*2,
+ 0, 0, 0);
+
if (!silent)
printf("- Delete\n");
for (i=0 ; i<recant/10 ; i++)
diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c
index 885118d4eec..e05398f7c4a 100644
--- a/storage/myisam/mi_test3.c
+++ b/storage/myisam/mi_test3.c
@@ -178,7 +178,7 @@ void start_test(int id)
}
if (key_cacheing && rnd(2) == 0)
init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0,
- DEFAULT_KEY_CACHE_PARTITIONS);
+ 0, DEFAULT_KEY_CACHE_PARTITIONS);
printf("Process %d, pid: %ld\n", id, (long) getpid());
fflush(stdout);
diff --git a/storage/myisam/mi_test_all.sh b/storage/myisam/mi_test_all.sh
index 12c28d7d132..e6327fd8247 100755
--- a/storage/myisam/mi_test_all.sh
+++ b/storage/myisam/mi_test_all.sh
@@ -156,9 +156,9 @@ echo "mi_test2$suffix $silent -L -K -R1 -m2000 ; Should give error 135"
./myisamchk$suffix -sm test2
./mi_test2$suffix $silent -L -K -W -P -m50 -l
-./myisamlog$suffix
+./myisamlog$suffix -P
./mi_test2$suffix $silent -L -K -W -P -m50 -l -b100
-./myisamlog$suffix
+./myisamlog$suffix -P
time ./mi_test2$suffix $silent
time ./mi_test2$suffix $silent -K -B
time ./mi_test2$suffix $silent -L -B
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index e1ea9f2de37..55ee3795f9b 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -84,7 +84,7 @@ int main(int argc,char *argv[])
usage();
}
- init_key_cache(dflt_key_cache, MI_KEY_BLOCK_LENGTH, KEY_BUFFER_INIT, 0, 0, 0);
+ init_key_cache(dflt_key_cache, MI_KEY_BLOCK_LENGTH, KEY_BUFFER_INIT, 0, 0, 0, 0);
if (!(info=mi_open(argv[0], O_RDONLY,
HA_OPEN_ABORT_IF_LOCKED|HA_OPEN_FROM_SQL_LAYER)))
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 0cd01398cbc..7835ab83531 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1115,7 +1115,7 @@ static int myisamchk(HA_CHECK *param, char * filename)
{
if (param->testflag & (T_EXTEND | T_MEDIUM))
(void) init_key_cache(dflt_key_cache,opt_key_cache_block_size,
- param->use_buffers, 0, 0, 0);
+ param->use_buffers, 0, 0, 0, 0);
(void) init_io_cache(&param->read_cache,datafile,
(uint) param->read_buffer_length,
READ_CACHE,
@@ -1532,7 +1532,7 @@ static int mi_sort_records(HA_CHECK *param,
DBUG_RETURN(0); /* Nothing to do */
init_key_cache(dflt_key_cache, opt_key_cache_block_size,
- (size_t) param->use_buffers, 0, 0, 0);
+ (size_t) param->use_buffers, 0, 0, 0, 0);
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
WRITE_CACHE,share->pack.header_length,1,
MYF(MY_WME | MY_WAIT_IF_FULL)))
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index 86e1978edaa..d549dd76037 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -333,7 +333,7 @@ static int examine_log(char * file_name, char **table_names)
(tree_element_free) file_info_free, NULL,
MYF(MY_TREE_WITH_DELETE));
(void) init_key_cache(dflt_key_cache,KEY_CACHE_BLOCK_SIZE,KEY_CACHE_SIZE,
- 0, 0, 0);
+ 0, 0, 0, 0);
files_open=0; access_time=0;
while (access_time++ != number_of_commands &&