Fixed problem with very slow shutdown when using 100,000 MyISAM tables with delay_key_write

Reason for the problem was that the hash of changed files in the key cache was too small (was 128). Fixed by making the hash size larger and changeable.

- Introduced key-cache-file-hash-size (default 512) for MyISAM and aria_pagecache_file_hash_size (default 512) for Aria.
- Added new status variable "Feature_delay_key_write" which counts number of tables opened that are using delay_key_write


mysql-test/r/features.result:
  Added test of Feature_delay_key_write
mysql-test/r/key_cache.result:
  Updated tests as the number of blocks has changed
mysql-test/r/mysqld--help.result:
  Updated result
mysql-test/suite/maria/maria3.result:
  Updated result
mysql-test/suite/sys_vars/r/key_cache_file_hash_size_basic.result:
  Test new variable
mysql-test/suite/sys_vars/t/aria_pagecache_file_hash_size_basic.test:
  Test new variable
mysql-test/suite/sys_vars/t/key_cache_file_hash_size_basic.test:
  Test new variable
mysql-test/t/features.test:
  Added test of Feature_delay_key_write
mysql-test/t/key_cache.test:
  Updated tests as the number of blocks has changed
mysys/mf_keycache.c:
  Made CHANGED_BLOCKS_HASH dynamic
sql/handler.cc:
  Updated call to init_key_cache()
sql/mysqld.cc:
  Added "Feature_delay_key_write"
  Added support for key-cache-file-hash-size
sql/mysqld.h:
  Added support for key-cache-file-hash-size
sql/sql_class.h:
  Added feature_files_opened_with_delayed_keys
sql/sys_vars.cc:
  Added key_cache_file_hash_size
storage/maria/ha_maria.cc:
  Added pagecache_file_hash_size
  Added counting of files with delay_key_write
storage/maria/ma_checkpoint.c:
  Fixed compiler warning
storage/maria/ma_pagecache.c:
  Made PAGECACHE_CHANGED_BLOCKS_HASH into a variable
storage/maria/ma_pagecache.h:
  Made PAGECACHE_CHANGED_BLOCKS_HASH into a variable
storage/maria/ma_rt_test.c:
  Updated parameters for init_pagecache()
storage/maria/ma_test1.c:
  Updated parameters for init_pagecache()
storage/maria/ma_test2.c:
  Updated parameters for init_pagecache()
storage/maria/ma_test3.c:
  Updated parameters for init_pagecache()
storage/maria/maria_chk.c:
  Updated parameters for init_pagecache()
storage/maria/maria_ftdump.c:
  Updated parameters for init_pagecache()
storage/maria/maria_pack.c:
  Updated parameters for init_pagecache()
storage/maria/maria_read_log.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_pagecache_consist.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_pagecache_rwconsist.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_pagecache_rwconsist2.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_pagecache_single.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_first_lsn-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_max_lsn-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_multigroup-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_multithread-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_noflush-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_nologs-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_pagecache-t.c:
  Updated parameters for init_pagecache()
storage/maria/unittest/ma_test_loghandler_purge-t.c:
  Updated parameters for init_pagecache()
storage/myisam/ha_myisam.cc:
  Added counting of files with delay_key_write
storage/myisam/mi_check.c:
  Updated call to init_key_cache()
storage/myisam/mi_test1.c:
  Updated call to init_key_cache()
storage/myisam/mi_test2.c:
  Updated call to init_key_cache()
storage/myisam/mi_test3.c:
  Updated call to init_key_cache()
storage/myisam/mi_test_all.sh:
  Fixed broken test
storage/myisam/myisam_ftdump.c:
  Updated call to init_key_cache()
storage/myisam/myisamchk.c:
  Updated call to init_key_cache()
storage/myisam/myisamlog.c:
  Updated call to init_key_cache()
This commit is contained in:
Michael Widenius 2014-07-19 17:46:08 +03:00
parent ff205b25d5
commit f0f2072d1f
51 changed files with 650 additions and 208 deletions

View file

@ -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 */

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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 #
########################################################################

View file

@ -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";

View file

@ -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

View file

@ -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);
}

View file

@ -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);

View file

@ -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:

View file

@ -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,

View file

@ -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,

View file

@ -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",

View file

@ -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),

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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) ||

View file

@ -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) ||

View file

@ -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) ||

View file

@ -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);

View file

@ -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);

View file

@ -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)))

View file

@ -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;

View file

@ -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))

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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:

View file

@ -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,

View file

@ -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"));

View file

@ -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++)

View file

@ -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);

View file

@ -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

View file

@ -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)))

View file

@ -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)))

View file

@ -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 &&