Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
47d3337e
Commit
47d3337e
authored
Nov 25, 2003
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge ibabaev@bk-internal.mysql.com:/home/bk/mysql-4.1
into rurik.mysql.com:/home/igor/mysql-4.1
parents
aec7248c
bf99e546
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
227 additions
and
35 deletions
+227
-35
include/keycache.h
include/keycache.h
+4
-0
mysys/mf_keycache.c
mysys/mf_keycache.c
+189
-33
tests/fork_big2.pl
tests/fork_big2.pl
+34
-2
No files found.
include/keycache.h
View file @
47d3337e
...
@@ -45,6 +45,8 @@ typedef struct st_keycache_wqueue
...
@@ -45,6 +45,8 @@ typedef struct st_keycache_wqueue
typedef
struct
st_key_cache
typedef
struct
st_key_cache
{
{
my_bool
key_cache_inited
;
my_bool
key_cache_inited
;
my_bool
resize_in_flush
;
/* true during flush of resize operation */
my_bool
can_be_used
;
/* usage of cache for read/write is allowed */
uint
key_cache_shift
;
uint
key_cache_shift
;
ulong
key_cache_mem_size
;
/* specified size of the cache memory */
ulong
key_cache_mem_size
;
/* specified size of the cache memory */
uint
key_cache_block_size
;
/* size of the page buffer of a cache block */
uint
key_cache_block_size
;
/* size of the page buffer of a cache block */
...
@@ -58,6 +60,7 @@ typedef struct st_key_cache
...
@@ -58,6 +60,7 @@ typedef struct st_key_cache
ulong
blocks_used
;
/* number of currently used blocks */
ulong
blocks_used
;
/* number of currently used blocks */
ulong
blocks_changed
;
/* number of currently dirty blocks */
ulong
blocks_changed
;
/* number of currently dirty blocks */
ulong
warm_blocks
;
/* number of blocks in warm sub-chain */
ulong
warm_blocks
;
/* number of blocks in warm sub-chain */
ulong
cnt_for_resize_op
;
/* counter to block resize operation */
long
blocks_available
;
/* number of blocks available in the LRU chain */
long
blocks_available
;
/* number of blocks available in the LRU chain */
HASH_LINK
**
hash_root
;
/* arr. of entries into hash table buckets */
HASH_LINK
**
hash_root
;
/* arr. of entries into hash table buckets */
HASH_LINK
*
hash_link_root
;
/* memory for hash table links */
HASH_LINK
*
hash_link_root
;
/* memory for hash table links */
...
@@ -67,6 +70,7 @@ typedef struct st_key_cache
...
@@ -67,6 +70,7 @@ typedef struct st_key_cache
BLOCK_LINK
*
used_last
;
/* ptr to the last block of the LRU chain */
BLOCK_LINK
*
used_last
;
/* ptr to the last block of the LRU chain */
BLOCK_LINK
*
used_ins
;
/* ptr to the insertion block in LRU chain */
BLOCK_LINK
*
used_ins
;
/* ptr to the insertion block in LRU chain */
pthread_mutex_t
cache_lock
;
/* to lock access to the cache structure */
pthread_mutex_t
cache_lock
;
/* to lock access to the cache structure */
KEYCACHE_WQUEUE
resize_queue
;
/* threads waiting during resize operation */
KEYCACHE_WQUEUE
waiting_for_hash_link
;
/* waiting for a free hash link */
KEYCACHE_WQUEUE
waiting_for_hash_link
;
/* waiting for a free hash link */
KEYCACHE_WQUEUE
waiting_for_block
;
/* requests waiting for a free block */
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
*
changed_blocks
[
CHANGED_BLOCKS_HASH
];
/* hash for dirty file bl.*/
...
...
mysys/mf_keycache.c
View file @
47d3337e
...
@@ -141,6 +141,11 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var;
...
@@ -141,6 +141,11 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var;
#define FLUSH_CACHE 2000
/* sort this many blocks at once */
#define FLUSH_CACHE 2000
/* sort this many blocks at once */
static
int
flush_all_key_blocks
(
KEY_CACHE
*
keycache
);
static
int
flush_all_key_blocks
(
KEY_CACHE
*
keycache
);
static
inline
void
link_into_queue
(
KEYCACHE_WQUEUE
*
wqueue
,
struct
st_my_thread_var
*
thread
);
static
inline
void
unlink_from_queue
(
KEYCACHE_WQUEUE
*
wqueue
,
struct
st_my_thread_var
*
thread
);
static
void
free_block
(
KEY_CACHE
*
keycache
,
BLOCK_LINK
*
block
);
static
void
test_key_cache
(
KEY_CACHE
*
keycache
,
static
void
test_key_cache
(
KEY_CACHE
*
keycache
,
const
char
*
where
,
my_bool
lock
);
const
char
*
where
,
my_bool
lock
);
...
@@ -225,10 +230,10 @@ static int keycache_pthread_cond_broadcast(pthread_cond_t *cond);
...
@@ -225,10 +230,10 @@ static int keycache_pthread_cond_broadcast(pthread_cond_t *cond);
static
uint
next_power
(
uint
value
)
static
uint
next_power
(
uint
value
)
{
{
uint
old_value
=
1
;
uint
old_value
=
1
;
while
(
value
)
while
(
value
)
{
{
old_value
=
value
;
old_value
=
value
;
value
&=
value
-
1
;
value
&=
value
-
1
;
}
}
return
(
old_value
<<
1
);
return
(
old_value
<<
1
);
...
@@ -239,8 +244,8 @@ static uint next_power(uint value)
...
@@ -239,8 +244,8 @@ static uint next_power(uint value)
Initialize a key cache
Initialize a key cache
SYNOPSIS
SYNOPSIS
init_ky_cache()
init_k
e
y_cache()
keycache pointer to
the key cache handle to initializ
e
keycache pointer to
a key cache data structur
e
key_cache_block_size size of blocks to keep cached data
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the key cache
use_mem total memory to use for the key cache
division_limit division limit (may be zero)
division_limit division limit (may be zero)
...
@@ -366,11 +371,16 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
...
@@ -366,11 +371,16 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
blocks
*
age_threshold
/
100
:
blocks
*
age_threshold
/
100
:
blocks
);
blocks
);
keycache
->
cnt_for_resize_op
=
0
;
keycache
->
resize_in_flush
=
0
;
keycache
->
can_be_used
=
1
;
keycache
->
resize_queue
.
last_thread
=
NULL
;
keycache
->
waiting_for_hash_link
.
last_thread
=
NULL
;
keycache
->
waiting_for_hash_link
.
last_thread
=
NULL
;
keycache
->
waiting_for_block
.
last_thread
=
NULL
;
keycache
->
waiting_for_block
.
last_thread
=
NULL
;
DBUG_PRINT
(
"exit"
,
DBUG_PRINT
(
"exit"
,
(
"disk_blocks: %d block_root: %lx hash_entries: %d
hash_root: %lx
\
(
"disk_blocks: %d block_root: %lx hash_entries: %d\
hash_links: %d hash_link_root %lx"
,
hash_root: %lx
hash_links: %d hash_link_root %lx"
,
keycache
->
disk_blocks
,
keycache
->
block_root
,
keycache
->
disk_blocks
,
keycache
->
block_root
,
keycache
->
hash_entries
,
keycache
->
hash_root
,
keycache
->
hash_entries
,
keycache
->
hash_root
,
keycache
->
hash_links
,
keycache
->
hash_link_root
));
keycache
->
hash_links
,
keycache
->
hash_link_root
));
...
@@ -398,6 +408,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
...
@@ -398,6 +408,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
keycache
->
block_root
=
NULL
;
keycache
->
block_root
=
NULL
;
}
}
my_errno
=
error
;
my_errno
=
error
;
keycache
->
can_be_used
=
0
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
}
}
...
@@ -407,7 +418,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
...
@@ -407,7 +418,7 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
SYNOPSIS
SYNOPSIS
resize_key_cache()
resize_key_cache()
keycache
in/out key cache handl
e
keycache
pointer to a key cache data structur
e
key_cache_block_size size of blocks to keep cached data
key_cache_block_size size of blocks to keep cached data
use_mem total memory to use for the new key cache
use_mem total memory to use for the new key cache
division_limit new division limit (if not zero)
division_limit new division limit (if not zero)
...
@@ -425,6 +436,10 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
...
@@ -425,6 +436,10 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
old key cache blocks by calling the end_key_cache function and
old key cache blocks by calling the end_key_cache function and
then rebuilds the key cache with new blocks by calling
then rebuilds the key cache with new blocks by calling
init_key_cache.
init_key_cache.
The function starts the operation only when all other threads
performing operations with the key cache let her to proceed
(when cnt_for_resize=0).
*/
*/
int
resize_key_cache
(
KEY_CACHE
*
keycache
,
uint
key_cache_block_size
,
int
resize_key_cache
(
KEY_CACHE
*
keycache
,
uint
key_cache_block_size
,
...
@@ -432,35 +447,90 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
...
@@ -432,35 +447,90 @@ int resize_key_cache(KEY_CACHE *keycache, uint key_cache_block_size,
uint
age_threshold
)
uint
age_threshold
)
{
{
int
blocks
;
int
blocks
;
struct
st_my_thread_var
*
thread
;
KEYCACHE_WQUEUE
*
wqueue
;
DBUG_ENTER
(
"resize_key_cache"
);
DBUG_ENTER
(
"resize_key_cache"
);
if
(
!
keycache
->
key_cache_inited
||
if
(
!
keycache
->
key_cache_inited
)
(
key_cache_block_size
==
keycache
->
key_cache_block_size
&&
DBUG_RETURN
(
keycache
->
disk_blocks
);
use_mem
==
keycache
->
key_cache_mem_size
))
if
(
key_cache_block_size
==
keycache
->
key_cache_block_size
&&
use_mem
==
keycache
->
key_cache_mem_size
)
{
change_key_cache_param
(
keycache
,
division_limit
,
age_threshold
);
DBUG_RETURN
(
keycache
->
disk_blocks
);
DBUG_RETURN
(
keycache
->
disk_blocks
);
}
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
wqueue
=
&
keycache
->
resize_queue
;
thread
=
my_thread_var
;
link_into_queue
(
wqueue
,
thread
);
while
(
wqueue
->
last_thread
->
next
!=
thread
)
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
cache_lock
);
}
keycache
->
resize_in_flush
=
1
;
if
(
flush_all_key_blocks
(
keycache
))
if
(
flush_all_key_blocks
(
keycache
))
{
{
/* TODO: if this happens, we should write a warning in the log file ! */
/* TODO: if this happens, we should write a warning in the log file ! */
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache
->
resize_in_flush
=
0
;
DBUG_RETURN
(
0
);
blocks
=
0
;
goto
finish
;
}
keycache
->
resize_in_flush
=
0
;
keycache
->
can_be_used
=
0
;
while
(
keycache
->
cnt_for_resize_op
)
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
cache_lock
);
}
}
end_key_cache
(
keycache
,
0
);
/* Don't free mutex */
end_key_cache
(
keycache
,
0
);
/* Don't free mutex */
/*
t
he following will work even if use_mem is 0 */
/*
T
he following will work even if use_mem is 0 */
blocks
=
init_key_cache
(
keycache
,
key_cache_block_size
,
use_mem
,
blocks
=
init_key_cache
(
keycache
,
key_cache_block_size
,
use_mem
,
division_limit
,
age_threshold
);
division_limit
,
age_threshold
);
finish:
unlink_from_queue
(
wqueue
,
thread
);
/* Signal for the next resize request to proceeed if any */
if
(
wqueue
->
last_thread
)
keycache_pthread_cond_signal
(
&
wqueue
->
last_thread
->
next
->
suspend
);
keycache
->
can_be_used
=
blocks
<=
0
;
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
return
blocks
;
return
blocks
;
}
}
/*
Increment counter blocking resize key cache operation
*/
static
inline
void
inc_counter_for_resize_op
(
KEY_CACHE
*
keycache
)
{
keycache
->
cnt_for_resize_op
++
;
}
/*
Decrement counter blocking resize key cache operation;
Signal the operation to proceed when counter becomes equal zero
*/
static
inline
void
dec_counter_for_resize_op
(
KEY_CACHE
*
keycache
)
{
struct
st_my_thread_var
*
last_thread
;
if
(
!--
keycache
->
cnt_for_resize_op
&&
(
last_thread
=
keycache
->
resize_queue
.
last_thread
))
keycache_pthread_cond_signal
(
&
last_thread
->
next
->
suspend
);
}
/*
/*
Change the key cache parameters
Change the key cache parameters
SYNOPSIS
SYNOPSIS
change_key_cache_param()
change_key_cache_param()
keycache
key cache handle
keycache
pointer to a key cache data structure
division_limit new division limit (if not zero)
division_limit new division limit (if not zero)
age_threshold new age threshold (if not zero)
age_threshold new age threshold (if not zero)
...
@@ -478,12 +548,14 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
...
@@ -478,12 +548,14 @@ void change_key_cache_param(KEY_CACHE *keycache, uint division_limit,
{
{
DBUG_ENTER
(
"change_key_cache_param"
);
DBUG_ENTER
(
"change_key_cache_param"
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
if
(
division_limit
)
if
(
division_limit
)
keycache
->
min_warm_blocks
=
(
keycache
->
disk_blocks
*
keycache
->
min_warm_blocks
=
(
keycache
->
disk_blocks
*
division_limit
/
100
+
1
);
division_limit
/
100
+
1
);
if
(
age_threshold
)
if
(
age_threshold
)
keycache
->
age_threshold
=
(
keycache
->
disk_blocks
*
keycache
->
age_threshold
=
(
keycache
->
disk_blocks
*
age_threshold
/
100
);
age_threshold
/
100
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -1018,7 +1090,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
...
@@ -1018,7 +1090,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
hash_link
->
block
=
NULL
;
hash_link
->
block
=
NULL
;
if
(
keycache
->
waiting_for_hash_link
.
last_thread
)
if
(
keycache
->
waiting_for_hash_link
.
last_thread
)
{
{
/* Signal that
A free hash link
appeared */
/* Signal that
a free hash link has
appeared */
struct
st_my_thread_var
*
last_thread
=
struct
st_my_thread_var
*
last_thread
=
keycache
->
waiting_for_hash_link
.
last_thread
;
keycache
->
waiting_for_hash_link
.
last_thread
;
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
struct
st_my_thread_var
*
first_thread
=
last_thread
->
next
;
...
@@ -1204,9 +1276,57 @@ static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
...
@@ -1204,9 +1276,57 @@ static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
))
block
->
hash_link
==
hash_link
&&
(
block
->
status
&
BLOCK_READ
))
page_status
=
PAGE_READ
;
page_status
=
PAGE_READ
;
if
(
page_status
==
PAGE_READ
&&
(
block
->
status
&
BLOCK_IN_SWITCH
))
if
(
wrmode
&&
keycache
->
resize_in_flush
)
{
/* This is a write request during the flush phase of a resize operation */
if
(
page_status
!=
PAGE_READ
)
{
/* We don't need the page in the cache: we are going to write on disk */
hash_link
->
requests
--
;
unlink_hash
(
keycache
,
hash_link
);
return
0
;
}
if
(
!
(
block
->
status
&
BLOCK_IN_FLUSH
))
{
hash_link
->
requests
--
;
/*
Remove block to invalidate the page in the block buffer
as we are going to write directly on disk.
Although we have an exlusive lock for the updated key part
the control can be yieded by the current thread as we might
have unfinished readers of other key parts in the block
buffer. Still we are guaranteed not to have any readers
of the key part we are writing into until the block is
removed from the cache as we set the BLOCL_REASSIGNED
flag (see the code below that handles reading requests).
*/
free_block
(
keycache
,
block
);
return
0
;
}
/* Wait intil the page is flushed on disk */
hash_link
->
requests
--
;
{
struct
st_my_thread_var
*
thread
=
my_thread_var
;
add_to_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
],
thread
);
do
{
keycache_pthread_cond_wait
(
&
thread
->
suspend
,
&
keycache
->
cache_lock
);
}
while
(
thread
->
next
);
}
/* Invalidate page in the block if it has not been done yet */
if
(
block
->
status
)
free_block
(
keycache
,
block
);
return
0
;
}
if
(
page_status
==
PAGE_READ
&&
(
block
->
status
&
(
BLOCK_IN_SWITCH
|
BLOCK_REASSIGNED
)))
{
{
/* This is a request for a page to be removed from cache */
/* This is a request for a page to be removed from cache */
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
KEYCACHE_DBUG_PRINT
(
"find_key_block"
,
(
"request for old page in block %u"
,
BLOCK_NUMBER
(
block
)));
(
"request for old page in block %u"
,
BLOCK_NUMBER
(
block
)));
/*
/*
...
@@ -1270,6 +1390,7 @@ static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
...
@@ -1270,6 +1390,7 @@ static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
else
else
{
{
/* There are no never used blocks, use a block from the LRU chain */
/* There are no never used blocks, use a block from the LRU chain */
/*
/*
Wait until a new block is added to the LRU chain;
Wait until a new block is added to the LRU chain;
several threads might wait here for the same page,
several threads might wait here for the same page,
...
@@ -1521,7 +1642,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
...
@@ -1521,7 +1642,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
(
uint
)
file
,
(
ulong
)
filepos
,
length
));
(
uint
)
file
,
(
ulong
)
filepos
,
length
));
if
(
keycache
->
disk_blocks
>
0
)
if
(
keycache
->
can_be_used
)
{
{
/* Key cache is used */
/* Key cache is used */
reg1
BLOCK_LINK
*
block
;
reg1
BLOCK_LINK
*
block
;
...
@@ -1533,7 +1654,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
...
@@ -1533,7 +1654,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
do
do
{
{
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
if
(
keycache
->
disk_blocks
<=
0
)
/* Resize failed */
if
(
!
keycache
->
can_be_used
)
{
{
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
goto
no_key_cache
;
goto
no_key_cache
;
...
@@ -1548,6 +1669,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
...
@@ -1548,6 +1669,7 @@ byte *key_cache_read(KEY_CACHE *keycache,
return_buffer
=
0
;
return_buffer
=
0
;
#endif
#endif
inc_counter_for_resize_op
(
keycache
);
keycache
->
global_cache_r_requests
++
;
keycache
->
global_cache_r_requests
++
;
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
0
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
0
,
&
page_st
);
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
...
@@ -1598,6 +1720,8 @@ byte *key_cache_read(KEY_CACHE *keycache,
...
@@ -1598,6 +1720,8 @@ byte *key_cache_read(KEY_CACHE *keycache,
*/
*/
unreg_request
(
keycache
,
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
if
(
status
&
BLOCK_ERROR
)
if
(
status
&
BLOCK_ERROR
)
...
@@ -1654,7 +1778,7 @@ int key_cache_insert(KEY_CACHE *keycache,
...
@@ -1654,7 +1778,7 @@ int key_cache_insert(KEY_CACHE *keycache,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
DBUG_PRINT
(
"enter"
,
(
"file %u, filepos %lu, length %u"
,
(
uint
)
file
,(
ulong
)
filepos
,
length
));
(
uint
)
file
,(
ulong
)
filepos
,
length
));
if
(
keycache
->
disk_blocks
>
0
)
if
(
keycache
->
can_be_used
)
{
{
/* Key cache is used */
/* Key cache is used */
reg1
BLOCK_LINK
*
block
;
reg1
BLOCK_LINK
*
block
;
...
@@ -1666,7 +1790,7 @@ int key_cache_insert(KEY_CACHE *keycache,
...
@@ -1666,7 +1790,7 @@ int key_cache_insert(KEY_CACHE *keycache,
{
{
uint
offset
;
uint
offset
;
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
if
(
keycache
->
disk_blocks
<=
0
)
/* Resize failed */
if
(
!
keycache
->
can_be_used
)
{
{
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
...
@@ -1678,6 +1802,7 @@ int key_cache_insert(KEY_CACHE *keycache,
...
@@ -1678,6 +1802,7 @@ int key_cache_insert(KEY_CACHE *keycache,
/* Read data into key cache from buff in key_cache_block_size incr. */
/* Read data into key cache from buff in key_cache_block_size incr. */
filepos
-=
offset
;
filepos
-=
offset
;
inc_counter_for_resize_op
(
keycache
);
keycache
->
global_cache_r_requests
++
;
keycache
->
global_cache_r_requests
++
;
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
0
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
0
,
&
page_st
);
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
)
...
@@ -1708,6 +1833,9 @@ int key_cache_insert(KEY_CACHE *keycache,
...
@@ -1708,6 +1833,9 @@ int key_cache_insert(KEY_CACHE *keycache,
unreg_request
(
keycache
,
block
,
1
);
unreg_request
(
keycache
,
block
,
1
);
error
=
(
block
->
status
&
BLOCK_ERROR
);
error
=
(
block
->
status
&
BLOCK_ERROR
);
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
if
(
error
)
if
(
error
)
...
@@ -1776,7 +1904,7 @@ int key_cache_write(KEY_CACHE *keycache,
...
@@ -1776,7 +1904,7 @@ int key_cache_write(KEY_CACHE *keycache,
test_key_cache
(
keycache
,
"start of key_cache_write"
,
1
););
test_key_cache
(
keycache
,
"start of key_cache_write"
,
1
););
#endif
#endif
if
(
keycache
->
disk_blocks
>
0
)
if
(
keycache
->
can_be_used
)
{
{
/* Key cache is used */
/* Key cache is used */
uint
read_length
;
uint
read_length
;
...
@@ -1786,7 +1914,7 @@ int key_cache_write(KEY_CACHE *keycache,
...
@@ -1786,7 +1914,7 @@ int key_cache_write(KEY_CACHE *keycache,
{
{
uint
offset
;
uint
offset
;
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
if
(
keycache
->
disk_blocks
<=
0
)
/* Resize failed */
if
(
!
keycache
->
can_be_used
)
{
{
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
goto
no_key_cache
;
goto
no_key_cache
;
...
@@ -1798,8 +1926,25 @@ int key_cache_write(KEY_CACHE *keycache,
...
@@ -1798,8 +1926,25 @@ int key_cache_write(KEY_CACHE *keycache,
/* Write data in key_cache_block_size increments */
/* Write data in key_cache_block_size increments */
filepos
-=
offset
;
filepos
-=
offset
;
inc_counter_for_resize_op
(
keycache
);
keycache
->
global_cache_w_requests
++
;
keycache
->
global_cache_w_requests
++
;
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
1
,
&
page_st
);
block
=
find_key_block
(
keycache
,
file
,
filepos
,
level
,
1
,
&
page_st
);
if
(
!
block
)
{
/* It happens only for requests submitted during resize operation */
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
if
(
dont_write
)
{
keycache
->
global_cache_w_requests
++
;
keycache
->
global_cache_write
++
;
if
(
my_pwrite
(
file
,
(
byte
*
)
buff
,
length
,
filepos
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
)))
error
=
1
;
}
goto
next_block
;
}
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
&&
if
(
block
->
status
!=
BLOCK_ERROR
&&
page_st
!=
PAGE_READ
&&
(
offset
||
read_length
<
keycache
->
key_cache_block_size
))
(
offset
||
read_length
<
keycache
->
key_cache_block_size
))
read_block
(
keycache
,
block
,
read_block
(
keycache
,
block
,
...
@@ -1841,8 +1986,11 @@ int key_cache_write(KEY_CACHE *keycache,
...
@@ -1841,8 +1986,11 @@ int key_cache_write(KEY_CACHE *keycache,
break
;
break
;
}
}
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
next_block:
buff
+=
read_length
;
buff
+=
read_length
;
filepos
+=
read_length
;
filepos
+=
read_length
;
offset
=
0
;
offset
=
0
;
...
@@ -1951,6 +2099,12 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
...
@@ -1951,6 +2099,12 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
if
(
!
last_errno
)
if
(
!
last_errno
)
last_errno
=
errno
?
errno
:
-
1
;
last_errno
=
errno
?
errno
:
-
1
;
}
}
/*
Let to proceed for possible waiting requests to write to the block page.
It might happen only during an operation to resize the key cache.
*/
if
(
block
->
wqueue
[
COND_FOR_SAVED
].
last_thread
)
release_queue
(
&
block
->
wqueue
[
COND_FOR_SAVED
]);
/* type will never be FLUSH_IGNORE_CHANGED here */
/* type will never be FLUSH_IGNORE_CHANGED here */
if
(
!
(
type
==
FLUSH_KEEP
||
type
==
FLUSH_FORCE_WRITE
))
if
(
!
(
type
==
FLUSH_KEEP
||
type
==
FLUSH_FORCE_WRITE
))
{
{
...
@@ -2187,18 +2341,20 @@ static int flush_key_blocks_int(KEY_CACHE *keycache,
...
@@ -2187,18 +2341,20 @@ static int flush_key_blocks_int(KEY_CACHE *keycache,
1 error
1 error
*/
*/
int
flush_key_blocks
(
KEY_CACHE
*
key
_
cache
,
int
flush_key_blocks
(
KEY_CACHE
*
keycache
,
File
file
,
enum
flush_type
type
)
File
file
,
enum
flush_type
type
)
{
{
int
res
;
int
res
;
DBUG_ENTER
(
"flush_key_blocks"
);
DBUG_ENTER
(
"flush_key_blocks"
);
DBUG_PRINT
(
"enter"
,
(
"key
_cache: %lx"
,
key_
cache
));
DBUG_PRINT
(
"enter"
,
(
"key
cache: %lx"
,
key
cache
));
if
(
key
_
cache
->
disk_blocks
<=
0
)
if
(
keycache
->
disk_blocks
<=
0
)
DBUG_RETURN
(
0
);
DBUG_RETURN
(
0
);
keycache_pthread_mutex_lock
(
&
key_cache
->
cache_lock
);
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
res
=
flush_key_blocks_int
(
key_cache
,
file
,
type
);
inc_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
key_cache
->
cache_lock
);
res
=
flush_key_blocks_int
(
keycache
,
file
,
type
);
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
DBUG_RETURN
(
res
);
DBUG_RETURN
(
res
);
}
}
...
...
tests/fork_big2.pl
View file @
47d3337e
...
@@ -23,14 +23,15 @@ $opt_select_count=$opt_join_count=0;
...
@@ -23,14 +23,15 @@ $opt_select_count=$opt_join_count=0;
$opt_update
=
1
;
$opt_delete
=
0
;
$opt_update
=
1
;
$opt_delete
=
0
;
$opt_flush
=
$opt_check
=
$opt_repair
=
$opt_alter
=
0
;
$opt_flush
=
$opt_check
=
$opt_repair
=
$opt_alter
=
0
;
$opt_join_range
=
100
;
$opt_join_range
=
100
;
$opt_resize_interval
=
0
;
$opt_time
=
0
;
$opt_time
=
0
;
$opt_host
=
$opt_user
=
$opt_password
=
"";
$opt_db
=
"
test
";
$opt_host
=
$opt_user
=
$opt_password
=
"";
$opt_db
=
"
test
";
$opt_verbose
=
$opt_debug
=
$opt_lock_tables
=
$opt_fast_insert
=
$opt_fast
=
$opt_skip_in
=
$opt_force
=
undef
;
# Ignore warnings from these
GetOptions
("
host=s
","
db=s
","
user=s
","
password=s
","
loop-count=i
","
skip-create
","
skip-in
","
skip-drop
",
GetOptions
("
host=s
","
db=s
","
user=s
","
password=s
","
loop-count=i
","
skip-create
","
skip-in
","
skip-drop
",
"
verbose
","
fast-insert
","
lock-tables
","
debug
","
fast
","
force
","
thread-factor=i
",
"
verbose
","
fast-insert
","
lock-tables
","
debug
","
fast
","
force
","
thread-factor=i
",
"
insert=i
",
"
select=i
",
"
join=i
",
"
select-count=i
",
"
join-count=i
",
"
update=i
",
"
delete=i
",
"
insert=i
",
"
select=i
",
"
join=i
",
"
select-count=i
",
"
join-count=i
",
"
update=i
",
"
delete=i
",
"
flush=i
",
"
check=i
",
"
repair=i
",
"
alter=i
",
"
max-join_range=i
",
"
time=i
")
||
die
"
Aborted
";
"
flush=i
",
"
check=i
",
"
repair=i
",
"
alter=i
",
"
resize-interval=i
",
"
max-join_range=i
",
"
time=i
")
||
die
"
Aborted
";
$opt_verbose
=
$opt_debug
=
$opt_lock_tables
=
$opt_fast_insert
=
$opt_fast
=
$opt_skip_in
=
$opt_force
=
undef
;
# Ignore warnings from these
print
"
Test of multiple connections that test the following things:
\n
";
print
"
Test of multiple connections that test the following things:
\n
";
print
"
insert, select, delete, update, alter, check, repair and flush
\n
";
print
"
insert, select, delete, update, alter, check, repair and flush
\n
";
...
@@ -158,6 +159,11 @@ for ($i=0 ; $i < $opt_alter ; $i ++)
...
@@ -158,6 +159,11 @@ for ($i=0 ; $i < $opt_alter ; $i ++)
test_alter
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
alter
";
test_alter
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
alter
";
}
}
$threads
+=
$i
;
$threads
+=
$i
;
if
(
$opt_resize_interval
!=
0
)
{
test_resize
()
if
((
$pid
=
fork
())
==
0
);
$work
{
$pid
}
=
"
resize
";
$threads
+=
1
;
}
print
"
Started
$threads
threads
\n
";
print
"
Started
$threads
threads
\n
";
...
@@ -590,6 +596,32 @@ sub test_flush
...
@@ -590,6 +596,32 @@ sub test_flush
exit
(
0
);
exit
(
0
);
}
}
#
# Do a resize key cache every periodically
#
sub
test_resize
{
my
(
$dbh
,
$key_buffer_size
);
$dbh
=
DBI
->
connect
("
DBI:mysql:
$opt_db
:
$opt_host
",
$opt_user
,
$opt_password
,
{
PrintError
=>
0
})
||
die
$
DBI::
errstr
;
$count
=
0
;
$key_buffer_size
=
1024
*
64
;
while
(
!
test_if_abort
(
$dbh
))
{
sleep
(
$opt_resize_interval
);
$dbh
->
do
("
set global key_buffer_size=
$key_buffer_size
")
||
die
"
Got error on resize key cache
$DBI
::errstr
\n
";
$key_buffer_size
+=
1024
*
16
;
$count
++
;
}
$dbh
->
disconnect
;
$dbh
=
0
;
print
"
Test_resize: Executed
$count
times resize key cache
\n
";
exit
(
0
);
}
#
#
# Test all tables in a database
# Test all tables in a database
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment