void native_procedure_init() { TABLE_LIST tables; MEM_ROOT mem; READ_RECORD read_record_info; TABLE *table; int error; DBUG_ENTER("native_procedure_init"); #ifdef HAVE_PSI_INTERFACE init_psi_keys(); #endif mysql_rwlock_init(key_THR_LOCK_np, &THR_LOCK_np); init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0); // Initialize THD (we don't have THD during server startup). THD *new_thd = new THD; if (!new_thd) { // NO_LINT_DEBUG sql_print_error("Can't allocate memory for native procedures"); free_root(&mem, MYF(0)); DBUG_VOID_RETURN; } new_thd->thread_stack = (char *)&new_thd; new_thd->store_globals(); new_thd->set_db(system_db, sizeof(system_db) - 1); // Open mysql.native_proc table. tables.init_one_table(system_db, sizeof(system_db), system_table, sizeof(system_table), system_table, TL_READ); if (open_and_lock_tables(new_thd, &tables, FALSE, MYSQL_LOCK_IGNORE_TIMEOUT)) { // NO_LINT_DEBUG sql_print_error("Can't open the mysql.native_proc table. " "Please run mysql_upgrade to create it."); goto exit; } // Read records in table. table = tables.table; if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 1, FALSE)) goto exit; table->use_all_columns(); while (!(error = read_record_info.read_record(&read_record_info))) { native_proc np; np.name = get_field(&mem, table->field[0]); np.dl = get_field(&mem, table->field[2]); DBUG_ASSERT(strcmp("native", get_field(&mem, table->field[1])) == 0); if (add_native_procedure(&np)) { // NO_LINT_DEBUG sql_print_error("Error adding native procedure: '%.64s'", np.name.c_str()); } else { DBUG_ASSERT(proc_map.count(np.name) > 0); proc_map[np.name].enabled = true; } } if (error > 0) { // NO_LINT_DEBUG sql_print_error("Got unknown error: %d", my_errno); } end_read_record(&read_record_info); // Force close to free memory. table->m_needs_reopen = TRUE; exit: close_mysql_tables(new_thd); free_root(&mem, MYF(0)); delete new_thd; my_pthread_setspecific_ptr(THR_THD, 0); DBUG_VOID_RETURN; }
看源码 它是先从 system_table 中找相关符号 然后读取,之后做 add_native_procedure
static int add_native_procedure(native_proc *np) { void *dl = nullptr; bool dlclose_needed = false; if (proc_map.count(np->name) > 0) { my_error(ER_NP_PROCEDURE_EXISTS, MYF(0), np->name.c_str()); return 1; } dl = search_dlhandle(np->dl); // If dlhandle not present, dlopen the shared object. if (dl == nullptr) { char dlpath[FN_REFLEN]; strxnmov(dlpath, sizeof(dlpath) - 1, opt_plugin_dir, "/", np->dl.c_str(), NullS); unpack_filename(dlpath, dlpath); if (!(dl = dlopen(dlpath, RTLD_NOW))) { const char *errmsg; int error_number = dlopen_errno; DLERROR_GENERATE(errmsg, error_number); my_error(ER_CANT_OPEN_LIBRARY, MYF(0), np->dl.c_str(), error_number, errmsg); return 1; } dlclose_needed = true; } np->dlhandle = dl; // Lookup function pointer with dlsym. if (!(np->proc = (proc_t *)dlsym(np->dlhandle, np->name.c_str()))) { my_error(ER_CANT_FIND_DL_ENTRY, MYF(0), np->name.c_str()); if (dlclose_needed) { DBUG_ASSERT(dl); dlclose(dl); } return 1; } // Insert into proc_map. proc_map[np->name] = *np; return 0; }
这里做了将 名字 和 函数做了关联 分别用了 dlopen(打开句柄),dlsym符号链接