From a2e281823a6f6796b85a458f3a25927745747c4c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 30 Jun 2015 14:58:36 +0300 Subject: [PATCH 01/41] Added NULL checks to readwritesplit. --- .../routing/readwritesplit/readwritesplit.c | 131 +++++++++++++----- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 14f99c361..b5b4ddb36 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -226,7 +226,7 @@ static rses_property_t* mysql_sescmd_get_property( static rses_property_t* rses_property_init( rses_property_type_t prop_type); -static void rses_property_add( +static int rses_property_add( ROUTER_CLIENT_SES* rses, rses_property_t* prop); @@ -2943,6 +2943,11 @@ static void bref_clear_state( backend_ref_t* bref, bref_state_t state) { + if(bref == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to bref_clear_state. (%s:%d)",__FILE__,__LINE__); + return; + } if (state != BREF_WAITING_RESULT) { bref->bref_state &= ~state; @@ -2972,6 +2977,11 @@ static void bref_set_state( backend_ref_t* bref, bref_state_t state) { + if(bref == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to bref_set_state. (%s:%d)",__FILE__,__LINE__); + return; + } if (state != BREF_WAITING_RESULT) { bref->bref_state |= state; @@ -3535,7 +3545,8 @@ static rses_property_t* rses_property_init( prop = (rses_property_t*)calloc(1, sizeof(rses_property_t)); if (prop == NULL) { - goto return_prop; + skygw_log_write(LE,"Error: Malloc returned NULL. (%s:%d)",__FILE__,__LINE__); + return NULL; } prop->rses_prop_type = prop_type; #if defined(SS_DEBUG) @@ -3554,6 +3565,11 @@ return_prop: static void rses_property_done( rses_property_t* prop) { + if(prop == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to rses_property_done. (%s:%d)",__FILE__,__LINE__); + return; + } CHK_RSES_PROP(prop); switch (prop->rses_prop_type) { @@ -3587,10 +3603,20 @@ static void rses_property_done( * * Router client session must be locked. */ -static void rses_property_add( +static int rses_property_add( ROUTER_CLIENT_SES* rses, rses_property_t* prop) { + if(rses == NULL) + { + skygw_log_write(LE,"Error: Router client session is NULL. (%s:%d)",__FILE__,__LINE__); + return -1; + } + if(prop == NULL) + { + skygw_log_write(LE,"Error: Router client session property is NULL. (%s:%d)",__FILE__,__LINE__); + return -1; + } rses_property_t* p; CHK_CLIENT_RSES(rses); @@ -3612,6 +3638,7 @@ static void rses_property_add( } p->rses_prop_next = prop; } + return 0; } /** @@ -3622,7 +3649,13 @@ static mysql_sescmd_t* rses_property_get_sescmd( rses_property_t* prop) { mysql_sescmd_t* sescmd; - + + if(prop == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to rses_property_get_sescmd. (%s:%d)",__FILE__,__LINE__); + return; + } + CHK_RSES_PROP(prop); ss_dassert(prop->rses_prop_rsession == NULL || SPINLOCK_IS_LOCKED(&prop->rses_prop_rsession->rses_lock)); @@ -3635,22 +3668,6 @@ static mysql_sescmd_t* rses_property_get_sescmd( } return sescmd; } - -/** -static void rses_begin_locked_property_action( - rses_property_t* prop) -{ - CHK_RSES_PROP(prop); - spinlock_acquire(&prop->rses_prop_lock); -} - -static void rses_end_locked_property_action( - rses_property_t* prop) -{ - CHK_RSES_PROP(prop); - spinlock_release(&prop->rses_prop_lock); -} -*/ /** * Create session command property. @@ -3683,6 +3700,11 @@ static mysql_sescmd_t* mysql_sescmd_init ( static void mysql_sescmd_done( mysql_sescmd_t* sescmd) { + if(sescmd == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to mysql_sescmd_done. (%s:%d)",__FILE__,__LINE__); + return; + } CHK_RSES_PROP(sescmd->my_sescmd_prop); gwbuf_free(sescmd->my_sescmd_buf); memset(sescmd, 0, sizeof(mysql_sescmd_t)); @@ -3855,6 +3877,12 @@ static bool sescmd_cursor_is_active( sescmd_cursor_t* sescmd_cursor) { bool succp; + + if(sescmd_cursor == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to sescmd_cursor_is_active. (%s:%d)",__FILE__,__LINE__); + return false; + } ss_dassert(SPINLOCK_IS_LOCKED(&sescmd_cursor->scmd_cur_rses->rses_lock)); succp = sescmd_cursor->scmd_cur_active; @@ -3880,6 +3908,11 @@ static GWBUF* sescmd_cursor_clone_querybuf( sescmd_cursor_t* scur) { GWBUF* buf; + if(scur == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to sescmd_cursor_clone_querybuf. (%s:%d)",__FILE__,__LINE__); + return NULL; + } ss_dassert(scur->scmd_cur_cmd != NULL); buf = gwbuf_clone(scur->scmd_cur_cmd->my_sescmd_buf); @@ -3892,7 +3925,12 @@ static bool sescmd_cursor_history_empty( sescmd_cursor_t* scur) { bool succp; - + + if(scur == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to sescmd_cursor_history_empty. (%s:%d)",__FILE__,__LINE__); + return true; + } CHK_SESCMD_CUR(scur); if (scur->scmd_cur_rses->rses_properties[RSES_PROP_TYPE_SESCMD] == NULL) @@ -3912,6 +3950,11 @@ static void sescmd_cursor_reset( sescmd_cursor_t* scur) { ROUTER_CLIENT_SES* rses; + if(scur == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to sescmd_cursor_reset. (%s:%d)",__FILE__,__LINE__); + return; + } CHK_SESCMD_CUR(scur); CHK_CLIENT_RSES(scur->scmd_cur_rses); rses = scur->scmd_cur_rses; @@ -3928,6 +3971,11 @@ static bool execute_sescmd_history( { bool succp; sescmd_cursor_t* scur; + if(bref == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to execute_sescmd_history. (%s:%d)",__FILE__,__LINE__); + return false; + } CHK_BACKEND_REF(bref); scur = &bref->bref_sescmd_cur; @@ -3964,6 +4012,11 @@ static bool execute_sescmd_in_backend( int rc = 0; sescmd_cursor_t* scur; + if(backend_ref == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to execute_sescmd_in_backend. (%s:%d)",__FILE__,__LINE__); + return false; + } if (BREF_IS_CLOSED(backend_ref)) { succp = false; @@ -4084,6 +4137,12 @@ static bool sescmd_cursor_next( rses_property_t* prop_curr; rses_property_t* prop_next; + if(scur == NULL) + { + skygw_log_write(LE,"Error: NULL parameter passed to sescmd_cursor_next. (%s:%d)",__FILE__,__LINE__); + return false; + } + ss_dassert(scur != NULL); ss_dassert(*(scur->scmd_cur_ptr_property) != NULL); ss_dassert(SPINLOCK_IS_LOCKED( @@ -4410,11 +4469,21 @@ static bool route_session_write( * prevent it from being released before properties * are cleaned up as a part of router sessionclean-up. */ - prop = rses_property_init(RSES_PROP_TYPE_SESCMD); + if((prop = rses_property_init(RSES_PROP_TYPE_SESCMD)) == NULL) + { + skygw_log_write(LE,"Error: Router session property initialization failed"); + rses_end_locked_router_action(router_cli_ses); + return false; + } mysql_sescmd_init(prop, querybuf, packet_type, router_cli_ses); /** Add sescmd property to router client session */ - rses_property_add(router_cli_ses, prop); + if(rses_property_add(router_cli_ses, prop) != 0) + { + skygw_log_write(LE,"Error: Session property addition failed."); + rses_end_locked_router_action(router_cli_ses); + return false; + } for (i=0; irses_nbackends; i++) { @@ -4537,7 +4606,10 @@ static void rwsplit_process_router_options( int i; char* value; select_criteria_t c; - + + if(options == NULL) + return; + for (i = 0; options[i]; i++) { if ((value = strchr(options[i], '=')) == NULL) @@ -4625,7 +4697,7 @@ static void handleError ( SESSION* session; ROUTER_INSTANCE* inst = (ROUTER_INSTANCE *)instance; ROUTER_CLIENT_SES* rses = (ROUTER_CLIENT_SES *)router_session; - + CHK_DCB(backend_dcb); /** Reset error handle flag from a given DCB */ @@ -5088,8 +5160,6 @@ static int router_handle_state_switch( { backend_ref_t* bref; int rc = 1; - ROUTER_CLIENT_SES* rses; - SESSION* ses; SERVER* srv; CHK_DCB(dcb); @@ -5110,11 +5180,8 @@ static int router_handle_state_switch( srv->name, srv->port, STRSRVSTATUS(srv)))); - ses = dcb->session; - CHK_SESSION(ses); - - rses = (ROUTER_CLIENT_SES *)dcb->session->router_session; - CHK_CLIENT_RSES(rses); + CHK_SESSION(dcb->session); + CHK_CLIENT_RSES(dcb->session->router_session); switch (reason) { case DCB_REASON_NOT_RESPONDING: From 4706b756c25c62b89803cc5bdf1bafa0521c1d57 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 30 Jun 2015 19:16:49 +0300 Subject: [PATCH 02/41] Changed the service resource hashing function into a proper string hashing function. --- server/core/dbusers.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 935644c18..6748a1437 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -1842,18 +1842,6 @@ char *mysql_format_user_entry(void *data) return mysql_user; } -/* - * The hash function we use for storing MySQL database names. - * - * @param key The key value - * @return The hash key - */ -int -resource_hash(char *key) -{ - return (*key + *(key + 1)); -} - /** * Remove the resources table * @@ -1877,7 +1865,7 @@ resource_alloc() { HASHTABLE *resources; - if ((resources = hashtable_alloc(10, resource_hash, strcmp)) == NULL) + if ((resources = hashtable_alloc(10, simple_str_hash, strcmp)) == NULL) { return NULL; } From 53a4dd393d0ad4b77be9f1c50525abcd5f315e01 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 1 Jul 2015 05:15:08 +0300 Subject: [PATCH 03/41] Fix to a Coverity defect. --- server/modules/routing/readwritesplit/readwritesplit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index b5b4ddb36..c4008e65e 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3653,7 +3653,7 @@ static mysql_sescmd_t* rses_property_get_sescmd( if(prop == NULL) { skygw_log_write(LE,"Error: NULL parameter passed to rses_property_get_sescmd. (%s:%d)",__FILE__,__LINE__); - return; + return NULL; } CHK_RSES_PROP(prop); From dc15fbb576ce19cca92f309f6c572238242353be Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 1 Jul 2015 16:46:32 +0300 Subject: [PATCH 04/41] Fixed build failure. --- server/modules/routing/readwritesplit/readwritesplit.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index c4008e65e..b801d9aec 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -5161,7 +5161,8 @@ static int router_handle_state_switch( backend_ref_t* bref; int rc = 1; SERVER* srv; - + ROUTER_CLIENT_SES* rses; + SESSION* ses; CHK_DCB(dcb); bref = (backend_ref_t *)data; CHK_BACKEND_REF(bref); @@ -5180,8 +5181,10 @@ static int router_handle_state_switch( srv->name, srv->port, STRSRVSTATUS(srv)))); - CHK_SESSION(dcb->session); - CHK_CLIENT_RSES(dcb->session->router_session); + ses = dcb->session; + CHK_SESSION(ses); + rses = (ROUTER_CLIENT_SES *)dcb->session->router_session; + CHK_CLIENT_RSES(rses); switch (reason) { case DCB_REASON_NOT_RESPONDING: From ea14839dbcdc31ddd572e13e78eb895d63c505fd Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 2 Jul 2015 14:55:43 +0300 Subject: [PATCH 05/41] Updated release notes with fixed bugs. --- .../MaxScale-1.2.0-Release-Notes.md | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index a84f94c27..49206f8ed 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -29,3 +29,27 @@ MaxScale now supports SSL/TLS encrypted connections to MaxScale. ### Monitor scripts State changes in backend servers can now trigger the execution of a custom script. With this you can easily customize MaxScale's behavior. + +## Bug fixes + +Here is a list of bugs fixed since the release of MaxScale 1.1.1. +|Key|Summary| +|[MXS-24](https://mariadb.atlassian.net/browse/MXS-24)|bugzillaId-604: Module load path documentation issues ...| +|[MXS-40](https://mariadb.atlassian.net/browse/MXS-40)|Display logged in users| +|[MXS-113](https://mariadb.atlassian.net/browse/MXS-113)|MaxScale seems to fail if built against MariaDB 10.0 libraries| +|[MXS-116](https://mariadb.atlassian.net/browse/MXS-116)|Do not run maxscale as root.| +|[MXS-125](https://mariadb.atlassian.net/browse/MXS-125)|inconsistency in maxkeys/maxpassword output and parameters| +|[MXS-136](https://mariadb.atlassian.net/browse/MXS-136)|Check for MaxScale replication heartbeat table existence before creating| +|[MXS-137](https://mariadb.atlassian.net/browse/MXS-137)|cannot get sql for queries with length >= 0x80| +|[MXS-139](https://mariadb.atlassian.net/browse/MXS-139)|Schemarouter authentication for wildcard grants fails without optimize_wildcard| +|[MXS-140](https://mariadb.atlassian.net/browse/MXS-140)|strip_db_esc does not work without auth_all_servers| +|[MXS-162](https://mariadb.atlassian.net/browse/MXS-162)|Fix Incorrect info in Configuration Guide| +|[MXS-163](https://mariadb.atlassian.net/browse/MXS-163)|Reload config leaks memory| +|[MXS-165](https://mariadb.atlassian.net/browse/MXS-165)|Concurrency issue while incrementing sessions in qlafilter| +|[MXS-166](https://mariadb.atlassian.net/browse/MXS-166)|Memory leak when creating a new event| +|[MXS-171](https://mariadb.atlassian.net/browse/MXS-171)|Allow reads on master for readwritesplit| +|[MXS-176](https://mariadb.atlassian.net/browse/MXS-176)|Missing dependencies in documentation| +|[MXS-181](https://mariadb.atlassian.net/browse/MXS-181)|Poor performance on TCP connection due to Nagle's algoritm| +|[MXS-212](https://mariadb.atlassian.net/browse/MXS-212)|Stopped services accept connections| +|[MXS-225](https://mariadb.atlassian.net/browse/MXS-225)|RPM Debug build packages have no debugging symbols| +|[MXS-227](https://mariadb.atlassian.net/browse/MXS-227)|Memory leak in Galera Monitor| From 3817b6fca8e6df12c72617c35cb669b97dc1d084 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 2 Jul 2015 15:01:16 +0300 Subject: [PATCH 06/41] Fixed broken table. --- Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index 49206f8ed..f98c2191f 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -34,6 +34,7 @@ State changes in backend servers can now trigger the execution of a custom scrip Here is a list of bugs fixed since the release of MaxScale 1.1.1. |Key|Summary| +------------ |[MXS-24](https://mariadb.atlassian.net/browse/MXS-24)|bugzillaId-604: Module load path documentation issues ...| |[MXS-40](https://mariadb.atlassian.net/browse/MXS-40)|Display logged in users| |[MXS-113](https://mariadb.atlassian.net/browse/MXS-113)|MaxScale seems to fail if built against MariaDB 10.0 libraries| From fed2cd9a3a3df2a8a3aa79df9af9f5965047d83c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 2 Jul 2015 15:02:19 +0300 Subject: [PATCH 07/41] More broken tables. --- Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index f98c2191f..636d46ad8 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -34,7 +34,7 @@ State changes in backend servers can now trigger the execution of a custom scrip Here is a list of bugs fixed since the release of MaxScale 1.1.1. |Key|Summary| ------------- +|---|--------| |[MXS-24](https://mariadb.atlassian.net/browse/MXS-24)|bugzillaId-604: Module load path documentation issues ...| |[MXS-40](https://mariadb.atlassian.net/browse/MXS-40)|Display logged in users| |[MXS-113](https://mariadb.atlassian.net/browse/MXS-113)|MaxScale seems to fail if built against MariaDB 10.0 libraries| From e09e5381ec9dc91080ff34828e717c23b8f50018 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 2 Jul 2015 15:05:03 +0300 Subject: [PATCH 08/41] Fixed table. --- .../MaxScale-1.2.0-Release-Notes.md | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index 636d46ad8..caf7e28c6 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -33,24 +33,25 @@ State changes in backend servers can now trigger the execution of a custom scrip ## Bug fixes Here is a list of bugs fixed since the release of MaxScale 1.1.1. -|Key|Summary| -|---|--------| -|[MXS-24](https://mariadb.atlassian.net/browse/MXS-24)|bugzillaId-604: Module load path documentation issues ...| -|[MXS-40](https://mariadb.atlassian.net/browse/MXS-40)|Display logged in users| -|[MXS-113](https://mariadb.atlassian.net/browse/MXS-113)|MaxScale seems to fail if built against MariaDB 10.0 libraries| -|[MXS-116](https://mariadb.atlassian.net/browse/MXS-116)|Do not run maxscale as root.| -|[MXS-125](https://mariadb.atlassian.net/browse/MXS-125)|inconsistency in maxkeys/maxpassword output and parameters| -|[MXS-136](https://mariadb.atlassian.net/browse/MXS-136)|Check for MaxScale replication heartbeat table existence before creating| -|[MXS-137](https://mariadb.atlassian.net/browse/MXS-137)|cannot get sql for queries with length >= 0x80| -|[MXS-139](https://mariadb.atlassian.net/browse/MXS-139)|Schemarouter authentication for wildcard grants fails without optimize_wildcard| -|[MXS-140](https://mariadb.atlassian.net/browse/MXS-140)|strip_db_esc does not work without auth_all_servers| -|[MXS-162](https://mariadb.atlassian.net/browse/MXS-162)|Fix Incorrect info in Configuration Guide| -|[MXS-163](https://mariadb.atlassian.net/browse/MXS-163)|Reload config leaks memory| -|[MXS-165](https://mariadb.atlassian.net/browse/MXS-165)|Concurrency issue while incrementing sessions in qlafilter| -|[MXS-166](https://mariadb.atlassian.net/browse/MXS-166)|Memory leak when creating a new event| -|[MXS-171](https://mariadb.atlassian.net/browse/MXS-171)|Allow reads on master for readwritesplit| -|[MXS-176](https://mariadb.atlassian.net/browse/MXS-176)|Missing dependencies in documentation| -|[MXS-181](https://mariadb.atlassian.net/browse/MXS-181)|Poor performance on TCP connection due to Nagle's algoritm| -|[MXS-212](https://mariadb.atlassian.net/browse/MXS-212)|Stopped services accept connections| -|[MXS-225](https://mariadb.atlassian.net/browse/MXS-225)|RPM Debug build packages have no debugging symbols| -|[MXS-227](https://mariadb.atlassian.net/browse/MXS-227)|Memory leak in Galera Monitor| + +| Key | Summary | +| --- | -------- | +| [MXS-24](https://mariadb.atlassian.net/browse/MXS-24) | bugzillaId-604: Module load path documentation issues ... | +| [MXS-40](https://mariadb.atlassian.net/browse/MXS-40) | Display logged in users | +| [MXS-113](https://mariadb.atlassian.net/browse/MXS-113) | MaxScale seems to fail if built against MariaDB 10.0 libraries | +| [MXS-116](https://mariadb.atlassian.net/browse/MXS-116) | Do not run maxscale as root. | +| [MXS-125](https://mariadb.atlassian.net/browse/MXS-125) | inconsistency in maxkeys/maxpassword output and parameters | +| [MXS-136](https://mariadb.atlassian.net/browse/MXS-136) | Check for MaxScale replication heartbeat table existence before creating | +| [MXS-137](https://mariadb.atlassian.net/browse/MXS-137) | cannot get sql for queries with length >= 0x80 | +| [MXS-139](https://mariadb.atlassian.net/browse/MXS-139) | Schemarouter authentication for wildcard grants fails without optimize_wildcard | +| [MXS-140](https://mariadb.atlassian.net/browse/MXS-140) | strip_db_esc does not work without auth_all_servers | +| [MXS-162](https://mariadb.atlassian.net/browse/MXS-162) | Fix Incorrect info in Configuration Guide | +| [MXS-163](https://mariadb.atlassian.net/browse/MXS-163) | Reload config leaks memory | +| [MXS-165](https://mariadb.atlassian.net/browse/MXS-165) | Concurrency issue while incrementing sessions in qlafilter | +| [MXS-166](https://mariadb.atlassian.net/browse/MXS-166) | Memory leak when creating a new event | +| [MXS-171](https://mariadb.atlassian.net/browse/MXS-171) | Allow reads on master for readwritesplit | +| [MXS-176](https://mariadb.atlassian.net/browse/MXS-176) | Missing dependencies in documentation | +| [MXS-181](https://mariadb.atlassian.net/browse/MXS-181) | Poor performance on TCP connection due to Nagle's algoritm | +| [MXS-212](https://mariadb.atlassian.net/browse/MXS-212) | Stopped services accept connections | +| [MXS-225](https://mariadb.atlassian.net/browse/MXS-225) | RPM Debug build packages have no debugging symbols | +| [MXS-227](https://mariadb.atlassian.net/browse/MXS-227) | Memory leak in Galera Monitor | From 5b75443744ef0a9b105efd8e40c017fd1ddeee44 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 4 Jul 2015 07:13:14 +0300 Subject: [PATCH 09/41] Fixed module load failure referring to lib/maxscale/modules instead of lib/maxscale. --- server/core/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/core/service.c b/server/core/service.c index 3dee01c91..4e36708f8 100644 --- a/server/core/service.c +++ b/server/core/service.c @@ -125,7 +125,7 @@ SERVICE *service; "Error : Unable to load %s module \"%s\".\n\t\t\t" " Ensure that lib%s.so exists in one of the " "following directories :\n\t\t\t " - "- %s/modules\n%s%s", + "- %s\n%s%s", MODULE_ROUTER, router, router, From 309b8bba9789de0036a48848ba4c347c717e44ca Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 4 Jul 2015 07:30:23 +0300 Subject: [PATCH 10/41] Added missing --piddir option to testall maxscale invokation. --- cmake/testall.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/testall.cmake b/cmake/testall.cmake index 65c27fa5a..839029312 100644 --- a/cmake/testall.cmake +++ b/cmake/testall.cmake @@ -1,4 +1,4 @@ -execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -f ${CMAKE_BINARY_DIR}/maxscale.cnf --logdir=${CMAKE_BINARY_DIR}/ --datadir=${CMAKE_BINARY_DIR}/ --cachedir=${CMAKE_BINARY_DIR}/ &> ${CMAKE_BINARY_DIR}/maxscale.output" +execute_process(COMMAND /bin/sh -c "${CMAKE_BINARY_DIR}/bin/maxscale -f ${CMAKE_BINARY_DIR}/maxscale.cnf --logdir=${CMAKE_BINARY_DIR}/ --datadir=${CMAKE_BINARY_DIR}/ --cachedir=${CMAKE_BINARY_DIR}/ --piddir=${CMAKE_BINARY_DIR}/ &> ${CMAKE_BINARY_DIR}/maxscale.output" OUTPUT_VARIABLE MAXSCALE_OUT) execute_process(COMMAND make test RESULT_VARIABLE RVAL) execute_process(COMMAND killall maxscale) From dc646bfbf16bf21978fedec789278379aca9f7c5 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sat, 4 Jul 2015 09:04:53 +0300 Subject: [PATCH 11/41] Fix to MXS-244: https://mariadb.atlassian.net/browse/MXS-244 Fixed buffers being only partially consumed if they contained more than one packet when a replu to a prepared statement is received. --- server/modules/routing/readwritesplit/readwritesplit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index b801d9aec..3c329f646 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3787,7 +3787,7 @@ static GWBUF* sescmd_cursor_process_replies( dcb_close(bref->bref_dcb); *reconnect = true; if(replybuf) - gwbuf_consume(replybuf,gwbuf_length(replybuf)); + while((replybuf = gwbuf_consume(replybuf,gwbuf_length(replybuf)))); } } /** This is a response from the master and it is the "right" one. @@ -3830,7 +3830,7 @@ static GWBUF* sescmd_cursor_process_replies( skygw_log_write(LOGFILE_DEBUG,"Slave '%s' responded faster to a session command.", bref->bref_backend->backend_server->unique_name); if(replybuf) - gwbuf_free(replybuf); + while((replybuf = gwbuf_consume(replybuf,gwbuf_length(replybuf)))); return NULL; } From 5b95e2b32e30b9b27155f1b68243f9265e023d3b Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 6 Jul 2015 10:38:03 +0300 Subject: [PATCH 12/41] Updated 1.2 release notes. --- .../MaxScale-1.2.0-Release-Notes.md | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index caf7e28c6..de4b7a461 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -27,8 +27,8 @@ A quick list of changes in installation directories and file names: ### Client side SSL encryption MaxScale now supports SSL/TLS encrypted connections to MaxScale. -### Monitor scripts -State changes in backend servers can now trigger the execution of a custom script. With this you can easily customize MaxScale's behavior. +### Launchable scripts +Now you can configure MaxScale monitor module to automatically launch a script when it detects change in the state of a backend server. The script can be any customer script defined by you to take diagnostic or reporting action. With this you can easily customize MaxScale's behavior. ## Bug fixes @@ -40,18 +40,58 @@ Here is a list of bugs fixed since the release of MaxScale 1.1.1. | [MXS-40](https://mariadb.atlassian.net/browse/MXS-40) | Display logged in users | | [MXS-113](https://mariadb.atlassian.net/browse/MXS-113) | MaxScale seems to fail if built against MariaDB 10.0 libraries | | [MXS-116](https://mariadb.atlassian.net/browse/MXS-116) | Do not run maxscale as root. | +| [MXS-117](https://mariadb.atlassian.net/browse/MXS-117) | Allow configuration of the log file directory | | [MXS-125](https://mariadb.atlassian.net/browse/MXS-125) | inconsistency in maxkeys/maxpassword output and parameters | +| [MXS-128](https://mariadb.atlassian.net/browse/MXS-128) | cyclic dependency utils -> log_manager -> utils | | [MXS-136](https://mariadb.atlassian.net/browse/MXS-136) | Check for MaxScale replication heartbeat table existence before creating | | [MXS-137](https://mariadb.atlassian.net/browse/MXS-137) | cannot get sql for queries with length >= 0x80 | | [MXS-139](https://mariadb.atlassian.net/browse/MXS-139) | Schemarouter authentication for wildcard grants fails without optimize_wildcard | | [MXS-140](https://mariadb.atlassian.net/browse/MXS-140) | strip_db_esc does not work without auth_all_servers | -| [MXS-162](https://mariadb.atlassian.net/browse/MXS-162) | Fix Incorrect info in Configuration Guide | -| [MXS-163](https://mariadb.atlassian.net/browse/MXS-163) | Reload config leaks memory | +| [MXS-162](https://mariadb.atlassian.net/browse/MXS-162) | Fix Incorrect info in Configuration Guide | | [MXS-165](https://mariadb.atlassian.net/browse/MXS-165) | Concurrency issue while incrementing sessions in qlafilter | | [MXS-166](https://mariadb.atlassian.net/browse/MXS-166) | Memory leak when creating a new event | | [MXS-171](https://mariadb.atlassian.net/browse/MXS-171) | Allow reads on master for readwritesplit | | [MXS-176](https://mariadb.atlassian.net/browse/MXS-176) | Missing dependencies in documentation | +| [MXS-180](https://mariadb.atlassian.net/browse/MXS-180) | MariaDB10 binlog router compatibilty | | [MXS-181](https://mariadb.atlassian.net/browse/MXS-181) | Poor performance on TCP connection due to Nagle's algoritm | +| [MXS-182](https://mariadb.atlassian.net/browse/MXS-182) | SHOW SLAVE STATUS and maxadmin "show services" for binlog router needs updated when used with MariaDB 10 Master | | [MXS-212](https://mariadb.atlassian.net/browse/MXS-212) | Stopped services accept connections | | [MXS-225](https://mariadb.atlassian.net/browse/MXS-225) | RPM Debug build packages have no debugging symbols | | [MXS-227](https://mariadb.atlassian.net/browse/MXS-227) | Memory leak in Galera Monitor | +| [MXS-244](https://mariadb.atlassian.net/browse/MXS-244) | Memory leak when using prepared statements without arguments | + +## Known Issues and Limitations + +There are a number bugs and known limitations within this version of MaxScale, the most serious of this are listed below. + +* MaxScale can not manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries. + +* When users have different passwords based on the host from which they connect MaxScale is unable to determine which password it should use to connect to the backend database. This results in failed connections and unusable usernames in MaxScale. + +* LONGBLOB are currently not supported. + +* Galera Cluster variables, such as @@wsrep_node_name, are not resolved by the embedded MariaDB parser. + +* The Database Firewall filter does not support multi-statements. Using them will result in an error being sent to the client. + +## Packaging + +Both RPM and Debian packages are available for MaxScale in addition to the tar based releases previously distributed we now provide + +* CentOS/RedHat 5 + +* CentOS/RedHat 6 + +* CentOS/RedHat 7 + +* Debian 6 + +* Debian 7 + +* Ubuntu 12.04 LTS + +* Ubuntu 14.04 LTS + +* SuSE Linux Enterprise 11 + +* SuSE Linux Enterprise 12 From 1af73b706148a64a470f79be297791b2586dbdd3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 3 Jul 2015 17:08:32 +0300 Subject: [PATCH 13/41] Fixed common sharding functions referring to schemarouter. --- server/modules/routing/schemarouter/sharding_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/modules/routing/schemarouter/sharding_common.c b/server/modules/routing/schemarouter/sharding_common.c index d69b12d02..cf6bf2c12 100644 --- a/server/modules/routing/schemarouter/sharding_common.c +++ b/server/modules/routing/schemarouter/sharding_common.c @@ -46,7 +46,7 @@ bool extract_database(GWBUF* buf, char* str) tok = strtok_r(query," ;",&saved); if(tok == NULL || strcasecmp(tok,"use") != 0) { - skygw_log_write(LOGFILE_ERROR,"Schemarouter: Malformed chage database packet."); + skygw_log_write(LOGFILE_ERROR,"extract_database: Malformed chage database packet."); succp = false; goto retblock; } @@ -54,7 +54,7 @@ bool extract_database(GWBUF* buf, char* str) tok = strtok_r(NULL," ;",&saved); if(tok == NULL) { - skygw_log_write(LOGFILE_ERROR,"Schemarouter: Malformed chage database packet."); + skygw_log_write(LOGFILE_ERROR,"extract_database: Malformed chage database packet."); succp = false; goto retblock; } From 5bdfa42aa7c961097933bc9961a81f61a39def5e Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 06:31:52 +0300 Subject: [PATCH 14/41] Fixed Building from Source document. --- .../Building-MaxScale-from-Source-Code.md | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md index 95236ed7e..2d8f0661e 100644 --- a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md +++ b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md @@ -87,16 +87,13 @@ You will also need some version specific packages. #### Earlier versions of Ubuntu or Debian -For these, you will need to obtain the MariaDB embedded library. It has to be manually extracted from the tarball. But first ascertain what version of glibc is installed. Run the command: +For these, you will need to obtain the MariaDB embedded library. It has to be manually extracted from the tarballs at the MariaDB site. But first ascertain what version of glibc is installed. Run the command: ``` dpkg -l | grep libc6 ``` -which will show the version number. If the version is less than 2.14 you should obtain the library from: -[https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-x86_64/mariadb-5.5.41-linux-x86_64.tar.gz](https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-x86_64/mariadb-5.5.41-linux-x86_64.tar.gz). -Otherwise, from: -[https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-glibc_214-x86_64/mariadb-5.5.41-linux-glibc_214-x86_64.tar.gz](https://downloads.mariadb.org/interstitial/mariadb-5.5.41/bintar-linux-glibc_214-x86_64/mariadb-5.5.41-linux-glibc_214-x86_64.tar.gz) +which will show the version number. For versions older than 2.14 you should obtain the library which supports GLIBC versions older than 2.14 and for newer versions, the library which supports newer GLIBC versions should be used. The suggested location for extracting the tarball is `/usr` so the operation can be done by the following commands: @@ -107,22 +104,6 @@ The suggested location for extracting the tarball is `/usr` so the operation can where /path/to/mariadb.library.tar.gz is replaced by the actual path and name of the downloaded tarball. -## OpenSUSE - -At the time this guide was written, the MariaDB development packages for OpenSUSE were broken and the build failed. - -The packages required are: - -``` -gcc gcc-c++ ncurses-devel bison glibc-devel cmake libgcc_s1 perl -make libtool libopenssl-devel libaio libaio-devel -libedit-devel librabbitmq-devel - MariaDB-devel MariaDB-client MariaDB-server -``` - -If zypper ask which MariaDB client should be installed `MariaDB-client` or `mariadb-client` - please select `MariaDB-client`. This is the package provided by the MariaDB repository. - # Obtaining the MaxScale Source Code Now clone the GitHub project to your machine either via the web interface, your favorite graphical interface or the git command line @@ -152,16 +133,15 @@ wipe the build directory clean without the danger of deleting important files wh something goes wrong. Building 'out-of-source' also allows you to have multiple configurations of MaxScale at the same time. -The default values that CMake uses can be found in the 'macros.cmake' file. -If you wish to change these, edit the 'macros.cmake' file or define the -variables manually at configuration time. +The default values that MaxScale uses for CMake can be found in the 'macros.cmake' file under the `cmake` folder. +If you wish to change these, edit the 'macros.cmake' file or define the variables manually at configuration time. To display all CMake variables with their descriptions: ``` cmake .. -LH ``` -This is a useful command if you have your libraries installed in non-standard locations. +This is a useful command if you have your libraries installed in non-standard locations and need to provide them manually. When you are ready to run cmake, provide the following command: @@ -241,7 +221,7 @@ $ make install This will result in an installation being created which is identical to that which would be achieved by installing the binary package. -By default, MaxScale installs to `/usr/local/mariadb-maxscale` and places init.d scripts and ldconfig files into their folders. Change the `CMAKE_INSTALL_PREFIX` variable to your desired installation directory and set `WITH_SCRIPTS=N` to prevent the init.d script and ldconfig file installation. +When building from source, MaxScale installs to `/usr/local/` and places init.d scripts and ldconfig files into their folders. Change the `CMAKE_INSTALL_PREFIX` variable to your desired installation directory and set `WITH_SCRIPTS=N` to prevent the init.d script and ldconfig file installation. Other useful targets for Make are `documentation`, which generates the Doxygen documentation, and `uninstall` which uninstall MaxScale binaries after an install. From 9d5d6da865d11a5daf391ad0562f0a7472bb2259 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 06:33:49 +0300 Subject: [PATCH 15/41] Removed Fedora references from the source building documentation. --- .../Building-MaxScale-from-Source-Code.md | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md index 2d8f0661e..96147c0f1 100644 --- a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md +++ b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md @@ -22,9 +22,9 @@ After following the instructions on that site you should have a working MariaDB The full list of dependencies for the most common distributions is provided in this section. If your system is not listed here, MaxScale building isn't guaranteed to be compatible but might still be successful. -## RHEL, CentOS and Fedora +## RHEL and CentOS -You will need to install all of the following packages for all versions of RHEL, CentOS and Fedora. +You will need to install all of the following packages for all versions of RHEL and CentOS. ``` gcc gcc-c++ ncurses-devel bison glibc-devel cmake libgcc perl make libtool @@ -39,7 +39,7 @@ rpm-build There are also some version specific packages you need to install. -#### RHEL 6, 7, CentOS 6, 7, Fedora: +#### RHEL 6, 7, CentOS 6, 7: ``` libedit-devel @@ -51,17 +51,11 @@ libedit-devel mariadb-devel mariadb-embedded-devel ``` -#### RHEL 5, 6, CentOS 5, 6, Fedora 19, 20 +#### RHEL 5, 6, CentOS 5, 6 ``` MariaDB-devel MariaDB-server ``` -#### Fedora 19, 20 - -``` -systemtap-sdt-devel -``` - ## Ubuntu and Debian These packages are required on all versions of Ubuntu and Debian. From c2e51f2e983df1bbd47f9253c7106a2041545a8a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 08:16:29 +0300 Subject: [PATCH 16/41] Fix to MXS-223: https://mariadb.atlassian.net/browse/MXS-223 Added a temporary buffer to prevent losing the pointer to the cloned buffer when dcb->func.write fails. --- .../routing/readwritesplit/readwritesplit.c | 30 +++++-------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 3c329f646..be2fb68df 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -4011,7 +4011,7 @@ static bool execute_sescmd_in_backend( bool succp; int rc = 0; sescmd_cursor_t* scur; - + GWBUF* buf; if(backend_ref == NULL) { skygw_log_write(LE,"Error: NULL parameter passed to execute_sescmd_in_backend. (%s:%d)",__FILE__,__LINE__); @@ -4048,27 +4048,9 @@ static bool execute_sescmd_in_backend( /** Cursor is left active when function returns. */ sescmd_cursor_set_active(scur, true); } -#if defined(SS_DEBUG) - LOGIF(LT, tracelog_routed_query(scur->scmd_cur_rses, - "execute_sescmd_in_backend", - backend_ref, - sescmd_cursor_clone_querybuf(scur))); - { - GWBUF* tmpbuf = sescmd_cursor_clone_querybuf(scur); - uint8_t* ptr = GWBUF_DATA(tmpbuf); - unsigned char cmd = MYSQL_GET_COMMAND(ptr); - - LOGIF(LD, (skygw_log_write( - LOGFILE_DEBUG, - "%lu [execute_sescmd_in_backend] Just before write, fd " - "%d : cmd %s.", - pthread_self(), - dcb->fd, - STRPACKETTYPE(cmd)))); - gwbuf_free(tmpbuf); - } -#endif /*< SS_DEBUG */ + buf = sescmd_cursor_clone_querybuf(scur); + switch (scur->scmd_cur_cmd->my_sescmd_packet_type) { case MYSQL_COM_CHANGE_USER: /** This makes it possible to handle replies correctly */ @@ -4077,7 +4059,7 @@ static bool execute_sescmd_in_backend( dcb, NULL, dcb->session, - sescmd_cursor_clone_querybuf(scur)); + buf); break; case MYSQL_COM_INIT_DB: @@ -4103,10 +4085,11 @@ static bool execute_sescmd_in_backend( * Mark session command buffer, it triggers writing * MySQL command to protocol */ + gwbuf_set_type(scur->scmd_cur_cmd->my_sescmd_buf, GWBUF_TYPE_SESCMD); rc = dcb->func.write( dcb, - sescmd_cursor_clone_querybuf(scur)); + buf); break; } @@ -4116,6 +4099,7 @@ static bool execute_sescmd_in_backend( } else { + while((buf = GWBUF_CONSUME_ALL(buf)) != NULL); succp = false; } return_succp: From fb09cbf1000ccb90062c2c316d4d9fc43d11dc42 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 13:15:23 +0300 Subject: [PATCH 17/41] Fixed queries being routed when the session is already closing. --- server/core/buffer.c | 1 + server/modules/protocol/mysql_backend.c | 11 +- server/modules/protocol/mysql_client.c | 140 ++++++++++-------- server/modules/routing/readconnroute.c | 12 +- .../routing/readwritesplit/readwritesplit.c | 2 +- 5 files changed, 89 insertions(+), 77 deletions(-) diff --git a/server/core/buffer.c b/server/core/buffer.c index 4c788cdd2..c3adacd34 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -197,6 +197,7 @@ GWBUF *rval; rval->gwbuf_info = buf->gwbuf_info; rval->gwbuf_bufobj = buf->gwbuf_bufobj; rval->tail = rval; + rval->next = NULL; CHK_GWBUF(rval); return rval; } diff --git a/server/modules/protocol/mysql_backend.c b/server/modules/protocol/mysql_backend.c index 477ca4cf0..3a5e8f52b 100644 --- a/server/modules/protocol/mysql_backend.c +++ b/server/modules/protocol/mysql_backend.c @@ -1080,7 +1080,7 @@ gw_backend_hangup(DCB *dcb) len = sizeof(error); if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0) { - if (error != 0) + if (error != 0 && ses_state != SESSION_STATE_STOPPING) { strerror_r(error, buf, 100); LOGIF(LE, (skygw_log_write_flush( @@ -1094,9 +1094,12 @@ gw_backend_hangup(DCB *dcb) goto retblock; } #if defined(SS_DEBUG) - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Backend hangup error handling."))); + if(ses_state != SESSION_STATE_STOPPING) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Backend hangup error handling."))); + } #endif router->handleError(router_instance, diff --git a/server/modules/protocol/mysql_client.c b/server/modules/protocol/mysql_client.c index c3e463139..bab5971a8 100644 --- a/server/modules/protocol/mysql_client.c +++ b/server/modules/protocol/mysql_client.c @@ -1092,7 +1092,8 @@ int gw_read_client_event( case MYSQL_IDLE: { uint8_t* payload = NULL; - + session_state_t ses_state; + session = dcb->session; ss_dassert(session!= NULL); @@ -1100,93 +1101,106 @@ int gw_read_client_event( { CHK_SESSION(session); } + spinlock_acquire(&session->ses_lock); + ses_state = session->state; + spinlock_release(&session->ses_lock); /* Now, we are assuming in the first buffer there is * the information form mysql command */ payload = GWBUF_DATA(read_buffer); - /** Route COM_QUIT to backend */ - if (MYSQL_IS_COM_QUIT(payload)) - { + if(ses_state == SESSION_STATE_ROUTER_READY) + { + /** Route COM_QUIT to backend */ + if (MYSQL_IS_COM_QUIT(payload)) + { /** - * Sends COM_QUIT packets since buffer is already - * created. A BREF_CLOSED flag is set so dcb_close won't - * send redundant COM_QUIT. - */ + * Sends COM_QUIT packets since buffer is already + * created. A BREF_CLOSED flag is set so dcb_close won't + * send redundant COM_QUIT. + */ SESSION_ROUTE_QUERY(session, read_buffer); /** - * Close router session which causes closing of backends. - */ + * Close router session which causes closing of backends. + */ dcb_close(dcb); - } - else - { + } + else + { /** Reset error handler when routing of the new query begins */ router->handleError(NULL, NULL, NULL, dcb, ERRACT_RESET, NULL); if (stmt_input) { - /** - * Feed each statement completely and separately - * to router. - */ - rc = route_by_statement(session, &read_buffer); - - if (read_buffer != NULL) - { - /** add incomplete mysql packet to read queue */ - dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); - } + /** + * Feed each statement completely and separately + * to router. + */ + rc = route_by_statement(session, &read_buffer); + + if (read_buffer != NULL) + { + /** add incomplete mysql packet to read queue */ + dcb->dcb_readqueue = gwbuf_append(dcb->dcb_readqueue, read_buffer); + } } else { - /** Feed whole packet to router */ - rc = SESSION_ROUTE_QUERY(session, read_buffer); + /** Feed whole packet to router */ + rc = SESSION_ROUTE_QUERY(session, read_buffer); } - + /** Routing succeed */ if (rc) { - rc = 0; /**< here '0' means success */ + rc = 0; /**< here '0' means success */ } else { - bool succp; - GWBUF* errbuf; - /** - * Create error to be sent to client if session - * can't be continued. - */ - errbuf = mysql_create_custom_error( - 1, - 0, - "Routing failed. Session is closed."); - /** - * Ensure that there are enough backends - * available. - */ - router->handleError( - router_instance, - session->router_session, - errbuf, - dcb, - ERRACT_NEW_CONNECTION, - &succp); - gwbuf_free(errbuf); - /** - * If there are not enough backends close - * session - */ - if (!succp) - { - LOGIF(LE, (skygw_log_write_flush( - LOGFILE_ERROR, - "Error : Routing the query failed. " - "Session will be closed."))); + bool succp; + GWBUF* errbuf; + /** + * Create error to be sent to client if session + * can't be continued. + */ + errbuf = mysql_create_custom_error( + 1, + 0, + "Routing failed. Session is closed."); + /** + * Ensure that there are enough backends + * available. + */ + router->handleError( + router_instance, + session->router_session, + errbuf, + dcb, + ERRACT_NEW_CONNECTION, + &succp); + gwbuf_free(errbuf); + /** + * If there are not enough backends close + * session + */ + if (!succp) + { + LOGIF(LE, (skygw_log_write_flush( + LOGFILE_ERROR, + "Error : Routing the query failed. " + "Session will be closed."))); - dcb_close(dcb); - } + dcb_close(dcb); + } } - } + } + } + else + { + skygw_log_write_flush(LT,"Session received a query in state %s", + STRSESSIONSTATE(ses_state)); + while((read_buffer = GWBUF_CONSUME_ALL(read_buffer)) != NULL); + goto return_rc; + } goto return_rc; } /* MYSQL_IDLE */ break; diff --git a/server/modules/routing/readconnroute.c b/server/modules/routing/readconnroute.c index b4b080c16..48c78b2e2 100644 --- a/server/modules/routing/readconnroute.c +++ b/server/modules/routing/readconnroute.c @@ -723,16 +723,10 @@ routeQuery(ROUTER *instance, void *router_session, GWBUF *queue) SERVER_IS_DOWN(router_cli_ses->backend->server)) { LOGIF(LT, (skygw_log_write( - LOGFILE_TRACE, + LOGFILE_TRACE|LOGFILE_ERROR, "Error : Failed to route MySQL command %d to backend " - "server.", - mysql_command))); - skygw_log_write( - LOGFILE_ERROR, - "Error : Failed to route MySQL command %d to backend " - "server %s.", - mysql_command, - router_cli_ses->backend->server->unique_name); + "server.%s", + mysql_command,rses_is_closed ? " Session is closed." : ""))); rc = 0; goto return_rc; diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index be2fb68df..b35a674c4 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -3915,7 +3915,7 @@ static GWBUF* sescmd_cursor_clone_querybuf( } ss_dassert(scur->scmd_cur_cmd != NULL); - buf = gwbuf_clone(scur->scmd_cur_cmd->my_sescmd_buf); + buf = gwbuf_clone_all(scur->scmd_cur_cmd->my_sescmd_buf); CHK_GWBUF(buf); return buf; From f7e165612f6d20d4b6f790c33b76432ccce28b05 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 14:40:13 +0300 Subject: [PATCH 18/41] Added Upgrading to 1.2 document. --- Documentation/Upgrading-To-MaxScale-1.2.0.md | 24 ++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 Documentation/Upgrading-To-MaxScale-1.2.0.md diff --git a/Documentation/Upgrading-To-MaxScale-1.2.0.md b/Documentation/Upgrading-To-MaxScale-1.2.0.md new file mode 100644 index 000000000..a48750076 --- /dev/null +++ b/Documentation/Upgrading-To-MaxScale-1.2.0.md @@ -0,0 +1,24 @@ +# Upgrading MaxScale from 1.1 to 1.2 + +This document describes upgrading MaxScale from version 1.1.1 to 1.2 and the major differences in the new version compared to the old version. The major changes can be found in the `Changelog.txt` file in the installation directory and the official release notes in the `ReleaseNotes.txt` file. + +## Installation + +Before starting the upgrade, we recommend you back up your configuration, log and binary log files in `/usr/local/mariadb-maxscale/`. + +Upgrading MaxScale will copy the `MaxScale.cnf` file in `/usr/local/mariadb-maxscale/etc/` to `/etc/` and renamed to `maxscale.cnf`. Binary log files are not automatically copied and should be manually moved from `/usr/local/mariadb-maxscale` to `/var/lib/maxscale/`. + +## File location changes + +MaxScale 1.2 follows the [FHS-standard](http://www.pathname.com/fhs/) and installs to `/usr/` and `/var/` subfolders. Here are the major changes and file locations. + +* Configuration files are located in `/etc/` and use lowercase letters: `/etc/maxscale.cnf` +* Binary files are in `/usr/bin/` +* Libraries and modules are in `/usr/lib64/maxscale/`. If you are using custom modules, please make sure they are in this directory before starting MaxScale. +* Log files are in the `var/log/maxscale/` folder +* MaxScale's PID file is located in `/var/run/maxscale/maxscale.pid` +* Data files and other persistent files are in `/var/lib/maxscale/` + +## Running MaxScale without root permissions + +MaxScale can run as a non-root user with the 1.2 version. RPM and DEB packages install the `maxscale` user and `maxscale` group which are used by the init scripts and systemd configuration files. If you are installing from a binary tarball, you can run the `postinst` script included in it to manually create these groups. From 309e6881688e20a79d0ed054c461f6b30e7530c6 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 15:03:23 +0300 Subject: [PATCH 19/41] Added link to 1.2 upgrade document in Documentation-Contents.md --- Documentation/Documentation-Contents.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index fc51d83ec..f19797d55 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -19,7 +19,8 @@ ## Upgrading MaxScale -- [Upgrading MaxScale to 1.1.0](Upgrading-To-MaxScale-1.1.0.md) +- [Upgrading MaxScale from 1.1.1 to 1.2.0](Upgrading-To-MaxScale-1.2.0.md) +- [Upgrading MaxScale from 1.0.5 to 1.1.0](Upgrading-To-MaxScale-1.1.0.md) ## Reference From 082a78ac3ded5947f2d0af6ca1a6ad7d04099eb4 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 16:02:29 +0300 Subject: [PATCH 20/41] Updated release notes. --- .../MaxScale-1.2.0-Release-Notes.md | 49 +++++++++---------- 1 file changed, 24 insertions(+), 25 deletions(-) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index de4b7a461..c1252a932 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -34,31 +34,30 @@ Now you can configure MaxScale monitor module to automatically launch a script w Here is a list of bugs fixed since the release of MaxScale 1.1.1. -| Key | Summary | -| --- | -------- | -| [MXS-24](https://mariadb.atlassian.net/browse/MXS-24) | bugzillaId-604: Module load path documentation issues ... | -| [MXS-40](https://mariadb.atlassian.net/browse/MXS-40) | Display logged in users | -| [MXS-113](https://mariadb.atlassian.net/browse/MXS-113) | MaxScale seems to fail if built against MariaDB 10.0 libraries | -| [MXS-116](https://mariadb.atlassian.net/browse/MXS-116) | Do not run maxscale as root. | -| [MXS-117](https://mariadb.atlassian.net/browse/MXS-117) | Allow configuration of the log file directory | -| [MXS-125](https://mariadb.atlassian.net/browse/MXS-125) | inconsistency in maxkeys/maxpassword output and parameters | -| [MXS-128](https://mariadb.atlassian.net/browse/MXS-128) | cyclic dependency utils -> log_manager -> utils | -| [MXS-136](https://mariadb.atlassian.net/browse/MXS-136) | Check for MaxScale replication heartbeat table existence before creating | -| [MXS-137](https://mariadb.atlassian.net/browse/MXS-137) | cannot get sql for queries with length >= 0x80 | -| [MXS-139](https://mariadb.atlassian.net/browse/MXS-139) | Schemarouter authentication for wildcard grants fails without optimize_wildcard | -| [MXS-140](https://mariadb.atlassian.net/browse/MXS-140) | strip_db_esc does not work without auth_all_servers | -| [MXS-162](https://mariadb.atlassian.net/browse/MXS-162) | Fix Incorrect info in Configuration Guide | -| [MXS-165](https://mariadb.atlassian.net/browse/MXS-165) | Concurrency issue while incrementing sessions in qlafilter | -| [MXS-166](https://mariadb.atlassian.net/browse/MXS-166) | Memory leak when creating a new event | -| [MXS-171](https://mariadb.atlassian.net/browse/MXS-171) | Allow reads on master for readwritesplit | -| [MXS-176](https://mariadb.atlassian.net/browse/MXS-176) | Missing dependencies in documentation | -| [MXS-180](https://mariadb.atlassian.net/browse/MXS-180) | MariaDB10 binlog router compatibilty | -| [MXS-181](https://mariadb.atlassian.net/browse/MXS-181) | Poor performance on TCP connection due to Nagle's algoritm | -| [MXS-182](https://mariadb.atlassian.net/browse/MXS-182) | SHOW SLAVE STATUS and maxadmin "show services" for binlog router needs updated when used with MariaDB 10 Master | -| [MXS-212](https://mariadb.atlassian.net/browse/MXS-212) | Stopped services accept connections | -| [MXS-225](https://mariadb.atlassian.net/browse/MXS-225) | RPM Debug build packages have no debugging symbols | -| [MXS-227](https://mariadb.atlassian.net/browse/MXS-227) | Memory leak in Galera Monitor | -| [MXS-244](https://mariadb.atlassian.net/browse/MXS-244) | Memory leak when using prepared statements without arguments | + * [MXS-24](https://mariadb.atlassian.net/browse/MXS-24): bugzillaId-604: Module load path documentation issues ... + * [MXS-40](https://mariadb.atlassian.net/browse/MXS-40): Display logged in users + * [MXS-113](https://mariadb.atlassian.net/browse/MXS-113): MaxScale seems to fail if built against MariaDB 10.0 libraries + * [MXS-116](https://mariadb.atlassian.net/browse/MXS-116): Do not run maxscale as root. + * [MXS-117](https://mariadb.atlassian.net/browse/MXS-117): Allow configuration of the log file directory + * [MXS-125](https://mariadb.atlassian.net/browse/MXS-125): inconsistency in maxkeys/maxpassword output and parameters + * [MXS-128](https://mariadb.atlassian.net/browse/MXS-128): cyclic dependency utils -> log_manager -> utils + * [MXS-136](https://mariadb.atlassian.net/browse/MXS-136): Check for MaxScale replication heartbeat table existence before creating + * [MXS-137](https://mariadb.atlassian.net/browse/MXS-137): cannot get sql for queries with length >= 0x80 + * [MXS-139](https://mariadb.atlassian.net/browse/MXS-139): Schemarouter authentication for wildcard grants fails without optimize_wildcard + * [MXS-140](https://mariadb.atlassian.net/browse/MXS-140): strip_db_esc does not work without auth_all_servers + * [MXS-162](https://mariadb.atlassian.net/browse/MXS-162): Fix Incorrect info in Configuration Guide + * [MXS-165](https://mariadb.atlassian.net/browse/MXS-165): Concurrency issue while incrementing sessions in qlafilter + * [MXS-166](https://mariadb.atlassian.net/browse/MXS-166): Memory leak when creating a new event + * [MXS-171](https://mariadb.atlassian.net/browse/MXS-171): Allow reads on master for readwritesplit + * [MXS-176](https://mariadb.atlassian.net/browse/MXS-176): Missing dependencies in documentation + * [MXS-179](https://mariadb.atlassian.net/browse/MXS-179): Keep configuration changes in synch across MaxScale Mate Nodes + * [MXS-180](https://mariadb.atlassian.net/browse/MXS-180): MariaDB10 binlog router compatibilty + * [MXS-181](https://mariadb.atlassian.net/browse/MXS-181): Poor performance on TCP connection due to Nagle's algoritm + * [MXS-182](https://mariadb.atlassian.net/browse/MXS-182): SHOW SLAVE STATUS and maxadmin "show services" for binlog router needs updated when used with MariaDB 10 Master + * [MXS-212](https://mariadb.atlassian.net/browse/MXS-212): Stopped services accept connections + * [MXS-225](https://mariadb.atlassian.net/browse/MXS-225): RPM Debug build packages have no debugging symbols + * [MXS-227](https://mariadb.atlassian.net/browse/MXS-227): Memory leak in Galera Monitor + * [MXS-244](https://mariadb.atlassian.net/browse/MXS-244): Memory leak when using prepared statements without arguments ## Known Issues and Limitations From 72844c9e138ebd6c92785df1ca027f8a21e7af1d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Tue, 7 Jul 2015 16:22:26 +0300 Subject: [PATCH 21/41] Added lsyncd guide to release notes. --- Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index c1252a932..43560ddff 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -30,6 +30,9 @@ MaxScale now supports SSL/TLS encrypted connections to MaxScale. ### Launchable scripts Now you can configure MaxScale monitor module to automatically launch a script when it detects change in the state of a backend server. The script can be any customer script defined by you to take diagnostic or reporting action. With this you can easily customize MaxScale's behavior. +### Lsyncd configuration guide +A new tutorial has beed added which helps you keep MaxScale's configuration files in sync across multiple hosts. This allows for easier HA setups with MaxScale and guarantees up-to-date configuration files on all nodes. The tutorial can be found [here](../Reference/MaxScale-HA-with-lsyncd.md). + ## Bug fixes Here is a list of bugs fixed since the release of MaxScale 1.1.1. From b73aedd0ca9e36474ac6407aeff6fc4ef27b7cb0 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 8 Jul 2015 10:05:15 +0300 Subject: [PATCH 22/41] Fixed debug log not working. --- log_manager/log_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/log_manager/log_manager.cc b/log_manager/log_manager.cc index a87157be7..79c2ace30 100644 --- a/log_manager/log_manager.cc +++ b/log_manager/log_manager.cc @@ -1457,7 +1457,7 @@ int skygw_log_write( * Write log string to buffer and add to file write list. */ - for (i = LOGFILE_FIRST; i Date: Wed, 8 Jul 2015 12:42:48 +0300 Subject: [PATCH 23/41] Added reference to hint document to rwsplit docs. --- Documentation/routers/ReadWriteSplit.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/routers/ReadWriteSplit.md b/Documentation/routers/ReadWriteSplit.md index e58367789..7fb6d5cf0 100644 --- a/Documentation/routers/ReadWriteSplit.md +++ b/Documentation/routers/ReadWriteSplit.md @@ -100,6 +100,10 @@ disable_slave_recovery=true master_accept_reads=true ``` +### Routing hints + +The readwritesplit router supports routing hints. For a detailed guide on hint syntax and functionality, please see [this](../Reference/Hint-Syntax.md) document. + ## Limitations In Master-Slave replication cluster also read-only queries are routed to master too in the following situations: From af2ce0f4f1484cc1367ff86473cbd9824da17baf Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Wed, 8 Jul 2015 12:45:48 +0300 Subject: [PATCH 24/41] Fix to MXS-252: https://mariadb.atlassian.net/browse/MXS-252 Added missing buffer length parameter. --- server/modules/routing/schemarouter/shardrouter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/modules/routing/schemarouter/shardrouter.c b/server/modules/routing/schemarouter/shardrouter.c index 94ab35974..c4148a237 100644 --- a/server/modules/routing/schemarouter/shardrouter.c +++ b/server/modules/routing/schemarouter/shardrouter.c @@ -1701,7 +1701,7 @@ routeQuery(ROUTER* instance, querybuf))) { extract_database(querybuf,db); - snprintf(errbuf,"Unknown database: %s",db); + snprintf(errbuf,25+MYSQL_DATABASE_MAXLEN,"Unknown database: %s",db); create_error_reply(errbuf,router_cli_ses->replydcb); LOGIF(LE, (skygw_log_write_flush( LOGFILE_ERROR, From b0e98bc420e97d71b95e2cafa4ed34f31bc2dff3 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 9 Jul 2015 14:41:23 +0300 Subject: [PATCH 25/41] Added template cnf file to /etc and renamed folders. --- CMakeLists.txt | 3 ++ .../Database-Firewall-Filter.md | 0 .../Query-Log-All-Filter.md | 0 .../RabbitMQ-Consumer-Client.md | 0 .../{filters => Filters}/RabbitMQ-Filter.md | 0 .../{filters => Filters}/Regex-Filter.md | 0 .../{filters => Filters}/Tee-Filter.md | 0 .../{filters => Filters}/Top-N-Filter.md | 0 .../{monitors => Monitors}/Galera-Monitor.md | 0 .../{monitors => Monitors}/MM-Monitor.md | 0 .../{monitors => Monitors}/MySQL-Monitor.md | 0 .../NDB-Cluster-Monitor.md | 0 .../{routers => Routers}/ReadConnRoute.md | 0 .../{routers => Routers}/ReadWriteSplit.md | 0 .../{routers => Routers}/SchemaRouter.md | 0 cmake/macros.cmake | 3 ++ server/maxscale_template.cnf | 41 ++++++++++++------- 17 files changed, 33 insertions(+), 14 deletions(-) rename Documentation/{filters => Filters}/Database-Firewall-Filter.md (100%) rename Documentation/{filters => Filters}/Query-Log-All-Filter.md (100%) rename Documentation/{filters => Filters}/RabbitMQ-Consumer-Client.md (100%) rename Documentation/{filters => Filters}/RabbitMQ-Filter.md (100%) rename Documentation/{filters => Filters}/Regex-Filter.md (100%) rename Documentation/{filters => Filters}/Tee-Filter.md (100%) rename Documentation/{filters => Filters}/Top-N-Filter.md (100%) rename Documentation/{monitors => Monitors}/Galera-Monitor.md (100%) rename Documentation/{monitors => Monitors}/MM-Monitor.md (100%) rename Documentation/{monitors => Monitors}/MySQL-Monitor.md (100%) rename Documentation/{monitors => Monitors}/NDB-Cluster-Monitor.md (100%) rename Documentation/{routers => Routers}/ReadConnRoute.md (100%) rename Documentation/{routers => Routers}/ReadWriteSplit.md (100%) rename Documentation/{routers => Routers}/SchemaRouter.md (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62abd54a7..ef21fa1d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -171,6 +171,9 @@ install(FILES ${CMAKE_BINARY_DIR}/Changelog.txt DESTINATION ${MAXSCALE_SHAREDIR} install(FILES ${CMAKE_BINARY_DIR}/ReleaseNotes.txt DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES ${CMAKE_BINARY_DIR}/UpgradingToMaxScale110.txt DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES server/maxscale_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) +if(WITH_MAXSCALE_CNF) + install(FILES server/maxscale_template.cnf DESTINATION ${MAXSCALE_CONFDIR} RENAME maxscale.cnf) +endif() install(FILES server/maxscale_binlogserver_template.cnf DESTINATION ${MAXSCALE_SHAREDIR}) install(FILES ${ERRMSG} DESTINATION ${MAXSCALE_VARDIR}/lib/maxscale PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/Documentation/filters/Database-Firewall-Filter.md b/Documentation/Filters/Database-Firewall-Filter.md similarity index 100% rename from Documentation/filters/Database-Firewall-Filter.md rename to Documentation/Filters/Database-Firewall-Filter.md diff --git a/Documentation/filters/Query-Log-All-Filter.md b/Documentation/Filters/Query-Log-All-Filter.md similarity index 100% rename from Documentation/filters/Query-Log-All-Filter.md rename to Documentation/Filters/Query-Log-All-Filter.md diff --git a/Documentation/filters/RabbitMQ-Consumer-Client.md b/Documentation/Filters/RabbitMQ-Consumer-Client.md similarity index 100% rename from Documentation/filters/RabbitMQ-Consumer-Client.md rename to Documentation/Filters/RabbitMQ-Consumer-Client.md diff --git a/Documentation/filters/RabbitMQ-Filter.md b/Documentation/Filters/RabbitMQ-Filter.md similarity index 100% rename from Documentation/filters/RabbitMQ-Filter.md rename to Documentation/Filters/RabbitMQ-Filter.md diff --git a/Documentation/filters/Regex-Filter.md b/Documentation/Filters/Regex-Filter.md similarity index 100% rename from Documentation/filters/Regex-Filter.md rename to Documentation/Filters/Regex-Filter.md diff --git a/Documentation/filters/Tee-Filter.md b/Documentation/Filters/Tee-Filter.md similarity index 100% rename from Documentation/filters/Tee-Filter.md rename to Documentation/Filters/Tee-Filter.md diff --git a/Documentation/filters/Top-N-Filter.md b/Documentation/Filters/Top-N-Filter.md similarity index 100% rename from Documentation/filters/Top-N-Filter.md rename to Documentation/Filters/Top-N-Filter.md diff --git a/Documentation/monitors/Galera-Monitor.md b/Documentation/Monitors/Galera-Monitor.md similarity index 100% rename from Documentation/monitors/Galera-Monitor.md rename to Documentation/Monitors/Galera-Monitor.md diff --git a/Documentation/monitors/MM-Monitor.md b/Documentation/Monitors/MM-Monitor.md similarity index 100% rename from Documentation/monitors/MM-Monitor.md rename to Documentation/Monitors/MM-Monitor.md diff --git a/Documentation/monitors/MySQL-Monitor.md b/Documentation/Monitors/MySQL-Monitor.md similarity index 100% rename from Documentation/monitors/MySQL-Monitor.md rename to Documentation/Monitors/MySQL-Monitor.md diff --git a/Documentation/monitors/NDB-Cluster-Monitor.md b/Documentation/Monitors/NDB-Cluster-Monitor.md similarity index 100% rename from Documentation/monitors/NDB-Cluster-Monitor.md rename to Documentation/Monitors/NDB-Cluster-Monitor.md diff --git a/Documentation/routers/ReadConnRoute.md b/Documentation/Routers/ReadConnRoute.md similarity index 100% rename from Documentation/routers/ReadConnRoute.md rename to Documentation/Routers/ReadConnRoute.md diff --git a/Documentation/routers/ReadWriteSplit.md b/Documentation/Routers/ReadWriteSplit.md similarity index 100% rename from Documentation/routers/ReadWriteSplit.md rename to Documentation/Routers/ReadWriteSplit.md diff --git a/Documentation/routers/SchemaRouter.md b/Documentation/Routers/SchemaRouter.md similarity index 100% rename from Documentation/routers/SchemaRouter.md rename to Documentation/Routers/SchemaRouter.md diff --git a/cmake/macros.cmake b/cmake/macros.cmake index d7921f1c4..49f4096dc 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -23,6 +23,9 @@ macro(set_variables) # Use C99 set(USE_C99 FALSE CACHE BOOL "Use C99 standard") + # Install the template maxscale.cnf file + set(WITH_MAXSCALE_CNF TRUE CACHE BOOL "Install the template maxscale.cnf file") + # hostname or IP address of MaxScale's host set(TEST_HOST "127.0.0.1" CACHE STRING "hostname or IP address of MaxScale's host") diff --git a/server/maxscale_template.cnf b/server/maxscale_template.cnf index feec5695d..0928a750d 100644 --- a/server/maxscale_template.cnf +++ b/server/maxscale_template.cnf @@ -128,6 +128,10 @@ module=regexfilter match=fetch replace=select +[hint] +type=filter +module=hintfilter + ## A series of service definition # @@ -218,11 +222,21 @@ router=readwritesplit servers=server1,server2,server3 user=myuser passwd=mypwd -#use_sql_variables_in= -#max_slave_connections=100% +max_slave_connections=100% +#use_sql_variables_in=master #max_slave_replication_lag=21 -#router_options=slave_selection_criteria= -#filters=fetch|qla +#filters=hint|fetch|qla +#router_options=slave_selection_criteria=LEAST_CURRENT_OPERATIONS + +# Uncomment this to disable the saving of session modifying comments. Some scripting +# languages use connection pooling and will use the same session. MaxScale sees them +# as the same session and stores them for the slave recovery process. +#router_options=disable_sescmd_history=true,disable_slave_recovery=true + +# This will allow the master server to be used for read queries. By default +# MaxScale will only use the master for write queries. +#router_options=master_accept_reads=true + [Debug Interface] type=service @@ -265,27 +279,26 @@ service=Read Connection Router protocol=MySQLClient address=192.168.100.102 port=4008 -#socket=/tmp/readconn.sock +socket=/var/lib/maxscale/readconn.sock [RW Split Listener] type=listener service=RW Split Router protocol=MySQLClient port=4006 -#socket=/tmp/rwsplit.sock +#socket=/var/lib/maxscale/rwsplit.sock [Debug Listener] type=listener service=Debug Interface protocol=telnetd -#address=127.0.0.1 +address=127.0.0.1 port=4442 [CLI Listener] type=listener service=CLI protocol=maxscaled -#address=localhost port=6603 ## Definition of the servers @@ -314,18 +327,18 @@ port=6603 [server1] type=server -address=192.168.100.101 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend [server2] type=server -address=192.168.100.102 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend [server3] type=server -address=192.168.100.103 -port=3000 +address=127.0.0.1 +port=3306 protocol=MySQLBackend From 8630e4284c4291e0e6ae4ea028162a86823e7112 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 9 Jul 2015 22:28:24 +0300 Subject: [PATCH 26/41] Fixed broken links. --- Documentation/Documentation-Contents.md | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index f19797d55..20c6e079d 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -47,30 +47,30 @@ ## Routers - - [Read Write Split](routers/ReadWriteSplit.md) - - [Read Connnection Router](routers/ReadConnRoute.md) - - [Schemarouter](routers/SchemaRouter.md) + - [Read Write Split](Routers/ReadWriteSplit.md) + - [Read Connnection Router](Routers/ReadConnRoute.md) + - [Schemarouter](Routers/SchemaRouter.md) ## Filters Here are detailed documents about the filters MaxScale offers. They contain configuration guides and example use cases. Before reading these,you should have read the filter tutorial so that you know how they work and how to configure them. - - [Query Log All](filters/Query-Log-All-Filter.md) - - [Regex Filter](filters/Regex-Filter.md) - - [Tee Filter](filters/Tee-Filter.md) - - [Top N Filter](filters/Top-N-Filter.md) - - [Database Firewall Filter](filters/Database-Firewall-Filter.md) - - [RabbitMQ Filter](filters/RabbitMQ-Filter.md) + - [Query Log All](Filters/Query-Log-All-Filter.md) + - [Regex Filter](Filters/Regex-Filter.md) + - [Tee Filter](Filters/Tee-Filter.md) + - [Top N Filter](Filters/Top-N-Filter.md) + - [Database Firewall Filter](Filters/Database-Firewall-Filter.md) + - [RabbitMQ Filter](Filters/RabbitMQ-Filter.md) ## Monitors - - [MySQL Monitor](monitors/MySQL-Monitor.md) - - [Galera Monitor](monitors/Galera-Monitor.md) - - [Multi-Master Monitor](monitors/MM-Monitor.md) - - [MySQL Cluster Monitor](monitors/NDB-Cluster-Monitor.md) + - [MySQL Monitor](Monitors/MySQL-Monitor.md) + - [Galera Monitor](Monitors/Galera-Monitor.md) + - [Multi-Master Monitor](Monitors/MM-Monitor.md) + - [MySQL Cluster Monitor](Monitors/NDB-Cluster-Monitor.md) ## Utilities - - [RabbitMQ Consumer Client](filters/RabbitMQ-Consumer-Client.md) + - [RabbitMQ Consumer Client](Filters/RabbitMQ-Consumer-Client.md) ## Design Documents From 40d022b667ae90417258d50270cd62570b65fe72 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 9 Jul 2015 23:26:19 +0300 Subject: [PATCH 27/41] Added link to simple sharding tutorial. --- Documentation/Documentation-Contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 20c6e079d..0a892001d 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -44,6 +44,7 @@ - [Replication Proxy with the Binlog Router Tutorial](Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md) - [RabbitMQ Setup and MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md) - [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md) + - [Simple Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md) ## Routers From 7585adb2289610a639f88beb0e48104678830058 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Thu, 9 Jul 2015 23:52:31 +0300 Subject: [PATCH 28/41] Fixed links. --- Documentation/Documentation-Contents.md | 2 +- Documentation/Routers/SchemaRouter.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index 0a892001d..a2f453a7b 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -44,7 +44,7 @@ - [Replication Proxy with the Binlog Router Tutorial](Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md) - [RabbitMQ Setup and MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md) - [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md) - - [Simple Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md) + - [Simple Schema Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md) ## Routers diff --git a/Documentation/Routers/SchemaRouter.md b/Documentation/Routers/SchemaRouter.md index d1de66b2b..55c3ad706 100644 --- a/Documentation/Routers/SchemaRouter.md +++ b/Documentation/Routers/SchemaRouter.md @@ -64,4 +64,4 @@ The schemarouter router currently has some limitations due to the nature of the ## Examples -[Here](../../Tutorials/Simple-Sharding-Tutorial.md) is a small tutorial on how to set up a sharded database. +[Here](../Tutorials/Simple-Sharding-Tutorial.md) is a small tutorial on how to set up a sharded database. From 1ca1a25e235e37553531323954a0956ca15f0d7a Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 13:01:56 +0300 Subject: [PATCH 29/41] Updated the getting started document. --- .../Getting-Started-With-MaxScale.md | 16 +++++++--------- .../Getting-Started/images/getting_started.png | Bin 0 -> 73575 bytes .../Getting-Started/images/getting_started2.png | Bin 0 -> 74584 bytes 3 files changed, 7 insertions(+), 9 deletions(-) create mode 100644 Documentation/Getting-Started/images/getting_started.png create mode 100644 Documentation/Getting-Started/images/getting_started2.png diff --git a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md index 344ac500d..0193fc08f 100644 --- a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md +++ b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md @@ -8,21 +8,19 @@ In this introduction to MaxScale the aim is to take the reader from the point of The simplest way to install MaxScale is to use one of the binary packages that are available for download from the MariaDB website. -* Simply go to [www.mariadb.com](http://www.mariadb.com) +* Simply go to [https://mariadb.com/resources/downloads](https://mariadb.com/resources/downloads) -* Select the Downloads option from the Resources menu +* Find and Click on the button "Download MariaDB MaxScale Binaries" inder the MaxScale section -* Find and click on the button "Download MariaDB MaxScale Binaries" +* Sign in to MariaDB.com -* Find the section on that page entitled MariaDB MaxScale +* Follow the instructions at the top of the page. -* Select your operating system from the drop down box +![image alt text](images/getting_started.png) -* Instructions that are specific for your operating system will then appear +If you want to install only MaxScale, futher down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distriution specific instructions. -![image alt text](images/image_1.png) - -* Follow these instructions to install MaxScale on your machine +![image alt text](images/getting_started2.png) Upon successful completion of the installation process you have a version of MaxScale that is missing only a configuration file before it can be started. diff --git a/Documentation/Getting-Started/images/getting_started.png b/Documentation/Getting-Started/images/getting_started.png new file mode 100644 index 0000000000000000000000000000000000000000..d90c3a2dd70b37cffcf959a880143a00d93cf6c0 GIT binary patch literal 73575 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 RA!CrsJzf1=);T3K0RTFAWOD!j literal 0 HcmV?d00001 diff --git a/Documentation/Getting-Started/images/getting_started2.png b/Documentation/Getting-Started/images/getting_started2.png new file mode 100644 index 0000000000000000000000000000000000000000..bac4926a5136e056258e87c5c55f3eb72f52948d GIT binary patch literal 74584 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 z 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 literal 0 HcmV?d00001 From a27289ca48bda6aedb6c86e2c5937ae13a9c23b1 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 13:23:08 +0300 Subject: [PATCH 30/41] Fixed typo. --- Documentation/Getting-Started/Getting-Started-With-MaxScale.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md index 0193fc08f..a965482ac 100644 --- a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md +++ b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md @@ -18,7 +18,7 @@ The simplest way to install MaxScale is to use one of the binary packages that a ![image alt text](images/getting_started.png) -If you want to install only MaxScale, futher down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distriution specific instructions. +If you want to install only MaxScale, futher down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distribution specific instructions. ![image alt text](images/getting_started2.png) From af6e010ba19302b36a0661c5ebc3c5eafe21685c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 13:51:32 +0300 Subject: [PATCH 31/41] Added missing namedserverfilter documentation. --- Documentation/Filters/Named-Server-Filter.md | 92 ++++++++++++++++++++ server/modules/filter/namedserverfilter.c | 2 +- 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 Documentation/Filters/Named-Server-Filter.md diff --git a/Documentation/Filters/Named-Server-Filter.md b/Documentation/Filters/Named-Server-Filter.md new file mode 100644 index 000000000..3e41092de --- /dev/null +++ b/Documentation/Filters/Named-Server-Filter.md @@ -0,0 +1,92 @@ +Named Server Filter + +# Overview + +The **namedserverfilter** is a filter module for MaxScale which is able to route queries to servers based on regular expression matches. + +# Configuration + +The configuration block for the Named Server filter requires the minimal filter options in it’s section within the maxscale.cnf file, stored in /etc/maxscale.cnf. + +``` +[NamedServerFilter] +type=filter +module=namedserverfilter +match=some string +server=server2 + +[MyService] +type=service +router=readwritesplit +servers=server1,server2 +user=myuser +passwd=mypasswd +filters=NamedServerFilter +``` + +## Filter Options + +The named server filter accepts the options ignorecase or case. These define if the pattern text should take the case of the string it is matching against into consideration or not. + +## Filter Parameters + +The named server filter requires two mandatory parameters to be defined. + +### `match` + +A parameter that can be used to match text in the SQL statement which should be replaced. + +``` +match=TYPE[ ]*= +``` + +If the filter option ignorecase is used all regular expressions are evaluated with the option to ignore the case of the text, therefore a match option of select will match both type, TYPE and any form of the word with upper or lowercase characters. + +### `server` + +This is the server where matching queries will be router. The server should be in use by the service which uses this filter. + +``` +server=server2 +``` + +### `source` + +The optional source parameter defines an address that is used to match against the address from which the client connection to MaxScale originates. Only sessions that originate from this address will have the match and replacement applied to them. + +``` +source=127.0.0.1 +``` + +### `user` + +The optional user parameter defines a user name that is used to match against the user from which the client connection to MaxScale originates. Only sessions that are connected using this username will have the match and replacement applied to them. + +``` +user=john +``` + +## Examples + +### Example 1 - Route queries targeting a specific table to a server + +This will route all queries matching the regular expression ` *from *users` to the server named *server2*. The filter will ignore character case in queries. + +A query like `SELECT * FROM users` would be routed to server2 where as a query like `SELECT * FROM accounts` would be routed according to the normal rules of the router. + +``` +[NamedServerFilter] +type=filter +module=namedserverfilter +match= *from *users +options=ignorecase +server=server2 + +[MyService] +type=service +router=readwritesplit +servers=server1,server2 +user=myuser +passwd=mypasswd +filters=NamedServerFilter +``` diff --git a/server/modules/filter/namedserverfilter.c b/server/modules/filter/namedserverfilter.c index b7a5b91c1..822b5eaf2 100644 --- a/server/modules/filter/namedserverfilter.c +++ b/server/modules/filter/namedserverfilter.c @@ -35,7 +35,7 @@ extern __thread log_info_t tls_log_info; * that routes to a named server if a regular expression match is found. * @verbatim * - * A simple regular expression query rewrite filter. + * A simple regular expression based query routing filter. * Two parameters should be defined in the filter configuration * match= * server= From 8fb2cf7064a3159fd4ef9b1ed7b88c17650b546c Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 13:52:42 +0300 Subject: [PATCH 32/41] Added missing link --- Documentation/Documentation-Contents.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index a2f453a7b..fd13f3bf1 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -62,6 +62,7 @@ Here are detailed documents about the filters MaxScale offers. They contain conf - [Top N Filter](Filters/Top-N-Filter.md) - [Database Firewall Filter](Filters/Database-Firewall-Filter.md) - [RabbitMQ Filter](Filters/RabbitMQ-Filter.md) + - [Named Server Filter](Filters/Named-Server-Filter.md) ## Monitors - [MySQL Monitor](Monitors/MySQL-Monitor.md) From d97011c23eca0c3082e554a70b7a9be7fc56d1fa Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 14:18:20 +0300 Subject: [PATCH 33/41] Moved password encryption from configuration guide to getting started. --- .../Getting-Started/Configuration-Guide.md | 31 ------------- .../Getting-Started-With-MaxScale.md | 46 ++++++++++++++++++- 2 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Documentation/Getting-Started/Configuration-Guide.md b/Documentation/Getting-Started/Configuration-Guide.md index c2f815d09..df49a03eb 100644 --- a/Documentation/Getting-Started/Configuration-Guide.md +++ b/Documentation/Getting-Started/Configuration-Guide.md @@ -1390,37 +1390,6 @@ count=10 In addition parameters may be added to define patterns to match against to either include or exclude particular SQL statements to be duplicated. You may also define that the filter is only active for connections from a particular source or when a particular user is connected. -## Encrypting Passwords - -Passwords stored in the maxscale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key. The default location MaxScale stores the keys is `/var/lib/maxscale`. - -``` - # Usage: maxkeys [PATH] -maxkeys /var/lib/maxscale/ -``` - -Changing the encryption key for MaxScale will invalidate any currently encrypted keys stored in the maxscale.cnf file. - -### Creating Encrypted Passwords - -Encrypted passwords are created by executing the maxpasswd command with the location of the .secrets file and the password you require to encrypt as an argument. - -``` -# Usage: maxpasswd PATH PASSWORD -maxpasswd /var/lib/maxscale/ MaxScalePw001 -61DD955512C39A4A8BC4BB1E5F116705 -``` - -The output of the maxpasswd command is a hexadecimal string, this should be inserted into the maxscale.cnf file in place of the ordinary, plain text, password. MaxScale will determine this as an encrypted password and automatically decrypt it before sending it the database server. - -``` -[Split Service] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -user=maxscale -password=61DD955512C39A4A8BC4BB1E5F116705 -``` ## Reloading Configuration diff --git a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md index a965482ac..56393415a 100644 --- a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md +++ b/Documentation/Getting-Started/Getting-Started-With-MaxScale.md @@ -22,7 +22,19 @@ If you want to install only MaxScale, futher down you will find the product spec ![image alt text](images/getting_started2.png) -Upon successful completion of the installation process you have a version of MaxScale that is missing only a configuration file before it can be started. +After you have installed MaxScale, you can start it. + +``` +systemctl start maxscale.service +``` + +If your system does not support systemd you can start MaxScale using the installed init.d script. + +``` +service maxscale start +``` + +An example configuration file is installed into the `/etc/` folder. This file should be changed according to your needs. ## Building MaxScale From Source Code @@ -52,6 +64,38 @@ It is also possible to use the Read/Write Splitter with Galera. Although it is n As well as the four major configuration choices outlined above there are also other configurations sub-options that may be mixed with those to provide a variety of different configuration and functionality. The MaxScale filter concept allows the basic configurations to be built upon in a large variety of ways. A separate filter tutorial is available that discusses the concept and gives some examples of ways to use filters. +## Encrypting Passwords + +Passwords stored in the maxscale.cnf file may optionally be encrypted for added security. This is done by creation of an encryption key on installation of MaxScale. Encryption keys may be created manually by executing the maxkeys utility with the argument of the filename to store the key. The default location MaxScale stores the keys is `/var/lib/maxscale`. + +``` + # Usage: maxkeys [PATH] +maxkeys /var/lib/maxscale/ +``` + +Changing the encryption key for MaxScale will invalidate any currently encrypted keys stored in the maxscale.cnf file. + +### Creating Encrypted Passwords + +Encrypted passwords are created by executing the maxpasswd command with the location of the .secrets file and the password you require to encrypt as an argument. + +``` +# Usage: maxpasswd PATH PASSWORD +maxpasswd /var/lib/maxscale/ MaxScalePw001 +61DD955512C39A4A8BC4BB1E5F116705 +``` + +The output of the maxpasswd command is a hexadecimal string, this should be inserted into the maxscale.cnf file in place of the ordinary, plain text, password. MaxScale will determine this as an encrypted password and automatically decrypt it before sending it the database server. + +``` +[Split Service] +type=service +router=readwritesplit +servers=server1,server2,server3,server4 +user=maxscale +password=61DD955512C39A4A8BC4BB1E5F116705 +``` + ## Running MaxScale MaxScale consists of a core executable and a number of modules that implement From f095ec353c806090690320c7e6093b63504c6bb4 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 21:31:33 +0300 Subject: [PATCH 34/41] Fixed config file being installed into /usr/etc instead of /etc. --- cmake/install_layout.cmake | 5 ++--- server/core/adminusers.c | 4 +++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index e25bd0a8d..a14ef05c5 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -5,8 +5,7 @@ set(MAXSCALE_LIBDIR ${CMAKE_INSTALL_LIBDIR}/maxscale CACHE PATH "Library install set(MAXSCALE_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Executable installation path") set(MAXSCALE_SHAREDIR ${CMAKE_INSTALL_DATADIR}/maxscale CACHE PATH "Share file installation path, includes licence and readme files") set(MAXSCALE_DOCDIR ${CMAKE_INSTALL_DOCDIR}/maxscale CACHE PATH "Documentation installation path, text versions only") -set(MAXSCALE_CONFDIR ${CMAKE_INSTALL_SYSCONFDIR} CACHE PATH "Configuration file installation path, this is not usually needed") -# This is the only hard-coded absolute path +# These are the only hard-coded absolute paths set(MAXSCALE_VARDIR /var CACHE PATH "Data file path (usually /var/)") - +set(MAXSCALE_CONFDIR /etc CACHE PATH "Configuration file installation path (/etc/)") diff --git a/server/core/adminusers.c b/server/core/adminusers.c index 53734e9cc..4b3f9af21 100644 --- a/server/core/adminusers.c +++ b/server/core/adminusers.c @@ -19,7 +19,9 @@ #include #include #include -#define _XOPEN_SOURCE +#ifndef _XOPEN_SOURCE +#define _XOPEN_SOURCE 700 +#endif #include #include #include From a6b35af9f6f8af372062c1922b00bdbf0c82e10d Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Fri, 10 Jul 2015 22:23:10 +0300 Subject: [PATCH 35/41] Fixed release note titles. --- Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md | 2 +- Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md | 4 ++-- Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md | 2 +- 11 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md index 3ae56ce9e..5f09d7bfd 100644 --- a/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.5-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.5 Alpha Release Notes 0.5 Alpha diff --git a/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md index ff7033e4d..4b2c445c3 100644 --- a/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.6-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.6 Alpha Release Notes 0.6 Alpha diff --git a/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md b/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md index bc43ee00d..21d9320ec 100644 --- a/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-0.7-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 0.7 Alpha Release Notes 0.7 Alpha diff --git a/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md index a15757e0f..4ce52f6c3 100644 --- a/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0 Beta Release Notes 1.0 Beta diff --git a/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md index a82083ac9..5586696a4 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.1-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0.1 Beta Release Notes 1.0.1 Beta diff --git a/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md index 67c5e3ece..db8329366 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.3-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes +# MariaDB MaxScale 1.0.3 Release Notes 1.0.3 GA diff --git a/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md index db341e893..9103c830a 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.4-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.0.4 Release Notes 1.0.4 GA diff --git a/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md index 4b65fd92f..e979ff6c1 100644 --- a/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.0.5-Release-Notes.md @@ -1,4 +1,4 @@ -MaxScale Release Notes 1.0.5 GA +# MariaDB MaxScale 1.0.5 Release Notes This document details the changes in version 1.0.5 since the release of the 1.0.4 GA of the MaxScale product. diff --git a/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md index c3ed66b73..e196335b9 100644 --- a/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.1-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.1 Release Notes ## 1.1 GA diff --git a/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md index 6c1631d4c..689323543 100644 --- a/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.1.1-Release-Notes.md @@ -1,6 +1,6 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.1.1 Release Notes -## 1.1 GA +## 1.1.1 GA This document details the changes in version 1.1.1 since the release of the 1.1 GA Release of the MaxScale product. diff --git a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md index 43560ddff..4ffdcba1f 100644 --- a/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-1.2.0-Release-Notes.md @@ -1,4 +1,4 @@ -# MaxScale Release Notes +# MariaDB MaxScale 1.2 Release Notes ## 1.2 GA From ed5ee2d58659ca840ce07ab46fa9e2e082addb75 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Sun, 12 Jul 2015 22:59:19 +0300 Subject: [PATCH 36/41] Updated documents. --- Documentation/Documentation-Contents.md | 2 +- ...axScale.md => MariaDB-MaxScale-Installation-Guide.md} | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) rename Documentation/Getting-Started/{Getting-Started-With-MaxScale.md => MariaDB-MaxScale-Installation-Guide.md} (95%) diff --git a/Documentation/Documentation-Contents.md b/Documentation/Documentation-Contents.md index fd13f3bf1..a7a92d999 100644 --- a/Documentation/Documentation-Contents.md +++ b/Documentation/Documentation-Contents.md @@ -13,7 +13,7 @@ ## Getting Started - - [Getting Started with MaxScale](Getting-Started/Getting-Started-With-MaxScale.md) + - [MariaDB MaxScale Installation Guide](Getting-Started/MariaDB-MaxScale-Installation-Guide.md) - [Building MaxScale from Source Code](Getting-Started/Building-MaxScale-from-Source-Code.md) - [Configuration Guide](Getting-Started/Configuration-Guide.md) diff --git a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md similarity index 95% rename from Documentation/Getting-Started/Getting-Started-With-MaxScale.md rename to Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md index 56393415a..5bf239df8 100644 --- a/Documentation/Getting-Started/Getting-Started-With-MaxScale.md +++ b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md @@ -8,9 +8,7 @@ In this introduction to MaxScale the aim is to take the reader from the point of The simplest way to install MaxScale is to use one of the binary packages that are available for download from the MariaDB website. -* Simply go to [https://mariadb.com/resources/downloads](https://mariadb.com/resources/downloads) - -* Find and Click on the button "Download MariaDB MaxScale Binaries" inder the MaxScale section +* Simply go to [http://www.mariadb.com/my_portal/download](http://www.mariadb.com/my_portal/download) * Sign in to MariaDB.com @@ -44,6 +42,8 @@ Alternatively you may download the MaxScale source and build your own binaries. The first step in configuring your MaxScale is to determine what it is you want to achieve with your MaxScale and what environment it will run in. The later is probably the easiest starting point for choosing which configuration route you wish to take. There are two distinct database environments which the first GA release of MaxScale supports; MySQL Master/Slave Replication clusters and Galera Cluster. +For more details, refer to the [Configuration Guide](Configuration-Guide.md). + ### Master/Slave Replication Clusters There are two major configuration options available to use MaxScale with a MySQL Replication cluster; connection routing with separate read and write connections, or read/write splitting with a single connection. A separate tutorial is available for each of these configurations that describes how to build the configuration file for MaxScale that will work with your environment. @@ -111,5 +111,4 @@ Configuration is read by default from the file /etc/maxscale.cnf. An example fil ## Administration Of MaxScale -There are various administration tasks that may be done with MaxScale, a client command, maxadmin, is available that will interact with a running MaxScale and allow the status of MaxScale to be monitored and give some control of the MaxScale functionality. There is a separate reference guide for the maxadmin utility and also a short administration tutorial that covers the common administration tasks that need to be done with MaxScale. - +There are various administration tasks that may be done with MaxScale, a client command, maxadmin, is available that will interact with a running MaxScale and allow the status of MaxScale to be monitored and give some control of the MaxScale functionality. There is [a separate reference guide](../Reference/MaxAdmin.md) for the maxadmin utility and also [a short administration tutorial](../Tutorials/Administration-Tutorial.md) that covers the common administration tasks that need to be done with MaxScale. From ff3c9b94cb8481d8e06fde5b04e74c39890614f1 Mon Sep 17 00:00:00 2001 From: Timofey Turenko Date: Mon, 13 Jul 2015 09:11:38 +0300 Subject: [PATCH 37/41] Add architecture and distro name to package name --- CMakeLists.txt | 3 ++- cmake/package_rpm.cmake | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef21fa1d3..a43e527bc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -219,6 +219,7 @@ endif() # Only do packaging if configured if(PACKAGE) + execute_process(COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE) # Install the files copied by the postinst script into the share folder install(FILES ${CMAKE_BINARY_DIR}/maxscale DESTINATION ${MAXSCALE_SHAREDIR} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) @@ -239,7 +240,7 @@ if(PACKAGE) set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") - set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") + set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}-${DISTRIB_SUFFIX}") set(CPACK_PACKAGE_NAME "maxscale") set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) diff --git a/cmake/package_rpm.cmake b/cmake/package_rpm.cmake index 0f65bcdd2..05e09c57f 100644 --- a/cmake/package_rpm.cmake +++ b/cmake/package_rpm.cmake @@ -5,7 +5,7 @@ set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}") set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") -set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") +set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}-${CPACK_PACKAGE_ARCHITECTURE}-${DISTRIB_SUFFIX}") set(CPACK_PACKAGE_NAME "maxscale") set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) From 05fad5685303716f5fcef522cb1749c93462dfe0 Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 13 Jul 2015 12:50:48 +0300 Subject: [PATCH 38/41] Fixed DEB packages not being build if both rpmbuild and dpkg-buildpackage are found. --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef21fa1d3..b5f601768 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -253,7 +253,8 @@ if(PACKAGE) if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) include(cmake/package_rpm.cmake) message(STATUS "Generating RPM packages") - elseif(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) + endif() + if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) include(cmake/package_deb.cmake) message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") endif() From 9728ec6169a397fe78c7d53a84825e3247ea0d7a Mon Sep 17 00:00:00 2001 From: MassimilianoPinto Date: Fri, 12 Jun 2015 19:05:48 +0200 Subject: [PATCH 39/41] Addition of new mariadb10 events to diagnostics() Addition of new mariadb10 events to diagnostics() --- server/modules/include/blr.h | 135 ++++++++++++--------- server/modules/routing/binlog/blr.c | 39 +++++- server/modules/routing/binlog/blr_master.c | 6 +- 3 files changed, 116 insertions(+), 64 deletions(-) diff --git a/server/modules/include/blr.h b/server/modules/include/blr.h index 6f6d61fb6..5c1270633 100644 --- a/server/modules/include/blr.h +++ b/server/modules/include/blr.h @@ -26,7 +26,8 @@ * * Date Who Description * 02/04/14 Mark Riddoch Initial implementation - * 11/05/15 Massimilaino Pinto Added mariadb10_compat to master and slave structs + * 11/05/15 Massimiliano Pinto Added mariadb10_compat to master and slave structs + * 12/06/15 Massimiliano Pinto Added mariadb10 new events * * @endverbatim */ @@ -45,7 +46,77 @@ #define BINLOG_EVENT_HDR_LEN 19 -/* How often to call the binlog status function (seconds) */ +/** + * Binlog event types + */ +#define START_EVENT_V3 0x01 +#define QUERY_EVENT 0x02 +#define STOP_EVENT 0x03 +#define ROTATE_EVENT 0x04 +#define INTVAR_EVENT 0x05 +#define LOAD_EVENT 0x06 +#define SLAVE_EVENT 0x07 +#define CREATE_FILE_EVENT 0x08 +#define APPEND_BLOCK_EVENT 0x09 +#define EXEC_LOAD_EVENT 0x0A +#define DELETE_FILE_EVENT 0x0B +#define NEW_LOAD_EVENT 0x0C +#define RAND_EVENT 0x0D +#define USER_VAR_EVENT 0x0E +#define FORMAT_DESCRIPTION_EVENT 0x0F +#define XID_EVENT 0x10 +#define BEGIN_LOAD_QUERY_EVENT 0x11 +#define EXECUTE_LOAD_QUERY_EVENT 0x12 +#define TABLE_MAP_EVENT 0x13 +#define WRITE_ROWS_EVENTv0 0x14 +#define UPDATE_ROWS_EVENTv0 0x15 +#define DELETE_ROWS_EVENTv0 0x16 +#define WRITE_ROWS_EVENTv1 0x17 +#define UPDATE_ROWS_EVENTv1 0x18 +#define DELETE_ROWS_EVENTv1 0x19 +#define INCIDENT_EVENT 0x1A +#define HEARTBEAT_EVENT 0x1B +#define IGNORABLE_EVENT 0x1C +#define ROWS_QUERY_EVENT 0x1D +#define WRITE_ROWS_EVENTv2 0x1E +#define UPDATE_ROWS_EVENTv2 0x1F +#define DELETE_ROWS_EVENTv2 0x20 +#define GTID_EVENT 0x21 +#define ANONYMOUS_GTID_EVENT 0x22 +#define PREVIOUS_GTIDS_EVENT 0x23 + +#define MAX_EVENT_TYPE 0x23 + +/* New MariaDB event numbers start from 0xa0 */ +#define MARIADB_NEW_EVENTS_BEGIN 0xa0 +#define MARIADB_ANNOTATE_ROWS_EVENT 0xa0 +/* New MariaDB 10 event numbers start from here */ +#define MARIADB10_BINLOG_CHECKPOINT_EVENT 0xa1 +#define MARIADB10_GTID_EVENT 0xa2 +#define MARIADB10_GTID_GTID_LIST_EVENT 0xa3 + +#define MAX_EVENT_TYPE_MARIADB10 0xa3 + +/* Maximum event type so far */ +#define MAX_EVENT_TYPE_END MAX_EVENT_TYPE_MARIADB10 + +/** + * Binlog event flags + */ +#define LOG_EVENT_BINLOG_IN_USE_F 0x0001 +#define LOG_EVENT_FORCED_ROTATE_F 0x0002 +#define LOG_EVENT_THREAD_SPECIFIC_F 0x0004 +#define LOG_EVENT_SUPPRESS_USE_F 0x0008 +#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x0010 +#define LOG_EVENT_ARTIFICIAL_F 0x0020 +#define LOG_EVENT_RELAY_LOG_F 0x0040 +#define LOG_EVENT_IGNORABLE_F 0x0080 +#define LOG_EVENT_NO_FILTER_F 0x0100 +#define LOG_EVENT_MTS_ISOLATE_F 0x0200 + +/** + * How often to call the binlog status function (seconds) + */ #define BLR_STATS_FREQ 60 #define BLR_NSTATS_MINUTES 30 @@ -212,7 +283,7 @@ typedef struct { uint64_t n_fakeevents; /*< Fake events not written to disk */ uint64_t n_artificial; /*< Artificial events not written to disk */ int n_badcrc; /*< No. of bad CRC's from master */ - uint64_t events[0x24]; /*< Per event counters */ + uint64_t events[MAX_EVENT_TYPE_END + 1]; /*< Per event counters */ uint64_t lastsample; int minno; int minavgs[BLR_NSTATS_MINUTES]; @@ -327,7 +398,7 @@ static char *blrm_states[] = { "Unconnected", "Connecting", "Authenticated", "Ti "binlog checksum rerieval", "GTID Mode retrieval", "Master UUID retrieval", "Set Slave UUID", "Set Names latin1", "Set Names utf8", "select 1", "select version()", "select @@version_comment", "select @@hostname", - "select @@mx_allowed_packet", "Register slave", "Binlog Dump", "Set MariaDB slave capability" }; + "select @@max_allowed_packet", "Register slave", "Binlog Dump", "Set MariaDB slave capability" }; #define BLRS_CREATED 0x0000 #define BLRS_UNREGISTERED 0x0001 @@ -361,62 +432,6 @@ static char *blrs_states[] = { "Created", "Unregistered", "Registered", #define COM_REGISTER_SLAVE 0x15 #define COM_BINLOG_DUMP 0x12 -/** - * Binlog event types - */ -#define START_EVENT_V3 0x01 -#define QUERY_EVENT 0x02 -#define STOP_EVENT 0x03 -#define ROTATE_EVENT 0x04 -#define INTVAR_EVENT 0x05 -#define LOAD_EVENT 0x06 -#define SLAVE_EVENT 0x07 -#define CREATE_FILE_EVENT 0x08 -#define APPEND_BLOCK_EVENT 0x09 -#define EXEC_LOAD_EVENT 0x0A -#define DELETE_FILE_EVENT 0x0B -#define NEW_LOAD_EVENT 0x0C -#define RAND_EVENT 0x0D -#define USER_VAR_EVENT 0x0E -#define FORMAT_DESCRIPTION_EVENT 0x0F -#define XID_EVENT 0x10 -#define BEGIN_LOAD_QUERY_EVENT 0x11 -#define EXECUTE_LOAD_QUERY_EVENT 0x12 -#define TABLE_MAP_EVENT 0x13 -#define WRITE_ROWS_EVENTv0 0x14 -#define UPDATE_ROWS_EVENTv0 0x15 -#define DELETE_ROWS_EVENTv0 0x16 -#define WRITE_ROWS_EVENTv1 0x17 -#define UPDATE_ROWS_EVENTv1 0x18 -#define DELETE_ROWS_EVENTv1 0x19 -#define INCIDENT_EVENT 0x1A -#define HEARTBEAT_EVENT 0x1B -#define IGNORABLE_EVENT 0x1C -#define ROWS_QUERY_EVENT 0x1D -#define WRITE_ROWS_EVENTv2 0x1E -#define UPDATE_ROWS_EVENTv2 0x1F -#define DELETE_ROWS_EVENTv2 0x20 -#define GTID_EVENT 0x21 -#define ANONYMOUS_GTID_EVENT 0x22 -#define PREVIOUS_GTIDS_EVENT 0x23 - -#define MAX_EVENT_TYPE 0x23 -#define MAX_EVENT_TYPE_MARIADB10 0xa3 - -/** - * Binlog event flags - */ -#define LOG_EVENT_BINLOG_IN_USE_F 0x0001 -#define LOG_EVENT_FORCED_ROTATE_F 0x0002 -#define LOG_EVENT_THREAD_SPECIFIC_F 0x0004 -#define LOG_EVENT_SUPPRESS_USE_F 0x0008 -#define LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F 0x0010 -#define LOG_EVENT_ARTIFICIAL_F 0x0020 -#define LOG_EVENT_RELAY_LOG_F 0x0040 -#define LOG_EVENT_IGNORABLE_F 0x0080 -#define LOG_EVENT_NO_FILTER_F 0x0100 -#define LOG_EVENT_MTS_ISOLATE_F 0x0200 - /** * Macros to extract common fields */ diff --git a/server/modules/routing/binlog/blr.c b/server/modules/routing/binlog/blr.c index 8dce5ea58..7eac9e739 100644 --- a/server/modules/routing/binlog/blr.c +++ b/server/modules/routing/binlog/blr.c @@ -36,6 +36,7 @@ * 17/02/2015 Massimiliano Pinto Addition of slave port and username in diagnostics * 18/02/2015 Massimiliano Pinto Addition of dcb_close in closeSession * 07/05/2015 Massimiliano Pinto Addition of MariaDB 10 compatibility support + * 12/06/2015 Massimiliano Pinto Addition of MariaDB 10 events in diagnostics() * * @endverbatim @@ -682,6 +683,15 @@ static char *event_names[] = { "Anonymous GTID Event", "Previous GTIDS Event" }; +/* New MariaDB event numbers starts from 0xa0 */ +static char *event_names_mariadb10[] = { + "Annotate Rows Event", + /* New MariaDB 10.x event numbers */ + "Binlog Checkpoint Event", + "GTID Event", + "GTID List Event" +}; + /** * Display an entry from the spinlock statistics data * @@ -798,11 +808,28 @@ struct tm tm; buf); dcb_printf(dcb, "\t (%d seconds ago)\n", time(0) - router_inst->stats.lastReply); - dcb_printf(dcb, "\tLast event from master: 0x%x, %s", + + if (!router_inst->mariadb10_compat) { + dcb_printf(dcb, "\tLast event from master: 0x%x, %s", router_inst->lastEventReceived, (router_inst->lastEventReceived >= 0 && - router_inst->lastEventReceived < 0x24) ? + router_inst->lastEventReceived <= MAX_EVENT_TYPE) ? event_names[router_inst->lastEventReceived] : "unknown"); + } else { + char *ptr = NULL; + if (router_inst->lastEventReceived >= 0 && router_inst->lastEventReceived <= MAX_EVENT_TYPE) { + ptr = event_names[router_inst->lastEventReceived]; + } else { + /* Check MariaDB 10 new events */ + if (router_inst->lastEventReceived >= MARIADB_NEW_EVENTS_BEGIN && router_inst->lastEventReceived <= MAX_EVENT_TYPE_MARIADB10) { + ptr = event_names_mariadb10[(router_inst->lastEventReceived - MARIADB_NEW_EVENTS_BEGIN)]; + } + } + + dcb_printf(dcb, "\tLast event from master: 0x%x, %s", + router_inst->lastEventReceived, (ptr != NULL) ? ptr : "unknown"); + } + if (router_inst->lastEventTimestamp) { localtime_r(&router_inst->lastEventTimestamp, &tm); @@ -815,11 +842,17 @@ struct tm tm; if (router_inst->reconnect_pending) dcb_printf(dcb, "\tRouter pending reconnect to master\n"); dcb_printf(dcb, "\tEvents received:\n"); - for (i = 0; i < 0x24; i++) + for (i = 0; i <= MAX_EVENT_TYPE; i++) { dcb_printf(dcb, "\t\t%-38s %u\n", event_names[i], router_inst->stats.events[i]); } + if (router_inst->mariadb10_compat) { + /* Display MariaDB 10 new events */ + for (i = MARIADB_NEW_EVENTS_BEGIN; i <= MAX_EVENT_TYPE_MARIADB10; i++) + dcb_printf(dcb, "\t\tMariaDB 10 %-38s %u\n", event_names_mariadb10[(i - MARIADB_NEW_EVENTS_BEGIN)], router_inst->stats.events[i]); + } + #if SPINLOCK_PROFILE dcb_printf(dcb, "\tSpinlock statistics (instlock):\n"); spinlock_stats(&instlock, spin_reporter, dcb); diff --git a/server/modules/routing/binlog/blr_master.c b/server/modules/routing/binlog/blr_master.c index 3a0519108..86bee0b6b 100644 --- a/server/modules/routing/binlog/blr_master.c +++ b/server/modules/routing/binlog/blr_master.c @@ -917,6 +917,7 @@ static REP_HEADER phdr; phdr = hdr; if (hdr.ok == 0) { + int event_limit; /* * First check that the checksum we calculate matches the * checksum in the packet we received. @@ -957,8 +958,11 @@ static REP_HEADER phdr; #ifdef SHOW_EVENTS printf("blr: event type 0x%02x, flags 0x%04x, event size %d", hdr.event_type, hdr.flags, hdr.event_size); #endif - if (hdr.event_type >= 0 && hdr.event_type < 0x24) + event_limit = router->mariadb10_compat ? MAX_EVENT_TYPE_MARIADB10 : MAX_EVENT_TYPE; + + if (hdr.event_type >= 0 && hdr.event_type <= event_limit) router->stats.events[hdr.event_type]++; + if (hdr.event_type == FORMAT_DESCRIPTION_EVENT && hdr.next_pos == 0) { // Fake format description message From 38b51665430d5501e3e0df791b60e1a88fc879bc Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 13 Jul 2015 13:03:15 +0300 Subject: [PATCH 40/41] fixed double definition of CMake variables. --- CMakeLists.txt | 2 +- cmake/package_rpm.cmake | 10 ---------- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b5f601768..ee0d8523c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -270,7 +270,7 @@ add_custom_target(buildtests ) add_custom_target(testall - COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DBUILD_TESTS=Y -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=${CMAKE_BINARY_DIR} -DWITH_SCRIPTS=N -DWITH_MAXSCALE_CNF=N -DMAXSCALE_VARDIR=${CMAKE_BINARY_DIR} COMMAND make install COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/testall.cmake COMMENT "Running full test suite..." VERBATIM) diff --git a/cmake/package_rpm.cmake b/cmake/package_rpm.cmake index 0f65bcdd2..7f11587a7 100644 --- a/cmake/package_rpm.cmake +++ b/cmake/package_rpm.cmake @@ -1,15 +1,5 @@ # RPM specific CPack configuration parameters set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") -set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MaxScale") -set(CPACK_PACKAGE_VERSION_MAJOR "${MAXSCALE_VERSION_MAJOR}") -set(CPACK_PACKAGE_VERSION_MINOR "${MAXSCALE_VERSION_MINOR}") -set(CPACK_PACKAGE_VERSION_PATCH "${MAXSCALE_VERSION_PATCH}") -set(CPACK_PACKAGE_CONTACT "MariaDB Corporation Ab") -set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") -set(CPACK_PACKAGE_NAME "maxscale") -set(CPACK_PACKAGE_VENDOR "MariaDB Corporation Ab") -set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_SOURCE_DIR}/etc/DESCRIPTION) -set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") set(CPACK_RPM_PACKAGE_RELEASE ${MAXSCALE_BUILD_NUMBER}) set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postinst) set(CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE ${CMAKE_BINARY_DIR}/postrm) From 584ad321ff2e0b85bdb13b34803ff08cebad1fde Mon Sep 17 00:00:00 2001 From: Markus Makela Date: Mon, 13 Jul 2015 13:22:19 +0300 Subject: [PATCH 41/41] Fixed possible crash. --- server/core/dbusers.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/core/dbusers.c b/server/core/dbusers.c index 6748a1437..57594f63d 100644 --- a/server/core/dbusers.c +++ b/server/core/dbusers.c @@ -210,7 +210,7 @@ HASHTABLE *oldresources; oldusers = service->users; /* digest compare */ - if (memcmp(oldusers->cksum, newusers->cksum, SHA_DIGEST_LENGTH) == 0) { + if (oldusers != NULL && memcmp(oldusers->cksum, newusers->cksum, SHA_DIGEST_LENGTH) == 0) { /* same data, nothing to do */ LOGIF(LD, (skygw_log_write_flush( LOGFILE_DEBUG, @@ -234,7 +234,7 @@ HASHTABLE *oldresources; spinlock_release(&service->spin); - if (i) { + if (i && oldusers) { /* free the old table */ users_free(oldusers); }