1 | /* Copyright (C) 2009-2017 Kentoku Shiba |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ |
15 | |
16 | #define MYSQL_SERVER 1 |
17 | #include <my_global.h> |
18 | #include "mysql_version.h" |
19 | #include "spd_environ.h" |
20 | #if MYSQL_VERSION_ID < 50500 |
21 | #include "mysql_priv.h" |
22 | #include <mysql/plugin.h> |
23 | #else |
24 | #include "sql_priv.h" |
25 | #include "probes_mysql.h" |
26 | #include "sql_class.h" |
27 | #include "sql_partition.h" |
28 | #include "sql_acl.h" |
29 | #endif |
30 | #include "spd_err.h" |
31 | #include "spd_param.h" |
32 | #include "spd_db_include.h" |
33 | #include "spd_include.h" |
34 | #include "ha_spider.h" |
35 | #include "spd_db_conn.h" |
36 | #include "spd_trx.h" |
37 | #include "spd_conn.h" |
38 | #include "spd_sys_table.h" |
39 | #include "spd_table.h" |
40 | #include "spd_ping_table.h" |
41 | #include "spd_direct_sql.h" |
42 | #include "spd_udf.h" |
43 | #include "spd_malloc.h" |
44 | |
45 | extern bool volatile *spd_abort_loop; |
46 | |
47 | extern handlerton *spider_hton_ptr; |
48 | |
49 | #ifdef HAVE_PSI_INTERFACE |
50 | extern PSI_mutex_key spd_key_mutex_mon_list_caller; |
51 | extern PSI_mutex_key spd_key_mutex_mon_list_receptor; |
52 | extern PSI_mutex_key spd_key_mutex_mon_list_monitor; |
53 | extern PSI_mutex_key spd_key_mutex_mon_list_update_status; |
54 | extern PSI_mutex_key spd_key_mutex_mon_table_cache; |
55 | #endif |
56 | |
57 | HASH *spider_udf_table_mon_list_hash; |
58 | uint spider_udf_table_mon_list_hash_id; |
59 | const char *spider_udf_table_mon_list_hash_func_name; |
60 | const char *spider_udf_table_mon_list_hash_file_name; |
61 | ulong spider_udf_table_mon_list_hash_line_no; |
62 | pthread_mutex_t *spider_udf_table_mon_mutexes; |
63 | pthread_cond_t *spider_udf_table_mon_conds; |
64 | |
65 | pthread_mutex_t spider_mon_table_cache_mutex; |
66 | DYNAMIC_ARRAY spider_mon_table_cache; |
67 | uint spider_mon_table_cache_id; |
68 | const char *spider_mon_table_cache_func_name; |
69 | const char *spider_mon_table_cache_file_name; |
70 | ulong spider_mon_table_cache_line_no; |
71 | volatile ulonglong spider_mon_table_cache_version = 0; |
72 | volatile ulonglong spider_mon_table_cache_version_req = 1; |
73 | |
74 | SPIDER_TABLE_MON_LIST *spider_get_ping_table_mon_list( |
75 | SPIDER_TRX *trx, |
76 | THD *thd, |
77 | spider_string *str, |
78 | uint conv_name_length, |
79 | int link_idx, |
80 | char *static_link_id, |
81 | uint static_link_id_length, |
82 | uint32 server_id, |
83 | bool need_lock, |
84 | int *error_num |
85 | ) { |
86 | uint mutex_hash; |
87 | SPIDER_TABLE_MON_LIST *table_mon_list; |
88 | MEM_ROOT mem_root; |
89 | ulonglong mon_table_cache_version; |
90 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
91 | my_hash_value_type hash_value; |
92 | #endif |
93 | DBUG_ENTER("spider_get_ping_table_mon_list" ); |
94 | if (spider_mon_table_cache_version != spider_mon_table_cache_version_req) |
95 | { |
96 | SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); |
97 | if ((*error_num = spider_init_ping_table_mon_cache(thd, &mem_root, |
98 | need_lock))) |
99 | { |
100 | free_root(&mem_root, MYF(0)); |
101 | goto error; |
102 | } |
103 | free_root(&mem_root, MYF(0)); |
104 | } |
105 | |
106 | mutex_hash = spider_udf_calc_hash(str->c_ptr(), |
107 | spider_param_udf_table_mon_mutex_count()); |
108 | DBUG_PRINT("info" ,("spider hash key=%s" , str->c_ptr())); |
109 | DBUG_PRINT("info" ,("spider hash key length=%u" , str->length())); |
110 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
111 | hash_value = my_calc_hash( |
112 | &spider_udf_table_mon_list_hash[mutex_hash], |
113 | (uchar*) str->c_ptr(), str->length()); |
114 | #endif |
115 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]); |
116 | mon_table_cache_version = (ulonglong) spider_mon_table_cache_version; |
117 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
118 | if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *) |
119 | my_hash_search_using_hash_value( |
120 | &spider_udf_table_mon_list_hash[mutex_hash], hash_value, |
121 | (uchar*) str->c_ptr(), str->length())) || |
122 | table_mon_list->mon_table_cache_version != mon_table_cache_version |
123 | ) |
124 | #else |
125 | if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *) my_hash_search( |
126 | &spider_udf_table_mon_list_hash[mutex_hash], |
127 | (uchar*) str->c_ptr(), str->length())) || |
128 | table_mon_list->mon_table_cache_version != mon_table_cache_version |
129 | ) |
130 | #endif |
131 | { |
132 | if ( |
133 | table_mon_list && |
134 | table_mon_list->mon_table_cache_version != mon_table_cache_version |
135 | ) |
136 | spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list); |
137 | |
138 | if (!(table_mon_list = spider_get_ping_table_tgt(thd, str->c_ptr(), |
139 | conv_name_length, link_idx, static_link_id, static_link_id_length, |
140 | server_id, str, need_lock, error_num))) |
141 | { |
142 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); |
143 | goto error; |
144 | } |
145 | table_mon_list->mutex_hash = mutex_hash; |
146 | table_mon_list->mon_table_cache_version = mon_table_cache_version; |
147 | uint old_elements = |
148 | spider_udf_table_mon_list_hash[mutex_hash].array.max_element; |
149 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
150 | table_mon_list->key_hash_value = hash_value; |
151 | #endif |
152 | #ifdef HASH_UPDATE_WITH_HASH_VALUE |
153 | if (my_hash_insert_with_hash_value( |
154 | &spider_udf_table_mon_list_hash[mutex_hash], |
155 | hash_value, (uchar*) table_mon_list)) |
156 | #else |
157 | if (my_hash_insert(&spider_udf_table_mon_list_hash[mutex_hash], |
158 | (uchar*) table_mon_list)) |
159 | #endif |
160 | { |
161 | spider_ping_table_free_mon_list(table_mon_list); |
162 | *error_num = HA_ERR_OUT_OF_MEM; |
163 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
164 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); |
165 | goto error; |
166 | } |
167 | if (spider_udf_table_mon_list_hash[mutex_hash].array.max_element > |
168 | old_elements) |
169 | { |
170 | spider_alloc_calc_mem(spider_current_trx, |
171 | spider_udf_table_mon_list_hash, |
172 | (spider_udf_table_mon_list_hash[mutex_hash].array.max_element - |
173 | old_elements) * |
174 | spider_udf_table_mon_list_hash[mutex_hash].array.size_of_element); |
175 | } |
176 | } |
177 | table_mon_list->use_count++; |
178 | DBUG_PRINT("info" ,("spider table_mon_list->use_count=%d" , |
179 | table_mon_list->use_count)); |
180 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); |
181 | DBUG_RETURN(table_mon_list); |
182 | |
183 | error: |
184 | DBUG_RETURN(NULL); |
185 | } |
186 | |
187 | void spider_free_ping_table_mon_list( |
188 | SPIDER_TABLE_MON_LIST *table_mon_list |
189 | ) { |
190 | DBUG_ENTER("spider_free_ping_table_mon_list" ); |
191 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[ |
192 | table_mon_list->mutex_hash]); |
193 | table_mon_list->use_count--; |
194 | DBUG_PRINT("info" ,("spider table_mon_list->use_count=%d" , table_mon_list->use_count)); |
195 | if (!table_mon_list->use_count) |
196 | pthread_cond_broadcast(&spider_udf_table_mon_conds[ |
197 | table_mon_list->mutex_hash]); |
198 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[ |
199 | table_mon_list->mutex_hash]); |
200 | DBUG_VOID_RETURN; |
201 | } |
202 | |
203 | void spider_release_ping_table_mon_list_loop( |
204 | uint mutex_hash, |
205 | SPIDER_TABLE_MON_LIST *table_mon_list |
206 | ) { |
207 | DBUG_ENTER("spider_release_ping_table_mon_list_loop" ); |
208 | #ifdef HASH_UPDATE_WITH_HASH_VALUE |
209 | my_hash_delete_with_hash_value(&spider_udf_table_mon_list_hash[mutex_hash], |
210 | table_mon_list->key_hash_value, (uchar*) table_mon_list); |
211 | #else |
212 | my_hash_delete(&spider_udf_table_mon_list_hash[mutex_hash], |
213 | (uchar*) table_mon_list); |
214 | #endif |
215 | while (TRUE) |
216 | { |
217 | if (table_mon_list->use_count) |
218 | pthread_cond_wait(&spider_udf_table_mon_conds[mutex_hash], |
219 | &spider_udf_table_mon_mutexes[mutex_hash]); |
220 | else { |
221 | spider_ping_table_free_mon_list(table_mon_list); |
222 | break; |
223 | } |
224 | } |
225 | DBUG_VOID_RETURN; |
226 | } |
227 | |
228 | int spider_release_ping_table_mon_list( |
229 | const char *conv_name, |
230 | uint conv_name_length, |
231 | int link_idx |
232 | ) { |
233 | uint mutex_hash; |
234 | SPIDER_TABLE_MON_LIST *table_mon_list; |
235 | char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; |
236 | int link_idx_str_length; |
237 | DBUG_ENTER("spider_release_ping_table_mon_list" ); |
238 | DBUG_PRINT("info" , ("spider conv_name=%s" , conv_name)); |
239 | DBUG_PRINT("info" , ("spider conv_name_length=%u" , conv_name_length)); |
240 | DBUG_PRINT("info" , ("spider link_idx=%d" , link_idx)); |
241 | link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d" , |
242 | link_idx)); |
243 | char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1); |
244 | if (!buf) |
245 | { |
246 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
247 | DBUG_RETURN(HA_ERR_OUT_OF_MEM); |
248 | } |
249 | spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, |
250 | system_charset_info); |
251 | conv_name_str.init_calc_mem(134); |
252 | conv_name_str.length(0); |
253 | conv_name_str.q_append(conv_name, conv_name_length); |
254 | conv_name_str.q_append(link_idx_str, link_idx_str_length); |
255 | |
256 | mutex_hash = spider_udf_calc_hash(conv_name_str.c_ptr_safe(), |
257 | spider_param_udf_table_mon_mutex_count()); |
258 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
259 | my_hash_value_type hash_value = my_calc_hash( |
260 | &spider_udf_table_mon_list_hash[mutex_hash], |
261 | (uchar*) conv_name_str.c_ptr(), conv_name_str.length()); |
262 | #endif |
263 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[mutex_hash]); |
264 | #ifdef SPIDER_HAS_HASH_VALUE_TYPE |
265 | if ((table_mon_list = (SPIDER_TABLE_MON_LIST *) |
266 | my_hash_search_using_hash_value( |
267 | &spider_udf_table_mon_list_hash[mutex_hash], hash_value, |
268 | (uchar*) conv_name_str.c_ptr(), conv_name_str.length()))) |
269 | #else |
270 | if ((table_mon_list = (SPIDER_TABLE_MON_LIST *) my_hash_search( |
271 | &spider_udf_table_mon_list_hash[mutex_hash], |
272 | (uchar*) conv_name_str.c_ptr(), conv_name_str.length()))) |
273 | #endif |
274 | spider_release_ping_table_mon_list_loop(mutex_hash, table_mon_list); |
275 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[mutex_hash]); |
276 | my_afree(buf); |
277 | DBUG_RETURN(0); |
278 | } |
279 | |
280 | int spider_get_ping_table_mon( |
281 | THD *thd, |
282 | SPIDER_TABLE_MON_LIST *table_mon_list, |
283 | char *name, |
284 | uint name_length, |
285 | int link_idx, |
286 | uint32 server_id, |
287 | MEM_ROOT *mem_root, |
288 | bool need_lock |
289 | ) { |
290 | int error_num; |
291 | TABLE *table_link_mon = NULL; |
292 | #if MYSQL_VERSION_ID < 50500 |
293 | Open_tables_state open_tables_backup; |
294 | #else |
295 | Open_tables_backup open_tables_backup; |
296 | #endif |
297 | char table_key[MAX_KEY_LENGTH]; |
298 | SPIDER_TABLE_MON *table_mon, *table_mon_prev = NULL; |
299 | SPIDER_SHARE *tmp_share; |
300 | char **tmp_connect_info, *tmp_ptr; |
301 | uint *tmp_connect_info_length; |
302 | long *tmp_long; |
303 | longlong *tmp_longlong; |
304 | int list_size = 0; |
305 | DBUG_ENTER("spider_get_ping_table_mon" ); |
306 | |
307 | if ( |
308 | !(table_link_mon = spider_open_sys_table( |
309 | thd, SPIDER_SYS_LINK_MON_TABLE_NAME_STR, |
310 | SPIDER_SYS_LINK_MON_TABLE_NAME_LEN, FALSE, &open_tables_backup, |
311 | need_lock, &error_num)) |
312 | ) { |
313 | my_error(error_num, MYF(0)); |
314 | goto error; |
315 | } |
316 | if (table_mon_list->share->static_link_ids[0]) |
317 | { |
318 | spider_store_tables_name(table_link_mon, name, name_length); |
319 | spider_store_tables_link_idx_str(table_link_mon, |
320 | table_mon_list->share->static_link_ids[0], |
321 | table_mon_list->share->static_link_ids_lengths[0]); |
322 | if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root))) |
323 | goto create_table_mon; |
324 | if (error_num == HA_ERR_OUT_OF_MEM) |
325 | goto error; |
326 | if ((tmp_ptr = strstr(name, "#P#" ))) |
327 | { |
328 | *tmp_ptr = '\0'; |
329 | spider_store_tables_name(table_link_mon, name, strlen(name)); |
330 | *tmp_ptr = '#'; |
331 | if (!(error_num = spider_ping_table_cache_compare(table_link_mon, |
332 | mem_root))) |
333 | goto create_table_mon; |
334 | if (error_num == HA_ERR_OUT_OF_MEM) |
335 | goto error; |
336 | } |
337 | } |
338 | spider_store_tables_name(table_link_mon, name, name_length); |
339 | spider_store_tables_link_idx(table_link_mon, link_idx); |
340 | if (!(error_num = spider_ping_table_cache_compare(table_link_mon, mem_root))) |
341 | goto create_table_mon; |
342 | if (error_num == HA_ERR_OUT_OF_MEM) |
343 | goto error; |
344 | if ((tmp_ptr = strstr(name, "#P#" ))) |
345 | { |
346 | *tmp_ptr = '\0'; |
347 | spider_store_tables_name(table_link_mon, name, strlen(name)); |
348 | *tmp_ptr = '#'; |
349 | if (!(error_num = spider_ping_table_cache_compare(table_link_mon, |
350 | mem_root))) |
351 | goto create_table_mon; |
352 | if (error_num == HA_ERR_OUT_OF_MEM) |
353 | goto error; |
354 | } |
355 | error_num = HA_ERR_KEY_NOT_FOUND; |
356 | table_link_mon->file->print_error(error_num, MYF(0)); |
357 | goto error; |
358 | |
359 | create_table_mon: |
360 | if ((error_num = spider_get_sys_table_by_idx(table_link_mon, table_key, |
361 | table_link_mon->s->primary_key, 3))) |
362 | { |
363 | table_link_mon->file->print_error(error_num, MYF(0)); |
364 | goto error; |
365 | } |
366 | |
367 | do { |
368 | if (!(table_mon = (SPIDER_TABLE_MON *) |
369 | spider_bulk_malloc(spider_current_trx, 35, MYF(MY_WME | MY_ZEROFILL), |
370 | &table_mon, sizeof(SPIDER_TABLE_MON), |
371 | &tmp_share, sizeof(SPIDER_SHARE), |
372 | &tmp_connect_info, sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT, |
373 | &tmp_connect_info_length, sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT, |
374 | &tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT, |
375 | &tmp_longlong, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT, |
376 | NullS)) |
377 | ) { |
378 | spider_sys_index_end(table_link_mon); |
379 | error_num = HA_ERR_OUT_OF_MEM; |
380 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
381 | goto error; |
382 | } |
383 | spider_set_tmp_share_pointer(tmp_share, tmp_connect_info, |
384 | tmp_connect_info_length, tmp_long, tmp_longlong); |
385 | tmp_share->link_statuses[0] = -1; |
386 | table_mon->share = tmp_share; |
387 | table_mon->parent = table_mon_list; |
388 | if (table_mon_prev) |
389 | table_mon_prev->next = table_mon; |
390 | else |
391 | table_mon_list->first = table_mon; |
392 | table_mon_prev = table_mon; |
393 | if ( |
394 | (error_num = spider_get_sys_link_mon_server_id( |
395 | table_link_mon, &table_mon->server_id, mem_root)) || |
396 | (error_num = spider_get_sys_link_mon_connect_info( |
397 | table_link_mon, tmp_share, 0, mem_root)) |
398 | ) { |
399 | table_link_mon->file->print_error(error_num, MYF(0)); |
400 | spider_sys_index_end(table_link_mon); |
401 | goto error; |
402 | } |
403 | if ( |
404 | (error_num = spider_set_connect_info_default( |
405 | tmp_share, |
406 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
407 | NULL, |
408 | NULL, |
409 | #endif |
410 | NULL |
411 | )) || |
412 | (error_num = spider_set_connect_info_default_dbtable( |
413 | tmp_share, name, name_length |
414 | )) || |
415 | (error_num = spider_create_conn_keys(tmp_share)) |
416 | ) { |
417 | spider_sys_index_end(table_link_mon); |
418 | goto error; |
419 | } |
420 | DBUG_PRINT("info" ,("spider table_mon->server_id=%u" , |
421 | table_mon->server_id)); |
422 | DBUG_PRINT("info" ,("spider server_id=%u" , server_id)); |
423 | if (table_mon->server_id == server_id) |
424 | table_mon_list->current = table_mon; |
425 | list_size++; |
426 | error_num = spider_sys_index_next_same(table_link_mon, table_key); |
427 | } while (error_num == 0); |
428 | spider_sys_index_end(table_link_mon); |
429 | spider_close_sys_table(thd, table_link_mon, |
430 | &open_tables_backup, need_lock); |
431 | table_link_mon = NULL; |
432 | table_mon_list->list_size = list_size; |
433 | |
434 | if (!table_mon_list->current) |
435 | { |
436 | error_num = ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_NUM; |
437 | my_printf_error(ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_NUM, |
438 | ER_SPIDER_UDF_PING_TABLE_NO_SERVER_ID_STR, MYF(0)); |
439 | goto error; |
440 | } |
441 | |
442 | DBUG_RETURN(0); |
443 | |
444 | error: |
445 | if (table_link_mon) |
446 | spider_close_sys_table(thd, table_link_mon, |
447 | &open_tables_backup, need_lock); |
448 | table_mon = table_mon_list->first; |
449 | table_mon_list->first = NULL; |
450 | table_mon_list->current = NULL; |
451 | while (table_mon) |
452 | { |
453 | spider_free_tmp_share_alloc(table_mon->share); |
454 | table_mon_prev = table_mon->next; |
455 | spider_free(spider_current_trx, table_mon, MYF(0)); |
456 | table_mon = table_mon_prev; |
457 | } |
458 | DBUG_RETURN(error_num); |
459 | } |
460 | |
461 | SPIDER_TABLE_MON_LIST *spider_get_ping_table_tgt( |
462 | THD *thd, |
463 | char *name, |
464 | uint name_length, |
465 | int link_idx, |
466 | char *static_link_id, |
467 | uint static_link_id_length, |
468 | uint32 server_id, |
469 | spider_string *str, |
470 | bool need_lock, |
471 | int *error_num |
472 | ) { |
473 | TABLE *table_tables = NULL; |
474 | #if MYSQL_VERSION_ID < 50500 |
475 | Open_tables_state open_tables_backup; |
476 | #else |
477 | Open_tables_backup open_tables_backup; |
478 | #endif |
479 | char table_key[MAX_KEY_LENGTH]; |
480 | |
481 | SPIDER_TABLE_MON_LIST *table_mon_list = NULL; |
482 | SPIDER_SHARE *tmp_share; |
483 | char **tmp_connect_info; |
484 | uint *tmp_connect_info_length; |
485 | long *tmp_long; |
486 | longlong *tmp_longlong; |
487 | char *key_str; |
488 | MEM_ROOT mem_root; |
489 | DBUG_ENTER("spider_get_ping_table_tgt" ); |
490 | |
491 | SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); |
492 | if (!(table_mon_list = (SPIDER_TABLE_MON_LIST *) |
493 | spider_bulk_malloc(spider_current_trx, 36, MYF(MY_WME | MY_ZEROFILL), |
494 | &table_mon_list, sizeof(SPIDER_TABLE_MON_LIST), |
495 | &tmp_share, sizeof(SPIDER_SHARE), |
496 | &tmp_connect_info, sizeof(char *) * SPIDER_TMP_SHARE_CHAR_PTR_COUNT, |
497 | &tmp_connect_info_length, sizeof(uint) * SPIDER_TMP_SHARE_UINT_COUNT, |
498 | &tmp_long, sizeof(long) * SPIDER_TMP_SHARE_LONG_COUNT, |
499 | &tmp_longlong, sizeof(longlong) * SPIDER_TMP_SHARE_LONGLONG_COUNT, |
500 | &key_str, str->length() + 1, |
501 | NullS)) |
502 | ) { |
503 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
504 | goto error; |
505 | } |
506 | spider_set_tmp_share_pointer(tmp_share, tmp_connect_info, |
507 | tmp_connect_info_length, tmp_long, tmp_longlong); |
508 | table_mon_list->share = tmp_share; |
509 | table_mon_list->key = key_str; |
510 | table_mon_list->key_length = str->length(); |
511 | memcpy(key_str, str->ptr(), table_mon_list->key_length); |
512 | tmp_share->access_charset = thd->variables.character_set_client; |
513 | |
514 | if ( |
515 | !(table_tables = spider_open_sys_table( |
516 | thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, |
517 | SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup, need_lock, |
518 | error_num)) |
519 | ) { |
520 | my_error(*error_num, MYF(0)); |
521 | goto error; |
522 | } |
523 | spider_store_tables_name(table_tables, name, name_length); |
524 | if (static_link_id) |
525 | { |
526 | spider_store_tables_static_link_id(table_tables, |
527 | static_link_id, static_link_id_length); |
528 | if ( |
529 | (*error_num = spider_get_sys_table_by_idx(table_tables, table_key, 2, |
530 | SPIDER_SYS_TABLES_UIDX1_COL_CNT)) || |
531 | (*error_num = spider_get_sys_tables_link_idx( |
532 | table_tables, &link_idx, &mem_root)) |
533 | ) { |
534 | table_tables->file->print_error(*error_num, MYF(0)); |
535 | goto error; |
536 | } |
537 | } else { |
538 | spider_store_tables_link_idx(table_tables, link_idx); |
539 | if ( |
540 | (*error_num = spider_check_sys_table(table_tables, table_key)) |
541 | ) { |
542 | table_tables->file->print_error(*error_num, MYF(0)); |
543 | goto error; |
544 | } |
545 | } |
546 | if ( |
547 | (*error_num = spider_get_sys_tables_connect_info( |
548 | table_tables, tmp_share, 0, &mem_root)) || |
549 | (*error_num = spider_get_sys_tables_link_status( |
550 | table_tables, tmp_share, 0, &mem_root)) |
551 | ) { |
552 | table_tables->file->print_error(*error_num, MYF(0)); |
553 | goto error; |
554 | } |
555 | spider_close_sys_table(thd, table_tables, |
556 | &open_tables_backup, need_lock); |
557 | table_tables = NULL; |
558 | |
559 | if ( |
560 | (*error_num = spider_set_connect_info_default( |
561 | tmp_share, |
562 | #ifdef WITH_PARTITION_STORAGE_ENGINE |
563 | NULL, |
564 | NULL, |
565 | #endif |
566 | NULL |
567 | )) || |
568 | (*error_num = spider_set_connect_info_default_dbtable( |
569 | tmp_share, name, name_length |
570 | )) || |
571 | (*error_num = spider_create_conn_keys(tmp_share)) || |
572 | /* |
573 | (*error_num = spider_db_create_table_names_str(tmp_share)) || |
574 | */ |
575 | (*error_num = spider_get_ping_table_mon( |
576 | thd, table_mon_list, name, name_length, link_idx, server_id, &mem_root, |
577 | need_lock)) |
578 | ) |
579 | goto error; |
580 | |
581 | if (tmp_share->link_statuses[0] == SPIDER_LINK_STATUS_NG) |
582 | table_mon_list->mon_status = SPIDER_LINK_MON_NG; |
583 | |
584 | #if MYSQL_VERSION_ID < 50500 |
585 | if (pthread_mutex_init(&table_mon_list->caller_mutex, MY_MUTEX_INIT_FAST)) |
586 | #else |
587 | if (mysql_mutex_init(spd_key_mutex_mon_list_caller, |
588 | &table_mon_list->caller_mutex, MY_MUTEX_INIT_FAST)) |
589 | #endif |
590 | { |
591 | *error_num = HA_ERR_OUT_OF_MEM; |
592 | goto error_caller_mutex_init; |
593 | } |
594 | #if MYSQL_VERSION_ID < 50500 |
595 | if (pthread_mutex_init(&table_mon_list->receptor_mutex, MY_MUTEX_INIT_FAST)) |
596 | #else |
597 | if (mysql_mutex_init(spd_key_mutex_mon_list_receptor, |
598 | &table_mon_list->receptor_mutex, MY_MUTEX_INIT_FAST)) |
599 | #endif |
600 | { |
601 | *error_num = HA_ERR_OUT_OF_MEM; |
602 | goto error_receptor_mutex_init; |
603 | } |
604 | #if MYSQL_VERSION_ID < 50500 |
605 | if (pthread_mutex_init(&table_mon_list->monitor_mutex, MY_MUTEX_INIT_FAST)) |
606 | #else |
607 | if (mysql_mutex_init(spd_key_mutex_mon_list_monitor, |
608 | &table_mon_list->monitor_mutex, MY_MUTEX_INIT_FAST)) |
609 | #endif |
610 | { |
611 | *error_num = HA_ERR_OUT_OF_MEM; |
612 | goto error_monitor_mutex_init; |
613 | } |
614 | #if MYSQL_VERSION_ID < 50500 |
615 | if (pthread_mutex_init(&table_mon_list->update_status_mutex, |
616 | MY_MUTEX_INIT_FAST)) |
617 | #else |
618 | if (mysql_mutex_init(spd_key_mutex_mon_list_update_status, |
619 | &table_mon_list->update_status_mutex, MY_MUTEX_INIT_FAST)) |
620 | #endif |
621 | { |
622 | *error_num = HA_ERR_OUT_OF_MEM; |
623 | goto error_update_status_mutex_init; |
624 | } |
625 | |
626 | free_root(&mem_root, MYF(0)); |
627 | DBUG_RETURN(table_mon_list); |
628 | |
629 | error_update_status_mutex_init: |
630 | pthread_mutex_destroy(&table_mon_list->monitor_mutex); |
631 | error_monitor_mutex_init: |
632 | pthread_mutex_destroy(&table_mon_list->receptor_mutex); |
633 | error_receptor_mutex_init: |
634 | pthread_mutex_destroy(&table_mon_list->caller_mutex); |
635 | error_caller_mutex_init: |
636 | error: |
637 | if (table_tables) |
638 | spider_close_sys_table(thd, table_tables, |
639 | &open_tables_backup, need_lock); |
640 | free_root(&mem_root, MYF(0)); |
641 | if (table_mon_list) |
642 | { |
643 | spider_free_tmp_share_alloc(table_mon_list->share); |
644 | spider_free(spider_current_trx, table_mon_list, MYF(0)); |
645 | } |
646 | DBUG_RETURN(NULL); |
647 | } |
648 | |
649 | SPIDER_CONN *spider_get_ping_table_tgt_conn( |
650 | SPIDER_TRX *trx, |
651 | SPIDER_SHARE *share, |
652 | int *error_num |
653 | ) { |
654 | SPIDER_CONN *conn; |
655 | DBUG_ENTER("spider_get_ping_table_tgt_conn" ); |
656 | if ( |
657 | !(conn = spider_get_conn( |
658 | share, 0, share->conn_keys[0], trx, NULL, FALSE, FALSE, |
659 | SPIDER_CONN_KIND_MYSQL, error_num)) |
660 | ) { |
661 | my_error(ER_CONNECT_TO_FOREIGN_DATA_SOURCE, MYF(0), |
662 | share->server_names[0]); |
663 | *error_num = ER_CONNECT_TO_FOREIGN_DATA_SOURCE; |
664 | goto error; |
665 | } |
666 | #ifndef DBUG_OFF |
667 | DBUG_PRINT("info" ,("spider conn->thd=%p" , conn->thd)); |
668 | if (conn->thd) |
669 | { |
670 | DBUG_PRINT("info" ,("spider query_id=%lld" , conn->thd->query_id)); |
671 | } |
672 | #endif |
673 | conn->error_mode = 0; |
674 | DBUG_RETURN(conn); |
675 | |
676 | error: |
677 | DBUG_RETURN(NULL); |
678 | } |
679 | |
680 | int spider_get_ping_table_gtid_pos( |
681 | SPIDER_TRX *trx, |
682 | THD *thd, |
683 | spider_string *str, |
684 | uint conv_name_length, |
685 | int failed_link_idx, |
686 | uint32 server_id, |
687 | bool need_lock, |
688 | spider_string *tmp_str |
689 | ) { |
690 | int error_num, source_link_idx, need_mon; |
691 | char table_key[MAX_KEY_LENGTH]; |
692 | TABLE *table_tables, *table_gtid_pos; |
693 | #if MYSQL_VERSION_ID < 50500 |
694 | Open_tables_state open_tables_backup_tables; |
695 | Open_tables_state open_tables_backup_gtid_pos; |
696 | #else |
697 | Open_tables_backup open_tables_backup_tables; |
698 | Open_tables_backup open_tables_backup_gtid_pos; |
699 | #endif |
700 | MEM_ROOT mem_root; |
701 | long link_status; |
702 | long monitoring_binlog_pos_at_failing; |
703 | SPIDER_TABLE_MON_LIST *table_mon_list; |
704 | SPIDER_CONN *ping_conn = NULL; |
705 | char *static_link_id; |
706 | uint static_link_id_length; |
707 | DBUG_ENTER("spider_get_ping_table_gtid_pos" ); |
708 | |
709 | /* |
710 | select * from |
711 | mysql.spider_tables |
712 | where |
713 | db_name = setted db_name and |
714 | table_name = setted table_name |
715 | */ |
716 | if ( |
717 | !(table_tables = spider_open_sys_table( |
718 | thd, SPIDER_SYS_TABLES_TABLE_NAME_STR, |
719 | SPIDER_SYS_TABLES_TABLE_NAME_LEN, FALSE, &open_tables_backup_tables, |
720 | need_lock, &error_num)) |
721 | ) |
722 | goto error_open_table_tables; |
723 | |
724 | if ( |
725 | !(table_gtid_pos = spider_open_sys_table( |
726 | thd, SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_STR, |
727 | SPIDER_SYS_POS_FOR_RECOVERY_TABLE_NAME_LEN, TRUE, |
728 | &open_tables_backup_gtid_pos, need_lock, &error_num)) |
729 | ) |
730 | goto error_open_table_gtid_pos; |
731 | |
732 | table_tables->use_all_columns(); |
733 | table_gtid_pos->use_all_columns(); |
734 | spider_store_tables_name(table_tables, str->ptr(), conv_name_length); |
735 | spider_store_tables_name(table_gtid_pos, str->ptr(), conv_name_length); |
736 | spider_store_binlog_pos_failed_link_idx(table_gtid_pos, failed_link_idx); |
737 | if ((error_num = spider_get_sys_table_by_idx(table_tables, table_key, 0, |
738 | SPIDER_SYS_TABLES_PK_COL_CNT - 1))) |
739 | { |
740 | if (error_num == HA_ERR_KEY_NOT_FOUND || error_num == HA_ERR_END_OF_FILE) |
741 | { |
742 | error_num = 0; |
743 | } |
744 | goto error_get_sys_table_by_idx; |
745 | } |
746 | |
747 | SPD_INIT_ALLOC_ROOT(&mem_root, 4096, 0, MYF(MY_WME)); |
748 | do { |
749 | if ( |
750 | (error_num = spider_get_sys_tables_link_status(table_tables, |
751 | &link_status, &mem_root)) || |
752 | (error_num = spider_get_sys_tables_static_link_id(table_tables, |
753 | &static_link_id, &static_link_id_length, &mem_root)) || |
754 | (error_num = spider_get_sys_tables_monitoring_binlog_pos_at_failing( |
755 | table_tables, &monitoring_binlog_pos_at_failing, &mem_root)) |
756 | ) { |
757 | goto error_get_sys_tables_link_status; |
758 | } |
759 | |
760 | if (link_status == 1 && monitoring_binlog_pos_at_failing > 0) |
761 | { |
762 | if ((error_num = spider_get_sys_tables_link_idx(table_tables, |
763 | &source_link_idx, &mem_root))) |
764 | { |
765 | goto error_get_sys_tables_link_idx; |
766 | } |
767 | if ( |
768 | (table_mon_list = spider_get_ping_table_mon_list( |
769 | trx, |
770 | thd, |
771 | str, |
772 | conv_name_length, |
773 | source_link_idx, |
774 | static_link_id, |
775 | static_link_id_length, |
776 | server_id, |
777 | need_lock, |
778 | &error_num |
779 | )) |
780 | ) { |
781 | SPIDER_DB_RESULT *res1 = NULL; |
782 | SPIDER_DB_RESULT *res2 = NULL; |
783 | if ( |
784 | (ping_conn = spider_get_ping_table_tgt_conn(trx, |
785 | table_mon_list->share, &error_num |
786 | )) && |
787 | !(error_num = ping_conn->db_conn->show_master_status( |
788 | trx, table_mon_list->share, 0, &need_mon, table_gtid_pos, tmp_str, |
789 | monitoring_binlog_pos_at_failing == 1 ? 0 : 1, &res1, &res2)) |
790 | ) { |
791 | spider_store_binlog_pos_source_link_idx( |
792 | table_gtid_pos, source_link_idx); |
793 | spider_insert_sys_table(table_gtid_pos); |
794 | } |
795 | if (res1) |
796 | { |
797 | res1->free_result(); |
798 | delete res1; |
799 | } |
800 | if (res2) |
801 | { |
802 | res2->free_result(); |
803 | delete res2; |
804 | } |
805 | spider_free_ping_table_mon_list(table_mon_list); |
806 | } |
807 | } |
808 | |
809 | error_num = spider_sys_index_next_same(table_tables, table_key); |
810 | } while (error_num == 0); |
811 | free_root(&mem_root, MYF(0)); |
812 | |
813 | if ((error_num = spider_sys_index_end(table_tables))) |
814 | { |
815 | goto error_sys_index_end; |
816 | } |
817 | spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos, |
818 | need_lock); |
819 | spider_close_sys_table(thd, table_tables, &open_tables_backup_tables, |
820 | need_lock); |
821 | |
822 | DBUG_RETURN(0); |
823 | |
824 | error_get_sys_tables_link_idx: |
825 | error_get_sys_tables_link_status: |
826 | free_root(&mem_root, MYF(0)); |
827 | spider_sys_index_end(table_tables); |
828 | error_sys_index_end: |
829 | error_get_sys_table_by_idx: |
830 | spider_close_sys_table(thd, table_gtid_pos, &open_tables_backup_gtid_pos, |
831 | need_lock); |
832 | error_open_table_gtid_pos: |
833 | spider_close_sys_table(thd, table_tables, &open_tables_backup_tables, |
834 | need_lock); |
835 | error_open_table_tables: |
836 | DBUG_RETURN(error_num); |
837 | } |
838 | |
839 | int spider_init_ping_table_mon_cache( |
840 | THD *thd, |
841 | MEM_ROOT *mem_root, |
842 | bool need_lock |
843 | ) { |
844 | int error_num, same; |
845 | TABLE *table_link_mon = NULL; |
846 | #if MYSQL_VERSION_ID < 50500 |
847 | Open_tables_state open_tables_backup; |
848 | #else |
849 | Open_tables_backup open_tables_backup; |
850 | #endif |
851 | SPIDER_MON_KEY mon_key; |
852 | DBUG_ENTER("spider_init_ping_table_mon_cache" ); |
853 | |
854 | if ( |
855 | !(table_link_mon = spider_open_sys_table( |
856 | thd, SPIDER_SYS_LINK_MON_TABLE_NAME_STR, |
857 | SPIDER_SYS_LINK_MON_TABLE_NAME_LEN, FALSE, &open_tables_backup, |
858 | need_lock, &error_num)) |
859 | ) { |
860 | my_error(error_num, MYF(0)); |
861 | goto error_open_sys_table; |
862 | } |
863 | |
864 | pthread_mutex_lock(&spider_mon_table_cache_mutex); |
865 | if (spider_mon_table_cache_version != spider_mon_table_cache_version_req) |
866 | { |
867 | /* reset */ |
868 | spider_mon_table_cache.elements = 0; |
869 | |
870 | if ((error_num = spider_sys_index_first(table_link_mon, |
871 | table_link_mon->s->primary_key))) |
872 | { |
873 | if (error_num != HA_ERR_KEY_NOT_FOUND && error_num != HA_ERR_END_OF_FILE) |
874 | { |
875 | table_link_mon->file->print_error(error_num, MYF(0)); |
876 | goto error_sys_index_first; |
877 | } |
878 | } |
879 | |
880 | if (!error_num) |
881 | { |
882 | mon_key.db_name_length = SPIDER_SYS_LINK_MON_TABLE_DB_NAME_SIZE + 1; |
883 | mon_key.table_name_length = SPIDER_SYS_LINK_MON_TABLE_TABLE_NAME_SIZE + 1; |
884 | mon_key.link_id_length = SPIDER_SYS_LINK_MON_TABLE_LINK_ID_SIZE + 1; |
885 | do { |
886 | if ((error_num = spider_get_sys_link_mon_key(table_link_mon, &mon_key, |
887 | mem_root, &same))) |
888 | goto error_get_sys_link_mon_key; |
889 | |
890 | if (!same) |
891 | { |
892 | mon_key.sort = spider_calc_for_sort(3, mon_key.db_name, |
893 | mon_key.table_name, mon_key.link_id); |
894 | if (push_dynamic(&spider_mon_table_cache, (uchar *) &mon_key)) |
895 | { |
896 | error_num = HA_ERR_OUT_OF_MEM; |
897 | goto error_push_dynamic; |
898 | } |
899 | } |
900 | |
901 | if ((error_num = spider_sys_index_next(table_link_mon))) |
902 | { |
903 | if ( |
904 | error_num != HA_ERR_KEY_NOT_FOUND && |
905 | error_num != HA_ERR_END_OF_FILE |
906 | ) { |
907 | table_link_mon->file->print_error(error_num, MYF(0)); |
908 | goto error_sys_index_next; |
909 | } |
910 | } |
911 | } while (!error_num); |
912 | spider_sys_index_end(table_link_mon); |
913 | } |
914 | my_qsort( |
915 | (uchar *) dynamic_element(&spider_mon_table_cache, 0, SPIDER_MON_KEY *), |
916 | spider_mon_table_cache.elements, sizeof(SPIDER_MON_KEY), |
917 | (qsort_cmp) spider_compare_for_sort); |
918 | uint old_elements = spider_mon_table_cache.max_element; |
919 | freeze_size(&spider_mon_table_cache); |
920 | if (spider_mon_table_cache.max_element < old_elements) |
921 | { |
922 | spider_free_mem_calc(spider_current_trx, |
923 | spider_mon_table_cache_id, |
924 | spider_mon_table_cache.max_element * |
925 | spider_mon_table_cache.size_of_element); |
926 | } |
927 | spider_mon_table_cache_version = spider_mon_table_cache_version_req; |
928 | } |
929 | pthread_mutex_unlock(&spider_mon_table_cache_mutex); |
930 | spider_close_sys_table(thd, table_link_mon, &open_tables_backup, need_lock); |
931 | DBUG_RETURN(0); |
932 | |
933 | error_push_dynamic: |
934 | error_get_sys_link_mon_key: |
935 | error_sys_index_next: |
936 | spider_sys_index_end(table_link_mon); |
937 | error_sys_index_first: |
938 | pthread_mutex_unlock(&spider_mon_table_cache_mutex); |
939 | spider_close_sys_table(thd, table_link_mon, &open_tables_backup, need_lock); |
940 | error_open_sys_table: |
941 | DBUG_RETURN(error_num); |
942 | } |
943 | |
944 | int spider_ping_table_cache_compare( |
945 | TABLE *table, |
946 | MEM_ROOT *mem_root |
947 | ) { |
948 | uint32 roop_count; |
949 | SPIDER_MON_KEY *mon_key; |
950 | char *db_name, *table_name, *link_id; |
951 | DBUG_ENTER("spider_ping_table_cache_compare" ); |
952 | |
953 | if ( |
954 | !(db_name = get_field(mem_root, table->field[0])) || |
955 | !(table_name = get_field(mem_root, table->field[1])) || |
956 | !(link_id = get_field(mem_root, table->field[2])) |
957 | ) |
958 | DBUG_RETURN(HA_ERR_OUT_OF_MEM); |
959 | DBUG_PRINT("info" , ("spider db_name=%s" , db_name)); |
960 | DBUG_PRINT("info" , ("spider table_name=%s" , table_name)); |
961 | DBUG_PRINT("info" , ("spider link_id=%s" , link_id)); |
962 | |
963 | pthread_mutex_lock(&spider_mon_table_cache_mutex); |
964 | for (roop_count = 0; roop_count < spider_mon_table_cache.elements; |
965 | roop_count++) |
966 | { |
967 | mon_key = dynamic_element(&spider_mon_table_cache, roop_count, |
968 | SPIDER_MON_KEY *); |
969 | DBUG_PRINT("info" , ("spider roop_count=%d" , roop_count)); |
970 | DBUG_PRINT("info" , ("spider mon_key.db_name=%s" , mon_key->db_name)); |
971 | DBUG_PRINT("info" , ("spider mon_key.table_name=%s" , mon_key->table_name)); |
972 | DBUG_PRINT("info" , ("spider mon_key.link_id=%s" , mon_key->link_id)); |
973 | if ( |
974 | !wild_case_compare(system_charset_info, db_name, mon_key->db_name) && |
975 | !wild_case_compare(system_charset_info, table_name, |
976 | mon_key->table_name) && |
977 | !wild_case_compare(system_charset_info, link_id, mon_key->link_id) |
978 | ) { |
979 | spider_store_db_and_table_name( |
980 | table, |
981 | mon_key->db_name, |
982 | mon_key->db_name_length, |
983 | mon_key->table_name, |
984 | mon_key->table_name_length |
985 | ); |
986 | spider_store_tables_link_idx_str( |
987 | table, |
988 | mon_key->link_id, |
989 | mon_key->link_id_length |
990 | ); |
991 | pthread_mutex_unlock(&spider_mon_table_cache_mutex); |
992 | DBUG_PRINT("info" , ("spider found" )); |
993 | DBUG_RETURN(0); |
994 | } |
995 | } |
996 | pthread_mutex_unlock(&spider_mon_table_cache_mutex); |
997 | DBUG_PRINT("info" , ("spider not found" )); |
998 | DBUG_RETURN(1); |
999 | } |
1000 | |
1001 | long long spider_ping_table_body( |
1002 | UDF_INIT *initid, |
1003 | UDF_ARGS *args, |
1004 | char *is_null, |
1005 | char *error |
1006 | ) { |
1007 | int error_num = 0, link_idx, flags, full_mon_count, current_mon_count, |
1008 | success_count, fault_count, tmp_error_num = 0; |
1009 | uint32 first_sid, server_id; |
1010 | longlong limit, tmp_sid = -1; |
1011 | SPIDER_MON_TABLE_RESULT *mon_table_result = |
1012 | (SPIDER_MON_TABLE_RESULT *) initid->ptr; |
1013 | SPIDER_TRX *trx = mon_table_result->trx; |
1014 | THD *thd = trx->thd; |
1015 | SPIDER_CONN *ping_conn = NULL, *mon_conn; |
1016 | char *where_clause; |
1017 | SPIDER_TABLE_MON_LIST *table_mon_list; |
1018 | SPIDER_TABLE_MON *table_mon; |
1019 | |
1020 | char buf[MAX_FIELD_WIDTH], buf2[MAX_FIELD_WIDTH]; |
1021 | spider_string conv_name(buf, sizeof(buf), system_charset_info); |
1022 | spider_string tmp_str(buf2, sizeof(buf2), system_charset_info); |
1023 | int conv_name_length; |
1024 | char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; |
1025 | int link_idx_str_length; |
1026 | char *static_link_id = NULL; |
1027 | int static_link_id_length = 0; |
1028 | bool get_lock = FALSE, status_changed_to_ng = FALSE; |
1029 | DBUG_ENTER("spider_ping_table_body" ); |
1030 | conv_name.init_calc_mem(135); |
1031 | tmp_str.init_calc_mem(247); |
1032 | conv_name.length(0); |
1033 | #if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100002 |
1034 | server_id = global_system_variables.server_id; |
1035 | #else |
1036 | server_id = thd->server_id; |
1037 | #endif |
1038 | if ( |
1039 | thd->open_tables != 0 || |
1040 | thd->handler_tables_hash.records != 0 || |
1041 | thd->derived_tables != 0 || |
1042 | thd->lock != 0 || |
1043 | #if MYSQL_VERSION_ID < 50500 |
1044 | thd->locked_tables != 0 || |
1045 | thd->prelocked_mode != NON_PRELOCKED |
1046 | #else |
1047 | thd->locked_tables_list.locked_tables() || |
1048 | thd->locked_tables_mode != LTM_NONE |
1049 | #endif |
1050 | ) { |
1051 | if (thd->open_tables != 0) |
1052 | { |
1053 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1054 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0), |
1055 | "thd->open_tables" , thd->open_tables); |
1056 | } else if (thd->handler_tables_hash.records != 0) |
1057 | { |
1058 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1059 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0), |
1060 | "thd->handler_tables_hash.records" , |
1061 | (longlong) thd->handler_tables_hash.records); |
1062 | } else if (thd->derived_tables != 0) |
1063 | { |
1064 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1065 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0), |
1066 | "thd->derived_tables" , thd->derived_tables); |
1067 | } else if (thd->lock != 0) |
1068 | { |
1069 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1070 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0), |
1071 | "thd->lock" , thd->lock); |
1072 | #if MYSQL_VERSION_ID < 50500 |
1073 | } else if (thd->locked_tables != 0) |
1074 | { |
1075 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1076 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0), |
1077 | "thd->locked_tables" , thd->locked_tables); |
1078 | } else if (thd->prelocked_mode != NON_PRELOCKED) |
1079 | { |
1080 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1081 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0), |
1082 | "thd->prelocked_mode" , (longlong) thd->prelocked_mode); |
1083 | #else |
1084 | } else if (thd->locked_tables_list.locked_tables()) |
1085 | { |
1086 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1087 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_PTR, MYF(0), |
1088 | "thd->locked_tables_list.locked_tables()" , |
1089 | thd->locked_tables_list.locked_tables()); |
1090 | } else if (thd->locked_tables_mode != LTM_NONE) |
1091 | { |
1092 | my_printf_error(ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_NUM, |
1093 | ER_SPIDER_UDF_CANT_USE_IF_OPEN_TABLE_STR_WITH_NUM, MYF(0), |
1094 | "thd->locked_tables_mode" , (longlong) thd->locked_tables_mode); |
1095 | #endif |
1096 | } |
1097 | goto error; |
1098 | } |
1099 | |
1100 | if ( |
1101 | args->lengths[0] > SPIDER_CONNECT_INFO_MAX_LEN |
1102 | ) { |
1103 | my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM, |
1104 | ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "table name" ); |
1105 | goto error; |
1106 | } |
1107 | if ( |
1108 | args->lengths[0] == 0 |
1109 | ) { |
1110 | my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM, |
1111 | ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "table name" ); |
1112 | goto error; |
1113 | } |
1114 | if (args->arg_type[1] == STRING_RESULT) |
1115 | { |
1116 | if ( |
1117 | !args->args[1] |
1118 | ) { |
1119 | my_printf_error(ER_SPIDER_UDF_PARAM_REQIRED_NUM, |
1120 | ER_SPIDER_UDF_PARAM_REQIRED_STR, MYF(0), "link id" ); |
1121 | goto error; |
1122 | } |
1123 | if ( |
1124 | args->lengths[1] > SPIDER_CONNECT_INFO_MAX_LEN |
1125 | ) { |
1126 | my_printf_error(ER_SPIDER_UDF_PARAM_TOO_LONG_NUM, |
1127 | ER_SPIDER_UDF_PARAM_TOO_LONG_STR, MYF(0), "link id" ); |
1128 | goto error; |
1129 | } |
1130 | link_idx_str_length = args->lengths[1]; |
1131 | memcpy(link_idx_str, args->args[1], link_idx_str_length + 1); |
1132 | if (link_idx_str[0] >= '0' && link_idx_str[0] <= '9') |
1133 | { |
1134 | link_idx = atoi(link_idx_str); |
1135 | } else { |
1136 | link_idx = -1; |
1137 | static_link_id = link_idx_str; |
1138 | static_link_id_length = link_idx_str_length; |
1139 | } |
1140 | } else { |
1141 | link_idx = (int) (args->args[1] ? *((longlong *) args->args[1]) : 0); |
1142 | link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d" , |
1143 | link_idx)); |
1144 | } |
1145 | flags = (int) (args->args[2] ? *((longlong *) args->args[2]) : 0); |
1146 | limit = args->args[3] ? *((longlong *) args->args[3]) : 0; |
1147 | where_clause = args->args[4] ? args->args[4] : (char *) "" ; |
1148 | |
1149 | if (conv_name.append(args->args[0], args->lengths[0], |
1150 | trx->thd->variables.character_set_client)) |
1151 | { |
1152 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
1153 | goto error; |
1154 | } |
1155 | conv_name_length = conv_name.length(); |
1156 | if (conv_name.reserve(link_idx_str_length + 1)) |
1157 | { |
1158 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
1159 | goto error; |
1160 | } |
1161 | conv_name.q_append(link_idx_str, link_idx_str_length + 1); |
1162 | conv_name.length(conv_name.length() - 1); |
1163 | |
1164 | if (!(table_mon_list = spider_get_ping_table_mon_list(trx, trx->thd, |
1165 | &conv_name, conv_name_length, link_idx, |
1166 | static_link_id, static_link_id_length, |
1167 | server_id, TRUE, &error_num))) |
1168 | goto error; |
1169 | |
1170 | if (table_mon_list->mon_status == SPIDER_LINK_MON_NG) |
1171 | { |
1172 | mon_table_result->result_status = SPIDER_LINK_MON_NG; |
1173 | DBUG_PRINT("info" , |
1174 | ("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 1" )); |
1175 | goto end; |
1176 | } |
1177 | |
1178 | if (args->args[5]) |
1179 | tmp_sid = *((longlong *) args->args[5]); |
1180 | |
1181 | if (tmp_sid >= 0) |
1182 | { |
1183 | first_sid = (uint32) tmp_sid; |
1184 | full_mon_count = (int) (args->args[6] ? *((longlong *) args->args[6]) : 0); |
1185 | current_mon_count = |
1186 | (int) (args->args[7] ? *((longlong *) args->args[7]) + 1 : 1); |
1187 | if (full_mon_count != table_mon_list->list_size) |
1188 | { |
1189 | my_printf_error(ER_SPIDER_UDF_PING_TABLE_DIFFERENT_MON_NUM, |
1190 | ER_SPIDER_UDF_PING_TABLE_DIFFERENT_MON_STR, MYF(0)); |
1191 | goto error_with_free_table_mon_list; |
1192 | } |
1193 | } else { |
1194 | first_sid = server_id; |
1195 | full_mon_count = table_mon_list->list_size; |
1196 | current_mon_count = 1; |
1197 | } |
1198 | |
1199 | success_count = (int) (args->args[8] ? *((longlong *) args->args[8]) : 0); |
1200 | fault_count = (int) (args->args[9] ? *((longlong *) args->args[9]) : 0); |
1201 | if ( |
1202 | table_mon_list->mon_status != SPIDER_LINK_MON_NG && |
1203 | !(ping_conn = spider_get_ping_table_tgt_conn(trx, |
1204 | table_mon_list->share, &error_num)) |
1205 | ) { |
1206 | if (error_num == HA_ERR_OUT_OF_MEM) |
1207 | goto error_with_free_table_mon_list; |
1208 | else |
1209 | thd->clear_error(); |
1210 | } |
1211 | if ( |
1212 | table_mon_list->mon_status == SPIDER_LINK_MON_NG || |
1213 | error_num || |
1214 | (tmp_error_num = spider_db_udf_ping_table(table_mon_list, table_mon_list->share, trx, |
1215 | ping_conn, where_clause, args->lengths[4], |
1216 | (flags & SPIDER_UDF_PING_TABLE_PING_ONLY), |
1217 | (flags & SPIDER_UDF_PING_TABLE_USE_WHERE), |
1218 | limit |
1219 | )) |
1220 | ) { |
1221 | DBUG_PRINT("info" ,("spider table_mon_list->mon_status == SPIDER_LINK_MON_NG:%s" , |
1222 | table_mon_list->mon_status == SPIDER_LINK_MON_NG ? "TRUE" : "FALSE" )); |
1223 | DBUG_PRINT("info" ,("spider error_num=%d" , error_num)); |
1224 | DBUG_PRINT("info" ,("spider tmp_error_num=%d" , tmp_error_num)); |
1225 | if (tmp_error_num == HA_ERR_OUT_OF_MEM) |
1226 | goto error_with_free_table_mon_list; |
1227 | else if(tmp_error_num) |
1228 | thd->clear_error(); |
1229 | if (tmp_error_num != ER_CON_COUNT_ERROR) |
1230 | { |
1231 | fault_count++; |
1232 | error_num = 0; |
1233 | if ( |
1234 | !(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) && |
1235 | fault_count > full_mon_count / 2 |
1236 | ) { |
1237 | mon_table_result->result_status = SPIDER_LINK_MON_NG; |
1238 | DBUG_PRINT("info" ,("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 2" )); |
1239 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1240 | { |
1241 | /* |
1242 | pthread_mutex_lock(&table_mon_list->update_status_mutex); |
1243 | */ |
1244 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1245 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1246 | { |
1247 | table_mon_list->mon_status = SPIDER_LINK_MON_NG; |
1248 | table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG; |
1249 | spider_update_link_status_for_share(conv_name.c_ptr(), |
1250 | conv_name_length, link_idx, SPIDER_LINK_STATUS_NG); |
1251 | spider_sys_update_tables_link_status(trx->thd, |
1252 | conv_name.c_ptr(), conv_name_length, link_idx, |
1253 | SPIDER_LINK_STATUS_NG, TRUE); |
1254 | spider_sys_log_tables_link_failed(trx->thd, |
1255 | conv_name.c_ptr(), conv_name_length, link_idx, TRUE); |
1256 | status_changed_to_ng = TRUE; |
1257 | } |
1258 | /* |
1259 | pthread_mutex_unlock(&table_mon_list->update_status_mutex); |
1260 | */ |
1261 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1262 | if (status_changed_to_ng) |
1263 | { |
1264 | bool is_error = trx->thd->is_error(); |
1265 | spider_get_ping_table_gtid_pos(trx, trx->thd, |
1266 | &conv_name, conv_name_length, link_idx, server_id, TRUE, |
1267 | &tmp_str); |
1268 | if (!is_error && trx->thd->is_error()) |
1269 | trx->thd->clear_error(); |
1270 | } |
1271 | } |
1272 | goto end; |
1273 | } |
1274 | } |
1275 | } else { |
1276 | success_count++; |
1277 | if ( |
1278 | !(flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) && |
1279 | success_count > full_mon_count / 2 |
1280 | ) { |
1281 | mon_table_result->result_status = SPIDER_LINK_MON_OK; |
1282 | DBUG_PRINT("info" ,("spider mon_table_result->result_status=SPIDER_LINK_MON_OK 1" )); |
1283 | goto end; |
1284 | } |
1285 | } |
1286 | |
1287 | if (tmp_sid < 0) |
1288 | { |
1289 | if (!pthread_mutex_trylock(&table_mon_list->receptor_mutex)) |
1290 | get_lock = TRUE; |
1291 | } |
1292 | |
1293 | if ( |
1294 | tmp_sid >= 0 || |
1295 | get_lock |
1296 | ) { |
1297 | table_mon = table_mon_list->current->next; |
1298 | while (TRUE) |
1299 | { |
1300 | if (!table_mon) |
1301 | table_mon = table_mon_list->first; |
1302 | if ( |
1303 | table_mon->server_id == first_sid || |
1304 | current_mon_count > full_mon_count |
1305 | ) { |
1306 | if ( |
1307 | (flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) && |
1308 | fault_count > full_mon_count / 2 |
1309 | ) { |
1310 | mon_table_result->result_status = SPIDER_LINK_MON_NG; |
1311 | DBUG_PRINT("info" ,("spider mon_table_result->result_status=SPIDER_LINK_MON_NG 3" )); |
1312 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1313 | { |
1314 | /* |
1315 | pthread_mutex_lock(&table_mon_list->update_status_mutex); |
1316 | */ |
1317 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1318 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1319 | { |
1320 | table_mon_list->mon_status = SPIDER_LINK_MON_NG; |
1321 | table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG; |
1322 | spider_update_link_status_for_share(conv_name.c_ptr(), |
1323 | conv_name_length, link_idx, SPIDER_LINK_STATUS_NG); |
1324 | spider_sys_update_tables_link_status(trx->thd, |
1325 | conv_name.c_ptr(), conv_name_length, link_idx, |
1326 | SPIDER_LINK_STATUS_NG, TRUE); |
1327 | spider_sys_log_tables_link_failed(trx->thd, |
1328 | conv_name.c_ptr(), conv_name_length, link_idx, TRUE); |
1329 | status_changed_to_ng = TRUE; |
1330 | } |
1331 | /* |
1332 | pthread_mutex_unlock(&table_mon_list->update_status_mutex); |
1333 | */ |
1334 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1335 | if (status_changed_to_ng) |
1336 | { |
1337 | bool is_error = trx->thd->is_error(); |
1338 | spider_get_ping_table_gtid_pos(trx, trx->thd, |
1339 | &conv_name, conv_name_length, link_idx, server_id, TRUE, |
1340 | &tmp_str); |
1341 | if (!is_error && trx->thd->is_error()) |
1342 | trx->thd->clear_error(); |
1343 | } |
1344 | } |
1345 | } else if ( |
1346 | (flags & SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES) && |
1347 | success_count > full_mon_count / 2 |
1348 | ) { |
1349 | mon_table_result->result_status = SPIDER_LINK_MON_OK; |
1350 | DBUG_PRINT("info" ,("spider mon_table_result->result_status=SPIDER_LINK_MON_OK 2" )); |
1351 | } else if (success_count + fault_count > full_mon_count / 2) |
1352 | { |
1353 | mon_table_result->result_status = SPIDER_LINK_MON_DRAW; |
1354 | DBUG_PRINT("info" ,( |
1355 | "spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW 1" )); |
1356 | } else { |
1357 | mon_table_result->result_status = SPIDER_LINK_MON_DRAW_FEW_MON; |
1358 | DBUG_PRINT("info" ,( |
1359 | "spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1" )); |
1360 | } |
1361 | table_mon_list->last_receptor_result = mon_table_result->result_status; |
1362 | break; |
1363 | } |
1364 | if ((mon_conn = spider_get_ping_table_tgt_conn(trx, |
1365 | table_mon->share, &error_num)) |
1366 | ) { |
1367 | if (!spider_db_udf_ping_table_mon_next( |
1368 | thd, table_mon, mon_conn, mon_table_result, args->args[0], |
1369 | args->lengths[0], link_idx, |
1370 | where_clause, args->lengths[4], first_sid, full_mon_count, |
1371 | current_mon_count, success_count, fault_count, flags, limit)) |
1372 | { |
1373 | if ( |
1374 | mon_table_result->result_status == SPIDER_LINK_MON_NG && |
1375 | table_mon_list->mon_status != SPIDER_LINK_MON_NG |
1376 | ) { |
1377 | /* |
1378 | pthread_mutex_lock(&table_mon_list->update_status_mutex); |
1379 | */ |
1380 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1381 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1382 | { |
1383 | table_mon_list->mon_status = SPIDER_LINK_MON_NG; |
1384 | table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG; |
1385 | spider_update_link_status_for_share(conv_name.c_ptr(), |
1386 | conv_name_length, link_idx, SPIDER_LINK_STATUS_NG); |
1387 | spider_sys_update_tables_link_status(trx->thd, |
1388 | conv_name.c_ptr(), conv_name_length, link_idx, |
1389 | SPIDER_LINK_STATUS_NG, TRUE); |
1390 | spider_sys_log_tables_link_failed(trx->thd, |
1391 | conv_name.c_ptr(), conv_name_length, link_idx, TRUE); |
1392 | status_changed_to_ng = TRUE; |
1393 | } |
1394 | /* |
1395 | pthread_mutex_unlock(&table_mon_list->update_status_mutex); |
1396 | */ |
1397 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1398 | if (status_changed_to_ng) |
1399 | { |
1400 | bool is_error = trx->thd->is_error(); |
1401 | spider_get_ping_table_gtid_pos(trx, trx->thd, |
1402 | &conv_name, conv_name_length, link_idx, server_id, TRUE, |
1403 | &tmp_str); |
1404 | if (!is_error && trx->thd->is_error()) |
1405 | trx->thd->clear_error(); |
1406 | } |
1407 | } |
1408 | table_mon_list->last_receptor_result = |
1409 | mon_table_result->result_status; |
1410 | break; |
1411 | } |
1412 | } |
1413 | thd->clear_error(); |
1414 | table_mon = table_mon->next; |
1415 | current_mon_count++; |
1416 | } |
1417 | if (get_lock) |
1418 | pthread_mutex_unlock(&table_mon_list->receptor_mutex); |
1419 | } else { |
1420 | pthread_mutex_lock(&table_mon_list->receptor_mutex); |
1421 | mon_table_result->result_status = table_mon_list->last_receptor_result; |
1422 | DBUG_PRINT("info" ,("spider mon_table_result->result_status=%d 1" , |
1423 | table_mon_list->last_receptor_result)); |
1424 | pthread_mutex_unlock(&table_mon_list->receptor_mutex); |
1425 | } |
1426 | |
1427 | end: |
1428 | spider_free_ping_table_mon_list(table_mon_list); |
1429 | DBUG_RETURN(mon_table_result->result_status); |
1430 | |
1431 | error_with_free_table_mon_list: |
1432 | spider_free_ping_table_mon_list(table_mon_list); |
1433 | error: |
1434 | *error = 1; |
1435 | DBUG_RETURN(0); |
1436 | } |
1437 | |
1438 | my_bool spider_ping_table_init_body( |
1439 | UDF_INIT *initid, |
1440 | UDF_ARGS *args, |
1441 | char *message |
1442 | ) { |
1443 | int error_num; |
1444 | THD *thd = current_thd; |
1445 | SPIDER_TRX *trx; |
1446 | SPIDER_MON_TABLE_RESULT *mon_table_result = NULL; |
1447 | DBUG_ENTER("spider_ping_table_init_body" ); |
1448 | if (args->arg_count != 10) |
1449 | { |
1450 | strcpy(message, "spider_ping_table() requires 10 arguments" ); |
1451 | goto error; |
1452 | } |
1453 | if ( |
1454 | args->arg_type[0] != STRING_RESULT || |
1455 | args->arg_type[4] != STRING_RESULT |
1456 | ) { |
1457 | strcpy(message, "spider_ping_table() requires string 1st " |
1458 | "and 5th arguments" ); |
1459 | goto error; |
1460 | } |
1461 | if ( |
1462 | args->arg_type[2] != INT_RESULT || |
1463 | args->arg_type[3] != INT_RESULT || |
1464 | args->arg_type[5] != INT_RESULT || |
1465 | args->arg_type[6] != INT_RESULT || |
1466 | args->arg_type[7] != INT_RESULT || |
1467 | args->arg_type[8] != INT_RESULT || |
1468 | args->arg_type[9] != INT_RESULT |
1469 | ) { |
1470 | strcpy(message, "spider_ping_table() requires integer 3rd, 4,6,7,8," |
1471 | "9th and 10th argument" ); |
1472 | goto error; |
1473 | } |
1474 | if ( |
1475 | args->arg_type[1] != INT_RESULT && |
1476 | args->arg_type[1] != STRING_RESULT |
1477 | ) { |
1478 | strcpy(message, "spider_ping_table() requires string or integer for " |
1479 | "2nd argument" ); |
1480 | goto error; |
1481 | } |
1482 | |
1483 | if (!(trx = spider_get_trx(thd, TRUE, &error_num))) |
1484 | { |
1485 | my_error(error_num, MYF(0)); |
1486 | strcpy(message, spider_stmt_da_message(thd)); |
1487 | goto error; |
1488 | } |
1489 | |
1490 | if (!(mon_table_result = (SPIDER_MON_TABLE_RESULT *) |
1491 | spider_malloc(spider_current_trx, 11, sizeof(SPIDER_MON_TABLE_RESULT), |
1492 | MYF(MY_WME | MY_ZEROFILL))) |
1493 | ) { |
1494 | strcpy(message, "spider_ping_table() out of memory" ); |
1495 | goto error; |
1496 | } |
1497 | mon_table_result->trx = trx; |
1498 | initid->ptr = (char *) mon_table_result; |
1499 | DBUG_RETURN(FALSE); |
1500 | |
1501 | error: |
1502 | if (mon_table_result) |
1503 | { |
1504 | spider_free(spider_current_trx, mon_table_result, MYF(0)); |
1505 | } |
1506 | DBUG_RETURN(TRUE); |
1507 | } |
1508 | |
1509 | void spider_ping_table_deinit_body( |
1510 | UDF_INIT *initid |
1511 | ) { |
1512 | SPIDER_MON_TABLE_RESULT *mon_table_result = |
1513 | (SPIDER_MON_TABLE_RESULT *) initid->ptr; |
1514 | DBUG_ENTER("spider_ping_table_deinit_body" ); |
1515 | if (mon_table_result) |
1516 | { |
1517 | spider_free(spider_current_trx, mon_table_result, MYF(0)); |
1518 | } |
1519 | DBUG_VOID_RETURN; |
1520 | } |
1521 | |
1522 | long long spider_flush_table_mon_cache_body() |
1523 | { |
1524 | DBUG_ENTER("spider_flush_table_mon_cache_body" ); |
1525 | spider_mon_table_cache_version_req++; |
1526 | DBUG_RETURN(1); |
1527 | } |
1528 | |
1529 | void spider_ping_table_free_mon_list( |
1530 | SPIDER_TABLE_MON_LIST *table_mon_list |
1531 | ) { |
1532 | DBUG_ENTER("spider_ping_table_free_mon_list" ); |
1533 | if (table_mon_list) |
1534 | { |
1535 | spider_ping_table_free_mon(table_mon_list->first); |
1536 | spider_free_tmp_share_alloc(table_mon_list->share); |
1537 | pthread_mutex_destroy(&table_mon_list->update_status_mutex); |
1538 | pthread_mutex_destroy(&table_mon_list->monitor_mutex); |
1539 | pthread_mutex_destroy(&table_mon_list->receptor_mutex); |
1540 | pthread_mutex_destroy(&table_mon_list->caller_mutex); |
1541 | spider_free(spider_current_trx, table_mon_list, MYF(0)); |
1542 | } |
1543 | DBUG_VOID_RETURN; |
1544 | } |
1545 | |
1546 | void spider_ping_table_free_mon( |
1547 | SPIDER_TABLE_MON *table_mon |
1548 | ) { |
1549 | SPIDER_TABLE_MON *table_mon_next; |
1550 | DBUG_ENTER("spider_ping_table_free_mon" ); |
1551 | while (table_mon) |
1552 | { |
1553 | spider_free_tmp_share_alloc(table_mon->share); |
1554 | table_mon_next = table_mon->next; |
1555 | spider_free(spider_current_trx, table_mon, MYF(0)); |
1556 | table_mon = table_mon_next; |
1557 | } |
1558 | DBUG_VOID_RETURN; |
1559 | } |
1560 | |
1561 | int spider_ping_table_mon_from_table( |
1562 | SPIDER_TRX *trx, |
1563 | THD *thd, |
1564 | SPIDER_SHARE *share, |
1565 | int base_link_idx, |
1566 | uint32 server_id, |
1567 | char *conv_name, |
1568 | uint conv_name_length, |
1569 | int link_idx, |
1570 | char *where_clause, |
1571 | uint where_clause_length, |
1572 | long monitoring_kind, |
1573 | longlong monitoring_limit, |
1574 | long monitoring_flag, |
1575 | bool need_lock |
1576 | ) { |
1577 | int error_num = 0, current_mon_count, flags; |
1578 | uint32 first_sid; |
1579 | /* |
1580 | THD *thd = trx->thd; |
1581 | */ |
1582 | SPIDER_TABLE_MON_LIST *table_mon_list; |
1583 | SPIDER_TABLE_MON *table_mon; |
1584 | SPIDER_MON_TABLE_RESULT mon_table_result; |
1585 | SPIDER_CONN *mon_conn; |
1586 | TABLE_SHARE *table_share = share->table_share; |
1587 | char link_idx_str[SPIDER_CONNECT_INFO_MAX_LEN + 1]; |
1588 | int link_idx_str_length; |
1589 | uint sql_command = thd_sql_command(thd); |
1590 | DBUG_ENTER("spider_ping_table_mon_from_table" ); |
1591 | if (table_share->tmp_table != NO_TMP_TABLE) |
1592 | { |
1593 | my_printf_error(ER_SPIDER_TMP_TABLE_MON_NUM, |
1594 | ER_SPIDER_TMP_TABLE_MON_STR, MYF(0)); |
1595 | DBUG_RETURN(ER_SPIDER_TMP_TABLE_MON_NUM); |
1596 | } |
1597 | if ( |
1598 | sql_command == SQLCOM_DROP_TABLE || |
1599 | sql_command == SQLCOM_ALTER_TABLE |
1600 | ) { |
1601 | my_printf_error(ER_SPIDER_MON_AT_ALTER_TABLE_NUM, |
1602 | ER_SPIDER_MON_AT_ALTER_TABLE_STR, MYF(0)); |
1603 | DBUG_RETURN(ER_SPIDER_MON_AT_ALTER_TABLE_NUM); |
1604 | } |
1605 | DBUG_PRINT("info" ,("spider thd->killed=%s" , |
1606 | thd ? (thd->killed ? "TRUE" : "FALSE" ) : "NULL" )); |
1607 | DBUG_PRINT("info" ,("spider abort_loop=%s" , |
1608 | *spd_abort_loop ? "TRUE" : "FALSE" )); |
1609 | if ( |
1610 | (thd && thd->killed) || |
1611 | *spd_abort_loop |
1612 | ) { |
1613 | DBUG_RETURN(ER_SPIDER_COND_SKIP_NUM); |
1614 | } |
1615 | |
1616 | if (share->static_link_ids[link_idx]) |
1617 | { |
1618 | memcpy(link_idx_str, share->static_link_ids[link_idx], |
1619 | share->static_link_ids_lengths[link_idx] + 1); |
1620 | link_idx_str_length = share->static_link_ids_lengths[link_idx]; |
1621 | } else { |
1622 | link_idx_str_length = my_sprintf(link_idx_str, (link_idx_str, "%010d" , |
1623 | link_idx)); |
1624 | } |
1625 | char *buf = (char *) my_alloca(conv_name_length + link_idx_str_length + 1); |
1626 | if (!buf) |
1627 | { |
1628 | my_error(HA_ERR_OUT_OF_MEM, MYF(0)); |
1629 | DBUG_RETURN(HA_ERR_OUT_OF_MEM); |
1630 | } |
1631 | buf[conv_name_length + link_idx_str_length] = '\0'; |
1632 | spider_string conv_name_str(buf, conv_name_length + link_idx_str_length + 1, |
1633 | system_charset_info); |
1634 | conv_name_str.init_calc_mem(136); |
1635 | conv_name_str.length(0); |
1636 | conv_name_str.q_append(conv_name, conv_name_length); |
1637 | conv_name_str.q_append(link_idx_str, link_idx_str_length + 1); |
1638 | conv_name_str.length(conv_name_str.length() - 1); |
1639 | |
1640 | if (monitoring_kind == 1) |
1641 | flags = SPIDER_UDF_PING_TABLE_PING_ONLY; |
1642 | else if (monitoring_kind == 3) |
1643 | flags = SPIDER_UDF_PING_TABLE_USE_WHERE; |
1644 | else |
1645 | flags = 0; |
1646 | |
1647 | if (monitoring_flag & 1) |
1648 | flags |= SPIDER_UDF_PING_TABLE_USE_ALL_MONITORING_NODES; |
1649 | |
1650 | if (!(table_mon_list = spider_get_ping_table_mon_list(trx, thd, |
1651 | &conv_name_str, conv_name_length, link_idx, |
1652 | share->static_link_ids[link_idx], |
1653 | share->static_link_ids_lengths[link_idx], |
1654 | server_id, need_lock, &error_num))) |
1655 | { |
1656 | my_afree(buf); |
1657 | goto end; |
1658 | } |
1659 | |
1660 | if (table_mon_list->mon_status == SPIDER_LINK_MON_NG) |
1661 | { |
1662 | DBUG_PRINT("info" , |
1663 | ("spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG" , link_idx)); |
1664 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1665 | share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG; |
1666 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1667 | error_num = ER_SPIDER_LINK_MON_NG_NUM; |
1668 | my_printf_error(error_num, |
1669 | ER_SPIDER_LINK_MON_NG_STR, MYF(0), |
1670 | table_mon_list->share->tgt_dbs[0], |
1671 | table_mon_list->share->tgt_table_names[0]); |
1672 | my_afree(buf); |
1673 | goto end_with_free_table_mon_list; |
1674 | } |
1675 | |
1676 | if (!pthread_mutex_trylock(&table_mon_list->caller_mutex)) |
1677 | { |
1678 | table_mon = table_mon_list->current; |
1679 | first_sid = table_mon->server_id; |
1680 | current_mon_count = 1; |
1681 | while (TRUE) |
1682 | { |
1683 | DBUG_PRINT("info" ,("spider thd->killed=%s" , |
1684 | thd ? (thd->killed ? "TRUE" : "FALSE" ) : "NULL" )); |
1685 | DBUG_PRINT("info" ,("spider abort_loop=%s" , |
1686 | *spd_abort_loop ? "TRUE" : "FALSE" )); |
1687 | if ( |
1688 | (thd && thd->killed) || |
1689 | *spd_abort_loop |
1690 | ) { |
1691 | error_num = ER_SPIDER_COND_SKIP_NUM; |
1692 | break; |
1693 | } else { |
1694 | if (!table_mon) |
1695 | table_mon = table_mon_list->first; |
1696 | if ( |
1697 | current_mon_count > table_mon_list->list_size || |
1698 | (current_mon_count > 1 && table_mon->server_id == first_sid) |
1699 | ) { |
1700 | table_mon_list->last_caller_result = SPIDER_LINK_MON_DRAW_FEW_MON; |
1701 | mon_table_result.result_status = SPIDER_LINK_MON_DRAW_FEW_MON; |
1702 | DBUG_PRINT("info" ,( |
1703 | "spider mon_table_result->result_status=SPIDER_LINK_MON_DRAW_FEW_MON 1" )); |
1704 | error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM; |
1705 | my_printf_error(error_num, |
1706 | ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0), |
1707 | table_mon_list->share->tgt_dbs[0], |
1708 | table_mon_list->share->tgt_table_names[0]); |
1709 | break; |
1710 | } |
1711 | int prev_error = 0; |
1712 | char prev_error_msg[MYSQL_ERRMSG_SIZE]; |
1713 | if (thd->is_error()) |
1714 | { |
1715 | prev_error = spider_stmt_da_sql_errno(thd); |
1716 | strmov(prev_error_msg, spider_stmt_da_message(thd)); |
1717 | thd->clear_error(); |
1718 | } |
1719 | if ((mon_conn = spider_get_ping_table_tgt_conn(trx, |
1720 | table_mon->share, &error_num)) |
1721 | ) { |
1722 | if (!spider_db_udf_ping_table_mon_next( |
1723 | thd, table_mon, mon_conn, &mon_table_result, conv_name, |
1724 | conv_name_length, link_idx, |
1725 | where_clause, where_clause_length, -1, table_mon_list->list_size, |
1726 | 0, 0, 0, flags, monitoring_limit)) |
1727 | { |
1728 | if ( |
1729 | mon_table_result.result_status == SPIDER_LINK_MON_NG && |
1730 | table_mon_list->mon_status != SPIDER_LINK_MON_NG |
1731 | ) { |
1732 | /* |
1733 | pthread_mutex_lock(&table_mon_list->update_status_mutex); |
1734 | */ |
1735 | pthread_mutex_lock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1736 | if (table_mon_list->mon_status != SPIDER_LINK_MON_NG) |
1737 | { |
1738 | table_mon_list->mon_status = SPIDER_LINK_MON_NG; |
1739 | table_mon_list->share->link_statuses[0] = SPIDER_LINK_STATUS_NG; |
1740 | DBUG_PRINT("info" , ( |
1741 | "spider share->link_statuses[%d]=SPIDER_LINK_STATUS_NG" , |
1742 | link_idx)); |
1743 | share->link_statuses[link_idx] = SPIDER_LINK_STATUS_NG; |
1744 | spider_sys_update_tables_link_status(thd, conv_name, |
1745 | conv_name_length, link_idx, SPIDER_LINK_STATUS_NG, need_lock); |
1746 | spider_sys_log_tables_link_failed(thd, conv_name, |
1747 | conv_name_length, link_idx, need_lock); |
1748 | } |
1749 | /* |
1750 | pthread_mutex_unlock(&table_mon_list->update_status_mutex); |
1751 | */ |
1752 | pthread_mutex_unlock(&spider_udf_table_mon_mutexes[table_mon_list->mutex_hash]); |
1753 | } |
1754 | table_mon_list->last_caller_result = mon_table_result.result_status; |
1755 | if (mon_table_result.result_status == SPIDER_LINK_MON_OK) |
1756 | { |
1757 | if (prev_error) |
1758 | my_message(prev_error, prev_error_msg, MYF(0)); |
1759 | error_num = ER_SPIDER_LINK_MON_OK_NUM; |
1760 | my_printf_error(error_num, |
1761 | ER_SPIDER_LINK_MON_OK_STR, MYF(0), |
1762 | table_mon_list->share->tgt_dbs[0], |
1763 | table_mon_list->share->tgt_table_names[0]); |
1764 | break; |
1765 | } |
1766 | if (mon_table_result.result_status == SPIDER_LINK_MON_NG) |
1767 | { |
1768 | error_num = ER_SPIDER_LINK_MON_NG_NUM; |
1769 | my_printf_error(error_num, |
1770 | ER_SPIDER_LINK_MON_NG_STR, MYF(0), |
1771 | table_mon_list->share->tgt_dbs[0], |
1772 | table_mon_list->share->tgt_table_names[0]); |
1773 | break; |
1774 | } |
1775 | if (mon_table_result.result_status == |
1776 | SPIDER_LINK_MON_DRAW_FEW_MON) |
1777 | { |
1778 | error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM; |
1779 | my_printf_error(error_num, |
1780 | ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0), |
1781 | table_mon_list->share->tgt_dbs[0], |
1782 | table_mon_list->share->tgt_table_names[0]); |
1783 | break; |
1784 | } |
1785 | error_num = ER_SPIDER_LINK_MON_DRAW_NUM; |
1786 | my_printf_error(error_num, |
1787 | ER_SPIDER_LINK_MON_DRAW_STR, MYF(0), |
1788 | table_mon_list->share->tgt_dbs[0], |
1789 | table_mon_list->share->tgt_table_names[0]); |
1790 | break; |
1791 | } |
1792 | } |
1793 | table_mon = table_mon->next; |
1794 | current_mon_count++; |
1795 | } |
1796 | } |
1797 | pthread_mutex_unlock(&table_mon_list->caller_mutex); |
1798 | } else { |
1799 | pthread_mutex_lock(&table_mon_list->caller_mutex); |
1800 | DBUG_PRINT("info" ,("spider thd->killed=%s" , |
1801 | thd ? (thd->killed ? "TRUE" : "FALSE" ) : "NULL" )); |
1802 | DBUG_PRINT("info" ,("spider abort_loop=%s" , |
1803 | *spd_abort_loop ? "TRUE" : "FALSE" )); |
1804 | if ( |
1805 | (thd && thd->killed) || |
1806 | *spd_abort_loop |
1807 | ) { |
1808 | error_num = ER_SPIDER_COND_SKIP_NUM; |
1809 | } else { |
1810 | switch (table_mon_list->last_caller_result) |
1811 | { |
1812 | case SPIDER_LINK_MON_OK: |
1813 | error_num = ER_SPIDER_LINK_MON_OK_NUM; |
1814 | my_printf_error(error_num, |
1815 | ER_SPIDER_LINK_MON_OK_STR, MYF(0), |
1816 | table_mon_list->share->tgt_dbs[0], |
1817 | table_mon_list->share->tgt_table_names[0]); |
1818 | break; |
1819 | case SPIDER_LINK_MON_NG: |
1820 | error_num = ER_SPIDER_LINK_MON_NG_NUM; |
1821 | my_printf_error(error_num, |
1822 | ER_SPIDER_LINK_MON_NG_STR, MYF(0), |
1823 | table_mon_list->share->tgt_dbs[0], |
1824 | table_mon_list->share->tgt_table_names[0]); |
1825 | break; |
1826 | case SPIDER_LINK_MON_DRAW_FEW_MON: |
1827 | error_num = ER_SPIDER_LINK_MON_DRAW_FEW_MON_NUM; |
1828 | my_printf_error(error_num, |
1829 | ER_SPIDER_LINK_MON_DRAW_FEW_MON_STR, MYF(0), |
1830 | table_mon_list->share->tgt_dbs[0], |
1831 | table_mon_list->share->tgt_table_names[0]); |
1832 | break; |
1833 | default: |
1834 | error_num = ER_SPIDER_LINK_MON_DRAW_NUM; |
1835 | my_printf_error(error_num, |
1836 | ER_SPIDER_LINK_MON_DRAW_STR, MYF(0), |
1837 | table_mon_list->share->tgt_dbs[0], |
1838 | table_mon_list->share->tgt_table_names[0]); |
1839 | break; |
1840 | } |
1841 | } |
1842 | pthread_mutex_unlock(&table_mon_list->caller_mutex); |
1843 | } |
1844 | |
1845 | my_afree(buf); |
1846 | end_with_free_table_mon_list: |
1847 | spider_free_ping_table_mon_list(table_mon_list); |
1848 | end: |
1849 | DBUG_RETURN(error_num); |
1850 | } |
1851 | |