diff --git a/CMakeLists.txt b/CMakeLists.txt index 9d0773e25..42da6c06c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,11 @@ endif() set(CMAKE_INSTALL_RPATH ${CMAKE_INSTALL_RPATH}:${CMAKE_INSTALL_PREFIX}/${MAXSCALE_LIBDIR}) +# Only do packaging if configured +if(PACKAGE) + include(cmake/package.cmake) +endif() + # Make sure the release notes for this release are present if it is a stable one if(${MAXSCALE_VERSION} MATCHES "-stable") file(GLOB ${CMAKE_SOURCE_DIR}/Documentation/Release-Notes RELEASE_NOTES *${MAXSCALE_VERSION_NUMERIC}*.md) @@ -227,7 +232,6 @@ if(WITH_SCRIPTS) include(cmake/init_scripts.cmake) endif() -# Only do packaging if configured if(PACKAGE) # Install the files copied by the postinst script into the share folder @@ -236,9 +240,6 @@ if(PACKAGE) install_program(${CMAKE_BINARY_DIR}/postinst core) install_program(${CMAKE_BINARY_DIR}/postrm core) - # Include the package configuration - include(cmake/package.cmake) - # CPack needs to be included after everything is configured include(CPack) endif() diff --git a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md index a8b8b0f54..b45139c45 100644 --- a/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md +++ b/Documentation/Getting-Started/Building-MaxScale-from-Source-Code.md @@ -88,6 +88,7 @@ _NAME_=_VALUE_ format (e.g. `-DBUILD_TESTS=Y`). |WITH_SCRIPTS|Install systemd and init.d scripts| |PACKAGE|Enable building of packages| |TARGET_COMPONENT|Which component to install, default is the 'core' package. Other targets are 'experimental', which installs experimental packages, 'devel' which installs development headers and 'all' which installs all components.| +|TARBALL|Build tar.gz packages, requires PACKAGE=Y| **Note**: You can look into [defaults.cmake](../../cmake/defaults.cmake) for a list of the CMake variables. @@ -152,7 +153,10 @@ make make package ``` -This will create a tarball and a RPM/DEB package. +This will create a RPM/DEB package. + +To build a tarball, add `-DTARBALL=Y` to the cmake invokation. This will create +a _maxscale-x.y.z.tar.gz_ file where _x.y.z_ is the version number. Some Debian and Ubuntu systems suffer from a bug where `make package` fails with errors from dpkg-shlibdeps. This can be fixed by running `make` before diff --git a/Documentation/Getting-Started/Install-MariaDB-MaxScale-Using-a-Tarball.md b/Documentation/Getting-Started/Install-MariaDB-MaxScale-Using-a-Tarball.md index d9ceb1854..6dd5cd3c8 100644 --- a/Documentation/Getting-Started/Install-MariaDB-MaxScale-Using-a-Tarball.md +++ b/Documentation/Getting-Started/Install-MariaDB-MaxScale-Using-a-Tarball.md @@ -1,6 +1,6 @@ # Installing MariaDB MaxScale using a tarball -MariaDB MaxScale is also made available as a tarball, which is named like `maxscale-X.Y.X.tar.gz` where `X.Y.Z` is the same as the corresponding version, e.g. `maxscale-2.0.1.tar.gz`. +MariaDB MaxScale is also made available as a tarball, which is named like `maxscale-x.y.z.OS.tar.gz` where `x.y.z` is the same as the corresponding version and `OS` identifies the operating system, e.g. `maxscale-2.0.1.centos.7.tar.gz`. The tarball has been built with the assumption that it will be installed in `/usr/local`. However, it is possible to install it in any directory, but in that case MariaDB MaxScale must be invoked with a flag. @@ -13,8 +13,8 @@ The required steps are as follows: $ sudo groupadd maxscale $ sudo useradd -g maxscale maxscale $ cd /usr/local - $ sudo tar -xzvf maxscale-X.Y.Z.tar.gz - $ sudo ln -s maxscale-X.Y.Z maxscale + $ sudo tar -xzvf maxscale-x.y.z.OS.tar.gz + $ sudo ln -s maxscale-x.y.z maxscale $ cd maxscale $ chown -R maxscale var @@ -34,13 +34,13 @@ If you want to place the configuration file somewhere else but in `/etc` you can Enter a directory where you have the right to create a subdirectory. Then do as follows. - $ tar -xzvf maxscale-X.Y.Z.tar.gz + $ tar -xzvf maxscale-x.y.z.OS.tar.gz -The next step is to create the MaxScale configuration file `maxscale-X.Y.Z/etc/maxscale.cnf`. The file `maxscale-X.Y.Z/etc/maxscale.cnf.template` can be used as a base. Please refer to [Configuration Guide](Configuration-Guide.md) for details. +The next step is to create the MaxScale configuration file `maxscale-x.y.z/etc/maxscale.cnf`. The file `maxscale-x.y.z/etc/maxscale.cnf.template` can be used as a base. Please refer to [Configuration Guide](Configuration-Guide.md) for details. When the configuration file has been created, MariaDB MaxScale can be started. - $ cd maxscale-X.Y.Z + $ cd maxscale-x.y.z $ LD_LIBRARY_PATH=lib/maxscale bin/maxscale -d --basedir=. With the flag `--basedir`, MariaDB MaxScale is told where the `bin`, `etc`, `lib` diff --git a/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md index 75f1412ae..a8e0f7bd2 100644 --- a/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md +++ b/Documentation/Getting-Started/MariaDB-MaxScale-Installation-Guide.md @@ -6,21 +6,43 @@ In this introduction to MariaDB MaxScale the aim is to take the reader from the ## Installation -The simplest way to install MariaDB MaxScale is to use one of the binary packages that are available for download from the MariaDB website. +MariaDB MaxScale can be installed either using the MariaDB Enterprise Repository or directly from a downloaded package. -* Simply go to [http://www.mariadb.com/my_portal/download](http://www.mariadb.com/my_portal/download) +### Using the MariaDB Enterprise Repository -* Sign in to MariaDB.com +* Go to [https://mariadb.com/my_portal/download](https://mariadb.com/my_portal/download). -* Follow the instructions at the top of the page. +* Sign in or create an account for you. -![image alt text](images/getting_started.png) +* Select your operating system and follow the instructions. -If you want to install only MariaDB MaxScale, further down you will find the product specific download pages. Click on the MariaDB MaxScale link and follow the distribution specific instructions. +### From a Downloaded Package -![image alt text](images/getting_started2.png) +The MaxScale package can be downloaded from the following locations: -After you have installed MariaDB MaxScale, you can start it. +* [https://mariadb.com/my_portal/download/maxscale](https://mariadb.com/my_portal/download/maxscale) + +* [https://mariadb.com/downloads/maxscale](https://mariadb.com/downloads/maxscale) + +Select your operating system and download the package. + +Depending on your OS, the package will either be a _deb_ or an _rpm_. + +An _rpm_ is installed as follows +``` +$ sudo yum install path-to-maxscale-package.rpm +``` +and a _deb_ as follows +``` +$ sudo dpkg -i path-to-maxscale-package.deb +$ sudo apt-get install -f +``` + +### Starting MariaDB MaxScale + +Before starting MariaDB MaxScale, you need to create a configuration file for it; please see further [down](#configuring-mariadb-maxscale). + +Once a configuration file has been created you can start MariaDB MaxScale: ``` systemctl start maxscale.service diff --git a/Documentation/Monitors/MySQL-Monitor.md b/Documentation/Monitors/MySQL-Monitor.md index 86a031e7e..fe7ff6cf1 100644 --- a/Documentation/Monitors/MySQL-Monitor.md +++ b/Documentation/Monitors/MySQL-Monitor.md @@ -78,10 +78,6 @@ With this parameter, slaves that have lost their master but have been slaves of a master server can retain their slave status even without a master. This means that when a slave loses its master, it can still be used for reads. -If MaxScale loses the connection to the slave, the slave will lose the stale -slave state because MaxScale doesn't know if the slave has had recent contact -with the master server. - If this feature is disabled, a server is considered a valid slave if and only if it has a running master server monitored by this monitor. diff --git a/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md b/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md index fe6675efc..509cffad5 100644 --- a/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md +++ b/Documentation/Release-Notes/MaxScale-2.0.1-Release-Notes.md @@ -113,13 +113,17 @@ Please consult ## Bug fixes -[Here is a list of bugs fixed since the release of MaxScale 2.0.1.](https://jira.mariadb.org/issues/?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20in%20(2.0.0%2C%202.0.1)%20AND%20resolved%20%3E%3D%20-21d%20ORDER%20BY%20priority%20DESC%2C%20updated%20DESC) +[Here is a list of bugs fixed since the release of MaxScale 2.0.0.](https://jira.mariadb.org/browse/MXS-860?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20status%20%3D%20Closed%20AND%20fixVersion%20in%20(2.0.1)%20AND%20resolved%20%3E%3D%20-21d%20AND%20(resolution%20%3D%20Done%20OR%20resolution%20%3D%20Fixed)%20ORDER%20BY%20priority%20DESC) -* [MXS-812](https://jira.mariadb.org/browse/MXS-812): Number of conns not matching number of operations -* [MXS-847](https://jira.mariadb.org/browse/MXS-847): server_down event is executed 8 times due to putting sever into maintenance mode +* [MXS-860](https://jira.mariadb.org/browse/MXS-860): I want to access the web site if master server is down +* [MXS-870](https://jira.mariadb.org/browse/MXS-870): Assertion of Buffer Overflow * [MXS-845](https://jira.mariadb.org/browse/MXS-845): "Server down" event is re-triggered after maintenance mode is repeated -* [MXS-842](https://jira.mariadb.org/browse/MXS-842): Unexpected / undocumented behaviour when multiple available masters from mmmon monitor -* [MXS-846](https://jira.mariadb.org/browse/MXS-846): MMMon: Maintenance mode on slave logs error message every second +* [MXS-836](https://jira.mariadb.org/browse/MXS-836): "Failed to start all MaxScale services" without retrying +* [MXS-835](https://jira.mariadb.org/browse/MXS-835): Please reinstate remote access to maxscaled protocol +* [MXS-773](https://jira.mariadb.org/browse/MXS-773): 100% CPU on idle MaxScale with MaxInfo +* [MXS-812](https://jira.mariadb.org/browse/MXS-812): Number of conns not matching number of operations +* [MXS-856](https://jira.mariadb.org/browse/MXS-856): If config file cannot be accessed and creation of log file fails, MaxScale crashes with SIGSEGV +* [MXS-829](https://jira.mariadb.org/browse/MXS-829): When the config file isn't readable or doesn't exist, maxscale silently ends ## Known Issues and Limitations diff --git a/VERSION.cmake b/VERSION.cmake index f7abd4919..0693bfd8b 100644 --- a/VERSION.cmake +++ b/VERSION.cmake @@ -5,10 +5,10 @@ set(MAXSCALE_VERSION_MAJOR "2" CACHE STRING "Major version") set(MAXSCALE_VERSION_MINOR "0" CACHE STRING "Minor version") -set(MAXSCALE_VERSION_PATCH "0" CACHE STRING "Patch version") +set(MAXSCALE_VERSION_PATCH "1" CACHE STRING "Patch version") # This should only be incremented if a package is rebuilt set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number") set(MAXSCALE_VERSION_NUMERIC "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") -set(MAXSCALE_VERSION "beta-${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") +set(MAXSCALE_VERSION "${MAXSCALE_VERSION_MAJOR}.${MAXSCALE_VERSION_MINOR}.${MAXSCALE_VERSION_PATCH}") diff --git a/cmake/package.cmake b/cmake/package.cmake index a63c49049..46c93ab11 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -33,20 +33,22 @@ endif() find_program(RPMBUILD rpmbuild) find_program(DEBBUILD dpkg-buildpackage) -message(STATUS "Generating TGZ packages") -set(CPACK_GENERATOR "TGZ") +if(TARBALL) + include(cmake/package_tgz.cmake) -if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) - include(cmake/package_rpm.cmake) - message(STATUS "Generating RPM packages") - set(PACKAGE_SUFFIX "rpm") - set(RPM TRUE CACHE INTERNAL "RPM based installation") -elseif(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) - include(cmake/package_deb.cmake) - message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") - set(PACKAGE_SUFFIX "deb") - set(DEB TRUE CACHE INTERNAL "DEB based installation") +elseif (NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) OR NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" )) + if(NOT ( ${RPMBUILD} STREQUAL "RPMBUILD-NOTFOUND" ) ) + include(cmake/package_rpm.cmake) + endif() + if(NOT ( ${DEBBUILD} STREQUAL "DEBBUILD-NOTFOUND" ) ) + include(cmake/package_deb.cmake) + endif() + + message(STATUS "You can install startup scripts and system configuration files for MaxScale by running the 'postinst' shell script located at ${CMAKE_INSTALL_PREFIX}.") + message(STATUS "To remove these installed files, run the 'postrm' shell script located in the same folder.") + +else() + message(FATAL_ERROR "Could not automatically resolve the package generator and no generators " + "defined on the command line. Please install distribution specific packaging software or " + "define -DTARBALL=Y to build tar.gz packages.") endif() - -message(STATUS "You can install startup scripts and system configuration files for MaxScale by running the 'postinst' shell script located at ${CMAKE_INSTALL_PREFIX}.") -message(STATUS "To remove these installed files, run the 'postrm' shell script located in the same folder.") diff --git a/cmake/package_deb.cmake b/cmake/package_deb.cmake index c0612dc2c..ee0236753 100644 --- a/cmake/package_deb.cmake +++ b/cmake/package_deb.cmake @@ -12,3 +12,5 @@ endif() if(EXTRA_PACKAGE_DEPENDENCIES) set(CPACK_DEBIAN_PACKAGE_DEPENDS "${EXTRA_PACKAGE_DEPENDENCIES}") endif() + +message(STATUS "Generating DEB packages for ${DEB_ARCHITECTURE}") diff --git a/cmake/package_rpm.cmake b/cmake/package_rpm.cmake index ec6e9bed4..6d951e17b 100644 --- a/cmake/package_rpm.cmake +++ b/cmake/package_rpm.cmake @@ -32,3 +32,5 @@ endif() if(EXTRA_PACKAGE_DEPENDENCIES) set(CPACK_RPM_PACKAGE_REQUIRES "${EXTRA_PACKAGE_DEPENDENCIES}") endif() + +message(STATUS "Generating RPM packages") diff --git a/cmake/package_tgz.cmake b/cmake/package_tgz.cmake new file mode 100644 index 000000000..f99417748 --- /dev/null +++ b/cmake/package_tgz.cmake @@ -0,0 +1,19 @@ +# Tarball package configuration +message(STATUS "Generating tar.gz packages") +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) +set(MAXSCALE_BINDIR /bin CACHE PATH "" FORCE) +set(MAXSCALE_LIBDIR /lib CACHE PATH "" FORCE) +set(MAXSCALE_SHAREDIR /share CACHE PATH "" FORCE) +set(MAXSCALE_DOCDIR /share CACHE PATH "" FORCE) +set(MAXSCALE_VARDIR /var CACHE PATH "" FORCE) +set(MAXSCALE_CONFDIR /etc CACHE PATH "" FORCE) +set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "" FORCE) +set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib" CACHE PATH "" FORCE) +set(CMAKE_INSTALL_DATADIR /share CACHE PATH "" FORCE) +set(CPACK_GENERATOR "TGZ") + +if(DISTRIB_SUFFIX) + set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}.${DISTRIB_SUFFIX}") +else() + set(CPACK_PACKAGE_FILE_NAME "maxscale-${MAXSCALE_VERSION}") +endif() diff --git a/server/core/buffer.c b/server/core/buffer.c index c876b4ec7..1b13b5fa5 100644 --- a/server/core/buffer.c +++ b/server/core/buffer.c @@ -380,9 +380,9 @@ GWBUF* gwbuf_clone_all(GWBUF* buf) } -GWBUF *gwbuf_clone_portion(GWBUF *buf, - size_t start_offset, - size_t length) +static GWBUF *gwbuf_clone_portion(GWBUF *buf, + size_t start_offset, + size_t length) { GWBUF* clonebuf; diff --git a/server/core/test/testbuffer.c b/server/core/test/testbuffer.c index 499a14886..6c6e4ce3d 100644 --- a/server/core/test/testbuffer.c +++ b/server/core/test/testbuffer.c @@ -377,15 +377,6 @@ test1() gwbuf_free(clone); ss_dfprintf(stderr, "Freed cloned buffer"); ss_dfprintf(stderr, "\t..done\n"); - partclone = gwbuf_clone_portion(buffer, 25, 50); - buflen = GWBUF_LENGTH(partclone); - ss_dfprintf(stderr, "Part cloned buffer length is now %d", buflen); - ss_info_dassert(50 == buflen, "Incorrect buffer size"); - ss_info_dassert(0 == GWBUF_EMPTY(partclone), "Part cloned buffer should not be empty"); - ss_dfprintf(stderr, "\t..done\n"); - gwbuf_free(partclone); - ss_dfprintf(stderr, "Freed part cloned buffer"); - ss_dfprintf(stderr, "\t..done\n"); buffer = gwbuf_consume(buffer, bite1); ss_info_dassert(NULL != buffer, "Buffer should not be null"); buflen = GWBUF_LENGTH(buffer); diff --git a/server/include/buffer.h b/server/include/buffer.h index 206e87db4..f3ae40134 100644 --- a/server/include/buffer.h +++ b/server/include/buffer.h @@ -197,7 +197,6 @@ extern unsigned int gwbuf_length(GWBUF *head); extern int gwbuf_count(GWBUF *head); extern size_t gwbuf_copy_data(GWBUF *buffer, size_t offset, size_t bytes, uint8_t* dest); -extern GWBUF *gwbuf_clone_portion(GWBUF *head, size_t offset, size_t len); extern GWBUF *gwbuf_split(GWBUF **buf, size_t length); extern GWBUF *gwbuf_clone_transform(GWBUF *head, gwbuf_type_t type); extern GWBUF *gwbuf_clone_all(GWBUF* head); diff --git a/server/modules/monitor/mysqlmon/mysql_mon.c b/server/modules/monitor/mysqlmon/mysql_mon.c index b59777054..c45e7b60b 100644 --- a/server/modules/monitor/mysqlmon/mysql_mon.c +++ b/server/modules/monitor/mysqlmon/mysql_mon.c @@ -1127,10 +1127,6 @@ monitorMain(void *arg) { dcb_hangup_foreach(ptr->server); } - - - - } if (mon_status_changed(ptr)) @@ -1225,6 +1221,8 @@ monitorMain(void *arg) ptr = mon->databases; while (ptr) { + MYSQL_SERVER_INFO *serv_info = hashtable_fetch(handle->server_info, ptr->server->unique_name); + ss_dassert(serv_info); if (!SERVER_IN_MAINT(ptr->server)) { /** If "detect_stale_master" option is On, let's use the previous master. @@ -1287,6 +1285,10 @@ monitorMain(void *arg) { ptr->pending_status |= SERVER_SLAVE; } + else if (root_master == NULL && serv_info->slave_configured) + { + ptr->pending_status |= SERVER_SLAVE; + } } ptr->server->status = ptr->pending_status; diff --git a/server/modules/protocol/MySQLBackend/mysql_backend.c b/server/modules/protocol/MySQLBackend/mysql_backend.c index f6b9e8051..456d4b500 100644 --- a/server/modules/protocol/MySQLBackend/mysql_backend.c +++ b/server/modules/protocol/MySQLBackend/mysql_backend.c @@ -1185,48 +1185,38 @@ static int gw_write_backend_event(DCB *dcb) */ if (dcb->state != DCB_STATE_POLLING) { - uint8_t* data; + uint8_t* data = NULL; + bool com_quit = false; - if (dcb->writeq != NULL) + spinlock_acquire(&dcb->writeqlock); + if (dcb->writeq) { data = (uint8_t *) GWBUF_DATA(dcb->writeq); + com_quit = MYSQL_IS_COM_QUIT(data); + rc = 0; + } + spinlock_release(&dcb->writeqlock); - if (dcb->session->client_dcb == NULL) - { - rc = 0; - } - else if (!(MYSQL_IS_COM_QUIT(data))) - { - /*< vraa : errorHandle */ - mysql_send_custom_error(dcb->session->client_dcb, - 1, - 0, - "Writing to backend failed due invalid Maxscale " - "state."); - MXS_DEBUG("%lu [gw_write_backend_event] Write to backend " - "dcb %p fd %d " - "failed due invalid state %s.", - pthread_self(), - dcb, - dcb->fd, - STRDCBSTATE(dcb->state)); - MXS_ERROR("Attempt to write buffered data to backend " - "failed " - "due internal inconsistent state."); + if (data && !com_quit) + { + mysql_send_custom_error(dcb->session->client_dcb, 1, 0, + "Writing to backend failed due invalid Maxscale state."); + MXS_DEBUG("%lu [gw_write_backend_event] Write to backend " + "dcb %p fd %d failed due invalid state %s.", + pthread_self(), dcb, dcb->fd, STRDCBSTATE(dcb->state)); - rc = 0; - } + MXS_ERROR("Attempt to write buffered data to backend " + "failed due internal inconsistent state."); } else { MXS_DEBUG("%lu [gw_write_backend_event] Dcb %p in state %s " - "but there's nothing to write either.", - pthread_self(), - dcb, - STRDCBSTATE(dcb->state)); + "but there's nothing to write either.", + pthread_self(), dcb, STRDCBSTATE(dcb->state)); rc = 1; } + goto return_rc; } @@ -2031,22 +2021,17 @@ static GWBUF* process_response_data(DCB* dcb, outbuf = gwbuf_append(outbuf, readbuf); readbuf = NULL; } - /** - * Packet was read. There should be more since bytes were - * left over. - * Move the next packet to its own buffer and add that next - * to the prev packet's buffer. - */ - else /*< nbytes_left < nbytes_to_process */ + /** + * Buffer contains more data than we need. Split the complete packet and + * the extra data into two separate buffers. + */ + else { - ss_dassert(nbytes_left >= 0); - nbytes_to_process -= nbytes_left; - - /** Move the prefix of the buffer to outbuf from redbuf */ - outbuf = gwbuf_append(outbuf, - gwbuf_clone_portion(readbuf, 0, (size_t) nbytes_left)); - readbuf = gwbuf_consume(readbuf, (size_t) nbytes_left); + ss_dassert(nbytes_left < nbytes_to_process); + ss_dassert(nbytes_left > 0); ss_dassert(npackets_left > 0); + outbuf = gwbuf_append(outbuf, gwbuf_split(&readbuf, nbytes_left)); + nbytes_to_process -= nbytes_left; npackets_left -= 1; nbytes_left = 0; } diff --git a/server/modules/routing/readwritesplit/readwritesplit.c b/server/modules/routing/readwritesplit/readwritesplit.c index 67f818003..c30011465 100644 --- a/server/modules/routing/readwritesplit/readwritesplit.c +++ b/server/modules/routing/readwritesplit/readwritesplit.c @@ -651,7 +651,7 @@ static void closeSession(ROUTER *instance, void *router_session) } #endif /** Clean operation counter in bref and in SERVER */ - while (BREF_IS_WAITING_RESULT(bref)) + if (BREF_IS_WAITING_RESULT(bref)) { bref_clear_state(bref, BREF_WAITING_RESULT); } @@ -664,6 +664,10 @@ static void closeSession(ROUTER *instance, void *router_session) /** decrease server current connection counters */ atomic_add(&bref->bref_backend->backend_conn_count, -1); } + else + { + ss_dassert(!BREF_IS_WAITING_RESULT(bref)); + } } /** Unlock */ rses_end_locked_router_action(router_cli_ses); @@ -1121,6 +1125,10 @@ static void handleError(ROUTER *instance, void *router_session, if (bref != NULL) { CHK_BACKEND_REF(bref); + if (BREF_IS_WAITING_RESULT(bref)) + { + bref_clear_state(bref, BREF_WAITING_RESULT); + } bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); } @@ -1281,7 +1289,6 @@ void rses_end_locked_router_action(ROUTER_CLIENT_SES *rses) * @param bref The backend reference to be modified * @param state A bit string where the 1 bits indicate bits that should * be turned off in the bref state. - * */ void bref_clear_state(backend_ref_t *bref, bref_state_t state) { @@ -1290,11 +1297,8 @@ void bref_clear_state(backend_ref_t *bref, bref_state_t state) MXS_ERROR("[%s] Error: NULL parameter.", __FUNCTION__); return; } - if (state != BREF_WAITING_RESULT) - { - bref->bref_state &= ~state; - } - else + + if ((state & BREF_WAITING_RESULT) && (bref->bref_state & BREF_WAITING_RESULT)) { int prev1; int prev2; @@ -1319,6 +1323,8 @@ void bref_clear_state(backend_ref_t *bref, bref_state_t state) } } } + + bref->bref_state &= ~state; } /* @@ -1332,7 +1338,6 @@ void bref_clear_state(backend_ref_t *bref, bref_state_t state) * @param bref The backend reference to be modified * @param state A bit string where the 1 bits indicate bits that should * be turned on in the bref state. - * */ void bref_set_state(backend_ref_t *bref, bref_state_t state) { @@ -1341,11 +1346,8 @@ void bref_set_state(backend_ref_t *bref, bref_state_t state) MXS_ERROR("[%s] Error: NULL parameter.", __FUNCTION__); return; } - if (state != BREF_WAITING_RESULT) - { - bref->bref_state |= state; - } - else + + if ((state & BREF_WAITING_RESULT) && (bref->bref_state & BREF_WAITING_RESULT) == 0) { int prev1; int prev2; @@ -1371,6 +1373,8 @@ void bref_set_state(backend_ref_t *bref, bref_state_t state) bref->bref_backend->backend_server->port); } } + + bref->bref_state |= state; } /** @@ -1684,6 +1688,10 @@ static void handle_error_reply_client(SESSION *ses, ROUTER_CLIENT_SES *rses, CHK_BACKEND_REF(bref); bref_clear_state(bref, BREF_IN_USE); bref_set_state(bref, BREF_CLOSED); + if (BREF_IS_WAITING_RESULT(bref)) + { + bref_clear_state(bref, BREF_WAITING_RESULT); + } } if (sesstate == SESSION_STATE_ROUTER_READY)