Commit cd326536 authored by unknown's avatar unknown

Postmerge fixes.

added forgoten file.

The patch broke maria.test (will be fixed later)


sql/handler.cc:
  Pagecache block should be equal maria block.
sql/mysqld.cc:
  parameters Fixed.
storage/maria/ma_bitmap.c:
  fixed typo.
storage/maria/ma_blockrec.c:
  fixed typo.
storage/maria/ma_delete_all.c:
  fixed typo.
storage/maria/ma_page.c:
  fixed typo.
storage/maria/ma_pagecache.c:
  pin/lock debugging protection activated by default.
storage/maria/ma_pagecaches.c:
  parameters Fixed.
storage/maria/ma_preload.c:
  fixed typo.
mysys/my_safehash.c:
  New BitKeeper file ``mysys/my_safehash.c''
parent 142bfb37
/* Copyright (C) 2003-2007 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/*
Handling of multiple key caches
The idea is to have a thread safe hash on the table name,
with a default key cache value that is returned if the table name is not in
the cache.
*/
#include "mysys_priv.h"
#include <m_string.h>
#include "my_safehash.h"
/*****************************************************************************
General functions to handle SAFE_HASH objects.
A SAFE_HASH object is used to store the hash, the mutex and default value
needed by the rest of the key cache code.
This is a separate struct to make it easy to later reuse the code for other
purposes
All entries are linked in a list to allow us to traverse all elements
and delete selected ones. (HASH doesn't allow any easy ways to do this).
*****************************************************************************/
/*
Free a SAFE_HASH_ENTRY
SYNOPSIS
safe_hash_entry_free()
entry The entry which should be freed
NOTE
This function is called by the hash object on delete
*/
static void safe_hash_entry_free(SAFE_HASH_ENTRY *entry)
{
DBUG_ENTER("free_assign_entry");
my_free((gptr) entry, MYF(0));
DBUG_VOID_RETURN;
}
/*
Get key and length for a SAFE_HASH_ENTRY
SYNOPSIS
safe_hash_entry_get()
entry The entry for which the key should be returned
length Length of the key
RETURN
# reference on the key
*/
static byte *safe_hash_entry_get(SAFE_HASH_ENTRY *entry, uint *length,
my_bool not_used __attribute__((unused)))
{
*length= entry->length;
return (byte*) entry->key;
}
/*
Init a SAFE_HASH object
SYNOPSIS
safe_hash_init()
hash safe_hash handler
elements Expected max number of elements
default_value default value
NOTES
In case of error we set hash->default_value to 0 to allow one to call
safe_hash_free on an object that couldn't be initialized.
RETURN
0 OK
1 error
*/
my_bool safe_hash_init(SAFE_HASH *hash, uint elements,
byte *default_value)
{
DBUG_ENTER("safe_hash");
if (hash_init(&hash->hash, &my_charset_bin, elements,
0, 0, (hash_get_key) safe_hash_entry_get,
(void (*)(void*)) safe_hash_entry_free, 0))
{
hash->default_value= 0;
DBUG_RETURN(1);
}
my_rwlock_init(&hash->mutex, 0);
hash->default_value= default_value;
hash->root= 0;
DBUG_RETURN(0);
}
/*
Free a SAFE_HASH object
SYNOPSIS
safe_hash_free()
hash Hash handle
NOTES
This is safe to call on any object that has been sent to safe_hash_init()
*/
void safe_hash_free(SAFE_HASH *hash)
{
/*
Test if safe_hash_init succeeded. This will also guard us against multiple
free calls.
*/
if (hash->default_value)
{
hash_free(&hash->hash);
rwlock_destroy(&hash->mutex);
hash->default_value=0;
}
}
/*
Return the value stored for a key or default value if no key
SYNOPSIS
safe_hash_search()
hash Hash handle
key key (path to table etc..)
length Length of key
def Default value of data
RETURN
# data associated with the key of default value if data was not found
*/
byte *safe_hash_search(SAFE_HASH *hash, const byte *key, uint length,
byte *def)
{
byte *result;
DBUG_ENTER("safe_hash_search");
rw_rdlock(&hash->mutex);
result= hash_search(&hash->hash, key, length);
rw_unlock(&hash->mutex);
if (!result)
result= def;
else
result= ((SAFE_HASH_ENTRY*) result)->data;
DBUG_PRINT("exit",("data: 0x%lx", (long) result));
DBUG_RETURN(result);
}
/*
Associate a key with some data
SYNOPSIS
safe_hash_set()
hash Hash handle
key key (path to table etc..)
length Length of key
data data to to associate with the data
NOTES
This can be used both to insert a new entry and change an existing
entry.
If one associates a key with the default key cache, the key is deleted
RETURN
0 OK
1 error (Can only be EOM). In this case my_message() is called.
*/
my_bool safe_hash_set(SAFE_HASH *hash, const byte *key, uint length,
byte *data)
{
SAFE_HASH_ENTRY *entry;
my_bool error= 0;
DBUG_ENTER("safe_hash_set");
DBUG_PRINT("enter",("key: %.*s data: 0x%lx", length, key, (long) data));
rw_wrlock(&hash->mutex);
entry= (SAFE_HASH_ENTRY*) hash_search(&hash->hash, key, length);
if (data == hash->default_value)
{
/*
The key is to be associated with the default entry. In this case
we can just delete the entry (if it existed) from the hash as a
search will return the default entry
*/
if (!entry) /* nothing to do */
goto end;
/* unlink entry from list */
if ((*entry->prev= entry->next))
entry->next->prev= entry->prev;
hash_delete(&hash->hash, (byte*) entry);
goto end;
}
if (entry)
{
/* Entry existed; Just change the pointer to point at the new data */
entry->data= data;
}
else
{
if (!(entry= (SAFE_HASH_ENTRY *) my_malloc(sizeof(*entry) + length,
MYF(MY_WME))))
{
error= 1;
goto end;
}
entry->key= (byte*) (entry +1);
memcpy((char*) entry->key, (char*) key, length);
entry->length= length;
entry->data= data;
/* Link entry to list */
if ((entry->next= hash->root))
entry->next->prev= &entry->next;
entry->prev= &hash->root;
hash->root= entry;
if (my_hash_insert(&hash->hash, (byte*) entry))
{
/* This can only happen if hash got out of memory */
my_free((char*) entry, MYF(0));
error= 1;
goto end;
}
}
end:
rw_unlock(&hash->mutex);
DBUG_RETURN(error);
}
/*
Change all entries with one data value to another data value
SYNOPSIS
safe_hash_change()
hash Hash handle
old_data Old data
new_data Change all 'old_data' to this
NOTES
We use the linked list to traverse all elements in the hash as
this allows us to delete elements in the case where 'new_data' is the
default value.
*/
void safe_hash_change(SAFE_HASH *hash, byte *old_data, byte *new_data)
{
SAFE_HASH_ENTRY *entry, *next;
DBUG_ENTER("safe_hash_set");
rw_wrlock(&hash->mutex);
for (entry= hash->root ; entry ; entry= next)
{
next= entry->next;
if (entry->data == old_data)
{
if (new_data == hash->default_value)
{
if ((*entry->prev= entry->next))
entry->next->prev= entry->prev;
hash_delete(&hash->hash, (byte*) entry);
}
else
entry->data= new_data;
}
}
rw_unlock(&hash->mutex);
DBUG_VOID_RETURN;
}
......@@ -2796,13 +2796,12 @@ int ha_init_pagecache(const char *name, PAGECACHE *pagecache)
{
pthread_mutex_lock(&LOCK_global_system_variables);
long tmp_buff_size= (long) pagecache->param_buff_size;
long tmp_block_size= (long) pagecache->param_block_size;
uint division_limit= pagecache->param_division_limit;
uint age_threshold= pagecache->param_age_threshold;
pthread_mutex_unlock(&LOCK_global_system_variables);
DBUG_RETURN(!init_pagecache(pagecache,
tmp_buff_size, division_limit, age_threshold,
tmp_block_size));
MARIA_KEY_BLOCK_LENGTH));
}
DBUG_RETURN(0);
}
......
......@@ -2210,7 +2210,7 @@ and this may fail.\n\n");
(ulong) dflt_key_cache->key_cache_mem_size);
#ifdef WITH_MARIA_STORAGE_ENGINE
fprintf(stderr, "page_buffer_size=%lu\n",
(ulong) dflt_pagecache->mem_size);
(ulong) maria_pagecache->mem_size);
#endif /* WITH_MARIA_STORAGE_ENGINE */
fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
......@@ -2220,7 +2220,7 @@ and this may fail.\n\n");
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
#ifdef WITH_MARIA_STORAGE_ENGINE
(ulong) dflt_pagecache->mem_size +
(ulong) maria_pagecache->mem_size +
#endif /* WITH_MARIA_STORAGE_ENGINE */
(global_system_variables.read_buff_size +
global_system_variables.sortbuff_size) *
......@@ -2778,7 +2778,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
set_server_version();
#ifdef WITH_MARIA_STORAGE_ENGINE
if (!(dflt_pagecache= get_or_create_pagecache(maria_pagecache_base.str,
if (!(maria_pagecache= get_or_create_pagecache(maria_pagecache_base.str,
maria_pagecache_base.length)))
exit(1);
/*
......@@ -6091,15 +6091,6 @@ log and this option does nothing anymore.",
MARIA_KEY_BLOCK_LENGTH, MARIA_MIN_KEY_BLOCK_LENGTH,
MARIA_MAX_KEY_BLOCK_LENGTH,
0, MARIA_MIN_KEY_BLOCK_LENGTH, 0},
{"maria_key_buffer_size", OPT_KEY_BUFFER_SIZE,
"The size of the buffer used for index blocks for Maria tables. Increase "
"this to get better index handling (for all reads and multiple writes) to "
"as much as you can afford; 64M on a 256M machine that mainly runs MySQL "
"is quite common.",
(gptr*) &maria_pagecache_var.param_buff_size, (gptr*) 0,
0, (GET_ULL | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~(ulong) 0, MALLOC_OVERHEAD,
IO_SIZE, 0},
{"maria_max_sort_file_size", OPT_MARIA_MAX_SORT_FILE_SIZE,
"Don't use the fast sort index method to created index if the temporary "
"file would get bigger than this.",
......@@ -6293,26 +6284,20 @@ The minimum value for this variable is 4096.",
#ifdef WITH_MARIA_STORAGE_ENGINE
{"pagecache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
"This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache",
(gptr*) &dflt_pagecache_var.param_age_threshold,
(gptr*) &maria_pagecache_var.param_age_threshold,
(gptr*) 0,
0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
300, 100, ~0L, 0, 100, 0},
{"pagecache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
"The default size of key cache blocks",
(gptr*) &dflt_pagecache_var.param_block_size,
(gptr*) 0,
0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
{"pagecache_buffer_size", OPT_KEY_BUFFER_SIZE,
"The size of the buffer used for index blocks for MyISAM tables. Increase this to get better index handling (for all reads and multiple writes) to as much as you can afford; 64M on a 256M machine that mainly runs MySQL is quite common.",
(gptr*) &dflt_pagecache_var.param_buff_size,
(gptr*) &maria_pagecache_var.param_buff_size,
(gptr*) 0,
0, (GET_ULL | GET_ASK_ADDR),
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, ~(ulong) 0, MALLOC_OVERHEAD,
IO_SIZE, 0},
IO_SIZE, KEY_CACHE_SIZE},
{"pagecache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
"The minimum percentage of warm blocks in key cache",
(gptr*) &dflt_pagecache_var.param_division_limit,
(gptr*) &maria_pagecache_var.param_division_limit,
(gptr*) 0,
0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
1, 100, 0, 1, 0},
......@@ -7230,7 +7215,7 @@ static void mysql_init_variables(void)
multi_keycache_init();
#ifdef WITH_MARIA_STORAGE_ENGINE
/* set pagecache_hash.default_value = dflt_pagecache */
/* set pagecache_hash.default_value = maria_pagecache */
multi_pagecache_init();
#endif
......
......@@ -126,7 +126,7 @@ static inline my_bool write_changed_bitmap(MARIA_SHARE *share,
(PAGECACHE_FILE*)&bitmap->file, bitmap->page, 0,
(byte*) bitmap->map, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0));
}
......
......@@ -992,7 +992,7 @@ static my_bool write_tail(MARIA_HA *info,
&info->dfile, block->page, 0,
row_pos.buff,PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0));
}
......@@ -1065,7 +1065,7 @@ static my_bool write_full_pages(MARIA_HA *info,
&info->dfile, page, 0,
buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY,
0))
DBUG_RETURN(1);
......@@ -1599,7 +1599,7 @@ static my_bool write_block_record(MARIA_HA *info, const byte *record,
&info->dfile, head_block->page, 0,
page_buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0))
goto disk_err;
......@@ -1950,7 +1950,7 @@ static my_bool delete_head_or_tail(MARIA_HA *info,
&info->dfile, page, 0,
buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0))
DBUG_RETURN(1);
}
......
......@@ -67,7 +67,7 @@ int maria_delete_all_rows(MARIA_HA *info)
my_chsize(share->kfile.file, share->base.keystart, 0, MYF(MY_WME)) )
goto err;
if (_ma_initialize_data_file(info->dfile, info->s))
if (_ma_initialize_data_file(info->dfile.file, info->s))
goto err;
/*
......
......@@ -97,7 +97,7 @@ int _ma_write_keypage(register MARIA_HA *info, register MARIA_KEYDEF *keyinfo,
&info->s->kfile, page / keyinfo->block_length,
level, buff, PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0));
} /* maria_write_keypage */
......@@ -131,7 +131,7 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
&info->s->kfile, page_no, level, buff,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DELAY, 0,
offset, sizeof(buff)));
} /* _ma_dispose */
......@@ -142,7 +142,7 @@ int _ma_dispose(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, my_off_t pos,
my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
{
my_off_t pos;
byte buff[8];
byte *buff;
DBUG_ENTER("_ma_new");
if ((pos= info->s->state.key_del) == HA_OFFSET_ERROR)
......@@ -158,6 +158,7 @@ my_off_t _ma_new(register MARIA_HA *info, MARIA_KEYDEF *keyinfo, int level)
}
else
{
buff= alloca(info->s->block_size);
DBUG_ASSERT(info->s->pagecache->block_size == keyinfo->block_length &&
info->s->pagecache->block_size == info->s->block_size);
/*
......
......@@ -194,7 +194,7 @@ static char *page_cache_page_pin_str[]=
(char*)"pinned -> unpinned"
};
#endif
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
typedef struct st_pagecache_pin_info
{
struct st_pagecache_pin_info *next, **prev;
......@@ -289,7 +289,7 @@ struct st_pagecache_block_link
byte *buffer; /* buffer for the block page */
uint status; /* state of the block */
uint pins; /* pin counter */
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
PAGECACHE_PIN_INFO *pin_list;
PAGECACHE_LOCK_INFO *lock_list;
#endif
......@@ -301,10 +301,7 @@ struct st_pagecache_block_link
KEYCACHE_CONDVAR *condvar; /* condition variable for 'no readers' event */
};
PAGECACHE dflt_pagecache_var;
PAGECACHE *dflt_pagecache= &dflt_pagecache_var;
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
/* debug checks */
static my_bool info_check_pin(PAGECACHE_BLOCK_LINK *block,
enum pagecache_page_pin mode)
......@@ -312,6 +309,9 @@ static my_bool info_check_pin(PAGECACHE_BLOCK_LINK *block,
struct st_my_thread_var *thread= my_thread_var;
PAGECACHE_PIN_INFO *info= info_find(block->pin_list, thread);
DBUG_ENTER("info_check_pin");
DBUG_PRINT("enter", ("info_check_pin: thread: 0x%lx pin: %s",
(ulong)thread,
page_cache_page_pin_str[mode]));
if (info)
{
if (mode == PAGECACHE_PIN_LEFT_UNPINNED)
......@@ -2051,7 +2051,7 @@ static void add_pin(PAGECACHE_BLOCK_LINK *block)
block->pins));
PCBLOCK_INFO(block);
block->pins++;
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
{
PAGECACHE_PIN_INFO *info=
(PAGECACHE_PIN_INFO *)my_malloc(sizeof(PAGECACHE_PIN_INFO), MYF(0));
......@@ -2071,7 +2071,7 @@ static void remove_pin(PAGECACHE_BLOCK_LINK *block)
PCBLOCK_INFO(block);
DBUG_ASSERT(block->pins > 0);
block->pins--;
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
{
PAGECACHE_PIN_INFO *info= info_find(block->pin_list, my_thread_var);
DBUG_ASSERT(info != 0);
......@@ -2081,7 +2081,7 @@ static void remove_pin(PAGECACHE_BLOCK_LINK *block)
#endif
DBUG_VOID_RETURN;
}
#ifdef PAGECACHE_DEBUG
#ifndef DBUG_OFF
static void info_add_lock(PAGECACHE_BLOCK_LINK *block, my_bool wl)
{
PAGECACHE_LOCK_INFO *info=
......@@ -2237,10 +2237,8 @@ static my_bool make_lock_and_pin(PAGECACHE *pagecache,
page_cache_page_lock_str[lock],
page_cache_page_pin_str[pin]));
PCBLOCK_INFO(block);
#ifdef PAGECACHE_DEBUG
DBUG_ASSERT(info_check_pin(block, pin) == 0 &&
info_check_lock(block, lock, pin) == 0);
#endif
switch (lock)
{
case PAGECACHE_LOCK_WRITE: /* free -> write */
......
......@@ -38,7 +38,7 @@ static SAFE_HASH pagecache_hash;
my_bool multi_pagecache_init(void)
{
return safe_hash_init(&pagecache_hash, 16, (byte*) dflt_pagecache);
return safe_hash_init(&pagecache_hash, 16, (byte*) maria_pagecache);
}
......
......@@ -94,7 +94,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
(byte*) buff,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DONE, 0))
goto err;
}
......@@ -111,7 +111,7 @@ int maria_preload(MARIA_HA *info, ulonglong key_map, my_bool ignore_leaves)
(byte*) buff,
PAGECACHE_PLAIN_PAGE,
PAGECACHE_LOCK_LEFT_UNLOCKED,
PAGECACHE_PIN_LEFT_PINNED,
PAGECACHE_PIN_LEFT_UNPINNED,
PAGECACHE_WRITE_DONE, 0))
goto err;
pos+= length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment