Commit 52521cc8 authored by unknown's avatar unknown

Fixed memory leak with RAID tables

Fixed tests for RAID tables
Detect uninitialized mutexes on lock and destroy


mysql-test/r/raid.result:
  Updated results
mysql-test/r/rpl_change_master.result:
  Update results missing from last patch
mysql-test/t/raid.test:
  Clean up test
mysys/mf_iocache.c:
  Comments
  Small safety fix
mysys/thr_mutex.c:
  Detect uninitialized mutexes on lock and destroy
sql/sql_db.cc:
  Fixed memory leak with RAID tables
parent eaae7147
create database test_raid;
create table test_raid.r1 (i int) raid_type=1;
drop database test_raid;
DROP TABLE IF EXISTS t1,t2; DROP TABLE IF EXISTS t1,t2;
DROP DATABASE IF EXISTS test_$1;
create database test_$1;
create table test_$1.r1 (i int) raid_type=1;
drop database test_$1;
CREATE TABLE t1 ( CREATE TABLE t1 (
id int unsigned not null auto_increment primary key, id int unsigned not null auto_increment primary key,
c char(255) not null c char(255) not null
...@@ -99,7 +100,6 @@ count(*) ...@@ -99,7 +100,6 @@ count(*)
450 450
DROP TABLE t2; DROP TABLE t2;
/* variable rows */ /* variable rows */
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
id int unsigned not null auto_increment primary key, id int unsigned not null auto_increment primary key,
c varchar(255) not null c varchar(255) not null
......
...@@ -15,11 +15,11 @@ select * from t1; ...@@ -15,11 +15,11 @@ select * from t1;
n n
1 1
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root 9306 1 master-bin.000001 273 slave-relay-bin.000002 258 master-bin.000001 No No 0 0 214 317 None 0 No # # 127.0.0.1 root 9306 1 master-bin.000001 273 slave-relay-bin.000002 258 master-bin.000001 No No 0 0 214 317 None 0 No #
change master to master_user='root'; change master to master_user='root';
show slave status; show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
# 127.0.0.1 root 9306 1 master-bin.000001 214 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 214 4 None 0 No # # 127.0.0.1 root 9306 1 master-bin.000001 214 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 214 4 None 0 No #
select release_lock("a"); select release_lock("a");
release_lock("a") release_lock("a")
......
...@@ -9,6 +9,7 @@ enable_query_log; ...@@ -9,6 +9,7 @@ enable_query_log;
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1,t2; DROP TABLE IF EXISTS t1,t2;
DROP DATABASE IF EXISTS test_$1;
--enable_warnings --enable_warnings
# #
...@@ -111,8 +112,8 @@ ALTER TABLE t1 DROP COLUMN x; ...@@ -111,8 +112,8 @@ ALTER TABLE t1 DROP COLUMN x;
ALTER TABLE t1 RENAME t2; ALTER TABLE t1 RENAME t2;
select count(*) from t2; select count(*) from t2;
DROP TABLE t2; DROP TABLE t2;
/* variable rows */ /* variable rows */
DROP TABLE IF EXISTS t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
id int unsigned not null auto_increment primary key, id int unsigned not null auto_increment primary key,
c varchar(255) not null c varchar(255) not null
......
...@@ -110,11 +110,29 @@ init_functions(IO_CACHE* info, enum cache_type type) ...@@ -110,11 +110,29 @@ init_functions(IO_CACHE* info, enum cache_type type)
} }
} }
/*
** if cachesize == 0 then use default cachesize (from s-file) /*
** if file == -1 then real_open_cached_file() will be called. Initialize an IO_CACHE object
** returns 0 if ok
*/ SYNOPSOS
init_io_cache()
info cache handler to initialize
file File that should be associated to to the handler
If == -1 then real_open_cached_file()
will be called when it's time to open file.
cachesize Size of buffer to allocate for read/write
If == 0 then use my_default_record_cache_size
type Type of cache
seek_offset Where cache should start reading/writing
use_async_io Set to 1 of we should use async_io (if avaiable)
cache_myflags Bitmap of differnt flags
MY_WME | MY_FAE | MY_NABP | MY_FNABP |
MY_DONT_CHECK_FILESIZE
RETURN
0 ok
# error
*/
int init_io_cache(IO_CACHE *info, File file, uint cachesize, int init_io_cache(IO_CACHE *info, File file, uint cachesize,
enum cache_type type, my_off_t seek_offset, enum cache_type type, my_off_t seek_offset,
...@@ -127,7 +145,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, ...@@ -127,7 +145,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
(ulong) info, (int) type, (ulong) seek_offset)); (ulong) info, (int) type, (ulong) seek_offset));
info->file= file; info->file= file;
info->type=type; info->type= 0; /* Don't set it until mutex are created */
info->pos_in_file= seek_offset; info->pos_in_file= seek_offset;
info->pre_close = info->pre_read = info->post_read = 0; info->pre_close = info->pre_read = info->post_read = 0;
info->arg = 0; info->arg = 0;
...@@ -138,9 +156,8 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, ...@@ -138,9 +156,8 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
info->share=0; info->share=0;
#endif #endif
if (!cachesize) if (!cachesize && !(cachesize= my_default_record_cache_size))
if (! (cachesize= my_default_record_cache_size)) DBUG_RETURN(1); /* No cache requested */
DBUG_RETURN(1); /* No cache requested */
min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2; min_cache=use_async_io ? IO_SIZE*4 : IO_SIZE*2;
if (type == READ_CACHE || type == SEQ_READ_APPEND) if (type == READ_CACHE || type == SEQ_READ_APPEND)
{ /* Assume file isn't growing */ { /* Assume file isn't growing */
...@@ -201,6 +218,13 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, ...@@ -201,6 +218,13 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST); pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST);
#endif #endif
} }
#if defined(SAFE_MUTEX) && defined(THREAD)
else
{
/* Clear mutex so that safe_mutex will notice that it's not initialized */
bzero((char*) &info->append_buffer_lock, sizeof(info));
}
#endif
if (type == WRITE_CACHE) if (type == WRITE_CACHE)
info->write_end= info->write_end=
...@@ -211,6 +235,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, ...@@ -211,6 +235,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize,
/* End_of_file may be changed by user later */ /* End_of_file may be changed by user later */
info->end_of_file= end_of_file; info->end_of_file= end_of_file;
info->error=0; info->error=0;
info->type= type;
init_functions(info,type); init_functions(info,type);
#ifdef HAVE_AIOWAIT #ifdef HAVE_AIOWAIT
if (use_async_io && ! my_disable_async_io) if (use_async_io && ! my_disable_async_io)
...@@ -1142,6 +1167,22 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock) ...@@ -1142,6 +1167,22 @@ int _flush_io_cache(IO_CACHE *info, int need_append_buffer_lock)
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/*
Free an IO_CACHE object
SYNOPSOS
end_io_cache()
info IO_CACHE Handle to free
NOTES
It's currently safe to call this if one has called io_cache_init()
on the 'info' object, even if io_cache_init() failed.
This function is also safe to call twice with the same handle.
RETURN
0 ok
# Error
*/
int end_io_cache(IO_CACHE *info) int end_io_cache(IO_CACHE *info)
{ {
...@@ -1164,7 +1205,10 @@ int end_io_cache(IO_CACHE *info) ...@@ -1164,7 +1205,10 @@ int end_io_cache(IO_CACHE *info)
#endif #endif
if ((pre_close=info->pre_close)) if ((pre_close=info->pre_close))
{
(*pre_close)(info); (*pre_close)(info);
info->pre_close= 0;
}
if (info->alloced_buffer) if (info->alloced_buffer)
{ {
info->alloced_buffer=0; info->alloced_buffer=0;
......
...@@ -97,10 +97,12 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line) ...@@ -97,10 +97,12 @@ int safe_mutex_lock(safe_mutex_t *mp,const char *file, uint line)
int error; int error;
if (!mp->file) if (!mp->file)
{ {
fprintf(stderr,"safe_mutex: Trying to lock unitialized mutex at %s, line %d", file, line); fprintf(stderr,
"safe_mutex: Trying to lock unitialized mutex at %s, line %d\n",
file, line);
fflush(stderr); fflush(stderr);
abort(); abort();
} }
pthread_mutex_lock(&mp->global); pthread_mutex_lock(&mp->global);
if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread)) if (mp->count > 0 && pthread_equal(pthread_self(),mp->thread))
...@@ -262,6 +264,14 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp, ...@@ -262,6 +264,14 @@ int safe_cond_timedwait(pthread_cond_t *cond, safe_mutex_t *mp,
int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line) int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line)
{ {
int error=0; int error=0;
if (!mp->file)
{
fprintf(stderr,
"safe_mutex: Trying to destroy unitialized mutex at %s, line %d\n",
file, line);
fflush(stderr);
abort();
}
if (mp->count != 0) if (mp->count != 0)
{ {
fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n", fprintf(stderr,"safe_mutex: Trying to destroy a mutex that was locked at %s, line %d at %s, line %d\n",
......
...@@ -440,7 +440,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, ...@@ -440,7 +440,6 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
char filePath[FN_REFLEN]; char filePath[FN_REFLEN];
TABLE_LIST *tot_list=0, **tot_list_next; TABLE_LIST *tot_list=0, **tot_list_next;
List<String> raid_dirs; List<String> raid_dirs;
DBUG_ENTER("mysql_rm_known_files"); DBUG_ENTER("mysql_rm_known_files");
DBUG_PRINT("enter",("path: %s", org_path)); DBUG_PRINT("enter",("path: %s", org_path));
...@@ -516,17 +515,24 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, ...@@ -516,17 +515,24 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db,
deleted++; deleted++;
} }
} }
List_iterator<String> it(raid_dirs);
String *dir;
if (thd->killed || if (thd->killed ||
(tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 0, 1))) (tot_list && mysql_rm_table_part2_with_lock(thd, tot_list, 1, 0, 1)))
{ {
/* Free memory for allocated raid dirs */
while ((dir= it++))
delete dir;
my_dirend(dirp); my_dirend(dirp);
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
List_iterator<String> it(raid_dirs);
String *dir;
while ((dir= it++)) while ((dir= it++))
{
if (rmdir(dir->c_ptr()) < 0) if (rmdir(dir->c_ptr()) < 0)
found_other_files++; found_other_files++;
delete dir;
}
my_dirend(dirp); my_dirend(dirp);
/* /*
......
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