Merge branch '2.1' into develop
This commit is contained in:
commit
54d4a562ce
@ -12,7 +12,7 @@
|
||||
* MySQL Monitor now has a failover mode.
|
||||
* Named Server Filter now supports wildcards for source option.
|
||||
* Binlog Server can now be configured to encrypt binlog files.
|
||||
* New filters, _cache, _ccrfilter_, _masking_, and _maxrows_ are introduced.
|
||||
* New filters, _cache_, _ccrfilter_, _insertstream_, _masking_, and _maxrows_ are introduced.
|
||||
|
||||
For more details, please refer to:
|
||||
* [MariaDB MaxScale 2.1.0 Release Notes](Release-Notes/MaxScale-2.1.0-Release-Notes.md)
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Consistent Critical Read Filter
|
||||
|
||||
This filter was introduced in MariaDB MaxScale 2.1.
|
||||
|
||||
## Overview
|
||||
|
||||
The Consistent Critical Read (CCR) filter allows consistent critical reads to be
|
||||
@ -68,3 +70,24 @@ An optional parameter that can be used to control which statements don't trigger
|
||||
the statement re-routing. This does the opposite of the _match_ parameter. The
|
||||
parameter value is a regular expression that is used to match against the SQL
|
||||
text. Only non-SELECT statements are inspected.
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Here is a minimal filter configuration for the CCRFilter which should solve most
|
||||
problems with critical reads after writes.
|
||||
|
||||
```
|
||||
[CCRFilter]
|
||||
type=filter
|
||||
module=ccrfilter
|
||||
time=5
|
||||
```
|
||||
|
||||
This configuration will force all read queries after a write to the master for 5
|
||||
seconds, preventing read scaling until the modifications have been replicated to
|
||||
the slaves.
|
||||
|
||||
For best performance, the value of _time_ should be slightly greater than the
|
||||
actual replication lag between the master and its slaves. If the number of
|
||||
critical read statements is known, the _count_ parameter could be used to
|
||||
control the number reads that are sent to the master.
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Cache
|
||||
|
||||
This filter was introduced in MariaDB MaxScale 2.1.
|
||||
|
||||
## Overview
|
||||
The cache filter is a simple cache that is capable of caching the result of
|
||||
SELECTs, so that subsequent identical SELECTs are served directly by MaxScale,
|
||||
@ -8,6 +10,11 @@ without the queries being routed to any server.
|
||||
_Note that the cache is still experimental and that non-backward compatible
|
||||
changes may be made._
|
||||
|
||||
Note that installing the cache causes all statements to be parsed. The
|
||||
implication of that is that unless statements _already_ need to be parsed,
|
||||
e.g. due to the presence of another filter or the chosen router, then adding
|
||||
the cache will not necessarily improve the performance, but may decrease it.
|
||||
|
||||
## Limitations
|
||||
|
||||
All of these limitations may be addressed in forthcoming releases.
|
||||
@ -639,3 +646,44 @@ The value is a boolean and the default is `false`.
|
||||
```
|
||||
storage_options=collect_statistics=true
|
||||
```
|
||||
|
||||
# Example
|
||||
|
||||
In the following we define a cache _MyCache_ that uses the cache storage module
|
||||
`storage_inmemory` and whose _soft ttl_ is `30` seconds and whose _hard ttl_ is
|
||||
`45` seconds. The cached data is shared between all threads and the maximum size
|
||||
of the cached data is `50` mebibytes. The rules for the cache are in the file
|
||||
`cache_rules.json`.
|
||||
|
||||
### Configuration
|
||||
```
|
||||
[MyCache]
|
||||
type=filter
|
||||
module=cache
|
||||
storage=storage_inmemory
|
||||
soft_ttl=30
|
||||
hard_ttl=45
|
||||
cached_data=shared
|
||||
max_size=50Mi
|
||||
rules=cache_rules.json
|
||||
|
||||
[MyService]
|
||||
type=service
|
||||
...
|
||||
filters=MyCache
|
||||
```
|
||||
|
||||
### `cache_rules.json`
|
||||
The rules specify that the data of the table `sbtest` should be cached.
|
||||
|
||||
```
|
||||
{
|
||||
"store": [
|
||||
{
|
||||
"attribute": "table",
|
||||
"op": "=",
|
||||
"value": "sbtest"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -1,5 +1,8 @@
|
||||
# Insert Stream Filter
|
||||
|
||||
This filter was introduced in MariaDB MaxScale 2.1.
|
||||
|
||||
## Overview
|
||||
The _insertstream_ filter converts bulk inserts into CSV data streams that are
|
||||
consumed by the backend server via the LOAD DATA LOCAL INFILE mechanism. This
|
||||
leverages the speed advantage of LOAD DATA LOCAL INFILE over regular inserts
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Masking
|
||||
|
||||
This filter was introduced in MariaDB MaxScale 2.1.
|
||||
|
||||
## Overview
|
||||
With the _masking_ filter it is possible to obfuscate the returned
|
||||
value of a particular column.
|
||||
@ -302,3 +304,47 @@ MaxScale> call command masking reload MyMaskingFilter
|
||||
```
|
||||
`MyMaskingFilter` refers to a particular filter section in the
|
||||
MariaDB MaxScale configuration file.
|
||||
|
||||
# Example
|
||||
|
||||
In the following we configure a masking filter _MyMasking_ that should always log a
|
||||
warning if a masking rule matches a column that is of a type that cannot be masked,
|
||||
and that should abort the client connection if a resultset package is larger than
|
||||
16MB. The rules for the masking filter are in the file `masking_rules.json`.
|
||||
|
||||
### Configuration
|
||||
```
|
||||
[MyMasking]
|
||||
type=filter
|
||||
module=masking
|
||||
warn_type_mismatch=always
|
||||
large_payload=abort
|
||||
rules=masking_rules.json
|
||||
|
||||
[MyService]
|
||||
type=service
|
||||
...
|
||||
filters=MyMasking
|
||||
```
|
||||
|
||||
### `masking_rules.json`
|
||||
|
||||
The rules specify that the data of a column whose name is `ssn`, should
|
||||
be replaced with the string _012345-ABCD_. If the length of the data is
|
||||
not exactly the same as the length of the replacement value, then the
|
||||
data should be replaced with as many _X_ characters as needed.
|
||||
```
|
||||
{
|
||||
"rules": [
|
||||
{
|
||||
"replace": {
|
||||
"column": "ssn"
|
||||
},
|
||||
"with": {
|
||||
"value": "012345-ABCD",
|
||||
"fill": "X"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
@ -1,5 +1,7 @@
|
||||
# Maxrows
|
||||
|
||||
This filter was introduced in MariaDB MaxScale 2.1.
|
||||
|
||||
## Overview
|
||||
The maxrows filter is capable of restricting the amount of rows that a SELECT,
|
||||
a prepared statement or stored procedure could return to the client application.
|
||||
@ -68,3 +70,16 @@ Default is `0`. To log everything, give `debug` a value of `3`.
|
||||
```
|
||||
debug=2
|
||||
```
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Here is an example of filter configuration where the max number of returned
|
||||
rows is 10000 and max allowed resultset size is 256KB
|
||||
|
||||
```
|
||||
[MaxRows]
|
||||
type=filter
|
||||
module=maxrows
|
||||
max_resultset_rows=10000
|
||||
max_resultset_size=256000
|
||||
```
|
||||
|
@ -10,6 +10,38 @@ report at [Jira](https://jira.mariadb.org).
|
||||
|
||||
## Changed Features
|
||||
|
||||
### `router_options` to Parameters
|
||||
|
||||
The `router_options` values can also be given as parameters to the service for
|
||||
the _readwritesplit_, _schemarouter_ and _binlogrouter_ modules.
|
||||
|
||||
What this means is that in MaxScale 2.1 the following _readwritesplit_
|
||||
configration.
|
||||
|
||||
```
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1
|
||||
user=maxuser
|
||||
passwd=maxpwd
|
||||
router_options=slave_selection_criteria=LEAST_ROUTER_CONNECTIONS,max_sescmd_history=10,disable_sescmd_history=false
|
||||
```
|
||||
|
||||
Can also be written in the following form.
|
||||
|
||||
```
|
||||
[RW Split Router]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1
|
||||
user=maxuser
|
||||
passwd=maxpwd
|
||||
slave_selection_criteria=LEAST_ROUTER_CONNECTIONS
|
||||
max_sescmd_history=10
|
||||
disable_sescmd_history=false
|
||||
```
|
||||
|
||||
### Configuration Files
|
||||
|
||||
From 2.1.0 onwards MariaDB MaxScale supports hierarchical configuration
|
||||
@ -271,6 +303,17 @@ to large sets of data with a single query.
|
||||
For more information, refer to the [Maxrows](../Filters/Maxrows.md)
|
||||
documentation.
|
||||
|
||||
### Insert stream filter
|
||||
|
||||
The _insertstream_ filter converts bulk inserts into CSV data streams that are
|
||||
consumed by the backend server via the LOAD DATA LOCAL INFILE mechanism. This
|
||||
leverages the speed advantage of LOAD DATA LOCAL INFILE over regular inserts
|
||||
while also reducing the overall network traffic by condensing the inserted
|
||||
values into CSV.
|
||||
|
||||
For more information, refer to the [Insert Stream Filter](../Filters/Insert-Stream-Filter.md)
|
||||
documentation.
|
||||
|
||||
### Galeramon Monitor new option
|
||||
The `set_donor_nodes` option allows the setting of _global variable_ _wsrep_sst_donor_ with a list the preferred donor nodes (among slave ones).
|
||||
|
||||
|
56
Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md
Normal file
56
Documentation/Upgrading/Upgrading-To-MaxScale-2.1.md
Normal file
@ -0,0 +1,56 @@
|
||||
# Upgrading MariaDB MaxScale from 2.0 to 2.1
|
||||
|
||||
This document describes particular issues to take into account when upgrading
|
||||
MariaDB MaxScale from version 2.0 to 2.1.
|
||||
|
||||
For more information about MariaDB MaxScale 2.1, please refer to the
|
||||
[ChangeLog](../Changelog.md).
|
||||
|
||||
For a complete list of changes in MaxScale 2.1.0, refer to the
|
||||
[MaxScale 2.1.0 Release Notes](../Release-Notes/MaxScale-2.1.0-Release-Notes.md).
|
||||
|
||||
## Installation
|
||||
|
||||
Before starting the upgrade, we **strongly** recommend you back up your current
|
||||
configuration file.
|
||||
|
||||
## MaxScale Log Files
|
||||
|
||||
The name of the log file was changed from _maxscaleN.log_ to _maxscale.log_. The
|
||||
default location for the log file is _/var/log/maxscale/maxscale.log_.
|
||||
|
||||
Rotating the log files will cause MaxScale to reopen the file instead of
|
||||
renaming them. This makes the MaxScale logging facility _logrotate_ compatible.
|
||||
|
||||
## ReadWriteSplit
|
||||
|
||||
The `disable_sescmd_history` option is now enabled by default. This means that
|
||||
slaves will not be recovered mid-session even if a replacement slave is
|
||||
available. To enable the legacy behavior, add the `disable_sescmd_history=true`
|
||||
parameter to the service definition.
|
||||
|
||||
## Persistent Connections
|
||||
|
||||
The MySQL session state is reset in MaxScale 2.1 for persistent
|
||||
connections. This means that any modifications to the session state (default
|
||||
database, user variable etc.) will not survive if the connection is put into the
|
||||
connection pool. For most users, this is the expected behavior.
|
||||
|
||||
## User Data Cache
|
||||
|
||||
The location of the MySQL user data cache was moved from
|
||||
`/var/cache/maxscale/<Service>` to `/var/cache/maxscale/<Service>/<Listener>`.
|
||||
|
||||
## Galeramon Monitoring Algorithm
|
||||
|
||||
Galeramon will assign the master status *only* to the node which has a
|
||||
_wsrep_local_index_ value of 0. This will guarantee consistent writes with
|
||||
multiple MaxScales but it also causes slower changes of the master node.
|
||||
|
||||
To enable the legacy behavior, add `root_node_as_master=false` to the Galera
|
||||
monitor configuration.
|
||||
|
||||
## MaxAdmin Editing Mode
|
||||
|
||||
The default editing mode was changed from _vim_ to _emacs_ mode. To start
|
||||
maxadmin in the legacy mode, use the `-i` option.
|
@ -190,7 +190,6 @@ typedef struct dcb
|
||||
bool draining_flag; /**< Set while write queue is drained */
|
||||
bool drain_called_while_busy; /**< Set as described */
|
||||
dcb_role_t dcb_role;
|
||||
SPINLOCK dcb_initlock;
|
||||
DCBEVENTQ evq; /**< The event queue for this DCB */
|
||||
int fd; /**< The descriptor */
|
||||
dcb_state_t state; /**< Current descriptor state */
|
||||
@ -207,32 +206,20 @@ typedef struct dcb
|
||||
struct servlistener *listener; /**< For a client DCB, the listener data */
|
||||
MXS_PROTOCOL func; /**< The protocol functions for this descriptor */
|
||||
MXS_AUTHENTICATOR authfunc; /**< The authenticator functions for this descriptor */
|
||||
|
||||
int writeqlen; /**< Current number of byes in the write queue */
|
||||
SPINLOCK writeqlock; /**< Write Queue spinlock */
|
||||
GWBUF *writeq; /**< Write Data Queue */
|
||||
SPINLOCK delayqlock; /**< Delay Backend Write Queue spinlock */
|
||||
GWBUF *delayq; /**< Delay Backend Write Data Queue */
|
||||
GWBUF *dcb_readqueue; /**< read queue for storing incomplete reads */
|
||||
GWBUF *dcb_fakequeue; /**< Fake event queue for generated events */
|
||||
|
||||
DCBSTATS stats; /**< DCB related statistics */
|
||||
unsigned int dcb_server_status; /*< the server role indicator from SERVER */
|
||||
struct dcb *nextpersistent; /**< Next DCB in the persistent pool for SERVER */
|
||||
time_t persistentstart; /**< Time when DCB placed in persistent pool */
|
||||
struct service *service; /**< The related service */
|
||||
void *data; /**< Specific client data, shared between DCBs of this session */
|
||||
void *authenticator_data; /**< The authenticator data for this DCB */
|
||||
DCBMM memdata; /**< The data related to DCB memory management */
|
||||
SPINLOCK cb_lock; /**< The lock for the callbacks linked list */
|
||||
DCB_CALLBACK *callbacks; /**< The list of callbacks for the DCB */
|
||||
SPINLOCK pollinlock;
|
||||
int pollinbusy;
|
||||
int readcheck;
|
||||
|
||||
SPINLOCK polloutlock;
|
||||
int polloutbusy;
|
||||
int writecheck;
|
||||
long last_read; /*< Last time the DCB received data */
|
||||
int high_water; /**< High water mark */
|
||||
int low_water; /**< Low water mark */
|
||||
@ -242,7 +229,6 @@ typedef struct dcb
|
||||
bool ssl_read_want_write; /*< Flag */
|
||||
bool ssl_write_want_read; /*< Flag */
|
||||
bool ssl_write_want_write; /*< Flag */
|
||||
int dcb_port; /**< port of target server */
|
||||
bool was_persistent; /**< Whether this DCB was in the persistent pool */
|
||||
struct
|
||||
{
|
||||
@ -253,13 +239,11 @@ typedef struct dcb
|
||||
skygw_chk_t dcb_chk_tail;
|
||||
} DCB;
|
||||
|
||||
#define DCB_INIT {.dcb_chk_top = CHK_NUM_DCB, .dcb_initlock = SPINLOCK_INIT, \
|
||||
#define DCB_INIT {.dcb_chk_top = CHK_NUM_DCB, \
|
||||
.evq = DCBEVENTQ_INIT, .ipv4 = {0}, .func = {0}, .authfunc = {0}, \
|
||||
.writeqlock = SPINLOCK_INIT, .delayqlock = SPINLOCK_INIT, \
|
||||
.stats = {0}, .memdata = DCBMM_INIT, \
|
||||
.cb_lock = SPINLOCK_INIT, .pollinlock = SPINLOCK_INIT, \
|
||||
.fd = DCBFD_CLOSED, .stats = DCBSTATS_INIT, .ssl_state = SSL_HANDSHAKE_UNKNOWN, \
|
||||
.state = DCB_STATE_ALLOC, .polloutlock = SPINLOCK_INIT, .dcb_chk_tail = CHK_NUM_DCB, \
|
||||
.state = DCB_STATE_ALLOC, .dcb_chk_tail = CHK_NUM_DCB, \
|
||||
.authenticator_data = NULL, .thread = {0}}
|
||||
|
||||
/**
|
||||
|
@ -269,7 +269,6 @@ typedef struct
|
||||
#endif
|
||||
int fd; /*< The socket descriptor */
|
||||
struct dcb* owner_dcb; /*< The DCB of the socket we are running on */
|
||||
SPINLOCK protocol_lock; /*< Protocol lock */
|
||||
mysql_server_cmd_t current_command; /*< Current command being executed */
|
||||
server_command_t protocol_command; /*< session command list */
|
||||
server_command_t* protocol_cmd_history; /*< session command history */
|
||||
|
@ -126,7 +126,6 @@ typedef struct mxs_upstream
|
||||
typedef struct session
|
||||
{
|
||||
skygw_chk_t ses_chk_top;
|
||||
SPINLOCK ses_lock;
|
||||
mxs_session_state_t state; /*< Current descriptor state */
|
||||
size_t ses_id; /*< Unique session identifier */
|
||||
int enabled_log_priorities; /*< Bitfield of enabled syslog priorities */
|
||||
|
@ -1931,8 +1931,9 @@ check_config_objects(CONFIG_CONTEXT *context)
|
||||
if (mod == NULL ||
|
||||
!config_param_is_valid(mod->parameters, params->name, params->value, context))
|
||||
{
|
||||
MXS_ERROR("Unexpected parameter '%s' or parameter value for object '%s' of type '%s'.",
|
||||
params->name, obj->object, type);
|
||||
MXS_ERROR("Unexpected parameter '%s' for object '%s' of type '%s', "
|
||||
"or '%s' is an invalid value for parameter '%s'.",
|
||||
params->name, obj->object, type, params->value, params->name);
|
||||
rval = false;
|
||||
}
|
||||
else if (is_path_parameter(mod->parameters, params->name))
|
||||
|
@ -429,13 +429,13 @@ dcb_free_all_memory(DCB *dcb)
|
||||
gwbuf_free(dcb->dcb_fakequeue);
|
||||
dcb->dcb_fakequeue = NULL;
|
||||
}
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
|
||||
while ((cb_dcb = dcb->callbacks) != NULL)
|
||||
{
|
||||
dcb->callbacks = cb_dcb->next;
|
||||
MXS_FREE(cb_dcb);
|
||||
}
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
|
||||
if (dcb->ssl)
|
||||
{
|
||||
SSL_free(dcb->ssl);
|
||||
@ -757,10 +757,6 @@ dcb_connect(SERVER *server, MXS_SESSION *session, const char *protocol)
|
||||
*/
|
||||
dcb->server = server;
|
||||
|
||||
/** Copy status field to DCB */
|
||||
dcb->dcb_server_status = server->status;
|
||||
dcb->dcb_port = server->port;
|
||||
|
||||
dcb->was_persistent = false;
|
||||
|
||||
/**
|
||||
@ -1721,13 +1717,13 @@ dcb_maybe_add_persistent(DCB *dcb)
|
||||
session_put_ref(local_session);
|
||||
}
|
||||
}
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
|
||||
while ((loopcallback = dcb->callbacks) != NULL)
|
||||
{
|
||||
dcb->callbacks = loopcallback->next;
|
||||
MXS_FREE(loopcallback);
|
||||
}
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
|
||||
dcb->nextpersistent = dcb->server->persistent[dcb->thread.id];
|
||||
dcb->server->persistent[dcb->thread.id] = dcb;
|
||||
atomic_add(&dcb->server->stats.n_persistent, 1);
|
||||
@ -2070,20 +2066,7 @@ dprintDCB(DCB *pdcb, DCB *dcb)
|
||||
{
|
||||
dcb_printf(pdcb, "\t\tDCB is a clone.\n");
|
||||
}
|
||||
#if SPINLOCK_PROFILE
|
||||
dcb_printf(pdcb, "\tInitlock Statistics:\n");
|
||||
spinlock_stats(&dcb->dcb_initlock, spin_reporter, pdcb);
|
||||
dcb_printf(pdcb, "\tWrite Queue Lock Statistics:\n");
|
||||
spinlock_stats(&dcb->writeqlock, spin_reporter, pdcb);
|
||||
dcb_printf(pdcb, "\tDelay Queue Lock Statistics:\n");
|
||||
spinlock_stats(&dcb->delayqlock, spin_reporter, pdcb);
|
||||
dcb_printf(pdcb, "\tPollin Lock Statistics:\n");
|
||||
spinlock_stats(&dcb->pollinlock, spin_reporter, pdcb);
|
||||
dcb_printf(pdcb, "\tPollout Lock Statistics:\n");
|
||||
spinlock_stats(&dcb->polloutlock, spin_reporter, pdcb);
|
||||
dcb_printf(pdcb, "\tCallback Lock Statistics:\n");
|
||||
spinlock_stats(&dcb->cb_lock, spin_reporter, pdcb);
|
||||
#endif
|
||||
|
||||
if (dcb->persistentstart)
|
||||
{
|
||||
char buff[20];
|
||||
@ -2337,8 +2320,8 @@ dcb_add_callback(DCB *dcb,
|
||||
ptr->cb = callback;
|
||||
ptr->userdata = userdata;
|
||||
ptr->next = NULL;
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
cb = dcb->callbacks;
|
||||
|
||||
while (cb)
|
||||
{
|
||||
if (cb->reason == reason && cb->cb == callback &&
|
||||
@ -2346,7 +2329,6 @@ dcb_add_callback(DCB *dcb,
|
||||
{
|
||||
/* Callback is a duplicate, abandon it */
|
||||
MXS_FREE(ptr);
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
return 0;
|
||||
}
|
||||
lastcb = cb;
|
||||
@ -2360,7 +2342,7 @@ dcb_add_callback(DCB *dcb,
|
||||
{
|
||||
lastcb->next = ptr;
|
||||
}
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2384,9 +2366,8 @@ dcb_remove_callback(DCB *dcb,
|
||||
{
|
||||
DCB_CALLBACK *cb, *pcb = NULL;
|
||||
int rval = 0;
|
||||
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
cb = dcb->callbacks;
|
||||
|
||||
if (cb == NULL)
|
||||
{
|
||||
rval = 0;
|
||||
@ -2407,7 +2388,7 @@ dcb_remove_callback(DCB *dcb,
|
||||
{
|
||||
dcb->callbacks = cb->next;
|
||||
}
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
|
||||
MXS_FREE(cb);
|
||||
rval = 1;
|
||||
break;
|
||||
@ -2416,10 +2397,7 @@ dcb_remove_callback(DCB *dcb,
|
||||
cb = cb->next;
|
||||
}
|
||||
}
|
||||
if (!rval)
|
||||
{
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
@ -2433,22 +2411,19 @@ static void
|
||||
dcb_call_callback(DCB *dcb, DCB_REASON reason)
|
||||
{
|
||||
DCB_CALLBACK *cb, *nextcb;
|
||||
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
cb = dcb->callbacks;
|
||||
|
||||
while (cb)
|
||||
{
|
||||
if (cb->reason == reason)
|
||||
{
|
||||
nextcb = cb->next;
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
|
||||
MXS_DEBUG("%lu [dcb_call_callback] %s",
|
||||
pthread_self(),
|
||||
STRDCBREASON(reason));
|
||||
|
||||
cb->cb(dcb, reason, cb->userdata);
|
||||
spinlock_acquire(&dcb->cb_lock);
|
||||
cb = nextcb;
|
||||
}
|
||||
else
|
||||
@ -2456,7 +2431,6 @@ dcb_call_callback(DCB *dcb, DCB_REASON reason)
|
||||
cb = cb->next;
|
||||
}
|
||||
}
|
||||
spinlock_release(&dcb->cb_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2488,13 +2462,11 @@ dcb_hangup_foreach(struct server* server)
|
||||
|
||||
for (DCB *dcb = all_dcbs[i]; dcb; dcb = dcb->thread.next)
|
||||
{
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
if (dcb->state == DCB_STATE_POLLING && dcb->server &&
|
||||
dcb->server == server)
|
||||
{
|
||||
poll_fake_hangup_event(dcb);
|
||||
}
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
}
|
||||
|
||||
spinlock_release(&all_dcbs_lock[i]);
|
||||
|
@ -25,7 +25,7 @@ MXS_BEGIN_DECLS
|
||||
#define MXS_UPSTREAM_INIT {0}
|
||||
#define SESSION_FILTER_INIT {0}
|
||||
|
||||
#define SESSION_INIT {.ses_chk_top = CHK_NUM_SESSION, .ses_lock = SPINLOCK_INIT, \
|
||||
#define SESSION_INIT {.ses_chk_top = CHK_NUM_SESSION, \
|
||||
.stats = SESSION_STATS_INIT, .head = MXS_DOWNSTREAM_INIT, .tail = MXS_UPSTREAM_INIT, \
|
||||
.state = SESSION_STATE_ALLOC, .ses_chk_tail = CHK_NUM_SESSION}
|
||||
|
||||
|
@ -337,7 +337,6 @@ int poll_add_dcb(DCB *dcb)
|
||||
/*<
|
||||
* Choose new state according to the role of dcb.
|
||||
*/
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
if (dcb->dcb_role == DCB_ROLE_CLIENT_HANDLER || dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER)
|
||||
{
|
||||
new_state = DCB_STATE_POLLING;
|
||||
@ -388,7 +387,6 @@ int poll_add_dcb(DCB *dcb)
|
||||
}
|
||||
|
||||
dcb->thread.id = owner;
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
|
||||
dcb_add_to_list(dcb);
|
||||
|
||||
@ -396,7 +394,6 @@ int poll_add_dcb(DCB *dcb)
|
||||
|
||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
||||
{
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
/** Listeners are added to all epoll instances */
|
||||
int nthr = config_threadcount();
|
||||
|
||||
@ -413,7 +410,6 @@ int poll_add_dcb(DCB *dcb)
|
||||
break;
|
||||
}
|
||||
}
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -448,12 +444,10 @@ int poll_remove_dcb(DCB *dcb)
|
||||
struct epoll_event ev;
|
||||
CHK_DCB(dcb);
|
||||
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
/*< It is possible that dcb has already been removed from the set */
|
||||
if (dcb->state == DCB_STATE_NOPOLLING ||
|
||||
dcb->state == DCB_STATE_ZOMBIE)
|
||||
{
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
return 0;
|
||||
}
|
||||
if (DCB_STATE_POLLING != dcb->state
|
||||
@ -478,7 +472,6 @@ int poll_remove_dcb(DCB *dcb)
|
||||
* DCB_STATE_NOPOLLING.
|
||||
*/
|
||||
dcbfd = dcb->fd;
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
|
||||
if (dcbfd > 0)
|
||||
{
|
||||
@ -486,7 +479,6 @@ int poll_remove_dcb(DCB *dcb)
|
||||
|
||||
if (dcb->dcb_role == DCB_ROLE_SERVICE_LISTENER)
|
||||
{
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
/** Listeners are added to all epoll instances */
|
||||
int nthr = config_threadcount();
|
||||
|
||||
@ -502,7 +494,6 @@ int poll_remove_dcb(DCB *dcb)
|
||||
ss_dassert(error_num);
|
||||
}
|
||||
}
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -925,15 +916,12 @@ process_pollq(int thread_id, struct epoll_event *event)
|
||||
thread_data[thread_id].event = ev;
|
||||
}
|
||||
|
||||
ss_debug(spinlock_acquire(&dcb->dcb_initlock));
|
||||
ss_dassert(dcb->state != DCB_STATE_ALLOC);
|
||||
/* It isn't obvious that this is impossible */
|
||||
/* ss_dassert(dcb->state != DCB_STATE_DISCONNECTED); */
|
||||
if (DCB_STATE_DISCONNECTED == dcb->state)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
ss_debug(spinlock_release(&dcb->dcb_initlock));
|
||||
|
||||
MXS_DEBUG("%lu [poll_waitevents] event %d dcb %p "
|
||||
"role %s",
|
||||
@ -1059,11 +1047,10 @@ process_pollq(int thread_id, struct epoll_event *event)
|
||||
eno,
|
||||
strerror_r(eno, errbuf, sizeof(errbuf)));
|
||||
ts_stats_increment(pollStats.n_hup, thread_id);
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
if ((dcb->flags & DCBF_HUNG) == 0)
|
||||
{
|
||||
dcb->flags |= DCBF_HUNG;
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
|
||||
/** Read session id to thread's local storage */
|
||||
dcb_get_ses_log_info(dcb,
|
||||
&mxs_log_tls.li_sesid,
|
||||
@ -1074,10 +1061,6 @@ process_pollq(int thread_id, struct epoll_event *event)
|
||||
dcb->func.hangup(dcb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EPOLLRDHUP
|
||||
@ -1094,11 +1077,11 @@ process_pollq(int thread_id, struct epoll_event *event)
|
||||
eno,
|
||||
strerror_r(eno, errbuf, sizeof(errbuf)));
|
||||
ts_stats_increment(pollStats.n_hup, thread_id);
|
||||
spinlock_acquire(&dcb->dcb_initlock);
|
||||
|
||||
if ((dcb->flags & DCBF_HUNG) == 0)
|
||||
{
|
||||
dcb->flags |= DCBF_HUNG;
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
|
||||
/** Read session id to thread's local storage */
|
||||
dcb_get_ses_log_info(dcb,
|
||||
&mxs_log_tls.li_sesid,
|
||||
@ -1109,10 +1092,6 @@ process_pollq(int thread_id, struct epoll_event *event)
|
||||
dcb->func.hangup(dcb);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&dcb->dcb_initlock);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/random_jkiss.h>
|
||||
|
||||
/* Public domain code for JKISS RNG - Comment header added */
|
||||
@ -42,8 +41,6 @@
|
||||
static unsigned int x = 123456789, y = 987654321, z = 43219876, c = 6543217; /* Seed variables */
|
||||
static bool init = false;
|
||||
|
||||
static SPINLOCK random_jkiss_spinlock = SPINLOCK_INIT;
|
||||
|
||||
static unsigned int random_jkiss_devrand(void);
|
||||
static void random_init_jkiss(void);
|
||||
|
||||
@ -60,14 +57,11 @@ random_jkiss(void)
|
||||
unsigned long long t;
|
||||
unsigned int result;
|
||||
|
||||
spinlock_acquire(&random_jkiss_spinlock);
|
||||
if (!init)
|
||||
{
|
||||
/* Must set init first because initialisation calls this function */
|
||||
init = true;
|
||||
spinlock_release(&random_jkiss_spinlock);
|
||||
random_init_jkiss();
|
||||
spinlock_acquire(&random_jkiss_spinlock);
|
||||
}
|
||||
x = 314527869 * x + 1234567;
|
||||
y ^= y << 5;
|
||||
@ -77,7 +71,6 @@ random_jkiss(void)
|
||||
c = t >> 32;
|
||||
z = t;
|
||||
result = x + y + z;
|
||||
spinlock_release(&random_jkiss_spinlock);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -120,7 +113,6 @@ random_init_jkiss(void)
|
||||
{
|
||||
int newrand, i;
|
||||
|
||||
spinlock_acquire(&random_jkiss_spinlock);
|
||||
if ((newrand = random_jkiss_devrand()) != 0)
|
||||
{
|
||||
x = newrand;
|
||||
@ -140,7 +132,6 @@ random_init_jkiss(void)
|
||||
{
|
||||
c = newrand % 698769068 + 1; /* Should be less than 698769069 */
|
||||
}
|
||||
spinlock_release(&random_jkiss_spinlock);
|
||||
|
||||
/* "Warm up" our random number generator */
|
||||
for (i = 0; i < 100; i++)
|
||||
|
@ -230,7 +230,6 @@ session_set_dummy(DCB *client_dcb)
|
||||
session->ses_chk_top = CHK_NUM_SESSION;
|
||||
session->ses_chk_tail = CHK_NUM_SESSION;
|
||||
session->ses_is_child = false;
|
||||
spinlock_init(&session->ses_lock);
|
||||
session->service = NULL;
|
||||
session->client_dcb = NULL;
|
||||
session->n_filters = 0;
|
||||
@ -285,20 +284,17 @@ void session_disable_log_priority(MXS_SESSION* session, int priority)
|
||||
bool
|
||||
session_link_dcb(MXS_SESSION *session, DCB *dcb)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ss_info_dassert(session->state != SESSION_STATE_FREE,
|
||||
"If session->state is SESSION_STATE_FREE then this attempt to "
|
||||
"access freed memory block.");
|
||||
if (session->state == SESSION_STATE_FREE)
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
return false;
|
||||
}
|
||||
atomic_add(&session->refcount, 1);
|
||||
dcb->session = session;
|
||||
/** Move this DCB under the same thread */
|
||||
dcb->thread.id = session->client_dcb->thread.id;
|
||||
spinlock_release(&session->ses_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -6,6 +6,7 @@ add_subdirectory(hintfilter)
|
||||
add_subdirectory(luafilter)
|
||||
add_subdirectory(mqfilter)
|
||||
add_subdirectory(namedserverfilter)
|
||||
add_subdirectory(nullfilter)
|
||||
add_subdirectory(qlafilter)
|
||||
add_subdirectory(regexfilter)
|
||||
add_subdirectory(tee)
|
||||
|
7
server/modules/filter/nullfilter/CMakeLists.txt
Normal file
7
server/modules/filter/nullfilter/CMakeLists.txt
Normal file
@ -0,0 +1,7 @@
|
||||
add_library(nullfilter SHARED
|
||||
nullfilter.cc
|
||||
nullfiltersession.cc
|
||||
)
|
||||
target_link_libraries(nullfilter maxscale-common)
|
||||
set_target_properties(nullfilter PROPERTIES VERSION "1.0.0")
|
||||
install_module(nullfilter core)
|
133
server/modules/filter/nullfilter/nullfilter.cc
Normal file
133
server/modules/filter/nullfilter/nullfilter.cc
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-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.
|
||||
*/
|
||||
|
||||
#define MXS_MODULE_NAME "nullfilter"
|
||||
#include "nullfilter.hh"
|
||||
#include <string>
|
||||
#include <maxscale/utils.h>
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
#define VERSION_STRING "V1.0.0"
|
||||
|
||||
const char CAPABILITIES_PARAM[] = "capabilities";
|
||||
|
||||
MXS_ENUM_VALUE capability_values[] =
|
||||
{
|
||||
{ "RCAP_TYPE_STMT_INPUT", RCAP_TYPE_STMT_INPUT },
|
||||
{ "RCAP_TYPE_CONTIGUOUS_INPUT", RCAP_TYPE_CONTIGUOUS_INPUT },
|
||||
{ "RCAP_TYPE_TRANSACTION_TRACKING", RCAP_TYPE_TRANSACTION_TRACKING },
|
||||
{ "RCAP_TYPE_STMT_OUTPUT", RCAP_TYPE_STMT_OUTPUT },
|
||||
{ "RCAP_TYPE_CONTIGUOUS_OUTPUT", RCAP_TYPE_CONTIGUOUS_OUTPUT },
|
||||
{ "RCAP_TYPE_RESULTSET_OUTPUT", RCAP_TYPE_RESULTSET_OUTPUT },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
struct unit_variables
|
||||
{
|
||||
uint64_t capabilities;
|
||||
bool capabilities_set;
|
||||
} this_unit =
|
||||
{
|
||||
0,
|
||||
false
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Global symbols of the Module
|
||||
//
|
||||
|
||||
extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
MXS_NOTICE("Nullfilter module %s initialized.", VERSION_STRING);
|
||||
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_FILTER,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_FILTER_VERSION,
|
||||
"A null filter that does nothing.",
|
||||
VERSION_STRING,
|
||||
&NullFilter::s_object,
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{ CAPABILITIES_PARAM, MXS_MODULE_PARAM_ENUM, NULL, MXS_MODULE_OPT_REQUIRED, capability_values },
|
||||
{ MXS_END_MODULE_PARAMS }
|
||||
}
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
//
|
||||
// NullFilter
|
||||
//
|
||||
|
||||
NullFilter::NullFilter(const char* zName)
|
||||
{
|
||||
MXS_NOTICE("Null filter [%s] created.", zName);
|
||||
}
|
||||
|
||||
NullFilter::~NullFilter()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
NullFilter* NullFilter::create(const char* zName, char**, MXS_CONFIG_PARAMETER* pParams)
|
||||
{
|
||||
NullFilter* pFilter = NULL;
|
||||
|
||||
uint64_t capabilities = config_get_enum(pParams, CAPABILITIES_PARAM, capability_values);
|
||||
|
||||
if (this_unit.capabilities_set)
|
||||
{
|
||||
MXS_WARNING("The capabilities reported by NullFilter are currently global, "
|
||||
"and not specific for a particular NullFilter instance.");
|
||||
}
|
||||
|
||||
this_unit.capabilities = capabilities;
|
||||
this_unit.capabilities_set = true;
|
||||
|
||||
return new NullFilter(zName);
|
||||
}
|
||||
|
||||
|
||||
NullFilterSession* NullFilter::newSession(MXS_SESSION* pSession)
|
||||
{
|
||||
return NullFilterSession::create(pSession, this);
|
||||
}
|
||||
|
||||
// static
|
||||
void NullFilter::diagnostics(DCB* pDcb)
|
||||
{
|
||||
dcb_printf(pDcb, "Hello, World!\n");
|
||||
}
|
||||
|
||||
// static
|
||||
uint64_t NullFilter::getCapabilities()
|
||||
{
|
||||
if (!this_unit.capabilities_set)
|
||||
{
|
||||
MXS_ERROR("getCapabilities() called before they have been set.");
|
||||
}
|
||||
|
||||
return this_unit.capabilities;
|
||||
}
|
36
server/modules/filter/nullfilter/nullfilter.hh
Normal file
36
server/modules/filter/nullfilter/nullfilter.hh
Normal file
@ -0,0 +1,36 @@
|
||||
#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/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-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.
|
||||
*/
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
#include "nullfiltersession.hh"
|
||||
|
||||
class NullFilter : public maxscale::Filter<NullFilter, NullFilterSession>
|
||||
{
|
||||
public:
|
||||
~NullFilter();
|
||||
static NullFilter* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* pParams);
|
||||
|
||||
NullFilterSession* newSession(MXS_SESSION* pSession);
|
||||
|
||||
void diagnostics(DCB* pDcb);
|
||||
|
||||
static uint64_t getCapabilities();
|
||||
|
||||
private:
|
||||
NullFilter(const char* zName);
|
||||
|
||||
NullFilter(const NullFilter&);
|
||||
NullFilter& operator = (const NullFilter&);
|
||||
};
|
31
server/modules/filter/nullfilter/nullfiltersession.cc
Normal file
31
server/modules/filter/nullfilter/nullfiltersession.cc
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-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.
|
||||
*/
|
||||
|
||||
#define MXS_MODULE_NAME "nullfilter"
|
||||
#include "nullfiltersession.hh"
|
||||
|
||||
NullFilterSession::NullFilterSession(MXS_SESSION* pSession, const NullFilter* pFilter)
|
||||
: maxscale::FilterSession(pSession)
|
||||
, m_filter(*pFilter)
|
||||
{
|
||||
}
|
||||
|
||||
NullFilterSession::~NullFilterSession()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
NullFilterSession* NullFilterSession::create(MXS_SESSION* pSession, const NullFilter* pFilter)
|
||||
{
|
||||
return new NullFilterSession(pSession, pFilter);
|
||||
}
|
35
server/modules/filter/nullfilter/nullfiltersession.hh
Normal file
35
server/modules/filter/nullfilter/nullfiltersession.hh
Normal file
@ -0,0 +1,35 @@
|
||||
#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/bsl.
|
||||
*
|
||||
* Change Date: 2019-07-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.
|
||||
*/
|
||||
|
||||
#include <maxscale/cppdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
|
||||
class NullFilter;
|
||||
|
||||
class NullFilterSession : public maxscale::FilterSession
|
||||
{
|
||||
public:
|
||||
~NullFilterSession();
|
||||
|
||||
static NullFilterSession* create(MXS_SESSION* pSession, const NullFilter* pFilter);
|
||||
|
||||
private:
|
||||
NullFilterSession(MXS_SESSION* pSession, const NullFilter* pFilter);
|
||||
|
||||
NullFilterSession(const NullFilterSession&);
|
||||
NullFilterSession& operator = (const NullFilterSession&);
|
||||
|
||||
private:
|
||||
const NullFilter& m_filter;
|
||||
};
|
@ -536,7 +536,6 @@ closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
if ((bsession = my_session->branch_session) != NULL)
|
||||
{
|
||||
CHK_SESSION(bsession);
|
||||
spinlock_acquire(&bsession->ses_lock);
|
||||
|
||||
if (bsession->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
@ -545,7 +544,6 @@ closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
||||
router = bsession->service->router;
|
||||
router_instance = bsession->service->router_instance;
|
||||
rsession = bsession->router_session;
|
||||
spinlock_release(&bsession->ses_lock);
|
||||
|
||||
/** Close router session and all its connections */
|
||||
router->closeSession(router_instance, rsession);
|
||||
|
@ -637,9 +637,7 @@ gw_reply_on_error(DCB *dcb, mxs_auth_state_t state)
|
||||
session->router_session,
|
||||
errbuf, dcb, ERRACT_REPLY_CLIENT, &succp);
|
||||
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
ss_dassert(dcb->dcb_errhandle_called);
|
||||
}
|
||||
else
|
||||
@ -736,9 +734,7 @@ gw_read_and_write(DCB *dcb)
|
||||
|
||||
if (!succp)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1173,22 +1169,7 @@ static int gw_error_backend_event(DCB *dcb)
|
||||
0,
|
||||
"Lost connection to backend server.");
|
||||
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ses_state = session->state;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
/**
|
||||
* Session might be initialized when DCB already is in the poll set.
|
||||
* Thus hangup can occur in the middle of session initialization.
|
||||
* Only complete and successfully initialized sessions allow for
|
||||
* calling error handler.
|
||||
*/
|
||||
while (ses_state == SESSION_STATE_READY)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ses_state = session->state;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
if (ses_state != SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
@ -1225,9 +1206,7 @@ static int gw_error_backend_event(DCB *dcb)
|
||||
*/
|
||||
if (!succp)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
retblock:
|
||||
@ -1277,22 +1256,7 @@ static int gw_backend_hangup(DCB *dcb)
|
||||
0,
|
||||
"Lost connection to backend server.");
|
||||
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ses_state = session->state;
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
/**
|
||||
* Session might be initialized when DCB already is in the poll set.
|
||||
* Thus hangup can occur in the middle of session initialization.
|
||||
* Only complete and successfully initialized sessions allow for
|
||||
* calling error handler.
|
||||
*/
|
||||
while (ses_state == SESSION_STATE_READY)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
ses_state = session->state;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
if (ses_state != SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
@ -1330,9 +1294,7 @@ static int gw_backend_hangup(DCB *dcb)
|
||||
/** There are no required backends available, close session. */
|
||||
if (!succp)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
retblock:
|
||||
@ -1371,7 +1333,7 @@ static int gw_backend_close(DCB *dcb)
|
||||
* but client's close and adding client's DCB to zombies list is executed
|
||||
* only if client's DCB's state does _not_ change in parallel.
|
||||
*/
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
|
||||
/**
|
||||
* If session->state is STOPPING, start closing client session.
|
||||
* Otherwise only this backend connection is closed.
|
||||
@ -1381,19 +1343,9 @@ static int gw_backend_close(DCB *dcb)
|
||||
{
|
||||
if (session->client_dcb->state == DCB_STATE_POLLING)
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
/** Close client DCB */
|
||||
dcb_close(session->client_dcb);
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@ -1471,9 +1423,7 @@ static int backend_write_delayqueue(DCB *dcb, GWBUF *buffer)
|
||||
|
||||
if (!succp)
|
||||
{
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
session->state = SESSION_STATE_STOPPING;
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1564,8 +1514,6 @@ static int gw_change_user(DCB *backend,
|
||||
memcpy(&backend_protocol->charset, client_auth_packet, sizeof(int));
|
||||
}
|
||||
|
||||
spinlock_acquire(&in_session->ses_lock);
|
||||
|
||||
/* save current_database name */
|
||||
strcpy(current_database, current_session->db);
|
||||
|
||||
@ -1595,7 +1543,6 @@ static int gw_change_user(DCB *backend,
|
||||
client_sha1, sizeof(client_sha1));
|
||||
|
||||
strcpy(current_session->db, current_database);
|
||||
spinlock_release(&in_session->ses_lock);
|
||||
|
||||
if (auth_ret != 0)
|
||||
{
|
||||
@ -1603,7 +1550,6 @@ static int gw_change_user(DCB *backend,
|
||||
{
|
||||
/* Try authentication again with new repository data */
|
||||
/* Note: if no auth client authentication will fail */
|
||||
spinlock_acquire(&in_session->ses_lock);
|
||||
*current_session->db = 0;
|
||||
|
||||
auth_ret = dcb->authfunc.reauthenticate(dcb, username,
|
||||
@ -1613,7 +1559,6 @@ static int gw_change_user(DCB *backend,
|
||||
client_sha1, sizeof(client_sha1));
|
||||
|
||||
strcpy(current_session->db, current_database);
|
||||
spinlock_release(&in_session->ses_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,7 +1361,6 @@ gw_client_close(DCB *dcb)
|
||||
if (session != NULL && SESSION_STATE_DUMMY != session->state)
|
||||
{
|
||||
CHK_SESSION(session);
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
|
||||
if (session->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
@ -1375,14 +1374,9 @@ gw_client_close(DCB *dcb)
|
||||
*/
|
||||
if (session->router_session != NULL)
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
/** Close router session and all its connections */
|
||||
router->closeSession(router_instance, session->router_session);
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
@ -132,27 +132,21 @@ void mysql_protocol_done(DCB* dcb)
|
||||
|
||||
p = (MySQLProtocol *)dcb->protocol;
|
||||
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
|
||||
if (p->protocol_state != MYSQL_PROTOCOL_ACTIVE)
|
||||
if (p->protocol_state == MYSQL_PROTOCOL_ACTIVE)
|
||||
{
|
||||
goto retblock;
|
||||
scmd = p->protocol_cmd_history;
|
||||
|
||||
while (scmd != NULL)
|
||||
{
|
||||
scmd2 = scmd->scom_next;
|
||||
MXS_FREE(scmd);
|
||||
scmd = scmd2;
|
||||
}
|
||||
|
||||
gwbuf_free(p->stored_query);
|
||||
|
||||
p->protocol_state = MYSQL_PROTOCOL_DONE;
|
||||
}
|
||||
scmd = p->protocol_cmd_history;
|
||||
|
||||
while (scmd != NULL)
|
||||
{
|
||||
scmd2 = scmd->scom_next;
|
||||
MXS_FREE(scmd);
|
||||
scmd = scmd2;
|
||||
}
|
||||
|
||||
gwbuf_free(p->stored_query);
|
||||
|
||||
p->protocol_state = MYSQL_PROTOCOL_DONE;
|
||||
|
||||
retblock:
|
||||
spinlock_release(&p->protocol_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -660,8 +654,6 @@ void protocol_archive_srv_command(MySQLProtocol* p)
|
||||
|
||||
CHK_PROTOCOL(p);
|
||||
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
|
||||
if (p->protocol_state != MYSQL_PROTOCOL_ACTIVE)
|
||||
{
|
||||
goto retblock;
|
||||
@ -710,7 +702,6 @@ void protocol_archive_srv_command(MySQLProtocol* p)
|
||||
}
|
||||
|
||||
retblock:
|
||||
spinlock_release(&p->protocol_lock);
|
||||
CHK_PROTOCOL(p);
|
||||
}
|
||||
|
||||
@ -725,11 +716,10 @@ void protocol_add_srv_command(MySQLProtocol* p,
|
||||
#if defined(EXTRA_SS_DEBUG)
|
||||
server_command_t* c;
|
||||
#endif
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
|
||||
if (p->protocol_state != MYSQL_PROTOCOL_ACTIVE)
|
||||
{
|
||||
goto retblock;
|
||||
return;
|
||||
}
|
||||
/** this is the only server command in protocol */
|
||||
if (p->protocol_command.scom_cmd == MYSQL_COM_UNDEFINED)
|
||||
@ -758,8 +748,6 @@ void protocol_add_srv_command(MySQLProtocol* p,
|
||||
c = c->scom_next;
|
||||
}
|
||||
#endif
|
||||
retblock:
|
||||
spinlock_release(&p->protocol_lock);
|
||||
}
|
||||
|
||||
|
||||
@ -772,7 +760,7 @@ retblock:
|
||||
void protocol_remove_srv_command(MySQLProtocol* p)
|
||||
{
|
||||
server_command_t* s;
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
|
||||
s = &p->protocol_command;
|
||||
#if defined(EXTRA_SS_DEBUG)
|
||||
MXS_INFO("Removed command %s from fd %d.",
|
||||
@ -788,8 +776,6 @@ void protocol_remove_srv_command(MySQLProtocol* p)
|
||||
p->protocol_command = *(s->scom_next);
|
||||
MXS_FREE(s->scom_next);
|
||||
}
|
||||
|
||||
spinlock_release(&p->protocol_lock);
|
||||
}
|
||||
|
||||
mysql_server_cmd_t protocol_get_srv_command(MySQLProtocol* p,
|
||||
@ -889,10 +875,8 @@ bool protocol_get_response_status(MySQLProtocol* p,
|
||||
|
||||
CHK_PROTOCOL(p);
|
||||
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
*npackets = p->protocol_command.scom_nresponse_packets;
|
||||
*nbytes = (ssize_t)p->protocol_command.scom_nbytes_to_read;
|
||||
spinlock_release(&p->protocol_lock);
|
||||
|
||||
if (*npackets < 0 && *nbytes == 0)
|
||||
{
|
||||
@ -912,14 +896,10 @@ void protocol_set_response_status(MySQLProtocol* p,
|
||||
{
|
||||
CHK_PROTOCOL(p);
|
||||
|
||||
spinlock_acquire(&p->protocol_lock);
|
||||
|
||||
p->protocol_command.scom_nbytes_to_read = nbytes;
|
||||
ss_dassert(p->protocol_command.scom_nbytes_to_read >= 0);
|
||||
|
||||
p->protocol_command.scom_nresponse_packets = npackets_left;
|
||||
|
||||
spinlock_release(&p->protocol_lock);
|
||||
}
|
||||
|
||||
char* create_auth_failed_msg(GWBUF*readbuf,
|
||||
|
@ -291,20 +291,15 @@ static void handleError(MXS_ROUTER *instance,
|
||||
{
|
||||
backend_dcb->dcb_errhandle_called = true;
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
|
||||
sesstate = session->state;
|
||||
client_dcb = session->client_dcb;
|
||||
|
||||
if (sesstate == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
CHK_DCB(client_dcb);
|
||||
spinlock_release(&session->ses_lock);
|
||||
client_dcb->func.write(client_dcb, gwbuf_clone(errbuf));
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
/** false because connection is not available anymore */
|
||||
dcb_close(backend_dcb);
|
||||
|
@ -82,7 +82,6 @@
|
||||
#include <maxscale/atomic.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/dcb.h>
|
||||
#include <maxscale/spinlock.h>
|
||||
#include <maxscale/modinfo.h>
|
||||
#include <maxscale/log_manager.h>
|
||||
#include <maxscale/protocol/mysql.h>
|
||||
@ -105,9 +104,6 @@ static void rses_end_locked_router_action(ROUTER_CLIENT_SES* rses);
|
||||
static SERVER_REF *get_root_master(SERVER_REF *servers);
|
||||
static int handle_state_switch(DCB* dcb, DCB_REASON reason, void * routersession);
|
||||
|
||||
static SPINLOCK instlock;
|
||||
static ROUTER_INSTANCE *instances;
|
||||
|
||||
/**
|
||||
* The module entry point routine. It is this routine that
|
||||
* must populate the structure that is referred to as the
|
||||
@ -119,8 +115,6 @@ static ROUTER_INSTANCE *instances;
|
||||
MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
MXS_NOTICE("Initialise readconnroute router module.");
|
||||
spinlock_init(&instlock);
|
||||
instances = NULL;
|
||||
|
||||
static MXS_ROUTER_OBJECT MyObject =
|
||||
{
|
||||
@ -252,10 +246,6 @@ createInstance(SERVICE *service, char **options)
|
||||
* insert this router instance into the linked list of routers
|
||||
* that have been created with this module.
|
||||
*/
|
||||
spinlock_acquire(&instlock);
|
||||
inst->next = instances;
|
||||
instances = inst;
|
||||
spinlock_release(&instlock);
|
||||
|
||||
return (MXS_ROUTER *) inst;
|
||||
}
|
||||
@ -710,20 +700,16 @@ static void handleError(MXS_ROUTER *instance, void *router_session, GWBUF *errbu
|
||||
{
|
||||
problem_dcb->dcb_errhandle_called = true;
|
||||
}
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
|
||||
sesstate = session->state;
|
||||
client_dcb = session->client_dcb;
|
||||
|
||||
if (sesstate == SESSION_STATE_ROUTER_READY)
|
||||
{
|
||||
CHK_DCB(client_dcb);
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
client_dcb->func.write(client_dcb, gwbuf_clone(errbuf));
|
||||
}
|
||||
else
|
||||
{
|
||||
spinlock_release(&session->ses_lock);
|
||||
}
|
||||
|
||||
if (DCB_ROLE_CLIENT_HANDLER == problem_dcb->dcb_role)
|
||||
{
|
||||
|
@ -1535,10 +1535,8 @@ static void handle_error_reply_client(MXS_SESSION *ses, ROUTER_CLIENT_SES *rses,
|
||||
DCB *client_dcb;
|
||||
backend_ref_t *bref;
|
||||
|
||||
spinlock_acquire(&ses->ses_lock);
|
||||
sesstate = ses->state;
|
||||
client_dcb = ses->client_dcb;
|
||||
spinlock_release(&ses->ses_lock);
|
||||
|
||||
if ((bref = get_bref_from_dcb(rses, backend_dcb)) != NULL)
|
||||
{
|
||||
|
@ -860,8 +860,6 @@ static void* newSession(MXS_ROUTER* router_inst, MXS_SESSION* session)
|
||||
bool using_db = false;
|
||||
bool have_db = false;
|
||||
|
||||
spinlock_acquire(&session->ses_lock);
|
||||
|
||||
/* To enable connecting directly to a sharded database we first need
|
||||
* to disable it for the client DCB's protocol so that we can connect to them*/
|
||||
if (protocol->client_capabilities & GW_MYSQL_CAPABILITIES_CONNECT_WITH_DB &&
|
||||
@ -880,8 +878,6 @@ static void* newSession(MXS_ROUTER* router_inst, MXS_SESSION* session)
|
||||
MXS_INFO("Client'%s' connecting with empty database.", data->user);
|
||||
}
|
||||
|
||||
spinlock_release(&session->ses_lock);
|
||||
|
||||
client_rses = (ROUTER_CLIENT_SES *)MXS_CALLOC(1, sizeof(ROUTER_CLIENT_SES));
|
||||
|
||||
if (client_rses == NULL)
|
||||
@ -3647,10 +3643,8 @@ static void handle_error_reply_client(MXS_SESSION* ses,
|
||||
DCB* client_dcb;
|
||||
backend_ref_t* bref;
|
||||
|
||||
spinlock_acquire(&ses->ses_lock);
|
||||
sesstate = ses->state;
|
||||
client_dcb = ses->client_dcb;
|
||||
spinlock_release(&ses->ses_lock);
|
||||
|
||||
/**
|
||||
* If bref exists, mark it closed
|
||||
|
Loading…
x
Reference in New Issue
Block a user