The world's most popular open source database
#include "mysql_priv.h"#include "sql_select.h"#include <hash.h>#include <thr_alarm.h>Include dependency graph for sql_test.cc:

Go to the source code of this file.
Classes | |
| struct | st_debug_lock |
Typedefs | |
| typedef st_debug_lock | TABLE_LOCK_INFO |
Functions | |
| void | print_where (COND *cond, const char *info) |
| void | print_cached_tables (void) |
| void | TEST_filesort (SORT_FIELD *sortorder, uint s_length) |
| void | TEST_join (JOIN *join) |
| void | print_plan (JOIN *join, uint idx, double record_count, double read_time, double current_read_time, const char *info) |
| static int | dl_compare (TABLE_LOCK_INFO *a, TABLE_LOCK_INFO *b) |
| static void | push_locks_into_array (DYNAMIC_ARRAY *ar, THR_LOCK_DATA *data, bool wait, const char *text) |
| static void | display_table_locks (void) |
| static int | print_key_cache_status (const char *name, KEY_CACHE *key_cache) |
| void | mysql_print_status () |
Variables | |
| static const char * | lock_descriptions [] |
| typedef struct st_debug_lock TABLE_LOCK_INFO |
| static void display_table_locks | ( | void | ) | [static] |
Definition at line 368 of file sql_test.cc.
References delete_dynamic(), dl_compare(), dynamic_element, st_dynamic_array::elements, FALSE, freeze_size(), list(), list_rest, lock, lock_descriptions, my_init_dynamic_array, open_cache, pthread_mutex_lock, pthread_mutex_unlock, push_locks_into_array(), qsort(), qsort_cmp, st_hash::records, THR_LOCK_lock, thr_lock_thread_list, TRUE, and VOID.
Referenced by mysql_print_status().
00369 { 00370 LIST *list; 00371 DYNAMIC_ARRAY saved_table_locks; 00372 00373 VOID(my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO),open_cache.records + 20,50)); 00374 VOID(pthread_mutex_lock(&THR_LOCK_lock)); 00375 for (list= thr_lock_thread_list; list; list= list_rest(list)) 00376 { 00377 THR_LOCK *lock=(THR_LOCK*) list->data; 00378 00379 VOID(pthread_mutex_lock(&lock->mutex)); 00380 push_locks_into_array(&saved_table_locks, lock->write.data, FALSE, 00381 "Locked - write"); 00382 push_locks_into_array(&saved_table_locks, lock->write_wait.data, TRUE, 00383 "Waiting - write"); 00384 push_locks_into_array(&saved_table_locks, lock->read.data, FALSE, 00385 "Locked - read"); 00386 push_locks_into_array(&saved_table_locks, lock->read_wait.data, TRUE, 00387 "Waiting - read"); 00388 VOID(pthread_mutex_unlock(&lock->mutex)); 00389 } 00390 VOID(pthread_mutex_unlock(&THR_LOCK_lock)); 00391 if (!saved_table_locks.elements) goto end; 00392 00393 qsort((gptr) dynamic_element(&saved_table_locks,0,TABLE_LOCK_INFO *),saved_table_locks.elements,sizeof(TABLE_LOCK_INFO),(qsort_cmp) dl_compare); 00394 freeze_size(&saved_table_locks); 00395 00396 puts("\nThread database.table_name Locked/Waiting Lock_type\n"); 00397 00398 unsigned int i; 00399 for (i=0 ; i < saved_table_locks.elements ; i++) 00400 { 00401 TABLE_LOCK_INFO *dl_ptr=dynamic_element(&saved_table_locks,i,TABLE_LOCK_INFO*); 00402 printf("%-8ld%-28.28s%-22s%s\n", 00403 dl_ptr->thread_id,dl_ptr->table_name,dl_ptr->lock_text,lock_descriptions[(int)dl_ptr->type]); 00404 } 00405 puts("\n\n"); 00406 end: 00407 delete_dynamic(&saved_table_locks); 00408 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int dl_compare | ( | TABLE_LOCK_INFO * | a, | |
| TABLE_LOCK_INFO * | b | |||
| ) | [static] |
Definition at line 317 of file sql_test.cc.
References st_debug_lock::thread_id, and st_debug_lock::waiting.
Referenced by display_table_locks().
00318 { 00319 if (a->thread_id > b->thread_id) 00320 return 1; 00321 if (a->thread_id < b->thread_id) 00322 return -1; 00323 if (a->waiting == b->waiting) 00324 return 0; 00325 else if (a->waiting) 00326 return -1; 00327 return 1; 00328 }
Here is the caller graph for this function:

| void mysql_print_status | ( | ) |
Definition at line 448 of file sql_test.cc.
References st_alarm_info::active_alarms, cached_open_tables(), calc_sum_of_all_status(), display_table_locks(), FN_REFLEN, system_status_var::ha_delete_count, system_status_var::ha_read_first_count, system_status_var::ha_read_key_count, system_status_var::ha_read_next_count, system_status_var::ha_read_rnd_count, system_status_var::ha_update_count, system_status_var::ha_write_count, LOCK_status, st_alarm_info::max_used_alarms, my_checkmalloc, my_file_opened, my_getwd(), my_stream_opened, MYF, st_alarm_info::next_alarm_time, system_status_var::opened_tables, print_cached_tables(), print_key_cache_status(), process_key_caches(), pthread_mutex_lock, pthread_mutex_unlock, TERMINATE, thr_alarm_info(), thr_print_locks(), thread_count, thread_stack, and VOID.
Referenced by dispatch_command(), and signal_hand().
00449 { 00450 char current_dir[FN_REFLEN]; 00451 STATUS_VAR tmp; 00452 00453 calc_sum_of_all_status(&tmp); 00454 printf("\nStatus information:\n\n"); 00455 VOID(my_getwd(current_dir, sizeof(current_dir),MYF(0))); 00456 printf("Current dir: %s\n", current_dir); 00457 printf("Running threads: %d Stack size: %ld\n", thread_count, 00458 (long) thread_stack); 00459 thr_print_locks(); // Write some debug info 00460 #ifndef DBUG_OFF 00461 print_cached_tables(); 00462 #endif 00463 /* Print key cache status */ 00464 puts("\nKey caches:"); 00465 process_key_caches(print_key_cache_status); 00466 pthread_mutex_lock(&LOCK_status); 00467 printf("\nhandler status:\n\ 00468 read_key: %10lu\n\ 00469 read_next: %10lu\n\ 00470 read_rnd %10lu\n\ 00471 read_first: %10lu\n\ 00472 write: %10lu\n\ 00473 delete %10lu\n\ 00474 update: %10lu\n", 00475 tmp.ha_read_key_count, 00476 tmp.ha_read_next_count, 00477 tmp.ha_read_rnd_count, 00478 tmp.ha_read_first_count, 00479 tmp.ha_write_count, 00480 tmp.ha_delete_count, 00481 tmp.ha_update_count); 00482 pthread_mutex_unlock(&LOCK_status); 00483 printf("\nTable status:\n\ 00484 Opened tables: %10lu\n\ 00485 Open tables: %10lu\n\ 00486 Open files: %10lu\n\ 00487 Open streams: %10lu\n", 00488 tmp.opened_tables, 00489 (ulong) cached_open_tables(), 00490 (ulong) my_file_opened, 00491 (ulong) my_stream_opened); 00492 00493 ALARM_INFO alarm_info; 00494 #ifndef DONT_USE_THR_ALARM 00495 thr_alarm_info(&alarm_info); 00496 printf("\nAlarm status:\n\ 00497 Active alarms: %u\n\ 00498 Max used alarms: %u\n\ 00499 Next alarm time: %lu\n", 00500 alarm_info.active_alarms, 00501 alarm_info.max_used_alarms, 00502 alarm_info.next_alarm_time); 00503 #endif 00504 display_table_locks(); 00505 fflush(stdout); 00506 my_checkmalloc(); 00507 TERMINATE(stdout); // Write malloc information 00508 00509 #ifdef HAVE_MALLINFO 00510 struct mallinfo info= mallinfo(); 00511 printf("\nMemory status:\n\ 00512 Non-mmapped space allocated from system: %d\n\ 00513 Number of free chunks: %d\n\ 00514 Number of fastbin blocks: %d\n\ 00515 Number of mmapped regions: %d\n\ 00516 Space in mmapped regions: %d\n\ 00517 Maximum total allocated space: %d\n\ 00518 Space available in freed fastbin blocks: %d\n\ 00519 Total allocated space: %d\n\ 00520 Total free space: %d\n\ 00521 Top-most, releasable space: %d\n\ 00522 Estimated memory (with thread stack): %ld\n", 00523 (int) info.arena , 00524 (int) info.ordblks, 00525 (int) info.smblks, 00526 (int) info.hblks, 00527 (int) info.hblkhd, 00528 (int) info.usmblks, 00529 (int) info.fsmblks, 00530 (int) info.uordblks, 00531 (int) info.fordblks, 00532 (int) info.keepcost, 00533 (long) (thread_count * thread_stack + info.hblkhd + info.arena)); 00534 #endif 00535 puts(""); 00536 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void print_cached_tables | ( | void | ) |
Definition at line 70 of file sql_test.cc.
References count, hash_check(), hash_element(), lock_descriptions, LOCK_open, st_table::next, open_cache, st_table::prev, pthread_mutex_lock, pthread_mutex_unlock, st_hash::records, refresh_version, unused_tables, and VOID.
Referenced by mysql_print_status().
00071 { 00072 uint idx,count,unused; 00073 TABLE *start_link,*lnk; 00074 00075 VOID(pthread_mutex_lock(&LOCK_open)); 00076 puts("DB Table Version Thread L.thread Open Lock"); 00077 00078 for (idx=unused=0 ; idx < open_cache.records ; idx++) 00079 { 00080 TABLE *entry=(TABLE*) hash_element(&open_cache,idx); 00081 printf("%-14.14s %-32s%6ld%8ld%10ld%6d %s\n", 00082 entry->s->db.str, entry->s->table_name.str, entry->s->version, 00083 entry->in_use ? entry->in_use->thread_id : 0L, 00084 entry->in_use ? entry->in_use->dbug_thread_id : 0L, 00085 entry->db_stat ? 1 : 0, entry->in_use ? lock_descriptions[(int)entry->reginfo.lock_type] : "Not in use"); 00086 if (!entry->in_use) 00087 unused++; 00088 } 00089 count=0; 00090 if ((start_link=lnk=unused_tables)) 00091 { 00092 do 00093 { 00094 if (lnk != lnk->next->prev || lnk != lnk->prev->next) 00095 { 00096 printf("unused_links isn't linked properly\n"); 00097 return; 00098 } 00099 } while (count++ < open_cache.records && (lnk=lnk->next) != start_link); 00100 if (lnk != start_link) 00101 { 00102 printf("Unused_links aren't connected\n"); 00103 } 00104 } 00105 if (count != unused) 00106 printf("Unused_links (%d) doesn't match open_cache: %d\n", count,unused); 00107 printf("\nCurrent refresh version: %ld\n",refresh_version); 00108 if (hash_check(&open_cache)) 00109 printf("Error: File hash table is corrupted\n"); 00110 fflush(stdout); 00111 VOID(pthread_mutex_unlock(&LOCK_open)); 00112 return; 00113 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static int print_key_cache_status | ( | const char * | name, | |
| KEY_CACHE * | key_cache | |||
| ) | [static] |
Definition at line 411 of file sql_test.cc.
References st_key_cache::blocks_used, st_key_cache::global_blocks_changed, st_key_cache::global_cache_r_requests, st_key_cache::global_cache_read, st_key_cache::global_cache_w_requests, st_key_cache::global_cache_write, st_key_cache::key_cache_inited, llstr(), st_key_cache::param_age_threshold, st_key_cache::param_block_size, st_key_cache::param_buff_size, and st_key_cache::param_division_limit.
Referenced by mysql_print_status().
00412 { 00413 char llbuff1[22]; 00414 char llbuff2[22]; 00415 char llbuff3[22]; 00416 char llbuff4[22]; 00417 00418 if (!key_cache->key_cache_inited) 00419 { 00420 printf("%s: Not in use\n", name); 00421 } 00422 else 00423 { 00424 printf("%s\n\ 00425 Buffer_size: %10lu\n\ 00426 Block_size: %10lu\n\ 00427 Division_limit: %10lu\n\ 00428 Age_limit: %10lu\n\ 00429 blocks used: %10lu\n\ 00430 not flushed: %10lu\n\ 00431 w_requests: %10s\n\ 00432 writes: %10s\n\ 00433 r_requests: %10s\n\ 00434 reads: %10s\n\n", 00435 name, 00436 (ulong) key_cache->param_buff_size, key_cache->param_block_size, 00437 key_cache->param_division_limit, key_cache->param_age_threshold, 00438 key_cache->blocks_used,key_cache->global_blocks_changed, 00439 llstr(key_cache->global_cache_w_requests,llbuff1), 00440 llstr(key_cache->global_cache_write,llbuff2), 00441 llstr(key_cache->global_cache_r_requests,llbuff3), 00442 llstr(key_cache->global_cache_read,llbuff4)); 00443 } 00444 return 0; 00445 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void print_plan | ( | JOIN * | join, | |
| uint | idx, | |||
| double | record_count, | |||
| double | read_time, | |||
| double | current_read_time, | |||
| const char * | info | |||
| ) |
Definition at line 233 of file sql_test.cc.
References JOIN::best_positions, JOIN::best_read, JOIN::best_ref, DBL_MAX, DBUG_FILE, DBUG_LOCK_FILE, DBUG_UNLOCK_FILE, join_table, pos(), JOIN::positions, st_table::s, LEX_STRING::str, and st_table_share::table_name.
Referenced by best_extension_by_limited_search(), and greedy_search().
00235 { 00236 uint i; 00237 POSITION pos; 00238 JOIN_TAB *join_table; 00239 JOIN_TAB **plan_nodes; 00240 TABLE* table; 00241 00242 if (info == 0) 00243 info= ""; 00244 00245 DBUG_LOCK_FILE; 00246 if (join->best_read == DBL_MAX) 00247 { 00248 fprintf(DBUG_FILE, 00249 "%s; idx:%u, best: DBL_MAX, atime: %g, itime: %g, count: %g\n", 00250 info, idx, current_read_time, read_time, record_count); 00251 } 00252 else 00253 { 00254 fprintf(DBUG_FILE, 00255 "%s; idx:%u, best: %g, accumulated: %g, increment: %g, count: %g\n", 00256 info, idx, join->best_read, current_read_time, read_time, record_count); 00257 } 00258 00259 /* Print the tables in JOIN->positions */ 00260 fputs(" POSITIONS: ", DBUG_FILE); 00261 for (i= 0; i < idx ; i++) 00262 { 00263 pos = join->positions[i]; 00264 table= pos.table->table; 00265 if (table) 00266 fputs(table->s->table_name.str, DBUG_FILE); 00267 fputc(' ', DBUG_FILE); 00268 } 00269 fputc('\n', DBUG_FILE); 00270 00271 /* 00272 Print the tables in JOIN->best_positions only if at least one complete plan 00273 has been found. An indicator for this is the value of 'join->best_read'. 00274 */ 00275 if (join->best_read < DBL_MAX) 00276 { 00277 fputs("BEST_POSITIONS: ", DBUG_FILE); 00278 for (i= 0; i < idx ; i++) 00279 { 00280 pos= join->best_positions[i]; 00281 table= pos.table->table; 00282 if (table) 00283 fputs(table->s->table_name.str, DBUG_FILE); 00284 fputc(' ', DBUG_FILE); 00285 } 00286 } 00287 fputc('\n', DBUG_FILE); 00288 00289 /* Print the tables in JOIN->best_ref */ 00290 fputs(" BEST_REF: ", DBUG_FILE); 00291 for (plan_nodes= join->best_ref ; *plan_nodes ; plan_nodes++) 00292 { 00293 join_table= (*plan_nodes); 00294 fputs(join_table->table->s->table_name.str, DBUG_FILE); 00295 fprintf(DBUG_FILE, "(%lu,%lu,%lu)", 00296 (ulong) join_table->found_records, 00297 (ulong) join_table->records, 00298 (ulong) join_table->read_time); 00299 fputc(' ', DBUG_FILE); 00300 } 00301 fputc('\n', DBUG_FILE); 00302 00303 DBUG_UNLOCK_FILE; 00304 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void print_where | ( | COND * | cond, | |
| const char * | info | |||
| ) |
Definition at line 51 of file sql_test.cc.
References String::append(), cond, DBUG_FILE, DBUG_LOCK_FILE, DBUG_UNLOCK_FILE, String::length(), String::ptr(), and system_charset_info.
Referenced by add_not_null_conds(), JOIN::exec(), make_join_select(), JOIN::optimize(), and optimize_cond().
00052 { 00053 if (cond) 00054 { 00055 char buff[256]; 00056 String str(buff,(uint32) sizeof(buff), system_charset_info); 00057 str.length(0); 00058 cond->print(&str); 00059 str.append('\0'); 00060 DBUG_LOCK_FILE; 00061 (void) fprintf(DBUG_FILE,"\nWHERE:(%s) ",info); 00062 (void) fputs(str.ptr(),DBUG_FILE); 00063 (void) fputc('\n',DBUG_FILE); 00064 DBUG_UNLOCK_FILE; 00065 } 00066 }
Here is the call graph for this function:

Here is the caller graph for this function:

| static void push_locks_into_array | ( | DYNAMIC_ARRAY * | ar, | |
| THR_LOCK_DATA * | data, | |||
| bool | wait, | |||
| const char * | text | |||
| ) | [static] |
Definition at line 331 of file sql_test.cc.
References data, st_table::in_use, LEX_STRING::length, st_debug_lock::lock_text, st_reginfo::lock_type, memcpy, NO_TMP_TABLE, push_dynamic, st_table::reginfo, st_table::s, LEX_STRING::str, strlen(), st_table_share::table_cache_key, st_debug_lock::table_name, st_debug_lock::thread_id, st_table_share::tmp_table, st_debug_lock::type, VOID, and st_debug_lock::waiting.
Referenced by display_table_locks().
00333 { 00334 if (data) 00335 { 00336 TABLE *table=(TABLE *)data->debug_print_param; 00337 if (table && table->s->tmp_table == NO_TMP_TABLE) 00338 { 00339 TABLE_LOCK_INFO table_lock_info; 00340 table_lock_info.thread_id= table->in_use->thread_id; 00341 memcpy(table_lock_info.table_name, table->s->table_cache_key.str, 00342 table->s->table_cache_key.length); 00343 table_lock_info.table_name[strlen(table_lock_info.table_name)]='.'; 00344 table_lock_info.waiting=wait; 00345 table_lock_info.lock_text=text; 00346 // lock_type is also obtainable from THR_LOCK_DATA 00347 table_lock_info.type=table->reginfo.lock_type; 00348 VOID(push_dynamic(ar,(gptr) &table_lock_info)); 00349 } 00350 } 00351 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void TEST_filesort | ( | SORT_FIELD * | sortorder, | |
| uint | s_length | |||
| ) |
Definition at line 116 of file sql_test.cc.
References String::append(), DBUG_ENTER, DBUG_FILE, DBUG_LOCK_FILE, DBUG_UNLOCK_FILE, DBUG_VOID_RETURN, String::length(), String::ptr(), system_charset_info, and VOID.
Referenced by filesort().
00117 { 00118 char buff[256],buff2[256]; 00119 String str(buff,sizeof(buff),system_charset_info); 00120 String out(buff2,sizeof(buff2),system_charset_info); 00121 const char *sep; 00122 DBUG_ENTER("TEST_filesort"); 00123 00124 out.length(0); 00125 for (sep=""; s_length-- ; sortorder++, sep=" ") 00126 { 00127 out.append(sep); 00128 if (sortorder->reverse) 00129 out.append('-'); 00130 if (sortorder->field) 00131 { 00132 if (sortorder->field->table_name) 00133 { 00134 out.append(*sortorder->field->table_name); 00135 out.append('.'); 00136 } 00137 out.append(sortorder->field->field_name ? sortorder->field->field_name: 00138 "tmp_table_column"); 00139 } 00140 else 00141 { 00142 str.length(0); 00143 sortorder->item->print(&str); 00144 out.append(str); 00145 } 00146 } 00147 out.append('\0'); // Purify doesn't like c_ptr() 00148 DBUG_LOCK_FILE; 00149 VOID(fputs("\nInfo about FILESORT\n",DBUG_FILE)); 00150 fprintf(DBUG_FILE,"Sortorder: %s\n",out.ptr()); 00151 DBUG_UNLOCK_FILE; 00152 DBUG_VOID_RETURN; 00153 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void TEST_join | ( | JOIN * | join | ) |
Definition at line 157 of file sql_test.cc.
References buf, DBUG_ENTER, DBUG_FILE, DBUG_LOCK_FILE, DBUG_UNLOCK_FILE, DBUG_VOID_RETURN, FALSE, JOIN::join_tab, join_type_str, MAX_KEY, st_join_table::table, JOIN::tables, and VOID.
00158 { 00159 uint i,ref; 00160 DBUG_ENTER("TEST_join"); 00161 00162 DBUG_LOCK_FILE; 00163 VOID(fputs("\nInfo about JOIN\n",DBUG_FILE)); 00164 for (i=0 ; i < join->tables ; i++) 00165 { 00166 JOIN_TAB *tab=join->join_tab+i; 00167 TABLE *form=tab->table; 00168 char key_map_buff[128]; 00169 fprintf(DBUG_FILE,"%-16.16s type: %-7s q_keys: %s refs: %d key: %d len: %d\n", 00170 form->alias, 00171 join_type_str[tab->type], 00172 tab->keys.print(key_map_buff), 00173 tab->ref.key_parts, 00174 tab->ref.key, 00175 tab->ref.key_length); 00176 if (tab->select) 00177 { 00178 char buf[MAX_KEY/8+1]; 00179 if (tab->use_quick == 2) 00180 fprintf(DBUG_FILE, 00181 " quick select checked for each record (keys: %s)\n", 00182 tab->select->quick_keys.print(buf)); 00183 else if (tab->select->quick) 00184 { 00185 fprintf(DBUG_FILE, " quick select used:\n"); 00186 tab->select->quick->dbug_dump(18, FALSE); 00187 } 00188 else 00189 VOID(fputs(" select used\n",DBUG_FILE)); 00190 } 00191 if (tab->ref.key_parts) 00192 { 00193 VOID(fputs(" refs: ",DBUG_FILE)); 00194 for (ref=0 ; ref < tab->ref.key_parts ; ref++) 00195 { 00196 Item *item=tab->ref.items[ref]; 00197 fprintf(DBUG_FILE,"%s ", item->full_name()); 00198 } 00199 VOID(fputc('\n',DBUG_FILE)); 00200 } 00201 } 00202 DBUG_UNLOCK_FILE; 00203 DBUG_VOID_RETURN; 00204 }
const char* lock_descriptions[] [static] |
Initial value:
{
"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"
}
Definition at line 31 of file sql_test.cc.
Referenced by display_table_locks(), and print_cached_tables().
1.4.7

