Commit 461d1627 authored by monty@mashka.mysql.fi's avatar monty@mashka.mysql.fi

merge with 4.0 for more memory allocation variables.

parents c60a75e9 c95d142f
...@@ -1821,7 +1821,7 @@ AC_CHECK_FUNCS(alarm bmove \ ...@@ -1821,7 +1821,7 @@ AC_CHECK_FUNCS(alarm bmove \
cuserid fcntl fconvert poll \ cuserid fcntl fconvert poll \
getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \ getrusage getpwuid getcwd getrlimit getwd index stpcpy locking longjmp \
perror pread realpath readlink rename \ perror pread realpath readlink rename \
socket strnlen madvise mkstemp \ socket strnlen madvise mallinfo mkstemp \
strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \ strtol strtoul strtoll strtoull snprintf tempnam thr_setconcurrency \
gethostbyaddr_r gethostbyname_r getpwnam \ gethostbyaddr_r gethostbyname_r getpwnam \
bfill bzero bcmp strstr strpbrk strerror \ bfill bzero bcmp strstr strpbrk strerror \
......
...@@ -163,6 +163,38 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000; ...@@ -163,6 +163,38 @@ set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5); select ROUND(RAND(),5);
ROUND(RAND(),5) ROUND(RAND(),5)
0.02887 0.02887
show variables like '%alloc%';
Variable_name Value
query_alloc_block_size 8192
query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
set @@range_alloc_block_size=1024*16;
set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18;
set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size;
@@query_alloc_block_size
17408
show variables like '%alloc%';
Variable_name Value
query_alloc_block_size 17408
query_prealloc_size 18432
range_alloc_block_size 16384
transaction_alloc_block_size 19456
transaction_prealloc_size 20480
set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%';
Variable_name Value
query_alloc_block_size 8192
query_prealloc_size 8192
range_alloc_block_size 2048
transaction_alloc_block_size 8192
transaction_prealloc_size 4096
set big_tables=OFFF; set big_tables=OFFF;
ERROR 42000: Variable 'big_tables' can't be set to the value of 'OFFF' ERROR 42000: Variable 'big_tables' can't be set to the value of 'OFFF'
set big_tables="OFFF"; set big_tables="OFFF";
......
...@@ -98,6 +98,18 @@ select @@timestamp>0; ...@@ -98,6 +98,18 @@ select @@timestamp>0;
set @@rand_seed1=10000000,@@rand_seed2=1000000; set @@rand_seed1=10000000,@@rand_seed2=1000000;
select ROUND(RAND(),5); select ROUND(RAND(),5);
show variables like '%alloc%';
set @@range_alloc_block_size=1024*16;
set @@query_alloc_block_size=1024*17+2;
set @@query_prealloc_size=1024*18;
set @@transaction_alloc_block_size=1024*20-1;
set @@transaction_prealloc_size=1024*21-1;
select @@query_alloc_block_size;
show variables like '%alloc%';
set @@range_alloc_block_size=default;
set @@query_alloc_block_size=default, @@query_prealloc_size=default;
set transaction_alloc_block_size=default, @@transaction_prealloc_size=default;
show variables like '%alloc%';
# The following should give errors # The following should give errors
......
...@@ -37,6 +37,7 @@ bin_SCRIPTS = @server_scripts@ \ ...@@ -37,6 +37,7 @@ bin_SCRIPTS = @server_scripts@ \
mysql_create_system_tables mysql_create_system_tables
EXTRA_SCRIPTS = make_binary_distribution.sh \ EXTRA_SCRIPTS = make_binary_distribution.sh \
make_sharedlib_distribution.sh \
make_win_src_distribution.sh \ make_win_src_distribution.sh \
msql2mysql.sh \ msql2mysql.sh \
mysql_config.sh \ mysql_config.sh \
...@@ -69,6 +70,7 @@ dist_pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql ...@@ -69,6 +70,7 @@ dist_pkgdata_DATA = fill_help_tables.sql mysql_fix_privilege_tables.sql
# failures with it. # failures with it.
CLEANFILES = @server_scripts@ \ CLEANFILES = @server_scripts@ \
make_binary_distribution \ make_binary_distribution \
make_sharedlib_distribution \
msql2mysql \ msql2mysql \
mysql_config \ mysql_config \
mysql_fix_privilege_tables \ mysql_fix_privilege_tables \
...@@ -141,7 +143,7 @@ SUFFIXES = .sh ...@@ -141,7 +143,7 @@ SUFFIXES = .sh
# Don't update the files from bitkeeper # Don't update the files from bitkeeper
%::SCCS/s.% %::SCCS/s.%
all: fill_help_tables.sql make_win_src_distribution make_binary_distribution all: fill_help_tables.sql make_win_src_distribution make_binary_distribution make_sharedlib_distribution
fill_help_tables.sql: fill_help_tables ../Docs/manual.texi fill_help_tables.sql: fill_help_tables ../Docs/manual.texi
./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql ./fill_help_tables < ../Docs/manual.texi > fill_help_tables.sql
#!/bin/sh
# The default path should be /usr/local
# Get some info from configure
# chmod +x ./scripts/setsomevars
machine=@MACHINE_TYPE@
system=@SYSTEM_TYPE@
version=@VERSION@
export machine system version
SOURCE=`pwd`
CP="cp -p"
MV="mv"
STRIP=1
DEBUG=0
SILENT=0
TMP=/tmp
SUFFIX=""
parse_arguments() {
for arg do
case "$arg" in
--debug) DEBUG=1;;
--tmp=*) TMP=`echo "$arg" | sed -e "s;--tmp=;;"` ;;
--suffix=*) SUFFIX=`echo "$arg" | sed -e "s;--suffix=;;"` ;;
--no-strip) STRIP=0 ;;
--silent) SILENT=1 ;;
*)
echo "Unknown argument '$arg'"
exit 1
;;
esac
done
}
parse_arguments "$@"
BASE=$TMP/my_dist$SUFFIX
if [ -d $BASE ] ; then
rm -r -f $BASE
fi
mkdir -p $BASE/lib
for i in \
libmysql/.libs/libmysqlclient.so* \
libmysql_r/.libs/libmysqlclient_r.so*
do
if [ -f $i ]
then
$CP $i $BASE/lib
fi
done
# Change the distribution to a long descriptive name
NEW_NAME=mysql-shared-$version-$system-$machine$SUFFIX
BASE2=$TMP/$NEW_NAME
rm -r -f $BASE2
mv $BASE $BASE2
BASE=$BASE2
#if we are debugging, do not do tar/gz
if [ x$DEBUG = x1 ] ; then
exit
fi
# This is needed to prefer GNU tar instead of tar because tar can't
# always handle long filenames
PATH_DIRS=`echo $PATH | sed -e 's/^:/. /' -e 's/:$/ ./' -e 's/::/ . /g' -e 's/:/ /g' `
which_1 ()
{
for cmd
do
for d in $PATH_DIRS
do
for file in $d/$cmd
do
if test -x $file -a ! -d $file
then
echo $file
exit 0
fi
done
done
done
exit 1
}
#
# Create the result tar file
#
tar=`which_1 gnutar gtar`
if test "$?" = "1" -o "$tar" = ""
then
tar=tar
fi
echo "Using $tar to create archive"
cd $TMP
OPT=cvf
if [ x$SILENT = x1 ] ; then
OPT=cf
fi
$tar $OPT $SOURCE/$NEW_NAME.tar $NEW_NAME
cd $SOURCE
echo "Compressing archive"
gzip -9 $NEW_NAME.tar
echo "Removing temporary directory"
rm -r -f $BASE
echo "$NEW_NAME.tar.gz created"
...@@ -238,7 +238,7 @@ int berkeley_show_logs(Protocol *protocol) ...@@ -238,7 +238,7 @@ int berkeley_show_logs(Protocol *protocol)
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
DBUG_ENTER("berkeley_show_logs"); DBUG_ENTER("berkeley_show_logs");
init_alloc_root(&show_logs_root, 1024, 1024); init_sql_alloc(&show_logs_root, 1024, 1024);
my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root); my_pthread_setspecific_ptr(THR_MALLOC,&show_logs_root);
if ((error= db_env->log_archive(db_env, &all_logs, if ((error= db_env->log_archive(db_env, &all_logs,
......
...@@ -85,6 +85,16 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset; ...@@ -85,6 +85,16 @@ extern CHARSET_INFO *national_charset_info, *table_alias_charset;
#define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int. #define MYSQLD_NET_RETRY_COUNT 10 // Abort read after this many int.
#endif #endif
#define TEMP_POOL_SIZE 128 #define TEMP_POOL_SIZE 128
#define QUERY_ALLOC_BLOCK_SIZE 8192
#define QUERY_ALLOC_PREALLOC_SIZE 8192
#define TRANS_ALLOC_BLOCK_SIZE 4096
#define TRANS_ALLOC_PREALLOC_SIZE 4096
#define RANGE_ALLOC_BLOCK_SIZE 2048
#define ACL_ALLOC_BLOCK_SIZE 1024
#define UDF_ALLOC_BLOCK_SIZE 1024
#define TABLE_ALLOC_BLOCK_SIZE 1024
/* /*
The following parameters is to decide when to use an extra cache to The following parameters is to decide when to use an extra cache to
optimise seeks when reading a big table in sorted order optimise seeks when reading a big table in sorted order
......
...@@ -3567,6 +3567,10 @@ enum options ...@@ -3567,6 +3567,10 @@ enum options
OPT_BDB_LOG_BUFFER_SIZE, OPT_BDB_LOG_BUFFER_SIZE,
OPT_BDB_MAX_LOCK, OPT_BDB_MAX_LOCK,
OPT_ERROR_LOG_FILE, OPT_ERROR_LOG_FILE,
OPT_DEFAULT_WEEK_FORMAT,
OPT_RANGE_ALLOC_BLOCK_SIZE,
OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
OPT_ENABLE_SHARED_MEMORY, OPT_ENABLE_SHARED_MEMORY,
OPT_SHARED_MEMORY_BASE_NAME, OPT_SHARED_MEMORY_BASE_NAME,
OPT_OLD_PASSWORDS, OPT_OLD_PASSWORDS,
...@@ -4392,6 +4396,11 @@ The minimum value for this variable is 4096.", ...@@ -4392,6 +4396,11 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.preload_buff_size, (gptr*) &global_system_variables.preload_buff_size,
(gptr*) &max_system_variables.preload_buff_size, 0, GET_ULONG, (gptr*) &max_system_variables.preload_buff_size, 0, GET_ULONG,
REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0}, REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
{"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
"Allocation block size for query parsing and execution",
(gptr*) &global_system_variables.query_alloc_block_size,
(gptr*) &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
{"query_cache_limit", OPT_QUERY_CACHE_LIMIT, {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
"Don't cache results that are bigger than this.", "Don't cache results that are bigger than this.",
...@@ -4413,6 +4422,11 @@ The minimum value for this variable is 4096.", ...@@ -4413,6 +4422,11 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.query_cache_type, (gptr*) &global_system_variables.query_cache_type,
(gptr*) &max_system_variables.query_cache_type, (gptr*) &max_system_variables.query_cache_type,
0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0}, 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
{"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
"Persistent buffer for query parsing and execution",
(gptr*) &global_system_variables.query_prealloc_size,
(gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG,
REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
#endif /*HAVE_QUERY_CACHE*/ #endif /*HAVE_QUERY_CACHE*/
{"read_buffer_size", OPT_RECORD_BUFFER, {"read_buffer_size", OPT_RECORD_BUFFER,
"Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.", "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.",
...@@ -4451,6 +4465,11 @@ The minimum value for this variable is 4096.", ...@@ -4451,6 +4465,11 @@ The minimum value for this variable is 4096.",
(gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0,
GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
#endif /* HAVE_REPLICATION */ #endif /* HAVE_REPLICATION */
{"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
"Allocation block size for storing ranges during optimization",
(gptr*) &global_system_variables.range_alloc_block_size,
(gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
{"read-only", OPT_READONLY, {"read-only", OPT_READONLY,
"Make all tables readonly, with the expections for replications (slave) threads and users with the SUPER privilege.", "Make all tables readonly, with the expections for replications (slave) threads and users with the SUPER privilege.",
(gptr*) &opt_readonly, (gptr*) &opt_readonly,
...@@ -4487,6 +4506,16 @@ The minimum value for this variable is 4096.", ...@@ -4487,6 +4506,16 @@ The minimum value for this variable is 4096.",
"The stack size for each thread.", (gptr*) &thread_stack, "The stack size for each thread.", (gptr*) &thread_stack,
(gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
1024*32, ~0L, 0, 1024, 0}, 1024*32, ~0L, 0, 1024, 0},
{"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
"Allocation block size for transactions to be stored in binary log",
(gptr*) &global_system_variables.trans_alloc_block_size,
(gptr*) &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0},
{"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
"Persistent buffer for transactions to be stored in binary log",
(gptr*) &global_system_variables.trans_prealloc_size,
(gptr*) &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0},
{"wait_timeout", OPT_WAIT_TIMEOUT, {"wait_timeout", OPT_WAIT_TIMEOUT,
"The number of seconds the server waits for activity on a connection before closing it.", "The number of seconds the server waits for activity on a connection before closing it.",
(gptr*) &global_system_variables.net_wait_timeout, (gptr*) &global_system_variables.net_wait_timeout,
......
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
** Create a FT or QUICK RANGE based on a key ** Create a FT or QUICK RANGE based on a key
****************************************************************************/ ****************************************************************************/
QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab) QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table,
JOIN_TAB *tab)
{ {
if (tab->type == JT_FT) if (tab->type == JT_FT)
return new FT_SELECT(table, &tab->ref); return new FT_SELECT(thd, table, &tab->ref);
else return get_quick_select_for_ref(thd, table, &tab->ref);
return get_quick_select_for_ref(table, &tab->ref);
} }
...@@ -28,13 +28,14 @@ class FT_SELECT: public QUICK_SELECT { ...@@ -28,13 +28,14 @@ class FT_SELECT: public QUICK_SELECT {
public: public:
TABLE_REF *ref; TABLE_REF *ref;
FT_SELECT(TABLE *table, TABLE_REF *tref) : FT_SELECT(THD *thd, TABLE *table, TABLE_REF *tref) :
QUICK_SELECT (table,tref->key,1), ref(tref) { init(); } QUICK_SELECT (thd, table, tref->key, 1), ref(tref) { init(); }
int init() { return error=file->ft_init(); } int init() { return error=file->ft_init(); }
int get_next() { return error=file->ft_read(record); } int get_next() { return error=file->ft_read(record); }
}; };
QUICK_SELECT *get_ft_or_quick_select_for_ref(TABLE *table, JOIN_TAB *tab); QUICK_SELECT *get_ft_or_quick_select_for_ref(THD *thd, TABLE *table,
JOIN_TAB *tab);
#endif #endif
...@@ -279,6 +279,7 @@ public: ...@@ -279,6 +279,7 @@ public:
typedef struct st_qsel_param { typedef struct st_qsel_param {
THD *thd;
TABLE *table; TABLE *table;
KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY]; KEY_PART *key_parts,*key_parts_end,*key[MAX_KEY];
MEM_ROOT *mem_root; MEM_ROOT *mem_root;
...@@ -378,13 +379,14 @@ SQL_SELECT::~SQL_SELECT() ...@@ -378,13 +379,14 @@ SQL_SELECT::~SQL_SELECT()
#undef index // Fix for Unixware 7 #undef index // Fix for Unixware 7
QUICK_SELECT::QUICK_SELECT(TABLE *table,uint key_nr,bool no_alloc) QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc)
:dont_free(0),error(0),index(key_nr),max_used_key_length(0), :dont_free(0),error(0),index(key_nr),max_used_key_length(0),
used_key_parts(0), head(table), it(ranges),range(0) used_key_parts(0), head(table), it(ranges),range(0)
{ {
if (!no_alloc) if (!no_alloc)
{ {
init_sql_alloc(&alloc,1024,0); // Allocates everything here // Allocates everything through the internal memroot
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
my_pthread_setspecific_ptr(THR_MALLOC,&alloc); my_pthread_setspecific_ptr(THR_MALLOC,&alloc);
} }
else else
...@@ -456,7 +458,7 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) ...@@ -456,7 +458,7 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
SEL_ARG *tmp; SEL_ARG *tmp;
if (type != KEY_RANGE) if (type != KEY_RANGE)
{ {
if (!(tmp=new SEL_ARG(type))) if (!(tmp= new SEL_ARG(type)))
return 0; // out of memory return 0; // out of memory
tmp->prev= *next_arg; // Link into next/prev chain tmp->prev= *next_arg; // Link into next/prev chain
(*next_arg)->next=tmp; (*next_arg)->next=tmp;
...@@ -464,9 +466,9 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) ...@@ -464,9 +466,9 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
} }
else else
{ {
if (!(tmp=new SEL_ARG(field,part, min_value,max_value, if (!(tmp= new SEL_ARG(field,part, min_value,max_value,
min_flag, max_flag, maybe_flag))) min_flag, max_flag, maybe_flag)))
return 0; // out of memory return 0; // OOM
tmp->parent=new_parent; tmp->parent=new_parent;
tmp->next_key_part=next_key_part; tmp->next_key_part=next_key_part;
if (left != &null_element) if (left != &null_element)
...@@ -477,7 +479,8 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg) ...@@ -477,7 +479,8 @@ SEL_ARG *SEL_ARG::clone(SEL_ARG *new_parent,SEL_ARG **next_arg)
(*next_arg)= tmp; (*next_arg)= tmp;
if (right != &null_element) if (right != &null_element)
tmp->right=right->clone(tmp,next_arg); if (!(tmp->right= right->clone(tmp,next_arg)))
return 0; // OOM
} }
increment_use_count(1); increment_use_count(1);
return tmp; return tmp;
...@@ -556,10 +559,11 @@ SEL_ARG *SEL_ARG::clone_tree() ...@@ -556,10 +559,11 @@ SEL_ARG *SEL_ARG::clone_tree()
{ {
SEL_ARG tmp_link,*next_arg,*root; SEL_ARG tmp_link,*next_arg,*root;
next_arg= &tmp_link; next_arg= &tmp_link;
root=clone((SEL_ARG *) 0, &next_arg); root= clone((SEL_ARG *) 0, &next_arg);
next_arg->next=0; // Fix last link next_arg->next=0; // Fix last link
tmp_link.next->prev=0; // Fix first link tmp_link.next->prev=0; // Fix first link
root->use_count=0; if (root) // If not OOM
root->use_count= 0;
return root; return root;
} }
...@@ -577,7 +581,8 @@ SEL_ARG *SEL_ARG::clone_tree() ...@@ -577,7 +581,8 @@ SEL_ARG *SEL_ARG::clone_tree()
** quick_rows ; How many rows the key matches ** quick_rows ; How many rows the key matches
*****************************************************************************/ *****************************************************************************/
int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
table_map prev_tables,
ha_rows limit, bool force_quick_range) ha_rows limit, bool force_quick_range)
{ {
uint basflag; uint basflag;
...@@ -618,9 +623,9 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, ...@@ -618,9 +623,9 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
SEL_TREE *tree; SEL_TREE *tree;
KEY_PART *key_parts; KEY_PART *key_parts;
PARAM param; PARAM param;
THD *thd= current_thd;
/* set up parameter that is passed to all functions */ /* set up parameter that is passed to all functions */
param.thd= thd;
param.baseflag=basflag; param.baseflag=basflag;
param.prev_tables=prev_tables | const_tables; param.prev_tables=prev_tables | const_tables;
param.read_tables=read_tables; param.read_tables=read_tables;
...@@ -630,7 +635,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, ...@@ -630,7 +635,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
param.mem_root= &alloc; param.mem_root= &alloc;
thd->no_errors=1; // Don't warn about NULL thd->no_errors=1; // Don't warn about NULL
init_sql_alloc(&alloc,2048,0); init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc, if (!(param.key_parts = (KEY_PART*) alloc_root(&alloc,
sizeof(KEY_PART)* sizeof(KEY_PART)*
head->key_parts))) head->key_parts)))
...@@ -765,7 +770,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond) ...@@ -765,7 +770,7 @@ static SEL_TREE *get_mm_tree(PARAM *param,COND *cond)
while ((item=li++)) while ((item=li++))
{ {
SEL_TREE *new_tree=get_mm_tree(param,item); SEL_TREE *new_tree=get_mm_tree(param,item);
if (current_thd->is_fatal_error) if (param->thd->is_fatal_error)
DBUG_RETURN(0); // out of memory DBUG_RETURN(0); // out of memory
tree=tree_and(param,tree,new_tree); tree=tree_and(param,tree,new_tree);
if (tree && tree->type == SEL_TREE::IMPOSSIBLE) if (tree && tree->type == SEL_TREE::IMPOSSIBLE)
...@@ -906,7 +911,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, ...@@ -906,7 +911,7 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
{ {
SEL_ARG *sel_arg=0; SEL_ARG *sel_arg=0;
if (!tree && !(tree=new SEL_TREE())) if (!tree && !(tree=new SEL_TREE()))
DBUG_RETURN(0); // out of memory DBUG_RETURN(0); // OOM
if (!value || !(value->used_tables() & ~param->read_tables)) if (!value || !(value->used_tables() & ~param->read_tables))
{ {
sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value); sel_arg=get_mm_leaf(param,key_part->field,key_part,type,value);
...@@ -918,10 +923,11 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type, ...@@ -918,10 +923,11 @@ get_mm_parts(PARAM *param, Field *field, Item_func::Functype type,
DBUG_RETURN(tree); DBUG_RETURN(tree);
} }
} }
else { else
{
// This key may be used later // This key may be used later
if (!(sel_arg=new SEL_ARG(SEL_ARG::MAYBE_KEY))) if (!(sel_arg= new SEL_ARG(SEL_ARG::MAYBE_KEY)))
DBUG_RETURN(0); // out of memory DBUG_RETURN(0); // OOM
} }
sel_arg->part=(uchar) key_part->part; sel_arg->part=(uchar) key_part->part;
tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg); tree->keys[key_part->key]=sel_add(tree->keys[key_part->key],sel_arg);
...@@ -1126,8 +1132,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part, ...@@ -1126,8 +1132,8 @@ get_mm_leaf(PARAM *param, Field *field, KEY_PART *key_part,
******************************************************************************/ ******************************************************************************/
/* /*
** Add a new key test to a key when scanning through all keys Add a new key test to a key when scanning through all keys
** This will never be called for same key parts. This will never be called for same key parts.
*/ */
static SEL_ARG * static SEL_ARG *
...@@ -1311,7 +1317,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) ...@@ -1311,7 +1317,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
// key1->part < key2->part // key1->part < key2->part
key1->use_count--; key1->use_count--;
if (key1->use_count > 0) if (key1->use_count > 0)
key1=key1->clone_tree(); if (!(key1= key1->clone_tree()))
return 0; // OOM
return and_all_keys(key1,key2,clone_flag); return and_all_keys(key1,key2,clone_flag);
} }
...@@ -1330,7 +1337,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) ...@@ -1330,7 +1337,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (key1->use_count > 1) if (key1->use_count > 1)
{ {
key1->use_count--; key1->use_count--;
key1=key1->clone_tree(); if (!(key1=key1->clone_tree()))
return 0; // OOM
key1->use_count++; key1->use_count++;
} }
if (key1->type == SEL_ARG::MAYBE_KEY) if (key1->type == SEL_ARG::MAYBE_KEY)
...@@ -1374,6 +1382,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) ...@@ -1374,6 +1382,8 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag)
if (!next || next->type != SEL_ARG::IMPOSSIBLE) if (!next || next->type != SEL_ARG::IMPOSSIBLE)
{ {
SEL_ARG *new_arg= e1->clone_and(e2); SEL_ARG *new_arg= e1->clone_and(e2);
if (!new_arg)
return &null_element; // End of memory
new_arg->next_key_part=next; new_arg->next_key_part=next;
if (!new_tree) if (!new_tree)
{ {
...@@ -1461,8 +1471,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1461,8 +1471,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
{ {
swap(SEL_ARG *,key1,key2); swap(SEL_ARG *,key1,key2);
} }
else else if (!(key1=key1->clone_tree()))
key1=key1->clone_tree(); return 0; // OOM
} }
// Add tree at key2 to tree at key1 // Add tree at key2 to tree at key1
...@@ -1530,7 +1540,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1530,7 +1540,10 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
SEL_ARG *next=key2->next; // Keys are not overlapping SEL_ARG *next=key2->next; // Keys are not overlapping
if (key2_shared) if (key2_shared)
{ {
key1=key1->insert(new SEL_ARG(*key2)); // Must make copy SEL_ARG *tmp= new SEL_ARG(*key2); // Must make copy
if (!tmp)
return 0; // OOM
key1=key1->insert(tmp);
key2->increment_use_count(key1->use_count+1); key2->increment_use_count(key1->use_count+1);
} }
else else
...@@ -1576,6 +1589,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1576,6 +1589,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0) if (cmp >= 0 && tmp->cmp_min_to_min(key2) < 0)
{ // tmp.min <= x < key2.min { // tmp.min <= x < key2.min
SEL_ARG *new_arg=tmp->clone_first(key2); SEL_ARG *new_arg=tmp->clone_first(key2);
if (!new_arg)
return 0; // OOM
if ((new_arg->next_key_part= key1->next_key_part)) if ((new_arg->next_key_part= key1->next_key_part))
new_arg->increment_use_count(key1->use_count+1); new_arg->increment_use_count(key1->use_count+1);
tmp->copy_min_to_min(key2); tmp->copy_min_to_min(key2);
...@@ -1589,6 +1604,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1589,6 +1604,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
if (tmp->cmp_min_to_min(&key) > 0) if (tmp->cmp_min_to_min(&key) > 0)
{ // key.min <= x < tmp.min { // key.min <= x < tmp.min
SEL_ARG *new_arg=key.clone_first(tmp); SEL_ARG *new_arg=key.clone_first(tmp);
if (!new_arg)
return 0; // OOM
if ((new_arg->next_key_part=key.next_key_part)) if ((new_arg->next_key_part=key.next_key_part))
new_arg->increment_use_count(key1->use_count+1); new_arg->increment_use_count(key1->use_count+1);
key1=key1->insert(new_arg); key1=key1->insert(new_arg);
...@@ -1603,19 +1620,27 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) ...@@ -1603,19 +1620,27 @@ key_or(SEL_ARG *key1,SEL_ARG *key2)
key.copy_max_to_min(tmp); key.copy_max_to_min(tmp);
if (!(tmp=tmp->next)) if (!(tmp=tmp->next))
{ {
key1=key1->insert(new SEL_ARG(key)); SEL_ARG *tmp2= new SEL_ARG(key);
if (!tmp2)
return 0; // OOM
key1=key1->insert(tmp2);
key2=key2->next; key2=key2->next;
goto end; goto end;
} }
if (tmp->cmp_min_to_max(&key) > 0) if (tmp->cmp_min_to_max(&key) > 0)
{ {
key1=key1->insert(new SEL_ARG(key)); SEL_ARG *tmp2= new SEL_ARG(key);
if (!tmp2)
return 0; // OOM
key1=key1->insert(tmp2);
break; break;
} }
} }
else else
{ {
SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max SEL_ARG *new_arg=tmp->clone_last(&key); // tmp.min <= x <= key.max
if (!new_arg)
return 0; // OOM
tmp->copy_max_to_min(&key); tmp->copy_max_to_min(&key);
tmp->increment_use_count(key1->use_count+1); tmp->increment_use_count(key1->use_count+1);
new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part); new_arg->next_key_part=key_or(tmp->next_key_part,key.next_key_part);
...@@ -1632,8 +1657,11 @@ end: ...@@ -1632,8 +1657,11 @@ end:
SEL_ARG *next=key2->next; SEL_ARG *next=key2->next;
if (key2_shared) if (key2_shared)
{ {
SEL_ARG *tmp=new SEL_ARG(*key2); // Must make copy
if (!tmp)
return 0;
key2->increment_use_count(key1->use_count+1); key2->increment_use_count(key1->use_count+1);
key1=key1->insert(new SEL_ARG(*key2)); // Must make copy key1=key1->insert(tmp);
} }
else else
key1=key1->insert(key2); // Will destroy key2_root key1=key1->insert(key2); // Will destroy key2_root
...@@ -2222,7 +2250,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree) ...@@ -2222,7 +2250,8 @@ get_quick_select(PARAM *param,uint idx,SEL_ARG *key_tree)
{ {
QUICK_SELECT *quick; QUICK_SELECT *quick;
DBUG_ENTER("get_quick_select"); DBUG_ENTER("get_quick_select");
if ((quick=new QUICK_SELECT(param->table,param->real_keynr[idx]))) if ((quick=new QUICK_SELECT(param->thd, param->table,
param->real_keynr[idx])))
{ {
if (quick->error || if (quick->error ||
get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0, get_quick_keys(param,quick,param->key[idx],key_tree,param->min_key,0,
...@@ -2394,10 +2423,10 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length) ...@@ -2394,10 +2423,10 @@ static bool null_part_in_key(KEY_PART *key_part, const char *key, uint length)
** Create a QUICK RANGE based on a key ** Create a QUICK RANGE based on a key
****************************************************************************/ ****************************************************************************/
QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref)
{ {
table->file->index_end(); // Remove old cursor table->file->index_end(); // Remove old cursor
QUICK_SELECT *quick=new QUICK_SELECT(table, ref->key, 1); QUICK_SELECT *quick=new QUICK_SELECT(thd, table, ref->key, 1);
KEY *key_info = &table->key_info[ref->key]; KEY *key_info = &table->key_info[ref->key];
KEY_PART *key_part; KEY_PART *key_part;
uint part; uint part;
...@@ -2406,7 +2435,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref) ...@@ -2406,7 +2435,7 @@ QUICK_SELECT *get_quick_select_for_ref(TABLE *table, TABLE_REF *ref)
return 0; /* no ranges found */ return 0; /* no ranges found */
if (cp_buffer_from_ref(ref)) if (cp_buffer_from_ref(ref))
{ {
if (current_thd->is_fatal_error) if (thd->is_fatal_error)
return 0; // out of memory return 0; // out of memory
return quick; // empty range return quick; // empty range
} }
......
...@@ -83,7 +83,7 @@ public: ...@@ -83,7 +83,7 @@ public:
ha_rows records; ha_rows records;
double read_time; double read_time;
QUICK_SELECT(TABLE *table,uint index_arg,bool no_alloc=0); QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT(); virtual ~QUICK_SELECT();
void reset(void) { next=0; it.rewind(); } void reset(void) { next=0; it.rewind(); }
int init() { return error=file->index_init(index); } int init() { return error=file->index_init(index); }
...@@ -127,13 +127,15 @@ class SQL_SELECT :public Sql_alloc { ...@@ -127,13 +127,15 @@ class SQL_SELECT :public Sql_alloc {
SQL_SELECT(); SQL_SELECT();
~SQL_SELECT(); ~SQL_SELECT();
bool check_quick(bool force_quick_range=0, ha_rows limit = HA_POS_ERROR) bool check_quick(THD *thd, bool force_quick_range= 0,
{ return test_quick_select(~0L,0,limit, force_quick_range) < 0; } ha_rows limit= HA_POS_ERROR)
{ return test_quick_select(thd, ~0L,0,limit, force_quick_range) < 0; }
inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; } inline bool skipp_record() { return cond ? cond->val_int() == 0 : 0; }
int test_quick_select(key_map keys,table_map prev_tables,ha_rows limit, int test_quick_select(THD *thd, key_map keys, table_map prev_tables,
bool force_quick_range=0); ha_rows limit, bool force_quick_range=0);
}; };
QUICK_SELECT *get_quick_select_for_ref(TABLE *table, struct st_table_ref *ref); QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table,
struct st_table_ref *ref);
#endif #endif
...@@ -235,6 +235,18 @@ sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank", ...@@ -235,6 +235,18 @@ sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
sys_var_long_ptr sys_query_cache_size("query_cache_size", sys_var_long_ptr sys_query_cache_size("query_cache_size",
&query_cache_size, &query_cache_size,
fix_query_cache_size); fix_query_cache_size);
sys_var_thd_ulong sys_range_alloc_block_size("range_alloc_block_size",
&SV::range_alloc_block_size);
sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size",
&SV::query_alloc_block_size);
sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size",
&SV::query_prealloc_size);
sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size",
&SV::trans_alloc_block_size);
sys_var_thd_ulong sys_trans_prealloc_size("transaction_prealloc_size",
&SV::trans_prealloc_size);
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
sys_var_long_ptr sys_query_cache_limit("query_cache_limit", sys_var_long_ptr sys_query_cache_limit("query_cache_limit",
&query_cache.query_cache_limit); &query_cache.query_cache_limit);
...@@ -441,7 +453,9 @@ sys_var *sys_variables[]= ...@@ -441,7 +453,9 @@ sys_var *sys_variables[]=
&sys_old_passwords, &sys_old_passwords,
&sys_preload_buff_size, &sys_preload_buff_size,
&sys_pseudo_thread_id, &sys_pseudo_thread_id,
&sys_query_alloc_block_size,
&sys_query_cache_size, &sys_query_cache_size,
&sys_query_prealloc_size,
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
&sys_query_cache_limit, &sys_query_cache_limit,
&sys_query_cache_min_res_unit, &sys_query_cache_min_res_unit,
...@@ -452,6 +466,7 @@ sys_var *sys_variables[]= ...@@ -452,6 +466,7 @@ sys_var *sys_variables[]=
&sys_rand_seed2, &sys_rand_seed2,
&sys_read_buff_size, &sys_read_buff_size,
&sys_read_rnd_buff_size, &sys_read_rnd_buff_size,
&sys_range_alloc_block_size,
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
&sys_relay_log_purge, &sys_relay_log_purge,
#endif #endif
...@@ -478,6 +493,8 @@ sys_var *sys_variables[]= ...@@ -478,6 +493,8 @@ sys_var *sys_variables[]=
&sys_thread_cache_size, &sys_thread_cache_size,
&sys_timestamp, &sys_timestamp,
&sys_tmp_table_size, &sys_tmp_table_size,
&sys_trans_alloc_block_size,
&sys_trans_prealloc_size,
&sys_tx_isolation, &sys_tx_isolation,
#ifdef HAVE_INNOBASE_DB #ifdef HAVE_INNOBASE_DB
&sys_innodb_max_dirty_pages_pct, &sys_innodb_max_dirty_pages_pct,
...@@ -629,6 +646,8 @@ struct show_var_st init_vars[]= { ...@@ -629,6 +646,8 @@ struct show_var_st init_vars[]= {
{"protocol_version", (char*) &protocol_version, SHOW_INT}, {"protocol_version", (char*) &protocol_version, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS}, {sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
{sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS}, {sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS},
{sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
SHOW_SYS},
#ifdef HAVE_QUERY_CACHE #ifdef HAVE_QUERY_CACHE
{sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS}, {sys_query_cache_limit.name,(char*) &sys_query_cache_limit, SHOW_SYS},
{sys_query_cache_min_res_unit.name, (char*) &sys_query_cache_min_res_unit, {sys_query_cache_min_res_unit.name, (char*) &sys_query_cache_min_res_unit,
...@@ -637,9 +656,12 @@ struct show_var_st init_vars[]= { ...@@ -637,9 +656,12 @@ struct show_var_st init_vars[]= {
{sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS},
{"secure_auth", (char*) &sys_secure_auth, SHOW_SYS}, {"secure_auth", (char*) &sys_secure_auth, SHOW_SYS},
#endif /* HAVE_QUERY_CACHE */ #endif /* HAVE_QUERY_CACHE */
{sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS},
{sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS}, {sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
{sys_readonly.name, (char*) &sys_readonly, SHOW_SYS}, {sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
{sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS}, {sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
{sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size,
SHOW_SYS},
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
{sys_relay_log_purge.name, (char*) &sys_relay_log_purge, SHOW_SYS}, {sys_relay_log_purge.name, (char*) &sys_relay_log_purge, SHOW_SYS},
#endif #endif
...@@ -675,6 +697,9 @@ struct show_var_st init_vars[]= { ...@@ -675,6 +697,9 @@ struct show_var_st init_vars[]= {
#endif #endif
{sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS}, {sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
{"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR}, {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR},
{sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size,
SHOW_SYS},
{sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS},
{"version", server_version, SHOW_CHAR}, {"version", server_version, SHOW_CHAR},
{sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS}, {sys_net_wait_timeout.name, (char*) &sys_net_wait_timeout, SHOW_SYS},
{NullS, NullS, SHOW_LONG} {NullS, NullS, SHOW_LONG}
......
...@@ -186,7 +186,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) ...@@ -186,7 +186,7 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
thd->net.last_error); thd->net.last_error);
goto end; goto end;
} }
init_sql_alloc(&mem,1024,0); init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0);
init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0);
VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50));
while (!(read_record_info.read_record(&read_record_info))) while (!(read_record_info.read_record(&read_record_info)))
...@@ -2450,7 +2450,7 @@ my_bool grant_init(THD *org_thd) ...@@ -2450,7 +2450,7 @@ my_bool grant_init(THD *org_thd)
(void) hash_init(&column_priv_hash,&my_charset_latin1, (void) hash_init(&column_priv_hash,&my_charset_latin1,
0,0,0, (hash_get_key) get_grant_table, 0,0,0, (hash_get_key) get_grant_table,
(hash_free_key) free_grant_table,0); (hash_free_key) free_grant_table,0);
init_sql_alloc(&memex,1024,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0);
/* Don't do anything if running with --skip-grant */ /* Don't do anything if running with --skip-grant */
if (!initialized) if (!initialized)
......
...@@ -392,10 +392,15 @@ struct system_variables ...@@ -392,10 +392,15 @@ struct system_variables
ulong table_type; ulong table_type;
ulong tmp_table_size; ulong tmp_table_size;
ulong tx_isolation; ulong tx_isolation;
/* Determines if which non-standard SQL behaviour should be enabled */ /* Determines which non-standard SQL behaviour should be enabled */
ulong sql_mode; ulong sql_mode;
ulong default_week_format; ulong default_week_format;
ulong max_seeks_for_key; ulong max_seeks_for_key;
ulong range_alloc_block_size;
ulong query_alloc_block_size;
ulong query_prealloc_size;
ulong trans_alloc_block_size;
ulong trans_prealloc_size;
ulong group_concat_max_len; ulong group_concat_max_len;
/* /*
In slave thread we need to know in behalf of which In slave thread we need to know in behalf of which
......
...@@ -89,7 +89,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, ...@@ -89,7 +89,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
select=make_select(table,0,0,conds,&error); select=make_select(table,0,0,conds,&error);
if (error) if (error)
DBUG_RETURN(-1); DBUG_RETURN(-1);
if ((select && select->check_quick(safe_update, limit)) || !limit) if ((select && select->check_quick(thd, safe_update, limit)) || !limit)
{ {
delete select; delete select;
free_underlaid_joins(thd, &thd->lex.select_lex); free_underlaid_joins(thd, &thd->lex.select_lex);
......
...@@ -1574,7 +1574,8 @@ err: ...@@ -1574,7 +1574,8 @@ err:
Approximate how many records will be used in each table Approximate how many records will be used in each table
*****************************************************************************/ *****************************************************************************/
static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
TABLE *table,
key_map keys,ha_rows limit) key_map keys,ha_rows limit)
{ {
int error; int error;
...@@ -1583,7 +1584,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table, ...@@ -1583,7 +1584,7 @@ static ha_rows get_quick_record_count(SQL_SELECT *select,TABLE *table,
{ {
select->head=table; select->head=table;
table->reginfo.impossible_range=0; table->reginfo.impossible_range=0;
if ((error=select->test_quick_select(keys,(table_map) 0,limit)) if ((error=select->test_quick_select(thd, keys,(table_map) 0,limit))
== 1) == 1)
DBUG_RETURN(select->quick->records); DBUG_RETURN(select->quick->records);
if (error == -1) if (error == -1)
...@@ -1866,8 +1867,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, ...@@ -1866,8 +1867,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
found_const_table_map, found_const_table_map,
s->on_expr ? s->on_expr : conds, s->on_expr ? s->on_expr : conds,
&error); &error);
records= get_quick_record_count(select,s->table, s->const_keys, records= get_quick_record_count(join->thd, select, s->table,
join->row_limit); s->const_keys, join->row_limit);
s->quick=select->quick; s->quick=select->quick;
s->needed_reg=select->needed_reg; s->needed_reg=select->needed_reg;
select->quick=0; select->quick=0;
...@@ -3377,7 +3378,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -3377,7 +3378,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
/* Join with outer join condition */ /* Join with outer join condition */
COND *orig_cond=sel->cond; COND *orig_cond=sel->cond;
sel->cond=and_conds(sel->cond,tab->on_expr); sel->cond=and_conds(sel->cond,tab->on_expr);
if (sel->test_quick_select(tab->keys, if (sel->test_quick_select(join->thd, tab->keys,
used_tables & ~ current_map, used_tables & ~ current_map,
(join->select_options & (join->select_options &
OPTION_FOUND_ROWS ? OPTION_FOUND_ROWS ?
...@@ -3390,7 +3391,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -3390,7 +3391,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
*/ */
sel->cond=orig_cond; sel->cond=orig_cond;
if (!tab->on_expr || if (!tab->on_expr ||
sel->test_quick_select(tab->keys, sel->test_quick_select(join->thd, tab->keys,
used_tables & ~ current_map, used_tables & ~ current_map,
(join->select_options & (join->select_options &
OPTION_FOUND_ROWS ? OPTION_FOUND_ROWS ?
...@@ -5828,7 +5829,8 @@ test_if_quick_select(JOIN_TAB *tab) ...@@ -5828,7 +5829,8 @@ test_if_quick_select(JOIN_TAB *tab)
{ {
delete tab->select->quick; delete tab->select->quick;
tab->select->quick=0; tab->select->quick=0;
return tab->select->test_quick_select(tab->keys,(table_map) 0,HA_POS_ERROR); return tab->select->test_quick_select(tab->join->thd, tab->keys,
(table_map) 0, HA_POS_ERROR);
} }
...@@ -6921,7 +6923,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, ...@@ -6921,7 +6923,8 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
For impossible ranges (like when doing a lookup on NULL on a NOT NULL For impossible ranges (like when doing a lookup on NULL on a NOT NULL
field, quick will contain an empty record set. field, quick will contain an empty record set.
*/ */
if (!(select->quick=get_ft_or_quick_select_for_ref(table, tab))) if (!(select->quick=get_ft_or_quick_select_for_ref(tab->join->thd,
table, tab)))
goto err; goto err;
} }
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "sql_select.h" #include "sql_select.h"
#include <hash.h> #include <hash.h>
#include <thr_alarm.h> #include <thr_alarm.h>
#include <malloc.h>
/* Intern key cache variables */ /* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache; extern "C" pthread_mutex_t THR_LOCK_keycache;
...@@ -365,6 +366,32 @@ Next alarm time: %lu\n", ...@@ -365,6 +366,32 @@ Next alarm time: %lu\n",
thd->proc_info="malloc"; thd->proc_info="malloc";
my_checkmalloc(); my_checkmalloc();
TERMINATE(stdout); // Write malloc information TERMINATE(stdout); // Write malloc information
#ifdef HAVE_MALLINFO
struct mallinfo info= mallinfo();
printf("\nMemory status:\n\
Non-mmapped space allocated from system: %d\n\
Number of free chunks: %d\n\
Number of fastbin blocks: %d\n\
Number of mmapped regions: %d\n\
Space in mmapped regions: %d\n\
Maximum total allocated space: %d\n\
Space available in freed fastbin blocks: %d\n\
Total allocated space: %d\n\
Total free space: %d\n\
Top-most, releasable space: %d\n",
(int) info.arena,
(int) info.ordblks,
(int) info.smblks,
(int) info.hblks,
(int) info.hblkhd,
(int) info.usmblks,
(int) info.fsmblks,
(int) info.uordblks,
(int) info.fordblks,
(int) info.keepcost);
#endif
puts("");
if (thd) if (thd)
thd->proc_info=0; thd->proc_info=0;
} }
...@@ -128,7 +128,7 @@ void udf_init() ...@@ -128,7 +128,7 @@ void udf_init()
my_rwlock_init(&THR_LOCK_udf,NULL); my_rwlock_init(&THR_LOCK_udf,NULL);
init_sql_alloc(&mem, 1024,0); init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0);
THD *new_thd = new THD; THD *new_thd = new THD;
if (!new_thd || if (!new_thd ||
hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0)) hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0))
......
...@@ -152,7 +152,7 @@ int mysql_update(THD *thd, ...@@ -152,7 +152,7 @@ int mysql_update(THD *thd,
table->used_keys=0; table->used_keys=0;
select=make_select(table,0,0,conds,&error); select=make_select(table,0,0,conds,&error);
if (error || if (error ||
(select && select->check_quick(safe_update, limit)) || !limit) (select && select->check_quick(thd, safe_update, limit)) || !limit)
{ {
delete select; delete select;
free_underlaid_joins(thd, &thd->lex.select_lex); free_underlaid_joins(thd, &thd->lex.select_lex);
......
...@@ -90,7 +90,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, ...@@ -90,7 +90,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag,
outparam->db_stat = db_stat; outparam->db_stat = db_stat;
error=1; error=1;
init_sql_alloc(&outparam->mem_root,1024,0); init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC); MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root); my_pthread_setspecific_ptr(THR_MALLOC,&outparam->mem_root);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment