summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <Sinisa@sinisa.nasamreza.org>2002-10-30 16:52:12 +0200
committerunknown <Sinisa@sinisa.nasamreza.org>2002-10-30 16:52:12 +0200
commita30e284f6f5c0de8b44c5e1d195f6b2aaf7ee806 (patch)
treef019642072be903fd4c5606696e7df32356c28f0
parentd51b72cac30e5d02fde6e9c98c3e91716b19ed04 (diff)
downloadmariadb-git-a30e284f6f5c0de8b44c5e1d195f6b2aaf7ee806.tar.gz
changes for mysqladmin debug
and a bug fix for derived tables include/thr_lock.h: changes for mysqladmin debug mysys/thr_lock.c: changes for mysqladmin debug sql/lock.cc: changes for mysqladmin debug sql/sql_derived.cc: bug fix for derived .. sql/sql_parse.cc: bug fix for derived sql/sql_test.cc: changes for mysqladmin debug
-rw-r--r--include/thr_lock.h4
-rw-r--r--mysys/thr_lock.c8
-rw-r--r--sql/lock.cc11
-rw-r--r--sql/sql_derived.cc3
-rw-r--r--sql/sql_parse.cc10
-rw-r--r--sql/sql_test.cc94
6 files changed, 122 insertions, 8 deletions
diff --git a/include/thr_lock.h b/include/thr_lock.h
index 7459849cb04..cf5b0cce4bc 100644
--- a/include/thr_lock.h
+++ b/include/thr_lock.h
@@ -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);
diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c
index 0288c7c1cbe..c796bd1956a 100644
--- a/mysys/thr_lock.c
+++ b/mysys/thr_lock.c
@@ -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));
diff --git a/sql/lock.cc b/sql/lock.cc
index aed0e1988ea..3b2444c8e9d 100644
--- a/sql/lock.cc
+++ b/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;
}
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 81eade6edb7..9cc83a3835a 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -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 ...
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ae32cd078f7..0eb7acde9f1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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)) ||
@@ -2777,7 +2781,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;
}
diff --git a/sql/sql_test.cc b/sql/sql_test.cc
index 6ae07417e7d..5aac972e0bb 100644
--- a/sql/sql_test.cc
+++ b/sql/sql_test.cc
@@ -203,6 +203,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 +361,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";