diff options
Diffstat (limited to 'plugin')
55 files changed, 368 insertions, 3110 deletions
diff --git a/plugin/audit_null/audit_null.c b/plugin/audit_null/audit_null.c index 2747063670c..0f4efc25ef3 100644 --- a/plugin/audit_null/audit_null.c +++ b/plugin/audit_null/audit_null.c @@ -145,7 +145,7 @@ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)), break; case MYSQL_AUDIT_TABLE_RENAME: snprintf(buf, sizeof(buf), "rename to %s.%s", - event_table->new_database, event_table->new_table); + event_table->new_database.str, event_table->new_table.str); buf[sizeof(buf)-1]= 0; op= buf; break; @@ -154,7 +154,7 @@ static void audit_null_notify(MYSQL_THD thd __attribute__((unused)), fprintf(f, "%s[%s] @ %s [%s]\t%s.%s : %s\n", event_table->priv_user, event_table->user, event_table->host, ip, - event_table->database, event_table->table, op); + event_table->database.str, event_table->table.str, op); } } diff --git a/plugin/auth_examples/qa_auth_interface.c b/plugin/auth_examples/qa_auth_interface.c index 5002330fb80..08ddbf7f30a 100644 --- a/plugin/auth_examples/qa_auth_interface.c +++ b/plugin/auth_examples/qa_auth_interface.c @@ -68,7 +68,7 @@ static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *inf else if (strcmp(info->user_name, "qa_test_2_user")== 0) { /* Overwriting not intended, but with effect on USER() */ - strcpy(info->user_name, "user_name"); + strcpy((char*) info->user_name, "user_name"); info->user_name_length= 9; /* Overwriting not intended, effect not visible */ strcpy((char *)info->auth_string, "auth_string"); @@ -107,7 +107,7 @@ static int qa_auth_interface (MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *inf else if (strcmp(info->user_name, "qa_test_5_user")== 0) { /* This assignment has no effect.*/ - strcpy(info->user_name, ""); + strcpy((char*) info->user_name, ""); info->user_name_length= 0; /* This assignment has no effect.*/ strcpy((char *)info->auth_string, ""); diff --git a/plugin/auth_gssapi/gssapi_errmsg.cc b/plugin/auth_gssapi/gssapi_errmsg.cc index 8ea4cab5b02..b0eee0e992e 100644 --- a/plugin/auth_gssapi/gssapi_errmsg.cc +++ b/plugin/auth_gssapi/gssapi_errmsg.cc @@ -28,6 +28,7 @@ POSSIBILITY OF SUCH DAMAGE. #include <gssapi.h> #include <string.h> + void gssapi_errmsg(OM_uint32 major, OM_uint32 minor, char *buf, size_t size) { OM_uint32 message_context; diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc index 9197b3e06fc..a498aba982d 100644 --- a/plugin/auth_gssapi/gssapi_server.cc +++ b/plugin/auth_gssapi/gssapi_server.cc @@ -2,9 +2,8 @@ #include <gssapi/gssapi.h> #include <stdio.h> #include <mysql/plugin_auth.h> -#include <my_sys.h> #include <mysqld_error.h> -#include <log.h> +#include <string.h> #include "server_plugin.h" #include "gssapi_errmsg.h" @@ -18,11 +17,11 @@ static void log_error( OM_uint32 major, OM_uint32 minor, const char *msg) char sysmsg[1024]; gssapi_errmsg(major, minor, sysmsg, sizeof(sysmsg)); my_printf_error(ER_UNKNOWN_ERROR,"Server GSSAPI error (major %u, minor %u) : %s -%s", - MYF(0), major, minor, msg, sysmsg); + 0, major, minor, msg, sysmsg); } else { - my_printf_error(ER_UNKNOWN_ERROR, "Server GSSAPI error : %s", MYF(0), msg); + my_printf_error(ER_UNKNOWN_ERROR, "Server GSSAPI error : %s", 0, msg); } } @@ -197,7 +196,7 @@ int auth_server(MYSQL_PLUGIN_VIO *vio,const char *user, size_t userlen, int use_ /* send token to peer */ if (output.length) { - if (vio->write_packet(vio, (const uchar *) output.value, output.length)) + if (vio->write_packet(vio, (const unsigned char *) output.value, output.length)) { gss_release_buffer(&minor, &output); log_error(major, minor, "communication error(write)"); @@ -237,7 +236,7 @@ int auth_server(MYSQL_PLUGIN_VIO *vio,const char *user, size_t userlen, int use_ { my_printf_error(ER_ACCESS_DENIED_ERROR, "GSSAPI name mismatch, requested '%s', actual name '%.*s'", - MYF(0), user, (int)client_name_buf.length, client_name_str); + 0, user, (int)client_name_buf.length, client_name_str); } gss_release_buffer(&minor, &client_name_buf); diff --git a/plugin/auth_gssapi/server_plugin.cc b/plugin/auth_gssapi/server_plugin.cc index 0c0bcbbbb72..5db86cffbe4 100644 --- a/plugin/auth_gssapi/server_plugin.cc +++ b/plugin/auth_gssapi/server_plugin.cc @@ -31,9 +31,18 @@ GSSAPI authentication plugin, server side */ -#include <my_sys.h> + +#ifdef _WIN32 +typedef unsigned __int64 my_ulonglong; +#else +typedef unsigned long long my_ulonglong; +#endif + +#include <stdlib.h> #include <mysqld_error.h> +#include <typelib.h> #include <mysql/plugin_auth.h> +#include "string.h" #include "server_plugin.h" #include "common.h" @@ -47,7 +56,7 @@ static int first_packet_len; */ char *srv_principal_name; char *srv_keytab_path; -char *srv_mech_name=(char *)""; +const char *srv_mech_name=""; unsigned long srv_mech; /** @@ -101,7 +110,7 @@ static int initialize_plugin(void *unused) strcpy(first_packet, srv_principal_name); strcpy(first_packet + strlen(srv_principal_name) + 1,srv_mech_name); - first_packet_len = strlen(srv_principal_name) + strlen(srv_mech_name) + 2; + first_packet_len = (int)(strlen(srv_principal_name) + strlen(srv_mech_name) + 2); return 0; } @@ -132,7 +141,7 @@ static const char* mech_names[] = { NULL }; static TYPELIB mech_name_typelib = { - array_elements(mech_names) - 1, + 3, "mech_name_typelib", mech_names, NULL diff --git a/plugin/auth_gssapi/server_plugin.h b/plugin/auth_gssapi/server_plugin.h index 1348835e653..6284a319d03 100644 --- a/plugin/auth_gssapi/server_plugin.h +++ b/plugin/auth_gssapi/server_plugin.h @@ -37,7 +37,7 @@ typedef enum extern unsigned long srv_mech; extern char *srv_principal_name; -extern char *srv_mech_name; +extern const char *srv_mech_name; extern char *srv_keytab_path; /* Check, with GSSAPI/SSPI username of logged on user. diff --git a/plugin/auth_gssapi/sspi_client.cc b/plugin/auth_gssapi/sspi_client.cc index 34c1ce2e7ee..61249dd1072 100644 --- a/plugin/auth_gssapi/sspi_client.cc +++ b/plugin/auth_gssapi/sspi_client.cc @@ -180,4 +180,4 @@ cleanup: FreeCredentialsHandle(&cred); free(out); return ret; -}
\ No newline at end of file +} diff --git a/plugin/auth_gssapi/sspi_errmsg.cc b/plugin/auth_gssapi/sspi_errmsg.cc index 961ef51f42e..8e59da6f1ed 100644 --- a/plugin/auth_gssapi/sspi_errmsg.cc +++ b/plugin/auth_gssapi/sspi_errmsg.cc @@ -138,7 +138,7 @@ void sspi_errmsg(int err, char *buf, size_t size) len = FormatMessageA( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - buf, size, NULL); + buf, (DWORD)size, NULL); if(len > 0) { diff --git a/plugin/auth_gssapi/sspi_server.cc b/plugin/auth_gssapi/sspi_server.cc index fe90a195d88..af78829df6e 100644 --- a/plugin/auth_gssapi/sspi_server.cc +++ b/plugin/auth_gssapi/sspi_server.cc @@ -30,9 +30,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "common.h" #include "server_plugin.h" #include <mysql/plugin_auth.h> -#include <my_sys.h> #include <mysqld_error.h> -#include <log.h> /* This sends the error to the client */ @@ -115,7 +113,7 @@ static int get_client_name_from_context(CtxtHandle *ctxt, sspi_ret= ImpersonateSecurityContext(ctxt); if (sspi_ret == SEC_E_OK) { - ULONG len= name_len; + ULONG len= (ULONG)name_len; if (!GetUserNameEx(NameSamCompatible, name, &len)) { log_error(GetLastError(), "GetUserNameEx"); @@ -170,7 +168,7 @@ int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int co } sspi_ret= AcquireCredentialsHandle( srv_principal_name, - srv_mech_name, + (LPSTR)srv_mech_name, SECPKG_CRED_INBOUND, NULL, NULL, @@ -254,7 +252,7 @@ int auth_server(MYSQL_PLUGIN_VIO *vio, const char *user, size_t user_len, int co { my_printf_error(ER_ACCESS_DENIED_ERROR, "GSSAPI name mismatch, requested '%s', actual name '%s'", - MYF(0), user, client_name); + 0, user, client_name); } cleanup: @@ -294,7 +292,7 @@ int plugin_init() ret = AcquireCredentialsHandle( srv_principal_name, - srv_mech_name, + (LPSTR)srv_mech_name, SECPKG_CRED_INBOUND, NULL, NULL, diff --git a/plugin/aws_key_management/aws_key_management_plugin.cc b/plugin/aws_key_management/aws_key_management_plugin.cc index 2c89010c5a7..eb330103291 100644 --- a/plugin/aws_key_management/aws_key_management_plugin.cc +++ b/plugin/aws_key_management/aws_key_management_plugin.cc @@ -474,7 +474,7 @@ static int read_and_decrypt_key(const char *path, KEY_INFO *info) return(ENCRYPTION_KEY_BUFFER_TOO_SMALL); } memcpy(info->data, plaintext.GetUnderlyingData(), len); - info->length= len; + info->length= (unsigned int)len; return(0); } @@ -530,7 +530,7 @@ static int generate_and_save_datakey(uint keyid, uint version) my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: Can't create file %s", ME_ERROR_LOG, filename); return(-1); } - size_t len= byteBuffer.GetLength(); + unsigned int len= (unsigned int)byteBuffer.GetLength(); if (write(fd, byteBuffer.GetUnderlyingData(), len) != len) { my_printf_error(ER_UNKNOWN_ERROR, "AWS KMS plugin: can't write to %s", ME_ERROR_LOG, filename); diff --git a/plugin/cracklib_password_check/cracklib_password_check.c b/plugin/cracklib_password_check/cracklib_password_check.c index 94587a6d659..22d5eee21f2 100644 --- a/plugin/cracklib_password_check/cracklib_password_check.c +++ b/plugin/cracklib_password_check/cracklib_password_check.c @@ -13,17 +13,15 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <my_config.h> #include <mysql/plugin_password_validation.h> #include <crack.h> #include <string.h> #include <alloca.h> -#include <my_sys.h> #include <mysqld_error.h> static char *dictionary; -static int crackme(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) +static int crackme(MYSQL_CONST_LEX_STRING *username, MYSQL_CONST_LEX_STRING *password) { char *user= alloca(username->length + 1); char *host; @@ -37,11 +35,11 @@ static int crackme(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) if ((res= FascistCheckUser(password->str, dictionary, user, host))) { my_printf_error(ER_NOT_VALID_PASSWORD, "cracklib: %s", - MYF(ME_JUST_WARNING), res); - return TRUE; + ME_WARNING, res); + return 1; } - return FALSE; + return 0; } static MYSQL_SYSVAR_STR(dictionary, dictionary, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, diff --git a/plugin/disks/information_schema_disks.cc b/plugin/disks/information_schema_disks.cc index 122b3d3f17f..d2287631386 100644 --- a/plugin/disks/information_schema_disks.cc +++ b/plugin/disks/information_schema_disks.cc @@ -14,6 +14,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include <my_global.h> #include <sys/statvfs.h> #include <sys/types.h> #include <mntent.h> diff --git a/plugin/feedback/feedback.cc b/plugin/feedback/feedback.cc index 15a280f34bf..826a929643d 100644 --- a/plugin/feedback/feedback.cc +++ b/plugin/feedback/feedback.cc @@ -93,8 +93,8 @@ static COND* make_cond(THD *thd, TABLE_LIST *tables, LEX_STRING *filter) { Item_cond_or *res= NULL; Name_resolution_context nrc; - const char *db= tables->db, *table= tables->alias, - *field= tables->table->field[0]->field_name; + const char *db= tables->db.str, *table= tables->alias.str; + LEX_CSTRING *field= &tables->table->field[0]->field_name; CHARSET_INFO *cs= &my_charset_latin1; if (!filter->str) diff --git a/plugin/feedback/feedback.h b/plugin/feedback/feedback.h index 5e7e7b1516e..43c9f4ee844 100644 --- a/plugin/feedback/feedback.h +++ b/plugin/feedback/feedback.h @@ -14,6 +14,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #define MYSQL_SERVER 1 +#include <my_global.h> #include <sql_class.h> namespace feedback { diff --git a/plugin/feedback/sender_thread.cc b/plugin/feedback/sender_thread.cc index bcd10f6713f..92f186a1e2a 100644 --- a/plugin/feedback/sender_thread.cc +++ b/plugin/feedback/sender_thread.cc @@ -40,7 +40,7 @@ ulong interval= 60*60*24*7; ///< in seconds (one week) */ static int table_to_string(TABLE *table, String *result) { - bool res; + int res; char buff1[MAX_FIELD_WIDTH], buff2[MAX_FIELD_WIDTH]; String str1(buff1, sizeof(buff1), system_charset_info); String str2(buff2, sizeof(buff2), system_charset_info); @@ -64,7 +64,7 @@ static int table_to_string(TABLE *table, String *result) } } - res = res || result->append('\n'); + res = res || (int)result->append('\n'); /* Note, "|=" and not "||" - because we want to call ha_rnd_end() @@ -105,8 +105,7 @@ static int prepare_for_fill(TABLE_LIST *tables) thd->set_time(); thd->init_for_queries(); thd->real_id= pthread_self(); - thd->db= NULL; - thd->db_length= 0; + thd->db= null_clex_str; thd->security_ctx->host_or_ip= ""; thd->security_ctx->db_access= DB_ACLS; thd->security_ctx->master_access= ~NO_ACCESS; @@ -114,11 +113,9 @@ static int prepare_for_fill(TABLE_LIST *tables) lex_start(thd); mysql_init_select(thd->lex); - tables->init_one_table(INFORMATION_SCHEMA_NAME.str, - INFORMATION_SCHEMA_NAME.length, - i_s_feedback->table_name, - strlen(i_s_feedback->table_name), - 0, TL_READ); + LEX_CSTRING tbl_name= {i_s_feedback->table_name, strlen(i_s_feedback->table_name) }; + + tables->init_one_table(&INFORMATION_SCHEMA_NAME, &tbl_name, 0, TL_READ); tables->schema_table= i_s_feedback; tables->table= create_schema_table(thd, tables); if (!tables->table) diff --git a/plugin/feedback/url_http.cc b/plugin/feedback/url_http.cc index 4851097e63f..76aef909756 100644 --- a/plugin/feedback/url_http.cc +++ b/plugin/feedback/url_http.cc @@ -40,9 +40,9 @@ class Url_http: public Url { bool ssl; LEX_STRING proxy_host, proxy_port; - int use_proxy() + bool use_proxy() { - return proxy_host.length; + return proxy_host.length != 0; } Url_http(LEX_STRING &url_arg, LEX_STRING &host_arg, @@ -166,7 +166,7 @@ int Url_http::send(const char* data, size_t data_length) { my_socket fd= INVALID_SOCKET; char buf[1024]; - uint len= 0; + size_t len= 0; addrinfo *addrs, *addr, filter= {0, AF_UNSPEC, SOCK_STREAM, 6, 0, 0, 0, 0}; int res= use_proxy() ? @@ -186,7 +186,7 @@ int Url_http::send(const char* data, size_t data_length) if (fd == INVALID_SOCKET) continue; - if (connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) + if (connect(fd, addr->ai_addr, (int) addr->ai_addrlen) == 0) break; closesocket(fd); diff --git a/plugin/feedback/utils.cc b/plugin/feedback/utils.cc index b5b9d412f05..64510161691 100644 --- a/plugin/feedback/utils.cc +++ b/plugin/feedback/utils.cc @@ -92,12 +92,19 @@ static int uname(struct utsname *buf) { OSVERSIONINFOEX ver; ver.dwOSVersionInfoSize = (DWORD)sizeof(ver); + /* GetVersionEx got deprecated, we need it anyway, so disable deprecation warnings. */ +#ifdef _MSC_VER +#pragma warning (disable : 4996) +#endif +#ifdef __clang__ +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif if (!GetVersionEx((OSVERSIONINFO *)&ver)) return -1; buf->nodename[0]= 0; strcpy(buf->sysname, "Windows"); - sprintf(buf->release, "%d.%d", ver.dwMajorVersion, ver.dwMinorVersion); + sprintf(buf->release, "%d.%d", (int)ver.dwMajorVersion, (int)ver.dwMinorVersion); const char *version_str= get_os_version_name(&ver); if(version_str && version_str[0]) @@ -106,7 +113,7 @@ static int uname(struct utsname *buf) { /* Fallback for unknown versions, e.g "Windows <major_ver>.<minor_ver>" */ sprintf(buf->version, "Windows %d.%d%s", - ver.dwMajorVersion, ver.dwMinorVersion, + (int)ver.dwMajorVersion, (int)ver.dwMinorVersion, (ver.wProductType == VER_NT_WORKSTATION ? "" : " Server")); } @@ -380,9 +387,7 @@ int fill_misc_data(THD *thd, TABLE_LIST *tables) { TABLE *table= tables->table; -#ifdef MY_ATOMIC_OK INSERT1("Cpu_count", (my_getncpus(), UNSIGNED)); -#endif INSERT1("Mem_total", (my_getphysmem(), UNSIGNED)); INSERT1("Now", (thd->query_start(), UNSIGNED)); diff --git a/plugin/file_key_management/parser.cc b/plugin/file_key_management/parser.cc index 4700788bf83..13a9dfa0cb6 100644 --- a/plugin/file_key_management/parser.cc +++ b/plugin/file_key_management/parser.cc @@ -69,6 +69,7 @@ Example: openssl enc -aes-256-cbc -md sha1 -k "secret" -in keys.txt -out keys.enc ***********************************************************************/ +#include <my_global.h> #include "parser.h" #include <m_string.h> #include <mysys_err.h> diff --git a/plugin/handler_socket/CMakeLists.txt b/plugin/handler_socket/CMakeLists.txt index bd656ebc5b7..329ff58d7f2 100644 --- a/plugin/handler_socket/CMakeLists.txt +++ b/plugin/handler_socket/CMakeLists.txt @@ -5,14 +5,7 @@ IF(WIN32) RETURN() ENDIF() -#Remove -fno-implicit-templates from compiler flags(handlersocket would not work with it) -STRING(REPLACE "-fno-implicit-templates" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - -include(CheckCXXCompilerFlag) -check_cxx_compiler_flag(" -Wdeprecated-declarations" HAVE_CXX_WDEPRECATED_DECLARATIONS) -IF (HAVE_CXX_WDEPRECATED_DECLARATIONS) - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-deprecated-declarations") -ENDIF() +MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-deprecated-declarations") INCLUDE_DIRECTORIES(libhsclient) diff --git a/plugin/handler_socket/docs-en/protocol.en.txt b/plugin/handler_socket/docs-en/protocol.en.txt index e36f17444ae..3518be36dcf 100644 --- a/plugin/handler_socket/docs-en/protocol.en.txt +++ b/plugin/handler_socket/docs-en/protocol.en.txt @@ -46,7 +46,7 @@ Once an 'open_index' request is issued, the HandlerSocket plugin opens the specified index and keep it open until the client connection is closed. Each open index is identified by <indexid>. If <indexid> is already open, the old open index is closed. You can open the same combination of <dbname> -<tablename> <indexname> multple times, possibly with different <columns>. +<tablename> <indexname> multiple times, possibly with different <columns>. For efficiency, keep <indexid> small as far as possible. ---------------------------------------------------------------------------- diff --git a/plugin/handler_socket/handlersocket/database.cpp b/plugin/handler_socket/handlersocket/database.cpp index 4292b826753..a76428b29d3 100644 --- a/plugin/handler_socket/handlersocket/database.cpp +++ b/plugin/handler_socket/handlersocket/database.cpp @@ -6,10 +6,7 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> - -#include <stdlib.h> -#include <stdio.h> +#include <my_global.h> #include <string.h> #include "database.hpp" @@ -300,9 +297,9 @@ dbcontext::init_thread(const void *stack_bottom, volatile int& shutdown_flag) #else thd->options |= OPTION_BIN_LOG; #endif - safeFree(thd->db); - thd->db = 0; - thd->db = my_strdup("handlersocket", MYF(0)); + safeFree((char*) thd->db.str); + thd->db.str= my_strdup("handlersocket", MYF(0)); + thd->db.length= sizeof("handlersocket")-1; } thd->variables.option_bits |= OPTION_TABLE_LOCK; my_pthread_setspecific_ptr(THR_THD, thd); @@ -1008,8 +1005,9 @@ dbcontext::cmd_open(dbcallback_i& cb, const cmd_open_args& arg) bool refresh = true; const thr_lock_type lock_type = for_write_flag ? TL_WRITE : TL_READ; #if MYSQL_VERSION_ID >= 50505 - tables.init_one_table(arg.dbn, strlen(arg.dbn), arg.tbl, strlen(arg.tbl), - arg.tbl, lock_type); + LEX_CSTRING db_name= { arg.dbn, strlen(arg.dbn) }; + LEX_CSTRING tbl_name= { arg.tbl, strlen(arg.tbl) }; + tables.init_one_table(&db_name, &tbl_name, 0, lock_type); tables.mdl_request.init(MDL_key::TABLE, arg.dbn, arg.tbl, for_write_flag ? MDL_SHARED_WRITE : MDL_SHARED_READ, MDL_TRANSACTION); Open_table_context ot_act(thd, 0); @@ -1050,7 +1048,7 @@ dbcontext::cmd_open(dbcallback_i& cb, const cmd_open_args& arg) TABLE *const table = table_vec[tblnum].table; for (uint i = 0; i < table->s->keys; ++i) { KEY& kinfo = table->key_info[i]; - if (strcmp(kinfo.name, idx_name_to_open) == 0) { + if (strcmp(kinfo.name.str, idx_name_to_open) == 0) { idxnum = i; break; } @@ -1085,8 +1083,8 @@ dbcontext::parse_fields(TABLE *const table, const char *str, Field **fld = 0; size_t j = 0; for (fld = table->field; *fld; ++fld, ++j) { - DBG_FLD(fprintf(stderr, "f %s\n", (*fld)->field_name)); - string_ref fn((*fld)->field_name, strlen((*fld)->field_name)); + DBG_FLD(fprintf(stderr, "f %s\n", (*fld)->field_name.str)); + string_ref fn((*fld)->field_name.str, (*fld)->field_name.length); if (fn == fldnms[i]) { break; } @@ -1096,7 +1094,7 @@ dbcontext::parse_fields(TABLE *const table, const char *str, std::string(fldnms[i].begin(), fldnms[i].size()).c_str())); return false; } - DBG_FLD(fprintf(stderr, "FLD %s %zu\n", (*fld)->field_name, j)); + DBG_FLD(fprintf(stderr, "FLD %s %zu\n", (*fld)->field_name.str, j)); flds.push_back(j); } return true; diff --git a/plugin/handler_socket/handlersocket/handlersocket.cpp b/plugin/handler_socket/handlersocket/handlersocket.cpp index 6e4c03fcc24..8133497044c 100644 --- a/plugin/handler_socket/handlersocket/handlersocket.cpp +++ b/plugin/handler_socket/handlersocket/handlersocket.cpp @@ -6,8 +6,7 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> - +#include <my_global.h> #include <memory> #include <string> #include <stdio.h> diff --git a/plugin/handler_socket/handlersocket/hstcpsvr.cpp b/plugin/handler_socket/handlersocket/hstcpsvr.cpp index 925020023bc..250ef2c7be5 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr.cpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr.cpp @@ -6,15 +6,11 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> - -#include <stdlib.h> +#include <my_global.h> #include <vector> -#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> -#include <fcntl.h> #include <sys/resource.h> #include "hstcpsvr.hpp" diff --git a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp index c254d17dff5..9863602af7a 100644 --- a/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp +++ b/plugin/handler_socket/handlersocket/hstcpsvr_worker.cpp @@ -6,13 +6,11 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> -#include <sys/types.h> +#include <my_global.h> #include <netinet/in.h> #include <errno.h> #include <poll.h> #include <unistd.h> -#include <fcntl.h> #include <stdexcept> #include <signal.h> #include <list> diff --git a/plugin/handler_socket/handlersocket/mysql_incl.hpp b/plugin/handler_socket/handlersocket/mysql_incl.hpp index 0fb4fceb143..0d056a7ed4a 100644 --- a/plugin/handler_socket/handlersocket/mysql_incl.hpp +++ b/plugin/handler_socket/handlersocket/mysql_incl.hpp @@ -19,8 +19,7 @@ #define MYSQL_SERVER 1 -#include <my_config.h> - +#include <my_global.h> #include <mysql_version.h> #if MYSQL_VERSION_ID >= 50505 diff --git a/plugin/handler_socket/libhsclient/auto_addrinfo.hpp b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp index aee22a1d0f6..f9db70fe971 100644 --- a/plugin/handler_socket/libhsclient/auto_addrinfo.hpp +++ b/plugin/handler_socket/libhsclient/auto_addrinfo.hpp @@ -9,8 +9,7 @@ #ifndef DENA_AUTO_ADDRINFO_HPP #define DENA_AUTO_ADDRINFO_HPP -#include <my_config.h> -#include <sys/types.h> +#include <my_global.h> #include <sys/socket.h> #include <netdb.h> #include <string.h> diff --git a/plugin/handler_socket/libhsclient/hstcpcli.cpp b/plugin/handler_socket/libhsclient/hstcpcli.cpp index 21c964cb046..461bed3f5d0 100644 --- a/plugin/handler_socket/libhsclient/hstcpcli.cpp +++ b/plugin/handler_socket/libhsclient/hstcpcli.cpp @@ -6,8 +6,7 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> - +#include <my_global.h> #include <stdexcept> #include "hstcpcli.hpp" diff --git a/plugin/handler_socket/libhsclient/socket.cpp b/plugin/handler_socket/libhsclient/socket.cpp index 2c93a3b4846..f1cdc9fb20f 100644 --- a/plugin/handler_socket/libhsclient/socket.cpp +++ b/plugin/handler_socket/libhsclient/socket.cpp @@ -6,13 +6,10 @@ * See COPYRIGHT.txt for details. */ -#include <my_config.h> +#include <my_global.h> #include <stdexcept> #include <string.h> -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> #include <signal.h> #include <sys/un.h> diff --git a/plugin/locale_info/locale_info.cc b/plugin/locale_info/locale_info.cc index 3d775c0be7c..e444b4fade0 100644 --- a/plugin/locale_info/locale_info.cc +++ b/plugin/locale_info/locale_info.cc @@ -26,6 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <my_global.h> #include <sql_class.h> // THD #include <table.h> // ST_SCHEMA_TABLE #include <mysql/plugin.h> diff --git a/plugin/metadata_lock_info/metadata_lock_info.cc b/plugin/metadata_lock_info/metadata_lock_info.cc index a2e3667dbab..e32bbc55f3e 100644 --- a/plugin/metadata_lock_info/metadata_lock_info.cc +++ b/plugin/metadata_lock_info/metadata_lock_info.cc @@ -14,7 +14,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #define MYSQL_SERVER 1 -#include "my_config.h" +#include <my_global.h> #include "mysql_version.h" #include "mysql/plugin.h" #include "sql_class.h" @@ -26,6 +26,7 @@ static const LEX_STRING metadata_lock_info_lock_name[] = { { C_STRING_WITH_LEN("Table metadata lock") }, { C_STRING_WITH_LEN("Stored function metadata lock") }, { C_STRING_WITH_LEN("Stored procedure metadata lock") }, + { C_STRING_WITH_LEN("Stored package body metadata lock") }, { C_STRING_WITH_LEN("Trigger metadata lock") }, { C_STRING_WITH_LEN("Event metadata lock") }, { C_STRING_WITH_LEN("Commit lock") }, @@ -53,7 +54,7 @@ static ST_FIELD_INFO i_s_metadata_lock_info_fields_info[] = MY_I_S_MAYBE_NULL, "lock_mode", SKIP_OPEN_TABLE}, {"LOCK_DURATION", 30, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "lock_duration", SKIP_OPEN_TABLE}, - {"LOCK_TYPE", 30, MYSQL_TYPE_STRING, 0, + {"LOCK_TYPE", 33, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "lock_type", SKIP_OPEN_TABLE}, {"TABLE_SCHEMA", 64, MYSQL_TYPE_STRING, 0, MY_I_S_MAYBE_NULL, "table_schema", SKIP_OPEN_TABLE}, diff --git a/plugin/qc_info/qc_info.cc b/plugin/qc_info/qc_info.cc index e36e490dec3..c01207571d2 100644 --- a/plugin/qc_info/qc_info.cc +++ b/plugin/qc_info/qc_info.cc @@ -77,6 +77,7 @@ bool schema_table_store_record(THD *thd, TABLE *table); #define COLUMN_IN_TRANS 20 #define COLUMN_AUTOCOMMIT 21 #define COLUMN_PKT_NR 22 +#define COLUMN_HITS 23 /* ST_FIELD_INFO is defined in table.h */ static ST_FIELD_INFO qc_info_fields[]= @@ -104,6 +105,7 @@ static ST_FIELD_INFO qc_info_fields[]= {"IN_TRANS", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_TINY, 0, 0, 0, 0}, {"AUTOCOMMIT", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_TINY, 0, 0, 0, 0}, {"PACKET_NUMBER", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_TINY, 0, 0, 0, 0}, + {"HITS", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0, 0}, {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, 0} }; @@ -142,7 +144,7 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, size_t flags_length; const char *key, *db; size_t key_length, db_length; - LEX_STRING sql_mode_str; + LEX_CSTRING sql_mode_str; const String *tz; CHARSET_INFO *cs_client; CHARSET_INFO *cs_result; @@ -216,6 +218,7 @@ static int qc_info_fill_table(THD *thd, TABLE_LIST *tables, table->field[COLUMN_IN_TRANS]->store(flags.in_trans, 0); table->field[COLUMN_AUTOCOMMIT]->store(flags.autocommit, 0); table->field[COLUMN_PKT_NR]->store(flags.pkt_nr, 0); + table->field[COLUMN_HITS]->store(query_cache_query->hits(), 0); /* The database against which the statement is executed is part of the query cache query key diff --git a/plugin/query_response_time/plugin.cc b/plugin/query_response_time/plugin.cc index 0ed8b88dc60..7c4a7076c59 100644 --- a/plugin/query_response_time/plugin.cc +++ b/plugin/query_response_time/plugin.cc @@ -14,6 +14,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #define MYSQL_SERVER +#include <my_global.h> #include <sql_class.h> #include <table.h> #include <sql_show.h> diff --git a/plugin/semisync/semisync.cc b/plugin/semisync/semisync.cc deleted file mode 100644 index 4a80360ba4d..00000000000 --- a/plugin/semisync/semisync.cc +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (C) 2008 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include "semisync.h" - -const unsigned char ReplSemiSyncBase::kPacketMagicNum = 0xef; -const unsigned char ReplSemiSyncBase::kPacketFlagSync = 0x01; - - -const unsigned long Trace::kTraceGeneral = 0x0001; -const unsigned long Trace::kTraceDetail = 0x0010; -const unsigned long Trace::kTraceNetWait = 0x0020; -const unsigned long Trace::kTraceFunction = 0x0040; - -const unsigned char ReplSemiSyncBase::kSyncHeader[2] = - {ReplSemiSyncBase::kPacketMagicNum, 0}; diff --git a/plugin/semisync/semisync.h b/plugin/semisync/semisync.h deleted file mode 100644 index 28577296817..00000000000 --- a/plugin/semisync/semisync.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (C) 2008 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#ifndef SEMISYNC_H -#define SEMISYNC_H - -#define MYSQL_SERVER -#define HAVE_REPLICATION -#include <my_pthread.h> -#include <sql_priv.h> -#include <sql_class.h> -#include "unireg.h" -#include <replication.h> -#include "log.h" /* sql_print_information */ - -typedef struct st_mysql_show_var SHOW_VAR; -typedef struct st_mysql_sys_var SYS_VAR; - - -/** - This class is used to trace function calls and other process - information -*/ -class Trace { -public: - static const unsigned long kTraceFunction; - static const unsigned long kTraceGeneral; - static const unsigned long kTraceDetail; - static const unsigned long kTraceNetWait; - - unsigned long trace_level_; /* the level for tracing */ - - inline void function_enter(const char *func_name) - { - if (trace_level_ & kTraceFunction) - sql_print_information("---> %s enter", func_name); - } - inline int function_exit(const char *func_name, int exit_code) - { - if (trace_level_ & kTraceFunction) - sql_print_information("<--- %s exit (%d)", func_name, exit_code); - return exit_code; - } - - Trace() - :trace_level_(0L) - {} - Trace(unsigned long trace_level) - :trace_level_(trace_level) - {} -}; - -/** - Base class for semi-sync master and slave classes -*/ -class ReplSemiSyncBase - :public Trace { -public: - static const unsigned char kSyncHeader[2]; /* three byte packet header */ - - /* Constants in network packet header. */ - static const unsigned char kPacketMagicNum; - static const unsigned char kPacketFlagSync; -}; - -/* The layout of a semisync slave reply packet: - 1 byte for the magic num - 8 bytes for the binlog positon - n bytes for the binlog filename, terminated with a '\0' -*/ -#define REPLY_MAGIC_NUM_LEN 1 -#define REPLY_BINLOG_POS_LEN 8 -#define REPLY_BINLOG_NAME_LEN (FN_REFLEN + 1) -#define REPLY_MAGIC_NUM_OFFSET 0 -#define REPLY_BINLOG_POS_OFFSET (REPLY_MAGIC_NUM_OFFSET + REPLY_MAGIC_NUM_LEN) -#define REPLY_BINLOG_NAME_OFFSET (REPLY_BINLOG_POS_OFFSET + REPLY_BINLOG_POS_LEN) - -#endif /* SEMISYNC_H */ diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc deleted file mode 100644 index ab437bcfa7e..00000000000 --- a/plugin/semisync/semisync_master.cc +++ /dev/null @@ -1,1217 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (c) 2008, 2013, Oracle and/or its affiliates. - Copyright (c) 2011, 2016, MariaDB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include "semisync_master.h" - -#define TIME_THOUSAND 1000 -#define TIME_MILLION 1000000 -#define TIME_BILLION 1000000000 - -/* This indicates whether semi-synchronous replication is enabled. */ -char rpl_semi_sync_master_enabled; -unsigned long rpl_semi_sync_master_wait_point = - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT; -unsigned long rpl_semi_sync_master_timeout; -unsigned long rpl_semi_sync_master_trace_level; -char rpl_semi_sync_master_status = 0; -unsigned long rpl_semi_sync_master_yes_transactions = 0; -unsigned long rpl_semi_sync_master_no_transactions = 0; -unsigned long rpl_semi_sync_master_off_times = 0; -unsigned long rpl_semi_sync_master_timefunc_fails = 0; -unsigned long rpl_semi_sync_master_wait_timeouts = 0; -unsigned long rpl_semi_sync_master_wait_sessions = 0; -unsigned long rpl_semi_sync_master_wait_pos_backtraverse = 0; -unsigned long rpl_semi_sync_master_avg_trx_wait_time = 0; -unsigned long long rpl_semi_sync_master_trx_wait_num = 0; -unsigned long rpl_semi_sync_master_avg_net_wait_time = 0; -unsigned long long rpl_semi_sync_master_net_wait_num = 0; -unsigned long rpl_semi_sync_master_clients = 0; -unsigned long long rpl_semi_sync_master_net_wait_time = 0; -unsigned long long rpl_semi_sync_master_trx_wait_time = 0; -char rpl_semi_sync_master_wait_no_slave = 1; - - -static int getWaitTime(const struct timespec& start_ts); - -static unsigned long long timespec_to_usec(const struct timespec *ts) -{ - return (unsigned long long) ts->tv_sec * TIME_MILLION + ts->tv_nsec / TIME_THOUSAND; -} - -/******************************************************************************* - * - * <ActiveTranx> class : manage all active transaction nodes - * - ******************************************************************************/ - -ActiveTranx::ActiveTranx(mysql_mutex_t *lock, - unsigned long trace_level) - : Trace(trace_level), allocator_(max_connections), - num_entries_(max_connections << 1), /* Transaction hash table size - * is set to double the size - * of max_connections */ - lock_(lock) -{ - /* No transactions are in the list initially. */ - trx_front_ = NULL; - trx_rear_ = NULL; - - /* Create the hash table to find a transaction's ending event. */ - trx_htb_ = new TranxNode *[num_entries_]; - for (int idx = 0; idx < num_entries_; ++idx) - trx_htb_[idx] = NULL; - - sql_print_information("Semi-sync replication initialized for transactions."); -} - -ActiveTranx::~ActiveTranx() -{ - delete [] trx_htb_; - trx_htb_ = NULL; - num_entries_ = 0; -} - -unsigned int ActiveTranx::calc_hash(const unsigned char *key, - unsigned int length) -{ - unsigned int nr = 1, nr2 = 4; - - /* The hash implementation comes from calc_hashnr() in mysys/hash.c. */ - while (length--) - { - nr ^= (((nr & 63)+nr2)*((unsigned int) (unsigned char) *key++))+ (nr << 8); - nr2 += 3; - } - return((unsigned int) nr); -} - -unsigned int ActiveTranx::get_hash_value(const char *log_file_name, - my_off_t log_file_pos) -{ - unsigned int hash1 = calc_hash((const unsigned char *)log_file_name, - strlen(log_file_name)); - unsigned int hash2 = calc_hash((const unsigned char *)(&log_file_pos), - sizeof(log_file_pos)); - - return (hash1 + hash2) % num_entries_; -} - -int ActiveTranx::compare(const char *log_file_name1, my_off_t log_file_pos1, - const char *log_file_name2, my_off_t log_file_pos2) -{ - int cmp = strcmp(log_file_name1, log_file_name2); - - if (cmp != 0) - return cmp; - - if (log_file_pos1 > log_file_pos2) - return 1; - else if (log_file_pos1 < log_file_pos2) - return -1; - return 0; -} - -int ActiveTranx::insert_tranx_node(const char *log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ActiveTranx:insert_tranx_node"; - TranxNode *ins_node; - int result = 0; - unsigned int hash_val; - - function_enter(kWho); - - ins_node = allocator_.allocate_node(); - if (!ins_node) - { - sql_print_error("%s: transaction node allocation failed for: (%s, %lu)", - kWho, log_file_name, (unsigned long)log_file_pos); - result = -1; - goto l_end; - } - - /* insert the binlog position in the active transaction list. */ - strncpy(ins_node->log_name_, log_file_name, FN_REFLEN-1); - ins_node->log_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */ - ins_node->log_pos_ = log_file_pos; - - if (!trx_front_) - { - /* The list is empty. */ - trx_front_ = trx_rear_ = ins_node; - } - else - { - int cmp = compare(ins_node, trx_rear_); - if (cmp > 0) - { - /* Compare with the tail first. If the transaction happens later in - * binlog, then make it the new tail. - */ - trx_rear_->next_ = ins_node; - trx_rear_ = ins_node; - } - else - { - /* Otherwise, it is an error because the transaction should hold the - * mysql_bin_log.LOCK_log when appending events. - */ - sql_print_error("%s: binlog write out-of-order, tail (%s, %lu), " - "new node (%s, %lu)", kWho, - trx_rear_->log_name_, (unsigned long)trx_rear_->log_pos_, - ins_node->log_name_, (unsigned long)ins_node->log_pos_); - result = -1; - goto l_end; - } - } - - hash_val = get_hash_value(ins_node->log_name_, ins_node->log_pos_); - ins_node->hash_next_ = trx_htb_[hash_val]; - trx_htb_[hash_val] = ins_node; - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: insert (%s, %lu) in entry(%u)", kWho, - ins_node->log_name_, (unsigned long)ins_node->log_pos_, - hash_val); - - l_end: - return function_exit(kWho, result); -} - -bool ActiveTranx::is_tranx_end_pos(const char *log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ActiveTranx::is_tranx_end_pos"; - function_enter(kWho); - - unsigned int hash_val = get_hash_value(log_file_name, log_file_pos); - TranxNode *entry = trx_htb_[hash_val]; - - while (entry != NULL) - { - if (compare(entry, log_file_name, log_file_pos) == 0) - break; - - entry = entry->hash_next_; - } - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: probe (%s, %lu) in entry(%u)", kWho, - log_file_name, (unsigned long)log_file_pos, hash_val); - - function_exit(kWho, (entry != NULL)); - return (entry != NULL); -} - -int ActiveTranx::clear_active_tranx_nodes(const char *log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ActiveTranx::::clear_active_tranx_nodes"; - TranxNode *new_front; - - function_enter(kWho); - - if (log_file_name != NULL) - { - new_front = trx_front_; - - while (new_front) - { - if (compare(new_front, log_file_name, log_file_pos) > 0) - break; - new_front = new_front->next_; - } - } - else - { - /* If log_file_name is NULL, clear everything. */ - new_front = NULL; - } - - if (new_front == NULL) - { - /* No active transaction nodes after the call. */ - - /* Clear the hash table. */ - memset(trx_htb_, 0, num_entries_ * sizeof(TranxNode *)); - allocator_.free_all_nodes(); - - /* Clear the active transaction list. */ - if (trx_front_ != NULL) - { - trx_front_ = NULL; - trx_rear_ = NULL; - } - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: cleared all nodes", kWho); - } - else if (new_front != trx_front_) - { - TranxNode *curr_node, *next_node; - - /* Delete all transaction nodes before the confirmation point. */ - int n_frees = 0; - curr_node = trx_front_; - while (curr_node != new_front) - { - next_node = curr_node->next_; - n_frees++; - - /* Remove the node from the hash table. */ - unsigned int hash_val = get_hash_value(curr_node->log_name_, curr_node->log_pos_); - TranxNode **hash_ptr = &(trx_htb_[hash_val]); - while ((*hash_ptr) != NULL) - { - if ((*hash_ptr) == curr_node) - { - (*hash_ptr) = curr_node->hash_next_; - break; - } - hash_ptr = &((*hash_ptr)->hash_next_); - } - - curr_node = next_node; - } - - trx_front_ = new_front; - allocator_.free_nodes_before(trx_front_); - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: cleared %d nodes back until pos (%s, %lu)", - kWho, n_frees, - trx_front_->log_name_, (unsigned long)trx_front_->log_pos_); - } - - return function_exit(kWho, 0); -} - - -/******************************************************************************* - * - * <ReplSemiSyncMaster> class: the basic code layer for sync-replication master. - * <ReplSemiSyncSlave> class: the basic code layer for sync-replication slave. - * - * The most important functions during semi-syn replication listed: - * - * Master: - * . reportReplyBinlog(): called by the binlog dump thread when it receives - * the slave's status information. - * . updateSyncHeader(): based on transaction waiting information, decide - * whether to request the slave to reply. - * . writeTranxInBinlog(): called by the transaction thread when it finishes - * writing all transaction events in binlog. - * . commitTrx(): transaction thread wait for the slave reply. - * - * Slave: - * . slaveReadSyncHeader(): read the semi-sync header from the master, get the - * sync status and get the payload for events. - * . slaveReply(): reply to the master about the replication progress. - * - ******************************************************************************/ - -ReplSemiSyncMaster::ReplSemiSyncMaster() - : active_tranxs_(NULL), - init_done_(false), - reply_file_name_inited_(false), - reply_file_pos_(0L), - wait_file_name_inited_(false), - wait_file_pos_(0), - master_enabled_(false), - wait_timeout_(0L), - state_(0) -{ - strcpy(reply_file_name_, ""); - strcpy(wait_file_name_, ""); -} - -int ReplSemiSyncMaster::initObject() -{ - int result; - const char *kWho = "ReplSemiSyncMaster::initObject"; - - if (init_done_) - { - fprintf(stderr, "%s called twice\n", kWho); - return 1; - } - init_done_ = true; - - /* References to the parameter works after set_options(). */ - setWaitTimeout(rpl_semi_sync_master_timeout); - setTraceLevel(rpl_semi_sync_master_trace_level); - - /* Mutex initialization can only be done after MY_INIT(). */ - mysql_mutex_init(key_ss_mutex_LOCK_binlog_, - &LOCK_binlog_, MY_MUTEX_INIT_FAST); - mysql_cond_init(key_ss_cond_COND_binlog_send_, - &COND_binlog_send_, NULL); - - if (rpl_semi_sync_master_enabled) - result = enableMaster(); - else - result = disableMaster(); - - return result; -} - -int ReplSemiSyncMaster::enableMaster() -{ - int result = 0; - - /* Must have the lock when we do enable of disable. */ - lock(); - - if (!getMasterEnabled()) - { - active_tranxs_ = new ActiveTranx(&LOCK_binlog_, trace_level_); - if (active_tranxs_ != NULL) - { - commit_file_name_inited_ = false; - reply_file_name_inited_ = false; - wait_file_name_inited_ = false; - - set_master_enabled(true); - state_ = true; - sql_print_information("Semi-sync replication enabled on the master."); - } - else - { - sql_print_error("Cannot allocate memory to enable semi-sync on the master."); - result = -1; - } - } - - unlock(); - - return result; -} - -int ReplSemiSyncMaster::disableMaster() -{ - /* Must have the lock when we do enable of disable. */ - lock(); - - if (getMasterEnabled()) - { - /* Switch off the semi-sync first so that waiting transaction will be - * waken up. - */ - switch_off(); - - assert(active_tranxs_ != NULL); - delete active_tranxs_; - active_tranxs_ = NULL; - - reply_file_name_inited_ = false; - wait_file_name_inited_ = false; - commit_file_name_inited_ = false; - - set_master_enabled(false); - sql_print_information("Semi-sync replication disabled on the master."); - } - - unlock(); - - return 0; -} - -void ReplSemiSyncMaster::cleanup() -{ - if (init_done_) - { - mysql_mutex_destroy(&LOCK_binlog_); - mysql_cond_destroy(&COND_binlog_send_); - init_done_= 0; - } - - delete active_tranxs_; -} - -void ReplSemiSyncMaster::lock() -{ - mysql_mutex_lock(&LOCK_binlog_); -} - -void ReplSemiSyncMaster::unlock() -{ - mysql_mutex_unlock(&LOCK_binlog_); -} - -void ReplSemiSyncMaster::cond_broadcast() -{ - mysql_cond_broadcast(&COND_binlog_send_); -} - -int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time) -{ - const char *kWho = "ReplSemiSyncMaster::cond_timewait()"; - int wait_res; - - function_enter(kWho); - wait_res= mysql_cond_timedwait(&COND_binlog_send_, - &LOCK_binlog_, wait_time); - return function_exit(kWho, wait_res); -} - -void ReplSemiSyncMaster::add_slave() -{ - lock(); - rpl_semi_sync_master_clients++; - unlock(); -} - -void ReplSemiSyncMaster::remove_slave() -{ - lock(); - rpl_semi_sync_master_clients--; - - /* Only switch off if semi-sync is enabled and is on */ - if (getMasterEnabled() && is_on()) - { - /* If user has chosen not to wait if no semi-sync slave available - and the last semi-sync slave exits, turn off semi-sync on master - immediately. - */ - if (!rpl_semi_sync_master_wait_no_slave && - rpl_semi_sync_master_clients == 0) - switch_off(); - } - unlock(); -} - -bool ReplSemiSyncMaster::is_semi_sync_slave() -{ - int null_value; - long long val= 0; - get_user_var_int("rpl_semi_sync_slave", &val, &null_value); - return val; -} - -int ReplSemiSyncMaster::reportReplyBinlog(uint32 server_id, - const char *log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ReplSemiSyncMaster::reportReplyBinlog"; - int cmp; - bool can_release_threads = false; - bool need_copy_send_pos = true; - - if (!(getMasterEnabled())) - return 0; - - function_enter(kWho); - - lock(); - - /* This is the real check inside the mutex. */ - if (!getMasterEnabled()) - goto l_end; - - if (!is_on()) - /* We check to see whether we can switch semi-sync ON. */ - try_switch_on(server_id, log_file_name, log_file_pos); - - /* The position should increase monotonically, if there is only one - * thread sending the binlog to the slave. - * In reality, to improve the transaction availability, we allow multiple - * sync replication slaves. So, if any one of them get the transaction, - * the transaction session in the primary can move forward. - */ - if (reply_file_name_inited_) - { - cmp = ActiveTranx::compare(log_file_name, log_file_pos, - reply_file_name_, reply_file_pos_); - - /* If the requested position is behind the sending binlog position, - * would not adjust sending binlog position. - * We based on the assumption that there are multiple semi-sync slave, - * and at least one of them shou/ld be up to date. - * If all semi-sync slaves are behind, at least initially, the primary - * can find the situation after the waiting timeout. After that, some - * slaves should catch up quickly. - */ - if (cmp < 0) - { - /* If the position is behind, do not copy it. */ - need_copy_send_pos = false; - } - } - - if (need_copy_send_pos) - { - strmake_buf(reply_file_name_, log_file_name); - reply_file_pos_ = log_file_pos; - reply_file_name_inited_ = true; - - /* Remove all active transaction nodes before this point. */ - assert(active_tranxs_ != NULL); - active_tranxs_->clear_active_tranx_nodes(log_file_name, log_file_pos); - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: Got reply at (%s, %lu)", kWho, - log_file_name, (unsigned long)log_file_pos); - } - - if (rpl_semi_sync_master_wait_sessions > 0) - { - /* Let us check if some of the waiting threads doing a trx - * commit can now proceed. - */ - cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_, - wait_file_name_, wait_file_pos_); - if (cmp >= 0) - { - /* Yes, at least one waiting thread can now proceed: - * let us release all waiting threads with a broadcast - */ - can_release_threads = true; - wait_file_name_inited_ = false; - } - } - - l_end: - unlock(); - - if (can_release_threads) - { - if (trace_level_ & kTraceDetail) - sql_print_information("%s: signal all waiting threads.", kWho); - - cond_broadcast(); - } - - return function_exit(kWho, 0); -} - -int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name, - my_off_t trx_wait_binlog_pos) -{ - const char *kWho = "ReplSemiSyncMaster::commitTrx"; - - function_enter(kWho); - - if (getMasterEnabled() && trx_wait_binlog_name) - { - struct timespec start_ts; - struct timespec abstime; - int wait_result; - PSI_stage_info old_stage; - - set_timespec(start_ts, 0); - - DEBUG_SYNC(current_thd, "rpl_semisync_master_commit_trx_before_lock"); - /* Acquire the mutex. */ - lock(); - - /* This must be called after acquired the lock */ - THD_ENTER_COND(NULL, &COND_binlog_send_, &LOCK_binlog_, - & stage_waiting_for_semi_sync_ack_from_slave, - & old_stage); - - /* This is the real check inside the mutex. */ - if (!getMasterEnabled() || !is_on()) - goto l_end; - - if (trace_level_ & kTraceDetail) - { - sql_print_information("%s: wait pos (%s, %lu), repl(%d)\n", kWho, - trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos, - (int)is_on()); - } - - while (is_on() && !thd_killed(current_thd)) - { - if (reply_file_name_inited_) - { - int cmp = ActiveTranx::compare(reply_file_name_, reply_file_pos_, - trx_wait_binlog_name, trx_wait_binlog_pos); - if (cmp >= 0) - { - /* We have already sent the relevant binlog to the slave: no need to - * wait here. - */ - if (trace_level_ & kTraceDetail) - sql_print_information("%s: Binlog reply is ahead (%s, %lu),", - kWho, reply_file_name_, (unsigned long)reply_file_pos_); - break; - } - } - - /* Let us update the info about the minimum binlog position of waiting - * threads. - */ - if (wait_file_name_inited_) - { - int cmp = ActiveTranx::compare(trx_wait_binlog_name, trx_wait_binlog_pos, - wait_file_name_, wait_file_pos_); - if (cmp <= 0) - { - /* This thd has a lower position, let's update the minimum info. */ - strmake_buf(wait_file_name_, trx_wait_binlog_name); - wait_file_pos_ = trx_wait_binlog_pos; - - rpl_semi_sync_master_wait_pos_backtraverse++; - if (trace_level_ & kTraceDetail) - sql_print_information("%s: move back wait position (%s, %lu),", - kWho, wait_file_name_, (unsigned long)wait_file_pos_); - } - } - else - { - strmake_buf(wait_file_name_, trx_wait_binlog_name); - wait_file_pos_ = trx_wait_binlog_pos; - wait_file_name_inited_ = true; - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: init wait position (%s, %lu),", - kWho, wait_file_name_, (unsigned long)wait_file_pos_); - } - - /* Calcuate the waiting period. */ - long diff_secs = (long) (wait_timeout_ / TIME_THOUSAND); - long diff_nsecs = (long) ((wait_timeout_ % TIME_THOUSAND) * TIME_MILLION); - long nsecs = start_ts.tv_nsec + diff_nsecs; - abstime.tv_sec = start_ts.tv_sec + diff_secs + nsecs/TIME_BILLION; - abstime.tv_nsec = nsecs % TIME_BILLION; - - /* In semi-synchronous replication, we wait until the binlog-dump - * thread has received the reply on the relevant binlog segment from the - * replication slave. - * - * Let us suspend this thread to wait on the condition; - * when replication has progressed far enough, we will release - * these waiting threads. - */ - rpl_semi_sync_master_wait_sessions++; - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: wait %lu ms for binlog sent (%s, %lu)", - kWho, wait_timeout_, - wait_file_name_, (unsigned long)wait_file_pos_); - - wait_result = cond_timewait(&abstime); - rpl_semi_sync_master_wait_sessions--; - - if (wait_result != 0) - { - /* This is a real wait timeout. */ - sql_print_warning("Timeout waiting for reply of binlog (file: %s, pos: %lu), " - "semi-sync up to file %s, position %lu.", - trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos, - reply_file_name_, (unsigned long)reply_file_pos_); - rpl_semi_sync_master_wait_timeouts++; - - /* switch semi-sync off */ - switch_off(); - } - else - { - int wait_time; - - wait_time = getWaitTime(start_ts); - if (wait_time < 0) - { - if (trace_level_ & kTraceGeneral) - { - sql_print_error("Replication semi-sync getWaitTime fail at " - "wait position (%s, %lu)", - trx_wait_binlog_name, (unsigned long)trx_wait_binlog_pos); - } - rpl_semi_sync_master_timefunc_fails++; - } - else - { - rpl_semi_sync_master_trx_wait_num++; - rpl_semi_sync_master_trx_wait_time += wait_time; - } - } - } - - /* - At this point, the binlog file and position of this transaction - must have been removed from ActiveTranx. - active_tranxs_ may be NULL if someone disabled semi sync during - cond_timewait() - */ - assert(thd_killed(current_thd) || !active_tranxs_ || - !active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name, - trx_wait_binlog_pos)); - - l_end: - /* Update the status counter. */ - if (is_on()) - rpl_semi_sync_master_yes_transactions++; - else - rpl_semi_sync_master_no_transactions++; - - /* The lock held will be released by thd_exit_cond, so no need to - call unlock() here */ - THD_EXIT_COND(NULL, & old_stage); - } - - return function_exit(kWho, 0); -} - -/* Indicate that semi-sync replication is OFF now. - * - * What should we do when it is disabled? The problem is that we want - * the semi-sync replication enabled again when the slave catches up - * later. But, it is not that easy to detect that the slave has caught - * up. This is caused by the fact that MySQL's replication protocol is - * asynchronous, meaning that if the master does not use the semi-sync - * protocol, the slave would not send anything to the master. - * Still, if the master is sending (N+1)-th event, we assume that it is - * an indicator that the slave has received N-th event and earlier ones. - * - * If semi-sync is disabled, all transactions still update the wait - * position with the last position in binlog. But no transactions will - * wait for confirmations and the active transaction list would not be - * maintained. In binlog dump thread, updateSyncHeader() checks whether - * the current sending event catches up with last wait position. If it - * does match, semi-sync will be switched on again. - */ -int ReplSemiSyncMaster::switch_off() -{ - const char *kWho = "ReplSemiSyncMaster::switch_off"; - int result; - - function_enter(kWho); - state_ = false; - - /* Clear the active transaction list. */ - assert(active_tranxs_ != NULL); - result = active_tranxs_->clear_active_tranx_nodes(NULL, 0); - - rpl_semi_sync_master_off_times++; - wait_file_name_inited_ = false; - reply_file_name_inited_ = false; - sql_print_information("Semi-sync replication switched OFF."); - cond_broadcast(); /* wake up all waiting threads */ - - return function_exit(kWho, result); -} - -int ReplSemiSyncMaster::try_switch_on(int server_id, - const char *log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ReplSemiSyncMaster::try_switch_on"; - bool semi_sync_on = false; - - function_enter(kWho); - - /* If the current sending event's position is larger than or equal to the - * 'largest' commit transaction binlog position, the slave is already - * catching up now and we can switch semi-sync on here. - * If commit_file_name_inited_ indicates there are no recent transactions, - * we can enable semi-sync immediately. - */ - if (commit_file_name_inited_) - { - int cmp = ActiveTranx::compare(log_file_name, log_file_pos, - commit_file_name_, commit_file_pos_); - semi_sync_on = (cmp >= 0); - } - else - { - semi_sync_on = true; - } - - if (semi_sync_on) - { - /* Switch semi-sync replication on. */ - state_ = true; - - sql_print_information("Semi-sync replication switched ON with slave (server_id: %d) " - "at (%s, %lu)", - server_id, log_file_name, - (unsigned long)log_file_pos); - } - - return function_exit(kWho, 0); -} - -int ReplSemiSyncMaster::reserveSyncHeader(unsigned char *header, - unsigned long size) -{ - const char *kWho = "ReplSemiSyncMaster::reserveSyncHeader"; - function_enter(kWho); - - int hlen=0; - if (!is_semi_sync_slave()) - { - hlen= 0; - } - else - { - /* No enough space for the extra header, disable semi-sync master */ - if (sizeof(kSyncHeader) > size) - { - sql_print_warning("No enough space in the packet " - "for semi-sync extra header, " - "semi-sync replication disabled"); - disableMaster(); - return 0; - } - - /* Set the magic number and the sync status. By default, no sync - * is required. - */ - memcpy(header, kSyncHeader, sizeof(kSyncHeader)); - hlen= sizeof(kSyncHeader); - } - return function_exit(kWho, hlen); -} - -int ReplSemiSyncMaster::updateSyncHeader(unsigned char *packet, - const char *log_file_name, - my_off_t log_file_pos, - uint32 server_id) -{ - const char *kWho = "ReplSemiSyncMaster::updateSyncHeader"; - int cmp = 0; - bool sync = false; - - /* If the semi-sync master is not enabled, or the slave is not a semi-sync - * target, do not request replies from the slave. - */ - if (!getMasterEnabled() || !is_semi_sync_slave()) - return 0; - - function_enter(kWho); - - lock(); - - /* This is the real check inside the mutex. */ - if (!getMasterEnabled()) - goto l_end; // sync= false at this point in time - - if (is_on()) - { - /* semi-sync is ON */ - /* sync= false; No sync unless a transaction is involved. */ - - if (reply_file_name_inited_) - { - cmp = ActiveTranx::compare(log_file_name, log_file_pos, - reply_file_name_, reply_file_pos_); - if (cmp <= 0) - { - /* If we have already got the reply for the event, then we do - * not need to sync the transaction again. - */ - goto l_end; - } - } - - if (wait_file_name_inited_) - { - cmp = ActiveTranx::compare(log_file_name, log_file_pos, - wait_file_name_, wait_file_pos_); - } - else - { - cmp = 1; - } - - /* If we are already waiting for some transaction replies which - * are later in binlog, do not wait for this one event. - */ - if (cmp >= 0) - { - /* - * We only wait if the event is a transaction's ending event. - */ - assert(active_tranxs_ != NULL); - sync = active_tranxs_->is_tranx_end_pos(log_file_name, - log_file_pos); - } - } - else - { - if (commit_file_name_inited_) - { - int cmp = ActiveTranx::compare(log_file_name, log_file_pos, - commit_file_name_, commit_file_pos_); - sync = (cmp >= 0); - } - else - { - sync = true; - } - } - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: server(%d), (%s, %lu) sync(%d), repl(%d)", - kWho, server_id, log_file_name, - (unsigned long)log_file_pos, sync, (int)is_on()); - - l_end: - unlock(); - - /* We do not need to clear sync flag because we set it to 0 when we - * reserve the packet header. - */ - if (sync) - { - (packet)[2] = kPacketFlagSync; - } - - return function_exit(kWho, 0); -} - -int ReplSemiSyncMaster::writeTranxInBinlog(const char* log_file_name, - my_off_t log_file_pos) -{ - const char *kWho = "ReplSemiSyncMaster::writeTranxInBinlog"; - int result = 0; - - function_enter(kWho); - - lock(); - - /* This is the real check inside the mutex. */ - if (!getMasterEnabled()) - goto l_end; - - /* Update the 'largest' transaction commit position seen so far even - * though semi-sync is switched off. - * It is much better that we update commit_file_* here, instead of - * inside commitTrx(). This is mostly because updateSyncHeader() - * will watch for commit_file_* to decide whether to switch semi-sync - * on. The detailed reason is explained in function updateSyncHeader(). - */ - if (commit_file_name_inited_) - { - int cmp = ActiveTranx::compare(log_file_name, log_file_pos, - commit_file_name_, commit_file_pos_); - if (cmp > 0) - { - /* This is a larger position, let's update the maximum info. */ - strncpy(commit_file_name_, log_file_name, FN_REFLEN-1); - commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */ - commit_file_pos_ = log_file_pos; - } - } - else - { - strncpy(commit_file_name_, log_file_name, FN_REFLEN-1); - commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */ - commit_file_pos_ = log_file_pos; - commit_file_name_inited_ = true; - } - - if (is_on()) - { - assert(active_tranxs_ != NULL); - if(active_tranxs_->insert_tranx_node(log_file_name, log_file_pos)) - { - /* - if insert tranx_node failed, print a warning message - and turn off semi-sync - */ - sql_print_warning("Semi-sync failed to insert tranx_node for binlog file: %s, position: %lu", - log_file_name, (ulong)log_file_pos); - switch_off(); - } - } - - l_end: - unlock(); - - return function_exit(kWho, result); -} - -int ReplSemiSyncMaster::readSlaveReply(NET *net, uint32 server_id, - const char *event_buf) -{ - const char *kWho = "ReplSemiSyncMaster::readSlaveReply"; - const unsigned char *packet; - char log_file_name[FN_REFLEN]; - my_off_t log_file_pos; - ulong log_file_len = 0; - ulong packet_len; - int result = -1; - struct timespec start_ts; - ulong trc_level = trace_level_; - LINT_INIT_STRUCT(start_ts); - - function_enter(kWho); - - assert((unsigned char)event_buf[1] == kPacketMagicNum); - if ((unsigned char)event_buf[2] != kPacketFlagSync) - { - /* current event does not require reply */ - result = 0; - goto l_end; - } - - if (trc_level & kTraceNetWait) - set_timespec(start_ts, 0); - - /* We flush to make sure that the current event is sent to the network, - * instead of being buffered in the TCP/IP stack. - */ - if (net_flush(net)) - { - sql_print_error("Semi-sync master failed on net_flush() " - "before waiting for slave reply"); - goto l_end; - } - - net_clear(net, 0); - if (trc_level & kTraceDetail) - sql_print_information("%s: Wait for replica's reply", kWho); - - /* Wait for the network here. Though binlog dump thread can indefinitely wait - * here, transactions would not wait indefintely. - * Transactions wait on binlog replies detected by binlog dump threads. If - * binlog dump threads wait too long, transactions will timeout and continue. - */ - packet_len = my_net_read(net); - - if (trc_level & kTraceNetWait) - { - int wait_time = getWaitTime(start_ts); - if (wait_time < 0) - { - sql_print_error("Semi-sync master wait for reply " - "fail to get wait time."); - rpl_semi_sync_master_timefunc_fails++; - } - else - { - rpl_semi_sync_master_net_wait_num++; - rpl_semi_sync_master_net_wait_time += wait_time; - } - } - - if (packet_len == packet_error || packet_len < REPLY_BINLOG_NAME_OFFSET) - { - if (packet_len == packet_error) - sql_print_error("Read semi-sync reply network error: %s (errno: %d)", - net->last_error, net->last_errno); - else - sql_print_error("Read semi-sync reply length error: %s (errno: %d)", - net->last_error, net->last_errno); - goto l_end; - } - - packet = net->read_pos; - if (packet[REPLY_MAGIC_NUM_OFFSET] != ReplSemiSyncMaster::kPacketMagicNum) - { - sql_print_error("Read semi-sync reply magic number error"); - goto l_end; - } - - log_file_pos = uint8korr(packet + REPLY_BINLOG_POS_OFFSET); - log_file_len = packet_len - REPLY_BINLOG_NAME_OFFSET; - if (log_file_len >= FN_REFLEN) - { - sql_print_error("Read semi-sync reply binlog file length too large"); - goto l_end; - } - strncpy(log_file_name, (const char*)packet + REPLY_BINLOG_NAME_OFFSET, log_file_len); - log_file_name[log_file_len] = 0; - - if (trc_level & kTraceDetail) - sql_print_information("%s: Got reply (%s, %lu)", - kWho, log_file_name, (ulong)log_file_pos); - - result = reportReplyBinlog(server_id, log_file_name, log_file_pos); - - l_end: - return function_exit(kWho, result); -} - - -int ReplSemiSyncMaster::resetMaster() -{ - const char *kWho = "ReplSemiSyncMaster::resetMaster"; - int result = 0; - - function_enter(kWho); - - - lock(); - - state_ = getMasterEnabled()? 1 : 0; - - wait_file_name_inited_ = false; - reply_file_name_inited_ = false; - commit_file_name_inited_ = false; - - rpl_semi_sync_master_yes_transactions = 0; - rpl_semi_sync_master_no_transactions = 0; - rpl_semi_sync_master_off_times = 0; - rpl_semi_sync_master_timefunc_fails = 0; - rpl_semi_sync_master_wait_sessions = 0; - rpl_semi_sync_master_wait_pos_backtraverse = 0; - rpl_semi_sync_master_trx_wait_num = 0; - rpl_semi_sync_master_trx_wait_time = 0; - rpl_semi_sync_master_net_wait_num = 0; - rpl_semi_sync_master_net_wait_time = 0; - - unlock(); - - return function_exit(kWho, result); -} - -void ReplSemiSyncMaster::setExportStats() -{ - lock(); - - rpl_semi_sync_master_status = state_; - rpl_semi_sync_master_avg_trx_wait_time= - ((rpl_semi_sync_master_trx_wait_num) ? - (unsigned long)((double)rpl_semi_sync_master_trx_wait_time / - ((double)rpl_semi_sync_master_trx_wait_num)) : 0); - rpl_semi_sync_master_avg_net_wait_time= - ((rpl_semi_sync_master_net_wait_num) ? - (unsigned long)((double)rpl_semi_sync_master_net_wait_time / - ((double)rpl_semi_sync_master_net_wait_num)) : 0); - - unlock(); -} - -/* Get the waiting time given the wait's staring time. - * - * Return: - * >= 0: the waiting time in microsecons(us) - * < 0: error in get time or time back traverse - */ -static int getWaitTime(const struct timespec& start_ts) -{ - unsigned long long start_usecs, end_usecs; - struct timespec end_ts; - - /* Starting time in microseconds(us). */ - start_usecs = timespec_to_usec(&start_ts); - - /* Get the wait time interval. */ - set_timespec(end_ts, 0); - - /* Ending time in microseconds(us). */ - end_usecs = timespec_to_usec(&end_ts); - - if (end_usecs < start_usecs) - return -1; - - return (int)(end_usecs - start_usecs); -} diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h deleted file mode 100644 index c2862476ec8..00000000000 --- a/plugin/semisync/semisync_master.h +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#ifndef SEMISYNC_MASTER_H -#define SEMISYNC_MASTER_H - -#include "semisync.h" - -#ifdef HAVE_PSI_INTERFACE -extern PSI_mutex_key key_ss_mutex_LOCK_binlog_; -extern PSI_cond_key key_ss_cond_COND_binlog_send_; -#endif - -extern PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave; - -struct TranxNode { - char log_name_[FN_REFLEN]; - my_off_t log_pos_; - struct TranxNode *next_; /* the next node in the sorted list */ - struct TranxNode *hash_next_; /* the next node during hash collision */ -}; - -/** - @class TranxNodeAllocator - - This class provides memory allocating and freeing methods for - TranxNode. The main target is performance. - - @section ALLOCATE How to allocate a node - The pointer of the first node after 'last_node' in current_block is - returned. current_block will move to the next free Block when all nodes of - it are in use. A new Block is allocated and is put into the rear of the - Block link table if no Block is free. - - The list starts up empty (ie, there is no allocated Block). - - After some nodes are freed, there probably are some free nodes before - the sequence of the allocated nodes, but we do not reuse it. It is better - to keep the allocated nodes are in the sequence, for it is more efficient - for allocating and freeing TranxNode. - - @section FREENODE How to free nodes - There are two methods for freeing nodes. They are free_all_nodes and - free_nodes_before. - - 'A Block is free' means all of its nodes are free. - @subsection free_nodes_before - As all allocated nodes are in the sequence, 'Before one node' means all - nodes before given node in the same Block and all Blocks before the Block - which containing the given node. As such, all Blocks before the given one - ('node') are free Block and moved into the rear of the Block link table. - The Block containing the given 'node', however, is not. For at least the - given 'node' is still in use. This will waste at most one Block, but it is - more efficient. - */ -#define BLOCK_TRANX_NODES 16 -class TranxNodeAllocator -{ -public: - /** - @param reserved_nodes - The number of reserved TranxNodes. It is used to set 'reserved_blocks' - which can contain at least 'reserved_nodes' number of TranxNodes. When - freeing memory, we will reserve at least reserved_blocks of Blocks not - freed. - */ - TranxNodeAllocator(uint reserved_nodes) : - reserved_blocks(reserved_nodes/BLOCK_TRANX_NODES + - (reserved_nodes%BLOCK_TRANX_NODES > 1 ? 2 : 1)), - first_block(NULL), last_block(NULL), - current_block(NULL), last_node(-1), block_num(0) {} - - ~TranxNodeAllocator() - { - Block *block= first_block; - while (block != NULL) - { - Block *next= block->next; - free_block(block); - block= next; - } - } - - /** - The pointer of the first node after 'last_node' in current_block is - returned. current_block will move to the next free Block when all nodes of - it are in use. A new Block is allocated and is put into the rear of the - Block link table if no Block is free. - - @return Return a TranxNode *, or NULL if an error occurred. - */ - TranxNode *allocate_node() - { - TranxNode *trx_node; - Block *block= current_block; - - if (last_node == BLOCK_TRANX_NODES-1) - { - current_block= current_block->next; - last_node= -1; - } - - if (current_block == NULL && allocate_block()) - { - current_block= block; - if (current_block) - last_node= BLOCK_TRANX_NODES-1; - return NULL; - } - - trx_node= &(current_block->nodes[++last_node]); - trx_node->log_name_[0] = '\0'; - trx_node->log_pos_= 0; - trx_node->next_= 0; - trx_node->hash_next_= 0; - return trx_node; - } - - /** - All nodes are freed. - - @return Return 0, or 1 if an error occurred. - */ - int free_all_nodes() - { - current_block= first_block; - last_node= -1; - free_blocks(); - return 0; - } - - /** - All Blocks before the given 'node' are free Block and moved into the rear - of the Block link table. - - @param node All nodes before 'node' will be freed - - @return Return 0, or 1 if an error occurred. - */ - int free_nodes_before(TranxNode* node) - { - Block *block; - Block *prev_block= NULL; - - block= first_block; - while (block != current_block->next) - { - /* Find the Block containing the given node */ - if (&(block->nodes[0]) <= node && &(block->nodes[BLOCK_TRANX_NODES]) >= node) - { - /* All Blocks before the given node are put into the rear */ - if (first_block != block) - { - last_block->next= first_block; - first_block= block; - last_block= prev_block; - last_block->next= NULL; - free_blocks(); - } - return 0; - } - prev_block= block; - block= block->next; - } - - /* Node does not find should never happen */ - DBUG_ASSERT(0); - return 1; - } - -private: - uint reserved_blocks; - - /** - A sequence memory which contains BLOCK_TRANX_NODES TranxNodes. - - BLOCK_TRANX_NODES The number of TranxNodes which are in a Block. - - next Every Block has a 'next' pointer which points to the next Block. - These linking Blocks constitute a Block link table. - */ - struct Block { - Block *next; - TranxNode nodes[BLOCK_TRANX_NODES]; - }; - - /** - The 'first_block' is the head of the Block link table; - */ - Block *first_block; - /** - The 'last_block' is the rear of the Block link table; - */ - Block *last_block; - - /** - current_block always points the Block in the Block link table in - which the last allocated node is. The Blocks before it are all in use - and the Blocks after it are all free. - */ - Block *current_block; - - /** - It always points to the last node which has been allocated in the - current_block. - */ - int last_node; - - /** - How many Blocks are in the Block link table. - */ - uint block_num; - - /** - Allocate a block and then assign it to current_block. - */ - int allocate_block() - { - Block *block= (Block *)my_malloc(sizeof(Block), MYF(0)); - if (block) - { - block->next= NULL; - - if (first_block == NULL) - first_block= block; - else - last_block->next= block; - - /* New Block is always put into the rear */ - last_block= block; - /* New Block is always the current_block */ - current_block= block; - ++block_num; - return 0; - } - return 1; - } - - /** - Free a given Block. - @param block The Block will be freed. - */ - void free_block(Block *block) - { - my_free(block); - --block_num; - } - - - /** - If there are some free Blocks and the total number of the Blocks in the - Block link table is larger than the 'reserved_blocks', Some free Blocks - will be freed until the total number of the Blocks is equal to the - 'reserved_blocks' or there is only one free Block behind the - 'current_block'. - */ - void free_blocks() - { - if (current_block == NULL || current_block->next == NULL) - return; - - /* One free Block is always kept behind the current block */ - Block *block= current_block->next->next; - while (block_num > reserved_blocks && block != NULL) - { - Block *next= block->next; - free_block(block); - block= next; - } - current_block->next->next= block; - if (block == NULL) - last_block= current_block->next; - } -}; - -/** - This class manages memory for active transaction list. - - We record each active transaction with a TranxNode, each session - can have only one open transaction. Because of EVENT, the total - active transaction nodes can exceed the maximum allowed - connections. -*/ -class ActiveTranx - :public Trace { -private: - - TranxNodeAllocator allocator_; - /* These two record the active transaction list in sort order. */ - TranxNode *trx_front_, *trx_rear_; - - TranxNode **trx_htb_; /* A hash table on active transactions. */ - - int num_entries_; /* maximum hash table entries */ - mysql_mutex_t *lock_; /* mutex lock */ - - inline void assert_lock_owner(); - - inline unsigned int calc_hash(const unsigned char *key,unsigned int length); - unsigned int get_hash_value(const char *log_file_name, my_off_t log_file_pos); - - int compare(const char *log_file_name1, my_off_t log_file_pos1, - const TranxNode *node2) { - return compare(log_file_name1, log_file_pos1, - node2->log_name_, node2->log_pos_); - } - int compare(const TranxNode *node1, - const char *log_file_name2, my_off_t log_file_pos2) { - return compare(node1->log_name_, node1->log_pos_, - log_file_name2, log_file_pos2); - } - int compare(const TranxNode *node1, const TranxNode *node2) { - return compare(node1->log_name_, node1->log_pos_, - node2->log_name_, node2->log_pos_); - } - -public: - ActiveTranx(mysql_mutex_t *lock, unsigned long trace_level); - ~ActiveTranx(); - - /* Insert an active transaction node with the specified position. - * - * Return: - * 0: success; non-zero: error - */ - int insert_tranx_node(const char *log_file_name, my_off_t log_file_pos); - - /* Clear the active transaction nodes until(inclusive) the specified - * position. - * If log_file_name is NULL, everything will be cleared: the sorted - * list and the hash table will be reset to empty. - * - * Return: - * 0: success; non-zero: error - */ - int clear_active_tranx_nodes(const char *log_file_name, - my_off_t log_file_pos); - - /* Given a position, check to see whether the position is an active - * transaction's ending position by probing the hash table. - */ - bool is_tranx_end_pos(const char *log_file_name, my_off_t log_file_pos); - - /* Given two binlog positions, compare which one is bigger based on - * (file_name, file_position). - */ - static int compare(const char *log_file_name1, my_off_t log_file_pos1, - const char *log_file_name2, my_off_t log_file_pos2); - -}; - -/** - The extension class for the master of semi-synchronous replication -*/ -class ReplSemiSyncMaster - :public ReplSemiSyncBase { - private: - ActiveTranx *active_tranxs_; /* active transaction list: the list will - be cleared when semi-sync switches off. */ - - /* True when initObject has been called */ - bool init_done_; - - /* This cond variable is signaled when enough binlog has been sent to slave, - * so that a waiting trx can return the 'ok' to the client for a commit. - */ - mysql_cond_t COND_binlog_send_; - - /* Mutex that protects the following state variables and the active - * transaction list. - * Under no cirumstances we can acquire mysql_bin_log.LOCK_log if we are - * already holding LOCK_binlog_ because it can cause deadlocks. - */ - mysql_mutex_t LOCK_binlog_; - - /* This is set to true when reply_file_name_ contains meaningful data. */ - bool reply_file_name_inited_; - - /* The binlog name up to which we have received replies from any slaves. */ - char reply_file_name_[FN_REFLEN]; - - /* The position in that file up to which we have the reply from any slaves. */ - my_off_t reply_file_pos_; - - /* This is set to true when we know the 'smallest' wait position. */ - bool wait_file_name_inited_; - - /* NULL, or the 'smallest' filename that a transaction is waiting for - * slave replies. - */ - char wait_file_name_[FN_REFLEN]; - - /* The smallest position in that file that a trx is waiting for: the trx - * can proceed and send an 'ok' to the client when the master has got the - * reply from the slave indicating that it already got the binlog events. - */ - my_off_t wait_file_pos_; - - /* This is set to true when we know the 'largest' transaction commit - * position in the binlog file. - * We always maintain the position no matter whether semi-sync is switched - * on switched off. When a transaction wait timeout occurs, semi-sync will - * switch off. Binlog-dump thread can use the three fields to detect when - * slaves catch up on replication so that semi-sync can switch on again. - */ - bool commit_file_name_inited_; - - /* The 'largest' binlog filename that a commit transaction is seeing. */ - char commit_file_name_[FN_REFLEN]; - - /* The 'largest' position in that file that a commit transaction is seeing. */ - my_off_t commit_file_pos_; - - /* All global variables which can be set by parameters. */ - volatile bool master_enabled_; /* semi-sync is enabled on the master */ - unsigned long wait_timeout_; /* timeout period(ms) during tranx wait */ - - bool state_; /* whether semi-sync is switched */ - - void lock(); - void unlock(); - void cond_broadcast(); - int cond_timewait(struct timespec *wait_time); - - /* Is semi-sync replication on? */ - bool is_on() { - return (state_); - } - - void set_master_enabled(bool enabled) { - master_enabled_ = enabled; - } - - /* Switch semi-sync off because of timeout in transaction waiting. */ - int switch_off(); - - /* Switch semi-sync on when slaves catch up. */ - int try_switch_on(int server_id, - const char *log_file_name, my_off_t log_file_pos); - - public: - ReplSemiSyncMaster(); - ~ReplSemiSyncMaster() {} - - void cleanup(); - - bool getMasterEnabled() { - return master_enabled_; - } - void setTraceLevel(unsigned long trace_level) { - trace_level_ = trace_level; - if (active_tranxs_) - active_tranxs_->trace_level_ = trace_level; - } - - /* Set the transaction wait timeout period, in milliseconds. */ - void setWaitTimeout(unsigned long wait_timeout) { - wait_timeout_ = wait_timeout; - } - - /* Initialize this class after MySQL parameters are initialized. this - * function should be called once at bootstrap time. - */ - int initObject(); - - /* Enable the object to enable semi-sync replication inside the master. */ - int enableMaster(); - - /* Enable the object to enable semi-sync replication inside the master. */ - int disableMaster(); - - /* Add a semi-sync replication slave */ - void add_slave(); - - /* Remove a semi-sync replication slave */ - void remove_slave(); - - /* Is the slave servered by the thread requested semi-sync */ - bool is_semi_sync_slave(); - - /* In semi-sync replication, reports up to which binlog position we have - * received replies from the slave indicating that it already get the events. - * - * Input: - * server_id - (IN) master server id number - * log_file_name - (IN) binlog file name - * end_offset - (IN) the offset in the binlog file up to which we have - * the replies from the slave - * - * Return: - * 0: success; non-zero: error - */ - int reportReplyBinlog(uint32 server_id, - const char* log_file_name, - my_off_t end_offset); - - /* Commit a transaction in the final step. This function is called from - * InnoDB before returning from the low commit. If semi-sync is switch on, - * the function will wait to see whether binlog-dump thread get the reply for - * the events of the transaction. Remember that this is not a direct wait, - * instead, it waits to see whether the binlog-dump thread has reached the - * point. If the wait times out, semi-sync status will be switched off and - * all other transaction would not wait either. - * - * Input: (the transaction events' ending binlog position) - * trx_wait_binlog_name - (IN) ending position's file name - * trx_wait_binlog_pos - (IN) ending position's file offset - * - * Return: - * 0: success; non-zero: error - */ - int commitTrx(const char* trx_wait_binlog_name, - my_off_t trx_wait_binlog_pos); - - /* Reserve space in the replication event packet header: - * . slave semi-sync off: 1 byte - (0) - * . slave semi-sync on: 3 byte - (0, 0xef, 0/1} - * - * Input: - * header - (IN) the header buffer - * size - (IN) size of the header buffer - * - * Return: - * size of the bytes reserved for header - */ - int reserveSyncHeader(unsigned char *header, unsigned long size); - - /* Update the sync bit in the packet header to indicate to the slave whether - * the master will wait for the reply of the event. If semi-sync is switched - * off and we detect that the slave is catching up, we switch semi-sync on. - * - * Input: - * packet - (IN) the packet containing the replication event - * log_file_name - (IN) the event ending position's file name - * log_file_pos - (IN) the event ending position's file offset - * server_id - (IN) master server id number - * - * Return: - * 0: success; non-zero: error - */ - int updateSyncHeader(unsigned char *packet, - const char *log_file_name, - my_off_t log_file_pos, - uint32 server_id); - - /* Called when a transaction finished writing binlog events. - * . update the 'largest' transactions' binlog event position - * . insert the ending position in the active transaction list if - * semi-sync is on - * - * Input: (the transaction events' ending binlog position) - * log_file_name - (IN) transaction ending position's file name - * log_file_pos - (IN) transaction ending position's file offset - * - * Return: - * 0: success; non-zero: error - */ - int writeTranxInBinlog(const char* log_file_name, my_off_t log_file_pos); - - /* Read the slave's reply so that we know how much progress the slave makes - * on receive replication events. - * - * Input: - * net - (IN) the connection to master - * server_id - (IN) master server id number - * event_buf - (IN) pointer to the event packet - * - * Return: - * 0: success; non-zero: error - */ - int readSlaveReply(NET *net, uint32 server_id, const char *event_buf); - - /* Export internal statistics for semi-sync replication. */ - void setExportStats(); - - /* 'reset master' command is issued from the user and semi-sync need to - * go off for that. - */ - int resetMaster(); -}; - -enum rpl_semi_sync_master_wait_point_t { - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC, - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT, -}; - -/* System and status variables for the master component */ -extern char rpl_semi_sync_master_enabled; -extern char rpl_semi_sync_master_status; -extern unsigned long rpl_semi_sync_master_wait_point; -extern unsigned long rpl_semi_sync_master_clients; -extern unsigned long rpl_semi_sync_master_timeout; -extern unsigned long rpl_semi_sync_master_trace_level; -extern unsigned long rpl_semi_sync_master_yes_transactions; -extern unsigned long rpl_semi_sync_master_no_transactions; -extern unsigned long rpl_semi_sync_master_off_times; -extern unsigned long rpl_semi_sync_master_wait_timeouts; -extern unsigned long rpl_semi_sync_master_timefunc_fails; -extern unsigned long rpl_semi_sync_master_num_timeouts; -extern unsigned long rpl_semi_sync_master_wait_sessions; -extern unsigned long rpl_semi_sync_master_wait_pos_backtraverse; -extern unsigned long rpl_semi_sync_master_avg_trx_wait_time; -extern unsigned long rpl_semi_sync_master_avg_net_wait_time; -extern unsigned long long rpl_semi_sync_master_net_wait_num; -extern unsigned long long rpl_semi_sync_master_trx_wait_num; -extern unsigned long long rpl_semi_sync_master_net_wait_time; -extern unsigned long long rpl_semi_sync_master_trx_wait_time; - -/* - This indicates whether we should keep waiting if no semi-sync slave - is available. - 0 : stop waiting if detected no avaialable semi-sync slave. - 1 (default) : keep waiting until timeout even no available semi-sync slave. -*/ -extern char rpl_semi_sync_master_wait_no_slave; - -#endif /* SEMISYNC_MASTER_H */ diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc deleted file mode 100644 index 309910312c4..00000000000 --- a/plugin/semisync/semisync_master_plugin.cc +++ /dev/null @@ -1,495 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (c) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include "semisync_master.h" -#include "sql_class.h" // THD - -static ReplSemiSyncMaster repl_semisync; - -C_MODE_START - -int repl_semi_report_binlog_update(Binlog_storage_param *param, - const char *log_file, - my_off_t log_pos, uint32 flags) -{ - int error= 0; - - if (repl_semisync.getMasterEnabled()) - { - /* - Let us store the binlog file name and the position, so that - we know how long to wait for the binlog to the replicated to - the slave in synchronous replication. - */ - error= repl_semisync.writeTranxInBinlog(log_file, - log_pos); - } - - return error; -} - -int repl_semi_request_commit(Trans_param *param) -{ - return 0; -} - -int repl_semi_report_binlog_sync(Binlog_storage_param *param, - const char *log_file, - my_off_t log_pos, uint32 flags) -{ - int error= 0; - if (rpl_semi_sync_master_wait_point == - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_BINLOG_SYNC) - { - error = repl_semisync.commitTrx(log_file, log_pos); - } - - return error; -} - -int repl_semi_report_commit(Trans_param *param) -{ - if (rpl_semi_sync_master_wait_point != - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT) - { - return 0; - } - - bool is_real_trans= param->flags & TRANS_IS_REAL_TRANS; - - if (is_real_trans && param->log_pos) - { - const char *binlog_name= param->log_file; - return repl_semisync.commitTrx(binlog_name, param->log_pos); - } - return 0; -} - -int repl_semi_report_rollback(Trans_param *param) -{ - return repl_semi_report_commit(param); -} - -int repl_semi_binlog_dump_start(Binlog_transmit_param *param, - const char *log_file, - my_off_t log_pos) -{ - bool semi_sync_slave= repl_semisync.is_semi_sync_slave(); - - if (semi_sync_slave) - { - /* One more semi-sync slave */ - repl_semisync.add_slave(); - - /* - Let's assume this semi-sync slave has already received all - binlog events before the filename and position it requests. - */ - repl_semisync.reportReplyBinlog(param->server_id, log_file, log_pos); - } - sql_print_information("Start %s binlog_dump to slave (server_id: %d), pos(%s, %lu)", - semi_sync_slave ? "semi-sync" : "asynchronous", - param->server_id, log_file, (unsigned long)log_pos); - - return 0; -} - -int repl_semi_binlog_dump_end(Binlog_transmit_param *param) -{ - bool semi_sync_slave= repl_semisync.is_semi_sync_slave(); - - sql_print_information("Stop %s binlog_dump to slave (server_id: %d)", - semi_sync_slave ? "semi-sync" : "asynchronous", - param->server_id); - if (semi_sync_slave) - { - /* One less semi-sync slave */ - repl_semisync.remove_slave(); - } - return 0; -} - -int repl_semi_reserve_header(Binlog_transmit_param *param, - unsigned char *header, - unsigned long size, unsigned long *len) -{ - *len += repl_semisync.reserveSyncHeader(header, size); - return 0; -} - -int repl_semi_before_send_event(Binlog_transmit_param *param, - unsigned char *packet, unsigned long len, - const char *log_file, my_off_t log_pos) -{ - return repl_semisync.updateSyncHeader(packet, - log_file, - log_pos, - param->server_id); -} - -int repl_semi_after_send_event(Binlog_transmit_param *param, - const char *event_buf, unsigned long len) -{ - if (repl_semisync.is_semi_sync_slave()) - { - THD *thd= current_thd; - /* - Possible errors in reading slave reply are ignored deliberately - because we do not want dump thread to quit on this. Error - messages are already reported. - */ - (void) repl_semisync.readSlaveReply(&thd->net, - param->server_id, event_buf); - thd->clear_error(); - } - return 0; -} - -int repl_semi_reset_master(Binlog_transmit_param *param) -{ - if (repl_semisync.resetMaster()) - return 1; - return 0; -} - -C_MODE_END - -/* - semisync system variables - */ -static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val); - -static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val); - -static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val); - -static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_master_enabled, - PLUGIN_VAR_OPCMDARG, - "Enable semi-synchronous replication master (disabled by default). ", - NULL, // check - &fix_rpl_semi_sync_master_enabled, // update - 0); - -/* NOTE: must match order of rpl_semi_sync_master_wait_point_t */ -static const char *rpl_semi_sync_master_wait_point_names[] = -{ - "AFTER_SYNC", - "AFTER_COMMIT", - NullS -}; - -static TYPELIB rpl_semi_sync_master_wait_point_typelib = -{ - array_elements(rpl_semi_sync_master_wait_point_names) - 1, - "", - rpl_semi_sync_master_wait_point_names, - NULL -}; - -static MYSQL_SYSVAR_ENUM( - wait_point, - rpl_semi_sync_master_wait_point, - PLUGIN_VAR_RQCMDARG, - "Should transaction wait for semi-sync ack after having synced binlog, " - "or after having committed in storeage engine.", - NULL, // check - NULL, // update - SEMI_SYNC_MASTER_WAIT_POINT_AFTER_STORAGE_COMMIT, - &rpl_semi_sync_master_wait_point_typelib); - -static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout, - PLUGIN_VAR_OPCMDARG, - "The timeout value (in ms) for semi-synchronous replication in the master", - NULL, // check - fix_rpl_semi_sync_master_timeout, // update - 10000, 0, ~0UL, 1); - -static MYSQL_SYSVAR_BOOL(wait_no_slave, rpl_semi_sync_master_wait_no_slave, - PLUGIN_VAR_OPCMDARG, - "Wait until timeout when no semi-synchronous replication slave available (enabled by default). ", - NULL, // check - NULL, // update - 1); - -static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level, - PLUGIN_VAR_OPCMDARG, - "The tracing level for semi-sync replication.", - NULL, // check - &fix_rpl_semi_sync_master_trace_level, // update - 32, 0, ~0UL, 1); - -static SYS_VAR* semi_sync_master_system_vars[]= { - MYSQL_SYSVAR(enabled), - MYSQL_SYSVAR(wait_point), - MYSQL_SYSVAR(timeout), - MYSQL_SYSVAR(wait_no_slave), - MYSQL_SYSVAR(trace_level), - NULL, -}; - - -static void fix_rpl_semi_sync_master_timeout(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val) -{ - *(unsigned long *)ptr= *(unsigned long *)val; - repl_semisync.setWaitTimeout(rpl_semi_sync_master_timeout); - return; -} - -static void fix_rpl_semi_sync_master_trace_level(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val) -{ - *(unsigned long *)ptr= *(unsigned long *)val; - repl_semisync.setTraceLevel(rpl_semi_sync_master_trace_level); - return; -} - -static void fix_rpl_semi_sync_master_enabled(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val) -{ - *(char *)ptr= *(char *)val; - if (rpl_semi_sync_master_enabled) - { - if (repl_semisync.enableMaster() != 0) - rpl_semi_sync_master_enabled = false; - } - else - { - if (repl_semisync.disableMaster() != 0) - rpl_semi_sync_master_enabled = true; - } - - return; -} - -Trans_observer trans_observer = { - sizeof(Trans_observer), // len - - repl_semi_report_commit, // after_commit - repl_semi_report_rollback, // after_rollback -}; - -Binlog_storage_observer storage_observer = { - sizeof(Binlog_storage_observer), // len - - repl_semi_report_binlog_update, // report_update - repl_semi_report_binlog_sync, // after_sync -}; - -Binlog_transmit_observer transmit_observer = { - sizeof(Binlog_transmit_observer), // len - - repl_semi_binlog_dump_start, // start - repl_semi_binlog_dump_end, // stop - repl_semi_reserve_header, // reserve_header - repl_semi_before_send_event, // before_send_event - repl_semi_after_send_event, // after_send_event - repl_semi_reset_master, // reset -}; - - -#define SHOW_FNAME(name) \ - rpl_semi_sync_master_show_##name - -#define DEF_SHOW_FUNC(name, show_type) \ - static int SHOW_FNAME(name)(MYSQL_THD thd, SHOW_VAR *var, char *buff) \ - { \ - repl_semisync.setExportStats(); \ - var->type= show_type; \ - var->value= (char *)&rpl_semi_sync_master_##name; \ - return 0; \ - } - -DEF_SHOW_FUNC(status, SHOW_BOOL) -DEF_SHOW_FUNC(clients, SHOW_LONG) -DEF_SHOW_FUNC(wait_sessions, SHOW_LONG) -DEF_SHOW_FUNC(trx_wait_time, SHOW_LONGLONG) -DEF_SHOW_FUNC(trx_wait_num, SHOW_LONGLONG) -DEF_SHOW_FUNC(net_wait_time, SHOW_LONGLONG) -DEF_SHOW_FUNC(net_wait_num, SHOW_LONGLONG) -DEF_SHOW_FUNC(avg_net_wait_time, SHOW_LONG) -DEF_SHOW_FUNC(avg_trx_wait_time, SHOW_LONG) - - -/* plugin status variables */ -static SHOW_VAR semi_sync_master_status_vars[]= { - {"Rpl_semi_sync_master_status", - (char*) &SHOW_FNAME(status), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_clients", - (char*) &SHOW_FNAME(clients), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_yes_tx", - (char*) &rpl_semi_sync_master_yes_transactions, - SHOW_LONG}, - {"Rpl_semi_sync_master_no_tx", - (char*) &rpl_semi_sync_master_no_transactions, - SHOW_LONG}, - {"Rpl_semi_sync_master_wait_sessions", - (char*) &SHOW_FNAME(wait_sessions), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_no_times", - (char*) &rpl_semi_sync_master_off_times, - SHOW_LONG}, - {"Rpl_semi_sync_master_timefunc_failures", - (char*) &rpl_semi_sync_master_timefunc_fails, - SHOW_LONG}, - {"Rpl_semi_sync_master_wait_pos_backtraverse", - (char*) &rpl_semi_sync_master_wait_pos_backtraverse, - SHOW_LONG}, - {"Rpl_semi_sync_master_tx_wait_time", - (char*) &SHOW_FNAME(trx_wait_time), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_tx_waits", - (char*) &SHOW_FNAME(trx_wait_num), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_tx_avg_wait_time", - (char*) &SHOW_FNAME(avg_trx_wait_time), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_net_wait_time", - (char*) &SHOW_FNAME(net_wait_time), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_net_waits", - (char*) &SHOW_FNAME(net_wait_num), - SHOW_SIMPLE_FUNC}, - {"Rpl_semi_sync_master_net_avg_wait_time", - (char*) &SHOW_FNAME(avg_net_wait_time), - SHOW_SIMPLE_FUNC}, - {NULL, NULL, SHOW_LONG}, -}; - -#ifdef HAVE_PSI_INTERFACE -PSI_mutex_key key_ss_mutex_LOCK_binlog_; - -static PSI_mutex_info all_semisync_mutexes[]= -{ - { &key_ss_mutex_LOCK_binlog_, "LOCK_binlog_", 0} -}; - -PSI_cond_key key_ss_cond_COND_binlog_send_; - -static PSI_cond_info all_semisync_conds[]= -{ - { &key_ss_cond_COND_binlog_send_, "COND_binlog_send_", 0} -}; -#endif /* HAVE_PSI_INTERFACE */ - -PSI_stage_info stage_waiting_for_semi_sync_ack_from_slave= -{ 0, "Waiting for semi-sync ACK from slave", 0}; - -#ifdef HAVE_PSI_INTERFACE -PSI_stage_info *all_semisync_stages[]= -{ - & stage_waiting_for_semi_sync_ack_from_slave -}; - -static void init_semisync_psi_keys(void) -{ - const char* category= "semisync"; - int count; - - count= array_elements(all_semisync_mutexes); - mysql_mutex_register(category, all_semisync_mutexes, count); - - count= array_elements(all_semisync_conds); - mysql_cond_register(category, all_semisync_conds, count); - - count= array_elements(all_semisync_stages); - mysql_stage_register(category, all_semisync_stages, count); -} -#endif /* HAVE_PSI_INTERFACE */ - -static int semi_sync_master_plugin_init(void *p) -{ -#ifdef HAVE_PSI_INTERFACE - init_semisync_psi_keys(); -#endif - - if (repl_semisync.initObject()) - return 1; - if (register_trans_observer(&trans_observer, p)) - return 1; - if (register_binlog_storage_observer(&storage_observer, p)) - return 1; - if (register_binlog_transmit_observer(&transmit_observer, p)) - return 1; - return 0; -} - -static int semi_sync_master_plugin_deinit(void *p) -{ - if (unregister_trans_observer(&trans_observer, p)) - { - sql_print_error("unregister_trans_observer failed"); - return 1; - } - if (unregister_binlog_storage_observer(&storage_observer, p)) - { - sql_print_error("unregister_binlog_storage_observer failed"); - return 1; - } - if (unregister_binlog_transmit_observer(&transmit_observer, p)) - { - sql_print_error("unregister_binlog_transmit_observer failed"); - return 1; - } - repl_semisync.cleanup(); - sql_print_information("unregister_replicator OK"); - return 0; -} - -struct Mysql_replication semi_sync_master_plugin= { - MYSQL_REPLICATION_INTERFACE_VERSION -}; - -/* - Plugin library descriptor -*/ -maria_declare_plugin(semisync_master) -{ - MYSQL_REPLICATION_PLUGIN, - &semi_sync_master_plugin, - "rpl_semi_sync_master", - "He Zhenxing", - "Semi-synchronous replication master", - PLUGIN_LICENSE_GPL, - semi_sync_master_plugin_init, /* Plugin Init */ - semi_sync_master_plugin_deinit, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - semi_sync_master_status_vars, /* status variables */ - semi_sync_master_system_vars, /* system variables */ - "1.0", - MariaDB_PLUGIN_MATURITY_STABLE -} -maria_declare_plugin_end; - diff --git a/plugin/semisync/semisync_slave.cc b/plugin/semisync/semisync_slave.cc deleted file mode 100644 index 5f98472d5d7..00000000000 --- a/plugin/semisync/semisync_slave.cc +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright (c) 2008 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include "semisync_slave.h" - -char rpl_semi_sync_slave_enabled; -char rpl_semi_sync_slave_status= 0; -unsigned long rpl_semi_sync_slave_trace_level; - -int ReplSemiSyncSlave::initObject() -{ - int result= 0; - const char *kWho = "ReplSemiSyncSlave::initObject"; - - if (init_done_) - { - fprintf(stderr, "%s called twice\n", kWho); - return 1; - } - init_done_ = true; - - /* References to the parameter works after set_options(). */ - setSlaveEnabled(rpl_semi_sync_slave_enabled); - setTraceLevel(rpl_semi_sync_slave_trace_level); - - return result; -} - -int ReplSemiSyncSlave::slaveReadSyncHeader(const char *header, - unsigned long total_len, - bool *need_reply, - const char **payload, - unsigned long *payload_len) -{ - const char *kWho = "ReplSemiSyncSlave::slaveReadSyncHeader"; - int read_res = 0; - function_enter(kWho); - - if ((unsigned char)(header[0]) == kPacketMagicNum) - { - *need_reply = (header[1] & kPacketFlagSync); - *payload_len = total_len - 2; - *payload = header + 2; - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: reply - %d", kWho, *need_reply); - } - else - { - sql_print_error("Missing magic number for semi-sync packet, packet " - "len: %lu", total_len); - read_res = -1; - } - - return function_exit(kWho, read_res); -} - -int ReplSemiSyncSlave::slaveStart(Binlog_relay_IO_param *param) -{ - bool semi_sync= getSlaveEnabled(); - - sql_print_information("Slave I/O thread: Start %s replication to\ - master '%s@%s:%d' in log '%s' at position %lu", - semi_sync ? "semi-sync" : "asynchronous", - param->user, param->host, param->port, - param->master_log_name[0] ? param->master_log_name : "FIRST", - (unsigned long)param->master_log_pos); - - if (semi_sync && !rpl_semi_sync_slave_status) - rpl_semi_sync_slave_status= 1; - return 0; -} - -int ReplSemiSyncSlave::slaveStop(Binlog_relay_IO_param *param) -{ - if (rpl_semi_sync_slave_status) - rpl_semi_sync_slave_status= 0; - if (mysql_reply) - mysql_close(mysql_reply); - mysql_reply= 0; - return 0; -} - -int ReplSemiSyncSlave::slaveReply(MYSQL *mysql, - const char *binlog_filename, - my_off_t binlog_filepos) -{ - const char *kWho = "ReplSemiSyncSlave::slaveReply"; - NET *net= &mysql->net; - uchar reply_buffer[REPLY_MAGIC_NUM_LEN - + REPLY_BINLOG_POS_LEN - + REPLY_BINLOG_NAME_LEN]; - int reply_res, name_len = strlen(binlog_filename); - - function_enter(kWho); - - /* Prepare the buffer of the reply. */ - reply_buffer[REPLY_MAGIC_NUM_OFFSET] = kPacketMagicNum; - int8store(reply_buffer + REPLY_BINLOG_POS_OFFSET, binlog_filepos); - memcpy(reply_buffer + REPLY_BINLOG_NAME_OFFSET, - binlog_filename, - name_len + 1 /* including trailing '\0' */); - - if (trace_level_ & kTraceDetail) - sql_print_information("%s: reply (%s, %lu)", kWho, - binlog_filename, (ulong)binlog_filepos); - - net_clear(net, 0); - /* Send the reply. */ - reply_res = my_net_write(net, reply_buffer, - name_len + REPLY_BINLOG_NAME_OFFSET); - if (!reply_res) - { - reply_res = net_flush(net); - if (reply_res) - sql_print_error("Semi-sync slave net_flush() reply failed"); - } - else - { - sql_print_error("Semi-sync slave send reply failed: %s (%d)", - net->last_error, net->last_errno); - } - - return function_exit(kWho, reply_res); -} diff --git a/plugin/semisync/semisync_slave.h b/plugin/semisync/semisync_slave.h deleted file mode 100644 index 1bf8cf31972..00000000000 --- a/plugin/semisync/semisync_slave.h +++ /dev/null @@ -1,97 +0,0 @@ -/* Copyright (c) 2006 MySQL AB, 2009 Sun Microsystems, Inc. - Use is subject to license terms. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#ifndef SEMISYNC_SLAVE_H -#define SEMISYNC_SLAVE_H - -#include "semisync.h" - -/** - The extension class for the slave of semi-synchronous replication -*/ -class ReplSemiSyncSlave - :public ReplSemiSyncBase { -public: - ReplSemiSyncSlave() - :slave_enabled_(false) - {} - ~ReplSemiSyncSlave() {} - - void setTraceLevel(unsigned long trace_level) { - trace_level_ = trace_level; - } - - /* Initialize this class after MySQL parameters are initialized. this - * function should be called once at bootstrap time. - */ - int initObject(); - - bool getSlaveEnabled() { - return slave_enabled_; - } - void setSlaveEnabled(bool enabled) { - slave_enabled_ = enabled; - } - - /* A slave reads the semi-sync packet header and separate the metadata - * from the payload data. - * - * Input: - * header - (IN) packet header pointer - * total_len - (IN) total packet length: metadata + payload - * need_reply - (IN) whether the master is waiting for the reply - * payload - (IN) payload: the replication event - * payload_len - (IN) payload length - * - * Return: - * 0: success; non-zero: error - */ - int slaveReadSyncHeader(const char *header, unsigned long total_len, bool *need_reply, - const char **payload, unsigned long *payload_len); - - /* A slave replies to the master indicating its replication process. It - * indicates that the slave has received all events before the specified - * binlog position. - * - * Input: - * mysql - (IN) the mysql network connection - * binlog_filename - (IN) the reply point's binlog file name - * binlog_filepos - (IN) the reply point's binlog file offset - * - * Return: - * 0: success; non-zero: error - */ - int slaveReply(MYSQL *mysql, const char *binlog_filename, - my_off_t binlog_filepos); - - int slaveStart(Binlog_relay_IO_param *param); - int slaveStop(Binlog_relay_IO_param *param); - -private: - /* True when initObject has been called */ - bool init_done_; - bool slave_enabled_; /* semi-sycn is enabled on the slave */ - MYSQL *mysql_reply; /* connection to send reply */ -}; - - -/* System and status variables for the slave component */ -extern char rpl_semi_sync_slave_enabled; -extern unsigned long rpl_semi_sync_slave_trace_level; -extern char rpl_semi_sync_slave_status; - -#endif /* SEMISYNC_SLAVE_H */ diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc deleted file mode 100644 index 3a6c7625d93..00000000000 --- a/plugin/semisync/semisync_slave_plugin.cc +++ /dev/null @@ -1,233 +0,0 @@ -/* Copyright (C) 2007 Google Inc. - Copyright (C) 2008 MySQL AB - Use is subject to license terms - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - -#include "semisync_slave.h" -#include <mysql.h> - -static ReplSemiSyncSlave repl_semisync; - -/* - indicate whether or not the slave should send a reply to the master. - - This is set to true in repl_semi_slave_read_event if the current - event read is the last event of a transaction. And the value is - checked in repl_semi_slave_queue_event. -*/ -bool semi_sync_need_reply= false; - -C_MODE_START - -int repl_semi_reset_slave(Binlog_relay_IO_param *param) -{ - // TODO: reset semi-sync slave status here - return 0; -} - -int repl_semi_slave_request_dump(Binlog_relay_IO_param *param, - uint32 flags) -{ - MYSQL *mysql= param->mysql; - MYSQL_RES *res= 0; - MYSQL_ROW row; - const char *query; - - if (!repl_semisync.getSlaveEnabled()) - return 0; - - /* Check if master server has semi-sync plugin installed */ - query= "SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'"; - if (mysql_real_query(mysql, query, strlen(query)) || - !(res= mysql_store_result(mysql))) - { - sql_print_error("Execution failed on master: %s", query); - return 1; - } - - row= mysql_fetch_row(res); - if (!row) - { - /* Master does not support semi-sync */ - sql_print_warning("Master server does not support semi-sync, " - "fallback to asynchronous replication"); - rpl_semi_sync_slave_status= 0; - mysql_free_result(res); - return 0; - } - mysql_free_result(res); - - /* - Tell master dump thread that we want to do semi-sync - replication - */ - query= "SET @rpl_semi_sync_slave= 1"; - if (mysql_real_query(mysql, query, strlen(query))) - { - sql_print_error("Set 'rpl_semi_sync_slave=1' on master failed"); - return 1; - } - mysql_free_result(mysql_store_result(mysql)); - rpl_semi_sync_slave_status= 1; - return 0; -} - -int repl_semi_slave_read_event(Binlog_relay_IO_param *param, - const char *packet, unsigned long len, - const char **event_buf, unsigned long *event_len) -{ - if (rpl_semi_sync_slave_status) - return repl_semisync.slaveReadSyncHeader(packet, len, - &semi_sync_need_reply, - event_buf, event_len); - *event_buf= packet; - *event_len= len; - return 0; -} - -int repl_semi_slave_queue_event(Binlog_relay_IO_param *param, - const char *event_buf, - unsigned long event_len, - uint32 flags) -{ - if (rpl_semi_sync_slave_status && semi_sync_need_reply) - { - /* - We deliberately ignore the error in slaveReply, such error - should not cause the slave IO thread to stop, and the error - messages are already reported. - */ - (void) repl_semisync.slaveReply(param->mysql, - param->master_log_name, - param->master_log_pos); - } - return 0; -} - -int repl_semi_slave_io_start(Binlog_relay_IO_param *param) -{ - return repl_semisync.slaveStart(param); -} - -int repl_semi_slave_io_end(Binlog_relay_IO_param *param) -{ - return repl_semisync.slaveStop(param); -} - -C_MODE_END - -static void fix_rpl_semi_sync_slave_enabled(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val) -{ - *(char *)ptr= *(char *)val; - repl_semisync.setSlaveEnabled(rpl_semi_sync_slave_enabled != 0); - return; -} - -static void fix_rpl_semi_sync_trace_level(MYSQL_THD thd, - SYS_VAR *var, - void *ptr, - const void *val) -{ - *(unsigned long *)ptr= *(unsigned long *)val; - repl_semisync.setTraceLevel(rpl_semi_sync_slave_trace_level); - return; -} - -/* plugin system variables */ -static MYSQL_SYSVAR_BOOL(enabled, rpl_semi_sync_slave_enabled, - PLUGIN_VAR_OPCMDARG, - "Enable semi-synchronous replication slave (disabled by default). ", - NULL, // check - &fix_rpl_semi_sync_slave_enabled, // update - 0); - -static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level, - PLUGIN_VAR_OPCMDARG, - "The tracing level for semi-sync replication.", - NULL, // check - &fix_rpl_semi_sync_trace_level, // update - 32, 0, ~0UL, 1); - -static SYS_VAR* semi_sync_slave_system_vars[]= { - MYSQL_SYSVAR(enabled), - MYSQL_SYSVAR(trace_level), - NULL, -}; - - -/* plugin status variables */ -static SHOW_VAR semi_sync_slave_status_vars[]= { - {"Rpl_semi_sync_slave_status", - (char*) &rpl_semi_sync_slave_status, SHOW_BOOL}, - {NULL, NULL, SHOW_BOOL}, -}; - -Binlog_relay_IO_observer relay_io_observer = { - sizeof(Binlog_relay_IO_observer), // len - - repl_semi_slave_io_start, // start - repl_semi_slave_io_end, // stop - repl_semi_slave_request_dump, // request_transmit - repl_semi_slave_read_event, // after_read_event - repl_semi_slave_queue_event, // after_queue_event - repl_semi_reset_slave, // reset -}; - -static int semi_sync_slave_plugin_init(void *p) -{ - if (repl_semisync.initObject()) - return 1; - if (register_binlog_relay_io_observer(&relay_io_observer, p)) - return 1; - return 0; -} - -static int semi_sync_slave_plugin_deinit(void *p) -{ - if (unregister_binlog_relay_io_observer(&relay_io_observer, p)) - return 1; - return 0; -} - - -struct Mysql_replication semi_sync_slave_plugin= { - MYSQL_REPLICATION_INTERFACE_VERSION -}; - -/* - Plugin library descriptor -*/ -maria_declare_plugin(semisync_slave) -{ - MYSQL_REPLICATION_PLUGIN, - &semi_sync_slave_plugin, - "rpl_semi_sync_slave", - "He Zhenxing", - "Semi-synchronous replication slave", - PLUGIN_LICENSE_GPL, - semi_sync_slave_plugin_init, /* Plugin Init */ - semi_sync_slave_plugin_deinit, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - semi_sync_slave_status_vars, /* status variables */ - semi_sync_slave_system_vars, /* system variables */ - "1.0", - MariaDB_PLUGIN_MATURITY_STABLE -} -maria_declare_plugin_end; - diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 612e9e91515..72d5a91d59d 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -20,10 +20,6 @@ #define _my_thread_var loc_thread_var #include <my_config.h> -#include <stdio.h> -#include <time.h> -#include <string.h> -#include <fcntl.h> #include <assert.h> #ifndef _WIN32 @@ -76,6 +72,7 @@ static void closelog() {} */ #if !defined(MYSQL_DYNAMIC_PLUGIN) && !defined(MARIADB_ONLY) +#include <typelib.h> #define MARIADB_ONLY #endif /*MYSQL_PLUGIN_DYNAMIC*/ @@ -83,11 +80,12 @@ static void closelog() {} #define MYSQL_SERVICE_LOGGER_INCLUDED #endif /*MARIADB_ONLY*/ +#include <my_global.h> #include <my_base.h> -//#include <my_dir.h> #include <typelib.h> #include <mysql/plugin.h> #include <mysql/plugin_audit.h> +#include <string.h> #ifndef RTLD_DEFAULT #define RTLD_DEFAULT NULL #endif @@ -441,6 +439,7 @@ static const char *syslog_facility_names[]= "LOG_LOCAL4", "LOG_LOCAL5", "LOG_LOCAL6", "LOG_LOCAL7", 0 }; +#ifndef _WIN32 static unsigned int syslog_facility_codes[]= { LOG_USER, LOG_MAIL, LOG_DAEMON, LOG_AUTH, @@ -455,6 +454,7 @@ static unsigned int syslog_facility_codes[]= LOG_LOCAL0, LOG_LOCAL1, LOG_LOCAL2, LOG_LOCAL3, LOG_LOCAL4, LOG_LOCAL5, LOG_LOCAL6, LOG_LOCAL7, }; +#endif static TYPELIB syslog_facility_typelib= { array_elements(syslog_facility_names) - 1, "syslog_facility_typelib", @@ -472,11 +472,13 @@ static const char *syslog_priority_names[]= 0 }; +#ifndef _WIN32 static unsigned int syslog_priority_codes[]= { LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_NOTICE, LOG_INFO, LOG_DEBUG, }; +#endif static TYPELIB syslog_priority_typelib= { @@ -1106,7 +1108,7 @@ static void setup_connection_connect(struct connection_info *cn, cn->log_always= 0; cn->thread_id= event->thread_id; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); get_str_n(cn->user, &cn->user_length, sizeof(cn->db), event->user, event->user_length); get_str_n(cn->host, &cn->host_length, sizeof(cn->host), @@ -1194,7 +1196,7 @@ static void setup_connection_table(struct connection_info *cn, cn->log_always= 0; cn->query_length= 0; get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); get_str_n(cn->user, &cn->user_length, sizeof(cn->db), event->user, SAFE_STRLEN(event->user)); get_str_n(cn->host, &cn->host_length, sizeof(cn->host), @@ -1342,7 +1344,7 @@ static int log_connection_event(const struct mysql_event_connection *event, event->ip, event->ip_length, event->thread_id, 0, type); csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, - ",%.*s,,%d", event->database_length, event->database, event->status); + ",%.*s,,%d", event->database.length, event->database.str, event->status); message[csize]= '\n'; return write_log(message, csize + 1); } @@ -1765,8 +1767,8 @@ static int log_table(const struct connection_info *cn, event->ip, (unsigned int)SAFE_STRLEN(event->ip), event->thread_id, cn->query_id, type); csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, - ",%.*s,%.*s,",event->database_length, event->database, - event->table_length, event->table); + ",%.*s,%.*s,",event->database.length, event->database.str, + event->table.length, event->table.str); message[csize]= '\n'; return write_log(message, csize + 1); } @@ -1787,10 +1789,10 @@ static int log_rename(const struct connection_info *cn, event->ip, (unsigned int)SAFE_STRLEN(event->ip), event->thread_id, cn->query_id, "RENAME"); csize+= my_snprintf(message+csize, sizeof(message) - 1 - csize, - ",%.*s,%.*s|%.*s.%.*s,",event->database_length, event->database, - event->table_length, event->table, - event->new_database_length, event->new_database, - event->new_table_length, event->new_table); + ",%.*s,%.*s|%.*s.%.*s,",event->database.length, event->database.str, + event->table.length, event->table.str, + event->new_database.length, event->new_database.str, + event->new_table.length, event->new_table.str); message[csize]= '\n'; return write_log(message, csize + 1); } @@ -1855,7 +1857,7 @@ static void update_connection_info(struct connection_info *cn, /* Change DB */ if (mysql_57_started) get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); else get_str_n(cn->db, &cn->db_length, sizeof(cn->db), event->general_query, event->general_query_length); @@ -1881,9 +1883,9 @@ static void update_connection_info(struct connection_info *cn, if (ci_needs_setup(cn)) setup_connection_query(cn, event); - if (mode == 0 && cn->db_length == 0 && event->database_length > 0) + if (mode == 0 && cn->db_length == 0 && event->database.length > 0) get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); if (event->general_error_code == 0) { @@ -1898,7 +1900,7 @@ static void update_connection_info(struct connection_info *cn, event->general_query + 4, event->general_query_length - 4); else get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); } } update_general_user(cn, event); @@ -1939,9 +1941,9 @@ static void update_connection_info(struct connection_info *cn, event->ip, SAFE_STRLEN(event->ip)); } - if (cn->db_length == 0 && event->database_length != 0) + if (cn->db_length == 0 && event->database.length != 0) get_str_n(cn->db, &cn->db_length, sizeof(cn->db), - event->database, event->database_length); + event->database.str, event->database.length); if (mode == 0) cn->query_id= event->query_id; @@ -2129,6 +2131,7 @@ struct mysql_event_general_v8 static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8) { +#ifdef __linux__ #ifdef DBUG_OFF #ifdef __x86_64__ static const int cmd_off= 4200; @@ -2150,7 +2153,7 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8) static const int db_len_off= 68; #endif /*x86_64*/ #endif /*DBUG_OFF*/ - +#endif /* __linux__ */ struct mysql_event_general event; if (ev_v8->event_class != MYSQL_AUDIT_GENERAL_CLASS) @@ -2168,8 +2171,8 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8) event.general_charset= ev_v8->general_charset; event.general_time= ev_v8->general_time; event.general_rows= ev_v8->general_rows; - event.database= 0; - event.database_length= 0; + event.database.str= 0; + event.database.length= 0; if (event.general_query_length > 0) { @@ -2177,8 +2180,8 @@ static void auditing_v8(MYSQL_THD thd, struct mysql_event_general_v8 *ev_v8) event.general_command= "Query"; event.general_command_length= 5; #ifdef __linux__ - event.database= *(char **) (((char *) thd) + db_off); - event.database_length= *(size_t *) (((char *) thd) + db_len_off); + event.database.str= *(char **) (((char *) thd) + db_off); + event.database.length= *(size_t *) (((char *) thd) + db_len_off); #endif /*__linux*/ } #ifdef __linux__ diff --git a/plugin/server_audit/test_audit_v4.c b/plugin/server_audit/test_audit_v4.c index 85d45e35808..8cb24bc693b 100644 --- a/plugin/server_audit/test_audit_v4.c +++ b/plugin/server_audit/test_audit_v4.c @@ -1,5 +1,6 @@ #define PLUGIN_CONTEXT +/* Can't use <my_global.h> as this includes plugin.h */ #include <stdio.h> typedef void *MYSQL_THD; diff --git a/plugin/simple_password_check/simple_password_check.c b/plugin/simple_password_check/simple_password_check.c index 977a7487b78..5a76c3d3005 100644 --- a/plugin/simple_password_check/simple_password_check.c +++ b/plugin/simple_password_check/simple_password_check.c @@ -14,16 +14,16 @@ along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include <my_sys.h> #include <mysqld_error.h> +#include <my_attribute.h> #include <mysql/plugin_password_validation.h> #include <ctype.h> #include <string.h> -#include <my_attribute.h> static unsigned min_length, min_digits, min_letters, min_others; -static int validate(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) +static int validate(MYSQL_CONST_LEX_STRING *username, + MYSQL_CONST_LEX_STRING *password) { unsigned digits=0 , uppers=0 , lowers=0, others=0, length= (unsigned)password->length; const char *ptr= password->str, *end= ptr + length; @@ -52,18 +52,18 @@ static int validate(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) } static void fix_min_length(MYSQL_THD thd __attribute__((unused)), - struct st_mysql_sys_var *var __attribute__((unused)), + struct st_mysql_sys_var *var + __attribute__((unused)), void *var_ptr, const void *save) { - uint new_min_length; + unsigned int new_min_length; *((unsigned int *)var_ptr)= *((unsigned int *)save); new_min_length= min_digits + 2 * min_letters + min_others; if (min_length < new_min_length) { my_printf_error(ER_TRUNCATED_WRONG_VALUE, "Adjusted the value of simple_password_check_minimal_length " - "from %u to %u", ME_JUST_WARNING, - min_length, new_min_length); + "from %u to %u", ME_WARNING, min_length, new_min_length); min_length= new_min_length; } } diff --git a/plugin/user_variables/user_variables.cc b/plugin/user_variables/user_variables.cc index 35378e0c8c8..80bf58612b5 100644 --- a/plugin/user_variables/user_variables.cc +++ b/plugin/user_variables/user_variables.cc @@ -14,6 +14,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ #define MYSQL_SERVER +#include <my_global.h> #include <sql_class.h> #include <table.h> #include <sql_show.h> diff --git a/plugin/userstat/index_stats.cc b/plugin/userstat/index_stats.cc index 87e6da63e38..0528507c50e 100644 --- a/plugin/userstat/index_stats.cc +++ b/plugin/userstat/index_stats.cc @@ -17,27 +17,26 @@ static int index_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) INDEX_STATS *index_stats = (INDEX_STATS*) my_hash_element(&global_index_stats, i); TABLE_LIST tmp_table; - char *index_name; - size_t schema_name_length, table_name_length, index_name_length; + const char *index_name; + size_t index_name_length; bzero((char*) &tmp_table,sizeof(tmp_table)); - tmp_table.db= index_stats->index; - tmp_table.table_name= strend(index_stats->index)+1; + tmp_table.db.str= index_stats->index; + tmp_table.db.length= strlen(index_stats->index); + tmp_table.table_name.str= index_stats->index + tmp_table.db.length + 1; + tmp_table.table_name.length= strlen(tmp_table.table_name.str); tmp_table.grant.privilege= 0; - if (check_access(thd, SELECT_ACL, tmp_table.db, + if (check_access(thd, SELECT_ACL, tmp_table.db.str, &tmp_table.grant.privilege, NULL, 0, 1) || check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) continue; - index_name= strend(tmp_table.table_name)+1; - schema_name_length= (tmp_table.table_name - index_stats->index) -1; - table_name_length= (index_name - tmp_table.table_name)-1; - index_name_length= (index_stats->index_name_length - schema_name_length - - table_name_length - 3); + index_name= tmp_table.table_name.str + tmp_table.table_name.length + 1; + index_name_length= (index_stats->index_name_length - tmp_table.db.length - + tmp_table.table_name.length - 3); - table->field[0]->store(tmp_table.db, (uint)schema_name_length, - system_charset_info); - table->field[1]->store(tmp_table.table_name, (uint) table_name_length, + table->field[0]->store(tmp_table.db.str, tmp_table.db.length, system_charset_info); + table->field[1]->store(tmp_table.table_name.str, tmp_table.table_name.length, system_charset_info); table->field[2]->store(index_name, (uint) index_name_length, system_charset_info); table->field[3]->store((longlong)index_stats->rows_read, TRUE); diff --git a/plugin/userstat/table_stats.cc b/plugin/userstat/table_stats.cc index 7b522a388d7..3119e516e06 100644 --- a/plugin/userstat/table_stats.cc +++ b/plugin/userstat/table_stats.cc @@ -26,10 +26,12 @@ static int table_stats_fill(THD *thd, TABLE_LIST *tables, COND *cond) table_name_length= strlen(table_stats->table + schema_length + 1); bzero((char*) &tmp_table,sizeof(tmp_table)); - tmp_table.db= table_stats->table; - tmp_table.table_name= end_of_schema+1; + tmp_table.db.str= table_stats->table; + tmp_table.db.length= schema_length; + tmp_table.table_name.str= end_of_schema+1; + tmp_table.table_name.length= table_name_length; tmp_table.grant.privilege= 0; - if (check_access(thd, SELECT_ACL, tmp_table.db, + if (check_access(thd, SELECT_ACL, tmp_table.db.str, &tmp_table.grant.privilege, NULL, 0, 1) || check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1)) diff --git a/plugin/userstat/userstat.cc b/plugin/userstat/userstat.cc index 96d926ac908..2084453fbca 100644 --- a/plugin/userstat/userstat.cc +++ b/plugin/userstat/userstat.cc @@ -1,4 +1,4 @@ -#include <my_config.h> +#include <my_global.h> #include <mysql/plugin.h> #include <mysql_version.h> #include "table.h" diff --git a/plugin/semisync/CMakeLists.txt b/plugin/versioning/CMakeLists.txt index 88998fb3093..fc741121e10 100644 --- a/plugin/semisync/CMakeLists.txt +++ b/plugin/versioning/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2016, MariaDB corporation. All rights reserved. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -13,16 +13,5 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -SET(SEMISYNC_MASTER_SOURCES - semisync.cc semisync_master.cc semisync_master_plugin.cc - semisync.h semisync_master.h) - -MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES} - RECOMPILE_FOR_EMBEDDED) - -SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc - semisync_slave_plugin.cc semisync.h semisync_slave.h ) - -MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES} - RECOMPILE_FOR_EMBEDDED) - +MYSQL_ADD_PLUGIN(test_versioning versioning.cc RECOMPILE_FOR_EMBEDDED + MODULE_ONLY COMPONENT Test) diff --git a/plugin/versioning/versioning.cc b/plugin/versioning/versioning.cc new file mode 100644 index 00000000000..7e3c29e1494 --- /dev/null +++ b/plugin/versioning/versioning.cc @@ -0,0 +1,204 @@ +/* Copyright (c) 2016, MariaDB corporation. All rights + reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#define MYSQL_SERVER 1 +#include <my_global.h> +#include <mysql_version.h> +#include <mysqld.h> +#include <mysql/plugin.h> +#include "sql_plugin.h" // st_plugin_int +#include "sql_class.h" +#include "item.h" +#include "vers_utils.h" + +/* System Versioning: TRT_TRX_ID(), TRT_COMMIT_ID(), TRT_BEGIN_TS(), TRT_COMMIT_TS(), TRT_ISO_LEVEL() */ +template <TR_table::field_id_t TRT_FIELD> +class Create_func_trt : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list); + + static Create_func_trt<TRT_FIELD> s_singleton; + +protected: + Create_func_trt<TRT_FIELD>() {} + virtual ~Create_func_trt<TRT_FIELD>() {} +}; + +template<TR_table::field_id_t TRT_FIELD> +Create_func_trt<TRT_FIELD> Create_func_trt<TRT_FIELD>::s_singleton; + +template <TR_table::field_id_t TRT_FIELD> +Item* +Create_func_trt<TRT_FIELD>::create_native(THD *thd, LEX_CSTRING *name, + List<Item> *item_list) +{ + Item *func= NULL; + int arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + + switch (arg_count) { + case 1: + { + Item *param_1= item_list->pop(); + switch (TRT_FIELD) + { + case TR_table::FLD_BEGIN_TS: + case TR_table::FLD_COMMIT_TS: + func= new (thd->mem_root) Item_func_trt_ts(thd, param_1, TRT_FIELD); + break; + case TR_table::FLD_TRX_ID: + case TR_table::FLD_COMMIT_ID: + case TR_table::FLD_ISO_LEVEL: + func= new (thd->mem_root) Item_func_trt_id(thd, param_1, TRT_FIELD); + break; + default: + DBUG_ASSERT(0); + } + break; + } + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + switch (TRT_FIELD) + { + case TR_table::FLD_TRX_ID: + case TR_table::FLD_COMMIT_ID: + func= new (thd->mem_root) Item_func_trt_id(thd, param_1, param_2, TRT_FIELD); + break; + default: + goto error; + } + break; + } + error: + default: + { + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + break; + } + } + + return func; +}; + +template <class Item_func_trt_trx_seesX> +class Create_func_trt_trx_sees : public Create_native_func +{ +public: + virtual Item *create_native(THD *thd, LEX_CSTRING *name, List<Item> *item_list) + { + Item *func= NULL; + int arg_count= 0; + + if (item_list != NULL) + arg_count= item_list->elements; + + switch (arg_count) { + case 2: + { + Item *param_1= item_list->pop(); + Item *param_2= item_list->pop(); + func= new (thd->mem_root) Item_func_trt_trx_seesX(thd, param_1, param_2); + break; + } + default: + my_error(ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT, MYF(0), name->str); + break; + } + + return func; + } + + static Create_func_trt_trx_sees<Item_func_trt_trx_seesX> s_singleton; + +protected: + Create_func_trt_trx_sees<Item_func_trt_trx_seesX>() {} + virtual ~Create_func_trt_trx_sees<Item_func_trt_trx_seesX>() {} +}; + +template<class X> +Create_func_trt_trx_sees<X> Create_func_trt_trx_sees<X>::s_singleton; + +#define BUILDER(F) & F::s_singleton + +static Native_func_registry func_array[] = +{ + { { C_STRING_WITH_LEN("TRT_BEGIN_TS") }, BUILDER(Create_func_trt<TR_table::FLD_BEGIN_TS>)}, + { { C_STRING_WITH_LEN("TRT_COMMIT_ID") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_ID>)}, + { { C_STRING_WITH_LEN("TRT_COMMIT_TS") }, BUILDER(Create_func_trt<TR_table::FLD_COMMIT_TS>)}, + { { C_STRING_WITH_LEN("TRT_ISO_LEVEL") }, BUILDER(Create_func_trt<TR_table::FLD_ISO_LEVEL>)}, + { { C_STRING_WITH_LEN("TRT_TRX_ID") }, BUILDER(Create_func_trt<TR_table::FLD_TRX_ID>)}, + { { C_STRING_WITH_LEN("TRT_TRX_SEES") }, BUILDER(Create_func_trt_trx_sees<Item_func_trt_trx_sees>)}, + { { C_STRING_WITH_LEN("TRT_TRX_SEES_EQ") }, BUILDER(Create_func_trt_trx_sees<Item_func_trt_trx_sees_eq>)}, + { {0, 0}, NULL} +}; + + +/* + Disable __attribute__() on non-gcc compilers. +*/ +#if !defined(__attribute__) && !defined(__GNUC__) +#define __attribute__(A) +#endif + +static int versioning_plugin_init(void *p __attribute__ ((unused))) +{ + DBUG_ENTER("versioning_plugin_init"); + // No need in locking since we so far single-threaded + int res= item_create_append(func_array); + if (res) + { + my_message(ER_PLUGIN_IS_NOT_LOADED, "Can't append function array" , MYF(0)); + DBUG_RETURN(res); + } + + DBUG_RETURN(0); +} + +static int versioning_plugin_deinit(void *p __attribute__ ((unused))) +{ + DBUG_ENTER("versioning_plugin_deinit"); + DBUG_RETURN(0); +} + +struct st_mysql_daemon versioning_plugin= +{ MYSQL_REPLICATION_INTERFACE_VERSION }; + +/* + Plugin library descriptor +*/ + +maria_declare_plugin(versioning) +{ + MYSQL_REPLICATION_PLUGIN, // initialized after MYSQL_STORAGE_ENGINE_PLUGIN + &versioning_plugin, + "test_versioning", + "MariaDB Corp", + "System Vesioning testing features", + PLUGIN_LICENSE_GPL, + versioning_plugin_init, /* Plugin Init */ + versioning_plugin_deinit, /* Plugin Deinit */ + 0x0100 /* 1.0 */, + NULL, /* status variables */ + NULL, /* system variables */ + "1.0", /* string version */ + MariaDB_PLUGIN_MATURITY_EXPERIMENTAL +} +maria_declare_plugin_end; diff --git a/plugin/win_auth_client/common.cc b/plugin/win_auth_client/common.cc index 30a8e0b3b13..007a511171a 100644 --- a/plugin/win_auth_client/common.cc +++ b/plugin/win_auth_client/common.cc @@ -69,7 +69,7 @@ Connection::Connection(MYSQL_PLUGIN_VIO *vio): m_vio(vio), m_error(0) int Connection::write(const Blob &blob) { - m_error= m_vio->write_packet(m_vio, blob.ptr(), blob.len()); + m_error= m_vio->write_packet(m_vio, blob.ptr(), (int)blob.len()); #ifndef DBUG_OFF if (m_error) @@ -375,7 +375,7 @@ char* wchar_to_utf8(const wchar_t *string, size_t *len) /* A conversion from utf8 to wchar_t will never take more than 3 bytes per - character, so a buffer of length 3 * str_len schould be sufficient. + character, so a buffer of length 3 * str_len should be sufficient. We check that assumption with an assertion later. */ @@ -392,8 +392,8 @@ char* wchar_to_utf8(const wchar_t *string, size_t *len) int res= WideCharToMultiByte(CP_UTF8, // convert to UTF-8 0, // conversion flags string, // input buffer - str_len, // its length - buf, buf_len, // output buffer and its size + (int)str_len, // its length + buf, (int)buf_len, // output buffer and its size NULL, NULL); // default character (not used) if (res) @@ -460,8 +460,8 @@ wchar_t* utf8_to_wchar(const char *string, size_t *len) res= MultiByteToWideChar(CP_UTF8, // convert from UTF-8 0, // conversion flags string, // input buffer - buf_len, // its size - buf, buf_len); // output buffer and its size + (int)buf_len, // its size + buf, (int)buf_len); // output buffer and its size if (res) { buf[res]= '\0'; @@ -504,7 +504,7 @@ const char* get_last_error_message(Error_message_buf buf) buf[0]= '\0'; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)buf, sizeof(buf), NULL ); + (LPTSTR)buf, ERRMSG_BUFSIZE , NULL ); return buf; } diff --git a/plugin/win_auth_client/common.h b/plugin/win_auth_client/common.h index 415294b1ed9..cd7dc8c2e66 100644 --- a/plugin/win_auth_client/common.h +++ b/plugin/win_auth_client/common.h @@ -77,8 +77,8 @@ void error_log_print(const char *fmt, ...) error_log_vprint(Level, fmt, args); va_end(args); } - -typedef char Error_message_buf[1024]; +#define ERRMSG_BUFSIZE 1024 +typedef char Error_message_buf[ERRMSG_BUFSIZE]; const char* get_last_error_message(Error_message_buf); diff --git a/plugin/win_auth_client/handshake.h b/plugin/win_auth_client/handshake.h index adab4715c99..66d492f79ab 100644 --- a/plugin/win_auth_client/handshake.h +++ b/plugin/win_auth_client/handshake.h @@ -49,7 +49,7 @@ class Security_buffer: public SecBufferDesc m_buf.BufferType= SECBUFFER_TOKEN; m_buf.pvBuffer= ptr; - m_buf.cbBuffer= len; + m_buf.cbBuffer= (ULONG)len; } /// If @c false, no deallocation will be done in the destructor. @@ -100,7 +100,7 @@ public: Handshake(const char *ssp, side_t side); virtual ~Handshake(); - int Handshake::packet_processing_loop(); + int packet_processing_loop(); bool virtual is_complete() const { diff --git a/plugin/win_auth_client/handshake_client.cc b/plugin/win_auth_client/handshake_client.cc index 856dda76217..7969a6f3c49 100644 --- a/plugin/win_auth_client/handshake_client.cc +++ b/plugin/win_auth_client/handshake_client.cc @@ -160,7 +160,7 @@ int Handshake_client::write_packet(Blob &data) Store in byte 255 the number of 512b blocks that are needed to keep all the data. */ - unsigned block_count= data.len()/512 + ((data.len() % 512) ? 1 : 0); + unsigned block_count= (uint)(data.len()/512) + ((data.len() % 512) ? 1 : 0); #if !defined(DBUG_OFF) && defined(WINAUTH_USE_DBUG_LIB) diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm index 9f684ae6b0c..9268cb3e06b 100644 --- a/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm +++ b/plugin/wsrep_info/mysql-test/wsrep_info/suite.pm @@ -9,8 +9,10 @@ return "Not run for embedded server" if $::opt_embedded_server; return "WSREP is not compiled in" unless defined $::mysqld_variables{'wsrep-on'}; my ($provider) = grep { -f $_ } $ENV{WSREP_PROVIDER}, - "/usr/lib/galera/libgalera_smm.so", - "/usr/lib64/galera/libgalera_smm.so"; + "/usr/lib64/galera-3/libgalera_smm.so", + "/usr/lib64/galera/libgalera_smm.so", + "/usr/lib/galera-3/libgalera_smm.so", + "/usr/lib/galera/libgalera_smm.so"; return "No wsrep provider library" unless -f $provider; diff --git a/plugin/wsrep_info/plugin.cc b/plugin/wsrep_info/plugin.cc index ed502d30f88..428bcc5dcfc 100644 --- a/plugin/wsrep_info/plugin.cc +++ b/plugin/wsrep_info/plugin.cc @@ -17,7 +17,7 @@ #define MYSQL_SERVER #endif -#include <my_config.h> +#include <my_global.h> #include <mysql/plugin.h> #include <table.h> /* ST_SCHEMA_TABLE */ #include <sql_show.h> |