mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 21:42:35 +01:00
Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/work-in-4.1
This commit is contained in:
commit
0e72864211
9 changed files with 150 additions and 26 deletions
|
@ -513,3 +513,6 @@ innobase/stamp-h1
|
|||
myisam/rt_test.MYD
|
||||
myisam/rt_test.MYI
|
||||
stamp-h1
|
||||
libmysqld/sql_help.cc
|
||||
scripts/fill_func_tables
|
||||
scripts/fill_func_tables.sql
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct st_thr_lock_data {
|
|||
enum thr_lock_type type;
|
||||
ulong thread_id;
|
||||
void *status_param; /* Param to status functions */
|
||||
void *debug_print_param;
|
||||
} THR_LOCK_DATA;
|
||||
|
||||
struct st_lock_list {
|
||||
|
@ -97,6 +98,9 @@ typedef struct st_thr_lock {
|
|||
} THR_LOCK;
|
||||
|
||||
|
||||
extern LIST *thr_lock_thread_list;
|
||||
extern pthread_mutex_t THR_LOCK_lock;
|
||||
|
||||
my_bool init_thr_lock(void); /* Must be called once/thread */
|
||||
void thr_lock_init(THR_LOCK *lock);
|
||||
void thr_lock_delete(THR_LOCK *lock);
|
||||
|
|
|
@ -18,3 +18,9 @@ a y
|
|||
3 3
|
||||
3 3
|
||||
drop table if exists t1.t2,t3;
|
||||
select * from (select 1);
|
||||
1
|
||||
1
|
||||
select a from (select 1 as a);
|
||||
a
|
||||
1
|
||||
|
|
|
@ -9,3 +9,5 @@ CREATE TABLE t3 (a int not null, b char (10) not null);
|
|||
insert into t3 values (3,'f'),(4,'y'),(5,'z'),(6,'c');
|
||||
select t1.a,t4.y from t1,(select t2.a as y from t2,(select t3.b from t3 where t3.a>3) as t5 where t2.b=t5.b) as t4 where t1.a = t4.y;
|
||||
drop table if exists t1.t2,t3;
|
||||
select * from (select 1);
|
||||
select a from (select 1 as a);
|
||||
|
|
|
@ -91,7 +91,7 @@ enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
|
|||
#define MAX_LOCKS 100
|
||||
|
||||
|
||||
static LIST *thread_list; /* List of threads in use */
|
||||
LIST *thr_lock_thread_list; /* List of threads in use */
|
||||
ulong max_write_lock_count= ~(ulong) 0L;
|
||||
|
||||
static inline pthread_cond_t *get_cond(void)
|
||||
|
@ -307,7 +307,7 @@ void thr_lock_init(THR_LOCK *lock)
|
|||
|
||||
pthread_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */
|
||||
lock->list.data=(void*) lock;
|
||||
thread_list=list_add(thread_list,&lock->list);
|
||||
thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list);
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ void thr_lock_delete(THR_LOCK *lock)
|
|||
DBUG_ENTER("thr_lock_delete");
|
||||
VOID(pthread_mutex_destroy(&lock->mutex));
|
||||
pthread_mutex_lock(&THR_LOCK_lock);
|
||||
thread_list=list_delete(thread_list,&lock->list);
|
||||
thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
|
||||
pthread_mutex_unlock(&THR_LOCK_lock);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
@ -1061,7 +1061,7 @@ void thr_print_locks(void)
|
|||
|
||||
pthread_mutex_lock(&THR_LOCK_lock);
|
||||
puts("Current locks:");
|
||||
for (list=thread_list ; list && count++ < MAX_THREADS ; list=rest(list))
|
||||
for (list=thr_lock_thread_list ; list && count++ < MAX_THREADS ; list=rest(list))
|
||||
{
|
||||
THR_LOCK *lock=(THR_LOCK*) list->data;
|
||||
VOID(pthread_mutex_lock(&lock->mutex));
|
||||
|
|
11
sql/lock.cc
11
sql/lock.cc
|
@ -69,6 +69,12 @@ TODO:
|
|||
#include "mysql_priv.h"
|
||||
#include <hash.h>
|
||||
#include <assert.h>
|
||||
#include <ha_myisammrg.h>
|
||||
#ifndef MASTER
|
||||
#include "../srclib/myisammrg/myrg_def.h"
|
||||
#else
|
||||
#include "../myisammrg/myrg_def.h"
|
||||
#endif
|
||||
|
||||
extern HASH open_cache;
|
||||
|
||||
|
@ -154,6 +160,7 @@ retry:
|
|||
sql_lock=0;
|
||||
}
|
||||
}
|
||||
|
||||
thd->lock_time();
|
||||
DBUG_RETURN (sql_lock);
|
||||
}
|
||||
|
@ -410,8 +417,12 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
THR_LOCK_DATA **org_locks = locks;
|
||||
locks=table->file->store_lock(thd, locks, get_old_locks ? TL_IGNORE :
|
||||
lock_type);
|
||||
if (locks)
|
||||
for ( ; org_locks != locks ; org_locks++)
|
||||
(*org_locks)->debug_print_param= (void *) table;
|
||||
}
|
||||
return sql_lock;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
|||
|
||||
if (tables_is_opened || !(res=open_and_lock_tables(thd,tables)))
|
||||
{
|
||||
if (tables && setup_fields(thd,tables,item_list,0,0,1))
|
||||
if (setup_fields(thd,tables,item_list,0,0,1))
|
||||
{
|
||||
res=-1;
|
||||
goto exit;
|
||||
|
@ -113,6 +113,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t,
|
|||
t->table=table;
|
||||
table->derived_select_number= sl->select_number;
|
||||
sl->exclude();
|
||||
t->db= (tables && tables->db && tables->db[0]) ? t->db : thd->db;
|
||||
t->derived=(SELECT_LEX *)0; // just in case ...
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1388,10 +1388,14 @@ mysql_execute_command(THD *thd)
|
|||
for (TABLE_LIST *cursor= tables;
|
||||
cursor;
|
||||
cursor= cursor->next)
|
||||
if (cursor->derived && mysql_derived(thd, lex,
|
||||
if (cursor->derived && (res=mysql_derived(thd, lex,
|
||||
(SELECT_LEX_UNIT *)cursor->derived,
|
||||
cursor, 0))
|
||||
cursor, 0)))
|
||||
{
|
||||
if (res < 0)
|
||||
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
if ((lex->select_lex.next_select_in_list() &&
|
||||
lex->unit.create_total_list(thd, lex, &tables)) ||
|
||||
|
@ -2781,7 +2785,7 @@ check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
|
|||
found=1;
|
||||
}
|
||||
}
|
||||
else if (check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
else if (tables->db && check_access(thd,want_access,tables->db,&tables->grant.privilege,
|
||||
0, no_errors))
|
||||
return TRUE;
|
||||
}
|
||||
|
|
129
sql/sql_test.cc
129
sql/sql_test.cc
|
@ -26,6 +26,23 @@
|
|||
/* Intern key cache variables */
|
||||
extern "C" pthread_mutex_t THR_LOCK_keycache;
|
||||
|
||||
static const char *lock_descriptions[] =
|
||||
{
|
||||
"No lock",
|
||||
"Low priority read lock",
|
||||
"Shared Read lock",
|
||||
"High priority read lock",
|
||||
"Read lock without concurrent inserts",
|
||||
"Write lock that allows other writers",
|
||||
"Write lock, but allow reading",
|
||||
"Concurrent insert lock",
|
||||
"Lock Used by delayed insert",
|
||||
"Low priority write lock",
|
||||
"High priority write lock",
|
||||
"Highest priority write lock"
|
||||
};
|
||||
|
||||
|
||||
#ifndef DBUG_OFF
|
||||
|
||||
void
|
||||
|
@ -45,29 +62,11 @@ print_where(COND *cond,const char *info)
|
|||
DBUG_UNLOCK_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This is for debugging purposes */
|
||||
|
||||
extern HASH open_cache;
|
||||
extern TABLE *unused_tables;
|
||||
|
||||
static const char *lock_descriptions[] =
|
||||
{
|
||||
"No lock",
|
||||
"Low priority read lock",
|
||||
"Shared Read lock",
|
||||
"High priority read lock",
|
||||
"Read lock without concurrent inserts",
|
||||
"Write lock that allows other writers",
|
||||
"Write lock, but allow reading",
|
||||
"Concurrent insert lock",
|
||||
"Lock Used by delayed insert",
|
||||
"Low priority write lock",
|
||||
"High priority write lock",
|
||||
"Highest priority write lock"
|
||||
};
|
||||
|
||||
|
||||
void print_cached_tables(void)
|
||||
{
|
||||
uint idx,count,unused;
|
||||
|
@ -203,6 +202,99 @@ TEST_join(JOIN *join)
|
|||
|
||||
#endif
|
||||
|
||||
typedef struct st_debug_lock
|
||||
{
|
||||
ulong thread_id;
|
||||
char table_name[FN_REFLEN];
|
||||
bool waiting;
|
||||
const char *lock_text;
|
||||
enum thr_lock_type type;
|
||||
} TABLE_LOCK_INFO;
|
||||
|
||||
static int dl_compare(TABLE_LOCK_INFO *a,TABLE_LOCK_INFO *b)
|
||||
{
|
||||
if (a->thread_id > b->thread_id)
|
||||
return 1;
|
||||
if (a->thread_id < b->thread_id)
|
||||
return -1;
|
||||
if (a->waiting == b->waiting)
|
||||
return 0;
|
||||
else if (a->waiting)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void push_locks_into_array(DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, bool wait, const char *text)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
TABLE *table=(TABLE *)data->debug_print_param;
|
||||
if (table && table->tmp_table == NO_TMP_TABLE)
|
||||
{
|
||||
TABLE_LOCK_INFO table_lock_info;
|
||||
table_lock_info.thread_id=table->in_use->thread_id;
|
||||
memcpy(table_lock_info.table_name, table->table_cache_key, table->key_length);
|
||||
table_lock_info.table_name[strlen(table_lock_info.table_name)]='.';
|
||||
table_lock_info.waiting=wait;
|
||||
table_lock_info.lock_text=text;
|
||||
table_lock_info.type=table->reginfo.lock_type; // obtainable also from THR_LOCK_DATA
|
||||
VOID(push_dynamic(ar,(gptr) &table_lock_info));
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
Regarding MERGE tables:
|
||||
|
||||
For now, the best option is to use the common TABLE *pointer for all
|
||||
cases; The drawback is that for MERGE tables we will see many locks
|
||||
for the merge tables even if some of them are for individual tables.
|
||||
|
||||
The way to solve this is to add to 'THR_LOCK' structure a pointer to
|
||||
the filename and use this when printing the data.
|
||||
(We can for now ignore this and just print the same name for all merge
|
||||
table parts; Please add the above as a comment to the display_lock
|
||||
function so that we can easily add this if we ever need this.
|
||||
|
||||
*/
|
||||
|
||||
static void display_table_locks (void)
|
||||
{
|
||||
LIST *list;
|
||||
DYNAMIC_ARRAY saved_table_locks;
|
||||
|
||||
VOID(my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO),open_cache.records + 20,50));
|
||||
VOID(pthread_mutex_lock(&THR_LOCK_lock));
|
||||
for (list=thr_lock_thread_list ; list ; list=rest(list))
|
||||
{
|
||||
THR_LOCK *lock=(THR_LOCK*) list->data;
|
||||
|
||||
VOID(pthread_mutex_lock(&lock->mutex));
|
||||
push_locks_into_array(&saved_table_locks, lock->write.data, false, "Locked - write");
|
||||
push_locks_into_array(&saved_table_locks, lock->write_wait.data, true, "Waiting - write");
|
||||
push_locks_into_array(&saved_table_locks, lock->read.data, false, "Locked - read");
|
||||
push_locks_into_array(&saved_table_locks, lock->read_wait.data, true, "Waiting - read");
|
||||
VOID(pthread_mutex_unlock(&lock->mutex));
|
||||
}
|
||||
VOID(pthread_mutex_unlock(&THR_LOCK_lock));
|
||||
if (!saved_table_locks.elements) goto end;
|
||||
|
||||
qsort((gptr) dynamic_element(&saved_table_locks,0,TABLE_LOCK_INFO *),saved_table_locks.elements,sizeof(TABLE_LOCK_INFO),(qsort_cmp) dl_compare);
|
||||
freeze_size(&saved_table_locks);
|
||||
|
||||
puts("\nThread database.table_name Locked/Waiting Lock_type\n");
|
||||
|
||||
for (uint i=0 ; i < saved_table_locks.elements ; i++)
|
||||
{
|
||||
TABLE_LOCK_INFO *dl_ptr=dynamic_element(&saved_table_locks,i,TABLE_LOCK_INFO*);
|
||||
printf("%-8ld%-28.28s%-22s%s\n",
|
||||
dl_ptr->thread_id,dl_ptr->table_name,dl_ptr->lock_text,lock_descriptions[(int)dl_ptr->type]);
|
||||
}
|
||||
puts("\n\n");
|
||||
end:
|
||||
delete_dynamic(&saved_table_locks);
|
||||
}
|
||||
|
||||
|
||||
void mysql_print_status(THD *thd)
|
||||
{
|
||||
char current_dir[FN_REFLEN];
|
||||
|
@ -268,6 +360,7 @@ Next alarm time: %lu\n",
|
|||
alarm_info.max_used_alarms,
|
||||
alarm_info.next_alarm_time);
|
||||
#endif
|
||||
display_table_locks();
|
||||
fflush(stdout);
|
||||
if (thd)
|
||||
thd->proc_info="malloc";
|
||||
|
|
Loading…
Reference in a new issue