Merge branch '2.2' into 2.2-mrm

This commit is contained in:
Johan Wikman
2017-11-08 10:44:35 +02:00
13 changed files with 36 additions and 647 deletions

View File

@ -9,12 +9,18 @@ For any problems you encounter, please consider submitting a bug
report at [Jira](https://jira.mariadb.org).
## Changed Features
### Binlog server
- MariaDB 10 GTID is always enabled for slave connections.
- Automatically set binlog storage to 'tree' mode when
_mariadb10_master_gtid_ option is on.
* The `mariadb10_slave_gtid` parameter was removed and slave connections can now
always register with MariaDB 10 GTID.
* The `binlog_structure` parameter was removed and the binlogs are stored
automatically in 'tree' mode when `mariadb10_master_gtid` is enabled.
* If `mariadb10_master_gtid` is enabled, the `transaction_safety` is
automatically enabled. In MaxScale 2.2.0, if `transaction_safety` was disabled
when `mariadb10_master_gtid` was enabled MaxScale would refuse to start.
## Dropped Features

View File

@ -296,13 +296,13 @@ Example:
```
### `mariadb10_master_gtid`
This option allows MaxScale binlog router to register
with MariaDB 10.X master using GTID instead of _binlog_file_ name
and _position_ in CHANGE MASTER TO admin command.
The user can set a known GTID or an empty value
(in this case the Master server will send events
from it's first available binlog file).
This option allows MaxScale binlog router to register with MariaDB 10.X master
using GTID instead of _binlog_file_ name and _position_ in CHANGE MASTER TO
admin command. This feature is disabled by default.
The user can set a known GTID or an empty value (in this case the Master server
will send events from it's first available binlog file).
Example of MaxScale connection to a MariaDB 10.X Master
@ -316,13 +316,12 @@ MariaDB> CHANGE MASTER TO
MariaDB> START SLAVE;
```
If using GTID request then it's no longer possible to use
MASTER_LOG_FILE and MASTER_LOG_POS in `CHANGE MASTER TO`
command: an error will be reported.
If using GTID request then it's no longer possible to use MASTER_LOG_FILE and
MASTER_LOG_POS in `CHANGE MASTER TO` command: an error will be reported.
The default option value is _Off_, setting it to _On_
automatically sets _mariadb10_slave_gtid_ to _On_
(which enables GTID storage and GTID slave connections)
If this feature is enabled, the _transaction_safety_ option will be
automatically enabled. The binlog files will also be stored in a
hierarchical directory tree instead of a single directory.
**Note:**

View File

@ -1,26 +0,0 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file queuemanager.h The Queue Manager public header
*/
#include <maxscale/cdefs.h>
MXS_BEGIN_DECLS
struct queue_config;
typedef struct queue_config QUEUE_CONFIG;
MXS_END_DECLS

View File

@ -35,7 +35,6 @@
#include <maxscale/hashtable.h>
#include <maxscale/resultset.h>
#include <maxscale/config.h>
#include <maxscale/queuemanager.h>
#include <maxscale/jansson.h>
MXS_BEGIN_DECLS
@ -128,7 +127,6 @@ typedef struct service
int state; /**< The service state */
int client_count; /**< Number of connected clients */
int max_connections; /**< Maximum client connections */
QUEUE_CONFIG *queued_connections; /**< Queued connections, if set */
SERV_LISTENER *ports; /**< Linked list of ports and protocols
* that this service will listen on */
char *routerModule; /**< Name of router module to use */

View File

@ -33,7 +33,6 @@ add_library(maxscale-common SHARED
paths.cc
poll.cc
query_classifier.cc
queuemanager.cc
random_jkiss.cc
resultset.cc
resource.cc

View File

@ -597,7 +597,9 @@ bool runtime_alter_service(SERVICE *service, const char* zKey, const char* zValu
{
valid = true;
// TODO: Once connection queues are implemented, use correct values
serviceSetConnectionLimits(service, i, 0, 0);
const int queued_connections = 0; // At most this many pending connections.
const int timeout = 0; // Wait at most this much for a connection.
serviceSetConnectionLimits(service, i, queued_connections, timeout);
}
}
else if (key == CN_CONNECTION_TIMEOUT)

View File

@ -56,7 +56,6 @@
#include <maxscale/utils.h>
#include "maxscale/modules.h"
#include "maxscale/queuemanager.h"
#include "maxscale/semaphore.hh"
#include "maxscale/session.h"
#include "maxscale/worker.hh"
@ -2435,14 +2434,13 @@ dcb_accept(DCB *listener)
if (client_dcb->service->max_connections &&
client_dcb->service->client_count >= client_dcb->service->max_connections)
{
if (!mxs_enqueue(client_dcb->service->queued_connections, client_dcb))
{
// TODO: If connections can be queued, this is the place to put the
// TODO: connection on that queue.
if (client_dcb->func.connlimit)
{
client_dcb->func.connlimit(client_dcb, client_dcb->service->max_connections);
}
dcb_close(client_dcb);
}
client_dcb = NULL;
}
}

View File

@ -1,54 +0,0 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file core/maxscale/queuemanager.h - The private queuemanager interface
*/
#include <maxscale/queuemanager.h>
#include <maxscale/spinlock.h>
MXS_BEGIN_DECLS
typedef struct queue_entry
{
void *queued_object;
long heartbeat;
#if defined(SS_DEBUG)
long sequence_check;
#endif /* SS_DEBUG */
} QUEUE_ENTRY;
struct queue_config
{
int queue_limit;
int start;
int end;
int timeout;
bool has_entries;
SPINLOCK queue_lock;
QUEUE_ENTRY *queue_array;
#if defined(SS_DEBUG)
long sequence_number;
#endif /* SS_DEBUG */
};
QUEUE_CONFIG *mxs_queue_alloc(int limit, int timeout);
void mxs_queue_free(QUEUE_CONFIG *queue_config);
bool mxs_enqueue(QUEUE_CONFIG *queue_config, void *new_entry);
bool mxs_dequeue(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result);
bool mxs_dequeue_if_expired(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result);
MXS_END_DECLS

View File

@ -1,229 +0,0 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file queuemanager.c - Logic for FIFO queue handling
*
* MaxScale contains a number of FIFO queues. This code attempts to provide
* standard functions for handling them.
*
* @verbatim
* Revision History
*
* Date Who Description
* 27/04/16 Martin Brampton Initial implementation
*
* @endverbatim
*/
#include <maxscale/queuemanager.h>
#include <stdlib.h>
#include <stdio.h>
#include <maxscale/alloc.h>
#include <maxscale/debug.h>
#include <maxscale/hk_heartbeat.h>
#include <maxscale/log_manager.h>
#include <maxscale/spinlock.h>
#include "maxscale/queuemanager.h"
#if defined(SS_DEBUG)
int debug_check_fail = 0;
#endif /* SS_DEBUG */
static inline int mxs_queue_count(QUEUE_CONFIG*);
/**
* @brief Allocate a new queue
*
* Provides for FIFO queues, this is the first operation to be requested
* for the use of a queue.
*
* @param limit The maximum size of the queue
* @param timeout The maximum time for which an entry is valid
* @return QUEUE_CONFIG A queue configuration and anchor structure
*/
QUEUE_CONFIG
*mxs_queue_alloc(int limit, int timeout)
{
QUEUE_CONFIG *new_queue = (QUEUE_CONFIG *)MXS_CALLOC(1, sizeof(QUEUE_CONFIG));
if (new_queue)
{
new_queue->queue_array = (QUEUE_ENTRY*)MXS_CALLOC(limit + 1, sizeof(QUEUE_ENTRY));
if (new_queue->queue_array)
{
new_queue->queue_limit = limit;
new_queue->timeout = timeout;
spinlock_init(&new_queue->queue_lock);
#if defined(SS_DEBUG)
new_queue->sequence_number = 0;
#endif /* SS_DEBUG */
return new_queue;
}
MXS_FREE(new_queue);
}
return NULL;
}
/**
* @brief Free a queue configuration
*
* Provides for FIFO queues, this is the last operation to be requested, when
* there is no further use for the queue.
*
* @param QUEUE_CONFIG A queue configuration and anchor structure
*/
void mxs_queue_free(QUEUE_CONFIG *queue_config)
{
if (queue_config)
{
MXS_FREE(queue_config->queue_array);
MXS_FREE(queue_config);
}
}
/**
* @brief Add an item to a queue
*
* Add a new item to a FIFO queue. If the queue config is null, this function
* will behave as if the queue is full.
*
* @param queue_config The configuration and anchor structure for the queue
* @param new_entry The new entry, to be added
* @return bool Whether the enqueue succeeded
*/
bool mxs_enqueue(QUEUE_CONFIG *queue_config, void *new_entry)
{
bool result = false;
if (queue_config)
{
spinlock_acquire(&queue_config->queue_lock);
if (mxs_queue_count(queue_config) < queue_config->queue_limit)
{
queue_config->queue_array[queue_config->end].queued_object = new_entry;
queue_config->queue_array[queue_config->end].heartbeat = hkheartbeat;
#if defined(SS_DEBUG)
queue_config->queue_array[queue_config->end].sequence_check = queue_config->sequence_number;
queue_config->sequence_number++;
#endif /* SS_DEBUG */
queue_config->end++;
if (queue_config->end > queue_config->queue_limit)
{
queue_config->end = 0;
}
queue_config->has_entries = true;
result = true;
}
else
{
result = false;
}
spinlock_release(&queue_config->queue_lock);
}
return result;
}
/**
* @brief Remove an item from a queue
*
* Remove an item from a FIFO queue. If the queue config is NULL, the function
* will behave as if for an empty queue.
*
* @param queue_config The configuration and anchor structure for the queue
* @param result A queue entry structure that will receive the result
* @return bool indicating whether an item was successfully dequeued
*/
bool mxs_dequeue(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result)
{
QUEUE_ENTRY *found = NULL;
if (queue_config && queue_config->has_entries)
{
spinlock_acquire(&queue_config->queue_lock);
if (mxs_queue_count(queue_config) > 0)
{
found = &(queue_config->queue_array[queue_config->start]);
#if defined(SS_DEBUG)
ss_dassert((queue_config->sequence_number) == (found->sequence_check + mxs_queue_count(queue_config)));
if ((queue_config->sequence_number) != (found->sequence_check + mxs_queue_count(queue_config)))
{
debug_check_fail++;
}
#endif /* SS_DEBUG */
result->heartbeat = found->heartbeat;
result->queued_object = found->queued_object;
if (++queue_config->start > queue_config->queue_limit)
{
queue_config->start = 0;
}
queue_config->has_entries = (mxs_queue_count(queue_config) > 0);
}
spinlock_release(&queue_config->queue_lock);
}
return (found != NULL);
}
/**
* @brief Remove an item from a queue if it has passed the timeout limit
*
* Remove an item from a FIFO queue if expired. If the queue config is NULL,
* the function will behave as for an empty queue.
*
* @param queue_config The configuration and anchor structure for the queue
* @param result A queue entry structure that will receive the result
* @return bool indicating whether an item was successfully dequeued
*/
bool mxs_dequeue_if_expired(QUEUE_CONFIG *queue_config, QUEUE_ENTRY *result)
{
QUEUE_ENTRY *found = NULL;
if (queue_config && queue_config->has_entries)
{
spinlock_acquire(&queue_config->queue_lock);
if (mxs_queue_count(queue_config) > 0)
{
found = &(queue_config->queue_array[queue_config->start]);
if (found->heartbeat > hkheartbeat - queue_config->timeout)
{
found = NULL;
}
else
{
#if defined(SS_DEBUG)
ss_dassert((queue_config->sequence_number) == (found->sequence_check + mxs_queue_count(queue_config)));
if ((queue_config->sequence_number) != (found->sequence_check + mxs_queue_count(queue_config)))
{
debug_check_fail++;
}
#endif /* SS_DEBUG */
result->heartbeat = found->heartbeat;
result->queued_object = found->queued_object;
if (++queue_config->start > queue_config->queue_limit)
{
queue_config->start = 0;
}
queue_config->has_entries = (mxs_queue_count(queue_config) > 0);
}
}
spinlock_release(&queue_config->queue_lock);
}
return (found != NULL);
}
static inline int mxs_queue_count(QUEUE_CONFIG *queue_config)
{
int count = queue_config->end - queue_config->start;
return count < 0 ? (count + queue_config->queue_limit + 1) : count;
}

View File

@ -39,7 +39,6 @@
#include <maxscale/log_manager.h>
#include <maxscale/poll.h>
#include <maxscale/protocol.h>
#include <maxscale/queuemanager.h>
#include <maxscale/resultset.h>
#include <maxscale/router.h>
#include <maxscale/server.h>
@ -54,7 +53,6 @@
#include "maxscale/config.h"
#include "maxscale/filter.h"
#include "maxscale/modules.h"
#include "maxscale/queuemanager.h"
#include "maxscale/service.h"
/** This define is needed in CentOS 6 systems */
@ -97,7 +95,6 @@ static int find_type(typelib_t* tl, const char* needle, int maxlen);
static void service_add_qualified_param(SERVICE* svc,
MXS_CONFIG_PARAMETER* param);
static void service_internal_restart(void *data);
static void service_queue_check(void *data);
static void service_calculate_weights(SERVICE *service);
SERVICE* service_alloc(const char *name, const char *router)
@ -145,7 +142,6 @@ SERVICE* service_alloc(const char *name, const char *router)
service->name = my_name;
service->routerModule = my_router;
service->users_from_all = false;
service->queued_connections = NULL;
service->localhost_match_wildcard_host = SERVICE_PARAM_UNINIT;
service->retry_start = true;
service->conn_idle_timeout = SERVICE_NO_SESSION_TIMEOUT;
@ -1157,6 +1153,8 @@ void serviceSetVersionString(SERVICE *service, const char* value)
* @param max The maximum number of client connections at any one time
* @param queued The maximum number of connections to queue up when
* max_connections clients are already connected
* @param timeout Maximum amount of time to wait for a connection to
* become available.
* @return 1 on success, 0 when the values are invalid
*/
int
@ -1169,45 +1167,13 @@ serviceSetConnectionLimits(SERVICE *service, int max, int queued, int timeout)
}
service->max_connections = max;
if (queued && timeout)
{
char callback_name[100];
sprintf(callback_name, "Check queued connections %p", service);
/* If memory allocation fails, result will be null so no queue */
service->queued_connections = mxs_queue_alloc(queued, timeout);
if (service->queued_connections)
{
hktask_add(callback_name, service_queue_check, (void *)service->queued_connections, 1);
}
}
ss_info_dassert(queued == 0, "Queued connections not implemented.");
ss_info_dassert(timeout == 0, "Queued connections not implemented.");
return 1;
}
/*
* @brief The callback function triggered by housekeeping every second
*
* This function removes any expired connection requests from the queue, and
* sends an error message "too many connections" for them.
*
* @param The parameter provided by the callback is the queue config
*/
static void
service_queue_check(void *data)
{
QUEUE_ENTRY expired;
QUEUE_CONFIG *queue_config = (QUEUE_CONFIG *)data;
/* The queued connections are in a FIFO queue, so we only look at the */
/* start of the queue, and remove any expired entries. As soon as this */
/* returns nothing, we stop. */
while ((mxs_dequeue_if_expired(queue_config, &expired)))
{
DCB *dcb = (DCB *)expired.queued_object;
dcb->func.connlimit(dcb, queue_config->queue_limit);
dcb_close(dcb);
}
}
/**
* Enable or disable the restarting of the service on failure.
* @param service Service to configure

View File

@ -10,7 +10,6 @@ add_executable(test_logorder testlogorder.cc)
add_executable(test_logthrottling testlogthrottling.cc)
add_executable(test_modutil testmodutil.cc)
add_executable(test_poll testpoll.cc)
add_executable(test_queuemanager testqueuemanager.cc)
add_executable(test_semaphore testsemaphore.cc)
add_executable(test_server testserver.cc)
add_executable(test_service testservice.cc)
@ -38,7 +37,6 @@ target_link_libraries(test_logorder maxscale-common)
target_link_libraries(test_logthrottling maxscale-common)
target_link_libraries(test_modutil maxscale-common)
target_link_libraries(test_poll maxscale-common)
target_link_libraries(test_queuemanager maxscale-common)
target_link_libraries(test_semaphore maxscale-common)
target_link_libraries(test_server maxscale-common)
target_link_libraries(test_service maxscale-common)
@ -68,7 +66,6 @@ add_test(TestMaxScalePCRE2 testmaxscalepcre2)
add_test(TestModutil test_modutil)
add_test(NAME TestMaxPasswd COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/testmaxpasswd.sh)
add_test(TestPoll test_poll)
add_test(TestQueueManager test_queuemanager)
add_test(TestSemaphore test_semaphore)
add_test(TestServer test_server)
add_test(TestService test_service)

View File

@ -1,259 +0,0 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl11.
*
* Change Date: 2020-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
*
* @verbatim
* Revision History
*
* Date Who Description
* 21/06/2016 Martin Brampton Initial implementation
*
* @endverbatim
*/
// To ensure that ss_info_assert asserts also when builing in non-debug mode.
#if !defined(SS_DEBUG)
#define SS_DEBUG
int debug_check_fail = 1;
#else
// This is defined in the queuemanager code but only in debug builds
extern int debug_check_fail;
#endif
#if defined(NDEBUG)
#undef NDEBUG
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <maxscale/random_jkiss.h>
#include <maxscale/hk_heartbeat.h>
#include <maxscale/alloc.h>
#include "../maxscale/queuemanager.h"
#include "test_utils.h"
/**
* test1 Allocate a queue and do lots of other things
*
*/
#define TEST_QUEUE_SIZE 5
#define HEARTBEATS_TO_EXPIRE 3
#define NUMBER_OF_THREADS 4
#define THREAD_TEST_COUNT 1000000
static QUEUE_CONFIG *thread_queue;
static int
test1()
{
QUEUE_CONFIG *queue;
int filled = 0;
int emptied = 0;
int expired = 0;
int input_counter = 0;
int output_counter = 0;
random_jkiss_init();
hkheartbeat = 0;
queue = mxs_queue_alloc(TEST_QUEUE_SIZE, HEARTBEATS_TO_EXPIRE);
{
QUEUE_ENTRY entry;
if (mxs_dequeue(queue, &entry))
{
ss_dfprintf(stderr, "\nError mxs_dequeue on empty queue did not return false.\n");
return 1;
}
if (mxs_dequeue_if_expired(queue, &entry))
{
ss_dfprintf(stderr, "\nError mxs_dequeue_if_expired on empty queue did not return false.\n");
return 1;
}
}
while (filled < 250 || emptied < 250 || expired < 250)
{
ss_dfprintf(stderr, "Input counter %d and output counter %d\n", input_counter, output_counter);
ss_dfprintf(stderr, "Difference between counters %d\n", input_counter - output_counter);
ss_dfprintf(stderr, "Filled %d, emptied %d, expired %d\n", filled, emptied, expired);
if (random_jkiss() % 2)
{
int *entrynumber = (int*)MXS_MALLOC(sizeof(int));
*entrynumber = input_counter;
if (mxs_enqueue(queue, entrynumber))
{
input_counter++;
if ((input_counter - output_counter) > TEST_QUEUE_SIZE)
{
ss_dfprintf(stderr, "\nQueue full, but mxs_enqueue accepted entry.\n");
return 3;
}
}
else
{
QUEUE_ENTRY entry;
if ((input_counter - output_counter) != TEST_QUEUE_SIZE)
{
ss_dfprintf(stderr, "\nFailed enqueue, but input counter %d and output counter %d do not differ by %d.\n",
input_counter,
output_counter,
TEST_QUEUE_SIZE);
return 4;
}
filled++;
if (0 == (random_jkiss() % 5))
{
if ((mxs_dequeue_if_expired(queue, &entry)))
{
if ((entry.heartbeat) > (hkheartbeat - HEARTBEATS_TO_EXPIRE))
{
ss_dfprintf(stderr, "\nReturned an expired entry even though none or not expired.\n");
return 5;
}
if (*(int *)entry.queued_object != output_counter)
{
ss_dfprintf(stderr, "\nOutput counter was %d, but dequeue gave %d.\n",
output_counter,
*(int *)entry.queued_object);
return 10;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
hkheartbeat += (HEARTBEATS_TO_EXPIRE + 1);
if (mxs_dequeue_if_expired(queue, &entry))
{
if (*(int *)entry.queued_object != output_counter)
{
ss_dfprintf(stderr, "\nOutput counter was %d, but dequeue gave %d.\n",
output_counter,
*(int *)entry.queued_object);
return 6;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
ss_dfprintf(stderr, "\nReturned no expired entry even though all are expired.\n");
return 7;
}
expired++;
}
}
}
}
else
{
QUEUE_ENTRY entry;
if (mxs_dequeue(queue, &entry))
{
if (*(int *)entry.queued_object != output_counter)
{
ss_dfprintf(stderr, "\nOutput counter was %d, but dequeue gave %d.\n",
output_counter,
*(int *)entry.queued_object);
return 8;
}
output_counter++;
MXS_FREE(entry.queued_object);
}
else
{
if (input_counter != output_counter)
{
ss_dfprintf(stderr, "\nNULL from dequeue, but input counter %d and output counter %d.\n",
input_counter,
output_counter);
return 9;
}
emptied++;
}
}
}
ss_dfprintf(stderr, "Successfully ended test\n");
mxs_queue_free(queue);
return 0;
}
static void *
thread_test(void *arg)
{
int i;
QUEUE_ENTRY entry;
int emptied = 0;
int filled = 0;
for (i = 0; i < THREAD_TEST_COUNT; i++)
{
if (random_jkiss() % 2)
{
if (!mxs_enqueue(thread_queue, (void *)"Just for test"))
{
filled++;
}
}
else
{
if (!mxs_dequeue(thread_queue, &entry))
{
emptied++;
}
}
}
ss_dfprintf(stderr, "Queue was full %d times, empty %d times\n", filled, emptied);
return NULL;
}
static int
test2()
{
pthread_t tid[NUMBER_OF_THREADS];
int err, i, limit;
thread_queue = mxs_queue_alloc(TEST_QUEUE_SIZE, HEARTBEATS_TO_EXPIRE);
limit = NUMBER_OF_THREADS;
for (i = 0; i < limit; i++)
{
err = pthread_create(&tid[i], NULL, thread_test, NULL);
ss_info_dassert((0 == err), "Must create threads successfully");
}
for (i = 0; i < limit; i++)
{
err = pthread_join(tid[i], NULL);
ss_info_dassert((0 == err), "Must join threads successfully");
ss_dfprintf(stderr, "\nThread %d ended with debug check fail at %d.\n", i, debug_check_fail);
}
mxs_queue_free(thread_queue);
return debug_check_fail ? 1 : 0;
}
int main(int argc, char **argv)
{
int result = 0;
result += (test1() ? 1 : 0);
result += (test2() ? 1 : 0);
exit(result);
}

View File

@ -770,6 +770,8 @@ createInstance(SERVICE *service, char **options)
{
/* Force GTID slave request handling */
inst->mariadb10_gtid = true;
/* Force transaction safety */
inst->trx_safe = true;
/* Force binlog storage as tree */
inst->storage_type = BLR_BINLOG_STORAGE_TREE;
}
@ -782,18 +784,8 @@ createInstance(SERVICE *service, char **options)
"'tree' mode using GTID domain_id and server_id");
/* Enable MariaDB the GTID maps store */
if (inst->mariadb10_compat &&
inst->mariadb10_gtid)
if (inst->mariadb10_compat && inst->mariadb10_master_gtid)
{
if (!inst->trx_safe)
{
MXS_ERROR("MariaDB GTID can be enabled only"
" with Transaction Safety feature."
" Please enable it with option 'transaction_safety = on'");
free_instance(inst);
return NULL;
}
/* Create/Open R/W GTID sqlite3 storage */
if (!blr_open_gtid_maps_storage(inst))
{