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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
5b3f34f4
Commit
5b3f34f4
authored
Sep 17, 2009
by
Alexander Nozdrin
Browse files
Options
Browse Files
Download
Plain Diff
Merge 5.1-bugteam -> trunk-alik.
parents
4e32e4f0
a57ba331
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
96 additions
and
52 deletions
+96
-52
mysys/mf_keycache.c
mysys/mf_keycache.c
+96
-52
No files found.
mysys/mf_keycache.c
View file @
5b3f34f4
...
...
@@ -13,7 +13,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
/**
@file
These functions handle keyblock cacheing for ISAM and MyISAM tables.
One cache can handle many files.
...
...
@@ -36,7 +37,9 @@
blocks_unused is the sum of never used blocks in the pool and of currently
free blocks. blocks_used is the number of blocks fetched from the pool and
as such gives the maximum number of in-use blocks at any time.
*/
/*
Key Cache Locking
=================
...
...
@@ -369,8 +372,8 @@ static inline uint next_power(uint value)
*/
int
init_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
)
{
ulong
blocks
,
hash_links
;
size_t
length
;
...
...
@@ -561,8 +564,8 @@ err:
*/
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
)
{
int
blocks
;
DBUG_ENTER
(
"resize_key_cache"
);
...
...
@@ -761,6 +764,13 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup)
(
ulong
)
keycache
->
global_cache_r_requests
,
(
ulong
)
keycache
->
global_cache_read
));
/*
Reset these values to be able to detect a disabled key cache.
See Bug#44068 (RESTORE can disable the MyISAM Key Cache).
*/
keycache
->
blocks_used
=
0
;
keycache
->
blocks_unused
=
0
;
if
(
cleanup
)
{
pthread_mutex_destroy
(
&
keycache
->
cache_lock
);
...
...
@@ -1344,7 +1354,11 @@ static void unreg_request(KEY_CACHE *keycache,
DBUG_ASSERT
(
block
->
prev_changed
&&
*
block
->
prev_changed
==
block
);
DBUG_ASSERT
(
!
block
->
next_used
);
DBUG_ASSERT
(
!
block
->
prev_used
);
if
(
!
--
block
->
requests
)
/*
Unregister the request, but do not link erroneous blocks into the
LRU ring.
*/
if
(
!--
block
->
requests
&&
!
(
block
->
status
&
BLOCK_ERROR
))
{
my_bool
hot
;
if
(
block
->
hits_left
)
...
...
@@ -1426,8 +1440,7 @@ static void wait_for_readers(KEY_CACHE *keycache,
#ifdef THREAD
struct
st_my_thread_var
*
thread
=
my_thread_var
;
DBUG_ASSERT
(
block
->
status
&
(
BLOCK_READ
|
BLOCK_IN_USE
));
DBUG_ASSERT
(
!
(
block
->
status
&
(
BLOCK_ERROR
|
BLOCK_IN_FLUSH
|
BLOCK_CHANGED
)));
DBUG_ASSERT
(
!
(
block
->
status
&
(
BLOCK_IN_FLUSH
|
BLOCK_CHANGED
)));
DBUG_ASSERT
(
block
->
hash_link
);
DBUG_ASSERT
(
block
->
hash_link
->
block
==
block
);
/* Linked in file_blocks or changed_blocks hash. */
...
...
@@ -2211,9 +2224,9 @@ restart:
thread might change the block->hash_link value
*/
error
=
my_pwrite
(
block
->
hash_link
->
file
,
block
->
buffer
+
block
->
offset
,
block
->
buffer
+
block
->
offset
,
block
->
length
-
block
->
offset
,
block
->
hash_link
->
diskpos
+
block
->
offset
,
block
->
hash_link
->
diskpos
+
block
->
offset
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
keycache_pthread_mutex_lock
(
&
keycache
->
cache_lock
);
...
...
@@ -2537,7 +2550,6 @@ uchar *key_cache_read(KEY_CACHE *keycache,
reg1
BLOCK_LINK
*
block
;
uint
read_length
;
uint
offset
;
uint
status
;
int
page_st
;
if
(
MYSQL_KEYCACHE_READ_START_ENABLED
())
...
...
@@ -2581,9 +2593,11 @@ uchar *key_cache_read(KEY_CACHE *keycache,
do
{
/* Cache could be disabled in a later iteration. */
if
(
!
keycache
->
can_be_used
)
goto
no_key_cache
;
{
KEYCACHE_DBUG_PRINT
(
"key_cache_read"
,
(
"keycache cannot be used"
));
goto
no_key_cache
;
}
/* Start reading at the beginning of the cache block. */
filepos
-=
offset
;
/* Do not read beyond the end of the cache block. */
...
...
@@ -2652,7 +2666,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
}
/* block status may have added BLOCK_ERROR in the above 'if'. */
if
(
!
(
(
status
=
block
->
status
)
&
BLOCK_ERROR
))
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
#ifndef THREAD
if
(
!
return_buffer
)
...
...
@@ -2678,14 +2692,22 @@ uchar *key_cache_read(KEY_CACHE *keycache,
remove_reader
(
block
);
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
/* Error injection for coverage testing. */
DBUG_EXECUTE_IF
(
"key_cache_read_block_error"
,
block
->
status
|=
BLOCK_ERROR
;);
if
(
status
&
BLOCK_ERROR
)
/* Do not link erroneous blocks into the LRU ring, but free them. */
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
}
else
{
free_block
(
keycache
,
block
);
error
=
1
;
break
;
}
...
...
@@ -2704,7 +2726,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
DBUG_RETURN
(
block
->
buffer
);
}
#endif
next_block:
next_block:
buff
+=
read_length
;
filepos
+=
read_length
+
offset
;
offset
=
0
;
...
...
@@ -2719,6 +2741,7 @@ uchar *key_cache_read(KEY_CACHE *keycache,
}
goto
end
;
}
KEYCACHE_DBUG_PRINT
(
"key_cache_read"
,
(
"keycache not initialized"
));
no_key_cache:
/* Key cache is not used */
...
...
@@ -2739,6 +2762,7 @@ end:
dec_counter_for_resize_op
(
keycache
);
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
}
DBUG_PRINT
(
"exit"
,
(
"error: %d"
,
error
));
DBUG_RETURN
(
error
?
(
uchar
*
)
0
:
start
);
}
...
...
@@ -2947,19 +2971,27 @@ int key_cache_insert(KEY_CACHE *keycache,
DBUG_ASSERT
(
block
->
status
&
(
BLOCK_READ
|
BLOCK_IN_USE
));
}
/* end of if (!(block->status & BLOCK_ERROR)) */
remove_reader
(
block
);
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
error
=
(
block
->
status
&
BLOCK_ERROR
);
/* Error injection for coverage testing. */
DBUG_EXECUTE_IF
(
"key_cache_insert_block_error"
,
block
->
status
|=
BLOCK_ERROR
;
errno
=
EIO
;);
if
(
error
)
/* Do not link erroneous blocks into the LRU ring, but free them. */
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
}
else
{
free_block
(
keycache
,
block
);
error
=
1
;
break
;
}
buff
+=
read_length
;
filepos
+=
read_length
+
offset
;
...
...
@@ -3221,7 +3253,7 @@ int key_cache_write(KEY_CACHE *keycache,
if
(
!
dont_write
)
{
/* Not used in the server. buff has been written to disk at start. */
/* Not used in the server. buff has been written to disk at start. */
if
((
block
->
status
&
BLOCK_CHANGED
)
&&
(
!
offset
&&
read_length
>=
keycache
->
key_cache_block_size
))
link_to_file_list
(
keycache
,
block
,
block
->
hash_link
->
file
,
1
);
...
...
@@ -3251,14 +3283,24 @@ int key_cache_write(KEY_CACHE *keycache,
*/
remove_reader
(
block
);
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
/* Error injection for coverage testing. */
DBUG_EXECUTE_IF
(
"key_cache_write_block_error"
,
block
->
status
|=
BLOCK_ERROR
;);
if
(
block
->
status
&
BLOCK_ERROR
)
/* Do not link erroneous blocks into the LRU ring, but free them. */
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
/*
Link the block into the LRU ring if it's the last submitted
request for the block. This enables eviction for the block.
*/
unreg_request
(
keycache
,
block
,
1
);
}
else
{
/* Pretend a "clean" block to avoid complications. */
block
->
status
&=
~
(
BLOCK_CHANGED
);
free_block
(
keycache
,
block
);
error
=
1
;
break
;
}
...
...
@@ -3342,8 +3384,9 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
{
KEYCACHE_THREAD_TRACE
(
"free block"
);
KEYCACHE_DBUG_PRINT
(
"free_block"
,
(
"block %u to be freed, hash_link %p"
,
BLOCK_NUMBER
(
block
),
block
->
hash_link
));
(
"block %u to be freed, hash_link %p status: %u"
,
BLOCK_NUMBER
(
block
),
block
->
hash_link
,
block
->
status
));
/*
Assert that the block is not free already. And that it is in a clean
state. Note that the block might just be assigned to a hash_link and
...
...
@@ -3425,10 +3468,14 @@ static void free_block(KEY_CACHE *keycache, BLOCK_LINK *block)
if
(
block
->
status
&
BLOCK_IN_EVICTION
)
return
;
/* Here the block must be in the LRU ring. Unlink it again. */
DBUG_ASSERT
(
block
->
next_used
&&
block
->
prev_used
&&
*
block
->
prev_used
==
block
);
unlink_block
(
keycache
,
block
);
/* Error blocks are not put into the LRU ring. */
if
(
!
(
block
->
status
&
BLOCK_ERROR
))
{
/* Here the block must be in the LRU ring. Unlink it again. */
DBUG_ASSERT
(
block
->
next_used
&&
block
->
prev_used
&&
*
block
->
prev_used
==
block
);
unlink_block
(
keycache
,
block
);
}
if
(
block
->
temperature
==
BLOCK_WARM
)
keycache
->
warm_blocks
--
;
block
->
temperature
=
BLOCK_COLD
;
...
...
@@ -3517,8 +3564,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
(
BLOCK_READ
|
BLOCK_IN_FLUSH
|
BLOCK_CHANGED
|
BLOCK_IN_USE
));
block
->
status
|=
BLOCK_IN_FLUSHWRITE
;
keycache_pthread_mutex_unlock
(
&
keycache
->
cache_lock
);
error
=
my_pwrite
(
file
,
block
->
buffer
+
block
->
offset
,
error
=
my_pwrite
(
file
,
block
->
buffer
+
block
->
offset
,
block
->
length
-
block
->
offset
,
block
->
hash_link
->
diskpos
+
block
->
offset
,
MYF
(
MY_NABP
|
MY_WAIT_IF_FULL
));
...
...
@@ -3545,7 +3591,6 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
right queue anyway.
*/
link_to_file_list
(
keycache
,
block
,
file
,
1
);
}
block
->
status
&=
~
BLOCK_IN_FLUSH
;
/*
...
...
@@ -3581,7 +3626,7 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
/*
f
lush all key blocks for a file to disk, but don't do any mutex locks.
F
lush all key blocks for a file to disk, but don't do any mutex locks.
SYNOPSIS
flush_key_blocks_int()
...
...
@@ -3614,8 +3659,8 @@ static int flush_key_blocks_int(KEY_CACHE *keycache,
file
,
keycache
->
blocks_used
,
keycache
->
blocks_changed
));
#if !defined(DBUG_OFF) && defined(EXTRA_DEBUG)
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
keycache
,
"start of flush_key_blocks"
,
0
););
DBUG_EXECUTE
(
"check_keycache"
,
test_key_cache
(
keycache
,
"start of flush_key_blocks"
,
0
););
#endif
cache
=
cache_buff
;
...
...
@@ -3746,7 +3791,6 @@ restart:
{
/* It's a temporary file */
DBUG_ASSERT
(
!
(
block
->
status
&
BLOCK_REASSIGNED
));
/*
free_block() must not be called with BLOCK_CHANGED. Note
that we must not change the BLOCK_CHANGED flag outside of
...
...
@@ -4457,8 +4501,8 @@ static void keycache_debug_print(const char * fmt,...)
va_start
(
args
,
fmt
);
if
(
keycache_debug_log
)
{
VOID
(
vfprintf
(
keycache_debug_log
,
fmt
,
args
)
);
VOID
(
fputc
(
'\n'
,
keycache_debug_log
)
);
(
void
)
vfprintf
(
keycache_debug_log
,
fmt
,
args
);
(
void
)
fputc
(
'\n'
,
keycache_debug_log
);
}
va_end
(
args
);
}
...
...
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