Commit 32cd2fe6 authored by unknown's avatar unknown

Merge mysql.com:/home/svoj/devel/bk/mysql-5.1

into  mysql.com:/home/svoj/devel/mysql/merge/mysql-5.1-engines


mysql-test/mysql-test-run.pl:
  Auto merged
mysql-test/t/disabled.def:
  Auto merged
sql/handler.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
storage/myisam/ha_myisam.cc:
  Auto merged
parents 2d95236b c367385f
......@@ -44,6 +44,7 @@ typedef struct st_keycache_wqueue
typedef struct st_key_cache
{
my_bool key_cache_inited;
my_bool in_resize; /* true during resize operation */
my_bool resize_in_flush; /* true during flush of resize operation */
my_bool can_be_used; /* usage of cache for read/write is allowed */
uint key_cache_shift;
......@@ -72,6 +73,11 @@ typedef struct st_key_cache
BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */
pthread_mutex_t cache_lock; /* to lock access to the cache structure */
KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */
/*
Waiting for a zero resize count. Using a queue for symmetry though
only one thread can wait here.
*/
KEYCACHE_WQUEUE waiting_for_resize_cnt;
KEYCACHE_WQUEUE waiting_for_hash_link; /* waiting for a free hash link */
KEYCACHE_WQUEUE waiting_for_block; /* requests waiting for a free block */
BLOCK_LINK *changed_blocks[CHANGED_BLOCKS_HASH]; /* hash for dirty file bl.*/
......
......@@ -66,8 +66,8 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_ALLOW_ZERO_PTR 64 /* my_realloc() ; zero ptr -> malloc */
#define MY_FREE_ON_ERROR 128 /* my_realloc() ; Free old ptr on error */
#define MY_HOLD_ON_ERROR 256 /* my_realloc() ; Return old ptr on error */
#define MY_THREADSAFE 128 /* pread/pwrite: Don't allow interrupts */
#define MY_DONT_OVERWRITE_FILE 1024 /* my_copy: Don't overwrite file */
#define MY_THREADSAFE 2048 /* my_seek(): lock fd mutex */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
......
......@@ -124,6 +124,16 @@ let $VERSION=`select version()`;
source include/show_binlog_events.inc;
drop table t1,t2,t3;
#
# BUG#27998 - mysqld crashed when executing INSERT DELAYED on a BLACKHOLE
# table
#
CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
INSERT DELAYED INTO t1 VALUES(1);
DROP TABLE t1;
# End of 4.1 tests
#
#Bug#19717: DELETE Query Error on BLACKHOLE when using WHERE on column with UNIQUE INDEX
#
......@@ -139,7 +149,8 @@ ALTER TABLE t1 ADD PRIMARY KEY(a);
DELETE FROM t1 WHERE a=10;
DROP TABLE t1;
# End of 4.1 tests
# End of 5.0 tests
# Test that a transaction which is rolled back does not go into binlog
# and that a transaction which is committed does
......@@ -156,4 +167,4 @@ set autocommit=1;
source include/show_binlog_events.inc;
drop table if exists t1;
# End of 5.0 tests
# End of 5.1 tests
......@@ -120,7 +120,11 @@ sub mtr_get_opts_from_file ($) {
$arg =~ s/\$(\w+)/envsubst($1)/ge;
# print STDERR "ARG: $arg\n";
push(@args, $arg);
# Do not pass empty string since my_getopt is not capable to handle it.
if (length($arg))
{
push(@args, $arg)
}
}
}
close FILE;
......
......@@ -1766,22 +1766,6 @@ sub environment_setup () {
push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs");
}
# --------------------------------------------------------------------------
# Add the path where mysqld will find udf_example.so
# --------------------------------------------------------------------------
if ( $lib_udf_example )
{
push(@ld_library_paths, dirname($lib_udf_example));
}
# --------------------------------------------------------------------------
# Add the path where mysqld will find ha_example.so
# --------------------------------------------------------------------------
if ( $lib_example_plugin )
{
push(@ld_library_paths, dirname($lib_example_plugin));
}
# --------------------------------------------------------------------------
# Valgrind need to be run with debug libraries otherwise it's almost
# impossible to add correct supressions, that means if "/usr/lib/debug"
......@@ -2060,12 +2044,16 @@ sub environment_setup () {
# ----------------------------------------------------
$ENV{'UDF_EXAMPLE_LIB'}=
($lib_udf_example ? basename($lib_udf_example) : "");
$ENV{'UDF_EXAMPLE_LIB_OPT'}=
($lib_udf_example ? "--plugin_dir=" . dirname($lib_udf_example) : "");
# ----------------------------------------------------
# Add the path where mysqld will find ha_example.so
# ----------------------------------------------------
$ENV{'EXAMPLE_PLUGIN'}=
($lib_example_plugin ? basename($lib_example_plugin) : "");
$ENV{'EXAMPLE_PLUGIN_OPT'}=
($lib_example_plugin ? "--plugin_dir=" . dirname($lib_example_plugin) : "");
# ----------------------------------------------------
# We are nice and report a bit about our settings
......@@ -3821,9 +3809,6 @@ sub mysqld_arguments ($$$$) {
mtr_add_arg($args, "%s--ndb-extra-logging", $prefix);
}
}
mtr_add_arg($args, "%s--plugin_dir=%s", $prefix,
dirname($lib_example_plugin));
}
else
{
......
......@@ -121,6 +121,9 @@ master-bin.000001 # Query # # use `test`; alter table t1 add b int
master-bin.000001 # Query # # use `test`; alter table t1 drop b
master-bin.000001 # Query # # use `test`; create table t3 like t1
drop table t1,t2,t3;
CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
INSERT DELAYED INTO t1 VALUES(1);
DROP TABLE t1;
CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
DELETE FROM t1 WHERE a=10;
ALTER TABLE t1 ADD INDEX(a);
......
......@@ -122,6 +122,9 @@ master-bin.000001 # Query # # use `test`; create table t3 like t1
master-bin.000001 # Query # # use `test`; insert into t1 select * from t3
master-bin.000001 # Query # # use `test`; replace into t1 select * from t3
drop table t1,t2,t3;
CREATE TABLE t1(a INT) ENGINE=BLACKHOLE;
INSERT DELAYED INTO t1 VALUES(1);
DROP TABLE t1;
CREATE TABLE t1(a INT, b INT) ENGINE=BLACKHOLE;
DELETE FROM t1 WHERE a=10;
ALTER TABLE t1 ADD INDEX(a);
......
CREATE TABLE t1(a int) ENGINE=EXAMPLE;
Warnings:
Error 1286 Unknown table engine 'EXAMPLE'
Warning 1286 Unknown table engine 'EXAMPLE'
Warning 1266 Using storage engine MyISAM for table 't1'
DROP TABLE t1;
INSTALL PLUGIN example SONAME 'ha_example.so';
INSTALL PLUGIN EXAMPLE SONAME 'ha_example.so';
......@@ -11,5 +12,8 @@ CREATE TABLE t1(a int) ENGINE=EXAMPLE;
SELECT * FROM t1;
a
DROP TABLE t1;
UNINSTALL PLUGIN example;
UNINSTALL PLUGIN EXAMPLE;
ERROR 42000: PLUGIN EXAMPLE does not exist
UNINSTALL PLUGIN non_exist;
ERROR 42000: PLUGIN non_exist does not exist
......@@ -37,7 +37,6 @@ synchronization : Bug#24529 Test 'synchronization' fails on Mac pushb
#ndb_binlog_discover : bug#21806 2006-08-24
#ndb_autodiscover3 : bug#21806
plugin : Bug#25659 memory leak via "plugins" test
#rpl_ndb_dd_advance : Bug#25913 rpl_ndb_dd_advance fails randomly
rpl_ndb_stm_innodb : Bug#26783
......
......@@ -18,9 +18,9 @@ SELECT * FROM t1;
DROP TABLE t1;
# Waiting for fix to BUG#22694
#UNINSTALL PLUGIN example;
#UNINSTALL PLUGIN EXAMPLE;
UNINSTALL PLUGIN example;
--error 1305
UNINSTALL PLUGIN EXAMPLE;
--error 1305
UNINSTALL PLUGIN non_exist;
$UDF_EXAMPLE_LIB_OPT
......@@ -426,6 +426,23 @@
fun:_dl_map_object
}
{
libc pthread_exit 6
Memcheck:Leak
fun:malloc
fun:_dl_map_object
fun:openaux
fun:_dl_catch_error
}
{
libc pthread_exit 7
Memcheck:Leak
fun:malloc
fun:dl_open_worker
fun:_dl_catch_error
fun:_dl_open
}
#
# This is seen internally in the system libraries on 64-bit RHAS3.
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -23,7 +23,9 @@
my_off_t pos The expected position (absolute or relative)
int whence A direction parameter and one of
{SEEK_SET, SEEK_CUR, SEEK_END}
myf MyFlags Not used.
myf MyFlags MY_THREADSAFE must be set in case my_seek may be mixed
with my_pread/my_pwrite calls and fd is shared among
threads.
DESCRIPTION
The my_seek function is a wrapper around the system call lseek and
......@@ -54,9 +56,16 @@ my_off_t my_seek(File fd, my_off_t pos, int whence,
Make sure we are using a valid file descriptor!
*/
DBUG_ASSERT(fd != -1);
#if defined(THREAD) && !defined(HAVE_PREAD)
if (MyFlags & MY_THREADSAFE)
{
pthread_mutex_lock(&my_file_info[fd].mutex);
newpos= lseek(fd, pos, whence);
pthread_mutex_unlock(&my_file_info[fd].mutex);
}
else
#endif
newpos= lseek(fd, pos, whence);
if (newpos == (os_off_t) -1)
{
my_errno=errno;
......
......@@ -48,9 +48,6 @@ struct st_remember _my_sig_remember[MAX_SIGNALS]={{0,0}};
sigset_t my_signals; /* signals blocked by mf_brkhant */
#endif
/* from mf_keycache.c */
my_bool key_cache_inited=0;
/* from mf_reccache.c */
ulong my_default_record_cache_size=RECORD_CACHE_SIZE;
......
......@@ -2717,8 +2717,8 @@ int ha_init_key_cache(const char *name, KEY_CACHE *key_cache)
if (!key_cache->key_cache_inited)
{
pthread_mutex_lock(&LOCK_global_system_variables);
long tmp_buff_size= (long) key_cache->param_buff_size;
long tmp_block_size= (long) key_cache->param_block_size;
ulong tmp_buff_size= (ulong) key_cache->param_buff_size;
uint tmp_block_size= (uint) key_cache->param_block_size;
uint division_limit= key_cache->param_division_limit;
uint age_threshold= key_cache->param_age_threshold;
pthread_mutex_unlock(&LOCK_global_system_variables);
......
......@@ -4653,8 +4653,13 @@ int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
{
DBUG_ENTER("mysql_preload_keys");
/*
We cannot allow concurrent inserts. The storage engine reads
directly from the index file, bypassing the cache. It could read
outdated information if parallel inserts into cache blocks happen.
*/
DBUG_RETURN(mysql_admin_table(thd, tables, 0,
"preload_keys", TL_READ, 0, 0, 0, 0,
"preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
&handler::preload_keys, 0));
}
......
......@@ -169,9 +169,13 @@ void udf_init()
Ensure that the .dll doesn't have a path
This is done to ensure that only approved dll from the system
directories are used (to make this even remotely secure).
On windows we must check both FN_LIBCHAR and '/'.
*/
if (my_strchr(files_charset_info, dl_name,
dl_name + strlen(dl_name), FN_LIBCHAR) ||
IF_WIN(my_strchr(files_charset_info, dl_name,
dl_name + strlen(dl_name), '/'), 0) ||
check_string_char_length(&name, "", NAME_CHAR_LEN,
system_charset_info, 1))
{
......@@ -190,7 +194,10 @@ void udf_init()
void *dl = find_udf_dl(tmp->dl);
if (dl == NULL)
{
if (!(dl= dlopen(tmp->dl, RTLD_NOW)))
char dlpath[FN_REFLEN];
strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", tmp->dl,
NullS);
if (!(dl= dlopen(dlpath, RTLD_NOW)))
{
/* Print warning to log */
sql_print_error(ER(ER_CANT_OPEN_LIBRARY), tmp->dl, errno, dlerror());
......@@ -394,8 +401,13 @@ int mysql_create_function(THD *thd,udf_func *udf)
Ensure that the .dll doesn't have a path
This is done to ensure that only approved dll from the system
directories are used (to make this even remotely secure).
On windows we must check both FN_LIBCHAR and '/'.
*/
if (my_strchr(files_charset_info, udf->dl, udf->dl + strlen(udf->dl), FN_LIBCHAR))
if (my_strchr(files_charset_info, udf->dl,
udf->dl + strlen(udf->dl), FN_LIBCHAR) ||
IF_WIN(my_strchr(files_charset_info, udf->dl,
udf->dl + strlen(udf->dl), '/'), 0))
{
my_message(ER_UDF_NO_PATHS, ER(ER_UDF_NO_PATHS), MYF(0));
DBUG_RETURN(1);
......@@ -422,7 +434,9 @@ int mysql_create_function(THD *thd,udf_func *udf)
}
if (!(dl = find_udf_dl(udf->dl)))
{
if (!(dl = dlopen(udf->dl, RTLD_NOW)))
char dlpath[FN_REFLEN];
strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", udf->dl, NullS);
if (!(dl = dlopen(dlpath, RTLD_NOW)))
{
DBUG_PRINT("error",("dlopen of %s failed, error: %d (%s)",
udf->dl, errno, dlerror()));
......
......@@ -31,6 +31,14 @@ static handler *blackhole_create_handler(handlerton *hton,
}
/* Static declarations for shared structures */
static pthread_mutex_t blackhole_mutex;
static HASH blackhole_open_tables;
static st_blackhole_share *get_share(const char *table_name);
static void free_share(st_blackhole_share *share);
/*****************************************************************************
** BLACKHOLE tables
*****************************************************************************/
......@@ -53,15 +61,18 @@ const char **ha_blackhole::bas_ext() const
int ha_blackhole::open(const char *name, int mode, uint test_if_locked)
{
DBUG_ENTER("ha_blackhole::open");
thr_lock_init(&thr_lock);
thr_lock_data_init(&thr_lock,&lock,NULL);
if (!(share= get_share(name)))
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
thr_lock_data_init(&share->lock, &lock, NULL);
DBUG_RETURN(0);
}
int ha_blackhole::close(void)
{
DBUG_ENTER("ha_blackhole::close");
thr_lock_delete(&thr_lock);
free_share(share);
DBUG_RETURN(0);
}
......@@ -136,17 +147,39 @@ int ha_blackhole::external_lock(THD *thd, int lock_type)
}
uint ha_blackhole::lock_count(void) const
{
DBUG_ENTER("ha_blackhole::lock_count");
DBUG_RETURN(0);
}
THR_LOCK_DATA **ha_blackhole::store_lock(THD *thd,
THR_LOCK_DATA **to,
enum thr_lock_type lock_type)
{
DBUG_ENTER("ha_blackhole::store_lock");
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK)
{
/*
Here is where we get into the guts of a row level lock.
If TL_UNLOCK is set
If we are not doing a LOCK TABLE or DISCARD/IMPORT
TABLESPACE, then allow multiple writers
*/
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT &&
lock_type <= TL_WRITE) && !thd_in_lock_tables(thd)
&& !thd_tablespace_op(thd))
lock_type = TL_WRITE_ALLOW_WRITE;
/*
In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
would conflict with TL_WRITE_ALLOW_WRITE, blocking all inserts
to t2. Convert the lock to a normal read lock to allow
concurrent inserts to t2.
*/
if (lock_type == TL_READ_NO_INSERT && !thd_in_lock_tables(thd))
lock_type = TL_READ;
lock.type= lock_type;
}
*to++= &lock;
DBUG_RETURN(to);
}
......@@ -204,6 +237,63 @@ int ha_blackhole::index_last(byte * buf)
DBUG_RETURN(HA_ERR_END_OF_FILE);
}
static st_blackhole_share *get_share(const char *table_name)
{
st_blackhole_share *share;
uint length;
length= (uint) strlen(table_name);
pthread_mutex_lock(&blackhole_mutex);
if (!(share= (st_blackhole_share*) hash_search(&blackhole_open_tables,
(byte*) table_name, length)))
{
if (!(share= (st_blackhole_share*) my_malloc(sizeof(st_blackhole_share) +
length,
MYF(MY_WME | MY_ZEROFILL))))
goto error;
share->table_name_length= length;
strmov(share->table_name, table_name);
if (my_hash_insert(&blackhole_open_tables, (byte*) share))
{
my_free((gptr) share, MYF(0));
share= NULL;
goto error;
}
thr_lock_init(&share->lock);
}
share->use_count++;
error:
pthread_mutex_unlock(&blackhole_mutex);
return share;
}
static void free_share(st_blackhole_share *share)
{
pthread_mutex_lock(&blackhole_mutex);
if (!--share->use_count)
hash_delete(&blackhole_open_tables, (byte*) share);
pthread_mutex_unlock(&blackhole_mutex);
}
static void blackhole_free_key(st_blackhole_share *share)
{
thr_lock_delete(&share->lock);
my_free((gptr) share, MYF(0));
}
static byte* blackhole_get_key(st_blackhole_share *share, uint *length,
my_bool not_used __attribute__((unused)))
{
*length= share->table_name_length;
return (byte*) share->table_name;
}
static int blackhole_init(void *p)
{
handlerton *blackhole_hton;
......@@ -212,6 +302,20 @@ static int blackhole_init(void *p)
blackhole_hton->db_type= DB_TYPE_BLACKHOLE_DB;
blackhole_hton->create= blackhole_create_handler;
blackhole_hton->flags= HTON_CAN_RECREATE;
VOID(pthread_mutex_init(&blackhole_mutex, MY_MUTEX_INIT_FAST));
(void) hash_init(&blackhole_open_tables, system_charset_info,32,0,0,
(hash_get_key) blackhole_get_key,
(hash_free_key) blackhole_free_key, 0);
return 0;
}
static int blackhole_fini(void *p)
{
hash_free(&blackhole_open_tables);
pthread_mutex_destroy(&blackhole_mutex);
return 0;
}
......@@ -227,7 +331,7 @@ mysql_declare_plugin(blackhole)
"/dev/null storage engine (anything you write to it disappears)",
PLUGIN_LICENSE_GPL,
blackhole_init, /* Plugin Init */
NULL, /* Plugin Deinit */
blackhole_fini, /* Plugin Deinit */
0x0100 /* 1.0 */,
NULL, /* status variables */
NULL, /* system variables */
......
......@@ -17,6 +17,17 @@
#pragma interface /* gcc class implementation */
#endif
/*
Shared structure for correct LOCK operation
*/
struct st_blackhole_share {
THR_LOCK lock;
uint use_count;
uint table_name_length;
char table_name[1];
};
/*
Class definition for the blackhole storage engine
"Dumbest named feature ever"
......@@ -24,7 +35,7 @@
class ha_blackhole: public handler
{
THR_LOCK_DATA lock; /* MySQL lock */
THR_LOCK thr_lock;
st_blackhole_share *share;
public:
ha_blackhole(handlerton *hton, TABLE_SHARE *table_arg);
......@@ -76,7 +87,6 @@ class ha_blackhole: public handler
void position(const byte *record);
int info(uint flag);
int external_lock(THD *thd, int lock_type);
uint lock_count(void) const;
int create(const char *name, TABLE *table_arg,
HA_CREATE_INFO *create_info);
THR_LOCK_DATA **store_lock(THD *thd,
......
......@@ -1263,6 +1263,7 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
ulonglong map;
TABLE_LIST *table_list= table->pos_in_table_list;
my_bool ignore_leaves= table_list->ignore_leaves;
char buf[ERRMSGSIZE+20];
DBUG_ENTER("ha_myisam::preload_keys");
......@@ -1294,7 +1295,6 @@ int ha_myisam::preload_keys(THD* thd, HA_CHECK_OPT *check_opt)
errmsg= "Failed to allocate buffer";
break;
default:
char buf[ERRMSGSIZE+20];
my_snprintf(buf, ERRMSGSIZE,
"Failed to read from index file (errno: %d)", my_errno);
errmsg= buf;
......
......@@ -335,7 +335,7 @@ int chk_size(MI_CHECK *param, register MI_INFO *info)
flush_key_blocks(info->s->key_cache,
info->s->kfile, FLUSH_FORCE_WRITE);
size=my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0));
size= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE));
if ((skr=(my_off_t) info->state->key_file_length) != size)
{
/* Don't give error if file generated by myisampack */
......@@ -595,7 +595,8 @@ static int chk_index_down(MI_CHECK *param, MI_INFO *info, MI_KEYDEF *keyinfo,
{
/* purecov: begin tested */
/* Give it a chance to fit in the real file size. */
my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(0));
my_off_t max_length= my_seek(info->s->kfile, 0L, MY_SEEK_END,
MYF(MY_THREADSAFE));
mi_check_print_error(param, "Invalid key block position: %s "
"key block size: %u file_length: %s",
llstr(page, llbuff), keyinfo->block_length,
......@@ -4080,10 +4081,10 @@ int test_if_almost_full(MI_INFO *info)
{
if (info->s->options & HA_OPTION_COMPRESS_RECORD)
return 0;
return (my_seek(info->s->kfile,0L,MY_SEEK_END,MYF(0))/10*9 >
(my_off_t) (info->s->base.max_key_file_length) ||
my_seek(info->dfile,0L,MY_SEEK_END,MYF(0))/10*9 >
(my_off_t) info->s->base.max_data_file_length);
return my_seek(info->s->kfile, 0L, MY_SEEK_END, MYF(MY_THREADSAFE)) / 10 * 9 >
(my_off_t) info->s->base.max_key_file_length ||
my_seek(info->dfile, 0L, MY_SEEK_END, MYF(0)) / 10 * 9 >
(my_off_t) info->s->base.max_data_file_length;
}
/* Recreate table with bigger more alloced record-data */
......
......@@ -55,12 +55,17 @@ int mi_preload(MI_INFO *info, ulonglong key_map, my_bool ignore_leaves)
block_length= keyinfo[0].block_length;
if (ignore_leaves)
{
/* Check whether all indexes use the same block size */
for (i= 1 ; i < keys ; i++)
{
if (keyinfo[i].block_length != block_length)
DBUG_RETURN(my_errno= HA_ERR_NON_UNIQUE_BLOCK_SIZE);
}
}
else
block_length= share->key_cache->key_cache_block_size;
length= info->preload_buff_size/block_length * block_length;
set_if_bigger(length, block_length);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment