From d9569c37f9142b2c4337927e3cad9e544c225a0a Mon Sep 17 00:00:00 2001 From: gowink Date: Tue, 19 May 2015 17:48:18 +0800 Subject: [PATCH] 1. fix bug: when config dbgroup not index from 0, will make coredump. fix it by convert the config dbgroup from groupid to array index.\r\n 2. add automake install hook to src/Makefile.am to install script/encrypt and script/mysql-proxyd --- configure.in | 432 +++++++++++++++++++++++++++++++++++ plugins/proxy/proxy-plugin.c | 70 ++++-- src/Makefile.am | 5 + src/Makefile.in | 12 +- src/chassis-mainloop.c | 8 +- src/chassis-sharding.c | 75 +++--- src/chassis-sharding.h | 2 +- 7 files changed, 545 insertions(+), 59 deletions(-) create mode 100644 configure.in diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..5df5f64 --- /dev/null +++ b/configure.in @@ -0,0 +1,432 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. +AC_PREREQ(2.57) +AC_INIT(mysql-proxy, 0.8.2, mysql-proxy-discuss@lists.launchpad.net) +AC_CONFIG_SRCDIR([src/mysql-proxy-cli.c]) + +AC_CANONICAL_TARGET + +dnl require 1.10 to get abs_top_builddir and docdir +AM_INIT_AUTOMAKE(1.10 gnits) + +AC_CONFIG_HEADER([config.h]) + +AM_MAINTAINER_MODE + +dnl check environment +AC_AIX +AC_ISC_POSIX + +AC_EXEEXT + + +# Checks for programs. +AC_PROG_CC +AC_PROG_LD +AC_PROG_INSTALL +AC_PROG_AWK +dnl we need flex +AC_PROG_LEX + +dnl AC_PROG_LEX returns LEX=: in case it didn't found flex or lex +dnl we replace it by 'missing' to give the user a useful errormsg +if test x$LEX = x:; then + AM_MISSING_PROG(LEXMISSING, flex) + LEX=$LEXMISSING +fi + + +AC_PROG_CPP +dnl AC_PROG_CXX +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_MAKE_SET +AM_PROG_CC_C_O + +if test x$RST2HTML = x; then + AM_MISSING_PROG(RST2HTMLMISSING, rst2html.py) + RST2HTML=$RST2HTMLMISSING +fi +AC_SUBST(RST2HTML) + + +dnl more automake stuff +AM_C_PROTOTYPES +AC_C_BIGENDIAN + +dnl libtool + +dnl we don't want to get static libs of the lua-libs +AC_DISABLE_STATIC +dnl AC_ENABLE_SHARED + +dnl AC_LIBTOOL_DLOPEN +AC_PROG_LIBTOOL + +dnl keep theses tests close to AC_PROC_LIBTOOL and hope that we are still in the directory where libtool was created +AC_MSG_CHECKING([shared library path variable]) +DYNLIB_PATH_VAR="$shlibpath_var" +AS_IF([test "x$DYNLIB_PATH_VAR" != x], + [AC_MSG_RESULT([$DYNLIB_PATH_VAR])], + [AC_MSG_ERROR([eval "libtool --config | grep ^shlibpath_var" failed])]) +AC_SUBST(DYNLIB_PATH_VAR) + +dnl "so" is the default on all platforms, even on OS X as we build lua-c stuff as loadable modules. +dnl however HP/UX 11.31 is behaving differently, so we need to use "sl" there. This should get fixed in a more general way. +AC_MSG_CHECKING([lua module suffix]) +module=yes +eval "DYNLIB_LUA_SUFFIX=$shrext_cmds" +AS_IF([test "x$DYNLIB_LUA_SUFFIX" != x], + [DYNLIB_LUA_SUFFIX=`echo $DYNLIB_LUA_SUFFIX | sed 's/^\.//'` + AC_MSG_RESULT([$DYNLIB_LUA_SUFFIX])], + [AC_MSG_ERROR([eval "DYNLIB_LUA_SUFFIX=$shrext_cmds" failed])]) +AC_SUBST(DYNLIB_LUA_SUFFIX) + +dnl we have to hack around some glib distributions that +dnl don't set the correct G_MODULE_SUFFIX, notably MacPorts +AC_MSG_CHECKING([plugin suffix]) +module=no +eval "SHARED_LIBRARY_SUFFIX=$shrext_cmds" +AS_IF([test "x$SHARED_LIBRARY_SUFFIX" != x], + [SHARED_LIBRARY_SUFFIX=`echo $SHARED_LIBRARY_SUFFIX | sed 's/^\.//'` + AC_MSG_RESULT([$SHARED_LIBRARY_SUFFIX])], + [AC_MSG_ERROR([eval "SHARED_LIBRARY_SUFFIX=$shrext_cmds" failed])]) + +AC_DEFINE_UNQUOTED([SHARED_LIBRARY_SUFFIX], ["$SHARED_LIBRARY_SUFFIX"], [shared library extension on this platform]) + + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS([\ + arpa/inet.h \ + netinet/in.h \ + sys/filio.h \ + sys/socket.h \ + sys/param.h \ + sys/time.h \ + sys/un.h \ + sys/uio.h \ + sys/ioctl.h \ + sys/resource.h \ + pwd.h \ + signal.h \ + fcntl.h \ + libproc.h \ + valgrind/valgrind.h ]) + +AC_CHECK_HEADERS([syslog.h]) + +dnl my_rdtsc.h +AC_CHECK_HEADERS([\ + sys/time.h \ + time.h \ + asm/msr.h \ + sys/timeb.h \ + sys/times.h \ + ia64intrin.h ]) +AC_CHECK_FUNCS([\ + rdtscll \ + ftime \ + times \ + clock_gettime \ + get_hrtime \ + read_real_time \ + gettimeofday \ + time \ + wait4 + ]) + + +# When compiling with Sun Studio C / C++ we need to include +# my_timer_cycles.il, an "inline templates" separate file, +# on the command line. It has assembly code, "rd %tick" for +# SPARC or "rdtsc" for x86. + +# sun cc output the version info on stderr +AC_MSG_CHECKING([cc is Sun CC]) +IS_SUNCC=no +SUNCC_VERSION=`$CC -V 2>&1 | grep '^cc: Sun C'` +if test $? -eq "0"; then + IS_SUNCC=yes +fi +AM_CONDITIONAL(USE_SUNCC_ASSEMBLY, test x$IS_SUNCC = xyes) +AC_MSG_RESULT([$IS_SUNCC $SUNCC_VERSION]) + +DARWIN_HAS_LIBPROC_H= +if test $ac_cv_header_libproc_h = yes; then + DARWIN_HAS_LIBPROC_H="-DDARWIN_HAS_LIBPROC_H=1" +fi + +AC_SUBST(DARWIN_HAS_LIBPROC_H) + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_C_INLINE +AC_C_CHAR_UNSIGNED + +# Checks for library functions. +AC_TYPE_SIGNAL +AC_FUNC_STAT +AC_FUNC_STRFTIME + +# +AC_SEARCH_LIBS(socket,socket) +AC_SEARCH_LIBS(gethostbyname,nsl socket) +AC_SEARCH_LIBS(hstrerror,resolv) + +AC_CHECK_TYPES(socklen_t,,,[#include + #include ]) + +AC_CHECK_TYPES([ulong, ulong_t]) + +dnl Checks for database. +MYSQL_CFLAGS="" +MYSQL_LIBS="" + +AC_MSG_CHECKING(for MySQL support) +AC_ARG_WITH(mysql, + AC_HELP_STRING([--with-mysql@<:@=PATH@:>@],[Include MySQL support. PATH is the path to 'mysql_config']), + [WITH_MYSQL=$withval],[WITH_MYSQL=yes]) + +if test "$WITH_MYSQL" = "no"; then + AC_MSG_ERROR([mysql support is required, don't use --with-mysql=no or --without-mysql]) +fi + +AC_MSG_RESULT(yes) +if test "$WITH_MYSQL" = "yes"; then + AC_PATH_PROG(MYSQL_CONFIG, mysql_config) +else + MYSQL_CONFIG=$WITH_MYSQL +fi + +if test "$MYSQL_CONFIG" = ""; then + AC_MSG_ERROR([mysql_config is not found, use $ ./configure --with-mysql=/path/to/mysql_config]) +fi + +if test -d $MYSQL_CONFIG; then + MYSQL_CONFIG="$MYSQL_CONFIG/bin/mysql_config" +fi + +if test \! -x $MYSQL_CONFIG; then + AC_MSG_ERROR([mysql_config not exists or not executable, use $ ./configure --with-mysql=/path/to/mysql_config]) +fi + +if $MYSQL_CONFIG | grep -- '--include' > /dev/null ; then + MYSQL_CFLAGS="`$MYSQL_CONFIG --include | sed s/\'//g`" +else + MYSQL_CFLAGS="`$MYSQL_CONFIG --cflags | sed s/\'//g`" +fi + +AC_MSG_CHECKING(for MySQL includes at) +AC_MSG_RESULT($MYSQL_CFLAGS) + +dnl check for errmsg.h, which isn't installed by some versions of 3.21 +old_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $MYSQL_CFLAGS" +AC_CHECK_HEADERS(errmsg.h mysql.h) +CPPFLAGS="$old_CPPFLAGS" + +if test x"$ac_cv_header_mysql_h" = xno; then + AC_MSG_ERROR([mysql.h is required, please install the mysql header package]) +fi + +AC_DEFINE([HAVE_MYSQL], [1], [mysql support]) + +AC_MSG_CHECKING(for mysqltest binary) +if test x"$MYSQL_TEST_BIN" = x; then + MYSQL_TEST_BIN=`dirname "$MYSQL_CONFIG"`/mysqltest +fi +if test -x "$MYSQL_TEST_BIN"; then + AC_MSG_RESULT([$MYSQL_TEST_BIN]) +else + MYSQL_TEST_BIN=mysqltest + AC_MSG_RESULT([$MYSQL_TEST_BIN]) +fi +AC_MSG_CHECKING(for mysql libs) +if test x"$MYSQL_LIBS" = x; then + MYSQL_LIBS="`$MYSQL_CONFIG --libs | sed s/\'//g`" +fi +AC_MSG_RESULT([$MYSQL_LIBS]) + +AC_SUBST(MYSQL_TEST_BIN) +AC_SUBST(MYSQL_LIBS) +AC_SUBST(MYSQL_CFLAGS) + +dnl Check for pkg-config +if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, AC_MSG_ERROR([pkg-config wasn't found. Pass it's path via $ ./configure PKG_CONFIG=/path/to/pkg-config])) +fi + +dnl Check if we are to build with bundled shared libraries, +dnl in non standard location (just unpack a TAR anywhere). +AC_MSG_CHECKING(if build will be self-contained) +AC_ARG_ENABLE(self-contained, + AC_HELP_STRING([--enable-self-contained],[use wrapper script (default=no)]) + ) +AS_IF([test "x$enable_self_contained" = xyes], + [WITH_WRAPPER_SCRIPT=yes], + [WITH_WRAPPER_SCRIPT=no] + ) +AC_MSG_RESULT($WITH_WRAPPER_SCRIPT) +AM_CONDITIONAL(USE_WRAPPER_SCRIPT, test x$WITH_WRAPPER_SCRIPT = xyes) + +dnl Check for lua +AC_MSG_CHECKING(which pkg-config file to use to find Lua) +AC_ARG_WITH(lua, AC_HELP_STRING([--with-lua],[lua]), +[WITH_LUA=$withval],[WITH_LUA=yes]) + +if test "$WITH_LUA" != "no"; then + ## if WITH_LUA is give, use that as .pc file + ## if not, prove lua.pc and lua5.1.pc + if test "$WITH_LUA" = "yes"; then + AC_MSG_RESULT(lua.pc and lua5.1.pc) + PKG_CHECK_MODULES(LUA, lua >= 5.1, [ + AC_DEFINE([HAVE_LUA], [1], [liblua]) + AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) + ],[ + AC_MSG_RESULT([... checked for Lua via pkg-config: $LUA_PKG_ERRORS. retrying with lua5.1]) + if test x"$LUA_PKG_ERROR" != "x"; then + PKG_CHECK_MODULES(LUA, lua5.1 >= 5.1, [ + AC_DEFINE([HAVE_LUA], [1], [liblua]) + AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) + ],[ + AC_MSG_ERROR([checked for Lua via pkg-config: $LUA_PKG_ERRORS. Make sure lua and its devel-package, which includes the lua5.1.pc (debian and friends) or lua.pc (all others) file, is installed])]) + fi + ]) + else + AC_MSG_RESULT($WITH_LUA.pc) + + PKG_CHECK_MODULES(LUA, $WITH_LUA >= 5.1, [ + AC_DEFINE([HAVE_LUA], [1], [liblua]) + AC_DEFINE([HAVE_LUA_H], [1], [lua.h]) + ],[AC_MSG_ERROR([checked for Lua via pkg-config: $LUA_PKG_ERRORS. Make sure lua and its devel-package, which includes the $WITH_LUA.pc file, is installed])]) + fi + + AC_SUBST(LUA_CFLAGS) + AC_SUBST(LUA_LIBS) +else + AC_MSG_ERROR([MySQL Proxy can't be built using --without-lua, lua 5.1 is required]) +fi + +PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16.0, [ + AC_DEFINE([HAVE_GLIB], [1], [libglib]) + AC_DEFINE([HAVE_GLIB_H], [1], [glib.h]) +]) + +PKG_CHECK_MODULES(GMODULE, gmodule-2.0 >= 2.16.0, [ + AC_DEFINE([HAVE_GMODULE], [1], [libgmodule]) + AC_DEFINE([HAVE_GMODULE_H], [1], [gmodule.h]) +]) + +PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16.0, [ + AC_DEFINE([HAVE_GTHREAD], [1], [libgthread]) + AC_DEFINE([HAVE_GTHREAD_H], [1], [gthread.h]) +]) + +case $host_os in + *mingw* ) + LIBS="$LIBS -lwsock32" + ARCH=win32 + ;; + *darwin* ) + ARCH=macosx + ;; + *linux* ) + ARCH=linux + ;; + *freebsd* ) + ARCH=freebsd + ;; + *aix* ) + ARCH=aix + ;; + *hpux* ) + ARCH=hpux + ;; + *solaris* ) + ARCH=solaris + ;; + * ) AC_MSG_ERROR([we havn't mapped $host_os to sigar-architecture yet, please report it to mysql-proxy-discuss@lists.launchpad.net]);; +esac + +AM_CONDITIONAL(OS_WIN32, test x$ARCH = xwin32) +AM_CONDITIONAL(OS_MACOSX, test x$ARCH = xmacosx) +AM_CONDITIONAL(OS_LINUX, test x$ARCH = xlinux) +AM_CONDITIONAL(OS_FREEBSD, test x$ARCH = xfreebsd) +AM_CONDITIONAL(OS_HPUX, test x$ARCH = xhpux) +AM_CONDITIONAL(OS_AIX, test x$ARCH = xaix) +AM_CONDITIONAL(OS_SOLARIS, test x$ARCH = xsolaris) + +dnl on windows we need wsock32 to get socket support +AC_CHECK_FUNCS([inet_ntoa inet_ntop strerror getcwd chdir writev gmtime_r sigaction getaddrinfo]) + +dnl make sure we off_t is 64bit +dnl CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGE_FILES" + +dnl has to be checked _after_ any large-file-support flags are set for solaris 8 +AC_CHECK_SIZEOF([rlim_t]) + +EVENT_LIBS= +AC_CHECK_LIB(event, event_init, EVENT_LIBS="-levent",AC_MSG_ERROR([libevent is required])) +AC_CHECK_LIB(event, event_base_new, AC_DEFINE(HAVE_EVENT_BASE_NEW,[],[event_base_new()]),AC_MSG_ERROR([event_base_new() wasn't found in libevent. we need at least libevent 1.4])) +AC_CHECK_LIB(event, event_base_free, AC_DEFINE(HAVE_EVENT_BASE_FREE,[],[having event_base_free()])) +AC_CHECK_HEADERS([event.h]) +AC_SUBST(EVENT_LIBS) + +dnl check for DTrace support on this platform and +dnl whether it should be used if it's there +AC_CHECK_PROGS([DTRACE], [dtrace]) +AC_CHECK_HEADERS([sys/sdt.h], [have_sdt_h=yes], [have_sdt_h=no]) +AC_MSG_CHECKING(if dtrace probes are enabled) + +AC_ARG_ENABLE(dtrace, + AC_HELP_STRING([--enable-dtrace], [enable static DTrace probes (default is NO)]), + [], + [enable_dtrace=no]) + +AS_IF([test "x$enable_dtrace" != xno], + [ AS_IF([test "x$have_sdt_h" != xno], + [ AC_DEFINE([ENABLE_DTRACE], [1], [DTrace support]) + AM_CONDITIONAL(ENABLE_DTRACE, true) + AC_MSG_RESULT(yes) + ], + [ AM_CONDITIONAL(ENABLE_DTRACE, false) + AC_MSG_RESULT(no) + AC_MSG_WARN(--enable-dtrace used, but sys/sdt.h header not present. Continuing without DTrace support) + ]) + ], + [ AM_CONDITIONAL(ENABLE_DTRACE, false) + AC_MSG_RESULT(no) + ]) + + +dnl build version-id +PACKAGE_VERSION_ID=`echo $PACKAGE_VERSION | $AWK -F '.' '{print "(" $1 " << 16 | " $2 " << 8 | " $3 ")"}'` +AC_DEFINE_UNQUOTED([PACKAGE_VERSION_ID], [$PACKAGE_VERSION_ID], [lpackage-version-id]) + +AC_CONFIG_FILES([Makefile \ + m4/Makefile \ + src/Makefile \ + plugins/Makefile \ + examples/Makefile \ + lib/Makefile \ + lib/proxy/Makefile \ + mysql-proxy.spec \ + ]) + +AC_CONFIG_FILES([plugins/admin/Makefile]) +AC_CONFIG_FILES([plugins/proxy/Makefile]) +AC_CONFIG_FILES([plugins/replicant/Makefile]) +dnl cli plugin requires readline, so we disable it for now +dnl AC_CONFIG_FILES([plugins/cli/Makefile]) +AC_CONFIG_FILES([plugins/debug/Makefile]) + +dnl Create the wrapper script for starting mysql-proxy in self-contained builds +AC_CONFIG_FILES([mysql-proxy.pc]) +AC_CONFIG_FILES([mysql-chassis.pc]) +AC_CONFIG_FILES([doc/Makefile]) +AC_CONFIG_FILES([doc/chapter/Makefile]) +AC_OUTPUT + + diff --git a/plugins/proxy/proxy-plugin.c b/plugins/proxy/proxy-plugin.c index 0821835..3f8144f 100644 --- a/plugins/proxy/proxy-plugin.c +++ b/plugins/proxy/proxy-plugin.c @@ -1254,11 +1254,20 @@ G_INLINE_FUNC void free_recvd_packets(network_socket* sockobj) { while((packet = g_queue_pop_head(sockobj->recv_queue->chunks))) { g_string_free(packet, TRUE); } } -G_INLINE_FUNC void hit_all_dbgroup(guint dbgroup_count, GArray* hit_dbgroups) { +G_INLINE_FUNC void hit_all_dbgroup(sharding_table_t *sharding_rule, GArray* hit_dbgroups) { g_array_set_size(hit_dbgroups, 0); + GArray *shard_groups = sharding_rule->shard_group; guint i; - for (i = 0; i < dbgroup_count; ++i) { - g_array_append_val(hit_dbgroups, i); + for (i = 0; i < shard_groups->len; ++i) { + guint db_group_index = 0; + if (sharding_rule->shard_type == SHARDING_TYPE_RANGE) { + group_range_map_t *range_map = &g_array_index(shard_groups, group_range_map_t, i); + db_group_index = range_map->db_group_index; + } else if (sharding_rule->shard_type == SHARDING_TYPE_HASH) { + group_hash_map_t *hash_map = &g_array_index(shard_groups, group_hash_map_t, i); + db_group_index = hash_map->db_group_index; + } + g_array_append_val(hit_dbgroups, db_group_index); } } @@ -1292,7 +1301,7 @@ static network_socket_retval_t sharding_query_handle(parse_info_t *parse_info, G /*"select * from test;" OR "select * from test where noshardkey = 'test';" */ if (sharding_ret == SHARDING_RET_ALL_SHARD || sharding_ret == SHARDING_RET_ERR_NO_SHARDKEY) { - hit_all_dbgroup(config->db_groups->len, hit_dbgroups); + hit_all_dbgroup(sharding_table_rule, hit_dbgroups); sharding_ret = SHARDING_RET_ALL_SHARD; } @@ -1314,6 +1323,8 @@ static network_socket_retval_t sharding_query_handle(parse_info_t *parse_info, G for (i = 0; i < hit_dbgroups->len; ++i) { guint dbgroup_index = g_array_index(hit_dbgroups, guint, i); db_group_t *dbgroup_obj = g_ptr_array_index(config->db_groups, dbgroup_index); + if (dbgroup_obj == NULL) { continue; } + if (trans_ctx->trans_stage == TRANS_STAGE_IN_TRANS && trans_ctx->in_trans_dbgroup_ctx != NULL && trans_ctx->in_trans_dbgroup_ctx->group_id != dbgroup_obj->group_id) { sharding_proxy_send_error_result("Proxy Warning - sharding dbgroup is in trans, transaction will not work across multi dbgroup", con, recv_sock, packets, ER_CANT_DO_THIS_DURING_AN_TRANSACTION, "25000"); @@ -3135,28 +3146,37 @@ gpointer check_state(chassis *chas) { /*get the shard rule from GKeyFile, and insert the shard rule into a hashtable*/ int proxy_plugin_get_shard_rules(GKeyFile *keyfile, chassis *chas, chassis_plugin_config *config) { - GError *gerr = NULL; - gchar **groups, **gname; - gsize length; - int i, j; - - network_backends_t *bs = chas->backends; - groups = g_key_file_get_groups(keyfile, &length); - for(i = 0; i < length; i++) { - gname = g_strsplit(groups[i], "-", 2); - if(gname == NULL || gname[0] == NULL || strcasecmp(gname[0], "mysql") == 0) continue; - if(strcasecmp(gname[0], "shardrule") == 0) { - sharding_table_t *stable = keyfile_to_sharding_table(keyfile, groups[i]); - g_hash_table_insert(config->table_shard_rules, g_strdup(stable->table_name->str), stable); - } - if(strcasecmp(gname[0], "group") == 0) { - db_group_t *dg = keyfile_to_db_group(keyfile, groups[i], chas->event_thread_count); - g_ptr_array_add(config->db_groups, dg); - } - g_strfreev(gname); + GError *gerr = NULL; + gchar **groups, **gname; + gsize length; + int i, j; + + network_backends_t *bs = chas->backends; + groups = g_key_file_get_groups(keyfile, &length); + // must get config->db_groups firstly + for(i = 0; i < length; i++) { + gname = g_strsplit(groups[i], "-", 2); + if(gname == NULL || gname[0] == NULL || strcasecmp(gname[0], "mysql") == 0) continue; + if(strcasecmp(gname[0], "group") == 0) { + db_group_t *dg = keyfile_to_db_group(keyfile, groups[i], chas->event_thread_count); + g_ptr_array_add(config->db_groups, dg); } - g_strfreev(groups); - return 0; + g_strfreev(gname); + } + + for(i = 0; i < length; i++) { + gname = g_strsplit(groups[i], "-", 2); + if(gname == NULL || gname[0] == NULL || strcasecmp(gname[0], "mysql") == 0) continue; + if(strcasecmp(gname[0], "shardrule") == 0) { + sharding_table_t *stable = keyfile_to_sharding_table(keyfile, groups[i], config->db_groups); + if (stable != NULL) { + g_hash_table_insert(config->table_shard_rules, g_strdup(stable->table_name->str), stable); + } + } + g_strfreev(gname); + } + g_strfreev(groups); + return 0; } /** diff --git a/src/Makefile.am b/src/Makefile.am index cb9e2f6..894bbff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -245,3 +245,8 @@ endif # test_latency_LDADD= $(MYSQL_LIBS) $(GLIB_LIBS) EXTRA_DIST=test-latency.c proxy-dtrace-provider.d CMakeLists.txt my_timer_cycles.il + +install-exec-hook: + mkdir -p $(prefix)/conf + mkdir -p $(prefix)/log + cd $(top_srcdir)/script; make; cp -f encrypt mysql-proxyd $(prefix)/bin diff --git a/src/Makefile.in b/src/Makefile.in index 9f79477..6ec8d99 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -1438,7 +1438,8 @@ install-dvi-am: install-exec-am: install-binPROGRAMS install-libLTLIBRARIES \ install-libexecPROGRAMS - + @$(NORMAL_INSTALL) + $(MAKE) $(AM_MAKEFLAGS) install-exec-hook install-html: install-html-am install-html-am: @@ -1480,7 +1481,7 @@ ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ uninstall-libLTLIBRARIES uninstall-libexecPROGRAMS -.MAKE: all check install install-am install-strip +.MAKE: all check install install-am install-exec-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libLTLIBRARIES clean-libexecPROGRAMS \ @@ -1489,7 +1490,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am \ + install-exec-am install-exec-hook install-html install-html-am \ install-includeHEADERS install-info install-info-am \ install-libLTLIBRARIES install-libexecPROGRAMS install-man \ install-pdf install-pdf-am install-ps install-ps-am \ @@ -1514,6 +1515,11 @@ uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \ @ENABLE_DTRACE_TRUE@@OS_SOLARIS_TRUE@ $(DTRACE) -G -s $(top_srcdir)/src/proxy-dtrace-provider.d -o $(top_builddir)/src/proxy-dtrace-provider.o \ @ENABLE_DTRACE_TRUE@@OS_SOLARIS_TRUE@ $(libmysql_proxy_la_OBJECTS:%.lo=.libs/%.o) +install-exec-hook: + mkdir -p $(prefix)/conf + mkdir -p $(prefix)/log + cd $(top_srcdir)/script; make; cp -f encrypt mysql-proxyd $(prefix)/bin + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/src/chassis-mainloop.c b/src/chassis-mainloop.c index 665e909..1f9ae05 100644 --- a/src/chassis-mainloop.c +++ b/src/chassis-mainloop.c @@ -275,8 +275,12 @@ int chassis_mainloop(void *_chas, GKeyFile *keyfile) { G_STRLOC, p->name); return -1; } - if (i == 1) p->get_shard_rules(keyfile, chas, p->config); - } + if (i == 1) { + if (p->get_shard_rules) { + p->get_shard_rules(keyfile, chas, p->config); + } + } + } /* * drop root privileges if requested diff --git a/src/chassis-sharding.c b/src/chassis-sharding.c index 6565cf1..0a88186 100644 --- a/src/chassis-sharding.c +++ b/src/chassis-sharding.c @@ -961,12 +961,11 @@ static sharding_result_t sharding_get_dbgroup_by_hash(GArray* hited_db_groups, s gint group_count = shard_groups->len; if (shard_key->type == SHARDING_SHARDKEY_VALUE_EQ) { gint group_index = shard_key->value % group_count; - for (i = 0; i < group_count; i++) { - group_hash_map_t hm = g_array_index(shard_groups, group_hash_map_t, i); - if (hm.db_group_index == group_index) break; - } - if (i < group_count) { - g_array_unique_append_val(hited_db_groups, &group_index, guint_compare_func); + if (group_index < shard_groups->len) { + group_hash_map_t *hash_map = &g_array_index(shard_groups, group_hash_map_t, group_index); + if (hash_map) { + g_array_unique_append_val(hited_db_groups, &hash_map->db_group_index, guint_compare_func); + } } }else { // -- TODO -- replace with return SHARDING_RET_ALL_SHARD, because if the shard_key->len > 1, the branch will run more than once /* for (i = 0; i < group_count; i++) { */ @@ -1121,8 +1120,25 @@ gint verify_group_index(GKeyFile* keyfile, sharding_table_t *rule) { return ret; } +gint convert_groupid2index(GPtrArray *dbgroups, gint groupid) { + g_assert(dbgroups != NULL); + guint i; + for (i = 0; i < dbgroups->len; i++) { + db_group_t *db_group = (db_group_t*)g_ptr_array_index(dbgroups, i); + if (db_group->group_id == groupid) { + return i; + } + } + + return -1; +} + /*read the GKeyFile, and set sharding_table*/ -sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name) { +sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name, GPtrArray *dbgroups) { + if (dbgroups == NULL || dbgroups->len == 0) { + return NULL; + } + int i = 0; gchar **groups = NULL; gchar **range_map = NULL; @@ -1141,17 +1157,13 @@ sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name config_entries[i++].arg_data = &(shard_key); config_entries[i++].arg_data = &(groups); if(-1 == chassis_keyfile_to_options(keyfile, group_name, config_entries)) { - g_message("%s:chassis_keyfile_to_options error", G_STRLOC); - return NULL; + g_error("%s:chassis_keyfile_to_options error", G_STRLOC); } + if(strchr(table_name, '.') == NULL) { - g_message("%s:%s must include the database name.", G_STRLOC, table_name); - g_free(table_name); - g_free(type); - g_strfreev(groups); - g_free(shard_key); - return NULL; + g_error("%s:%s must include the database name.", G_STRLOC, table_name); } + rule = g_new0(sharding_table_t, 1); rule->table_name = g_string_new(table_name); rule->shard_key = g_string_new(shard_key); @@ -1160,19 +1172,30 @@ sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name rule->shard_type = SHARDING_TYPE_HASH; rule->shard_group = g_array_new(FALSE, TRUE, sizeof(group_hash_map_t)); for(i = 0; groups && groups[i]; i++) { - hm.db_group_index = atoi(groups[i]); + hm.db_group_index = convert_groupid2index(dbgroups, atoi(groups[i])); + if (hm.db_group_index == -1) { + g_error("%s: the groupid:%s are invalid, rule->table_name:%s", G_STRLOC, groups[i], rule->table_name->str); + } g_array_append_val(rule->shard_group, hm); } - if(verify_group_index(keyfile, rule) != 0) - g_error("%s:the group indexs in shardrule are not mapping.", G_STRLOC); + /* if(verify_group_index(keyfile, rule) != 0) { */ + /* g_error("%s:the group indexs in shardrule are not mapping.", G_STRLOC); */ + /* } */ + }else { group_range_map_t rm; rule->shard_type = SHARDING_TYPE_RANGE; rule->shard_group = g_array_new(FALSE, TRUE, sizeof(group_range_map_t)); for(i = 0; groups && groups[i]; i++) { gchar **gvec = g_strsplit(groups[i], ":", 2); + if (gvec[0] == NULL || gvec == NULL) { + g_error("%s: invalid groupid:%s, rule->table_name:%s", G_STRLOC, groups[i], rule->table_name->str); + } if(gvec[0]) { - rm.db_group_index = atoi(gvec[0]); + rm.db_group_index = convert_groupid2index(dbgroups, atoi(gvec[0])); + if (rm.db_group_index == -1) { + g_error("%s: the groupid:%s are invalid, rule->table_name:%s", G_STRLOC, gvec[0], rule->table_name->str); + } if(gvec[1]) { gchar **range = g_strsplit(gvec[1], "-", 2); if(range[0] && range[1]) { @@ -1183,7 +1206,7 @@ sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name } else { rm.range_end = g_ascii_strtoll(range[1], NULL, 10); } - + if (rm.range_begin > rm.range_end) { g_error("group:%d range(%d-%d) begin must less than end!", rm.db_group_index, rm.range_begin, rm.range_end); } @@ -1196,8 +1219,8 @@ sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name g_strfreev(gvec); g_array_append_val(rule->shard_group, rm); } - if(verify_group_index(keyfile, rule) != 0) - g_error("%s:the group indexs in shardrule are not mapping.", G_STRLOC); + /* if(verify_group_index(keyfile, rule) != 0) */ + /* g_error("%s:the group indexs in shardrule are not mapping.", G_STRLOC); */ } g_free(table_name); @@ -1205,7 +1228,6 @@ sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name g_free(shard_key); g_strfreev(groups); return rule; - } db_group_t* keyfile_to_db_group(GKeyFile* keyfile, gchar* group_name, guint event_thread_count) { @@ -1223,14 +1245,11 @@ db_group_t* keyfile_to_db_group(GKeyFile* keyfile, gchar* group_name, guint even config_entries[i++].arg_data = &(read_only_backend_addresses); config_entries[i++].arg_data = &(backend_addresses); if(-1 == chassis_keyfile_to_options(keyfile, group_name, config_entries)) { - g_message("%s:chassis_keyfile_to_options error", G_STRLOC); - return NULL; + g_error("%s:chassis_keyfile_to_options error", G_STRLOC); } gvec = g_strsplit(group_name, "-", 2); if(gvec == NULL || gvec[1] == NULL) { - g_message("%s:the format of group name(%s) error.", G_STRLOC, group_name); - g_strfreev(gvec); - return NULL; + g_error("%s:the format of group name(%s) error.", G_STRLOC, group_name); } db_group_t *dg = g_new0(db_group_t, 1); dg->group_id = atoi(gvec[1]); diff --git a/src/chassis-sharding.h b/src/chassis-sharding.h index 2219002..d1d8dd1 100644 --- a/src/chassis-sharding.h +++ b/src/chassis-sharding.h @@ -277,7 +277,7 @@ network_backend_t* sharding_read_write_split(Parse *parse_obj, network_backends_ /** * sharding config */ -sharding_table_t* keyfile_to_sharding_table(GKeyFile* keyfile, gchar* group_name); +sharding_table_t* keyfile_to_sharding_table(GKeyFile *keyfile, gchar *group_name, GPtrArray *dbgroups); db_group_t* keyfile_to_db_group(GKeyFile* keyfile, gchar* group_name, guint event_thread_count); void sharding_table_free(sharding_table_t *table);