1670 lines
56 KiB
Diff
1670 lines
56 KiB
Diff
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
|
|
index b2b64a0..6acfb34 100644
|
|
--- a/include/CMakeLists.txt
|
|
+++ b/include/CMakeLists.txt
|
|
@@ -54,6 +54,7 @@ SET(HEADERS
|
|
m_ctype.h
|
|
my_attribute.h
|
|
my_compiler.h
|
|
+ governor.h
|
|
${HEADERS_GEN_CONFIGURE}
|
|
)
|
|
|
|
diff --git a/include/governor.h b/include/governor.h
|
|
new file mode 100644
|
|
index 0000000..7ee5698
|
|
--- /dev/null
|
|
+++ b/include/governor.h
|
|
@@ -0,0 +1,14 @@
|
|
+/*
|
|
+ * governor_pthread_wrapper.h
|
|
+ *
|
|
+ * Created on: Sep 26, 2012
|
|
+ * Author: alexey
|
|
+*/
|
|
+
|
|
+#ifndef GOVERNOR_PTHREAD_WRAPPER_H_
|
|
+#define GOVERNOR_PTHREAD_WRAPPER_H_
|
|
+
|
|
+#include <stdint.h>
|
|
+
|
|
+
|
|
+#endif /* GOVERNOR_PTHREAD_WRAPPER_H_ */
|
|
diff --git a/include/my_pthread.h b/include/my_pthread.h
|
|
index e521564..a45ad34 100644
|
|
--- a/include/my_pthread.h
|
|
+++ b/include/my_pthread.h
|
|
@@ -192,6 +192,7 @@ int pthread_cancel(pthread_t thread);
|
|
#include <signal.h>
|
|
#undef sigwait
|
|
#endif
|
|
+#include <governor.h>
|
|
#include <pthread.h>
|
|
#ifndef _REENTRANT
|
|
#define _REENTRANT
|
|
@@ -497,6 +498,13 @@ typedef struct st_safe_mutex_info_t
|
|
} safe_mutex_info_t;
|
|
#endif /* SAFE_MUTEX_DETECT_DESTROY */
|
|
|
|
+int put_in_lve(char *user);
|
|
+void lve_thr_exit();
|
|
+void governor_setlve_mysql_thread_info(pid_t thread_id);
|
|
+void governor_detroy_mysql_thread_info();
|
|
+__attribute__((noinline)) void my_release_slot();
|
|
+__attribute__((noinline)) void my_reserve_slot();
|
|
+
|
|
int safe_mutex_init(safe_mutex_t *mp, const pthread_mutexattr_t *attr,
|
|
const char *file, uint line);
|
|
int safe_mutex_lock(safe_mutex_t *mp, my_bool try_lock, const char *file, uint line);
|
|
@@ -512,6 +520,8 @@ void safe_mutex_end(FILE *file);
|
|
|
|
/* Wrappers if safe mutex is actually used */
|
|
#ifdef SAFE_MUTEX
|
|
+
|
|
+
|
|
#undef pthread_mutex_init
|
|
#undef pthread_mutex_lock
|
|
#undef pthread_mutex_unlock
|
|
@@ -565,12 +575,22 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
|
|
#undef pthread_cond_timedwait
|
|
#undef pthread_mutex_trylock
|
|
#define pthread_mutex_init(A,B) my_pthread_fastmutex_init((A),(B))
|
|
-#define pthread_mutex_lock(A) my_pthread_fastmutex_lock(A)
|
|
-#define pthread_mutex_unlock(A) pthread_mutex_unlock(&(A)->mutex)
|
|
+
|
|
+int put_in_lve(char *user);
|
|
+void lve_thr_exit();
|
|
+void governor_setlve_mysql_thread_info(pid_t thread_id);
|
|
+void governor_detroy_mysql_thread_info();
|
|
+__attribute__ ((noinline)) int my_pthread_lvemutex_unlock(pthread_mutex_t *mutex);
|
|
+__attribute__ ((noinline)) int my_pthread_lvemutex_lock(my_pthread_fastmutex_t *mp);
|
|
+__attribute__ ((noinline)) int my_pthread_lvemutex_trylock(pthread_mutex_t *mutex);
|
|
+__attribute__((noinline)) void my_release_slot();
|
|
+__attribute__((noinline)) void my_reserve_slot();
|
|
+#define pthread_mutex_lock(A) my_pthread_lvemutex_lock(A)
|
|
+#define pthread_mutex_unlock(A) my_pthread_lvemutex_unlock(&(A)->mutex)
|
|
+#define pthread_mutex_trylock(A) my_pthread_lvemutex_trylock(&(A)->mutex)
|
|
#define pthread_mutex_destroy(A) pthread_mutex_destroy(&(A)->mutex)
|
|
#define pthread_cond_wait(A,B) pthread_cond_wait((A),&(B)->mutex)
|
|
#define pthread_cond_timedwait(A,B,C) pthread_cond_timedwait((A),&(B)->mutex,(C))
|
|
-#define pthread_mutex_trylock(A) pthread_mutex_trylock(&(A)->mutex)
|
|
#define pthread_mutex_t my_pthread_fastmutex_t
|
|
#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
|
|
|
|
diff --git a/max_connection2_mysql_5_5_30_b403.patch b/max_connection2_mysql_5_5_30_b403.patch
|
|
new file mode 100644
|
|
index 0000000..8eba89d
|
|
diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c
|
|
index 4d05139..4c8cec2 100644
|
|
--- a/mysys/thr_mutex.c
|
|
+++ b/mysys/thr_mutex.c
|
|
@@ -25,12 +25,49 @@
|
|
#include "my_static.h"
|
|
#include <m_string.h>
|
|
|
|
+void * (*governor_load_lve_library)() = NULL;
|
|
+int (*governor_init_lve)() = NULL;
|
|
+void (*governor_destroy_lve)() = NULL;
|
|
+int (*governor_enter_lve)(uint32_t *, char *) = NULL;
|
|
+void (*governor_lve_exit)(uint32_t *) = NULL;
|
|
+int (*governor_enter_lve_light)(uint32_t *) = NULL;
|
|
+void (*governor_lve_exit_null)() = NULL;
|
|
+int (*governor_lve_enter_pid)(pid_t) = NULL;
|
|
+
|
|
+void governor_setlve_mysql_thread_info(pid_t thread_id) {
|
|
+ thread_id = 0;
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) int put_in_lve(char *user) {
|
|
+ user = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void lve_thr_exit() {
|
|
+ return;
|
|
+}
|
|
+
|
|
+void governor_detroy_mysql_thread_info(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_release_slot(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_reserve_slot(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+
|
|
#ifndef DO_NOT_REMOVE_THREAD_WRAPPERS
|
|
/* Remove wrappers */
|
|
#undef pthread_mutex_t
|
|
#undef pthread_mutex_init
|
|
#undef pthread_mutex_lock
|
|
#undef pthread_mutex_unlock
|
|
+#undef pthread_mutex_trylock
|
|
#undef pthread_mutex_destroy
|
|
#undef pthread_cond_wait
|
|
#undef pthread_cond_timedwait
|
|
@@ -399,6 +436,8 @@ void safe_mutex_end(FILE *file __attribute__((unused)))
|
|
|
|
#if defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
|
|
|
|
+#include <linux/unistd.h>
|
|
+
|
|
#include "mysys_priv.h"
|
|
#include "my_static.h"
|
|
#include <m_string.h>
|
|
@@ -492,6 +531,298 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp)
|
|
return pthread_mutex_lock(&mp->mutex);
|
|
}
|
|
|
|
+void * (*governor_load_lve_library)() = NULL;
|
|
+int (*governor_init_lve)() = NULL;
|
|
+void (*governor_destroy_lve)() = NULL;
|
|
+int (*governor_enter_lve)(uint32_t *, char *) = NULL;
|
|
+void (*governor_lve_exit)(uint32_t *) = NULL;
|
|
+int (*governor_enter_lve_light)(uint32_t *) = NULL;
|
|
+void (*governor_lve_exit_null)() = NULL;
|
|
+int (*governor_lve_enter_pid)(pid_t) = NULL;
|
|
+
|
|
+extern CHARSET_INFO my_charset_latin1_bin;
|
|
+CHARSET_INFO governor_charset_bin;
|
|
+
|
|
+__thread uint32_t lve_cookie = 0;
|
|
+
|
|
+pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
|
|
+
|
|
+typedef struct __mysql_mutex {
|
|
+ pid_t *key;
|
|
+ int is_in_lve;
|
|
+ int is_in_mutex;
|
|
+ int put_in_lve;
|
|
+} mysql_mutex;
|
|
+
|
|
+static HASH *mysql_lve_mutex_governor = NULL;
|
|
+
|
|
+__thread mysql_mutex *mysql_lve_mutex_governor_ptr = 0;
|
|
+
|
|
+pthread_mutex_t mtx_mysql_lve_mutex_governor_ptr = PTHREAD_MUTEX_INITIALIZER;
|
|
+
|
|
+void governor_value_destroyed(mysql_mutex *data) {
|
|
+ free(data);
|
|
+}
|
|
+
|
|
+uchar *governor_get_key_table_mutex(mysql_mutex *table_mutex, size_t *length,
|
|
+ my_bool not_used __attribute__((unused))) {
|
|
+ *length = sizeof(table_mutex->key);
|
|
+ return (uchar*) table_mutex->key;
|
|
+}
|
|
+
|
|
+/*
|
|
++ * RETURN
|
|
++ * < 0 s < t
|
|
++ * 0 s == t
|
|
++ * > 0 s > t
|
|
++ */
|
|
+int governor_my_strnncoll_8bit_bin(CHARSET_INFO * cs __attribute__((unused)), const uchar *s,
|
|
+ size_t slen, const uchar *t, size_t tlen, my_bool t_is_prefix) {
|
|
+ int res = 0;
|
|
+ pid_t s1 = (pid_t)s, t1 = (pid_t)t;
|
|
+ if (s1 < t1)
|
|
+ res = -1;
|
|
+ else if (s1 == t1)
|
|
+ res = 0;
|
|
+ else
|
|
+ res = 1;
|
|
+ return res;
|
|
+}
|
|
+
|
|
+void governor_hash_sort_8bit_bin(CHARSET_INFO *cs __attribute__((unused)),
|
|
+ const uchar *key, size_t len,
|
|
+ ulong *nr1, ulong *nr2)
|
|
+{
|
|
+ return;
|
|
+}
|
|
+
|
|
+HASH *governor_create_hash_table() {
|
|
+ mysql_lve_mutex_governor = (HASH *) calloc(1, sizeof(HASH));
|
|
+ if (mysql_lve_mutex_governor) {
|
|
+ memcpy(&governor_charset_bin, &my_charset_latin1_bin,
|
|
+ sizeof(CHARSET_INFO));
|
|
+ governor_charset_bin.coll->strnncoll = governor_my_strnncoll_8bit_bin;
|
|
+ governor_charset_bin.coll->hash_sort = governor_hash_sort_8bit_bin;
|
|
+ if (my_hash_init(mysql_lve_mutex_governor, &governor_charset_bin, 500, 0,
|
|
+ 0, (my_hash_get_key) governor_get_key_table_mutex,
|
|
+ (my_hash_free_key) governor_value_destroyed, 0)) {
|
|
+ mysql_lve_mutex_governor = NULL;
|
|
+ }
|
|
+ }
|
|
+ return mysql_lve_mutex_governor;
|
|
+}
|
|
+
|
|
+int governor_add_mysql_thread_info() {
|
|
+ pid_t *buf = NULL;
|
|
+ pthread_mutex_lock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ mysql_mutex *mm = NULL;
|
|
+ if (!mysql_lve_mutex_governor) {
|
|
+ mysql_lve_mutex_governor = governor_create_hash_table();
|
|
+ if (!mysql_lve_mutex_governor){
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ buf = (pid_t *)syscall(__NR_gettid);
|
|
+ mm = (mysql_mutex *) my_hash_search(mysql_lve_mutex_governor,
|
|
+ (uchar *) buf, sizeof(buf));
|
|
+ if (!mm) {
|
|
+ mm = (mysql_mutex *) calloc(1, sizeof(mysql_mutex));
|
|
+ if (!mm)
|
|
+ return -1;
|
|
+ mm->key = (pid_t *)syscall(__NR_gettid);
|
|
+ if (my_hash_insert(mysql_lve_mutex_governor, (uchar *) mm)) {
|
|
+ free(mm);
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ mysql_lve_mutex_governor_ptr = mm;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void governor_remove_mysql_thread_info() {
|
|
+ pid_t *buf = NULL;
|
|
+ pthread_mutex_lock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ mysql_mutex *mm = NULL;
|
|
+ if (mysql_lve_mutex_governor) {
|
|
+ buf = (pid_t *)syscall(__NR_gettid);
|
|
+ mm = (mysql_mutex *) my_hash_search(mysql_lve_mutex_governor,
|
|
+ (uchar *) buf, sizeof(buf));
|
|
+ if (mm)
|
|
+ my_hash_delete(mysql_lve_mutex_governor, (uchar *) mm);
|
|
+ }
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ mysql_lve_mutex_governor_ptr = NULL;
|
|
+}
|
|
+
|
|
+void governor_setlve_mysql_thread_info(pid_t thread_id) {
|
|
+ pid_t *buf = NULL;
|
|
+ pthread_mutex_lock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ mysql_mutex *mm = NULL;
|
|
+ if (mysql_lve_mutex_governor) {
|
|
+ buf = (pid_t *)thread_id;
|
|
+ mm = (mysql_mutex *) my_hash_search(mysql_lve_mutex_governor,
|
|
+ (uchar *) buf, sizeof(buf));
|
|
+ if (mm) {
|
|
+ if (!mm->is_in_lve) {
|
|
+ mm->put_in_lve = 1;
|
|
+ //if (mm->is_in_mutex) {
|
|
+ // mm->put_in_lve = 1;
|
|
+ //} else {
|
|
+ // mm->put_in_lve = 1;
|
|
+ // governor_lve_enter_pid(thread_id);
|
|
+ //}
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+}
|
|
+
|
|
+void governor_detroy_mysql_thread_info() {
|
|
+ if (mysql_lve_mutex_governor) {
|
|
+ pthread_mutex_lock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ my_hash_free(mysql_lve_mutex_governor);
|
|
+ free(mysql_lve_mutex_governor);
|
|
+ pthread_mutex_unlock(&mtx_mysql_lve_mutex_governor_ptr);
|
|
+ }
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) int put_in_lve(char *user) {
|
|
+ if (governor_add_mysql_thread_info()<0) return -1;
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if (!governor_enter_lve(&lve_cookie, user)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ }
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex = 0;
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void lve_thr_exit() {
|
|
+ if (mysql_lve_mutex_governor_ptr && mysql_lve_mutex_governor_ptr->is_in_lve
|
|
+ == 1) {
|
|
+ governor_lve_exit(&lve_cookie);
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 0;
|
|
+ }
|
|
+ governor_remove_mysql_thread_info();
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) int my_pthread_lvemutex_lock(my_pthread_fastmutex_t *mp) {
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if (mysql_lve_mutex_governor_ptr->is_in_lve == 1) {
|
|
+ governor_lve_exit(&lve_cookie);
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 2;
|
|
+ } else if (mysql_lve_mutex_governor_ptr->is_in_lve > 1) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve++;
|
|
+ } /*else if (mysql_lve_mutex_governor_ptr->put_in_lve
|
|
+ && !mysql_lve_mutex_governor_ptr->is_in_mutex) {
|
|
+ //governor_lve_exit_null();
|
|
+ mysql_lve_mutex_governor_ptr->put_in_lve = 0;
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 2;
|
|
+ }*/
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex++;
|
|
+ }
|
|
+ return my_pthread_fastmutex_lock(mp);
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) int my_pthread_lvemutex_trylock(pthread_mutex_t *mutex) {
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if (mysql_lve_mutex_governor_ptr->is_in_lve == 1) {
|
|
+ governor_lve_exit(&lve_cookie);
|
|
+ }
|
|
+ }
|
|
+ int ret = pthread_mutex_trylock(mutex);
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if (ret != EBUSY){
|
|
+ if (mysql_lve_mutex_governor_ptr->is_in_lve == 1) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 2;
|
|
+ } else if (mysql_lve_mutex_governor_ptr->is_in_lve > 1) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve++;
|
|
+ }
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex++;
|
|
+ } else {
|
|
+ if (mysql_lve_mutex_governor_ptr->is_in_lve == 1){
|
|
+ if (!governor_enter_lve_light(&lve_cookie)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ } else {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 0;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+
|
|
+__attribute__((noinline)) int my_pthread_lvemutex_unlock(
|
|
+ pthread_mutex_t *mutex) {
|
|
+ int ret = pthread_mutex_unlock(mutex);
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if ((mysql_lve_mutex_governor_ptr->is_in_lve == 2)
|
|
+ && governor_enter_lve_light) {
|
|
+ if (!governor_enter_lve_light(&lve_cookie)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ }
|
|
+ } else if (mysql_lve_mutex_governor_ptr->is_in_lve > 2) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve--;
|
|
+ }
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex--;
|
|
+ /*if (mysql_lve_mutex_governor_ptr->put_in_lve
|
|
+ && !mysql_lve_mutex_governor_ptr->is_in_mutex) {
|
|
+ if (governor_enter_lve_light && !governor_enter_lve_light(
|
|
+ &lve_cookie)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ mysql_lve_mutex_governor_ptr->put_in_lve = 0;
|
|
+ }
|
|
+ }*/
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_reserve_slot() {
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if (mysql_lve_mutex_governor_ptr->is_in_lve == 1) {
|
|
+ governor_lve_exit(&lve_cookie);
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 2;
|
|
+ } else if (mysql_lve_mutex_governor_ptr->is_in_lve > 1) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve++;
|
|
+ } /*else if (mysql_lve_mutex_governor_ptr->put_in_lve
|
|
+ && !mysql_lve_mutex_governor_ptr->is_in_mutex) {
|
|
+ //governor_lve_exit_null();
|
|
+ mysql_lve_mutex_governor_ptr->put_in_lve = 0;
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 2;
|
|
+ }*/
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex++;
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_release_slot() {
|
|
+ if (mysql_lve_mutex_governor_ptr) {
|
|
+ if ((mysql_lve_mutex_governor_ptr->is_in_lve == 2)
|
|
+ && governor_enter_lve_light) {
|
|
+ if (!governor_enter_lve_light(&lve_cookie)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ }
|
|
+ } else if (mysql_lve_mutex_governor_ptr->is_in_lve > 2) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve--;
|
|
+ }
|
|
+ mysql_lve_mutex_governor_ptr->is_in_mutex--;
|
|
+ /*if (mysql_lve_mutex_governor_ptr->put_in_lve
|
|
+ && !mysql_lve_mutex_governor_ptr->is_in_mutex) {
|
|
+ if (governor_enter_lve_light && !governor_enter_lve_light(
|
|
+ &lve_cookie)) {
|
|
+ mysql_lve_mutex_governor_ptr->is_in_lve = 1;
|
|
+ mysql_lve_mutex_governor_ptr->put_in_lve = 0;
|
|
+ }
|
|
+ }*/
|
|
+ }
|
|
+ return;
|
|
+}
|
|
+
|
|
+
|
|
|
|
void fastmutex_global_init(void)
|
|
{
|
|
@@ -501,3 +832,45 @@ void fastmutex_global_init(void)
|
|
}
|
|
|
|
#endif /* defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) */
|
|
+
|
|
+#if !defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX)
|
|
+
|
|
+#include <governor.h>
|
|
+
|
|
+void * (*governor_load_lve_library)() = NULL;
|
|
+int (*governor_init_lve)() = NULL;
|
|
+void (*governor_destroy_lve)() = NULL;
|
|
+int (*governor_enter_lve)(uint32_t *, char *) = NULL;
|
|
+void (*governor_lve_exit)(uint32_t *) = NULL;
|
|
+int (*governor_enter_lve_light)(uint32_t *) = NULL;
|
|
+void (*governor_lve_exit_null)() = NULL;
|
|
+int (*governor_lve_enter_pid)(pid_t) = NULL;
|
|
+
|
|
+void governor_setlve_mysql_thread_info(pid_t thread_id) {
|
|
+ thread_id = 0;
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) int put_in_lve(char *user) {
|
|
+ user = NULL;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void lve_thr_exit() {
|
|
+ return;
|
|
+}
|
|
+
|
|
+void governor_detroy_mysql_thread_info(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_release_slot(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+__attribute__((noinline)) void my_reserve_slot(){
|
|
+ return;
|
|
+}
|
|
+
|
|
+
|
|
+#endif
|
|
diff --git a/sql/lex.h b/sql/lex.h
|
|
index 9e90725..33e6d12 100644
|
|
--- a/sql/lex.h
|
|
+++ b/sql/lex.h
|
|
@@ -191,6 +191,10 @@ static SYMBOL symbols[] = {
|
|
{ "ELSE", SYM(ELSE)},
|
|
{ "ELSEIF", SYM(ELSEIF_SYM)},
|
|
{ "ENABLE", SYM(ENABLE_SYM)},
|
|
+ { "ENABLE_GOVERNOR", SYM(ENABLE_GOVERNOR_SYM)},
|
|
+ { "ENABLE_GOVERNOR_RECON", SYM(ENABLE_GOVERNOR_RECONN_SYM)},
|
|
+ { "ENABLE_GOVERNOR_LVE", SYM(ENABLE_GOVERNOR_LVE_SYM)},
|
|
+ { "ENABLE_GOVERNOR_RECON_LVE", SYM(ENABLE_GOVERNOR_RECONN_LVE_SYM)},
|
|
{ "ENCLOSED", SYM(ENCLOSED)},
|
|
{ "END", SYM(END)},
|
|
{ "ENDS", SYM(ENDS_SYM)},
|
|
@@ -316,6 +320,7 @@ static SYMBOL symbols[] = {
|
|
{ "LONGTEXT", SYM(LONGTEXT)},
|
|
{ "LOOP", SYM(LOOP_SYM)},
|
|
{ "LOW_PRIORITY", SYM(LOW_PRIORITY)},
|
|
+ { "LVECMD", SYM(LVECMD_SYM)},
|
|
{ "MASTER", SYM(MASTER_SYM)},
|
|
{ "MASTER_CONNECT_RETRY", SYM(MASTER_CONNECT_RETRY_SYM)},
|
|
{ "MASTER_HOST", SYM(MASTER_HOST_SYM)},
|
|
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
|
|
index 9df9436..ee14dff 100644
|
|
--- a/sql/mysqld.cc
|
|
+++ b/sql/mysqld.cc
|
|
@@ -69,6 +69,9 @@
|
|
#include "debug_sync.h"
|
|
#include "sql_callback.h"
|
|
|
|
+#include <dlfcn.h>
|
|
+#include <linux/unistd.h>
|
|
+
|
|
#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
|
|
#include "../storage/perfschema/pfs_server.h"
|
|
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
|
|
@@ -186,6 +189,10 @@ typedef fp_except fp_except_t;
|
|
# endif
|
|
#endif
|
|
|
|
+#ifndef GETTID
|
|
+pid_t gettid(void) {return syscall(__NR_gettid);}
|
|
+#endif
|
|
+
|
|
extern "C" my_bool reopen_fstreams(const char *filename,
|
|
FILE *outstream, FILE *errstream);
|
|
|
|
@@ -245,6 +252,28 @@ inline void setup_fpu()
|
|
|
|
} /* cplusplus */
|
|
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif /* __cplusplus */
|
|
+extern void * (*governor_load_lve_library)();
|
|
+extern int (*governor_init_lve)();
|
|
+extern void (*governor_destroy_lve)();
|
|
+extern int (*governor_enter_lve)(uint32_t *, char *);
|
|
+extern int (*governor_enter_lve_light)(uint32_t *);
|
|
+extern void (*governor_lve_exit)(uint32_t *);
|
|
+extern void (*governor_lve_exit_null)();
|
|
+extern int (*governor_lve_enter_pid)(pid_t);
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
+volatile int governor_get_command = 0;
|
|
+int (*connect_to_server)() = NULL;
|
|
+int (*send_info_begin)(char *) = NULL;
|
|
+int (*send_info_end)(char *) = NULL;
|
|
+int (*close_sock)() = NULL;
|
|
+void * governor_library_handle = NULL;
|
|
+
|
|
#define MYSQL_KILL_SIGNAL SIGTERM
|
|
|
|
#include <my_pthread.h> // For thr_setconcurency()
|
|
@@ -1513,6 +1542,20 @@ void clean_up(bool print_message)
|
|
free_global_thread_stats();
|
|
free_global_table_stats();
|
|
free_global_index_stats();
|
|
+
|
|
+ governor_detroy_mysql_thread_info();
|
|
+
|
|
+ if(governor_destroy_lve){
|
|
+ governor_destroy_lve();
|
|
+ }
|
|
+
|
|
+ if(close_sock){
|
|
+ (*close_sock)();
|
|
+ }
|
|
+ if (governor_library_handle) {
|
|
+ dlclose(governor_library_handle);
|
|
+ }
|
|
+
|
|
#ifdef HAVE_REPLICATION
|
|
end_slave_list();
|
|
#endif
|
|
@@ -2982,6 +3025,10 @@ SHOW_VAR com_status_vars[]= {
|
|
{"drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
|
|
{"drop_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
|
|
{"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
|
|
+ {"enable_governor", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ENABLE_GOVERNOR]), SHOW_LONG_STATUS},
|
|
+ {"enable_governor_reconn",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ENABLE_RECONN_GOVERNOR]), SHOW_LONG_STATUS},
|
|
+ {"enable_governor_lve", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ENABLE_GOVERNOR_LVE]), SHOW_LONG_STATUS},
|
|
+ {"enable_governor_reconn_lve",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ENABLE_RECONN_GOVERNOR_LVE]), SHOW_LONG_STATUS},
|
|
{"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
|
|
{"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
|
|
{"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
|
|
@@ -2995,6 +3042,7 @@ SHOW_VAR com_status_vars[]= {
|
|
{"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
|
|
{"load", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
|
|
{"lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
|
|
+ {"lvecmd", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LVECMD]), SHOW_LONG_STATUS},
|
|
{"optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
|
|
{"preload_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
|
|
{"prepare_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
|
|
@@ -6525,6 +6573,7 @@ SHOW_VAR status_vars[]= {
|
|
{"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
|
|
{"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
|
|
{"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
|
|
+ {"Enable_governor", (char*) &governor_get_command, SHOW_INT},
|
|
{"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
|
|
{"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
|
|
{"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
|
|
@@ -6749,6 +6798,25 @@ To see what values a running MySQL server is using, type\n\
|
|
}
|
|
#endif /*!EMBEDDED_LIBRARY*/
|
|
|
|
+void governor_set_fn_ptr_to_null(){
|
|
+ governor_load_lve_library = NULL;
|
|
+ governor_init_lve = NULL;
|
|
+ governor_destroy_lve = NULL;
|
|
+ governor_enter_lve = NULL;
|
|
+ governor_lve_exit = NULL;
|
|
+ governor_enter_lve_light = NULL;
|
|
+ governor_lve_exit_null = NULL;
|
|
+ governor_lve_enter_pid = NULL;
|
|
+}
|
|
+
|
|
+void governor_set_fn2_ptr_to_null(){
|
|
+ connect_to_server = NULL;
|
|
+ send_info_begin = NULL;
|
|
+ send_info_end = NULL;
|
|
+ close_sock = NULL;
|
|
+}
|
|
+
|
|
+
|
|
/**
|
|
Initialize MySQL global variables to default values.
|
|
|
|
@@ -6946,6 +7014,115 @@ static int mysql_init_variables(void)
|
|
tmpenv = DEFAULT_MYSQL_HOME;
|
|
(void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
|
|
#endif
|
|
+
|
|
+
|
|
+
|
|
+ governor_get_command = 0;
|
|
+ connect_to_server = NULL;
|
|
+ send_info_begin = NULL;
|
|
+ send_info_end = NULL;
|
|
+ close_sock = NULL;
|
|
+ governor_library_handle = NULL;
|
|
+
|
|
+ char *error_dl = NULL;
|
|
+ governor_library_handle = dlopen("libgovernor.so", RTLD_LAZY);
|
|
+ if (governor_library_handle) {
|
|
+ sql_print_information("libgovernor.so found");
|
|
+ while(1){
|
|
+ connect_to_server = (int (*)())dlsym(governor_library_handle, "connect_to_server");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn2_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ send_info_begin = (int (*)(char *))dlsym(governor_library_handle, "send_info_begin");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn2_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ send_info_end = (int (*)(char *))dlsym(governor_library_handle, "send_info_end");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn2_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ close_sock = (int (*)())dlsym(governor_library_handle, "close_sock");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn2_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ sql_print_information("All governors functions found too");
|
|
+ break;
|
|
+ }
|
|
+ } else {
|
|
+ sql_print_information("libgovernor.so not found");
|
|
+ }
|
|
+ if(connect_to_server){
|
|
+ if(!(*connect_to_server)()){
|
|
+ sql_print_information("Governor connected");
|
|
+ } else {
|
|
+ sql_print_error("Governor not connected");
|
|
+ }
|
|
+ }
|
|
+ if (governor_library_handle){
|
|
+
|
|
+ while(1){
|
|
+ governor_load_lve_library = (void * (*)())dlsym(governor_library_handle, "governor_load_lve_library");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ governor_init_lve = (int (*)())dlsym(governor_library_handle, "governor_init_lve");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ governor_destroy_lve = (void (*)())dlsym(governor_library_handle, "governor_destroy_lve");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+ governor_enter_lve = (int (*)(uint32_t *, char *))dlsym(governor_library_handle, "governor_enter_lve");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ governor_lve_exit = (void (*)(uint32_t *))dlsym(governor_library_handle, "governor_lve_exit");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ governor_enter_lve_light = (int (*)(uint32_t *))dlsym(governor_library_handle, "governor_enter_lve_light");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ governor_lve_exit_null = (void (*)(void))dlsym(governor_library_handle, "governor_lve_exit_null");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ governor_lve_enter_pid = (int (*)(pid_t))dlsym(governor_library_handle, "governor_lve_enter_pid");
|
|
+ if ((error_dl = dlerror()) != NULL){
|
|
+ governor_set_fn_ptr_to_null();
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ sql_print_information("All governors lve functions found too");
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ }
|
|
+
|
|
+ if(governor_load_lve_library){
|
|
+ if(!governor_load_lve_library()){
|
|
+ sql_print_information("Can't get LVE functions");
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -7471,6 +7648,7 @@ static void set_server_version(void)
|
|
#endif
|
|
if (opt_log || opt_slow_log || opt_bin_log)
|
|
strmov(end, "-log"); // This may slow down system
|
|
+ end= strmov(end, "-cll-lve");
|
|
}
|
|
|
|
|
|
@@ -7737,8 +7915,8 @@ static void delete_pid_file(myf flags)
|
|
File file;
|
|
if (opt_bootstrap ||
|
|
!pid_file_created ||
|
|
- !(file= mysql_file_open(key_file_pid, pidfile_name,
|
|
- O_RDONLY, flags)))
|
|
+ ((file= mysql_file_open(key_file_pid, pidfile_name,
|
|
+ O_RDONLY, flags))<0))
|
|
return;
|
|
|
|
/* Make sure that the pid file was created by the same process. */
|
|
diff --git a/sql/mysqld.h b/sql/mysqld.h
|
|
index 959c9d6..9fa02bf 100644
|
|
--- a/sql/mysqld.h
|
|
+++ b/sql/mysqld.h
|
|
@@ -16,6 +16,8 @@
|
|
#ifndef MYSQLD_INCLUDED
|
|
#define MYSQLD_INCLUDED
|
|
|
|
+#include <stdint.h>
|
|
+
|
|
#include "my_global.h" /* MYSQL_PLUGIN_IMPORT, FN_REFLEN, FN_EXTLEN */
|
|
#include "sql_bitmap.h" /* Bitmap */
|
|
#include "my_decimal.h" /* my_decimal */
|
|
@@ -138,6 +140,14 @@ extern ulong opt_tc_log_size, tc_log_max_pages_used, tc_log_page_size;
|
|
extern ulong tc_log_page_waits;
|
|
extern my_bool relay_log_purge, opt_innodb_safe_binlog, opt_innodb;
|
|
extern my_bool relay_log_recovery;
|
|
+
|
|
+extern volatile int governor_get_command;
|
|
+extern int (*connect_to_server)();
|
|
+extern int (*send_info_begin)(char *);
|
|
+extern int (*send_info_end)(char *);
|
|
+extern int (*close_sock)();
|
|
+extern void * governor_library_handle;
|
|
+
|
|
extern uint test_flags,select_errors,ha_open_options;
|
|
extern uint protocol_version, mysqld_port, dropping_tables;
|
|
extern ulong delay_key_write_options;
|
|
@@ -477,6 +487,14 @@ void free_global_index_stats(void);
|
|
void free_global_client_stats(void);
|
|
void free_global_thread_stats(void);
|
|
|
|
+extern "C" pid_t gettid(void);
|
|
+
|
|
+void set_governor_variable();
|
|
+void set_governor_variable_reconn();
|
|
+void set_governor_variable_lve();
|
|
+void set_governor_variable_reconn_lve();
|
|
+
|
|
+
|
|
/*
|
|
TODO: Replace this with an inline function.
|
|
*/
|
|
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
|
|
index fdd9b10..51d6129 100644
|
|
--- a/sql/sql_acl.cc
|
|
+++ b/sql/sql_acl.cc
|
|
@@ -903,7 +903,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
|
|
{
|
|
/* Starting from 5.0.3 we have max_user_connections field */
|
|
ptr= get_field(thd->mem_root, table->field[next_field++]);
|
|
- user.user_resource.user_conn= ptr ? atoi(ptr) : 0;
|
|
+ user.user_resource.user_conn= ptr ? atoll(ptr) : 0;
|
|
}
|
|
|
|
if (table->s->fields >= 41)
|
|
@@ -9584,10 +9584,7 @@ acl_authenticate(THD *thd, uint connect_errors, uint com_change_user_pkt_len)
|
|
}
|
|
|
|
/* Don't allow the user to connect if he has done too many queries */
|
|
- if ((acl_user->user_resource.questions || acl_user->user_resource.updates ||
|
|
- acl_user->user_resource.conn_per_hour ||
|
|
- acl_user->user_resource.user_conn ||
|
|
- global_system_variables.max_user_connections) &&
|
|
+ if (
|
|
get_or_create_user_conn(thd,
|
|
(opt_old_style_user_limits ? sctx->user : sctx->priv_user),
|
|
(opt_old_style_user_limits ? sctx->host_or_ip : sctx->priv_host),
|
|
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
|
|
index 1afcf23..8bd9167 100644
|
|
--- a/sql/sql_class.cc
|
|
+++ b/sql/sql_class.cc
|
|
@@ -809,6 +809,8 @@ THD::THD()
|
|
{
|
|
ulong tmp;
|
|
|
|
+ thread_tid_cll = 0;
|
|
+
|
|
mdl_context.init(this);
|
|
/*
|
|
Pass nominal parameters to init_alloc_root only to ensure that
|
|
@@ -1340,6 +1342,7 @@ void THD::update_stats(bool ran_command)
|
|
|
|
void THD::init_for_queries()
|
|
{
|
|
+ thread_tid_cll = gettid();
|
|
set_time();
|
|
ha_enable_transaction(this,TRUE);
|
|
|
|
diff --git a/sql/sql_class.h b/sql/sql_class.h
|
|
index b555b98..8e946fd 100644
|
|
--- a/sql/sql_class.h
|
|
+++ b/sql/sql_class.h
|
|
@@ -2006,6 +2006,7 @@ public:
|
|
ulong statement_id_counter;
|
|
ulong rand_saved_seed1, rand_saved_seed2;
|
|
pthread_t real_id; /* For debugging */
|
|
+ pid_t thread_tid_cll;
|
|
my_thread_id thread_id;
|
|
uint tmp_table;
|
|
uint server_status,open_options;
|
|
@@ -3745,6 +3746,7 @@ inline bool add_group_to_list(THD *thd, Item *item, bool asc)
|
|
|
|
#endif /* MYSQL_SERVER */
|
|
|
|
+
|
|
/**
|
|
The meat of thd_proc_info(THD*, char*), a macro that packs the last
|
|
three calling-info parameters.
|
|
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
|
|
index 12493be..28a2b31 100644
|
|
--- a/sql/sql_connect.cc
|
|
+++ b/sql/sql_connect.cc
|
|
@@ -81,6 +81,10 @@ extern mysql_mutex_t LOCK_global_index_stats;
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
static HASH hash_user_connections;
|
|
|
|
+int is_root_access(char *user_name){
|
|
+ return !strcmp(user_name,"root")||!strcmp(user_name,"mysql");
|
|
+}
|
|
+
|
|
int get_or_create_user_conn(THD *thd, const char *user,
|
|
const char *host,
|
|
const USER_RESOURCES *mqh)
|
|
@@ -735,6 +739,16 @@ int check_for_max_user_connections(THD *thd, const USER_CONN *uc)
|
|
DBUG_ENTER("check_for_max_user_connections");
|
|
|
|
mysql_mutex_lock(&LOCK_user_conn);
|
|
+
|
|
+
|
|
+
|
|
+ if (((uc->user_resources.user_conn==(uint)~0) || (global_system_variables.max_user_connections == (uint)~0)) && !is_root_access(uc->user))
|
|
+ {
|
|
+ my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
|
|
+ error=1;
|
|
+ goto end;
|
|
+ }
|
|
+
|
|
if (global_system_variables.max_user_connections &&
|
|
!uc->user_resources.user_conn &&
|
|
global_system_variables.max_user_connections < (uint) uc->connections)
|
|
@@ -1373,6 +1387,7 @@ void prepare_new_connection_state(THD* thd)
|
|
pthread_handler_t handle_one_connection(void *arg)
|
|
{
|
|
THD *thd= (THD*) arg;
|
|
+ thd->thread_tid_cll = gettid();
|
|
|
|
mysql_thread_set_psi_id(thd->thread_id);
|
|
|
|
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
|
|
index d16166a..00eee9a 100644
|
|
--- a/sql/sql_lex.h
|
|
+++ b/sql/sql_lex.h
|
|
@@ -193,7 +193,8 @@ enum enum_sql_command {
|
|
SQLCOM_SHOW_RELAYLOG_EVENTS,
|
|
// TODO(mcallaghan): update status_vars in mysqld to export these
|
|
SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
|
|
- SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS,
|
|
+ SQLCOM_SHOW_CLIENT_STATS, SQLCOM_SHOW_THREAD_STATS, SQLCOM_ENABLE_GOVERNOR, SQLCOM_ENABLE_RECONN_GOVERNOR,
|
|
+ SQLCOM_ENABLE_GOVERNOR_LVE, SQLCOM_ENABLE_RECONN_GOVERNOR_LVE, SQLCOM_LVECMD,
|
|
/*
|
|
When a command is added here, be sure it's also added in mysqld.cc
|
|
in "struct show_var_st status_vars[]= {" ...
|
|
diff --git a/sql/sql_list.cc b/sql/sql_list.cc
|
|
index 99aeccd..d8bea45 100644
|
|
--- a/sql/sql_list.cc
|
|
+++ b/sql/sql_list.cc
|
|
@@ -39,6 +39,14 @@ void free_list(I_List <i_string> *list)
|
|
}
|
|
|
|
|
|
+void free_list(I_List <i_thd> *list)
|
|
+{
|
|
+ i_thd *tmp;
|
|
+ while ((tmp= list->get()))
|
|
+ delete tmp;
|
|
+}
|
|
+
|
|
+
|
|
base_list::base_list(const base_list &rhs, MEM_ROOT *mem_root)
|
|
{
|
|
if (rhs.elements)
|
|
diff --git a/sql/sql_list.h b/sql/sql_list.h
|
|
index bdbe381..dea32d2 100644
|
|
--- a/sql/sql_list.h
|
|
+++ b/sql/sql_list.h
|
|
@@ -570,6 +570,15 @@ public:
|
|
i_string(const char* s) : ptr(s) {}
|
|
};
|
|
|
|
+/* DB_GOVERNOR ADDITIONS */
|
|
+class i_thd: public ilink
|
|
+{
|
|
+ public:
|
|
+ THD* ptr;
|
|
+ i_thd():ptr(0) { }
|
|
+ i_thd(THD* s) : ptr(s) {}
|
|
+};
|
|
+
|
|
/* needed for linked list of two strings for replicate-rewrite-db */
|
|
class i_string_pair: public ilink
|
|
{
|
|
@@ -723,5 +732,6 @@ list_copy_and_replace_each_value(List<T> &list, MEM_ROOT *mem_root)
|
|
|
|
void free_list(I_List <i_string_pair> *list);
|
|
void free_list(I_List <i_string> *list);
|
|
+void free_list(I_List <i_thd> *list);
|
|
|
|
#endif // INCLUDES_MYSQL_SQL_LIST_H
|
|
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
|
|
index 8e2841c..d4e8345 100644
|
|
--- a/sql/sql_parse.cc
|
|
+++ b/sql/sql_parse.cc
|
|
@@ -13,6 +13,7 @@
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
+#define HAVE_CLOCK_GETTIME 1
|
|
#define MYSQL_LEX 1
|
|
#include "my_global.h"
|
|
#include "sql_priv.h"
|
|
@@ -95,6 +96,21 @@
|
|
#include "probes_mysql.h"
|
|
#include "set_var.h"
|
|
|
|
+#ifdef __cplusplus
|
|
+extern "C" {
|
|
+#endif /* __cplusplus */
|
|
+
|
|
+extern void * (*governor_load_lve_library)();
|
|
+extern int (*governor_init_lve)();
|
|
+extern void (*governor_destroy_lve)();
|
|
+extern int (*governor_enter_lve)(uint32_t *, char *);
|
|
+extern int (*governor_enter_lve_light)(uint32_t *);
|
|
+extern void (*governor_lve_exit)(uint32_t *);
|
|
+
|
|
+#ifdef __cplusplus
|
|
+}
|
|
+#endif
|
|
+
|
|
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
|
|
|
|
/**
|
|
@@ -114,6 +130,8 @@
|
|
|
|
static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
|
|
static void sql_kill(THD *thd, ulong id, bool only_kill_query);
|
|
+static void sql_kill_user(THD *thd, char *user, bool only_kill_query);
|
|
+static void sql_kill_user_lve(THD *thd, char *user, bool only_kill_query);
|
|
|
|
// Uses the THD to update the global stats by user name and client IP
|
|
void update_global_user_stats(THD* thd, bool create_user, time_t now);
|
|
@@ -170,6 +188,52 @@ inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
|
|
}
|
|
#endif
|
|
|
|
+void set_governor_variable(){
|
|
+ governor_get_command = 1;
|
|
+}
|
|
+
|
|
+void set_governor_variable_reconn(){
|
|
+ governor_get_command = 1;
|
|
+ if(close_sock){
|
|
+ (*close_sock)();
|
|
+ }
|
|
+ if(connect_to_server){
|
|
+ if(!(*connect_to_server)()){
|
|
+ sql_print_information("Governor reconnected");
|
|
+ } else {
|
|
+ sql_print_error("Governor not reconnected. Failed connection");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+void set_governor_variable_lve(){
|
|
+ if(!governor_get_command){
|
|
+ if(governor_init_lve){
|
|
+ if(governor_init_lve()){
|
|
+ sql_print_error("Governor LVE initialization error");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ governor_get_command = 2;
|
|
+}
|
|
+
|
|
+void set_governor_variable_reconn_lve(){
|
|
+ set_governor_variable_reconn();
|
|
+ governor_get_command = 2;
|
|
+ if(governor_init_lve){
|
|
+ if(governor_init_lve()){
|
|
+ sql_print_error("Governor LVE initialization error");
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
+
|
|
+my_bool chek_governors_avaliable_command(THD *thd){
|
|
+ return (thd->lex->sql_command!=SQLCOM_ENABLE_GOVERNOR&&thd->lex->sql_command!=SQLCOM_ENABLE_RECONN_GOVERNOR
|
|
+ &&thd->lex->sql_command!=SQLCOM_ENABLE_GOVERNOR_LVE&&thd->lex->sql_command!=SQLCOM_ENABLE_RECONN_GOVERNOR_LVE)&&
|
|
+ (thd->security_ctx && thd->security_ctx->user && thd->security_ctx->user[0]);
|
|
+}
|
|
+
|
|
|
|
static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
|
|
{
|
|
@@ -3717,9 +3781,42 @@ end_with_restore_list:
|
|
MYF(0));
|
|
goto error;
|
|
}
|
|
- sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
|
|
+ if(it->type()==Item::STRING_ITEM){
|
|
+ sql_kill_user(thd, it->val_str(0)->c_ptr(), lex->type & ONLY_KILL_QUERY);
|
|
+ } else {
|
|
+ sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
|
|
+ }
|
|
+
|
|
break;
|
|
}
|
|
+ case SQLCOM_LVECMD:
|
|
+ {
|
|
+ Item *it= (Item *)lex->value_list.head();
|
|
+
|
|
+ if (lex->table_or_sp_used())
|
|
+ {
|
|
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
|
|
+ "function calls as part of this statement");
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
|
|
+ {
|
|
+ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
|
|
+ MYF(0));
|
|
+ goto error;
|
|
+ }
|
|
+
|
|
+ if(it->type()==Item::STRING_ITEM){
|
|
+ sql_kill_user_lve(thd, it->val_str(0)->c_ptr(), lex->type & ONLY_KILL_QUERY);
|
|
+ } else {
|
|
+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "LVE by thread ID is not supported yet");
|
|
+ }
|
|
+
|
|
+
|
|
+ break;
|
|
+ }
|
|
+
|
|
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
|
case SQLCOM_SHOW_GRANTS:
|
|
{
|
|
@@ -5626,6 +5723,17 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
|
|
}
|
|
}
|
|
|
|
+ if(send_info_begin&&governor_get_command&&chek_governors_avaliable_command(thd)){
|
|
+ (*send_info_begin)(thd->security_ctx->user);
|
|
+ }
|
|
+
|
|
+/* if(governor_enter_lve && (governor_get_command==2) && chek_governors_avaliable_command(thd)){
|
|
+ if(thd->security_ctx && thd->security_ctx->user && thd->security_ctx->user[0])
|
|
+ governor_enter_lve(&cookie, thd->security_ctx->user);
|
|
+ }*/
|
|
+
|
|
+
|
|
+
|
|
if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
|
|
{
|
|
LEX *lex= thd->lex;
|
|
@@ -5674,8 +5782,13 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
|
|
&thd->security_ctx->priv_user[0],
|
|
(char *) thd->security_ctx->host_or_ip,
|
|
0);
|
|
-
|
|
+ if(governor_enter_lve && (governor_get_command==2) && chek_governors_avaliable_command(thd)){
|
|
+ if(put_in_lve(thd->security_ctx->user)<0){
|
|
+ my_error(ER_GET_ERRNO, MYF(0), "Can't enter into LVE");
|
|
+ }
|
|
+ }
|
|
error= mysql_execute_command(thd);
|
|
+ lve_thr_exit();
|
|
MYSQL_QUERY_EXEC_DONE(error);
|
|
}
|
|
}
|
|
@@ -5696,6 +5809,14 @@ void mysql_parse(THD *thd, char *rawbuf, uint length,
|
|
DBUG_ASSERT(thd->change_list.is_empty());
|
|
}
|
|
|
|
+/* if(governor_lve_exit && (governor_get_command==2) && cookie &&chek_governors_avaliable_command(thd)){
|
|
+ governor_lve_exit(&cookie);
|
|
+ }*/
|
|
+
|
|
+ if(send_info_end&&governor_get_command&&chek_governors_avaliable_command(thd)){
|
|
+ (*send_info_end)(thd->security_ctx->user);
|
|
+ }
|
|
+
|
|
if (opt_userstat)
|
|
{
|
|
// Gets the end time.
|
|
@@ -6614,6 +6735,24 @@ void sql_kill(THD *thd, ulong id, bool only_kill_query)
|
|
my_error(error, MYF(0), id);
|
|
}
|
|
|
|
+static void sql_kill_user(THD *thd, char *user, bool only_kill_query)
|
|
+{
|
|
+ uint error;
|
|
+ if (!(error= kill_user_thread(thd, user, only_kill_query))){
|
|
+ if (! thd->killed) my_ok(thd);
|
|
+ } else
|
|
+ my_error(error, MYF(0), user);
|
|
+}
|
|
+
|
|
+void sql_kill_user_lve(THD *thd, char *user, bool only_kill_query)
|
|
+{
|
|
+ uint error;
|
|
+ if (!(error= kill_user_thread_lve(thd, user, only_kill_query)))
|
|
+ my_ok(thd);
|
|
+ else
|
|
+ my_error(error, MYF(0), user);
|
|
+}
|
|
+
|
|
|
|
/** If pointer is not a null pointer, append filename to it. */
|
|
|
|
@@ -7529,3 +7668,107 @@ merge_charset_and_collation(CHARSET_INFO *cs, CHARSET_INFO *cl)
|
|
}
|
|
return cs;
|
|
}
|
|
+
|
|
+
|
|
+uint kill_user_thread(THD *thd, char *user, bool only_kill_query)
|
|
+{
|
|
+ THD *tmp;
|
|
+ uint error=0;
|
|
+ DBUG_ENTER("kill_user_thread");
|
|
+ DBUG_PRINT("enter", ("id=%s only_kill=%d", !user?"nop":user, only_kill_query));
|
|
+ i_thd *thd_tmp;
|
|
+ I_List<i_thd> threads_tmp;
|
|
+ threads_tmp.empty();
|
|
+ mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
|
+ I_List_iterator<THD> it(threads);
|
|
+ while ((tmp=it++))
|
|
+ {
|
|
+ if (tmp->command == COM_DAEMON)
|
|
+ continue;
|
|
+ if((tmp)&&(user)&&(tmp->get_user_connect())&&(tmp->get_user_connect()->user)){
|
|
+ if (!strncmp(tmp->get_user_connect()->user,user,16))
|
|
+ {
|
|
+ mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
|
|
+ thd_tmp = new i_thd(tmp);
|
|
+ if (thd_tmp) threads_tmp.append(thd_tmp);
|
|
+ else mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ mysql_mutex_unlock(&LOCK_thread_count);
|
|
+
|
|
+ if(!threads_tmp.is_empty())
|
|
+ {
|
|
+ I_List_iterator<i_thd> it_tmp(threads_tmp);
|
|
+ while ((thd_tmp=it_tmp++)){
|
|
+ tmp=thd_tmp->ptr;
|
|
+
|
|
+ if ((tmp)&&((thd->security_ctx->master_access & SUPER_ACL) ||
|
|
+ thd->security_ctx->user_matches(tmp->security_ctx)))
|
|
+ {
|
|
+ tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
|
|
+ error=0;
|
|
+ }
|
|
+ else
|
|
+ error=ER_KILL_DENIED_ERROR;
|
|
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
|
+ }
|
|
+ free_list(&threads_tmp);
|
|
+ threads_tmp.empty();
|
|
+ }
|
|
+ DBUG_PRINT("exit", ("%d", error));
|
|
+ DBUG_RETURN(error);
|
|
+}
|
|
+
|
|
+uint kill_user_thread_lve(THD *thd, char *user, bool only_kill_query)
|
|
+{
|
|
+
|
|
+ DBUG_ENTER("kill_user_thread_lve");
|
|
+ THD *tmp;
|
|
+ i_thd *thd_tmp;
|
|
+ I_List<i_thd> threads_tmp;
|
|
+ threads_tmp.empty();
|
|
+ uint error=0;//ER_NO_SUCH_THREAD_USER;
|
|
+ mysql_mutex_lock(&LOCK_thread_count); // For unlink from list
|
|
+ I_List_iterator<THD> it(threads);
|
|
+ while ((tmp=it++))
|
|
+ {
|
|
+ if((tmp)&&(user)&&(tmp->get_user_connect())&&(tmp->get_user_connect()->user)){
|
|
+ if (!strncmp(tmp->get_user_connect()->user,user,16))
|
|
+ {
|
|
+ mysql_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
|
|
+ thd_tmp = new i_thd(tmp);
|
|
+ if (thd_tmp) threads_tmp.append(thd_tmp);
|
|
+ else mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ mysql_mutex_unlock(&LOCK_thread_count);
|
|
+
|
|
+ if(!threads_tmp.is_empty()){
|
|
+ I_List_iterator<i_thd> it_tmp(threads_tmp);
|
|
+ while ((thd_tmp=it_tmp++)){
|
|
+ tmp=thd_tmp->ptr;
|
|
+ if ((tmp)&&((thd->security_ctx->master_access & SUPER_ACL) ||
|
|
+ thd->security_ctx->user_matches(tmp->security_ctx)))
|
|
+ {
|
|
+ if(tmp->thread_tid_cll){
|
|
+ governor_setlve_mysql_thread_info(tmp->thread_tid_cll);
|
|
+ }
|
|
+ } else {
|
|
+ error=ER_KILL_DENIED_ERROR;
|
|
+ }
|
|
+ mysql_mutex_unlock(&tmp->LOCK_thd_data);
|
|
+
|
|
+ }
|
|
+ free_list(&threads_tmp);
|
|
+ threads_tmp.empty();
|
|
+ }
|
|
+
|
|
+ DBUG_RETURN(error);
|
|
+
|
|
+}
|
|
+
|
|
+
|
|
+
|
|
+
|
|
diff --git a/sql/sql_parse.h b/sql/sql_parse.h
|
|
index 9a55174..b2871fd 100644
|
|
--- a/sql/sql_parse.h
|
|
+++ b/sql/sql_parse.h
|
|
@@ -50,6 +50,8 @@ bool parse_sql(THD *thd,
|
|
Parser_state *parser_state,
|
|
Object_creation_ctx *creation_ctx);
|
|
|
|
+uint kill_user_thread(THD *thd, char *user, bool only_kill_query);
|
|
+uint kill_user_thread_lve(THD *thd, char *user, bool only_kill_query);
|
|
uint kill_one_thread(THD *thd, ulong id, bool only_kill_query);
|
|
|
|
void free_items(Item *item);
|
|
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
|
|
index 06a89c0..39fe9c7 100644
|
|
--- a/sql/sql_prepare.cc
|
|
+++ b/sql/sql_prepare.cc
|
|
@@ -2086,6 +2086,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
|
|
case SQLCOM_GRANT:
|
|
case SQLCOM_REVOKE:
|
|
case SQLCOM_KILL:
|
|
+ case SQLCOM_LVECMD:
|
|
break;
|
|
|
|
case SQLCOM_PREPARE:
|
|
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
|
|
index 181fa6e..14cb51f 100644
|
|
--- a/sql/sql_select.cc
|
|
+++ b/sql/sql_select.cc
|
|
@@ -11284,6 +11284,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|
|
|
save_proc_info=thd->proc_info;
|
|
thd_proc_info(thd, "converting HEAP to MyISAM");
|
|
+ my_reserve_slot();
|
|
|
|
if (create_myisam_tmp_table(&new_table, param,
|
|
thd->lex->select_lex.options | thd->variables.option_bits,
|
|
@@ -11350,10 +11351,12 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
|
|
if (save_proc_info)
|
|
thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
|
|
"Copying to tmp table on disk" : save_proc_info));
|
|
+ my_release_slot();
|
|
DBUG_RETURN(0);
|
|
|
|
err:
|
|
DBUG_PRINT("error",("Got error: %d",write_err));
|
|
+ my_release_slot();
|
|
table->file->print_error(write_err, MYF(0));
|
|
(void) table->file->ha_rnd_end();
|
|
(void) new_table.file->close();
|
|
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
|
|
index af19762..f64f29c 100644
|
|
--- a/sql/sql_yacc.yy
|
|
+++ b/sql/sql_yacc.yy
|
|
@@ -946,6 +946,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|
%token ELSE /* SQL-2003-R */
|
|
%token ELSEIF_SYM
|
|
%token ENABLE_SYM
|
|
+%token ENABLE_GOVERNOR_SYM
|
|
+%token ENABLE_GOVERNOR_RECONN_SYM
|
|
+%token ENABLE_GOVERNOR_LVE_SYM
|
|
+%token ENABLE_GOVERNOR_RECONN_LVE_SYM
|
|
%token ENCLOSED
|
|
%token END /* SQL-2003-R */
|
|
%token ENDS_SYM
|
|
@@ -1074,6 +1078,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|
%token LOOP_SYM
|
|
%token LOW_PRIORITY
|
|
%token LT /* OPERATOR */
|
|
+%token LVECMD_SYM
|
|
%token MASTER_CONNECT_RETRY_SYM
|
|
%token MASTER_HOST_SYM
|
|
%token MASTER_LOG_FILE_SYM
|
|
@@ -1559,7 +1564,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
|
|
reset purge begin commit rollback savepoint release
|
|
slave master_def master_defs master_file_def slave_until_opts
|
|
repair analyze check start checksum
|
|
- field_list field_list_item field_spec kill column_def key_def
|
|
+ field_list field_list_item field_spec kill lvecmd column_def key_def
|
|
keycache_list keycache_list_or_parts assign_to_keycache
|
|
assign_to_keycache_parts
|
|
preload_list preload_list_or_parts preload_keys preload_keys_parts
|
|
@@ -1728,6 +1733,10 @@ statement:
|
|
| describe
|
|
| do
|
|
| drop
|
|
+ | enable_governor
|
|
+ | enable_governor_reconn
|
|
+ | enable_governor_lve
|
|
+ | enable_governor_reconn_lve
|
|
| execute
|
|
| flush
|
|
| grant
|
|
@@ -1738,6 +1747,7 @@ statement:
|
|
| kill
|
|
| load
|
|
| lock
|
|
+ | lvecmd
|
|
| optimize
|
|
| keycache
|
|
| partition_entry
|
|
@@ -7053,6 +7063,21 @@ mi_check_type:
|
|
| CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
|
|
| FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }
|
|
;
|
|
+
|
|
+lvecmd:
|
|
+ LVECMD_SYM lvecmd_option expr
|
|
+ {
|
|
+ LEX *lex=Lex;
|
|
+ lex->value_list.empty();
|
|
+ lex->value_list.push_front($3);
|
|
+ lex->sql_command= SQLCOM_LVECMD;
|
|
+ }
|
|
+ ;
|
|
+
|
|
+lvecmd_option:
|
|
+ /* empty */ { Lex->type= ONLY_KILL_QUERY; }
|
|
+ ;
|
|
+
|
|
|
|
optimize:
|
|
OPTIMIZE opt_no_write_to_binlog table_or_tables
|
|
@@ -10894,6 +10919,41 @@ opt_profile_args:
|
|
}
|
|
;
|
|
|
|
+enable_governor:
|
|
+ ENABLE_GOVERNOR_SYM
|
|
+ {
|
|
+ LEX *lex= Lex;
|
|
+ lex->sql_command= SQLCOM_ENABLE_GOVERNOR;
|
|
+ set_governor_variable();
|
|
+ }
|
|
+ ;
|
|
+
|
|
+enable_governor_reconn:
|
|
+ ENABLE_GOVERNOR_RECONN_SYM
|
|
+ {
|
|
+ LEX *lex= Lex;
|
|
+ lex->sql_command= SQLCOM_ENABLE_RECONN_GOVERNOR;
|
|
+ set_governor_variable_reconn();
|
|
+ }
|
|
+ ;
|
|
+enable_governor_lve:
|
|
+ ENABLE_GOVERNOR_LVE_SYM
|
|
+ {
|
|
+ LEX *lex= Lex;
|
|
+ lex->sql_command= SQLCOM_ENABLE_GOVERNOR_LVE;
|
|
+ set_governor_variable_lve();
|
|
+ }
|
|
+ ;
|
|
+
|
|
+enable_governor_reconn_lve:
|
|
+ ENABLE_GOVERNOR_RECONN_LVE_SYM
|
|
+ {
|
|
+ LEX *lex= Lex;
|
|
+ lex->sql_command= SQLCOM_ENABLE_RECONN_GOVERNOR_LVE;
|
|
+ set_governor_variable_reconn_lve();
|
|
+ }
|
|
+ ;
|
|
+
|
|
/* Show things */
|
|
|
|
show:
|
|
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
|
|
index 8ef0906..f3d3b98 100644
|
|
--- a/storage/innobase/include/os0file.h
|
|
+++ b/storage/innobase/include/os0file.h
|
|
@@ -204,8 +204,9 @@ used to register actual file read, write and flush */
|
|
# define register_pfs_file_open_begin(state, locker, key, op, name, \
|
|
src_file, src_line) \
|
|
do { \
|
|
+ my_reserve_slot(); \
|
|
if (PSI_server) { \
|
|
- locker = PSI_server->get_thread_file_name_locker( \
|
|
+ locker = PSI_server->get_thread_file_name_locker( \
|
|
state, key, op, name, &locker); \
|
|
if (locker) { \
|
|
PSI_server->start_file_open_wait( \
|
|
@@ -220,11 +221,13 @@ do { \
|
|
PSI_server->end_file_open_wait_and_bind_to_descriptor( \
|
|
locker, file); \
|
|
} \
|
|
+ my_release_slot(); \
|
|
} while (0)
|
|
|
|
# define register_pfs_file_io_begin(state, locker, file, count, op, \
|
|
src_file, src_line) \
|
|
do { \
|
|
+ my_reserve_slot(); \
|
|
if (PSI_server) { \
|
|
locker = PSI_server->get_thread_file_descriptor_locker( \
|
|
state, file, op); \
|
|
@@ -240,6 +243,7 @@ do { \
|
|
if (locker) { \
|
|
PSI_server->end_file_wait(locker, count); \
|
|
} \
|
|
+ my_release_slot(); \
|
|
} while (0)
|
|
#endif /* UNIV_PFS_IO */
|
|
|
|
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
|
|
index db777f0..77ab113 100644
|
|
--- a/storage/innobase/os/os0file.c
|
|
+++ b/storage/innobase/os/os0file.c
|
|
@@ -3752,6 +3752,7 @@ os_aio_array_reserve_slot(
|
|
offset */
|
|
ulint len) /*!< in: length of the block to read or write */
|
|
{
|
|
+ my_reserve_slot();
|
|
os_aio_slot_t* slot = NULL;
|
|
#ifdef WIN_ASYNC_IO
|
|
OVERLAPPED* control;
|
|
@@ -3895,6 +3896,7 @@ os_aio_array_free_slot(
|
|
os_aio_array_t* array, /*!< in: aio array */
|
|
os_aio_slot_t* slot) /*!< in: pointer to slot */
|
|
{
|
|
+ my_release_slot();
|
|
ut_ad(array);
|
|
ut_ad(slot);
|
|
|
|
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
|
|
index 5872ff2..d3a949e 100644
|
|
--- a/storage/innobase/srv/srv0srv.c
|
|
+++ b/storage/innobase/srv/srv0srv.c
|
|
@@ -1144,6 +1144,7 @@ srv_conc_enter_innodb(
|
|
ibool has_slept = FALSE;
|
|
srv_conc_slot_t* slot = NULL;
|
|
ulint i;
|
|
+ my_reserve_slot();
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
|
|
@@ -1158,7 +1159,6 @@ srv_conc_enter_innodb(
|
|
|
|
return;
|
|
}
|
|
-
|
|
/* If trx has 'free tickets' to enter the engine left, then use one
|
|
such ticket */
|
|
|
|
@@ -1311,6 +1311,7 @@ srv_conc_force_enter_innodb(
|
|
trx_t* trx) /*!< in: transaction object associated with the
|
|
thread */
|
|
{
|
|
+ my_reserve_slot();
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
@@ -1342,6 +1343,7 @@ srv_conc_force_exit_innodb(
|
|
thread */
|
|
{
|
|
srv_conc_slot_t* slot = NULL;
|
|
+ my_release_slot();
|
|
|
|
if (trx->mysql_thd != NULL
|
|
&& thd_is_replication_slave_thread(trx->mysql_thd)) {
|
|
@@ -1401,6 +1403,7 @@ srv_conc_exit_innodb(
|
|
trx_t* trx) /*!< in: transaction object associated with the
|
|
thread */
|
|
{
|
|
+ my_release_slot();
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
diff --git a/support-files/mysql.server.sh b/support-files/mysql.server.sh
|
|
index b5115a5..f955e50 100644
|
|
--- a/support-files/mysql.server.sh
|
|
+++ b/support-files/mysql.server.sh
|
|
@@ -59,6 +59,33 @@ lock_file_path="$lockdir/mysql"
|
|
|
|
# The following variables are only set for letting mysql.server find things.
|
|
|
|
+cpu_limit=
|
|
+io_limit=
|
|
+
|
|
+get_limit(){
|
|
+ if [ -e /usr/sbin/lvectl ]; then
|
|
+ LVE_VER=`/usr/sbin/lvectl --lve-version`
|
|
+ if [ "$LVE_VER" == "4" ]; then
|
|
+ io_limit=`/usr/sbin/lvectl limits 3 | awk 'NR == 2' | awk '{print $6}'`
|
|
+ else
|
|
+ io_limit=`/usr/sbin/lvectl limits 3 | awk 'NR == 2' | awk '{print $8}'`
|
|
+ fi
|
|
+ cpu_limit=`/usr/sbin/lvectl limits 3 | awk 'NR == 2' | awk '{print $2}'`
|
|
+ fi
|
|
+}
|
|
+
|
|
+set_big_limit(){
|
|
+ if [ -e /usr/sbin/lvectl ]; then
|
|
+ /usr/sbin/lvectl set 3 --cpu=100 --io=0 --save-all-parameters
|
|
+ fi
|
|
+}
|
|
+
|
|
+set_old_limit(){
|
|
+ if [ -e /usr/sbin/lvectl ]; then
|
|
+ /usr/sbin/lvectl set 3 --cpu=$cpu_limit --io=$io_limit --save-all-parameters
|
|
+ fi
|
|
+}
|
|
+
|
|
# Set some defaults
|
|
mysqld_pid_file_path=
|
|
if test -z "$basedir"
|
|
@@ -298,6 +325,11 @@ case "$mode" in
|
|
'stop')
|
|
# Stop daemon. We use a signal here to avoid having to know the
|
|
# root password.
|
|
+
|
|
+ get_limit
|
|
+ set_big_limit
|
|
+ sleep 2
|
|
+
|
|
|
|
if test -s "$mysqld_pid_file_path"
|
|
then
|
|
@@ -319,10 +351,12 @@ case "$mode" in
|
|
then
|
|
rm -f "$lock_file_path"
|
|
fi
|
|
+ set_old_limit
|
|
exit $return_value
|
|
else
|
|
log_failure_msg "MySQL server PID file could not be found!"
|
|
fi
|
|
+ set_old_limit
|
|
;;
|
|
|
|
'restart')
|
|
@@ -337,14 +371,19 @@ case "$mode" in
|
|
;;
|
|
|
|
'reload'|'force-reload')
|
|
+ get_limit
|
|
+ set_big_limit
|
|
+ sleep 2
|
|
if test -s "$mysqld_pid_file_path" ; then
|
|
read mysqld_pid < "$mysqld_pid_file_path"
|
|
kill -HUP $mysqld_pid && log_success_msg "Reloading service MySQL"
|
|
touch "$mysqld_pid_file_path"
|
|
else
|
|
log_failure_msg "MySQL PID file could not be found!"
|
|
+ set_old_limit
|
|
exit 1
|
|
fi
|
|
+ set_old_limit
|
|
;;
|
|
'status')
|
|
# First, check to see if pid file exists
|