Commit 27561841 authored by sasha@mysql.sashanet.com's avatar sasha@mysql.sashanet.com

merged latest changes in 3.23

parents 6bedc859 cc35643e
This diff is collapsed.
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#define RPL_LOG_NAME (glob_mi.log_file_name[0] ? glob_mi.log_file_name :\ #define RPL_LOG_NAME (glob_mi.log_file_name[0] ? glob_mi.log_file_name :\
"FIRST") "FIRST")
bool slave_running = 0; volatile bool slave_running = 0;
pthread_t slave_real_id; pthread_t slave_real_id;
MASTER_INFO glob_mi; MASTER_INFO glob_mi;
HASH replicate_do_table, replicate_ignore_table; HASH replicate_do_table, replicate_ignore_table;
......
...@@ -98,8 +98,7 @@ int init_master_info(MASTER_INFO* mi); ...@@ -98,8 +98,7 @@ int init_master_info(MASTER_INFO* mi);
void end_master_info(MASTER_INFO* mi); void end_master_info(MASTER_INFO* mi);
extern bool opt_log_slave_updates ; extern bool opt_log_slave_updates ;
pthread_handler_decl(handle_slave,arg); pthread_handler_decl(handle_slave,arg);
extern bool volatile abort_loop, abort_slave; extern bool volatile abort_loop, abort_slave, slave_running;
extern bool slave_running;
extern uint32 slave_skip_counter; extern uint32 slave_skip_counter;
// needed for problems when slave stops and // needed for problems when slave stops and
// we want to restart it skipping one or more events in the master log that // we want to restart it skipping one or more events in the master log that
......
...@@ -34,6 +34,8 @@ HASH open_cache; /* Used by mysql_test */ ...@@ -34,6 +34,8 @@ HASH open_cache; /* Used by mysql_test */
static int open_unireg_entry(THD *thd,TABLE *entry,const char *db, static int open_unireg_entry(THD *thd,TABLE *entry,const char *db,
const char *name, const char *alias, bool locked); const char *name, const char *alias, bool locked);
static bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
const char *table_name, List_iterator<Item> *it);
static void free_cache_entry(TABLE *entry); static void free_cache_entry(TABLE *entry);
static void mysql_rm_tmp_tables(void); static void mysql_rm_tmp_tables(void);
static key_map get_key_map_from_key_list(TABLE *table, static key_map get_key_map_from_key_list(TABLE *table,
...@@ -109,71 +111,75 @@ static void check_unused(void) ...@@ -109,71 +111,75 @@ static void check_unused(void)
#define check_unused() #define check_unused()
#endif #endif
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) int list_open_tables(THD *thd,List<char> *tables, const char *db,
const char *wild)
{ {
int result = 0; int result = 0;
uint col_access=thd->col_access; uint col_access=thd->col_access;
OPEN_TABLE_LIST **start_list, *open_list;
TABLE_LIST table_list; TABLE_LIST table_list;
char name[NAME_LEN*2];
DBUG_ENTER("list_open_tables"); DBUG_ENTER("list_open_tables");
VOID(pthread_mutex_lock(&LOCK_open)); VOID(pthread_mutex_lock(&LOCK_open));
bzero((char*) &table_list,sizeof(table_list)); bzero((char*) &table_list,sizeof(table_list));
start_list= &open_list;
open_list=0;
for (uint idx=0 ; result == 0 && idx < open_cache.records; idx++) for (uint idx=0 ; idx < open_cache.records; idx++)
{ {
OPEN_TABLE_LIST *table;
TABLE *entry=(TABLE*) hash_element(&open_cache,idx); TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
if ((!entry->real_name) || strcmp(entry->table_cache_key,db))
if ((!entry->real_name)) continue;
continue; // Shouldn't happen if (wild && wild[0] && wild_compare(entry->real_name,wild))
if (wild) continue;
if (db && !(col_access & TABLE_ACLS))
{ {
strxmov(name,entry->table_cache_key,".",entry->real_name,NullS); table_list.db= (char*) db;
if (wild_compare(name,wild)) table_list.real_name= entry->real_name;/*real name*/
table_list.grant.privilege=col_access;
if (check_grant(thd,TABLE_ACLS,&table_list,1))
continue; continue;
} }
/* need to check if he have't already listed it */
/* Check if user has SELECT privilege for any column in the table */ List_iterator<char> it(*tables);
table_list.db= (char*) entry->table_cache_key; char *table_name;
table_list.real_name= entry->real_name; int check = 0;
table_list.grant.privilege=0; while (check == 0 && (table_name=it++))
if (check_table_access(thd,SELECT_ACL | EXTRA_ACL,&table_list))
continue;
/* need to check if we haven't already listed it */
for (table= open_list ; table ; table=table->next)
{ {
if (!strcmp(table->table,entry->real_name) && if (!strcmp(table_name,entry->real_name))
!strcmp(table->db,entry->table_cache_key)) check++;
{
if (entry->in_use)
table->in_use++;
if (entry->locked_by_name)
table->locked++;
break;
}
} }
if (table) if (check)
continue; continue;
if (!(*start_list = (OPEN_TABLE_LIST *)
sql_alloc(sizeof(OPEN_TABLE_LIST)+entry->key_length))) if (tables->push_back(thd->strdup(entry->real_name)))
{ {
open_list=0; // Out of memory result = -1;
break; break;
} }
(*start_list)->table=(strmov((*start_list)->db=(char*) ((*start_list)+1),
entry->table_cache_key)+1,
entry->real_name);
(*start_list)->in_use= entry->in_use ? 1 : 0;
(*start_list)->locked= entry->locked_by_name ? 1 : 0;
start_list= &(*start_list)->next;
} }
VOID(pthread_mutex_unlock(&LOCK_open)); VOID(pthread_mutex_unlock(&LOCK_open));
DBUG_RETURN(open_list); DBUG_RETURN(result);
}
char*
query_table_status(THD *thd,const char *db,const char *table_name)
{
int cached = 0, in_use = 0;
char info[256];
for (uint idx=0 ; idx < open_cache.records; idx++)
{
TABLE *entry=(TABLE*) hash_element(&open_cache,idx);
if (strcmp(entry->table_cache_key,db) ||
strcmp(entry->real_name,table_name))
continue;
cached++;
if (entry->in_use)
in_use++;
}
sprintf(info, "cached=%d, in_use=%d", cached, in_use);
return thd->strdup(info);
} }
...@@ -253,7 +259,7 @@ send_fields(THD *thd,List<Item> &list,uint flag) ...@@ -253,7 +259,7 @@ send_fields(THD *thd,List<Item> &list,uint flag)
if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length())) if (my_net_write(&thd->net, (char*) packet->ptr(),packet->length()))
break; /* purecov: inspected */ break; /* purecov: inspected */
} }
send_eof(&thd->net); send_eof(&thd->net,(test_flags & TEST_MIT_THREAD) ? 0: 1);
return 0; return 0;
err: err:
send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */ send_error(&thd->net,ER_OUT_OF_RESOURCES); /* purecov: inspected */
...@@ -424,34 +430,9 @@ void close_thread_tables(THD *thd, bool locked) ...@@ -424,34 +430,9 @@ void close_thread_tables(THD *thd, bool locked)
DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables)); DBUG_PRINT("info", ("thd->open_tables=%p", thd->open_tables));
while (thd->open_tables) for (table=thd->open_tables ; table ; table=next)
found_old_table|=close_thread_table(thd, &thd->open_tables);
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
check_unused();
if (found_old_table)
{ {
/* Tell threads waiting for refresh that something has happened */ next=table->next;
VOID(pthread_cond_broadcast(&COND_refresh));
}
if (!locked)
VOID(pthread_mutex_unlock(&LOCK_open));
/* VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */
DBUG_VOID_RETURN;
}
/* move one table to free list */
bool close_thread_table(THD *thd, TABLE **table_ptr)
{
DBUG_ENTER("close_thread_table");
bool found_old_table=0;
TABLE *table=*table_ptr;
*table_ptr=table->next;
if (table->version != refresh_version || if (table->version != refresh_version ||
thd->version != refresh_version || !table->db_stat) thd->version != refresh_version || !table->db_stat)
{ {
...@@ -481,7 +462,21 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) ...@@ -481,7 +462,21 @@ bool close_thread_table(THD *thd, TABLE **table_ptr)
else else
unused_tables=table->next=table->prev=table; unused_tables=table->next=table->prev=table;
} }
DBUG_RETURN(found_old_table); }
thd->open_tables=0;
/* Free tables to hold down open files */
while (open_cache.records > table_cache_size && unused_tables)
VOID(hash_delete(&open_cache,(byte*) unused_tables)); /* purecov: tested */
check_unused();
if (found_old_table)
{
/* Tell threads waiting for refresh that something has happened */
VOID(pthread_cond_broadcast(&COND_refresh));
}
if (!locked)
VOID(pthread_mutex_unlock(&LOCK_open));
/* VOID(pthread_sigmask(SIG_SETMASK,&thd->signals,NULL)); */
DBUG_VOID_RETURN;
} }
/* Close and delete temporary tables */ /* Close and delete temporary tables */
...@@ -1837,7 +1832,7 @@ static key_map get_key_map_from_key_list(TABLE *table, ...@@ -1837,7 +1832,7 @@ static key_map get_key_map_from_key_list(TABLE *table,
** Returns pointer to last inserted field if ok ** Returns pointer to last inserted field if ok
****************************************************************************/ ****************************************************************************/
bool static bool
insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
const char *table_name, List_iterator<Item> *it) const char *table_name, List_iterator<Item> *it)
{ {
......
...@@ -95,34 +95,38 @@ mysqld_show_dbs(THD *thd,const char *wild) ...@@ -95,34 +95,38 @@ mysqld_show_dbs(THD *thd,const char *wild)
** List all open tables in a database ** List all open tables in a database
***************************************************************************/ ***************************************************************************/
int mysqld_show_open_tables(THD *thd,const char *wild) int mysqld_show_open_tables(THD *thd,const char *db,const char *wild)
{ {
Item_string *field=new Item_string("",0);
List<Item> field_list; List<Item> field_list;
OPEN_TABLE_LIST *open_list; char *end,*table_name;
CONVERT *convert=thd->convert_set; List<char> tables;
DBUG_ENTER("mysqld_show_open_tables"); DBUG_ENTER("mysqld_show_open_tables");
field_list.push_back(new Item_empty_string("Database",NAME_LEN)); field->name=(char*) thd->alloc(20+(uint) strlen(db)+(wild ? (uint) strlen(wild)+4:0));
field_list.push_back(new Item_empty_string("Table",NAME_LEN)); end=strxmov(field->name,"Open_tables_in_",db,NullS);
field_list.push_back(new Item_int("In_use",0, 4)); if (wild && wild[0])
field_list.push_back(new Item_int("Name_locked",0, 4)); strxmov(end," (",wild,")",NullS);
field->max_length=NAME_LEN;
field_list.push_back(field);
field_list.push_back(new Item_empty_string("Comment",80));
if (send_fields(thd,field_list,1)) if (send_fields(thd,field_list,1))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!(open_list=list_open_tables(thd,wild))) if (list_open_tables(thd,&tables,db,wild))
DBUG_RETURN(-1); DBUG_RETURN(-1);
for ( ; open_list ; open_list=open_list->next) List_iterator<char> it(tables);
while ((table_name=it++))
{ {
thd->packet.length(0); thd->packet.length(0);
net_store_data(&thd->packet,convert, open_list->db); net_store_data(&thd->packet,table_name);
net_store_data(&thd->packet,convert, open_list->table); net_store_data(&thd->packet,query_table_status(thd,db,table_name));
net_store_data(&thd->packet,open_list->in_use);
net_store_data(&thd->packet,open_list->locked);
if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length())) if (my_net_write(&thd->net,(char*) thd->packet.ptr(),thd->packet.length()))
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
send_eof(&thd->net); send_eof(&thd->net);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
......
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