📄 instance.cc
字号:
is already started*/int Instance::start(){ /* clear crash flag */ pthread_mutex_lock(&LOCK_instance); crashed= 0; pthread_mutex_unlock(&LOCK_instance); if (!is_running()) { remove_pid(); /* No need to monitor this thread in the Thread_registry, as all instances are to be stopped during shutdown. */ pthread_t proxy_thd_id; pthread_attr_t proxy_thd_attr; int rc; pthread_attr_init(&proxy_thd_attr); pthread_attr_setdetachstate(&proxy_thd_attr, PTHREAD_CREATE_DETACHED); rc= pthread_create(&proxy_thd_id, &proxy_thd_attr, proxy, this); pthread_attr_destroy(&proxy_thd_attr); if (rc) { log_error("Instance::start(): pthread_create(proxy) failed"); return ER_CANNOT_START_INSTANCE; } return 0; } /* the instance is started already */ return ER_INSTANCE_ALREADY_STARTED;}/* The method sets the crash flag and wakes all waiters on COND_instance_stopped and COND_guardian SYNOPSYS set_crash_flag_n_wake_all() DESCRIPTION The method is called when an instance is crashed or terminated. In the former case it might indicate that guardian probably should restart it. RETURN Function returns no value*/void Instance::set_crash_flag_n_wake_all(){ /* set instance state to crashed */ pthread_mutex_lock(&LOCK_instance); crashed= 1; pthread_mutex_unlock(&LOCK_instance); /* Wake connection threads waiting for an instance to stop. This is needed if a user issued command to stop an instance via mysql connection. This is not the case if Guardian stop the thread. */ pthread_cond_signal(&COND_instance_stopped); /* wake guardian */ pthread_cond_signal(&instance_map->guardian->COND_guardian);}Instance::Instance(): crashed(0){ pthread_mutex_init(&LOCK_instance, 0); pthread_cond_init(&COND_instance_stopped, 0);}Instance::~Instance(){ pthread_cond_destroy(&COND_instance_stopped); pthread_mutex_destroy(&LOCK_instance);}int Instance::is_crashed(){ int val; pthread_mutex_lock(&LOCK_instance); val= crashed; pthread_mutex_unlock(&LOCK_instance); return val;}bool Instance::is_running(){ MYSQL mysql; uint port= 0; const char *socket= NULL; static const char *password= "check_connection"; static const char *username= "MySQL_Instance_Manager"; static const char *access_denied_message= "Access denied for user"; bool return_val; if (options.mysqld_port) port= options.mysqld_port_val; if (options.mysqld_socket) socket= strchr(options.mysqld_socket, '=') + 1; /* no port was specified => instance falled back to default value */ if (!options.mysqld_port && !options.mysqld_socket) port= SERVER_DEFAULT_PORT; pthread_mutex_lock(&LOCK_instance); mysql_init(&mysql); /* try to connect to a server with a fake username/password pair */ if (mysql_real_connect(&mysql, LOCAL_HOST, username, password, NullS, port, socket, 0)) { /* We have successfully connected to the server using fake username/password. Write a warning to the logfile. */ log_info("The Instance Manager was able to log into you server \ with faked compiled-in password while checking server status. \ Looks like something is wrong."); pthread_mutex_unlock(&LOCK_instance); return_val= TRUE; /* server is alive */ } else return_val= test(!strncmp(access_denied_message, mysql_error(&mysql), sizeof(access_denied_message) - 1)); mysql_close(&mysql); pthread_mutex_unlock(&LOCK_instance); return return_val;}/* Stop an instance. SYNOPSYS stop() RETURN: 0 ok ER_INSTANCE_IS_NOT_STARTED Looks like the instance it is not started ER_STOP_INSTANCE mysql_shutdown reported an error*/int Instance::stop(){ struct timespec timeout; uint waitchild= (uint) DEFAULT_SHUTDOWN_DELAY; if (options.shutdown_delay_val) waitchild= options.shutdown_delay_val; kill_instance(SIGTERM); /* sleep on condition to wait for SIGCHLD */ timeout.tv_sec= time(NULL) + waitchild; timeout.tv_nsec= 0; if (pthread_mutex_lock(&LOCK_instance)) goto err; while (options.get_pid() != 0) /* while server isn't stopped */ { int status; status= pthread_cond_timedwait(&COND_instance_stopped, &LOCK_instance, &timeout); if (status == ETIMEDOUT || status == ETIME) break; } pthread_mutex_unlock(&LOCK_instance); kill_instance(SIGKILL); return 0; return ER_INSTANCE_IS_NOT_STARTED;err: return ER_STOP_INSTANCE;}#ifdef __WIN__BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode){ DWORD dwTID, dwCode, dwErr= 0; HANDLE hProcessDup= INVALID_HANDLE_VALUE; HANDLE hRT= NULL; HINSTANCE hKernel= GetModuleHandle("Kernel32"); BOOL bSuccess= FALSE; BOOL bDup= DuplicateHandle(GetCurrentProcess(), hProcess, GetCurrentProcess(), &hProcessDup, PROCESS_ALL_ACCESS, FALSE, 0); // Detect the special case where the process is // already dead... if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) && (dwCode == STILL_ACTIVE)) { FARPROC pfnExitProc; pfnExitProc= GetProcAddress(hKernel, "ExitProcess"); hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pfnExitProc, (PVOID)uExitCode, 0, &dwTID); if (hRT == NULL) dwErr= GetLastError(); } else dwErr= ERROR_PROCESS_ABORTED; if (hRT) { // Must wait process to terminate to // guarantee that it has exited... WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE); CloseHandle(hRT); bSuccess= TRUE; } if (bDup) CloseHandle(hProcessDup); if (!bSuccess) SetLastError(dwErr); return bSuccess;}int kill(pid_t pid, int signum){ HANDLE processhandle= ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid); if (signum == SIGTERM) ::SafeTerminateProcess(processhandle, 0); else ::TerminateProcess(processhandle, -1); return 0;}#endifvoid Instance::kill_instance(int signum){ pid_t pid; /* if there are no pid, everything seems to be fine */ if ((pid= options.get_pid()) != 0) /* get pid from pidfile */ { /* If we cannot kill mysqld, then it has propably crashed. Let us try to remove staled pidfile and return successfully as mysqld is probably stopped. */ if (!kill(pid, signum)) options.unlink_pidfile(); else if (signum == SIGKILL) /* really killed instance with SIGKILL */ log_error("The instance %s is being stopped forsibly. Normally \ it should not happed. Probably the instance has been \ hanging. You should also check your IM setup", options.instance_name); } return;}/* We execute this function to initialize instance parameters. Return value: 0 - ok. 1 - unable to init DYNAMIC_ARRAY.*/int Instance::init(const char *name_arg){ return options.init(name_arg);}int Instance::complete_initialization(Instance_map *instance_map_arg, const char *mysqld_path, uint instance_type){ instance_map= instance_map_arg; return options.complete_initialization(mysqld_path, instance_type);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -