mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
merge
This commit is contained in:
commit
e5d75fb984
125 changed files with 1754 additions and 1216 deletions
|
@ -8,7 +8,8 @@ c_warnings="$c_warnings $debug_extra_warnings"
|
|||
cxx_warnings="$cxx_warnings $debug_extra_warnings"
|
||||
extra_configs="$pentium_configs $debug_configs"
|
||||
|
||||
extra_configs="$extra_configs --with-berkeley-db --with-innodb --without-isam --with-embedded-server --with-openssl"
|
||||
# We want to test isam when building with valgrind
|
||||
extra_configs="$extra_configs --with-berkeley-db --with-innodb --with-isam --with-embedded-server --with-openssl"
|
||||
|
||||
. "$path/FINISH.sh"
|
||||
|
||||
|
|
|
@ -2571,7 +2571,7 @@ sql_real_connect(char *host,char *database,char *user,char *password,
|
|||
mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, default_charset);
|
||||
if (!mysql_real_connect(&mysql, host, user, password,
|
||||
database, opt_mysql_port, opt_mysql_unix_port,
|
||||
connect_flag | CLIENT_MULTI_QUERIES))
|
||||
connect_flag | CLIENT_MULTI_STATEMENTS))
|
||||
{
|
||||
if (!silent ||
|
||||
(mysql_errno(&mysql) != CR_CONN_HOST_ERROR &&
|
||||
|
|
|
@ -126,14 +126,14 @@ enum ha_extra_function {
|
|||
HA_EXTRA_RESET_STATE, /* Reset positions */
|
||||
HA_EXTRA_IGNORE_DUP_KEY, /* Dup keys don't rollback everything*/
|
||||
HA_EXTRA_NO_IGNORE_DUP_KEY,
|
||||
HA_EXTRA_RETRIEVE_ALL_COLS, /* Instructs InnoDB to retrieve all
|
||||
columns, not just those where
|
||||
field->query_id is the same as the
|
||||
current query id */
|
||||
/*
|
||||
Instructs InnoDB to retrieve all columns, not just those where
|
||||
field->query_id is the same as the current query id
|
||||
*/
|
||||
HA_EXTRA_RETRIEVE_ALL_COLS,
|
||||
HA_EXTRA_PREPARE_FOR_DELETE,
|
||||
HA_EXTRA_PREPARE_FOR_UPDATE, /* Remove read cache if problems */
|
||||
HA_EXTRA_PRELOAD_BUFFER_SIZE, /* Set buffer size for preloading */
|
||||
HA_EXTRA_SET_KEY_CACHE /* Set ref to assigned key cache */
|
||||
};
|
||||
|
||||
/* The following is parameter to ha_panic() */
|
||||
|
|
|
@ -27,5 +27,9 @@
|
|||
#define pthread_mutex_lock(A)
|
||||
#define pthread_mutex_unlock(A)
|
||||
#define pthread_mutex_destroy(A)
|
||||
|
||||
#define my_rwlock_init(A,B)
|
||||
#define rw_rdlock(A)
|
||||
#define rw_wrlock(A)
|
||||
#define rw_unlock(A)
|
||||
#define rwlock_destroy(A)
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2000 MySQL AB
|
||||
/* Copyright (C) 2000-2003 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
|
||||
|
@ -111,6 +111,7 @@ extern int NEAR my_errno; /* Last error in mysys */
|
|||
#define MY_WAIT_FOR_USER_TO_FIX_PANIC 60 /* in seconds */
|
||||
#define MY_WAIT_GIVE_USER_A_MESSAGE 10 /* Every 10 times of prev */
|
||||
#define MIN_COMPRESS_LENGTH 50 /* Don't compress small bl. */
|
||||
#define DFLT_INIT_HITS 3
|
||||
|
||||
/* root_alloc flags */
|
||||
#define MY_KEEP_PREALLOC 1
|
||||
|
@ -510,13 +511,13 @@ typedef struct st_key_cache* KEY_CACHE_HANDLE;
|
|||
|
||||
/* Key cache variable structure */
|
||||
/*
|
||||
The structure contains the parameters of a key cache that can
|
||||
be set and undated by regular set global statements.
|
||||
It also contains read-only statistics parameters.
|
||||
If the corresponding key cache data structure has been already
|
||||
created the variable contains the key cache handle.
|
||||
The variables are put into a named list called key_caches.
|
||||
At present the variables are only added to this list.
|
||||
The structure contains the parameters of a key cache that can
|
||||
be set and undated by regular set global statements.
|
||||
It also contains read-only statistics parameters.
|
||||
If the corresponding key cache data structure has been already
|
||||
created the variable contains the key cache handle.
|
||||
The variables are put into a named list called key_caches.
|
||||
At present the variables are only added to this list.
|
||||
*/
|
||||
typedef struct st_key_cache_var
|
||||
{
|
||||
|
@ -532,16 +533,16 @@ typedef struct st_key_cache_var
|
|||
ulong cache_r_requests; /* number of read requests (read hits) */
|
||||
ulong cache_read; /* number of reads from files to the cache */
|
||||
int blocks; /* max number of blocks in the cache */
|
||||
my_bool in_init; /* Set to 1 in MySQL during init/resize */
|
||||
struct st_key_cache_asmt *assign_list; /* list of assignments to the cache */
|
||||
int assignments; /* number of not completed assignments */
|
||||
void (*action)(void *); /* optional call back function */
|
||||
void *extra_info; /* ptr to extra info */
|
||||
} KEY_CACHE_VAR;
|
||||
|
||||
#define DEFAULT_KEY_CACHE_NAME "default"
|
||||
|
||||
extern KEY_CACHE_HANDLE *dflt_keycache;
|
||||
extern KEY_CACHE_VAR dflt_key_cache_var;
|
||||
#define DFLT_INIT_HITS 3
|
||||
|
||||
#include <my_alloc.h>
|
||||
|
||||
|
@ -701,7 +702,15 @@ extern int key_cache_write(KEY_CACHE_HANDLE keycache,
|
|||
uint block_length,int force_write);
|
||||
extern int flush_key_blocks(KEY_CACHE_HANDLE keycache,
|
||||
int file, enum flush_type type);
|
||||
extern void end_key_cache(KEY_CACHE_HANDLE *pkeycache,my_bool cleanup);
|
||||
extern void end_key_cache(KEY_CACHE_HANDLE keycache, my_bool cleanup);
|
||||
extern my_bool multi_keycache_init(void);
|
||||
extern void multi_keycache_free(void);
|
||||
extern KEY_CACHE_HANDLE *multi_key_cache_search(byte *key, uint length);
|
||||
extern my_bool multi_key_cache_set(const byte *key, uint length,
|
||||
KEY_CACHE_HANDLE *key_cache);
|
||||
extern void multi_key_cache_change(KEY_CACHE_HANDLE *old_data,
|
||||
KEY_CACHE_HANDLE *new_data);
|
||||
|
||||
extern sig_handler my_set_alarm_variable(int signo);
|
||||
extern void my_string_ptr_sort(void *base,uint items,size_s size);
|
||||
extern void radixsort_for_str_ptr(uchar* base[], uint number_of_elements,
|
||||
|
|
|
@ -324,7 +324,7 @@ typedef struct st_mi_check_param
|
|||
sort_buffer_length,sort_key_blocks;
|
||||
uint out_flag,warning_printed,error_printed,verbose;
|
||||
uint opt_sort_key,total_files,max_level;
|
||||
uint testflag;
|
||||
uint testflag, key_cache_block_size;
|
||||
uint8 language;
|
||||
my_bool using_global_keycache, opt_lock_memory, opt_follow_links;
|
||||
my_bool retry_repair, force_sort, calc_checksum;
|
||||
|
@ -388,7 +388,6 @@ int change_to_newfile(const char * filename, const char * old_ext,
|
|||
int lock_file(MI_CHECK *param, File file, my_off_t start, int lock_type,
|
||||
const char *filetype, const char *filename);
|
||||
void lock_memory(MI_CHECK *param);
|
||||
int flush_blocks(MI_CHECK *param, File file);
|
||||
void update_auto_increment_key(MI_CHECK *param, MI_INFO *info,
|
||||
my_bool repair);
|
||||
int update_state_info(MI_CHECK *param, MI_INFO *info,uint update);
|
||||
|
@ -408,9 +407,10 @@ my_bool mi_test_if_sort_rep(MI_INFO *info, ha_rows rows, ulonglong key_map,
|
|||
int mi_init_bulk_insert(MI_INFO *info, ulong cache_size, ha_rows rows);
|
||||
void mi_flush_bulk_insert(MI_INFO *info, uint inx);
|
||||
void mi_end_bulk_insert(MI_INFO *info);
|
||||
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
|
||||
KEY_CACHE_VAR *key_cache,
|
||||
pthread_mutex_t *assign_lock);
|
||||
int mi_assign_to_key_cache(MI_INFO *info, ulonglong key_map,
|
||||
KEY_CACHE_VAR *key_cache);
|
||||
void mi_change_key_cache(KEY_CACHE_VAR *old_key_cache,
|
||||
KEY_CACHE_VAR *new_key_cache);
|
||||
int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -411,6 +411,9 @@ int STDCALL mysql_dump_debug_info(MYSQL *mysql);
|
|||
int STDCALL mysql_refresh(MYSQL *mysql,
|
||||
unsigned int refresh_options);
|
||||
int STDCALL mysql_kill(MYSQL *mysql,unsigned long pid);
|
||||
int STDCALL mysql_set_server_option(MYSQL *mysql,
|
||||
enum enum_mysql_set_option
|
||||
option);
|
||||
int STDCALL mysql_ping(MYSQL *mysql);
|
||||
const char * STDCALL mysql_stat(MYSQL *mysql);
|
||||
const char * STDCALL mysql_get_server_info(MYSQL *mysql);
|
||||
|
|
|
@ -44,7 +44,7 @@ enum enum_server_command
|
|||
COM_TIME, COM_DELAYED_INSERT, COM_CHANGE_USER, COM_BINLOG_DUMP,
|
||||
COM_TABLE_DUMP, COM_CONNECT_OUT, COM_REGISTER_SLAVE,
|
||||
COM_PREPARE, COM_EXECUTE, COM_LONG_DATA, COM_CLOSE_STMT,
|
||||
COM_RESET_STMT,
|
||||
COM_RESET_STMT, COM_SET_OPTION,
|
||||
COM_END /* Must be last */
|
||||
};
|
||||
|
||||
|
@ -116,7 +116,7 @@ enum enum_server_command
|
|||
#define CLIENT_TRANSACTIONS 8192 /* Client knows about transactions */
|
||||
#define CLIENT_RESERVED 16384 /* Old flag for 4.1 protocol */
|
||||
#define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */
|
||||
#define CLIENT_MULTI_QUERIES 65536 /* Enable/disable multiquery support */
|
||||
#define CLIENT_MULTI_STATEMENTS 65536 /* Enable/disable multi-stmt support */
|
||||
#define CLIENT_MULTI_RESULTS 131072 /* Enable/disable multi-results */
|
||||
#define CLIENT_REMEMBER_OPTIONS (1L << 31)
|
||||
|
||||
|
@ -192,6 +192,7 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
|||
};
|
||||
|
||||
/* For backward compatibility */
|
||||
#define CLIENT_MULTI_QUERIES CLIENT_MULTI_STATEMENTS
|
||||
#define FIELD_TYPE_DECIMAL MYSQL_TYPE_DECIMAL
|
||||
#define FIELD_TYPE_TINY MYSQL_TYPE_TINY
|
||||
#define FIELD_TYPE_SHORT MYSQL_TYPE_SHORT
|
||||
|
@ -230,6 +231,13 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
|
|||
#define MYSQL_TYPE_UINT24 -4
|
||||
#endif
|
||||
|
||||
/* options for mysql_set_option */
|
||||
enum enum_mysql_set_option
|
||||
{
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_ON,
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_OFF
|
||||
};
|
||||
|
||||
#define net_new_transaction(net) ((net)->pkt_nr=0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -302,4 +302,5 @@
|
|||
#define ER_WRONG_NAME_FOR_CATALOG 1283
|
||||
#define ER_WARN_QC_RESIZE 1284
|
||||
#define ER_BAD_FT_COLUMN 1285
|
||||
#define ER_ERROR_MESSAGES 286
|
||||
#define ER_UNKNOWN_KEY_CACHE 1286
|
||||
#define ER_ERROR_MESSAGES 287
|
||||
|
|
|
@ -1629,9 +1629,6 @@ NetWare. */
|
|||
|
||||
srv_file_per_table = srv_file_per_table_original_value;
|
||||
|
||||
fprintf(stderr,
|
||||
"TODO: make sure MySQL sets field->query_id right in prepare/execute\n");
|
||||
|
||||
return((int) DB_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -1088,10 +1088,20 @@ mysql_refresh(MYSQL *mysql,uint options)
|
|||
int STDCALL
|
||||
mysql_kill(MYSQL *mysql,ulong pid)
|
||||
{
|
||||
char buff[12];
|
||||
char buff[4];
|
||||
DBUG_ENTER("mysql_kill");
|
||||
int4store(buff,pid);
|
||||
DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,4,0));
|
||||
DBUG_RETURN(simple_command(mysql,COM_PROCESS_KILL,buff,sizeof(buff),0));
|
||||
}
|
||||
|
||||
|
||||
int STDCALL
|
||||
mysql_set_server_option(MYSQL *mysql, enum enum_mysql_set_option option)
|
||||
{
|
||||
char buff[2];
|
||||
DBUG_ENTER("mysql_set_server_option");
|
||||
int2store(buff, (uint) option);
|
||||
DBUG_RETURN(simple_command(mysql, COM_SET_OPTION, buff, sizeof(buff), 0));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ EXPORTS
|
|||
mysql_init
|
||||
mysql_insert_id
|
||||
mysql_kill
|
||||
mysql_set_server_option
|
||||
mysql_list_dbs
|
||||
mysql_list_fields
|
||||
mysql_list_processes
|
||||
|
|
|
@ -225,7 +225,8 @@ FT_INFO *ft_init_nlq_search(MI_INFO *info, uint keynr, byte *query,
|
|||
if (flags & FT_EXPAND && ft_query_expansion_limit)
|
||||
{
|
||||
QUEUE best;
|
||||
init_queue(&best,ft_query_expansion_limit,0,0, &FT_DOC_cmp, 0);
|
||||
init_queue(&best,ft_query_expansion_limit,0,0, (queue_compare) &FT_DOC_cmp,
|
||||
0);
|
||||
tree_walk(&aio.dtree, (tree_walk_action) &walk_and_push,
|
||||
&best, left_root_right);
|
||||
while (best.elements)
|
||||
|
|
|
@ -53,13 +53,17 @@ const struct _ft_vft _ft_vft_boolean = {
|
|||
ft_boolean_get_relevance, ft_boolean_reinit_search
|
||||
};
|
||||
|
||||
|
||||
FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
|
||||
byte *query, uint query_len, byte *record)
|
||||
{
|
||||
FT_INFO *res;
|
||||
if (flags & FT_BOOL)
|
||||
ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len);
|
||||
res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len);
|
||||
else
|
||||
ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags, record);
|
||||
res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags,
|
||||
record);
|
||||
return res;
|
||||
}
|
||||
|
||||
const char *ft_stopword_file = 0;
|
||||
|
|
|
@ -77,6 +77,7 @@ void myisamchk_init(MI_CHECK *param)
|
|||
param->tmpfile_createflag=O_RDWR | O_TRUNC | O_EXCL;
|
||||
param->myf_rw=MYF(MY_NABP | MY_WME | MY_WAIT_IF_FULL);
|
||||
param->start_check_pos=0;
|
||||
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* Check the status flags for the table */
|
||||
|
@ -241,7 +242,7 @@ static int check_k_link(MI_CHECK *param, register MI_INFO *info, uint nr)
|
|||
if (next_link > info->state->key_file_length ||
|
||||
next_link & (info->s->blocksize-1))
|
||||
DBUG_RETURN(1);
|
||||
if (!(buff=key_cache_read(*info->s->keycache,
|
||||
if (!(buff=key_cache_read(*info->s->key_cache,
|
||||
info->s->kfile, next_link, DFLT_INIT_HITS,
|
||||
(byte*) info->buff,
|
||||
myisam_block_size, block_size, 1)))
|
||||
|
@ -272,7 +273,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
|
|||
|
||||
if (!(param->testflag & T_SILENT)) puts("- check file-size");
|
||||
|
||||
flush_key_blocks(*info->s->keycache,
|
||||
flush_key_blocks(*info->s->key_cache,
|
||||
info->s->kfile, FLUSH_FORCE_WRITE); /* If called externally */
|
||||
|
||||
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
|
||||
|
@ -1142,8 +1143,8 @@ int mi_repair(MI_CHECK *param, register MI_INFO *info,
|
|||
param->testflag|=T_REP; /* for easy checking */
|
||||
|
||||
if (!param->using_global_keycache)
|
||||
VOID(init_key_cache(dflt_keycache,dflt_key_cache_var.block_size,
|
||||
param->use_buffers,&dflt_key_cache_var));
|
||||
VOID(init_key_cache(dflt_keycache, param->key_cache_block_size,
|
||||
param->use_buffers, &dflt_key_cache_var));
|
||||
|
||||
if (init_io_cache(¶m->read_cache,info->dfile,
|
||||
(uint) param->read_buffer_length,
|
||||
|
@ -1364,7 +1365,7 @@ err:
|
|||
VOID(end_io_cache(¶m->read_cache));
|
||||
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
|
||||
VOID(end_io_cache(&info->rec_cache));
|
||||
got_error|=flush_blocks(param,share->kfile);
|
||||
got_error|=flush_blocks(param, *share->key_cache, share->kfile);
|
||||
if (!got_error && param->testflag & T_UNPACK)
|
||||
{
|
||||
share->state.header.options[0]&= (uchar) ~HA_OPTION_COMPRESS_RECORD;
|
||||
|
@ -1500,15 +1501,15 @@ void lock_memory(MI_CHECK *param __attribute__((unused)))
|
|||
|
||||
/* Flush all changed blocks to disk */
|
||||
|
||||
int flush_blocks(MI_CHECK *param, File file)
|
||||
int flush_blocks(MI_CHECK *param, KEY_CACHE_HANDLE key_cache, File file)
|
||||
{
|
||||
if (flush_key_blocks(*dflt_keycache,file,FLUSH_RELEASE))
|
||||
if (flush_key_blocks(key_cache, file, FLUSH_RELEASE))
|
||||
{
|
||||
mi_check_print_error(param,"%d when trying to write bufferts",my_errno);
|
||||
return(1);
|
||||
}
|
||||
if (!param->using_global_keycache)
|
||||
end_key_cache(dflt_keycache,1);
|
||||
end_key_cache(key_cache,1);
|
||||
return 0;
|
||||
} /* flush_blocks */
|
||||
|
||||
|
@ -1563,7 +1564,7 @@ int mi_sort_index(MI_CHECK *param, register MI_INFO *info, my_string name)
|
|||
}
|
||||
|
||||
/* Flush key cache for this file if we are calling this outside myisamchk */
|
||||
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
|
||||
share->state.version=(ulong) time((time_t*) 0);
|
||||
old_state= share->state; /* save state if not stored */
|
||||
|
@ -1873,7 +1874,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||
Flush key cache for this file if we are calling this outside
|
||||
myisamchk
|
||||
*/
|
||||
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
/* Clear the pointers to the given rows */
|
||||
for (i=0 ; i < share->base.keys ; i++)
|
||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
||||
|
@ -1883,7 +1884,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
|
||||
if (flush_key_blocks(*share->key_cache,share->kfile, FLUSH_FORCE_WRITE))
|
||||
goto err;
|
||||
key_map= ~key_map; /* Create the missing keys */
|
||||
}
|
||||
|
@ -2075,7 +2076,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info,
|
|||
memcpy( &share->state.state, info->state, sizeof(*info->state));
|
||||
|
||||
err:
|
||||
got_error|= flush_blocks(param,share->kfile);
|
||||
got_error|= flush_blocks(param, *share->key_cache, share->kfile);
|
||||
VOID(end_io_cache(&info->rec_cache));
|
||||
if (!got_error)
|
||||
{
|
||||
|
@ -2236,7 +2237,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
Flush key cache for this file if we are calling this outside
|
||||
myisamchk
|
||||
*/
|
||||
flush_key_blocks(*share->keycache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
flush_key_blocks(*share->key_cache,share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
/* Clear the pointers to the given rows */
|
||||
for (i=0 ; i < share->base.keys ; i++)
|
||||
share->state.key_root[i]= HA_OFFSET_ERROR;
|
||||
|
@ -2246,7 +2247,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
}
|
||||
else
|
||||
{
|
||||
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_FORCE_WRITE))
|
||||
if (flush_key_blocks(*share->key_cache,share->kfile, FLUSH_FORCE_WRITE))
|
||||
goto err;
|
||||
key_map= ~key_map; /* Create the missing keys */
|
||||
}
|
||||
|
@ -2482,7 +2483,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
|
|||
memcpy(&share->state.state, info->state, sizeof(*info->state));
|
||||
|
||||
err:
|
||||
got_error|= flush_blocks(param,share->kfile);
|
||||
got_error|= flush_blocks(param, *share->key_cache, share->kfile);
|
||||
VOID(end_io_cache(&info->rec_cache));
|
||||
if (!got_error)
|
||||
{
|
||||
|
@ -3087,7 +3088,8 @@ int sort_write_record(MI_SORT_PARAM *sort_param)
|
|||
(info->state->records % WRITE_COUNT) == 0)
|
||||
{
|
||||
char llbuff[22];
|
||||
printf("%s\r", llstr(info->state->records,llbuff)); VOID(fflush(stdout));
|
||||
printf("%s\r", llstr(info->state->records,llbuff));
|
||||
VOID(fflush(stdout));
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
|
|
|
@ -27,7 +27,6 @@ ha_checksum mi_checksum(MI_INFO *info, const byte *buf)
|
|||
for (i=info->s->base.fields ; i-- ; buf+=(rec++)->length)
|
||||
{
|
||||
const byte *pos;
|
||||
const byte *end;
|
||||
ulong length;
|
||||
switch (rec->type) {
|
||||
case FIELD_BLOB:
|
||||
|
|
|
@ -64,7 +64,7 @@ int mi_close(register MI_INFO *info)
|
|||
if (flag)
|
||||
{
|
||||
if (share->kfile >= 0 &&
|
||||
flush_key_blocks(*share->keycache,share->kfile,
|
||||
flush_key_blocks(*share->key_cache, share->kfile,
|
||||
share->temporary ? FLUSH_IGNORE_CHANGED :
|
||||
FLUSH_RELEASE))
|
||||
error=my_errno;
|
||||
|
|
|
@ -53,7 +53,7 @@ int mi_delete_all_rows(MI_INFO *info)
|
|||
If we are using delayed keys or if the user has done changes to the tables
|
||||
since it was locked then there may be key blocks in the key cache
|
||||
*/
|
||||
flush_key_blocks(*share->keycache, share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
flush_key_blocks(*share->key_cache, share->kfile, FLUSH_IGNORE_CHANGED);
|
||||
if (my_chsize(info->dfile, 0, 0, MYF(MY_WME)) ||
|
||||
my_chsize(share->kfile, share->base.keystart, 0, MYF(MY_WME)) )
|
||||
goto err;
|
||||
|
|
|
@ -329,7 +329,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||
break;
|
||||
case HA_EXTRA_FLUSH:
|
||||
if (!share->temporary)
|
||||
flush_key_blocks(*share->keycache,share->kfile,FLUSH_KEEP);
|
||||
flush_key_blocks(*share->key_cache, share->kfile, FLUSH_KEEP);
|
||||
#ifdef HAVE_PWRITE
|
||||
_mi_decrement_open_count(info);
|
||||
#endif
|
||||
|
@ -362,9 +362,6 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
|
|||
case HA_EXTRA_PRELOAD_BUFFER_SIZE:
|
||||
info->preload_buff_size= *((ulong *) extra_arg);
|
||||
break;
|
||||
case HA_EXTRA_SET_KEY_CACHE:
|
||||
share->reg_keycache= share->keycache= (KEY_CACHE_HANDLE *) extra_arg;
|
||||
break;
|
||||
case HA_EXTRA_KEY_CACHE:
|
||||
case HA_EXTRA_NO_KEY_CACHE:
|
||||
default:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
||||
/* Copyright (C) 2003 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
|
||||
|
@ -20,88 +20,136 @@
|
|||
|
||||
#include "myisamdef.h"
|
||||
|
||||
|
||||
/*
|
||||
Assign pages of the index file for a table to a key cache
|
||||
|
||||
SYNOPSIS
|
||||
mi_assign_to_keycache()
|
||||
mi_assign_to_key_cache()
|
||||
info open table
|
||||
map map of indexes to assign to the key cache
|
||||
key_map map of indexes to assign to the key cache
|
||||
key_cache_ptr pointer to the key cache handle
|
||||
assign_lock Mutex to lock during assignment
|
||||
|
||||
RETURN VALUE
|
||||
0 if a success. error code - otherwise.
|
||||
PREREQUESTS
|
||||
One must have a READ lock or a WRITE lock on the table when calling
|
||||
the function to ensure that there is no other writers to it.
|
||||
|
||||
NOTES.
|
||||
The caller must also ensure that one doesn't call this function from
|
||||
two different threads with the same table.
|
||||
|
||||
NOTES
|
||||
At present pages for all indexes must be assigned to the same key cache.
|
||||
In future only pages for indexes specified in the key_map parameter
|
||||
of the table will be assigned to the specified key cache.
|
||||
|
||||
RETURN VALUE
|
||||
0 If a success
|
||||
# Error code
|
||||
*/
|
||||
|
||||
typedef struct st_assign_extra_info
|
||||
int mi_assign_to_key_cache(MI_INFO *info,
|
||||
ulonglong key_map __attribute__((unused)),
|
||||
KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
pthread_mutex_t *lock;
|
||||
struct st_my_thread_var *waiting_thread;
|
||||
} ASSIGN_EXTRA_INFO;
|
||||
|
||||
static void remove_key_cache_assign(void *arg)
|
||||
{
|
||||
KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) arg;
|
||||
ASSIGN_EXTRA_INFO *extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info;
|
||||
struct st_my_thread_var *waiting_thread;
|
||||
pthread_mutex_t *lock= extra_info->lock;
|
||||
pthread_mutex_lock(lock);
|
||||
if (!(--key_cache->assignments) &&
|
||||
(waiting_thread = extra_info->waiting_thread))
|
||||
{
|
||||
my_free(extra_info, MYF(0));
|
||||
key_cache->extra_info= 0;
|
||||
if (waiting_thread != my_thread_var)
|
||||
pthread_cond_signal(&waiting_thread->suspend);
|
||||
}
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
int mi_assign_to_keycache(MI_INFO *info, ulonglong key_map,
|
||||
KEY_CACHE_VAR *key_cache,
|
||||
pthread_mutex_t *assign_lock)
|
||||
{
|
||||
ASSIGN_EXTRA_INFO *extra_info;
|
||||
int error= 0;
|
||||
MYISAM_SHARE* share= info->s;
|
||||
DBUG_ENTER("mi_assign_to_key_cache");
|
||||
DBUG_PRINT("enter",("old_key_cache_handle: %lx new_key_cache_handle: %lx",
|
||||
share->key_cache, &key_cache->cache));
|
||||
|
||||
DBUG_ENTER("mi_assign_to_keycache");
|
||||
/*
|
||||
Skip operation if we didn't change key cache. This can happen if we
|
||||
call this for all open instances of the same table
|
||||
*/
|
||||
if (*share->key_cache == key_cache->cache)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
share->reg_keycache= &key_cache->cache;
|
||||
pthread_mutex_lock(assign_lock);
|
||||
if (!(extra_info= (ASSIGN_EXTRA_INFO *) key_cache->extra_info))
|
||||
/*
|
||||
First flush all blocks for the table in the old key cache.
|
||||
This is to ensure that the disk is consistent with the data pages
|
||||
in memory (which may not be the case if the table uses delayed_key_write)
|
||||
|
||||
Note that some other read thread may still fill in the key cache with
|
||||
new blocks during this call and after, but this doesn't matter as
|
||||
all threads will start using the new key cache for their next call to
|
||||
myisam library and we know that there will not be any changed blocks
|
||||
in the old key cache.
|
||||
*/
|
||||
|
||||
if (flush_key_blocks(*share->key_cache, share->kfile, FLUSH_REMOVE))
|
||||
{
|
||||
if (!(extra_info= (ASSIGN_EXTRA_INFO*) my_malloc(sizeof(ASSIGN_EXTRA_INFO),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||
key_cache->extra_info= extra_info;
|
||||
key_cache->action= remove_key_cache_assign;
|
||||
extra_info->lock= assign_lock;
|
||||
}
|
||||
key_cache->assignments++;
|
||||
pthread_mutex_unlock(assign_lock);
|
||||
|
||||
if (!(info->lock_type == F_WRLCK && share->w_locks))
|
||||
{
|
||||
if (flush_key_blocks(*share->keycache, share->kfile, FLUSH_REMOVE))
|
||||
{
|
||||
error=my_errno;
|
||||
mi_mark_crashed(info); /* Mark that table must be checked */
|
||||
}
|
||||
share->keycache= &key_cache->cache;
|
||||
}
|
||||
else
|
||||
{
|
||||
extra_info->waiting_thread= my_thread_var;
|
||||
error= my_errno;
|
||||
mi_mark_crashed(info); /* Mark that table must be checked */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Flush the new key cache for this file. This is needed to ensure
|
||||
that there is no old blocks (with outdated data) left in the new key
|
||||
cache from an earlier assign_to_keycache operation
|
||||
|
||||
(This can never fail as there is never any not written data in the
|
||||
new key cache)
|
||||
*/
|
||||
(void) flush_key_blocks(key_cache->cache, share->kfile, FLUSH_REMOVE);
|
||||
|
||||
/*
|
||||
Tell all threads to use the new key cache
|
||||
This should be seen at the lastes for the next call to an myisam function.
|
||||
*/
|
||||
share->key_cache= &key_cache->cache;
|
||||
|
||||
/* store the key cache in the global hash structure for future opens */
|
||||
if (multi_key_cache_set(share->unique_file_name, share->unique_name_length,
|
||||
share->key_cache))
|
||||
error= my_errno;
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Change all MyISAM entries that uses one key cache to another key cache
|
||||
|
||||
SYNOPSIS
|
||||
mi_change_key_cache()
|
||||
old_key_cache Old key cache
|
||||
new_key_cache New key cache
|
||||
|
||||
NOTES
|
||||
This is used when we delete one key cache.
|
||||
|
||||
To handle the case where some other threads tries to open an MyISAM
|
||||
table associated with the to-be-deleted key cache while this operation
|
||||
is running, we have to call 'multi_key_cache_change()' from this
|
||||
function while we have a lock on the MyISAM table list structure.
|
||||
|
||||
This is safe as long as it's only MyISAM that is using this specific
|
||||
key cache.
|
||||
*/
|
||||
|
||||
|
||||
void mi_change_key_cache(KEY_CACHE_VAR *old_key_cache,
|
||||
KEY_CACHE_VAR *new_key_cache)
|
||||
{
|
||||
LIST *pos;
|
||||
DBUG_ENTER("mi_change_key_cache");
|
||||
|
||||
/*
|
||||
Lock list to ensure that no one can close the table while we manipulate it
|
||||
*/
|
||||
pthread_mutex_lock(&THR_LOCK_myisam);
|
||||
for (pos=myisam_open_list ; pos ; pos=pos->next)
|
||||
{
|
||||
MI_INFO *info= (MI_INFO*) pos->data;
|
||||
MYISAM_SHARE *share= info->s;
|
||||
if (share->key_cache == &old_key_cache->cache)
|
||||
mi_assign_to_key_cache(info, (ulonglong) ~0, new_key_cache);
|
||||
}
|
||||
|
||||
/*
|
||||
We have to do the following call while we have the lock on the
|
||||
MyISAM list structure to ensure that another thread is not trying to
|
||||
open a new table that will be associted with the old key cache
|
||||
*/
|
||||
multi_key_cache_change(&old_key_cache->cache, &new_key_cache->cache);
|
||||
pthread_mutex_unlock(&THR_LOCK_myisam);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||
uint count;
|
||||
MYISAM_SHARE *share=info->s;
|
||||
uint flag;
|
||||
uint switch_fl= 0;
|
||||
DBUG_ENTER("mi_lock_database");
|
||||
DBUG_PRINT("info",("lock_type: %d", lock_type));
|
||||
|
||||
|
@ -61,21 +60,13 @@ int mi_lock_database(MI_INFO *info, int lock_type)
|
|||
else
|
||||
count= --share->w_locks;
|
||||
--share->tot_locks;
|
||||
/*
|
||||
During a key cache reassignment the current and registered
|
||||
key caches for the table are different.
|
||||
*/
|
||||
if (info->lock_type == F_WRLCK && !share->w_locks &&
|
||||
((switch_fl= share->keycache != share->reg_keycache) ||
|
||||
!share->delay_key_write) &&
|
||||
flush_key_blocks(*share->keycache, share->kfile,
|
||||
switch_fl ? FLUSH_REMOVE : FLUSH_KEEP))
|
||||
!share->delay_key_write && flush_key_blocks(*share->key_cache,
|
||||
share->kfile,FLUSH_KEEP))
|
||||
{
|
||||
error=my_errno;
|
||||
mi_mark_crashed(info); /* Mark that table must be checked */
|
||||
}
|
||||
if (switch_fl)
|
||||
share->keycache= share->reg_keycache;
|
||||
if (info->opt_flag & (READ_CACHE_USED | WRITE_CACHE_USED))
|
||||
{
|
||||
if (end_io_cache(&info->rec_cache))
|
||||
|
@ -398,7 +389,7 @@ int _mi_test_if_changed(register MI_INFO *info)
|
|||
{ /* Keyfile has changed */
|
||||
DBUG_PRINT("info",("index file changed"));
|
||||
if (share->state.process != share->this_process)
|
||||
VOID(flush_key_blocks(*share->keycache,share->kfile,FLUSH_RELEASE));
|
||||
VOID(flush_key_blocks(*share->key_cache, share->kfile, FLUSH_RELEASE));
|
||||
share->last_process=share->state.process;
|
||||
info->last_unique= share->state.unique;
|
||||
info->last_loop= share->state.update_count;
|
||||
|
|
|
@ -104,6 +104,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||
share_buff.state.rec_per_key_part=rec_per_key_part;
|
||||
share_buff.state.key_root=key_root;
|
||||
share_buff.state.key_del=key_del;
|
||||
share_buff.key_cache= multi_key_cache_search(name_buff, strlen(name_buff));
|
||||
|
||||
if ((kfile=my_open(name_buff,(open_mode=O_RDWR) | O_SHARE,MYF(0))) < 0)
|
||||
{
|
||||
|
@ -293,6 +294,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
|
|||
(char*) key_del, (sizeof(my_off_t) *
|
||||
share->state.header.max_block_size));
|
||||
strmov(share->unique_file_name, name_buff);
|
||||
share->unique_name_length= strlen(name_buff);
|
||||
strmov(share->index_file_name, index_name);
|
||||
strmov(share->data_file_name, data_name);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||
DBUG_ENTER("_mi_fetch_keypage");
|
||||
DBUG_PRINT("enter",("page: %ld",page));
|
||||
|
||||
tmp=(uchar*) key_cache_read(*info->s->keycache,
|
||||
tmp=(uchar*) key_cache_read(*info->s->key_cache,
|
||||
info->s->kfile, page, level, (byte*) buff,
|
||||
(uint) keyinfo->block_length,
|
||||
(uint) keyinfo->block_length,
|
||||
|
@ -52,6 +52,7 @@ uchar *_mi_fetch_keypage(register MI_INFO *info, MI_KEYDEF *keyinfo,
|
|||
{
|
||||
DBUG_PRINT("error",("page %lu had wrong page length: %u",
|
||||
(ulong) page, page_size));
|
||||
DBUG_DUMP("page", tmp, keyinfo->block_length);
|
||||
info->last_keypage = HA_OFFSET_ERROR;
|
||||
my_errno = HA_ERR_CRASHED;
|
||||
tmp = 0;
|
||||
|
@ -94,7 +95,7 @@ int _mi_write_keypage(register MI_INFO *info, register MI_KEYDEF *keyinfo,
|
|||
length=keyinfo->block_length;
|
||||
}
|
||||
#endif
|
||||
DBUG_RETURN((key_cache_write(*info->s->keycache,
|
||||
DBUG_RETURN((key_cache_write(*info->s->key_cache,
|
||||
info->s->kfile,page, level, (byte*) buff,length,
|
||||
(uint) keyinfo->block_length,
|
||||
(int) ((info->lock_type != F_UNLCK) ||
|
||||
|
@ -116,7 +117,7 @@ int _mi_dispose(register MI_INFO *info, MI_KEYDEF *keyinfo, my_off_t pos,
|
|||
info->s->state.key_del[keyinfo->block_size]=pos;
|
||||
mi_sizestore(buff,old_link);
|
||||
info->s->state.changed|= STATE_NOT_SORTED_PAGES;
|
||||
DBUG_RETURN(key_cache_write(*info->s->keycache,
|
||||
DBUG_RETURN(key_cache_write(*info->s->key_cache,
|
||||
info->s->kfile, pos , level, buff,
|
||||
sizeof(buff),
|
||||
(uint) keyinfo->block_length,
|
||||
|
@ -145,7 +146,7 @@ my_off_t _mi_new(register MI_INFO *info, MI_KEYDEF *keyinfo, int level)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!key_cache_read(*info->s->keycache,
|
||||
if (!key_cache_read(*info->s->key_cache,
|
||||
info->s->kfile, pos, level,
|
||||
buff,
|
||||
(uint) sizeof(buff),
|
||||
|
|
|
@ -48,7 +48,7 @@ int mi_panic(enum ha_panic_function flag)
|
|||
if (info->s->options & HA_OPTION_READ_ONLY_DATA)
|
||||
break;
|
||||
#endif
|
||||
if (flush_key_blocks(*info->s->keycache,info->s->kfile,FLUSH_RELEASE))
|
||||
if (flush_key_blocks(*info->s->key_cache, info->s->kfile, FLUSH_RELEASE))
|
||||
error=my_errno;
|
||||
if (info->opt_flag & WRITE_CACHE_USED)
|
||||
if (flush_io_cache(&info->rec_cache))
|
||||
|
|
|
@ -69,7 +69,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||
if (!(buff= (uchar *) my_malloc(length, MYF(MY_WME))))
|
||||
DBUG_RETURN(my_errno= HA_ERR_OUT_OF_MEM);
|
||||
|
||||
if (flush_key_blocks(*share->keycache,share->kfile, FLUSH_RELEASE))
|
||||
if (flush_key_blocks(*share->key_cache,share->kfile, FLUSH_RELEASE))
|
||||
goto err;
|
||||
|
||||
do
|
||||
|
@ -87,7 +87,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||
{
|
||||
if (mi_test_if_nod(buff))
|
||||
{
|
||||
if (key_cache_insert(*share->keycache,
|
||||
if (key_cache_insert(*share->key_cache,
|
||||
share->kfile, pos, DFLT_INIT_HITS,
|
||||
(byte*) buff, block_length))
|
||||
goto err;
|
||||
|
@ -99,7 +99,7 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (key_cache_insert(*share->keycache,
|
||||
if (key_cache_insert(*share->key_cache,
|
||||
share->kfile, pos, DFLT_INIT_HITS,
|
||||
(byte*) buff, length))
|
||||
goto err;
|
||||
|
|
|
@ -50,7 +50,7 @@ int main(int argc,char *argv[])
|
|||
MY_INIT(argv[0]);
|
||||
my_init();
|
||||
if (key_cacheing)
|
||||
init_key_cache(dflt_keycache,512,IO_SIZE*16,0);
|
||||
init_key_cache(dflt_keycache,KEY_CACHE_BLOCK_SIZE,IO_SIZE*16,0);
|
||||
get_options(argc,argv);
|
||||
|
||||
exit(run_test("test1"));
|
||||
|
|
|
@ -49,7 +49,7 @@ static int verbose=0,testflag=0,
|
|||
static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1,
|
||||
create_flag=0;
|
||||
static ulong key_cache_size=IO_SIZE*16;
|
||||
static uint key_cache_block_size=IO_SIZE;
|
||||
static uint key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
|
||||
|
||||
static uint keys=MYISAM_KEYS,recant=1000;
|
||||
static uint use_blob=0;
|
||||
|
@ -274,9 +274,9 @@ int main(int argc, char *argv[])
|
|||
puts("got error from mi_extra(HA_EXTRA_NO_CACHE)");
|
||||
goto end;
|
||||
}
|
||||
if (key_cacheing)
|
||||
resize_key_cache(dflt_keycache,key_cache_block_size,key_cache_size*2);
|
||||
}
|
||||
if (key_cacheing)
|
||||
resize_key_cache(dflt_keycache,key_cache_block_size,key_cache_size*2);
|
||||
|
||||
if (!silent)
|
||||
printf("- Delete\n");
|
||||
|
@ -829,7 +829,7 @@ reads: %10lu\n",
|
|||
my_cache_r_requests, my_cache_read);
|
||||
#endif
|
||||
}
|
||||
end_key_cache(dflt_keycache,1);
|
||||
end_key_cache(*dflt_keycache,1);
|
||||
if (blob_buffer)
|
||||
my_free(blob_buffer,MYF(0));
|
||||
my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO);
|
||||
|
|
|
@ -177,7 +177,7 @@ void start_test(int id)
|
|||
exit(1);
|
||||
}
|
||||
if (key_cacheing && rnd(2) == 0)
|
||||
init_key_cache(dflt_keycache,512,65536L,0);
|
||||
init_key_cache(dflt_keycache, KEY_CACHE_BLOCK_SIZE, 65536L,0);
|
||||
printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
|
||||
|
||||
for (error=i=0 ; i < tests && !error; i++)
|
||||
|
|
|
@ -715,6 +715,7 @@ static void get_options(register int *argc,register char ***argv)
|
|||
exit(1);
|
||||
|
||||
check_param.tmpdir=&myisamchk_tmpdir;
|
||||
check_param.key_cache_block_size= opt_key_cache_block_size;
|
||||
|
||||
if (set_charset_name)
|
||||
if (!(set_charset=get_charset_by_name(set_charset_name, MYF(MY_WME))))
|
||||
|
@ -1047,7 +1048,7 @@ static int myisamchk(MI_CHECK *param, my_string filename)
|
|||
HA_OPTION_COMPRESS_RECORD)) ||
|
||||
(param->testflag & (T_EXTEND | T_MEDIUM)))
|
||||
error|=chk_data_link(param, info, param->testflag & T_EXTEND);
|
||||
error|=flush_blocks(param,share->kfile);
|
||||
error|=flush_blocks(param, *share->key_cache, share->kfile);
|
||||
VOID(end_io_cache(¶m->read_cache));
|
||||
}
|
||||
if (!error)
|
||||
|
@ -1456,7 +1457,7 @@ static int mi_sort_records(MI_CHECK *param,
|
|||
if (share->state.key_root[sort_key] == HA_OFFSET_ERROR)
|
||||
DBUG_RETURN(0); /* Nothing to do */
|
||||
|
||||
init_key_cache(dflt_keycache,opt_key_cache_block_size,param->use_buffers,
|
||||
init_key_cache(dflt_keycache, opt_key_cache_block_size, param->use_buffers,
|
||||
&dflt_key_cache_var);
|
||||
if (init_io_cache(&info->rec_cache,-1,(uint) param->write_buffer_length,
|
||||
WRITE_CACHE,share->pack.header_length,1,
|
||||
|
@ -1571,7 +1572,8 @@ err:
|
|||
my_free(sort_info.buff,MYF(MY_ALLOW_ZERO_PTR));
|
||||
sort_info.buff=0;
|
||||
share->state.sortkey=sort_key;
|
||||
DBUG_RETURN(flush_blocks(param, share->kfile) | got_error);
|
||||
DBUG_RETURN(flush_blocks(param, *share->key_cache, share->kfile) |
|
||||
got_error);
|
||||
} /* sort_records */
|
||||
|
||||
|
||||
|
|
|
@ -166,8 +166,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
|
|||
char *data_file_name, /* Resolved path names from symlinks */
|
||||
*index_file_name;
|
||||
byte *file_map; /* mem-map of file if possible */
|
||||
KEY_CACHE_HANDLE *keycache; /* ref to the current key cache */
|
||||
KEY_CACHE_HANDLE *reg_keycache; /* ref to the registered key cache */
|
||||
KEY_CACHE_HANDLE *key_cache; /* ref to the current key cache */
|
||||
MI_DECODE_TREE *decode_trees;
|
||||
uint16 *decode_tables;
|
||||
int (*read_record)(struct st_myisam_info*, my_off_t, byte*);
|
||||
|
@ -188,6 +187,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
|
|||
ulong max_pack_length;
|
||||
ulong state_diff_length;
|
||||
uint rec_reflength; /* rec_reflength in use now */
|
||||
uint unique_name_length;
|
||||
File kfile; /* Shared keyfile */
|
||||
File data_file; /* Shared data file */
|
||||
int mode; /* mode of file on open */
|
||||
|
@ -713,6 +713,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param);
|
|||
#ifdef THREAD
|
||||
pthread_handler_decl(thr_find_all_keys,arg);
|
||||
#endif
|
||||
int flush_blocks(MI_CHECK *param, KEY_CACHE_HANDLE key_cache, File file);
|
||||
|
||||
int sort_write_record(MI_SORT_PARAM *sort_param);
|
||||
int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, ulong);
|
||||
|
|
|
@ -648,7 +648,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||
goto end;
|
||||
}
|
||||
}
|
||||
end_key_cache(dflt_keycache,1);
|
||||
end_key_cache(*dflt_keycache,1);
|
||||
delete_tree(&tree);
|
||||
VOID(end_io_cache(&cache));
|
||||
VOID(my_close(file,MYF(0)));
|
||||
|
@ -668,7 +668,7 @@ static int examine_log(my_string file_name, char **table_names)
|
|||
llstr(isamlog_filepos,llbuff)));
|
||||
fflush(stderr);
|
||||
end:
|
||||
end_key_cache(dflt_keycache,1);
|
||||
end_key_cache(*dflt_keycache, 1);
|
||||
delete_tree(&tree);
|
||||
VOID(end_io_cache(&cache));
|
||||
VOID(my_close(file,MYF(0)));
|
||||
|
|
|
@ -575,7 +575,7 @@ show_failed_diff ()
|
|||
$DIFF -c $result_file $reject_file
|
||||
echo "-------------------------------------------------------"
|
||||
echo "Please follow the instructions outlined at"
|
||||
echo "http://www.mysql.com/doc/R/e/Reporting_mysqltest_bugs.html"
|
||||
echo "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html"
|
||||
echo "to find the reason to this problem and how to report this."
|
||||
fi
|
||||
}
|
||||
|
@ -1311,7 +1311,7 @@ run_testcase ()
|
|||
show_failed_diff $tname
|
||||
$ECHO
|
||||
if [ x$FORCE != x1 ] ; then
|
||||
$ECHO "Aborting. To continue, re-run with '--force'."
|
||||
$ECHO "Aborting becasue $tname failed. To continue, re-run with '--force'."
|
||||
$ECHO
|
||||
if [ -z "$DO_GDB" ] && [ -z "$USE_RUNNING_SERVER" ] && [ -z "$DO_DDD" ]
|
||||
then
|
||||
|
|
|
@ -319,6 +319,29 @@ alter table t1 change a a char(10) character set koi8r;
|
|||
select a,hex(a) from t1;
|
||||
a hex(a)
|
||||
ÔĹÓÔ D4C5D3D4
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) character set koi8r default NULL
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
alter table t1 DEFAULT CHARACTER SET latin1;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) character set koi8r default NULL
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
alter table t1 CHARACTER SET latin1;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) default NULL
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
alter table t1 DEFAULT CHARACTER SET cp1251;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) character set latin1 default NULL
|
||||
) TYPE=MyISAM DEFAULT CHARSET=cp1251
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
Host varchar(16) binary NOT NULL default '',
|
||||
|
|
|
@ -103,7 +103,7 @@ t1 CREATE TABLE `t1` (
|
|||
`c6` char(3) default NULL,
|
||||
`c7` double(3,1) default NULL,
|
||||
`c8` double(3,1) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
SELECT CASE
|
||||
WHEN 1
|
||||
|
@ -150,5 +150,5 @@ t1 CREATE TABLE `t1` (
|
|||
`COALESCE(1,'1')` char(1) NOT NULL default '',
|
||||
`COALESCE(1.1,'1')` char(3) NOT NULL default '',
|
||||
`COALESCE('a' COLLATE latin1_bin,'b')` char(1) character set latin1 collate latin1_bin NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -45,7 +45,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`t` char(4) character set cp1251 NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select
|
||||
cast(_latin1'ab' AS char) as c1,
|
||||
|
@ -72,7 +72,7 @@ t1 CREATE TABLE `t1` (
|
|||
`c3` char(2) binary NOT NULL default '',
|
||||
`c4` char(2) binary NOT NULL default '',
|
||||
`c5` char(2) binary NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select
|
||||
cast(_koi8r'ÆÇ' AS nchar) as c1,
|
||||
|
@ -99,7 +99,7 @@ t1 CREATE TABLE `t1` (
|
|||
`c3` char(2) character set utf8 NOT NULL default '',
|
||||
`c4` char(2) character set utf8 NOT NULL default '',
|
||||
`c5` char(2) character set utf8 NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select cast("2001-1-1" as date) = "2001-01-01";
|
||||
cast("2001-1-1" as date) = "2001-01-01"
|
||||
|
|
|
@ -179,7 +179,7 @@ t1 CREATE TABLE `t1` (
|
|||
KEY `b_29` (`b`),
|
||||
KEY `b_30` (`b`),
|
||||
KEY `b_31` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 select if(1,'1','0'), month("2002-08-02");
|
||||
drop table t1;
|
||||
|
@ -197,7 +197,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=HEAP CHARSET=latin1
|
||||
) TYPE=HEAP DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
SET SESSION table_type="gemini";
|
||||
SELECT @@table_type;
|
||||
|
@ -210,7 +210,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET SESSION table_type=default;
|
||||
drop table t1;
|
||||
create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2));
|
||||
|
@ -275,7 +275,7 @@ Table Create Table
|
|||
t3 CREATE TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3;
|
||||
id name
|
||||
create table if not exists t3 like t1;
|
||||
|
@ -289,7 +289,7 @@ show create table t3;
|
|||
Table Create Table
|
||||
t3 CREATE TEMPORARY TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3;
|
||||
id
|
||||
drop table t3;
|
||||
|
@ -298,7 +298,7 @@ Table Create Table
|
|||
t3 CREATE TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t3;
|
||||
id name
|
||||
drop table t2, t3;
|
||||
|
@ -313,14 +313,14 @@ Table Create Table
|
|||
t3 CREATE TEMPORARY TABLE `t3` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
create table t2 like t3;
|
||||
show create table t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`id` int(11) NOT NULL default '0',
|
||||
`name` char(20) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t2;
|
||||
id name
|
||||
create table t3 like t1;
|
||||
|
@ -346,7 +346,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=HEAP CHARSET=latin1
|
||||
) TYPE=HEAP DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
SET SESSION table_type="gemini";
|
||||
SELECT @@table_type;
|
||||
|
@ -359,7 +359,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SET SESSION table_type=default;
|
||||
drop table t1;
|
||||
create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob);
|
||||
|
|
|
@ -491,7 +491,7 @@ SHOW CREATE TABLE t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`latin1_f` char(32) NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW FIELDS FROM t1;
|
||||
Field Type Null Key Default Extra
|
||||
latin1_f char(32)
|
||||
|
@ -501,7 +501,7 @@ SHOW CREATE TABLE t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`latin1_f` char(32) character set latin1 collate latin1_bin default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW FIELDS FROM t1;
|
||||
Field Type Null Key Default Extra
|
||||
latin1_f char(32) YES NULL
|
||||
|
@ -509,8 +509,8 @@ ALTER TABLE t1 CHARACTER SET latin1 COLLATE latin1_bin;
|
|||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`latin1_f` char(32) collate latin1_bin default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1 COLLATE=latin1_bin
|
||||
`latin1_f` char(32) character set latin1 collate latin1_bin default NULL
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW FIELDS FROM t1;
|
||||
Field Type Null Key Default Extra
|
||||
latin1_f char(32) YES NULL
|
||||
|
|
|
@ -225,7 +225,7 @@ t1 CREATE TABLE `t1` (
|
|||
`word` varchar(255) collate latin1_german2_ci NOT NULL default '',
|
||||
`word2` varchar(255) collate latin1_german2_ci NOT NULL default '',
|
||||
KEY `word` (`word`)
|
||||
) TYPE=MyISAM CHARSET=latin1 COLLATE=latin1_german2_ci
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci
|
||||
insert into t1 (word) values ('ss'),(0xDF),(0xE4),('ae');
|
||||
update t1 set word2=word;
|
||||
select word, word=binary 0xdf as t from t1 having t > 0;
|
||||
|
@ -284,7 +284,7 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`s1` char(5) collate latin1_german2_ci default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1 COLLATE=latin1_german2_ci
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci
|
||||
INSERT INTO t1 VALUES ('Ü');
|
||||
INSERT INTO t1 VALUES ('ue');
|
||||
SELECT DISTINCT s1 FROM t1;
|
||||
|
|
|
@ -9,14 +9,14 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) character set latin1 NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin5
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin5
|
||||
ALTER TABLE t1 CHANGE comment comment CHAR(32) CHARACTER SET latin2 NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) character set latin2 NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin5
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin5
|
||||
ALTER TABLE t1 ADD latin5_f CHAR(32) NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
|
@ -24,8 +24,8 @@ t1 CREATE TABLE `t1` (
|
|||
`comment` char(32) character set latin2 NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
|
||||
`latin5_f` char(32) NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin5
|
||||
ALTER TABLE t1 CHARSET=latin2;
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin5
|
||||
ALTER TABLE t1 DEFAULT CHARSET=latin2;
|
||||
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
|
@ -34,14 +34,14 @@ t1 CREATE TABLE `t1` (
|
|||
`koi8_ru_f` char(32) character set koi8r NOT NULL default '',
|
||||
`latin5_f` char(32) character set latin5 NOT NULL default '',
|
||||
`latin2_f` char(32) NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin2
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin2
|
||||
ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`comment` char(32) NOT NULL default '',
|
||||
`koi8_ru_f` char(32) character set koi8r NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin2
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin2
|
||||
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('a','LAT SMALL A');
|
||||
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('b','LAT SMALL B');
|
||||
INSERT INTO t1 (koi8_ru_f,comment) VALUES ('c','LAT SMALL C');
|
||||
|
|
|
@ -5,7 +5,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`c1` char(4) character set utf8 NOT NULL default '',
|
||||
`c2` char(4) character set utf8 NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
DELETE FROM t1;
|
||||
ALTER TABLE t1 ADD c3 CHAR(4) CHARACTER SET utf8;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
@ -14,7 +14,7 @@ t1 CREATE TABLE `t1` (
|
|||
`c1` char(4) character set utf8 NOT NULL default '',
|
||||
`c2` char(4) character set utf8 NOT NULL default '',
|
||||
`c3` char(4) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES ('aaaabbbbccccdddd','aaaabbbbccccdddd','aaaabbbbccccdddd');
|
||||
Warnings:
|
||||
Warning 1264 Data truncated for column 'c1' at row 1
|
||||
|
@ -30,7 +30,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` char(4) character set utf8 default NULL,
|
||||
KEY `key_a` (`a`(3))
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW KEYS FROM t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 key_a 1 a A NULL 9 NULL YES BTREE
|
||||
|
@ -40,7 +40,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` char(4) default NULL,
|
||||
KEY `key_a` (`a`(3))
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW KEYS FROM t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 key_a 1 a A NULL 3 NULL YES BTREE
|
||||
|
@ -50,7 +50,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` char(4) character set utf8 default NULL,
|
||||
KEY `key_a` (`a`(3))
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SHOW KEYS FROM t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
t1 1 key_a 1 a A NULL 9 NULL YES BTREE
|
||||
|
|
|
@ -6,7 +6,7 @@ SHOW CREATE TABLE t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` char(10) character set cp1251 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SELECT a FROM t1;
|
||||
a
|
||||
ÐÒÏÂÁ
|
||||
|
@ -25,7 +25,7 @@ SHOW CREATE TABLE
|
|||
Table Create Table
|
||||
ÔÁÂÌÉÃÁ CREATE TABLE `ÔÁÂÌÉÃÁ` (
|
||||
`ÐÏÌÅ` char(32) character set koi8r NOT NULL default '' COMMENT 'ËÏÍÍÅÎÔÁÒÉÊ ÐÏÌÑ'
|
||||
) TYPE=MyISAM CHARSET=latin1 COMMENT='ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COMMENT='ËÏÍÍÅÎÔÁÒÉÊ ÔÁÂÌÉÃÙ'
|
||||
SHOW FIELDS FROM ÔÁÂÌÉÃÁ;
|
||||
Field Type Null Key Default Extra
|
||||
ÐÏÌÅ char(32)
|
||||
|
@ -37,7 +37,7 @@ SHOW CREATE TABLE
|
|||
Table Create Table
|
||||
òàáëèöà CREATE TABLE `òàáëèöà` (
|
||||
`ïîëå` char(32) character set koi8r NOT NULL default '' COMMENT 'êîììåíòàðèé ïîëÿ'
|
||||
) TYPE=MyISAM CHARSET=latin1 COMMENT='êîììåíòàðèé òàáëèöû'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COMMENT='êîììåíòàðèé òàáëèöû'
|
||||
SHOW FIELDS FROM òàáëèöà;
|
||||
Field Type Null Key Default Extra
|
||||
ïîëå char(32)
|
||||
|
@ -49,7 +49,7 @@ SHOW CREATE TABLE таблица;
|
|||
Table Create Table
|
||||
таблица CREATE TABLE `таблица` (
|
||||
`поле` char(32) character set koi8r NOT NULL default '' COMMENT 'комментарий полÑ<C2BB>'
|
||||
) TYPE=MyISAM CHARSET=latin1 COMMENT='комментарий таблицы'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COMMENT='комментарий таблицы'
|
||||
SHOW FIELDS FROM таблица;
|
||||
Field Type Null Key Default Extra
|
||||
поле char(32)
|
||||
|
|
|
@ -45,7 +45,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`l` char(10) character set ucs2 NOT NULL default '',
|
||||
`r` char(10) character set ucs2 NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
SET NAMES koi8r;
|
||||
SET character_set_connection=ucs2;
|
||||
|
|
|
@ -164,7 +164,7 @@ create table t1 (mat_id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|||
create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED NOT NULL);
|
||||
insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
|
||||
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
||||
SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
pla_id mat_id
|
||||
100 1
|
||||
101 1
|
||||
|
@ -172,7 +172,7 @@ pla_id mat_id
|
|||
103 2
|
||||
104 2
|
||||
105 3
|
||||
SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
pla_id test
|
||||
100 1
|
||||
101 1
|
||||
|
@ -180,13 +180,13 @@ pla_id test
|
|||
103 2
|
||||
104 2
|
||||
105 3
|
||||
explain SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where
|
||||
2 DERIVED mp ALL NULL NULL NULL NULL 9 Using temporary; Using filesort
|
||||
2 DERIVED m2 index NULL PRIMARY 3 NULL 9 Using index
|
||||
explain SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY m2 ALL NULL NULL NULL NULL 9
|
||||
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6 Using where
|
||||
|
|
|
@ -201,7 +201,7 @@ t2 CREATE TABLE `t2` (
|
|||
`inhalt` text,
|
||||
KEY `tig` (`ticket`),
|
||||
FULLTEXT KEY `tix` (`inhalt`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
select * from t2 where MATCH inhalt AGAINST (NULL);
|
||||
ticket inhalt
|
||||
select * from t2 where MATCH inhalt AGAINST ('foobar');
|
||||
|
|
|
@ -539,7 +539,7 @@ t1 CREATE TABLE `t1` (
|
|||
`substring(_latin2'ab',1)` char(2) character set latin2 NOT NULL default '',
|
||||
`insert(_latin2'abcd',2,3,_latin2'ef')` char(6) character set latin2 NOT NULL default '',
|
||||
`replace(_latin2'abcd',_latin2'b',_latin2'B')` char(4) character set latin2 NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select SUBSTR('abcdefg',3,2);
|
||||
SUBSTR('abcdefg',3,2)
|
||||
|
|
|
@ -49,7 +49,7 @@ t1 CREATE TABLE `t1` (
|
|||
`database()` char(34) character set utf8 NOT NULL default '',
|
||||
`user()` char(77) character set utf8 NOT NULL default '',
|
||||
`version` char(40) default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
select TRUE,FALSE,NULL;
|
||||
TRUE FALSE NULL
|
||||
|
|
|
@ -11,7 +11,7 @@ t1 CREATE TABLE `t1` (
|
|||
`g` geometry NOT NULL default '',
|
||||
PRIMARY KEY (`fid`),
|
||||
SPATIAL KEY `g` (`g`(32))
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(150 150, 150 150)'));
|
||||
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(149 149, 151 151)'));
|
||||
INSERT INTO t1 (g) VALUES (GeomFromText('LineString(148 148, 152 152)'));
|
||||
|
@ -294,7 +294,7 @@ t2 CREATE TABLE `t2` (
|
|||
`g` geometry NOT NULL default '',
|
||||
PRIMARY KEY (`fid`),
|
||||
SPATIAL KEY `g` (`g`(32))
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
SELECT count(*) FROM t2;
|
||||
count(*)
|
||||
100
|
||||
|
|
|
@ -819,7 +819,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` char(20) default NULL,
|
||||
KEY `a` (`a`(5))
|
||||
) TYPE=InnoDB CHARSET=latin1
|
||||
) TYPE=InnoDB DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create temporary table t1 (a int not null auto_increment, primary key(a)) type=innodb;
|
||||
insert into t1 values (NULL),(NULL),(NULL);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
drop table if exists t1, t2, t3;
|
||||
SET @save_key_buffer=@@key_buffer_size;
|
||||
SELECT @@key_buffer_size, @@small.key_buffer_size;
|
||||
@@key_buffer_size @@small.key_buffer_size
|
||||
|
@ -74,15 +75,15 @@ select @@keycache1.key_buffer_size;
|
|||
0
|
||||
select @@keycache1.key_cache_block_size;
|
||||
@@keycache1.key_cache_block_size
|
||||
0
|
||||
2048
|
||||
select @@key_buffer_size;
|
||||
@@key_buffer_size
|
||||
2097152
|
||||
select @@key_cache_block_size;
|
||||
@@key_cache_block_size
|
||||
1024
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (p int primary key, a char(10));
|
||||
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));
|
||||
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
||||
insert into t2 values (1, 1, 'qqqq'), (2, 1, 'pppp'),
|
||||
|
@ -99,7 +100,7 @@ p i a
|
|||
4 3 zzzz
|
||||
update t1 set p=2 where p=1;
|
||||
update t2 set i=2 where i=1;
|
||||
cache index t1 keys in keycache1;
|
||||
cache index t1 keys (`primary`) in keycache1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 assign_to_keycache status OK
|
||||
explain select p from t1;
|
||||
|
@ -125,15 +126,15 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
select count(*) from t1, t2 where t1.p = t2.i;
|
||||
count(*)
|
||||
3
|
||||
cache index t2 keys in keycache1;
|
||||
cache index t2 in keycache1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 assign_to_keycache status OK
|
||||
update t2 set p=p+1000, i=2 where a='qqqq';
|
||||
cache index t2 keys in keycache2;
|
||||
cache index t2 in keycache2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 assign_to_keycache status OK
|
||||
insert into t2 values (2000, 3, 'yyyy');
|
||||
cache index t2 keys in keycache1;
|
||||
cache index t2 in keycache1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 assign_to_keycache status OK
|
||||
update t2 set p=3000 where a='zzzz';
|
||||
|
@ -174,6 +175,12 @@ qqqq
|
|||
yyyy
|
||||
yyyy
|
||||
zzzz
|
||||
cache index t1 in unknown_key_cache;
|
||||
ERROR HY000: Unknown key cache 'unknown_key_cache'
|
||||
cache index t1 keys (unknown_key) in keycache1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 assign_to_keycache error Key column 'unknown_key' doesn't exist in table
|
||||
test.t1 assign_to_keycache status Operation failed
|
||||
select @@keycache2.key_buffer_size;
|
||||
@@keycache2.key_buffer_size
|
||||
4194304
|
||||
|
@ -186,7 +193,11 @@ select @@keycache2.key_buffer_size;
|
|||
0
|
||||
select @@keycache2.key_cache_block_size;
|
||||
@@keycache2.key_cache_block_size
|
||||
0
|
||||
1024
|
||||
set global keycache2.key_buffer_size=1024*1024;
|
||||
select @@keycache2.key_buffer_size;
|
||||
@@keycache2.key_buffer_size
|
||||
1048576
|
||||
update t2 set p=4000 where a='zzzz';
|
||||
update t1 set p=p+1;
|
||||
set global keycache1.key_buffer_size=0;
|
||||
|
@ -232,3 +243,17 @@ select p from t1;
|
|||
p
|
||||
3
|
||||
12
|
||||
create table t3 (like t1);
|
||||
cache index t3 in small;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t3 assign_to_keycache status OK
|
||||
insert into t3 select * from t1;
|
||||
cache index t3 in keycache2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t3 assign_to_keycache status OK
|
||||
cache index t1,t2 in default;
|
||||
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;
|
||||
set global keycache1.key_buffer_size=0;
|
||||
|
|
|
@ -175,7 +175,7 @@ t3 CREATE TABLE `t3` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` char(20) default NULL,
|
||||
KEY `a` (`a`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
create table t4 (a int not null, b char(10), key(a)) type=MERGE UNION=(t1,t2);
|
||||
select * from t4;
|
||||
ERROR HY000: Can't open file: 't4.MRG' (errno: 143)
|
||||
|
@ -190,7 +190,7 @@ t5 CREATE TABLE `t5` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` char(20) default NULL,
|
||||
KEY `a` (`a`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`mysqltest`.`t6`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`mysqltest`.`t6`)
|
||||
alter table t5 type=myisam;
|
||||
drop table t5, mysqltest.t6;
|
||||
drop database mysqltest;
|
||||
|
@ -263,14 +263,14 @@ t3 CREATE TABLE `t3` (
|
|||
`incr` int(11) NOT NULL default '0',
|
||||
`othr` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`incr`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
alter table t3 drop primary key;
|
||||
show create table t3;
|
||||
Table Create Table
|
||||
t3 CREATE TABLE `t3` (
|
||||
`incr` int(11) NOT NULL default '0',
|
||||
`othr` int(11) NOT NULL default '0'
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
drop table t3,t2,t1;
|
||||
create table t1 (a int not null, key(a)) type=merge;
|
||||
select * from t1;
|
||||
|
@ -299,28 +299,28 @@ t3 CREATE TABLE `t3` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL default '0',
|
||||
KEY `a` (`a`,`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
show create table t4;
|
||||
Table Create Table
|
||||
t4 CREATE TABLE `t4` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL default '0',
|
||||
KEY `a` (`a`,`b`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`)
|
||||
show create table t5;
|
||||
Table Create Table
|
||||
t5 CREATE TABLE `t5` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL auto_increment,
|
||||
PRIMARY KEY (`a`,`b`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`)
|
||||
show create table t6;
|
||||
Table Create Table
|
||||
t6 CREATE TABLE `t6` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL auto_increment,
|
||||
PRIMARY KEY (`a`,`b`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=LAST UNION=(`t1`,`t2`)
|
||||
insert into t1 values (1,NULL),(1,NULL),(1,NULL),(1,NULL);
|
||||
insert into t2 values (2,NULL),(2,NULL),(2,NULL),(2,NULL);
|
||||
select * from t3 order by b,a limit 3;
|
||||
|
@ -385,7 +385,7 @@ t4 CREATE TABLE `t4` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL default '0',
|
||||
KEY `a` (`a`,`b`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 UNION=(`t1`,`t2`,`t3`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t1`,`t2`,`t3`)
|
||||
select * from t4 order by a,b;
|
||||
a b
|
||||
1 1
|
||||
|
@ -411,7 +411,7 @@ t4 CREATE TABLE `t4` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` int(11) NOT NULL default '0',
|
||||
KEY `a` (`a`,`b`)
|
||||
) TYPE=MRG_MyISAM CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`,`t3`)
|
||||
) TYPE=MRG_MyISAM DEFAULT CHARSET=latin1 INSERT_METHOD=FIRST UNION=(`t1`,`t2`,`t3`)
|
||||
insert into t4 values (4,1),(4,2);
|
||||
select * from t1 order by a,b;
|
||||
a b
|
||||
|
|
|
@ -69,7 +69,7 @@ flush status;
|
|||
select @@preload_buffer_size;
|
||||
@@preload_buffer_size
|
||||
32768
|
||||
load index into cache t1 keys;
|
||||
load index into cache t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 preload_keys status OK
|
||||
show status like "key_read%";
|
||||
|
@ -93,7 +93,7 @@ set session preload_buffer_size=256*1024;
|
|||
select @@preload_buffer_size;
|
||||
@@preload_buffer_size
|
||||
262144
|
||||
load index into cache t1 keys ignore leaves;
|
||||
load index into cache t1 ignore leaves;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 preload_keys status OK
|
||||
show status like "key_read%";
|
||||
|
@ -117,7 +117,7 @@ set session preload_buffer_size=1*1024;
|
|||
select @@preload_buffer_size;
|
||||
@@preload_buffer_size
|
||||
1024
|
||||
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
|
||||
load index into cache t1, t2 keys (primary,b) ignore leaves;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 preload_keys status OK
|
||||
test.t2 preload_keys status OK
|
||||
|
@ -141,7 +141,7 @@ show status like "key_read%";
|
|||
Variable_name Value
|
||||
Key_read_requests 0
|
||||
Key_reads 0
|
||||
load index into cache t3 keys, t2 keys (primary,b) ;
|
||||
load index into cache t3, t2 keys (primary,b) ;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t3 preload_keys error Table 'test.t3' doesn't exist
|
||||
test.t2 preload_keys status OK
|
||||
|
|
|
@ -77,13 +77,13 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TEMPORARY TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
alter table t1 rename t2;
|
||||
show create table t2;
|
||||
Table Create Table
|
||||
t2 CREATE TEMPORARY TABLE `t2` (
|
||||
`a` int(11) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t2;
|
||||
create table t1 (
|
||||
test_set set( 'val1', 'val2', 'val3' ) not null default '',
|
||||
|
@ -96,7 +96,7 @@ t1 CREATE TABLE `t1` (
|
|||
`test_set` set('val1','val2','val3') NOT NULL default '',
|
||||
`name` char(20) default 'O''Brien' COMMENT 'O''Brien as default',
|
||||
`c` int(11) NOT NULL default '0' COMMENT 'int column'
|
||||
) TYPE=MyISAM CHARSET=latin1 COMMENT='it''s a table'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 COMMENT='it''s a table'
|
||||
show full columns from t1;
|
||||
Field Type Collation Null Key Default Extra Privileges Comment
|
||||
test_set set('val1','val2','val3') latin1_swedish_ci select,insert,update,references
|
||||
|
@ -109,7 +109,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
UNIQUE KEY `aa` (`a`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a int not null, primary key (a));
|
||||
show create table t1;
|
||||
|
@ -117,7 +117,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (`a`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
flush tables;
|
||||
show open tables;
|
||||
|
@ -135,7 +135,7 @@ t1 CREATE TABLE `t1` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` char(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
|
||||
alter table t1 MAX_ROWS=200 ROW_FORMAT=dynamic PACK_KEYS=0;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
|
@ -143,7 +143,7 @@ t1 CREATE TABLE `t1` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` varchar(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=200 AVG_ROW_LENGTH=10 PACK_KEYS=0 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='test'
|
||||
ALTER TABLE t1 AVG_ROW_LENGTH=0 CHECKSUM=0 COMMENT="" MIN_ROWS=0 MAX_ROWS=0 PACK_KEYS=DEFAULT DELAY_KEY_WRITE=0 ROW_FORMAT=default;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
|
@ -151,7 +151,7 @@ t1 CREATE TABLE `t1` (
|
|||
`a` int(11) NOT NULL default '0',
|
||||
`b` varchar(10) default NULL,
|
||||
KEY `b` (`b`)
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a decimal(9,2), b decimal (9,0), e double(9,2), f double(5,0), h float(3,2), i float(3,0));
|
||||
show columns from t1;
|
||||
|
@ -221,7 +221,7 @@ t1 CREATE TABLE `t1` (
|
|||
`type_long_blob` longblob,
|
||||
PRIMARY KEY (`type_tiny`),
|
||||
KEY `type_short` (`type_short`)
|
||||
) TYPE=MyISAM CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1 MIN_ROWS=10 MAX_ROWS=100 AVG_ROW_LENGTH=10 PACK_KEYS=1 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=FIXED COMMENT='test'
|
||||
insert into t1 (type_timestamp) values ("2003-02-07 10:00:01");
|
||||
select * from t1;
|
||||
type_bool type_tiny type_short type_mediumint type_bigint type_decimal type_numeric empty_char type_char type_varchar type_timestamp type_date type_time type_datetime type_year type_enum type_set type_tinyblob type_blob type_medium_blob type_long_blob
|
||||
|
|
|
@ -18,7 +18,7 @@ t1 CREATE TABLE `t1` (
|
|||
`email` varchar(60) character set latin2 NOT NULL default '',
|
||||
PRIMARY KEY (`a`),
|
||||
UNIQUE KEY `email` TYPE BTREE (`email`)
|
||||
) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
) TYPE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
set @@sql_mode="ansi_quotes";
|
||||
show variables like 'sql_mode';
|
||||
Variable_name Value
|
||||
|
@ -31,7 +31,7 @@ t1 CREATE TABLE "t1" (
|
|||
"email" varchar(60) character set latin2 NOT NULL default '',
|
||||
PRIMARY KEY ("a"),
|
||||
UNIQUE KEY "email" TYPE BTREE ("email")
|
||||
) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
) TYPE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
set @@sql_mode="no_table_options";
|
||||
show variables like 'sql_mode';
|
||||
Variable_name Value
|
||||
|
@ -57,7 +57,7 @@ t1 CREATE TABLE `t1` (
|
|||
`email` varchar(60) character set latin2 NOT NULL default '',
|
||||
PRIMARY KEY (`a`),
|
||||
UNIQUE KEY `email` (`email`)
|
||||
) TYPE=HEAP CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
) TYPE=HEAP DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC
|
||||
set @@sql_mode="no_field_options,mysql323,mysql40";
|
||||
show variables like 'sql_mode';
|
||||
Variable_name Value
|
||||
|
|
|
@ -1071,7 +1071,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` bigint(1) NOT NULL default '0',
|
||||
`(SELECT 1)` bigint(1) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a)) a;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
@ -1079,7 +1079,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` bigint(1) NOT NULL default '0',
|
||||
`(SELECT a)` bigint(1) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 SELECT * FROM (SELECT 1 as a,(SELECT a+0)) a;
|
||||
SHOW CREATE TABLE t1;
|
||||
|
@ -1087,7 +1087,7 @@ Table Create Table
|
|||
t1 CREATE TABLE `t1` (
|
||||
`a` bigint(1) NOT NULL default '0',
|
||||
`(SELECT a+0)` bigint(17) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 SELECT (SELECT 1 as a UNION SELECT 1+1 limit 1,1) as a;
|
||||
select * from t1;
|
||||
|
@ -1097,7 +1097,7 @@ SHOW CREATE TABLE t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` bigint(17) NOT NULL default '0'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a int);
|
||||
insert into t1 values (1), (2), (3);
|
||||
|
|
|
@ -23,7 +23,7 @@ Table Create Table
|
|||
t3 CREATE TABLE `t3` (
|
||||
`a` mediumtext,
|
||||
`b` mediumblob
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1,t2,t3
|
||||
#;
|
||||
CREATE TABLE t1 (a char(257) default "hello");
|
||||
|
|
|
@ -1627,12 +1627,12 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` enum('','a','b') NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a enum (' ','a','b ') not null default 'b ');
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` enum('','a','b') NOT NULL default 'b'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -4,47 +4,47 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` char(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c national char(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` char(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c national varchar(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` varchar(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c nvarchar(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` varchar(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c nchar varchar(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` varchar(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c national character varying(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` varchar(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (c nchar varying(10));
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c` varchar(10) character set utf8 default NULL
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
|
|
|
@ -4,14 +4,14 @@ show create table t1;
|
|||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` set('','a','b') NOT NULL default ''
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
create table t1 (a set (' ','a','b ') not null default 'b ');
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` set('','a','b') NOT NULL default 'b'
|
||||
) TYPE=MyISAM CHARSET=latin1
|
||||
) TYPE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
CREATE TABLE t1 ( user varchar(64) NOT NULL default '', path varchar(255) NOT NULL default '', privilege set('select','RESERVED30','RESERVED29','RESERVED28','RESERVED27','RESERVED26', 'RESERVED25','RESERVED24','data.delete','RESERVED22','RESERVED21', 'RESERVED20','data.insert.none','data.insert.approve', 'data.insert.delete','data.insert.move','data.insert.propose', 'data.insert.reject','RESERVED13','RESERVED12','RESERVED11','RESERVED10', 'RESERVED09','data.update','RESERVED07','RESERVED06','RESERVED05', 'RESERVED04','metadata.delete','metadata.put','RESERVED01','RESERVED00') NOT NULL default '', KEY user (user) ) TYPE=MyISAM CHARSET=utf8;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -486,7 +486,7 @@ a b
|
|||
2 2
|
||||
3 3
|
||||
4 4
|
||||
explain (select * from t1 where a=1 and b=10) union (select t1.a,t2.a from t1,t2 where t1.a=t2.a);
|
||||
explain (select * from t1 where a=1 and b=10) union (select straight_join t1.a,t2.a from t1,t2 where t1.a=t2.a);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||
2 UNION t1 index PRIMARY PRIMARY 4 NULL 4 Using index
|
||||
|
|
|
@ -170,6 +170,17 @@ select a,hex(a) from t1;
|
|||
alter table t1 change a a char(10) character set koi8r;
|
||||
select a,hex(a) from t1;
|
||||
|
||||
#
|
||||
# Test ALTER TABLE .. CHARACTER SET ..
|
||||
#
|
||||
show create table t1;
|
||||
alter table t1 DEFAULT CHARACTER SET latin1;
|
||||
show create table t1;
|
||||
alter table t1 CHARACTER SET latin1;
|
||||
show create table t1;
|
||||
alter table t1 DEFAULT CHARACTER SET cp1251;
|
||||
show create table t1;
|
||||
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
|
|
@ -16,7 +16,7 @@ ALTER TABLE t1 CHANGE comment comment CHAR(32) CHARACTER SET latin2 NOT NULL;
|
|||
SHOW CREATE TABLE t1;
|
||||
ALTER TABLE t1 ADD latin5_f CHAR(32) NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
ALTER TABLE t1 CHARSET=latin2;
|
||||
ALTER TABLE t1 DEFAULT CHARSET=latin2;
|
||||
ALTER TABLE t1 ADD latin2_f CHAR(32) NOT NULL;
|
||||
SHOW CREATE TABLE t1;
|
||||
ALTER TABLE t1 DROP latin2_f, DROP latin5_f;
|
||||
|
|
|
@ -83,11 +83,11 @@ create table t2 (mat_id MEDIUMINT UNSIGNED NOT NULL, pla_id MEDIUMINT UNSIGNED N
|
|||
insert into t1 values (NULL, 'a', 1), (NULL, 'b', 2), (NULL, 'c', 3), (NULL, 'd', 4), (NULL, 'e', 5), (NULL, 'f', 6), (NULL, 'g', 7), (NULL, 'h', 8), (NULL, 'i', 9);
|
||||
insert into t2 values (1, 100), (1, 101), (1, 102), (2, 100), (2, 103), (2, 104), (3, 101), (3, 102), (3, 105);
|
||||
|
||||
SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
|
||||
explain SELECT d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
explain SELECT d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
explain SELECT STRAIGHT_JOIN d.pla_id, m2.mat_id FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
explain SELECT STRAIGHT_JOIN d.pla_id, m2.test FROM t1 m2 INNER JOIN (SELECT mp.pla_id, MIN(m1.matintnum) AS matintnum FROM t2 mp INNER JOIN t1 m1 ON mp.mat_id=m1.mat_id GROUP BY mp.pla_id) d ON d.matintnum=m2.matintnum;
|
||||
drop table t1,t2;
|
||||
|
||||
#
|
||||
|
|
|
@ -12,12 +12,14 @@ create table t1 (a tinyint not null auto_increment, b blob not null, primary key
|
|||
|
||||
let $1=100;
|
||||
disable_query_log;
|
||||
--disable_warnings
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 (b) values(repeat(char(65+$1),65540-$1));
|
||||
dec $1;
|
||||
}
|
||||
enable_query_log;
|
||||
--enable_warnings
|
||||
delete from t1 where (a & 1);
|
||||
select sum(length(b)) from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -112,7 +112,7 @@ drop table t1, t2;
|
|||
create table t1 (a int primary key);
|
||||
insert into t1 values(1),(2);
|
||||
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a);
|
||||
--replace_result "31 tables" "XX tables" "62 tables" "XX tables"
|
||||
--replace_result "31 tables" "XX tables" "61 tables" "XX tables"
|
||||
--error 1116
|
||||
select t1.a from t1 as t1 left join t1 as t2 using (a) left join t1 as t3 using (a) left join t1 as t4 using (a) left join t1 as t5 using (a) left join t1 as t6 using (a) left join t1 as t7 using (a) left join t1 as t8 using (a) left join t1 as t9 using (a) left join t1 as t10 using (a) left join t1 as t11 using (a) left join t1 as t12 using (a) left join t1 as t13 using (a) left join t1 as t14 using (a) left join t1 as t15 using (a) left join t1 as t16 using (a) left join t1 as t17 using (a) left join t1 as t18 using (a) left join t1 as t19 using (a) left join t1 as t20 using (a) left join t1 as t21 using (a) left join t1 as t22 using (a) left join t1 as t23 using (a) left join t1 as t24 using (a) left join t1 as t25 using (a) left join t1 as t26 using (a) left join t1 as t27 using (a) left join t1 as t28 using (a) left join t1 as t29 using (a) left join t1 as t30 using (a) left join t1 as t31 using (a) left join t1 as t32 using (a) left join t1 as t33 using (a) left join t1 as t34 using (a) left join t1 as t35 using (a) left join t1 as t36 using (a) left join t1 as t37 using (a) left join t1 as t38 using (a) left join t1 as t39 using (a) left join t1 as t40 using (a) left join t1 as t41 using (a) left join t1 as t42 using (a) left join t1 as t43 using (a) left join t1 as t44 using (a) left join t1 as t45 using (a) left join t1 as t46 using (a) left join t1 as t47 using (a) left join t1 as t48 using (a) left join t1 as t49 using (a) left join t1 as t50 using (a) left join t1 as t51 using (a) left join t1 as t52 using (a) left join t1 as t53 using (a) left join t1 as t54 using (a) left join t1 as t55 using (a) left join t1 as t56 using (a) left join t1 as t57 using (a) left join t1 as t58 using (a) left join t1 as t59 using (a) left join t1 as t60 using (a) left join t1 as t61 using (a) left join t1 as t62 using (a) left join t1 as t63 using (a) left join t1 as t64 using (a) left join t1 as t65 using (a);
|
||||
drop table t1;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#
|
||||
# Test of multiple key caches
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2, t3;
|
||||
--enable_warnings
|
||||
|
||||
SET @save_key_buffer=@@key_buffer_size;
|
||||
|
||||
|
@ -58,12 +61,9 @@ select @@keycache1.key_cache_block_size;
|
|||
select @@key_buffer_size;
|
||||
select @@key_cache_block_size;
|
||||
|
||||
set global keycache1.key_buffer_size=1024*1024;
|
||||
|
||||
--disable_warnings
|
||||
drop table if exists t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (p int primary key, a char(10));
|
||||
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));
|
||||
|
||||
insert into t1 values (1, 'qqqq'), (11, 'yyyy');
|
||||
|
@ -75,7 +75,7 @@ select * from t2;
|
|||
update t1 set p=2 where p=1;
|
||||
update t2 set i=2 where i=1;
|
||||
|
||||
cache index t1 keys in keycache1;
|
||||
cache index t1 keys (`primary`) in keycache1;
|
||||
|
||||
explain select p from t1;
|
||||
select p from t1;
|
||||
|
@ -84,11 +84,11 @@ select i from t2;
|
|||
explain select count(*) from t1, t2 where t1.p = t2.i;
|
||||
select count(*) from t1, t2 where t1.p = t2.i;
|
||||
|
||||
cache index t2 keys in keycache1;
|
||||
cache index t2 in keycache1;
|
||||
update t2 set p=p+1000, i=2 where a='qqqq';
|
||||
cache index t2 keys in keycache2;
|
||||
cache index t2 in keycache2;
|
||||
insert into t2 values (2000, 3, 'yyyy');
|
||||
cache index t2 keys in keycache1;
|
||||
cache index t2 in keycache1;
|
||||
update t2 set p=3000 where a='zzzz';
|
||||
select * from t2;
|
||||
explain select p from t2;
|
||||
|
@ -98,12 +98,18 @@ select i from t2;
|
|||
explain select a from t2;
|
||||
select a from t2;
|
||||
|
||||
# Test some error conditions
|
||||
--error 1287
|
||||
cache index t1 in unknown_key_cache;
|
||||
cache index t1 keys (unknown_key) in keycache1;
|
||||
|
||||
select @@keycache2.key_buffer_size;
|
||||
select @@keycache2.key_cache_block_size;
|
||||
set global keycache2.key_buffer_size=0;
|
||||
select @@keycache2.key_buffer_size;
|
||||
select @@keycache2.key_cache_block_size;
|
||||
|
||||
set global keycache2.key_buffer_size=1024*1024;
|
||||
select @@keycache2.key_buffer_size;
|
||||
|
||||
update t2 set p=4000 where a='zzzz';
|
||||
update t1 set p=p+1;
|
||||
|
@ -119,4 +125,14 @@ select a from t2;
|
|||
select * from t1;
|
||||
select p from t1;
|
||||
|
||||
# Use the 'small' key cache
|
||||
create table t3 (like t1);
|
||||
cache index t3 in small;
|
||||
insert into t3 select * from t1;
|
||||
cache index t3 in keycache2;
|
||||
cache index t1,t2 in default;
|
||||
drop table t1,t2,t3;
|
||||
|
||||
# Cleanup
|
||||
# We don't reset keycache2 as we want to ensure that mysqld will reset it
|
||||
set global keycache1.key_buffer_size=0;
|
||||
|
|
|
@ -63,7 +63,7 @@ show status like "key_read%";
|
|||
|
||||
flush tables; flush status;
|
||||
select @@preload_buffer_size;
|
||||
load index into cache t1 keys;
|
||||
load index into cache t1;
|
||||
show status like "key_read%";
|
||||
select count(*) from t1 where b = 'test1';
|
||||
show status like "key_read%";
|
||||
|
@ -72,7 +72,7 @@ flush tables; flush status;
|
|||
show status like "key_read%";
|
||||
set session preload_buffer_size=256*1024;
|
||||
select @@preload_buffer_size;
|
||||
load index into cache t1 keys ignore leaves;
|
||||
load index into cache t1 ignore leaves;
|
||||
show status like "key_read%";
|
||||
select count(*) from t1 where b = 'test1';
|
||||
show status like "key_read%";
|
||||
|
@ -81,7 +81,7 @@ flush tables; flush status;
|
|||
show status like "key_read%";
|
||||
set session preload_buffer_size=1*1024;
|
||||
select @@preload_buffer_size;
|
||||
load index into cache t1 keys, t2 keys (primary,b) ignore leaves;
|
||||
load index into cache t1, t2 keys (primary,b) ignore leaves;
|
||||
show status like "key_read%";
|
||||
select count(*) from t1 where b = 'test1';
|
||||
select count(*) from t2 where b = 'test1';
|
||||
|
@ -89,7 +89,7 @@ show status like "key_read%";
|
|||
|
||||
flush tables; flush status;
|
||||
show status like "key_read%";
|
||||
load index into cache t3 keys, t2 keys (primary,b) ;
|
||||
load index into cache t3, t2 keys (primary,b) ;
|
||||
show status like "key_read%";
|
||||
|
||||
flush tables; flush status;
|
||||
|
|
|
@ -280,7 +280,7 @@ explain extended (select * from t1 where a=1) union (select * from t2 where a=1)
|
|||
(select * from t1 where a=5 and a=6) union (select * from t2 where a=1);
|
||||
(select t1.a,t1.b from t1,t2 where t1.a=5) union (select * from t2 where a=1);
|
||||
(select * from t1 where a=1) union (select t1.a,t2.a from t1,t2 where t1.a=t2.a);
|
||||
explain (select * from t1 where a=1 and b=10) union (select t1.a,t2.a from t1,t2 where t1.a=t2.a);
|
||||
explain (select * from t1 where a=1 and b=10) union (select straight_join t1.a,t2.a from t1,t2 where t1.a=t2.a);
|
||||
explain (select * from t1 where a=1) union (select * from t1 where b=1);
|
||||
drop table t1,t2;
|
||||
create table t1 ( id int not null auto_increment, primary key (id) ,user_name text );
|
||||
|
|
|
@ -29,7 +29,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
|
|||
mf_path.c mf_loadpath.c\
|
||||
my_open.c my_create.c my_dup.c my_seek.c my_read.c \
|
||||
my_pread.c my_write.c \
|
||||
mf_keycache.c my_crc32.c \
|
||||
mf_keycache.c mf_keycaches.c my_crc32.c \
|
||||
mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
|
||||
mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
|
||||
my_malloc.c my_realloc.c my_once.c mulalloc.c \
|
||||
|
|
|
@ -53,7 +53,7 @@ _hash_init(HASH *hash,CHARSET_INFO *charset,
|
|||
if (my_init_dynamic_array_ci(&hash->array,sizeof(HASH_LINK),size,0))
|
||||
{
|
||||
hash->free=0; /* Allow call to hash_free */
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
hash->key_offset=key_offset;
|
||||
hash->key_length=key_length;
|
||||
|
|
|
@ -142,7 +142,7 @@ typedef struct st_block_link
|
|||
|
||||
KEY_CACHE_VAR dflt_key_cache_var=
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
KEY_CACHE_HANDLE *dflt_keycache= &dflt_key_cache_var.cache;
|
||||
|
||||
|
@ -168,7 +168,7 @@ typedef struct st_key_cache
|
|||
ulong warm_blocks; /* number of blocks in warm sub-chain */
|
||||
#if defined(KEYCACHE_DEBUG)
|
||||
long blocks_available; /* number of blocks available in the LRU chain */
|
||||
#endif
|
||||
#endif
|
||||
HASH_LINK **hash_root; /* arr. of entries into hash table buckets */
|
||||
HASH_LINK *hash_link_root; /* memory for hash table links */
|
||||
HASH_LINK *free_hash_list; /* list of free hash links */
|
||||
|
@ -184,7 +184,7 @@ typedef struct st_key_cache
|
|||
} KEY_CACHE;
|
||||
|
||||
static int flush_all_key_blocks(KEY_CACHE_HANDLE keycache);
|
||||
static void test_key_cache(KEY_CACHE *keycache,
|
||||
static void test_key_cache(KEY_CACHE *keycache,
|
||||
const char *where, my_bool lock);
|
||||
|
||||
#define KEYCACHE_HASH(f, pos) \
|
||||
|
@ -284,7 +284,7 @@ static uint next_power(uint value)
|
|||
SYNOPSIS
|
||||
init_ky_cache()
|
||||
pkeycache in/out pointer to the key cache handle
|
||||
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
|
||||
env ref to other parameters of the key cache, if any
|
||||
|
||||
|
@ -299,7 +299,7 @@ static uint next_power(uint value)
|
|||
handle for a key cache with new blocks.
|
||||
It's assumed that no two threads call this function simultaneously
|
||||
referring to the same key cache handle.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
||||
|
@ -308,14 +308,14 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
uint blocks, hash_links, length;
|
||||
int error;
|
||||
KEY_CACHE *keycache;
|
||||
|
||||
DBUG_ENTER("init_key_cache");
|
||||
DBUG_ASSERT(key_cache_block_size >= 512);
|
||||
|
||||
if (!(keycache= (KEY_CACHE *) *pkeycache) &&
|
||||
!(keycache= (KEY_CACHE *) my_malloc(sizeof(KEY_CACHE),
|
||||
MYF(MY_ZEROFILL))))
|
||||
DBUG_RETURN(0);
|
||||
|
||||
|
||||
keycache->env= env;
|
||||
|
||||
KEYCACHE_DEBUG_OPEN;
|
||||
|
@ -332,30 +332,30 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
|
||||
if (! keycache->key_cache_inited)
|
||||
{
|
||||
keycache->key_cache_inited= TRUE;
|
||||
keycache->key_cache_inited= 1;
|
||||
keycache->disk_blocks= -1;
|
||||
pthread_mutex_init(&keycache->cache_lock, MY_MUTEX_INIT_FAST);
|
||||
keycache->key_cache_shift= my_bit_log2(key_cache_block_size);
|
||||
keycache->key_cache_mem_size= use_mem;
|
||||
keycache->key_cache_block_size= key_cache_block_size;
|
||||
DBUG_PRINT("info", ("key_cache_block_size: %u",
|
||||
key_cache_block_size));
|
||||
key_cache_block_size));
|
||||
}
|
||||
|
||||
/*
|
||||
These are safety deallocations: actually we always call the
|
||||
function after having called end_key_cache that deallocates
|
||||
these memory itself.
|
||||
*/
|
||||
|
||||
/*
|
||||
These are safety deallocations: actually we always call the
|
||||
function after having called end_key_cache that deallocates
|
||||
these memory itself.
|
||||
*/
|
||||
if (keycache->block_mem)
|
||||
my_free_lock((gptr) keycache->block_mem, MYF(0));
|
||||
my_free_lock((gptr) keycache->block_mem, MYF(0));
|
||||
keycache->block_mem= NULL;
|
||||
if (keycache->block_root)
|
||||
my_free((gptr) keycache->block_root, MYF(0));
|
||||
my_free((gptr) keycache->block_root, MYF(0));
|
||||
keycache->block_root= NULL;
|
||||
|
||||
blocks= (uint) (use_mem / (sizeof(BLOCK_LINK) + 2 * sizeof(HASH_LINK) +
|
||||
sizeof(HASH_LINK*) * 5/4 + key_cache_block_size));
|
||||
sizeof(HASH_LINK*) * 5/4 + key_cache_block_size));
|
||||
/* It doesn't make sense to have too few blocks (less than 8) */
|
||||
if (blocks >= 8 && keycache->disk_blocks < 0)
|
||||
{
|
||||
|
@ -371,18 +371,18 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
#endif
|
||||
while ((length= (ALIGN_SIZE(blocks * sizeof(BLOCK_LINK)) +
|
||||
ALIGN_SIZE(hash_links * sizeof(HASH_LINK)) +
|
||||
ALIGN_SIZE(sizeof(HASH_LINK*) *
|
||||
ALIGN_SIZE(sizeof(HASH_LINK*) *
|
||||
keycache->hash_entries))) +
|
||||
((ulong) blocks << keycache->key_cache_shift) > use_mem)
|
||||
blocks--;
|
||||
/* Allocate memory for cache page buffers */
|
||||
if ((keycache->block_mem=
|
||||
my_malloc_lock((ulong) blocks * keycache->key_cache_block_size,
|
||||
MYF(0))))
|
||||
if ((keycache->block_mem=
|
||||
my_malloc_lock((ulong) blocks * keycache->key_cache_block_size,
|
||||
MYF(0))))
|
||||
{
|
||||
/*
|
||||
Allocate memory for blocks, hash_links and hash entries;
|
||||
For each block 2 hash links are allocated
|
||||
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((uint) length,
|
||||
MYF(0))))
|
||||
|
@ -402,13 +402,13 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
ALIGN_SIZE(blocks*sizeof(BLOCK_LINK)));
|
||||
keycache->hash_link_root= (HASH_LINK*) ((char*) keycache->hash_root +
|
||||
ALIGN_SIZE((sizeof(HASH_LINK*) *
|
||||
keycache->hash_entries)));
|
||||
keycache->hash_entries)));
|
||||
bzero((byte*) keycache->block_root,
|
||||
keycache->disk_blocks * sizeof(BLOCK_LINK));
|
||||
keycache->disk_blocks * sizeof(BLOCK_LINK));
|
||||
bzero((byte*) keycache->hash_root,
|
||||
keycache->hash_entries * sizeof(HASH_LINK*));
|
||||
bzero((byte*) keycache->hash_link_root,
|
||||
keycache->hash_links * sizeof(HASH_LINK));
|
||||
keycache->hash_links * sizeof(HASH_LINK));
|
||||
keycache->hash_links_used= 0;
|
||||
keycache->free_hash_list= NULL;
|
||||
keycache->blocks_used= keycache->blocks_changed= 0;
|
||||
|
@ -422,21 +422,21 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
keycache->used_ins= NULL;
|
||||
keycache->keycache_time= 0;
|
||||
keycache->warm_blocks= 0;
|
||||
keycache->min_warm_blocks= env && env->division_limit ?
|
||||
blocks * env->division_limit / 100 + 1 :
|
||||
blocks;
|
||||
keycache->age_threshold= env && env->age_threshold ?
|
||||
blocks * env->age_threshold / 100 :
|
||||
blocks;
|
||||
keycache->min_warm_blocks= (env && env->division_limit ?
|
||||
blocks * env->division_limit / 100 + 1 :
|
||||
blocks);
|
||||
keycache->age_threshold= (env && env->age_threshold ?
|
||||
blocks * env->age_threshold / 100 :
|
||||
blocks);
|
||||
|
||||
keycache->waiting_for_hash_link.last_thread= NULL;
|
||||
keycache->waiting_for_block.last_thread= NULL;
|
||||
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_root: %lx \
|
||||
hash_links: %d hash_link_root %lx",
|
||||
keycache->disk_blocks, keycache->block_root,
|
||||
keycache->hash_entries, keycache->hash_root,
|
||||
keycache->hash_links, keycache->hash_link_root));
|
||||
keycache->disk_blocks, keycache->block_root,
|
||||
keycache->hash_entries, keycache->hash_root,
|
||||
keycache->hash_links, keycache->hash_link_root));
|
||||
}
|
||||
bzero((gptr) keycache->changed_blocks,
|
||||
sizeof(keycache->changed_blocks[0]) * CHANGED_BLOCKS_HASH);
|
||||
|
@ -445,7 +445,8 @@ int init_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
|
||||
if (env)
|
||||
env->blocks= keycache->disk_blocks > 0 ? keycache->disk_blocks : 0;
|
||||
*pkeycache= keycache;
|
||||
*pkeycache= keycache;
|
||||
DBUG_PRINT("exit", ("key_cache: %lx", keycache));
|
||||
DBUG_RETURN((int) blocks);
|
||||
|
||||
err:
|
||||
|
@ -473,8 +474,8 @@ err:
|
|||
|
||||
SYNOPSIS
|
||||
resize_key_cache()
|
||||
pkeycache in/out pointer to the key cache handle
|
||||
key_cache_block_size size of blocks to keep cached data
|
||||
pkeycache in/out pointer to the key cache handle
|
||||
key_cache_block_size size of blocks to keep cached data
|
||||
use_mem total memory to use for the new key cache
|
||||
|
||||
RETURN VALUE
|
||||
|
@ -485,8 +486,8 @@ err:
|
|||
The function first compares the memory size and the block size parameters
|
||||
with the corresponding parameters of the key cache referred by
|
||||
*pkeycache. If they differ the function free the the memory allocated
|
||||
for the old key cache blocks by calling the end_key_cache function
|
||||
and then rebuilds the key cache with new blocks by calling init_key_cache.
|
||||
for the old key cache blocks by calling the end_key_cache function
|
||||
and then rebuilds the key cache with new blocks by calling init_key_cache.
|
||||
*/
|
||||
|
||||
int resize_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
||||
|
@ -494,6 +495,7 @@ int resize_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
{
|
||||
int blocks;
|
||||
KEY_CACHE *keycache= *pkeycache;
|
||||
DBUG_ENTER("resize_key_cache");
|
||||
|
||||
if (key_cache_block_size == keycache->key_cache_block_size &&
|
||||
use_mem == keycache->key_cache_mem_size)
|
||||
|
@ -507,20 +509,20 @@ int resize_key_cache(KEY_CACHE_HANDLE *pkeycache, uint key_cache_block_size,
|
|||
return 0;
|
||||
}
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
end_key_cache(pkeycache, 0);
|
||||
end_key_cache(keycache, 0);
|
||||
/* the following will work even if memory is 0 */
|
||||
blocks=init_key_cache(pkeycache, key_cache_block_size, use_mem,
|
||||
keycache->env);
|
||||
blocks= init_key_cache(pkeycache, key_cache_block_size, use_mem,
|
||||
keycache->env);
|
||||
return blocks;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Change the key cache parameters
|
||||
Change the key cache parameters
|
||||
|
||||
SYNOPSIS
|
||||
change_key_cache_param()
|
||||
keycache the key cache handle
|
||||
keycache the key cache handle
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
@ -537,14 +539,15 @@ void change_key_cache_param(KEY_CACHE_HANDLE keycache)
|
|||
KEY_CACHE_VAR *env= keycache->env;
|
||||
DBUG_ENTER("change_key_cache_param");
|
||||
|
||||
if (!env)
|
||||
return;
|
||||
if (env->division_limit)
|
||||
keycache->min_warm_blocks= keycache->disk_blocks *
|
||||
env->division_limit / 100 + 1;
|
||||
if (env->age_threshold)
|
||||
keycache->age_threshold= keycache->disk_blocks *
|
||||
env->age_threshold / 100;
|
||||
if (env)
|
||||
{
|
||||
if (env->division_limit)
|
||||
keycache->min_warm_blocks= (keycache->disk_blocks *
|
||||
env->division_limit / 100 + 1);
|
||||
if (env->age_threshold)
|
||||
keycache->age_threshold= (keycache->disk_blocks *
|
||||
env->age_threshold / 100);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -554,7 +557,7 @@ void change_key_cache_param(KEY_CACHE_HANDLE keycache)
|
|||
|
||||
SYNOPSIS
|
||||
end_key_cache()
|
||||
pkeycache in/out pointer to the key cache handle
|
||||
pkeycache in/out pointer to the key cache handle
|
||||
cleanup <-> the key cache data structure is freed as well
|
||||
|
||||
RETURN VALUE
|
||||
|
@ -562,15 +565,18 @@ void change_key_cache_param(KEY_CACHE_HANDLE keycache)
|
|||
|
||||
NOTES.
|
||||
If the cleanup parameter is TRUE the data structure with all associated
|
||||
elements are freed completely and NULL is assigned to *pkeycache.
|
||||
Otherwise only memory used by the key cache blocks is freed.
|
||||
elements are freed completely
|
||||
Otherwise only memory used by the key cache blocks is freed.
|
||||
*/
|
||||
|
||||
void end_key_cache(KEY_CACHE_HANDLE *pkeycache, my_bool cleanup)
|
||||
void end_key_cache(KEY_CACHE_HANDLE keycache, my_bool cleanup)
|
||||
{
|
||||
KEY_CACHE *keycache= *pkeycache;
|
||||
KEY_CACHE_VAR *env= keycache->env;
|
||||
KEY_CACHE_VAR *env;;
|
||||
DBUG_ENTER("end_key_cache");
|
||||
DBUG_PRINT("enter", ("key_cache: %lx", keycache));
|
||||
|
||||
if (!keycache)
|
||||
DBUG_VOID_RETURN;
|
||||
if (keycache->disk_blocks > 0)
|
||||
{
|
||||
if (keycache->block_mem)
|
||||
|
@ -584,18 +590,19 @@ void end_key_cache(KEY_CACHE_HANDLE *pkeycache, my_bool cleanup)
|
|||
}
|
||||
KEYCACHE_DEBUG_CLOSE;
|
||||
keycache->key_cache_inited= 0;
|
||||
if (env)
|
||||
if ((env= keycache->env))
|
||||
{
|
||||
DBUG_PRINT("status",
|
||||
("used: %d changed: %d w_requests: %ld \
|
||||
writes: %ld r_requests: %ld reads: %ld",
|
||||
env->blocks_used, env->blocks_changed,
|
||||
env->blocks_used, env->blocks_changed,
|
||||
env->cache_w_requests, env->cache_write,
|
||||
env->cache_r_requests, env->cache_read));
|
||||
}
|
||||
if (cleanup)
|
||||
{
|
||||
pthread_mutex_destroy(&keycache->cache_lock);
|
||||
my_free((gptr) *pkeycache, MYF(0));
|
||||
*pkeycache= NULL;
|
||||
my_free((gptr) keycache, MYF(0));
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
} /* end_key_cache */
|
||||
|
@ -606,8 +613,8 @@ void end_key_cache(KEY_CACHE_HANDLE *pkeycache, my_bool cleanup)
|
|||
|
||||
SYNOPSIS
|
||||
link_into_queue()
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
@ -643,8 +650,8 @@ static inline void link_into_queue(KEYCACHE_WQUEUE *wqueue,
|
|||
|
||||
SYNOPSIS
|
||||
unlink_from_queue()
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be removed from the queue
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be removed from the queue
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
@ -677,8 +684,8 @@ static inline void unlink_from_queue(KEYCACHE_WQUEUE *wqueue,
|
|||
|
||||
SYNOPSIS
|
||||
add_to_queue()
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
@ -709,8 +716,8 @@ static inline void add_to_queue(KEYCACHE_WQUEUE *wqueue,
|
|||
|
||||
SYNOPSIS
|
||||
realease_queue()
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
wqueue pointer to the queue structure
|
||||
thread pointer to the thread to be added to the queue
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
@ -718,7 +725,7 @@ static inline void add_to_queue(KEYCACHE_WQUEUE *wqueue,
|
|||
NOTES.
|
||||
See notes for add_to_queue
|
||||
When removed from the queue each thread is signaled via condition
|
||||
variable thread->suspend.
|
||||
variable thread->suspend.
|
||||
*/
|
||||
|
||||
static void release_queue(KEYCACHE_WQUEUE *wqueue)
|
||||
|
@ -809,7 +816,7 @@ static inline void link_to_changed_list(KEY_CACHE *keycache,
|
|||
|
||||
SYNOPSIS
|
||||
link_block()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
block pointer to the block to link to the LRU chain
|
||||
hot <-> to link the block into the hot subchain
|
||||
at_end <-> to link the block at the end of the subchain
|
||||
|
@ -818,11 +825,11 @@ static inline void link_to_changed_list(KEY_CACHE *keycache,
|
|||
none
|
||||
|
||||
NOTES.
|
||||
The LRU chain is represented by a curcular list of block structures.
|
||||
The list is double-linked of the type (**prev,*next) type.
|
||||
The LRU chain is divided into two parts - hot and warm.
|
||||
The LRU chain is represented by a curcular list of block structures.
|
||||
The list is double-linked of the type (**prev,*next) type.
|
||||
The LRU chain is divided into two parts - hot and warm.
|
||||
There are two pointers to access the last blocks of these two
|
||||
parts. The beginning of the warm part follows right after the
|
||||
parts. The beginning of the warm part follows right after the
|
||||
end of the hot part.
|
||||
Only blocks of the warm part can be used for replacement.
|
||||
The first block from the beginning of this subchain is always
|
||||
|
@ -836,12 +843,12 @@ static inline void link_to_changed_list(KEY_CACHE *keycache,
|
|||
| +------+ W A R M +------+ |
|
||||
+----| beg |---->...----| end |----+
|
||||
+------+ +------+ins
|
||||
first for eviction
|
||||
first for eviction
|
||||
*/
|
||||
|
||||
static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
|
||||
my_bool at_end)
|
||||
{
|
||||
{
|
||||
BLOCK_LINK *ins;
|
||||
BLOCK_LINK **pins;
|
||||
|
||||
|
@ -881,7 +888,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
|
|||
return;
|
||||
}
|
||||
pins= hot ? &keycache->used_ins : &keycache->used_last;
|
||||
ins= *pins;
|
||||
ins= *pins;
|
||||
if (ins)
|
||||
{
|
||||
ins->next_used->prev_used= &block->next_used;
|
||||
|
@ -915,7 +922,7 @@ static void link_block(KEY_CACHE *keycache, BLOCK_LINK *block, my_bool hot,
|
|||
|
||||
SYNOPSIS
|
||||
unlink_block()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
block pointer to the block to unlink from the LRU chain
|
||||
|
||||
RETURN VALUE
|
||||
|
@ -938,7 +945,7 @@ static void unlink_block(KEY_CACHE *keycache, BLOCK_LINK *block)
|
|||
keycache->used_last= STRUCT_PTR(BLOCK_LINK, next_used, block->prev_used);
|
||||
if (keycache->used_ins == block)
|
||||
keycache->used_ins=STRUCT_PTR(BLOCK_LINK, next_used, block->prev_used);
|
||||
}
|
||||
}
|
||||
block->next_used= NULL;
|
||||
|
||||
KEYCACHE_THREAD_TRACE("unlink_block");
|
||||
|
@ -972,27 +979,27 @@ static void reg_requests(KEY_CACHE *keycache, BLOCK_LINK *block, int count)
|
|||
SYNOPSIS
|
||||
|
||||
unreg_block()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
block pointer to the block to link to the LRU chain
|
||||
at_end <-> to link the block at the end of the LRU chain
|
||||
|
||||
RETURN VALUE
|
||||
none
|
||||
|
||||
NOTES.
|
||||
NOTES.
|
||||
Every linking to the LRU chain decrements by one a special block
|
||||
counter (if it's positive). If the at_end parameter is TRUE the block is
|
||||
added either at the end of warm sub-chain or at the end of hot sub-chain.
|
||||
It is added to the hot subchain if its counter is zero and number of
|
||||
blocks in warm sub-chain is not less than some low limit (determined by
|
||||
It is added to the hot subchain if its counter is zero and number of
|
||||
blocks in warm sub-chain is not less than some low limit (determined by
|
||||
the division_limit parameter). Otherwise the block is added to the warm
|
||||
sub-chain. If the at_end parameter is FALSE the block is always added
|
||||
at beginning of the warm sub-chain.
|
||||
at beginning of the warm sub-chain.
|
||||
Thus a warm block can be promoted to the hot sub-chain when its counter
|
||||
becomes zero for the first time.
|
||||
At the same time the block at the very beginning of the hot subchain
|
||||
might be moved to the beginning of the warm subchain if it stays untouched
|
||||
for a too long time (this time is determined by parameter age_threshold).
|
||||
for a too long time (this time is determined by parameter age_threshold).
|
||||
*/
|
||||
|
||||
static inline void unreg_request(KEY_CACHE *keycache,
|
||||
|
@ -1123,7 +1130,7 @@ static void unlink_hash(KEY_CACHE *keycache, HASH_LINK *hash_link)
|
|||
Get the hash link for a page
|
||||
*/
|
||||
|
||||
static HASH_LINK *get_hash_link(KEY_CACHE *keycache,
|
||||
static HASH_LINK *get_hash_link(KEY_CACHE *keycache,
|
||||
int file, my_off_t filepos)
|
||||
{
|
||||
reg1 HASH_LINK *hash_link, **start;
|
||||
|
@ -1206,16 +1213,16 @@ restart:
|
|||
Get a block for the file page requested by a keycache read/write operation;
|
||||
If the page is not in the cache return a free block, if there is none
|
||||
return the lru block after saving its buffer if the page is dirty.
|
||||
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
find_key_block()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file to read page from
|
||||
filepos position of the page in the file
|
||||
init_hits_left how initialize the block counter for the page
|
||||
wrmode <-> get for writing
|
||||
page_st out {PAGE_READ,PAGE_TO_BE_READ,PAGE_WAIT_TO_BE_READ}
|
||||
page_st out {PAGE_READ,PAGE_TO_BE_READ,PAGE_WAIT_TO_BE_READ}
|
||||
|
||||
RETURN VALUE
|
||||
Pointer to the found block if successful, 0 - otherwise
|
||||
|
@ -1227,15 +1234,15 @@ restart:
|
|||
If not, the function first chooses a block for this page. If there is
|
||||
no not used blocks in the key cache yet, the function takes the block
|
||||
at the very beginning of the warm sub-chain. It saves the page in that
|
||||
block if it's dirty before returning the pointer to it.
|
||||
block if it's dirty before returning the pointer to it.
|
||||
The function returns in the page_st parameter the following values:
|
||||
PAGE_READ - if page already in the block,
|
||||
PAGE_TO_BE_READ - if it is to be read yet by the current thread
|
||||
WAIT_TO_BE_READ - if it is to be read by another thread
|
||||
WAIT_TO_BE_READ - if it is to be read by another thread
|
||||
If an error occurs THE BLOCK_ERROR bit is set in the block status.
|
||||
It might happen that there are no blocks in LRU chain (in warm part) -
|
||||
all blocks are unlinked for some read/write operations. Then the function
|
||||
waits until first of this operations links any block back.
|
||||
waits until first of this operations links any block back.
|
||||
*/
|
||||
|
||||
static BLOCK_LINK *find_key_block(KEY_CACHE *keycache,
|
||||
|
@ -1388,9 +1395,11 @@ restart:
|
|||
The call is thread safe because only the current
|
||||
thread might change the block->hash_link value
|
||||
*/
|
||||
error=my_pwrite(block->hash_link->file, block->buffer,
|
||||
block->length, block->hash_link->diskpos,
|
||||
MYF(MY_NABP | MY_WAIT_IF_FULL));
|
||||
error= my_pwrite(block->hash_link->file,
|
||||
block->buffer+block->offset,
|
||||
block->length - block->offset,
|
||||
block->hash_link->diskpos+ block->offset,
|
||||
MYF(MY_NABP | MY_WAIT_IF_FULL));
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
if (keycache->env)
|
||||
keycache->env->cache_write++;
|
||||
|
@ -1465,12 +1474,12 @@ restart:
|
|||
SYNOPSIS
|
||||
|
||||
read_block()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
block block to which buffer the data is to be read
|
||||
read_length size of data to be read
|
||||
min_length at least so much data must be read
|
||||
primary <-> the current thread will read the data
|
||||
|
||||
read_length size of data to be read
|
||||
min_length at least so much data must be read
|
||||
primary <-> the current thread will read the data
|
||||
|
||||
RETURN VALUE
|
||||
None
|
||||
|
||||
|
@ -1551,15 +1560,15 @@ static void read_block(KEY_CACHE *keycache,
|
|||
SYNOPSIS
|
||||
|
||||
key_cache_read()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file for the block of data to be read
|
||||
filepos position of the block of data in the file
|
||||
level determines the weight of the data
|
||||
buff buffer to where the data must be placed
|
||||
buff buffer to where the data must be placed
|
||||
length length of the buffer
|
||||
block_length length of the block in the key cache buffer
|
||||
return_buffer return pointer to the key cache buffer with the data
|
||||
|
||||
block_length length of the block in the key cache buffer
|
||||
return_buffer return pointer to the key cache buffer with the data
|
||||
|
||||
RETURN VALUE
|
||||
Returns address from where the data is placed if sucessful, 0 - otherwise.
|
||||
|
||||
|
@ -1584,7 +1593,7 @@ byte *key_cache_read(KEY_CACHE_HANDLE keycache,
|
|||
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u",
|
||||
(uint) file, (ulong) filepos, length));
|
||||
|
||||
if (keycache->disk_blocks > 0)
|
||||
if (keycache && keycache->disk_blocks > 0)
|
||||
{
|
||||
/* Key cache is used */
|
||||
reg1 BLOCK_LINK *block;
|
||||
|
@ -1613,7 +1622,7 @@ byte *key_cache_read(KEY_CACHE_HANDLE keycache,
|
|||
if (block->status != BLOCK_ERROR && page_st != PAGE_READ)
|
||||
{
|
||||
/* The requested page is to be read into the block buffer */
|
||||
read_block(keycache, block,
|
||||
read_block(keycache, block,
|
||||
keycache->key_cache_block_size, read_length+offset,
|
||||
(my_bool)(page_st == PAGE_TO_BE_READ));
|
||||
}
|
||||
|
@ -1677,7 +1686,7 @@ byte *key_cache_read(KEY_CACHE_HANDLE keycache,
|
|||
}
|
||||
|
||||
/* Key cache is not used */
|
||||
if (keycache->env)
|
||||
if (keycache && keycache->env)
|
||||
{
|
||||
statistic_increment(keycache->env->cache_r_requests,
|
||||
&keycache->cache_lock);
|
||||
|
@ -1696,13 +1705,13 @@ byte *key_cache_read(KEY_CACHE_HANDLE keycache,
|
|||
SYNOPSIS
|
||||
|
||||
key_cache_insert()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file to insert data from
|
||||
filepos position of the block of data in the file to insert
|
||||
level determines the weight of the data
|
||||
buff buffer to read data from
|
||||
length length of the data in the buffer
|
||||
|
||||
|
||||
RETURN VALUE
|
||||
0 if a success, 1 - otherwise.
|
||||
*/
|
||||
|
@ -1777,20 +1786,20 @@ int key_cache_insert(KEY_CACHE_HANDLE keycache,
|
|||
|
||||
|
||||
/*
|
||||
Write a buffer into a cached file.
|
||||
|
||||
Write a buffer into a cached file.
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
key_cache_write()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file to write data to
|
||||
filepos position in the file to write data to
|
||||
level determines the weight of the data
|
||||
buff buffer with the data
|
||||
buff buffer with the data
|
||||
length length of the buffer
|
||||
dont_write if is 0 then all dirty pages involved in writing
|
||||
should have been flushed from key cache
|
||||
|
||||
should have been flushed from key cache
|
||||
|
||||
RETURN VALUE
|
||||
0 if a success, 1 - otherwise.
|
||||
|
||||
|
@ -1798,7 +1807,7 @@ int key_cache_insert(KEY_CACHE_HANDLE keycache,
|
|||
The function copies the data of size length from buff into buffers
|
||||
for key cache blocks that are assigned to contain the portion of
|
||||
the file starting with position filepos.
|
||||
It ensures that this data is flushed to the file if dont_write is FALSE.
|
||||
It ensures that this data is flushed to the file if dont_write is FALSE.
|
||||
Filepos must be a multiple of 'block_length', but it doesn't
|
||||
have to be a multiple of key_cache_block_size;
|
||||
*/
|
||||
|
@ -1811,15 +1820,16 @@ int key_cache_write(KEY_CACHE_HANDLE keycache,
|
|||
{
|
||||
reg1 BLOCK_LINK *block;
|
||||
int error=0;
|
||||
|
||||
DBUG_ENTER("key_cache_write");
|
||||
DBUG_PRINT("enter", ("file %u, filepos %lu, length %u block_length %u",
|
||||
(uint) file, (ulong) filepos, length, block_length));
|
||||
DBUG_PRINT("enter",
|
||||
("file %u filepos %lu length %u block_length %u key_block_length: %u",
|
||||
(uint) file, (ulong) filepos, length, block_length,
|
||||
keycache ? keycache->key_cache_block_size : 0));
|
||||
|
||||
if (!dont_write)
|
||||
{
|
||||
/* Force writing from buff into disk */
|
||||
if (keycache->env)
|
||||
if (keycache && keycache->env)
|
||||
statistic_increment(keycache->env->cache_write,
|
||||
&keycache->cache_lock);
|
||||
if (my_pwrite(file, buff, length, filepos, MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
||||
|
@ -1831,7 +1841,7 @@ int key_cache_write(KEY_CACHE_HANDLE keycache,
|
|||
test_key_cache(keycache, "start of key_cache_write", 1););
|
||||
#endif
|
||||
|
||||
if (keycache->disk_blocks > 0)
|
||||
if (keycache && keycache->disk_blocks > 0)
|
||||
{
|
||||
/* Key cache is used */
|
||||
uint read_length;
|
||||
|
@ -1872,7 +1882,7 @@ int key_cache_write(KEY_CACHE_HANDLE keycache,
|
|||
if (! (block->status & BLOCK_ERROR))
|
||||
{
|
||||
if (!(read_length & 511))
|
||||
bmove512(block->buffer+offset, buff, read_length);
|
||||
bmove512(block->buffer+offset, buff, read_length);
|
||||
else
|
||||
memcpy(block->buffer+offset, buff, (size_t) read_length);
|
||||
}
|
||||
|
@ -1903,14 +1913,14 @@ int key_cache_write(KEY_CACHE_HANDLE keycache,
|
|||
/* Key cache is not used */
|
||||
if (dont_write)
|
||||
{
|
||||
if (keycache->env)
|
||||
if (keycache && keycache->env)
|
||||
{
|
||||
statistic_increment(keycache->env->cache_w_requests,
|
||||
&keycache->cache_lock);
|
||||
statistic_increment(keycache->env->cache_write,
|
||||
&keycache->cache_lock);
|
||||
statistic_increment(keycache->env->cache_write,
|
||||
&keycache->cache_lock);
|
||||
}
|
||||
if (my_pwrite(file, (byte*) buff, length, filepos,
|
||||
if (my_pwrite(file, (byte*) buff, length, filepos,
|
||||
MYF(MY_NABP | MY_WAIT_IF_FULL)))
|
||||
error=1;
|
||||
}
|
||||
|
@ -1991,8 +2001,10 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
|
|||
KEYCACHE_DBUG_PRINT("flush_cached_blocks",
|
||||
("block %u to be flushed", BLOCK_NUMBER(block)));
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
error= my_pwrite(file, block->buffer+block->offset, block->length,
|
||||
block->hash_link->diskpos,
|
||||
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));
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
if (keycache->env)
|
||||
|
@ -2024,27 +2036,30 @@ static int flush_cached_blocks(KEY_CACHE *keycache,
|
|||
|
||||
|
||||
/*
|
||||
Flush all blocks for a file to disk
|
||||
|
||||
SYNOPSIS
|
||||
flush all key blocks for a file to disk, but don't do any mutex locks
|
||||
|
||||
flush_key_blocks()
|
||||
keycache pointer to a key cache data structure
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file to flush to
|
||||
flush_type type of the flush
|
||||
|
||||
RETURN VALUE
|
||||
0 if a success, 1 - otherwise.
|
||||
*/
|
||||
|
||||
int flush_key_blocks(KEY_CACHE_HANDLE keycache,
|
||||
File file, enum flush_type type)
|
||||
NOTES
|
||||
This function doesn't do any mutex locks because it needs to be called both
|
||||
from flush_key_blocks and flush_all_key_blocks (the later one does the
|
||||
mutex lock in the resize_key_cache() function).
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
static int flush_key_blocks_int(KEY_CACHE_HANDLE keycache,
|
||||
File file, enum flush_type type)
|
||||
{
|
||||
KEY_CACHE_VAR *env;
|
||||
BLOCK_LINK *cache_buff[FLUSH_CACHE],**cache;
|
||||
int last_errno= 0;
|
||||
|
||||
DBUG_ENTER("flush_key_blocks");
|
||||
DBUG_ENTER("flush_key_blocks_int");
|
||||
DBUG_PRINT("enter",("file: %d blocks_used: %d blocks_changed: %d",
|
||||
file, keycache->blocks_used, keycache->blocks_changed));
|
||||
|
||||
|
@ -2053,8 +2068,6 @@ int flush_key_blocks(KEY_CACHE_HANDLE keycache,
|
|||
test_key_cache(keycache, "start of flush_key_blocks", 0););
|
||||
#endif
|
||||
|
||||
keycache_pthread_mutex_lock(&keycache->cache_lock);
|
||||
|
||||
cache= cache_buff;
|
||||
if (keycache->disk_blocks > 0 &&
|
||||
(!my_disable_flush_key_blocks || type != FLUSH_KEEP))
|
||||
|
@ -2132,7 +2145,7 @@ restart:
|
|||
This happens only if there is not enough
|
||||
memory for the big block
|
||||
*/
|
||||
if ((error= flush_cached_blocks(keycache, file, cache,
|
||||
if ((error= flush_cached_blocks(keycache, file, cache,
|
||||
end,type)))
|
||||
last_errno=error;
|
||||
/*
|
||||
|
@ -2214,12 +2227,8 @@ restart:
|
|||
}
|
||||
}
|
||||
|
||||
keycache_pthread_mutex_unlock(&keycache->cache_lock);
|
||||
|
||||
if (type == FLUSH_REMOVE && (env= keycache->env) && (env->action))
|
||||
{
|
||||
(*env->action)((void *) env);
|
||||
}
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
DBUG_EXECUTE("check_keycache",
|
||||
|
@ -2233,6 +2242,37 @@ restart:
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Flush all blocks for a file to disk
|
||||
|
||||
SYNOPSIS
|
||||
|
||||
flush_key_blocks()
|
||||
keycache pointer to a key cache data structure
|
||||
file handler for the file to flush to
|
||||
flush_type type of the flush
|
||||
|
||||
RETURN
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
int flush_key_blocks(KEY_CACHE_HANDLE key_cache,
|
||||
File file, enum flush_type type)
|
||||
{
|
||||
int res;
|
||||
DBUG_ENTER("flush_key_blocks");
|
||||
DBUG_PRINT("enter", ("key_cache: %lx", key_cache));
|
||||
|
||||
if (!key_cache || !key_cache->disk_blocks)
|
||||
DBUG_RETURN(0);
|
||||
keycache_pthread_mutex_lock(&key_cache->cache_lock);
|
||||
res= flush_key_blocks_int(key_cache, file, type);
|
||||
keycache_pthread_mutex_unlock(&key_cache->cache_lock);
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Flush all blocks in the key cache to disk
|
||||
*/
|
||||
|
@ -2253,7 +2293,8 @@ static int flush_all_key_blocks(KEY_CACHE *keycache)
|
|||
cnt++;
|
||||
KEYCACHE_DBUG_ASSERT(cnt <= keycache->blocks_used);
|
||||
#endif
|
||||
if (flush_key_blocks(keycache, block->hash_link->file, FLUSH_RELEASE))
|
||||
if (flush_key_blocks_int(keycache, block->hash_link->file,
|
||||
FLUSH_RELEASE))
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
|
|
359
mysys/mf_keycaches.c
Normal file
359
mysys/mf_keycaches.c
Normal file
|
@ -0,0 +1,359 @@
|
|||
/* Copyright (C) 2003 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 <hash.h>
|
||||
#include <m_string.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).
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Struct to store a key and pointer to object
|
||||
*/
|
||||
|
||||
typedef struct st_safe_hash_entry
|
||||
{
|
||||
byte *key;
|
||||
uint length;
|
||||
byte *data;
|
||||
struct st_safe_hash_entry *next, **prev;
|
||||
} SAFE_HASH_ENTRY;
|
||||
|
||||
|
||||
typedef struct st_safe_hash_with_default
|
||||
{
|
||||
#ifdef THREAD
|
||||
rw_lock_t mutex;
|
||||
#endif
|
||||
HASH hash;
|
||||
byte *default_value;
|
||||
SAFE_HASH_ENTRY *root;
|
||||
} SAFE_HASH;
|
||||
|
||||
|
||||
/*
|
||||
Free a SAFE_HASH_ENTRY
|
||||
|
||||
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 */
|
||||
|
||||
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
|
||||
*/
|
||||
|
||||
static 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
|
||||
|
||||
NOTES
|
||||
This is safe to call on any object that has been sent to safe_hash_init()
|
||||
*/
|
||||
|
||||
static 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
|
||||
*/
|
||||
|
||||
static byte *safe_hash_search(SAFE_HASH *hash, const byte *key, uint length)
|
||||
{
|
||||
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= hash->default_value;
|
||||
else
|
||||
result= ((SAFE_HASH_ENTRY*) result)->data;
|
||||
DBUG_PRINT("exit",("data: %lx", result));
|
||||
DBUG_RETURN(result);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Associate a key with some data
|
||||
|
||||
SYONOPSIS
|
||||
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.
|
||||
*/
|
||||
|
||||
static 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: %lx", length, key, 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_delete((char*) entry, MYF(0));
|
||||
error= 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
rw_unlock(&hash->mutex);
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Change all entres with one data value to another data value
|
||||
|
||||
SYONOPSIS
|
||||
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.
|
||||
*/
|
||||
|
||||
static 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)
|
||||
hash_delete(&hash->hash, (byte*) entry);
|
||||
else
|
||||
entry->data= new_data;
|
||||
}
|
||||
}
|
||||
|
||||
rw_unlock(&hash->mutex);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Functions to handle the key cache objects
|
||||
*****************************************************************************/
|
||||
|
||||
/* Variable to store all key cache objects */
|
||||
static SAFE_HASH key_cache_hash;
|
||||
|
||||
|
||||
my_bool multi_keycache_init(void)
|
||||
{
|
||||
return safe_hash_init(&key_cache_hash, 16, (byte*) dflt_keycache);
|
||||
}
|
||||
|
||||
|
||||
void multi_keycache_free(void)
|
||||
{
|
||||
safe_hash_free(&key_cache_hash);
|
||||
}
|
||||
|
||||
/*
|
||||
Get a key cache to be used for a specific table.
|
||||
|
||||
SYNOPSIS
|
||||
multi_key_cache_get()
|
||||
key key to find (usually table path)
|
||||
uint length Length of key.
|
||||
|
||||
NOTES
|
||||
This function is coded in such a way that we will return the
|
||||
default key cache even if one never called multi_keycache_init.
|
||||
This will ensure that it works with old MyISAM clients.
|
||||
|
||||
RETURN
|
||||
key cache to use
|
||||
*/
|
||||
|
||||
KEY_CACHE_HANDLE *multi_key_cache_search(byte *key, uint length)
|
||||
{
|
||||
if (!key_cache_hash.hash.records)
|
||||
return dflt_keycache;
|
||||
return (KEY_CACHE_HANDLE*) safe_hash_search(&key_cache_hash, key, length);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Assosiate a key cache with a key
|
||||
|
||||
|
||||
SYONOPSIS
|
||||
multi_key_cache_set()
|
||||
key key (path to table etc..)
|
||||
length Length of key
|
||||
key_cache cache to assococite with the table
|
||||
|
||||
NOTES
|
||||
This can be used both to insert a new entry and change an existing
|
||||
entry
|
||||
*/
|
||||
|
||||
|
||||
my_bool multi_key_cache_set(const byte *key, uint length,
|
||||
KEY_CACHE_HANDLE *key_cache)
|
||||
{
|
||||
return safe_hash_set(&key_cache_hash, key, length, (byte*) key_cache);
|
||||
}
|
||||
|
||||
|
||||
void multi_key_cache_change(KEY_CACHE_HANDLE *old_data,
|
||||
KEY_CACHE_HANDLE *new_data)
|
||||
{
|
||||
safe_hash_change(&key_cache_hash, (byte*) old_data, (byte*) new_data);
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
#include <assert.h>
|
||||
#include <m_string.h>
|
||||
|
||||
|
||||
inline void bitmap_lock(MY_BITMAP *map)
|
||||
{
|
||||
#ifdef THREAD
|
||||
|
@ -46,6 +47,7 @@ inline void bitmap_lock(MY_BITMAP *map)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline void bitmap_unlock(MY_BITMAP *map)
|
||||
{
|
||||
#ifdef THREAD
|
||||
|
@ -54,14 +56,19 @@ inline void bitmap_unlock(MY_BITMAP *map)
|
|||
#endif
|
||||
}
|
||||
|
||||
my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread_safe)
|
||||
|
||||
my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size,
|
||||
my_bool thread_safe)
|
||||
{
|
||||
DBUG_ENTER("bitmap_init");
|
||||
|
||||
DBUG_ASSERT((bitmap_size & 7) == 0);
|
||||
bitmap_size/=8;
|
||||
if (!(map->bitmap=buf) &&
|
||||
!(map->bitmap=(uchar*)my_malloc(bitmap_size +
|
||||
(thread_safe ? sizeof(pthread_mutex_t) : 0),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
!(map->bitmap= (uchar*) my_malloc(bitmap_size +
|
||||
(thread_safe ?
|
||||
sizeof(pthread_mutex_t) : 0),
|
||||
MYF(MY_WME | MY_ZEROFILL))))
|
||||
return 1;
|
||||
map->bitmap_size=bitmap_size;
|
||||
#ifdef THREAD
|
||||
|
@ -73,22 +80,26 @@ my_bool bitmap_init(MY_BITMAP *map, uchar *buf, uint bitmap_size, my_bool thread
|
|||
else
|
||||
map->mutex=0;
|
||||
#endif
|
||||
return 0;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_free(MY_BITMAP *map)
|
||||
{
|
||||
#ifdef THREAD
|
||||
if (map->mutex)
|
||||
pthread_mutex_destroy(map->mutex);
|
||||
#endif
|
||||
DBUG_ENTER("bitmap_free");
|
||||
if (map->bitmap)
|
||||
{
|
||||
#ifdef THREAD
|
||||
if (map->mutex)
|
||||
pthread_mutex_destroy(map->mutex);
|
||||
#endif
|
||||
my_free((char*) map->bitmap, MYF(0));
|
||||
map->bitmap=0;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
|
||||
{
|
||||
DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
|
||||
|
@ -97,6 +108,7 @@ void bitmap_set_bit(MY_BITMAP *map, uint bitmap_bit)
|
|||
bitmap_unlock(map);
|
||||
}
|
||||
|
||||
|
||||
uint bitmap_set_next(MY_BITMAP *map)
|
||||
{
|
||||
uchar *bitmap=map->bitmap;
|
||||
|
@ -127,6 +139,7 @@ uint bitmap_set_next(MY_BITMAP *map)
|
|||
return bit_found;
|
||||
}
|
||||
|
||||
|
||||
void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
|
||||
{
|
||||
DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
|
||||
|
@ -135,12 +148,13 @@ void bitmap_clear_bit(MY_BITMAP *map, uint bitmap_bit)
|
|||
bitmap_unlock(map);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
|
||||
{
|
||||
uint prefix_bytes, prefix_bits;
|
||||
|
||||
DBUG_ASSERT(map->bitmap &&
|
||||
(prefix_size <= map->bitmap_size*8 || prefix_size == ~0));
|
||||
(prefix_size <= map->bitmap_size*8 || prefix_size == (uint) ~0));
|
||||
bitmap_lock(map);
|
||||
set_if_smaller(prefix_size, map->bitmap_size*8);
|
||||
if ((prefix_bytes= prefix_size / 8))
|
||||
|
@ -152,16 +166,19 @@ void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size)
|
|||
bitmap_unlock(map);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_clear_all(MY_BITMAP *map)
|
||||
{
|
||||
bitmap_set_prefix(map, 0);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_set_all(MY_BITMAP *map)
|
||||
{
|
||||
bitmap_set_prefix(map, ~0);
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_is_prefix(const MY_BITMAP *map, uint prefix_size)
|
||||
{
|
||||
uint prefix_bits= prefix_size & 7, res= 0;
|
||||
|
@ -188,6 +205,7 @@ ret:
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_is_clear_all(const MY_BITMAP *map)
|
||||
{
|
||||
return bitmap_is_prefix(map, 0);
|
||||
|
@ -198,15 +216,17 @@ my_bool bitmap_is_set_all(const MY_BITMAP *map)
|
|||
return bitmap_is_prefix(map, map->bitmap_size*8);
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_is_set(const MY_BITMAP *map, uint bitmap_bit)
|
||||
{
|
||||
DBUG_ASSERT(map->bitmap && bitmap_bit < map->bitmap_size*8);
|
||||
return map->bitmap[bitmap_bit / 8] & (1 << (bitmap_bit & 7));
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
|
||||
{
|
||||
uint length, res=0;
|
||||
uint res=0;
|
||||
uchar *m1=map1->bitmap, *m2=map2->bitmap, *end;
|
||||
|
||||
DBUG_ASSERT(map1->bitmap && map2->bitmap &&
|
||||
|
@ -217,8 +237,10 @@ my_bool bitmap_is_subset(const MY_BITMAP *map1, const MY_BITMAP *map2)
|
|||
end= m1+map1->bitmap_size;
|
||||
|
||||
while (m1 < end)
|
||||
{
|
||||
if ((*m1++) & ~(*m2++))
|
||||
goto ret;
|
||||
}
|
||||
|
||||
res=1;
|
||||
ret:
|
||||
|
@ -227,6 +249,7 @@ ret:
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
|
||||
{
|
||||
uint res;
|
||||
|
@ -243,6 +266,7 @@ my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2)
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
|
||||
{
|
||||
uchar *to=map->bitmap, *from=map2->bitmap, *end;
|
||||
|
@ -268,6 +292,7 @@ void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2)
|
|||
bitmap_unlock(map);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
|
||||
{
|
||||
uchar *to=map->bitmap, *from=map2->bitmap, *end;
|
||||
|
@ -286,6 +311,7 @@ void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2)
|
|||
bitmap_unlock(map);
|
||||
}
|
||||
|
||||
|
||||
void bitmap_union(MY_BITMAP *map, const MY_BITMAP *map2)
|
||||
{
|
||||
uchar *to=map->bitmap, *from=map2->bitmap, *end;
|
||||
|
|
|
@ -682,60 +682,77 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp)
|
|||
return num;
|
||||
}
|
||||
|
||||
/*
|
||||
function: init_variables
|
||||
|
||||
/*
|
||||
Init one value to it's default values
|
||||
|
||||
SYNOPSIS
|
||||
init_one_value()
|
||||
option Option to initialize
|
||||
value Pointer to variable
|
||||
*/
|
||||
|
||||
static void init_one_value(const struct my_option *option, gptr *variable,
|
||||
longlong value)
|
||||
{
|
||||
switch ((option->var_type & GET_TYPE_MASK)) {
|
||||
case GET_BOOL:
|
||||
*((my_bool*) variable)= (my_bool) value;
|
||||
break;
|
||||
case GET_INT:
|
||||
*((int*) variable)= (int) value;
|
||||
break;
|
||||
case GET_UINT:
|
||||
*((uint*) variable)= (uint) value;
|
||||
break;
|
||||
case GET_LONG:
|
||||
*((long*) variable)= (long) value;
|
||||
break;
|
||||
case GET_ULONG:
|
||||
*((ulong*) variable)= (ulong) value;
|
||||
break;
|
||||
case GET_LL:
|
||||
*((longlong*) variable)= (longlong) value;
|
||||
break;
|
||||
case GET_ULL:
|
||||
*((ulonglong*) variable)= (ulonglong) value;
|
||||
break;
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
initialize all variables to their default values
|
||||
|
||||
SYNOPSIS
|
||||
init_variables()
|
||||
options Array of options
|
||||
|
||||
NOTES
|
||||
We will initialize the value that is pointed to by options->value.
|
||||
If the value is of type GET_ASK_ADDR, we will also ask for the address
|
||||
for a value and initialize.
|
||||
*/
|
||||
|
||||
static void init_variables(const struct my_option *options)
|
||||
{
|
||||
for (; options->name; options++)
|
||||
{
|
||||
gptr *value= (options->var_type & GET_ASK_ADDR ?
|
||||
(*getopt_get_addr)("", 0, options) : options->value);
|
||||
if (value)
|
||||
{
|
||||
switch ((options->var_type & GET_TYPE_MASK)) {
|
||||
case GET_BOOL:
|
||||
if (options->u_max_value)
|
||||
*((my_bool*) options->u_max_value)= (my_bool) options->max_value;
|
||||
*((my_bool*) value)= (my_bool) options->def_value;
|
||||
break;
|
||||
case GET_INT:
|
||||
if (options->u_max_value)
|
||||
*((int*) options->u_max_value)= (int) options->max_value;
|
||||
*((int*) value)= (int) options->def_value;
|
||||
break;
|
||||
case GET_UINT:
|
||||
if (options->u_max_value)
|
||||
*((uint*) options->u_max_value)= (uint) options->max_value;
|
||||
*((uint*) value)= (uint) options->def_value;
|
||||
break;
|
||||
case GET_LONG:
|
||||
if (options->u_max_value)
|
||||
*((long*) options->u_max_value)= (long) options->max_value;
|
||||
*((long*) value)= (long) options->def_value;
|
||||
break;
|
||||
case GET_ULONG:
|
||||
if (options->u_max_value)
|
||||
*((ulong*) options->u_max_value)= (ulong) options->max_value;
|
||||
*((ulong*) value)= (ulong) options->def_value;
|
||||
break;
|
||||
case GET_LL:
|
||||
if (options->u_max_value)
|
||||
*((longlong*) options->u_max_value)= (longlong) options->max_value;
|
||||
*((longlong*) value)= (longlong) options->def_value;
|
||||
break;
|
||||
case GET_ULL:
|
||||
if (options->u_max_value)
|
||||
*((ulonglong*) options->u_max_value)= (ulonglong) options->max_value;
|
||||
*((ulonglong*) value)= (ulonglong) options->def_value;
|
||||
break;
|
||||
default: /* dummy default to avoid compiler warnings */
|
||||
break;
|
||||
}
|
||||
}
|
||||
gptr *variable;
|
||||
/*
|
||||
We must set u_max_value first as for some variables
|
||||
options->u_max_value == options->value and in this case we want to
|
||||
set the value to default value.
|
||||
*/
|
||||
if (options->u_max_value)
|
||||
init_one_value(options, options->u_max_value, options->max_value);
|
||||
if (options->value)
|
||||
init_one_value(options, options->value, options->def_value);
|
||||
if (options->var_type & GET_ASK_ADDR &&
|
||||
(variable= (*getopt_get_addr)("", 0, options)))
|
||||
init_one_value(options, variable, options->def_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ pthread_key(struct st_my_thread_var*, THR_KEY_mysys);
|
|||
#else
|
||||
pthread_key(struct st_my_thread_var, THR_KEY_mysys);
|
||||
#endif /* USE_TLS */
|
||||
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,THR_LOCK_keycache,
|
||||
pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open,
|
||||
THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap,
|
||||
THR_LOCK_net, THR_LOCK_charset;
|
||||
#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R)
|
||||
|
@ -63,7 +63,6 @@ my_bool my_thread_global_init(void)
|
|||
|
||||
pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_keycache,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST);
|
||||
pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW);
|
||||
pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW);
|
||||
|
@ -96,7 +95,6 @@ void my_thread_global_end(void)
|
|||
#endif
|
||||
pthread_mutex_destroy(&THR_LOCK_malloc);
|
||||
pthread_mutex_destroy(&THR_LOCK_open);
|
||||
pthread_mutex_destroy(&THR_LOCK_keycache);
|
||||
pthread_mutex_destroy(&THR_LOCK_lock);
|
||||
pthread_mutex_destroy(&THR_LOCK_isam);
|
||||
pthread_mutex_destroy(&THR_LOCK_myisam);
|
||||
|
|
|
@ -20,15 +20,28 @@
|
|||
#include <m_string.h>
|
||||
#include <m_ctype.h>
|
||||
|
||||
/***************************************************************************
|
||||
** Search after a fieldtype. Endspace in x is not compared.
|
||||
** If part, uniq field is found and full_name == 0 then x is expanded
|
||||
** to full field.
|
||||
** full_name has the following bit values:
|
||||
** If & 1 accept only whole names
|
||||
** If & 2 don't expand if half field
|
||||
** If & 4 allow #number# as type
|
||||
****************************************************************************/
|
||||
|
||||
/*
|
||||
Search after a string in a list of strings. Endspace in x is not compared.
|
||||
|
||||
SYNOPSIS
|
||||
find_type()
|
||||
x String to find
|
||||
lib TYPELIB (struct of pointer to values + count)
|
||||
full_name bitmap of what to do
|
||||
If & 1 accept only whole names
|
||||
If & 2 don't expand if half field
|
||||
If & 4 allow #number# as type
|
||||
|
||||
NOTES
|
||||
If part, uniq field is found and full_name == 0 then x is expanded
|
||||
to full field.
|
||||
|
||||
RETURN
|
||||
-1 Too many matching values
|
||||
0 No matching value
|
||||
>0 Offset+1 in typelib for matched string
|
||||
*/
|
||||
|
||||
int find_type(my_string x, TYPELIB *typelib, uint full_name)
|
||||
{
|
||||
|
|
|
@ -754,7 +754,15 @@ mysql_free_result(MYSQL_RES *result)
|
|||
if ((pkt_len=net_safe_read(result->handle)) == packet_error)
|
||||
break;
|
||||
if (pkt_len <= 8 && result->handle->net.read_pos[0] == 254)
|
||||
{
|
||||
if (protocol_41(result->handle))
|
||||
{
|
||||
char *pos= (char*) result->handle->net.read_pos;
|
||||
result->handle->warning_count=uint2korr(pos); pos+=2;
|
||||
result->handle->server_status=uint2korr(pos); pos+=2;
|
||||
}
|
||||
break; /* End of data */
|
||||
}
|
||||
}
|
||||
result->handle->status=MYSQL_STATUS_READY;
|
||||
}
|
||||
|
@ -987,7 +995,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
|
|||
options->client_flag|= CLIENT_MULTI_RESULTS;
|
||||
break;
|
||||
case 31:
|
||||
options->client_flag|= CLIENT_MULTI_QUERIES | CLIENT_MULTI_RESULTS;
|
||||
options->client_flag|= CLIENT_MULTI_STATEMENTS | CLIENT_MULTI_RESULTS;
|
||||
break;
|
||||
default:
|
||||
DBUG_PRINT("warning",("unknown option: %s",option[0]));
|
||||
|
@ -1231,6 +1239,7 @@ MYSQL_DATA * STDCALL cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields,
|
|||
if (pkt_len > 1) /* MySQL 4.1 protocol */
|
||||
{
|
||||
mysql->warning_count= uint2korr(cp+1);
|
||||
mysql->server_status= uint2korr(cp+3);
|
||||
DBUG_PRINT("info",("warning_count: %ld", mysql->warning_count));
|
||||
}
|
||||
DBUG_PRINT("exit",("Got %d rows",result->rows));
|
||||
|
@ -1256,7 +1265,10 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths)
|
|||
if (pkt_len <= 8 && net->read_pos[0] == 254)
|
||||
{
|
||||
if (pkt_len > 1) /* MySQL 4.1 protocol */
|
||||
{
|
||||
mysql->warning_count= uint2korr(net->read_pos+1);
|
||||
mysql->server_status= uint2korr(net->read_pos+3);
|
||||
}
|
||||
return 1; /* End of data */
|
||||
}
|
||||
prev_pos= 0; /* allowed to write at packet[-1] */
|
||||
|
@ -1818,7 +1830,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
|
|||
|
||||
client_flag|=mysql->options.client_flag;
|
||||
client_flag|=CLIENT_CAPABILITIES;
|
||||
if (client_flag & CLIENT_MULTI_QUERIES)
|
||||
if (client_flag & CLIENT_MULTI_STATEMENTS)
|
||||
client_flag|= CLIENT_MULTI_RESULTS;
|
||||
|
||||
#ifdef HAVE_OPENSSL
|
||||
|
|
103
sql/ha_myisam.cc
103
sql/ha_myisam.cc
|
@ -226,15 +226,10 @@ err:
|
|||
|
||||
int ha_myisam::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
KEY_CACHE_VAR *key_cache;
|
||||
if (!(file=mi_open(name, mode, test_if_locked)))
|
||||
return (my_errno ? my_errno : -1);
|
||||
|
||||
/* Synchronize key cache assignment of the handler */
|
||||
KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache :
|
||||
&dflt_key_cache_var;
|
||||
VOID(mi_extra(file, HA_EXTRA_SET_KEY_CACHE,
|
||||
(void*) &key_cache->cache));
|
||||
|
||||
if (test_if_locked & (HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_TMP_TABLE))
|
||||
VOID(mi_extra(file, HA_EXTRA_NO_WAIT_LOCK, 0));
|
||||
info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
|
||||
|
@ -698,93 +693,48 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize)
|
|||
|
||||
|
||||
/*
|
||||
Assign table indexes to a key cache.
|
||||
Assign table indexes to a specific key cache.
|
||||
*/
|
||||
|
||||
int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
uint len;
|
||||
KEY_CACHE_VAR *old_key_cache;
|
||||
KEY_CACHE_VAR *new_key_cache;
|
||||
const char *errmsg=0;
|
||||
KEY_CACHE_VAR *new_key_cache= check_opt->key_cache;
|
||||
const char *errmsg= 0;
|
||||
int error= HA_ADMIN_OK;
|
||||
ulonglong map= ~(ulonglong) 0;
|
||||
TABLE_LIST *table_list= table->pos_in_table_list;
|
||||
const char *new_key_cache_name= table_list->option ?
|
||||
(const char *) table_list->option :
|
||||
DEFAULT_KEY_CACHE_NAME;
|
||||
KEY_CACHE_ASMT *key_cache_asmt= table->key_cache_asmt;
|
||||
bool triggered= key_cache_asmt->triggered;
|
||||
|
||||
DBUG_ENTER("ha_myisam::assign_to_keycache");
|
||||
|
||||
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||
|
||||
old_key_cache= key_cache_asmt->key_cache;
|
||||
|
||||
/* Check validity of the index references */
|
||||
if (!triggered && table_list->use_index)
|
||||
if (table_list->use_index)
|
||||
{
|
||||
/* We only come here when the user did specify an index map */
|
||||
key_map kmap;
|
||||
get_key_map_from_key_list(&kmap, table, table_list->use_index);
|
||||
if (kmap.is_set_all())
|
||||
if (get_key_map_from_key_list(&kmap, table, table_list->use_index))
|
||||
{
|
||||
errmsg= thd->net.last_error;
|
||||
error= HA_ADMIN_FAILED;
|
||||
goto err;
|
||||
}
|
||||
if (!kmap.is_clear_all())
|
||||
map= kmap.to_ulonglong();
|
||||
map= kmap.to_ulonglong();
|
||||
}
|
||||
|
||||
len= strlen(new_key_cache_name);
|
||||
new_key_cache= get_or_create_key_cache(new_key_cache_name, len);
|
||||
if (old_key_cache == new_key_cache)
|
||||
{
|
||||
/* Nothing to do: table is assigned to the same key cache */
|
||||
goto ok;
|
||||
}
|
||||
|
||||
if (!new_key_cache ||
|
||||
(!new_key_cache->cache && ha_key_cache(new_key_cache)))
|
||||
{
|
||||
if (key_cache_asmt->triggered)
|
||||
error= HA_ERR_OUT_OF_MEM;
|
||||
else
|
||||
{
|
||||
char buf[ERRMSGSIZE];
|
||||
my_snprintf(buf, ERRMSGSIZE,
|
||||
"Failed to create key cache %s", new_key_cache_name);
|
||||
errmsg= buf;
|
||||
error= HA_ADMIN_FAILED;
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
||||
reassign_key_cache(key_cache_asmt, new_key_cache);
|
||||
|
||||
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||
error= mi_assign_to_keycache(file, map, new_key_cache, &LOCK_assign);
|
||||
VOID(pthread_mutex_lock(&LOCK_assign));
|
||||
|
||||
if (error && !key_cache_asmt->triggered)
|
||||
if ((error= mi_assign_to_key_cache(file, map, new_key_cache)))
|
||||
{
|
||||
switch (error) {
|
||||
default:
|
||||
char buf[ERRMSGSIZE+20];
|
||||
my_snprintf(buf, ERRMSGSIZE,
|
||||
"Failed to flush to index file (errno: %d)", my_errno);
|
||||
char buf[80];
|
||||
my_snprintf(buf, sizeof(buf),
|
||||
"Failed to flush to index file (errno: %d)", error);
|
||||
errmsg= buf;
|
||||
}
|
||||
error= HA_ADMIN_CORRUPT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
goto ok;
|
||||
|
||||
err:
|
||||
if (!triggered)
|
||||
if (error != HA_ADMIN_OK)
|
||||
{
|
||||
/* Send error to user */
|
||||
MI_CHECK param;
|
||||
myisamchk_init(¶m);
|
||||
param.thd= thd;
|
||||
|
@ -793,32 +743,7 @@ int ha_myisam::assign_to_keycache(THD* thd, HA_CHECK_OPT *check_opt)
|
|||
param.table_name= table->table_name;
|
||||
param.testflag= 0;
|
||||
mi_check_print_error(¶m, errmsg);
|
||||
}
|
||||
|
||||
ok:
|
||||
if (--key_cache_asmt->requests)
|
||||
{
|
||||
/* There is a queue of assignments for the table */
|
||||
|
||||
/* Remove the first member from the queue */
|
||||
struct st_my_thread_var *last= key_cache_asmt->queue;
|
||||
struct st_my_thread_var *thread= last->next;
|
||||
if (thread->next == thread)
|
||||
key_cache_asmt->queue= 0;
|
||||
else
|
||||
{
|
||||
last->next= thread->next;
|
||||
last->next->prev= &last->next;
|
||||
thread->next= 0;
|
||||
}
|
||||
/* Signal the first waiting thread to proceed */
|
||||
VOID(pthread_cond_signal(&thread->suspend));
|
||||
}
|
||||
|
||||
key_cache_asmt->triggered= 0;
|
||||
|
||||
VOID(pthread_mutex_unlock(&LOCK_assign));
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,9 +35,12 @@
|
|||
const char **ha_myisammrg::bas_ext() const
|
||||
{ static const char *ext[]= { ".MRG", NullS }; return ext; }
|
||||
|
||||
|
||||
int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
|
||||
{
|
||||
char name_buff[FN_REFLEN];
|
||||
KEY_CACHE_VAR *key_cache;
|
||||
|
||||
DBUG_PRINT("info", ("ha_myisammrg::open"));
|
||||
if (!(file=myrg_open(fn_format(name_buff,name,"","",2 | 4), mode,
|
||||
test_if_locked)))
|
||||
|
@ -45,12 +48,6 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked)
|
|||
DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno));
|
||||
return (my_errno ? my_errno : -1);
|
||||
}
|
||||
/* Synchronize key cache assignment for the file */
|
||||
KEY_CACHE_VAR *key_cache= table->key_cache ? table->key_cache :
|
||||
&dflt_key_cache_var;
|
||||
VOID(myrg_extra(file, HA_EXTRA_SET_KEY_CACHE,
|
||||
(void*) &key_cache->cache));
|
||||
|
||||
DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc..."))
|
||||
myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref);
|
||||
if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED ||
|
||||
|
|
143
sql/handler.cc
143
sql/handler.cc
|
@ -1105,67 +1105,6 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
|||
DBUG_RETURN(error != 0);
|
||||
}
|
||||
|
||||
/* Use key cacheing on all databases */
|
||||
|
||||
int ha_key_cache(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (!key_cache->cache)
|
||||
{
|
||||
/*
|
||||
The following mutex is not really needed as long as keybuff_size is
|
||||
treated as a long value, but we use the mutex here to guard for future
|
||||
changes.
|
||||
*/
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
if (!key_cache->block_size)
|
||||
key_cache->block_size= dflt_key_cache_block_size;
|
||||
if (!key_cache->buff_size)
|
||||
key_cache->buff_size= dflt_key_buff_size;
|
||||
long tmp_buff_size= (long) key_cache->buff_size;
|
||||
long tmp_block_size= (long) key_cache->block_size;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return !init_key_cache(&key_cache->cache,
|
||||
tmp_block_size,
|
||||
tmp_buff_size,
|
||||
key_cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ha_resize_key_cache(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache->cache)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
long tmp_buff_size= (long) key_cache->buff_size;
|
||||
long tmp_block_size= (long) key_cache->block_size;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return !resize_key_cache(&key_cache->cache, tmp_block_size,
|
||||
tmp_buff_size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache->cache)
|
||||
{
|
||||
change_key_cache_param(key_cache->cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ha_end_key_cache(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache->cache)
|
||||
{
|
||||
end_key_cache(&key_cache->cache, 1);
|
||||
return key_cache->cache ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int NEAR_F delete_file(const char *name,const char *ext,int extflag)
|
||||
{
|
||||
char buff[FN_REFLEN];
|
||||
|
@ -1178,3 +1117,85 @@ void st_ha_check_opt::init()
|
|||
flags= sql_flags= 0;
|
||||
sort_buffer_size = current_thd->variables.myisam_sort_buff_size;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Key cache handling.
|
||||
|
||||
This code is only relevant for ISAM/MyISAM tables
|
||||
|
||||
key_cache->cache may be 0 only in the case where a key cache is not
|
||||
initialized or when we where not able to init the key cache in a previous
|
||||
call to ha_init_key_cache() (probably out of memory)
|
||||
*****************************************************************************/
|
||||
|
||||
/* Init a key cache if it has not been initied before */
|
||||
|
||||
|
||||
int ha_init_key_cache(const char *name, KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
DBUG_ENTER("ha_init_key_cache");
|
||||
|
||||
if (!key_cache->cache)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
long tmp_buff_size= (long) key_cache->buff_size;
|
||||
long tmp_block_size= (long) key_cache->block_size;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
DBUG_RETURN(!init_key_cache(&key_cache->cache,
|
||||
tmp_block_size,
|
||||
tmp_buff_size,
|
||||
key_cache));
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/* Resize key cache */
|
||||
|
||||
int ha_resize_key_cache(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
DBUG_ENTER("ha_resize_key_cache");
|
||||
|
||||
if (key_cache->cache)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
long tmp_buff_size= (long) key_cache->buff_size;
|
||||
long tmp_block_size= (long) key_cache->block_size;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
DBUG_RETURN(!resize_key_cache(&key_cache->cache, tmp_block_size,
|
||||
tmp_buff_size));
|
||||
}
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/* Change parameters for key cache (like size) */
|
||||
|
||||
int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache->cache)
|
||||
change_key_cache_param(key_cache->cache);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Free memory allocated by a key cache */
|
||||
|
||||
int ha_end_key_cache(KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache->cache)
|
||||
{
|
||||
end_key_cache(key_cache->cache, 1); // Can never fail
|
||||
key_cache->cache= 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move all tables from one key cache to another one */
|
||||
|
||||
int ha_change_key_cache(KEY_CACHE_VAR *old_key_cache,
|
||||
KEY_CACHE_VAR *new_key_cache)
|
||||
{
|
||||
mi_change_key_cache(old_key_cache, new_key_cache);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -145,6 +145,7 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
|||
#define HA_CREATE_USED_AVG_ROW_LENGTH 64
|
||||
#define HA_CREATE_USED_PACK_KEYS 128
|
||||
#define HA_CREATE_USED_CHARSET 256
|
||||
#define HA_CREATE_USED_DEFAULT_CHARSET 512
|
||||
|
||||
typedef struct st_thd_trans {
|
||||
void *bdb_tid;
|
||||
|
@ -157,7 +158,7 @@ enum enum_tx_isolation { ISO_READ_UNCOMMITTED, ISO_READ_COMMITTED,
|
|||
|
||||
typedef struct st_ha_create_information
|
||||
{
|
||||
CHARSET_INFO *table_charset;
|
||||
CHARSET_INFO *table_charset, *default_table_charset;
|
||||
char *comment,*password;
|
||||
char *data_file_name, *index_file_name;
|
||||
ulonglong max_rows,min_rows;
|
||||
|
@ -180,15 +181,18 @@ typedef struct st_ha_create_information
|
|||
|
||||
struct st_table;
|
||||
typedef struct st_table TABLE;
|
||||
typedef struct st_key_cache_asmt KEY_CACHE_ASMT;
|
||||
|
||||
typedef struct st_ha_check_opt
|
||||
{
|
||||
ulong sort_buffer_size;
|
||||
uint flags; /* isam layer flags (e.g. for myisamchk) */
|
||||
uint sql_flags; /* sql layer flags - for something myisamchk cannot do */
|
||||
KEY_CACHE_VAR *key_cache; /* new key cache when changing key cache */
|
||||
void init();
|
||||
} HA_CHECK_OPT;
|
||||
|
||||
|
||||
class handler :public Sql_alloc
|
||||
{
|
||||
protected:
|
||||
|
@ -390,7 +394,7 @@ int ha_create_table(const char *name, HA_CREATE_INFO *create_info,
|
|||
bool update_create_info);
|
||||
int ha_delete_table(enum db_type db_type, const char *path);
|
||||
void ha_drop_database(char* path);
|
||||
int ha_key_cache(KEY_CACHE_VAR *key_cache);
|
||||
int ha_init_key_cache(const char *name, KEY_CACHE_VAR *key_cache);
|
||||
int ha_resize_key_cache(KEY_CACHE_VAR *key_cache);
|
||||
int ha_change_key_cache_param(KEY_CACHE_VAR *key_cache);
|
||||
int ha_end_key_cache(KEY_CACHE_VAR *key_cache);
|
||||
|
@ -407,3 +411,5 @@ int ha_autocommit_or_rollback(THD *thd, int error);
|
|||
void ha_set_spin_retries(uint retries);
|
||||
bool ha_flush_logs(void);
|
||||
int ha_recovery_logging(THD *thd, bool on);
|
||||
int ha_change_key_cache(KEY_CACHE_VAR *old_key_cache,
|
||||
KEY_CACHE_VAR *new_key_cache);
|
||||
|
|
|
@ -125,9 +125,10 @@ public:
|
|||
optimisation changes in prepared statements
|
||||
*/
|
||||
Item(THD *thd, Item &item);
|
||||
virtual ~Item() { name=0; } /*lint -e1509 */
|
||||
virtual ~Item() { name=0; cleanup(); } /*lint -e1509 */
|
||||
void set_name(const char *str,uint length, CHARSET_INFO *cs);
|
||||
void init_make_field(Send_field *tmp_field,enum enum_field_types type);
|
||||
virtual void cleanup() {}
|
||||
virtual void make_field(Send_field *field);
|
||||
virtual bool fix_fields(THD *, struct st_table_list *, Item **);
|
||||
virtual int save_in_field(Field *field, bool no_conversions);
|
||||
|
|
|
@ -715,7 +715,14 @@ class Item_func_in :public Item_int_func
|
|||
}
|
||||
longlong val_int();
|
||||
void fix_length_and_dec();
|
||||
~Item_func_in() { delete array; delete in_item; }
|
||||
~Item_func_in() {}
|
||||
void cleanup()
|
||||
{
|
||||
delete array;
|
||||
delete in_item;
|
||||
array= 0;
|
||||
in_item= 0;
|
||||
}
|
||||
optimize_type select_optimize() const
|
||||
{ return array ? OPTIMIZE_KEY : OPTIMIZE_NONE; }
|
||||
void print(String *str);
|
||||
|
|
|
@ -2648,6 +2648,8 @@ err:
|
|||
void Item_func_match::init_search(bool no_order)
|
||||
{
|
||||
DBUG_ENTER("Item_func_match::init_search");
|
||||
|
||||
/* Check if init_search() has been called before */
|
||||
if (ft_handler)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
|
@ -2685,7 +2687,8 @@ void Item_func_match::init_search(bool no_order)
|
|||
ft_tmp= &search_value;
|
||||
}
|
||||
|
||||
if (join_key && !no_order) flags|=FT_SORTED;
|
||||
if (join_key && !no_order)
|
||||
flags|=FT_SORTED;
|
||||
ft_handler=table->file->ft_init_ext(flags, key,
|
||||
(byte*) ft_tmp->ptr(),
|
||||
ft_tmp->length());
|
||||
|
|
|
@ -427,8 +427,6 @@ bool check_stack_overrun(THD *thd,char *dummy);
|
|||
void table_cache_init(void);
|
||||
void table_cache_free(void);
|
||||
uint cached_tables(void);
|
||||
void assign_cache_init(void);
|
||||
void assign_cache_free(void);
|
||||
void reassign_key_cache(KEY_CACHE_ASMT *key_cache_asmt,
|
||||
KEY_CACHE_VAR *new_key_cache);
|
||||
void kill_mysql(void);
|
||||
|
@ -460,10 +458,11 @@ int mysql_analyze_table(THD* thd, TABLE_LIST* table_list,
|
|||
HA_CHECK_OPT* check_opt);
|
||||
int mysql_optimize_table(THD* thd, TABLE_LIST* table_list,
|
||||
HA_CHECK_OPT* check_opt);
|
||||
int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list);
|
||||
int mysql_assign_to_keycache(THD* thd, TABLE_LIST* table_list,
|
||||
LEX_STRING *key_cache_name);
|
||||
int mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
|
||||
int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR* src_cache,
|
||||
char *dest_name, bool remove_fl);
|
||||
int reassign_keycache_tables(THD* thd, KEY_CACHE_VAR *src_cache,
|
||||
KEY_CACHE_VAR *dst_cache);
|
||||
|
||||
bool check_simple_select();
|
||||
|
||||
|
@ -662,7 +661,7 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
|||
extern const Item **not_found_item;
|
||||
Item ** find_item_in_list(Item *item, List<Item> &items, uint *counter,
|
||||
find_item_error_report_type report_error);
|
||||
void get_key_map_from_key_list(key_map *map, TABLE *table,
|
||||
bool get_key_map_from_key_list(key_map *map, TABLE *table,
|
||||
List<String> *index_list);
|
||||
bool insert_fields(THD *thd,TABLE_LIST *tables,
|
||||
const char *db_name, const char *table_name,
|
||||
|
@ -849,7 +848,7 @@ extern pthread_mutex_t LOCK_mysql_create_db,LOCK_Acl,LOCK_open,
|
|||
LOCK_error_log, LOCK_delayed_insert,
|
||||
LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
|
||||
LOCK_slave_list, LOCK_active_mi, LOCK_manager,
|
||||
LOCK_global_system_variables, LOCK_user_conn, LOCK_assign;
|
||||
LOCK_global_system_variables, LOCK_user_conn;
|
||||
extern rw_lock_t LOCK_grant;
|
||||
extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager;
|
||||
extern pthread_attr_t connection_attrib;
|
||||
|
@ -866,6 +865,8 @@ extern SHOW_COMP_OPTION have_berkeley_db;
|
|||
extern struct system_variables global_system_variables;
|
||||
extern struct system_variables max_system_variables;
|
||||
extern struct rand_struct sql_rand;
|
||||
extern KEY_CACHE_VAR *sql_key_cache;
|
||||
extern KEY_CACHE_HANDLE sql_key_cache_handle;
|
||||
|
||||
extern const char *opt_date_time_formats[];
|
||||
extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
|
||||
|
|
|
@ -355,6 +355,7 @@ struct system_variables max_system_variables;
|
|||
|
||||
MY_TMPDIR mysql_tmpdir_list;
|
||||
MY_BITMAP temp_pool;
|
||||
KEY_CACHE_VAR *sql_key_cache;
|
||||
|
||||
CHARSET_INFO *system_charset_info, *files_charset_info ;
|
||||
CHARSET_INFO *national_charset_info, *table_alias_charset;
|
||||
|
@ -373,7 +374,6 @@ pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
|
|||
LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
|
||||
LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
|
||||
LOCK_global_system_variables,
|
||||
LOCK_assign,
|
||||
LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
|
||||
rw_lock_t LOCK_grant;
|
||||
pthread_cond_t COND_refresh,COND_thread_count, COND_slave_stopped,
|
||||
|
@ -900,7 +900,6 @@ void clean_up(bool print_message)
|
|||
#endif
|
||||
query_cache_destroy();
|
||||
table_cache_free();
|
||||
assign_cache_free();
|
||||
hostname_cache_free();
|
||||
item_user_lock_free();
|
||||
lex_free(); /* Free some memory */
|
||||
|
@ -910,9 +909,8 @@ void clean_up(bool print_message)
|
|||
udf_free();
|
||||
#endif
|
||||
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
|
||||
process_key_caches(&ha_end_key_cache);
|
||||
ha_end_key_cache(&dflt_key_cache_var);
|
||||
delete_elements(&key_caches, free_key_cache);
|
||||
delete_elements(&key_caches, (void (*)(const char*, gptr)) free_key_cache);
|
||||
multi_keycache_free();
|
||||
end_thr_alarm(1); /* Free allocated memory */
|
||||
#ifdef USE_RAID
|
||||
end_raid();
|
||||
|
@ -997,7 +995,6 @@ static void clean_up_mutexes()
|
|||
#endif
|
||||
(void) pthread_mutex_destroy(&LOCK_active_mi);
|
||||
(void) pthread_mutex_destroy(&LOCK_global_system_variables);
|
||||
(void) pthread_mutex_destroy(&LOCK_assign);
|
||||
(void) pthread_cond_destroy(&COND_thread_count);
|
||||
(void) pthread_cond_destroy(&COND_refresh);
|
||||
(void) pthread_cond_destroy(&COND_thread_cache);
|
||||
|
@ -1568,14 +1565,14 @@ We will try our best to scrape up some info that will hopefully help diagnose\n\
|
|||
the problem, but since we have already crashed, something is definitely wrong\n\
|
||||
and this may fail.\n\n");
|
||||
fprintf(stderr, "key_buffer_size=%lu\n",
|
||||
(ulong) dflt_key_cache_var.buff_size);
|
||||
(ulong) sql_key_cache->buff_size);
|
||||
fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
|
||||
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
|
||||
fprintf(stderr, "max_connections=%ld\n", max_connections);
|
||||
fprintf(stderr, "threads_connected=%d\n", thread_count);
|
||||
fprintf(stderr, "It is possible that mysqld could use up to \n\
|
||||
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
|
||||
bytes of memory\n", ((ulong) dflt_key_cache_var.buff_size +
|
||||
bytes of memory\n", ((ulong) sql_key_cache->buff_size +
|
||||
(global_system_variables.read_buff_size +
|
||||
global_system_variables.sortbuff_size) *
|
||||
max_connections)/ 1024);
|
||||
|
@ -2204,7 +2201,6 @@ static int init_thread_environment()
|
|||
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_assign, MY_MUTEX_INIT_FAST);
|
||||
(void) my_rwlock_init(&LOCK_grant, NULL);
|
||||
(void) pthread_cond_init(&COND_thread_count,NULL);
|
||||
(void) pthread_cond_init(&COND_refresh,NULL);
|
||||
|
@ -2256,7 +2252,6 @@ static int init_server_components()
|
|||
{
|
||||
DBUG_ENTER("init_server_components");
|
||||
table_cache_init();
|
||||
assign_cache_init();
|
||||
hostname_cache_init();
|
||||
query_cache_result_size_limit(query_cache_limit);
|
||||
query_cache_set_min_res_unit(query_cache_min_res_unit);
|
||||
|
@ -2328,9 +2323,10 @@ Now disabling --log-slave-updates.");
|
|||
if (opt_myisam_log)
|
||||
(void) mi_log(1);
|
||||
|
||||
ha_key_cache(&dflt_key_cache_var);
|
||||
process_key_caches(&ha_key_cache);
|
||||
|
||||
/* call ha_init_key_cache() on all key caches to init them */
|
||||
process_key_caches(&ha_init_key_cache);
|
||||
/* We must set dflt_key_cache in case we are using ISAM tables */
|
||||
dflt_keycache= &sql_key_cache->cache;
|
||||
|
||||
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
|
||||
if (locked_in_memory && !geteuid())
|
||||
|
@ -4321,25 +4317,28 @@ replicating a LOAD DATA INFILE command.",
|
|||
{"key_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_key_cache_var.buff_size,
|
||||
(gptr*) &dflt_key_cache_var.buff_size, 0,
|
||||
(enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
|
||||
(gptr*) 0,
|
||||
0, (enum get_opt_var_type) (GET_ULL | GET_ASK_ADDR),
|
||||
REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD,
|
||||
IO_SIZE, 0},
|
||||
{"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
|
||||
"The default size of key cache blocks",
|
||||
(gptr*) &dflt_key_cache_var.block_size,
|
||||
(gptr*) &dflt_key_cache_var.block_size, 0, GET_ULONG,
|
||||
REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
|
||||
(gptr*) 0,
|
||||
0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
|
||||
KEY_CACHE_BLOCK_SIZE , 512, 1024*16, MALLOC_OVERHEAD, 512, 0},
|
||||
{"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
|
||||
"The minimum percentage of warm blocks in key cache",
|
||||
(gptr*) &dflt_key_cache_var.division_limit,
|
||||
(gptr*) &dflt_key_cache_var.division_limit, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
|
||||
(gptr*) 0,
|
||||
0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
|
||||
1, 100, 0, 1, 0},
|
||||
{"key_cache_division_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_key_cache_var.age_threshold,
|
||||
(gptr*) &dflt_key_cache_var.age_threshold, 0, GET_ULONG,
|
||||
REQUIRED_ARG, 300, 100, ~0L, 0, 100, 0},
|
||||
(gptr*) 0,
|
||||
0, (enum get_opt_var_type) (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG,
|
||||
300, 100, ~0L, 0, 100, 0},
|
||||
{"long_query_time", OPT_LONG_QUERY_TIME,
|
||||
"Log all queries that have taken more than long_query_time seconds to execute to file.",
|
||||
(gptr*) &global_system_variables.long_query_time,
|
||||
|
@ -4758,19 +4757,19 @@ struct show_var_st status_vars[]= {
|
|||
{"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG},
|
||||
{"Handler_update", (char*) &ha_update_count, SHOW_LONG},
|
||||
{"Handler_write", (char*) &ha_write_count, SHOW_LONG},
|
||||
{"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.blocks_changed,
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used,
|
||||
SHOW_LONG_CONST},
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Key_read_requests", (char*) &dflt_key_cache_var.cache_r_requests,
|
||||
SHOW_LONG},
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Key_reads", (char*) &dflt_key_cache_var.cache_read,
|
||||
SHOW_LONG},
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Key_write_requests", (char*) &dflt_key_cache_var.cache_w_requests,
|
||||
SHOW_LONG},
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Key_writes", (char*) &dflt_key_cache_var.cache_write,
|
||||
SHOW_LONG},
|
||||
SHOW_KEY_CACHE_LONG},
|
||||
{"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
|
||||
{"Not_flushed_key_blocks", (char*) &dflt_key_cache_var.blocks_changed,
|
||||
SHOW_LONG_CONST},
|
||||
{"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_CONST},
|
||||
{"Open_tables", (char*) 0, SHOW_OPENTABLES},
|
||||
{"Open_files", (char*) &my_file_opened, SHOW_LONG_CONST},
|
||||
|
@ -4984,8 +4983,9 @@ static void mysql_init_variables(void)
|
|||
threads.empty();
|
||||
thread_cache.empty();
|
||||
key_caches.empty();
|
||||
if (!get_or_create_key_cache(DEFAULT_KEY_CACHE_NAME,
|
||||
strlen(DEFAULT_KEY_CACHE_NAME)))
|
||||
multi_keycache_init();
|
||||
if (!(sql_key_cache= get_or_create_key_cache(default_key_cache_base.str,
|
||||
default_key_cache_base.length)))
|
||||
exit(1);
|
||||
|
||||
/* Initialize structures that is used when processing options */
|
||||
|
@ -5075,9 +5075,9 @@ static void mysql_init_variables(void)
|
|||
have_crypt=SHOW_OPTION_NO;
|
||||
#endif
|
||||
#ifdef HAVE_COMPRESS
|
||||
SHOW_COMP_OPTION have_compress= SHOW_OPTION_YES;
|
||||
have_compress= SHOW_OPTION_YES;
|
||||
#else
|
||||
SHOW_COMP_OPTION have_compress= SHOW_OPTION_NO;
|
||||
have_compress= SHOW_OPTION_NO;
|
||||
#endif
|
||||
#ifdef HAVE_LIBWRAP
|
||||
libwrapName= NullS;
|
||||
|
@ -5699,13 +5699,6 @@ static void get_options(int argc,char **argv)
|
|||
init_global_datetime_format(TIMESTAMP_DATETIME,
|
||||
&global_system_variables.datetime_format))
|
||||
exit(1);
|
||||
|
||||
/* Set up default values for a key cache */
|
||||
KEY_CACHE_VAR *key_cache= &dflt_key_cache_var;
|
||||
dflt_key_cache_block_size= key_cache->block_size;
|
||||
dflt_key_buff_size= key_cache->buff_size;
|
||||
dflt_key_cache_division_limit= key_cache->division_limit;
|
||||
dflt_key_cache_age_threshold= key_cache->age_threshold;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -120,6 +120,10 @@ void send_error(THD *thd, uint sql_errno, const char *err)
|
|||
#endif /* EMBEDDED_LIBRARY*/
|
||||
thd->is_fatal_error=0; // Error message is given
|
||||
thd->net.report_error= 0;
|
||||
|
||||
/* Abort multi-result sets */
|
||||
thd->lex.found_colon= 0;
|
||||
thd->server_status= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -338,7 +342,14 @@ send_eof(THD *thd, bool no_flush)
|
|||
uint tmp= min(thd->total_warn_count, 65535);
|
||||
buff[0]=254;
|
||||
int2store(buff+1, tmp);
|
||||
int2store(buff+3, 0); // No flags yet
|
||||
/*
|
||||
The following test should never be true, but it's better to do it
|
||||
because if 'is_fatal_error' is set the server is not going to execute
|
||||
other queries (see the if test in dispatch_command / COM_QUERY)
|
||||
*/
|
||||
if (thd->is_fatal_error)
|
||||
thd->server_status= ~SERVER_MORE_RESULTS_EXISTS;
|
||||
int2store(buff+3, thd->server_status);
|
||||
VOID(my_net_write(net,(char*) buff,5));
|
||||
VOID(net_flush(net));
|
||||
}
|
||||
|
|
261
sql/set_var.cc
261
sql/set_var.cc
|
@ -60,11 +60,6 @@
|
|||
#include "ha_innodb.h"
|
||||
#endif
|
||||
|
||||
ulonglong dflt_key_buff_size;
|
||||
uint dflt_key_cache_block_size;
|
||||
uint dflt_key_cache_division_limit;
|
||||
uint dflt_key_cache_age_threshold;
|
||||
|
||||
static HASH system_variable_hash;
|
||||
const char *bool_type_names[]= { "OFF", "ON", NullS };
|
||||
TYPELIB bool_typelib=
|
||||
|
@ -148,11 +143,15 @@ sys_var_thd_ulong sys_interactive_timeout("interactive_timeout",
|
|||
sys_var_thd_ulong sys_join_buffer_size("join_buffer_size",
|
||||
&SV::join_buff_size);
|
||||
sys_var_key_buffer_size sys_key_buffer_size("key_buffer_size");
|
||||
sys_var_key_cache_block_size sys_key_cache_block_size("key_cache_block_size");
|
||||
sys_var_key_cache_division_limit
|
||||
sys_key_cache_division_limit("key_cache_division_limit");
|
||||
sys_var_key_cache_age_threshold
|
||||
sys_key_cache_age_threshold("key_cache_age_threshold");
|
||||
sys_var_key_cache_long sys_key_cache_block_size("key_cache_block_size",
|
||||
offsetof(KEY_CACHE_VAR,
|
||||
block_size));
|
||||
sys_var_key_cache_long sys_key_cache_division_limit("key_cache_division_limit",
|
||||
offsetof(KEY_CACHE_VAR,
|
||||
division_limit));
|
||||
sys_var_key_cache_long sys_key_cache_age_threshold("key_cache_age_threshold",
|
||||
offsetof(KEY_CACHE_VAR,
|
||||
age_threshold));
|
||||
sys_var_bool_ptr sys_local_infile("local_infile",
|
||||
&opt_local_infile);
|
||||
sys_var_thd_bool sys_log_warnings("log_warnings", &SV::log_warnings);
|
||||
|
@ -1266,7 +1265,13 @@ Item *sys_var::item(THD *thd, enum_var_type var_type, LEX_STRING *base)
|
|||
}
|
||||
switch (type()) {
|
||||
case SHOW_LONG:
|
||||
return new Item_uint((int32) *(ulong*) value_ptr(thd, var_type, base));
|
||||
{
|
||||
ulong value;
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
value= *(ulong*) value_ptr(thd, var_type, base);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return new Item_uint((int32) value);
|
||||
}
|
||||
case SHOW_LONGLONG:
|
||||
{
|
||||
longlong value;
|
||||
|
@ -1771,24 +1776,21 @@ void sys_var_collation_server::set_default(THD *thd, enum_var_type type)
|
|||
}
|
||||
|
||||
|
||||
static LEX_STRING default_key_cache_base= {(char *) DEFAULT_KEY_CACHE_NAME, 7};
|
||||
LEX_STRING default_key_cache_base= {(char *) "default", 7 };
|
||||
|
||||
static KEY_CACHE_VAR zero_key_cache=
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
static KEY_CACHE_VAR *get_key_cache(LEX_STRING *cache_name)
|
||||
KEY_CACHE_VAR *get_key_cache(LEX_STRING *cache_name)
|
||||
{
|
||||
if (!cache_name || !cache_name->str || !cache_name->length ||
|
||||
cache_name->str == default_key_cache_base.str ||
|
||||
(cache_name->length == default_key_cache_base.length &&
|
||||
!memcmp(cache_name->str, default_key_cache_base.str,
|
||||
default_key_cache_base.length)))
|
||||
safe_mutex_assert_owner(&LOCK_global_system_variables);
|
||||
if (!cache_name || ! cache_name->length)
|
||||
cache_name= &default_key_cache_base;
|
||||
return ((KEY_CACHE_VAR*) find_named(&key_caches,
|
||||
cache_name->str, cache_name->length,
|
||||
0));
|
||||
cache_name->str, cache_name->length, 0));
|
||||
}
|
||||
|
||||
|
||||
byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
|
||||
LEX_STRING *base)
|
||||
{
|
||||
|
@ -1798,115 +1800,134 @@ byte *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
|
|||
return (byte*) key_cache + offset ;
|
||||
}
|
||||
|
||||
|
||||
bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
|
||||
{
|
||||
ulonglong tmp= var->save_result.ulonglong_value;
|
||||
|
||||
LEX_STRING *base_name= &var->base;
|
||||
KEY_CACHE_VAR *key_cache;
|
||||
bool error= 0;
|
||||
|
||||
/* If no basename, assume it's for the key cache named 'default' */
|
||||
if (!base_name->length)
|
||||
base_name= &default_key_cache_base;
|
||||
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
key_cache= get_key_cache(base_name);
|
||||
|
||||
if (!key_cache)
|
||||
{
|
||||
/* Key cache didn't exists */
|
||||
if (!tmp) // Tried to delete cache
|
||||
return 0; // Ok, nothing to do
|
||||
if (!(key_cache= create_key_cache(base_name->str,
|
||||
base_name->length)))
|
||||
return 1;
|
||||
goto end; // Ok, nothing to do
|
||||
if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
|
||||
{
|
||||
error= 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Abort if some other thread is changing the key cache
|
||||
TODO: This should be changed so that we wait until the previous
|
||||
assignment is done and then do the new assign
|
||||
*/
|
||||
if (key_cache->in_init)
|
||||
goto end;
|
||||
|
||||
if (!tmp) // Zero size means delete
|
||||
{
|
||||
if (!key_cache->cache)
|
||||
return 0;
|
||||
/* Delete not default key caches */
|
||||
if (key_cache != &dflt_key_cache_var)
|
||||
if (key_cache == sql_key_cache)
|
||||
goto end; // Ignore default key cache
|
||||
|
||||
if (key_cache->cache) // If initied
|
||||
{
|
||||
/*
|
||||
Move tables using this key cache to the default key cache
|
||||
and remove this key cache if no tables are assigned to it
|
||||
Move tables using this key cache to the default key cache
|
||||
and clear the old key cache.
|
||||
*/
|
||||
NAMED_LIST *list;
|
||||
key_cache= (KEY_CACHE_VAR *) find_named(&key_caches, base_name->str,
|
||||
base_name->length, &list);
|
||||
delete list;
|
||||
int rc= reassign_keycache_tables(thd, key_cache,
|
||||
default_key_cache_base.str, 1);
|
||||
my_free((char*) key_cache, MYF(0));
|
||||
return rc;
|
||||
|
||||
key_cache->in_init= 1;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
error= reassign_keycache_tables(thd, key_cache, sql_key_cache);
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
key_cache->in_init= 0;
|
||||
}
|
||||
return 0;
|
||||
/*
|
||||
We don't delete the key cache as some running threads my still be
|
||||
in the key cache code with a pointer to the deleted (empty) key cache
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
key_cache->buff_size= (ulonglong) getopt_ull_limit_value(tmp, option_limits);
|
||||
|
||||
/* If key cache didn't existed initialize it, else resize it */
|
||||
key_cache->in_init= 1;
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
|
||||
if (!key_cache->cache)
|
||||
return (bool)(ha_key_cache(key_cache));
|
||||
error= (bool) (ha_init_key_cache("", key_cache));
|
||||
else
|
||||
return (bool)(ha_resize_key_cache(key_cache));
|
||||
error= (bool)(ha_resize_key_cache(key_cache));
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
key_cache->in_init= 0;
|
||||
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return error;
|
||||
}
|
||||
|
||||
bool sys_var_key_cache_block_size::update(THD *thd, set_var *var)
|
||||
|
||||
bool sys_var_key_cache_long::update(THD *thd, set_var *var)
|
||||
{
|
||||
ulong tmp= var->value->val_int();
|
||||
LEX_STRING *base_name= &var->base;
|
||||
bool error= 0;
|
||||
|
||||
if (!base_name->length)
|
||||
base_name= &default_key_cache_base;
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||
|
||||
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||
base_name->length)))
|
||||
return 1;
|
||||
{
|
||||
error= 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
key_cache->block_size= (ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||
/*
|
||||
Abort if some other thread is changing the key cache
|
||||
TODO: This should be changed so that we wait until the previous
|
||||
assignment is done and then do the new assign
|
||||
*/
|
||||
if (key_cache->in_init)
|
||||
goto end;
|
||||
|
||||
if (key_cache->cache)
|
||||
/* Do not build a new key cache here */
|
||||
return (bool) (ha_resize_key_cache(key_cache));
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool sys_var_key_cache_division_limit::update(THD *thd, set_var *var)
|
||||
{
|
||||
ulong tmp= var->value->val_int();
|
||||
LEX_STRING *base_name= &var->base;
|
||||
if (!base_name->length)
|
||||
base_name= &default_key_cache_base;
|
||||
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||
|
||||
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||
base_name->length)))
|
||||
return 1;
|
||||
|
||||
key_cache->division_limit=
|
||||
*((ulong*) (((char*) key_cache) + offset))=
|
||||
(ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||
|
||||
if (key_cache->cache)
|
||||
/* Do not build a new key cache here */
|
||||
return (bool) (ha_change_key_cache_param(key_cache));
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
Don't create a new key cache if it didn't exist
|
||||
(key_caches are created only when the user sets block_size)
|
||||
*/
|
||||
key_cache->in_init= 1;
|
||||
|
||||
bool sys_var_key_cache_age_threshold::update(THD *thd, set_var *var)
|
||||
{
|
||||
ulong tmp= var->value->val_int();
|
||||
LEX_STRING *base_name= &var->base;
|
||||
if (!base_name->length)
|
||||
base_name= &default_key_cache_base;
|
||||
KEY_CACHE_VAR *key_cache= get_key_cache(base_name);
|
||||
|
||||
if (!key_cache && !(key_cache= create_key_cache(base_name->str,
|
||||
base_name->length)))
|
||||
return 1;
|
||||
|
||||
key_cache->division_limit=
|
||||
(ulong) getopt_ull_limit_value(tmp, option_limits);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
|
||||
if (key_cache->cache)
|
||||
/* Do not build a new key cache here */
|
||||
return (bool) (ha_change_key_cache_param(key_cache));
|
||||
return 0;
|
||||
error= (bool) (ha_resize_key_cache(key_cache));
|
||||
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
key_cache->in_init= 0;
|
||||
|
||||
end:
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2506,13 +2527,14 @@ gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
|
|||
}
|
||||
|
||||
|
||||
void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr))
|
||||
void delete_elements(I_List<NAMED_LIST> *list,
|
||||
void (*free_element)(const char *name, gptr))
|
||||
{
|
||||
NAMED_LIST *element;
|
||||
DBUG_ENTER("delete_elements");
|
||||
while ((element= list->get()))
|
||||
{
|
||||
(*free_element)(element->data);
|
||||
(*free_element)(element->name, element->data);
|
||||
delete element;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
|
@ -2524,60 +2546,65 @@ void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr))
|
|||
static KEY_CACHE_VAR *create_key_cache(const char *name, uint length)
|
||||
{
|
||||
KEY_CACHE_VAR *key_cache;
|
||||
DBUG_PRINT("info",("Creating key cache: %.*s length: %d", length, name,
|
||||
length));
|
||||
if (length != default_key_cache_base.length ||
|
||||
memcmp(name, default_key_cache_base.str, length))
|
||||
DBUG_ENTER("create_key_cache");
|
||||
DBUG_PRINT("enter",("name: %.*s", length, name));
|
||||
|
||||
if ((key_cache= (KEY_CACHE_VAR*) my_malloc(sizeof(KEY_CACHE_VAR),
|
||||
MYF(MY_ZEROFILL | MY_WME))))
|
||||
{
|
||||
if ((key_cache= (KEY_CACHE_VAR*) my_malloc(sizeof(KEY_CACHE_VAR),
|
||||
MYF(MY_ZEROFILL | MY_WME))))
|
||||
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
||||
{
|
||||
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
||||
{
|
||||
my_free((char*) key_cache, MYF(0));
|
||||
key_cache= 0;
|
||||
}
|
||||
my_free((char*) key_cache, MYF(0));
|
||||
key_cache= 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Set default values for a key cache
|
||||
The values in dflt_key_cache_var is set by my_getopt() at startup
|
||||
|
||||
We don't set 'buff_size' as this is used to enable the key cache
|
||||
*/
|
||||
key_cache->block_size= dflt_key_cache_var.block_size;
|
||||
key_cache->division_limit= dflt_key_cache_var.division_limit;
|
||||
key_cache->age_threshold= dflt_key_cache_var.age_threshold;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
key_cache= &dflt_key_cache_var;
|
||||
if (!new NAMED_LIST(&key_caches, name, length, (gptr) key_cache))
|
||||
key_cache= 0;
|
||||
}
|
||||
|
||||
return key_cache;
|
||||
DBUG_RETURN(key_cache);
|
||||
}
|
||||
|
||||
|
||||
KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length)
|
||||
{
|
||||
LEX_STRING key_cache_name;
|
||||
KEY_CACHE_VAR *key_cache;
|
||||
|
||||
key_cache_name.str= (char *) name;
|
||||
key_cache_name.length= length;
|
||||
KEY_CACHE_VAR *key_cache= get_key_cache(&key_cache_name);
|
||||
if (!key_cache)
|
||||
pthread_mutex_lock(&LOCK_global_system_variables);
|
||||
if (!(key_cache= get_key_cache(&key_cache_name)))
|
||||
key_cache= create_key_cache(name, length);
|
||||
pthread_mutex_unlock(&LOCK_global_system_variables);
|
||||
return key_cache;
|
||||
}
|
||||
|
||||
|
||||
void free_key_cache(gptr key_cache)
|
||||
void free_key_cache(const char *name, KEY_CACHE_VAR *key_cache)
|
||||
{
|
||||
if (key_cache != (gptr) &dflt_key_cache_var)
|
||||
my_free(key_cache, MYF(0));
|
||||
ha_end_key_cache(key_cache);
|
||||
my_free((char*) key_cache, MYF(0));
|
||||
}
|
||||
|
||||
bool process_key_caches(int (* func) (KEY_CACHE_VAR *))
|
||||
{
|
||||
|
||||
bool process_key_caches(int (* func) (const char *name, KEY_CACHE_VAR *))
|
||||
{
|
||||
I_List_iterator<NAMED_LIST> it(key_caches);
|
||||
NAMED_LIST *element;
|
||||
|
||||
while ((element= it++))
|
||||
{
|
||||
KEY_CACHE_VAR *key_cache= (KEY_CACHE_VAR *) element->data;
|
||||
if (key_cache != &dflt_key_cache_var)
|
||||
func(key_cache);
|
||||
func(element->name, key_cache);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,11 +30,6 @@ class set_var;
|
|||
typedef struct system_variables SV;
|
||||
extern TYPELIB bool_typelib, delay_key_write_typelib, sql_mode_typelib;
|
||||
|
||||
extern ulonglong dflt_key_buff_size;
|
||||
extern uint dflt_key_cache_block_size;
|
||||
extern uint dflt_key_cache_division_limit;
|
||||
extern uint dflt_key_cache_age_threshold;
|
||||
|
||||
enum enum_var_type
|
||||
{
|
||||
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
|
||||
|
@ -546,73 +541,40 @@ public:
|
|||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||
};
|
||||
|
||||
|
||||
class sys_var_key_cache_param :public sys_var
|
||||
{
|
||||
protected:
|
||||
uint offset;
|
||||
size_t offset;
|
||||
public:
|
||||
sys_var_key_cache_param(const char *name_arg)
|
||||
:sys_var(name_arg)
|
||||
{
|
||||
offset= 0;
|
||||
}
|
||||
sys_var_key_cache_param(const char *name_arg, size_t offset_arg)
|
||||
:sys_var(name_arg), offset(offset_arg)
|
||||
{}
|
||||
byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
|
||||
bool check_default(enum_var_type type) { return 1; }
|
||||
bool is_struct() { return 1; }
|
||||
};
|
||||
|
||||
|
||||
class sys_var_key_buffer_size :public sys_var_key_cache_param
|
||||
{
|
||||
public:
|
||||
sys_var_key_buffer_size(const char *name_arg)
|
||||
:sys_var_key_cache_param(name_arg)
|
||||
{
|
||||
offset= offsetof(KEY_CACHE_VAR, buff_size);
|
||||
}
|
||||
:sys_var_key_cache_param(name_arg, offsetof(KEY_CACHE_VAR, buff_size))
|
||||
{}
|
||||
bool update(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_LONGLONG; }
|
||||
bool check_default(enum_var_type type) { return 1; }
|
||||
bool is_struct() { return 1; }
|
||||
};
|
||||
|
||||
class sys_var_key_cache_block_size :public sys_var_key_cache_param
|
||||
{
|
||||
public:
|
||||
sys_var_key_cache_block_size(const char *name_arg)
|
||||
:sys_var_key_cache_param(name_arg)
|
||||
{
|
||||
offset= offsetof(KEY_CACHE_VAR, block_size);
|
||||
}
|
||||
bool update(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_LONG; }
|
||||
bool check_default(enum_var_type type) { return 1; }
|
||||
bool is_struct() { return 1; }
|
||||
};
|
||||
|
||||
class sys_var_key_cache_division_limit :public sys_var_key_cache_param
|
||||
class sys_var_key_cache_long :public sys_var_key_cache_param
|
||||
{
|
||||
public:
|
||||
sys_var_key_cache_division_limit(const char *name_arg)
|
||||
:sys_var_key_cache_param(name_arg)
|
||||
{
|
||||
offset= offsetof(KEY_CACHE_VAR, division_limit);
|
||||
}
|
||||
sys_var_key_cache_long(const char *name_arg, size_t offset_arg)
|
||||
:sys_var_key_cache_param(name_arg, offset_arg)
|
||||
{}
|
||||
bool update(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_LONG; }
|
||||
bool check_default(enum_var_type type) { return 1; }
|
||||
bool is_struct() { return 1; }
|
||||
};
|
||||
|
||||
class sys_var_key_cache_age_threshold :public sys_var_key_cache_param
|
||||
{
|
||||
public:
|
||||
sys_var_key_cache_age_threshold(const char *name_arg)
|
||||
:sys_var_key_cache_param(name_arg)
|
||||
{
|
||||
offset= offsetof(KEY_CACHE_VAR, age_threshold);
|
||||
}
|
||||
bool update(THD *thd, set_var *var);
|
||||
SHOW_TYPE type() { return SHOW_LONG; }
|
||||
bool check_default(enum_var_type type) { return 1; }
|
||||
bool is_struct() { return 1; }
|
||||
};
|
||||
|
||||
|
||||
|
@ -781,7 +743,7 @@ public:
|
|||
uint name_length_arg, gptr data_arg)
|
||||
:name_length(name_length_arg), data(data_arg)
|
||||
{
|
||||
name= my_memdup((byte*) name_arg, name_length, MYF(MY_WME));
|
||||
name= my_strdup_with_length((byte*) name_arg, name_length, MYF(MY_WME));
|
||||
links->push_back(this);
|
||||
}
|
||||
inline bool cmp(const char *name_cmp, uint length)
|
||||
|
@ -792,11 +754,16 @@ public:
|
|||
{
|
||||
my_free((char*) name, MYF(0));
|
||||
}
|
||||
friend bool process_key_caches(int (* func) (const char *name,
|
||||
KEY_CACHE_VAR *));
|
||||
friend void delete_elements(I_List<NAMED_LIST> *list,
|
||||
void (*free_element)(const char*, gptr));
|
||||
};
|
||||
|
||||
/* updated in sql_acl.cc */
|
||||
|
||||
extern sys_var_thd_bool sys_old_passwords;
|
||||
extern LEX_STRING default_key_cache_base;
|
||||
|
||||
/* For sql_yacc */
|
||||
struct sys_var_with_base
|
||||
|
@ -819,9 +786,8 @@ extern sys_var_str sys_charset_system;
|
|||
CHARSET_INFO *get_old_charset_by_name(const char *old_name);
|
||||
gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
|
||||
NAMED_LIST **found);
|
||||
void delete_elements(I_List<NAMED_LIST> *list, void (*free_element)(gptr));
|
||||
|
||||
/* key_cache functions */
|
||||
KEY_CACHE_VAR *get_key_cache(LEX_STRING *cache_name);
|
||||
KEY_CACHE_VAR *get_or_create_key_cache(const char *name, uint length);
|
||||
void free_key_cache(gptr key_cache);
|
||||
bool process_key_caches(int (* func) (KEY_CACHE_VAR *));
|
||||
void free_key_cache(const char *name, KEY_CACHE_VAR *key_cache);
|
||||
|
|
|
@ -298,3 +298,4 @@ character-set=latin2
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -292,3 +292,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -300,3 +300,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -289,3 +289,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -294,3 +294,4 @@ character-set=latin7
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -289,3 +289,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -301,3 +301,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -289,3 +289,4 @@ character-set=greek
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -291,3 +291,4 @@ character-set=latin2
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -289,3 +289,4 @@ character-set=latin1
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -291,3 +291,4 @@ character-set=ujis
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
|
@ -289,3 +289,4 @@ character-set=euckr
|
|||
"Incorrect catalog name '%-.100s'",
|
||||
"Query cache failed to set size %lu, new query cache size is %lu",
|
||||
"Column '%-.64s' cannot be part of FULLTEXT index",
|
||||
"Unknown key cache '%-.100s'",
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue