Merge branch 'release-1.3.0' into develop
This commit is contained in:
commit
cfefc046e9
@ -27,8 +27,6 @@
|
||||
## Reference
|
||||
|
||||
- [MaxAdmin](Reference/MaxAdmin.md)
|
||||
- [MaxScale HA with Corosync-Pacemaker](Reference/MaxScale-HA-with-Corosync-Pacemaker.md)
|
||||
- [MaxScale HA with Lsyncd](Reference/MaxScale-HA-with-lsyncd.md)
|
||||
- [How Errors are Handled in MaxScale](Reference/How-errors-are-handled-in-MaxScale.md)
|
||||
- [Debug and Diagnostic Support](Reference/Debug-And-Diagnostic-Support.md)
|
||||
- [Routing Hints](Reference/Hint-Syntax.md)
|
||||
@ -48,9 +46,14 @@ These tutorials are for specific use cases and module combinations.
|
||||
- [Replication Proxy with the Binlog Router Tutorial](Tutorials/Replication-Proxy-Binlog-Router-Tutorial.md)
|
||||
- [RabbitMQ Setup and MaxScale Integration Tutorial](Tutorials/RabbitMQ-Setup-And-MaxScale-Integration.md)
|
||||
- [RabbitMQ and Tee Filter Data Archiving Tutorial](Tutorials/RabbitMQ-And-Tee-Archiving.md)
|
||||
- [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md)
|
||||
- [Simple Schema Sharding Tutorial](Tutorials/Simple-Sharding-Tutorial.md)
|
||||
|
||||
Here are tutorials on monitoring and managing MaxScale in cluster envoronments.
|
||||
|
||||
- [Nagios Plugins for MaxScale Tutorial](Tutorials/Nagios-Plugins.md)
|
||||
- [MaxScale HA with Corosync-Pacemaker](Tutorials/MaxScale-HA-with-Corosync-Pacemaker.md)
|
||||
- [MaxScale HA with Lsyncd](Tutorials/MaxScale-HA-with-lsyncd.md)
|
||||
|
||||
## Routers
|
||||
|
||||
The routing module is the core of a MaxScale service. The router documentation
|
||||
|
@ -771,6 +771,8 @@ and short notations
|
||||
192.%.%
|
||||
192.168.%
|
||||
|
||||
Note that currently wildcards are only supported in conjunction with IP-addresses, not with domain names.
|
||||
|
||||
## Error Reporting
|
||||
|
||||
MaxScale is designed to be executed as a service, therefore all error reports, including configuration errors, are written to the MaxScale error log file. By default, MaxScale will log to a file in `/var/log/maxscale`, the only exception to this is if the log directory is not writable, in which case a message is sent to the standard error descriptor.
|
||||
|
@ -3,11 +3,7 @@
|
||||
This document describes the changes in release 1.3, when compared to
|
||||
release 1.2.1.
|
||||
|
||||
## 1.3.0 Beta
|
||||
|
||||
**NOTE** This is a beta release. We think it is better than 1.2.1,
|
||||
but there may still be rough edges. Keep that in mind when trying it
|
||||
out.
|
||||
## 1.3.0
|
||||
|
||||
For any problems you encounter, please consider submitting a bug
|
||||
report at [Jira](https://mariadb.atlassian.net).
|
||||
@ -149,85 +145,94 @@ details, please read the [Monitor Common](../Monitors/Monitor-Common.md) documen
|
||||
|
||||
## Bug fixes
|
||||
|
||||
Here is a list of bugs fixed since the release of MaxScale 1.2.1.
|
||||
[Here is a list of bugs fixed since the release of MaxScale 1.2.1.](https://mariadb.atlassian.net/browse/MXS-550?jql=project%20%3D%20MXS%20AND%20issuetype%20%3D%20Bug%20AND%20resolution%20in%20(Fixed%2C%20Done)%20AND%20fixVersion%20%3D%201.3.0)
|
||||
|
||||
* [MXS-414](https://mariadb.atlassian.net/browse/MXS-414): Maxscale crashed every day!
|
||||
* [MXS-415](https://mariadb.atlassian.net/browse/MXS-415): MaxScale 1.2.1 crashed with Signal 6 and 11
|
||||
* [MXS-351](https://mariadb.atlassian.net/browse/MXS-351): Router error handling can cause crash by leaving dangling DCB pointer
|
||||
* [MXS-428](https://mariadb.atlassian.net/browse/MXS-428): Maxscale crashes at startup.
|
||||
* [MXS-376](https://mariadb.atlassian.net/browse/MXS-376): MaxScale terminates with SIGABRT.
|
||||
* [MXS-269](https://mariadb.atlassian.net/browse/MXS-269): Crash in MySQL backend protocol
|
||||
* [MXS-500](https://mariadb.atlassian.net/browse/MXS-500): Tee filter hangs when statement aren't duplicated.
|
||||
* [MXS-447](https://mariadb.atlassian.net/browse/MXS-447): Monitors are started before they have been fully configured
|
||||
* [MXS-417](https://mariadb.atlassian.net/browse/MXS-417): Single character wildcard doesn't work in MaxScale
|
||||
* [MXS-409](https://mariadb.atlassian.net/browse/MXS-409): prepare should not hit all servers
|
||||
* [MXS-405](https://mariadb.atlassian.net/browse/MXS-405): Maxscale bin router crash
|
||||
* [MXS-412](https://mariadb.atlassian.net/browse/MXS-412): show dbusers segmentation fault
|
||||
* [MXS-289](https://mariadb.atlassian.net/browse/MXS-289): Corrupted memory or empty value are in Master_host field of SHOW SLAVE STATUS when master connection is broken
|
||||
* [MXS-283](https://mariadb.atlassian.net/browse/MXS-283): SSL connections leak memory
|
||||
* [MXS-54](https://mariadb.atlassian.net/browse/MXS-54): Write failed auth attempt to trace log
|
||||
* [MXS-501](https://mariadb.atlassian.net/browse/MXS-501): Use<db> hangs when Tee filter uses matching
|
||||
* [MXS-559](https://mariadb.atlassian.net/browse/MXS-559): Crash due to debug assertion in readwritesplit
|
||||
* [MXS-551](https://mariadb.atlassian.net/browse/MXS-551): Maxscale BETA 1.3.0 running as root
|
||||
* [MXS-548](https://mariadb.atlassian.net/browse/MXS-548): Maxscale 1.2.1 crash on Ubuntu 4.04.3 x86_64
|
||||
* [MXS-508](https://mariadb.atlassian.net/browse/MXS-508): regex filter ignores username
|
||||
* [MXS-505](https://mariadb.atlassian.net/browse/MXS-505): if Maxscale fails to start it goes to infinite "try-to-start and fail" loop
|
||||
* [MXS-501](https://mariadb.atlassian.net/browse/MXS-501): USE <db> hangs when Tee filter uses matching
|
||||
* [MXS-500](https://mariadb.atlassian.net/browse/MXS-500): Tee filter hangs when statements aren't duplicated.
|
||||
* [MXS-499](https://mariadb.atlassian.net/browse/MXS-499): Init script error on Debian Wheezy
|
||||
* [MXS-323](https://mariadb.atlassian.net/browse/MXS-323): mysql_client readwritesplit handleError seems using wrong dcb and cause wrong behavior
|
||||
* [MXS-494](https://mariadb.atlassian.net/browse/MXS-494): Weight calculation favors servers without connections
|
||||
* [MXS-493](https://mariadb.atlassian.net/browse/MXS-493): SIGFPE when weightby parameter is 0 and using LEAST_GLOBAL_CONNECTIONS
|
||||
* [MXS-492](https://mariadb.atlassian.net/browse/MXS-492): Segfault if server is missing weighting parameter
|
||||
* [MXS-360](https://mariadb.atlassian.net/browse/MXS-360): Persistent connections: maxadmin reports 0 all the time even if connections are created
|
||||
* [MXS-429](https://mariadb.atlassian.net/browse/MXS-429): Binlog Router crashes due to segmentation fault with no meaningful error if no listener is configured
|
||||
* [MXS-416](https://mariadb.atlassian.net/browse/MXS-416): Orphan sessions appear after many network errors
|
||||
* [MXS-472](https://mariadb.atlassian.net/browse/MXS-472): Monitors update status in multiple steps
|
||||
* [MXS-361](https://mariadb.atlassian.net/browse/MXS-361): crash on backend restart if persistent connections are in use
|
||||
* [MXS-403](https://mariadb.atlassian.net/browse/MXS-403): Monitor callback to DCBs evades thread control causing crashes
|
||||
* [MXS-392](https://mariadb.atlassian.net/browse/MXS-392): Update to "Rabbit MQ setup and MaxScale Integration" document
|
||||
* [MXS-491](https://mariadb.atlassian.net/browse/MXS-491): MaxScale can time out systemd if startup of services takes too long
|
||||
* [MXS-329](https://mariadb.atlassian.net/browse/MXS-329): The session pointer in a DCB can be null unexpectedly
|
||||
* [MXS-479](https://mariadb.atlassian.net/browse/MXS-479): localtime must not be used in the multi-threaded program.
|
||||
* [MXS-480](https://mariadb.atlassian.net/browse/MXS-480): Readwritesplit defaults cause connection pileup
|
||||
* [MXS-479](https://mariadb.atlassian.net/browse/MXS-479): localtime must not be used in the multi-threaded program.
|
||||
* [MXS-472](https://mariadb.atlassian.net/browse/MXS-472): Monitors update status in multiple steps
|
||||
* [MXS-464](https://mariadb.atlassian.net/browse/MXS-464): Upgrade 1.2.0 to 1.2.1 blocking start of `maxscale` service
|
||||
* [MXS-365](https://mariadb.atlassian.net/browse/MXS-365): Load data local infile connection abort when loading certain files
|
||||
* [MXS-450](https://mariadb.atlassian.net/browse/MXS-450): Syslog default prefix is MaxScale not maxscale
|
||||
* [MXS-447](https://mariadb.atlassian.net/browse/MXS-447): Monitors are started before they have been fully configured
|
||||
* [MXS-436](https://mariadb.atlassian.net/browse/MXS-436): Invalid threads argument is ignored and MaxScale starts with one thread
|
||||
* [MXS-431](https://mariadb.atlassian.net/browse/MXS-431): Backend authentication fails with schemarouter
|
||||
* [MXS-394](https://mariadb.atlassian.net/browse/MXS-394): Faults in regex_replace function of regexfilter.c
|
||||
* [MXS-379](https://mariadb.atlassian.net/browse/MXS-379): Incorrect handing of a GWBUF may cause SIGABRT.
|
||||
* [MXS-321](https://mariadb.atlassian.net/browse/MXS-321): Incorrect number of connections in maxadmin list view
|
||||
* [MXS-429](https://mariadb.atlassian.net/browse/MXS-429): Binlog Router crashes due to segmentation fault with no meaningful error if no listener is configured
|
||||
* [MXS-428](https://mariadb.atlassian.net/browse/MXS-428): Maxscale crashes at startup.
|
||||
* [MXS-427](https://mariadb.atlassian.net/browse/MXS-427): Logging a large string causes a segmentation fault
|
||||
* [MXS-417](https://mariadb.atlassian.net/browse/MXS-417): Single character wildcard doesn't work in MaxScale
|
||||
* [MXS-416](https://mariadb.atlassian.net/browse/MXS-416): Orphan sessions appear after many network errors
|
||||
* [MXS-415](https://mariadb.atlassian.net/browse/MXS-415): MaxScale 1.2.1 crashed with Signal 6 and 11
|
||||
* [MXS-414](https://mariadb.atlassian.net/browse/MXS-414): Maxscale crashed every day!
|
||||
* [MXS-413](https://mariadb.atlassian.net/browse/MXS-413): MaxAdmin hangs with show session
|
||||
* [MXS-412](https://mariadb.atlassian.net/browse/MXS-412): show dbusers segmentation fault
|
||||
* [MXS-409](https://mariadb.atlassian.net/browse/MXS-409): prepare should not hit all servers
|
||||
* [MXS-408](https://mariadb.atlassian.net/browse/MXS-408): Connections to backend databases do not clear promptly
|
||||
* [MXS-385](https://mariadb.atlassian.net/browse/MXS-385): disable_sescmd_history can cause false data to be read.
|
||||
* [MXS-407](https://mariadb.atlassian.net/browse/MXS-407): Maxscale binlogrouter binlog names are unncessarily length-limited
|
||||
* [MXS-405](https://mariadb.atlassian.net/browse/MXS-405): Maxscale bin router crash
|
||||
* [MXS-403](https://mariadb.atlassian.net/browse/MXS-403): Monitor callback to DCBs evades thread control causing crashes
|
||||
* [MXS-394](https://mariadb.atlassian.net/browse/MXS-394): Faults in regex_replace function of regexfilter.c
|
||||
* [MXS-392](https://mariadb.atlassian.net/browse/MXS-392): Update to "Rabbit MQ setup and MaxScale Integration" document
|
||||
* [MXS-386](https://mariadb.atlassian.net/browse/MXS-386): max_sescmd_history should not close connections
|
||||
* [MXS-385](https://mariadb.atlassian.net/browse/MXS-385): disable_sescmd_history can cause false data to be read.
|
||||
* [MXS-379](https://mariadb.atlassian.net/browse/MXS-379): Incorrect handing of a GWBUF may cause SIGABRT.
|
||||
* [MXS-376](https://mariadb.atlassian.net/browse/MXS-376): MaxScale terminates with SIGABRT.
|
||||
* [MXS-373](https://mariadb.atlassian.net/browse/MXS-373): If config file is non-existent, maxscale crashes.
|
||||
* [MXS-366](https://mariadb.atlassian.net/browse/MXS-366): Multi-source slave servers are not detected.
|
||||
* [MXS-271](https://mariadb.atlassian.net/browse/MXS-271): Schemarouter and unknown databases
|
||||
* [MXS-365](https://mariadb.atlassian.net/browse/MXS-365): Load data local infile connection abort when loading certain files
|
||||
* [MXS-363](https://mariadb.atlassian.net/browse/MXS-363): rpm building seems to do something wrong with maxscale libraries
|
||||
* [MXS-361](https://mariadb.atlassian.net/browse/MXS-361): crash on backend restart if persistent connections are in use
|
||||
* [MXS-360](https://mariadb.atlassian.net/browse/MXS-360): Persistent connections: maxadmin reports 0 all the time even if connections are created
|
||||
* [MXS-358](https://mariadb.atlassian.net/browse/MXS-358): Crash, Error in `/usr/bin/maxscale': free(): invalid next size (fast)
|
||||
* [MXS-352](https://mariadb.atlassian.net/browse/MXS-352): With no backend connection, services aren't started
|
||||
* [MXS-351](https://mariadb.atlassian.net/browse/MXS-351): Router error handling can cause crash by leaving dangling DCB pointer
|
||||
* [MXS-345](https://mariadb.atlassian.net/browse/MXS-345): maxscale.conf in /etc/init.d prevents puppet from starting maxscale
|
||||
* [MXS-342](https://mariadb.atlassian.net/browse/MXS-342): When ini_parse fails to parse config file, no log messages are printed.
|
||||
* [MXS-333](https://mariadb.atlassian.net/browse/MXS-333): use_sql_variables_in=master doesn't work
|
||||
* [MXS-329](https://mariadb.atlassian.net/browse/MXS-329): The session pointer in a DCB can be null unexpectedly
|
||||
* [MXS-323](https://mariadb.atlassian.net/browse/MXS-323): mysql_client readwritesplit handleError seems using wrong dcb and cause wrong behavior
|
||||
* [MXS-321](https://mariadb.atlassian.net/browse/MXS-321): Incorrect number of connections in maxadmin list view
|
||||
* [MXS-310](https://mariadb.atlassian.net/browse/MXS-310): MaxScale 1.2 does not completely cleanly change to the maxscale user
|
||||
* [MXS-297](https://mariadb.atlassian.net/browse/MXS-297): postinstall on debian copies wrong file in /etc/init.d
|
||||
* [MXS-293](https://mariadb.atlassian.net/browse/MXS-293): Bug in init script, and maxscale --user=maxscale does run as root
|
||||
* [MXS-291](https://mariadb.atlassian.net/browse/MXS-291): Random number generation has flaws
|
||||
* [MXS-289](https://mariadb.atlassian.net/browse/MXS-289): Corrupted memory or empty value are in Master_host field of SHOW SLAVE STATUS when master connection is broken
|
||||
* [MXS-286](https://mariadb.atlassian.net/browse/MXS-286): Fix the content and format of MaxScale-HA-with-Corosync-Pacemaker document
|
||||
* [MXS-283](https://mariadb.atlassian.net/browse/MXS-283): SSL connections leak memory
|
||||
* [MXS-282](https://mariadb.atlassian.net/browse/MXS-282): Add example to "Routing Hints" document
|
||||
* [MXS-281](https://mariadb.atlassian.net/browse/MXS-281): SELECT INTO OUTFILE query goes several times to one slave
|
||||
* [MXS-280](https://mariadb.atlassian.net/browse/MXS-280): SELECT INTO OUTFILE query succeeds even if backed fails
|
||||
* [MXS-276](https://mariadb.atlassian.net/browse/MXS-276): Memory leak of buffer in connection router readQuery
|
||||
* [MXS-274](https://mariadb.atlassian.net/browse/MXS-274): Memory Leak
|
||||
* [MXS-271](https://mariadb.atlassian.net/browse/MXS-271): Schemarouter and unknown databases
|
||||
* [MXS-269](https://mariadb.atlassian.net/browse/MXS-269): Crash in MySQL backend protocol
|
||||
* [MXS-260](https://mariadb.atlassian.net/browse/MXS-260): Multiple MaxScale processes
|
||||
* [MXS-258](https://mariadb.atlassian.net/browse/MXS-258): ERR_error_string could overflow in future
|
||||
* [MXS-254](https://mariadb.atlassian.net/browse/MXS-254): Failure to read configuration file results in no error log messages
|
||||
* [MXS-251](https://mariadb.atlassian.net/browse/MXS-251): Non-thread safe strerror
|
||||
* [MXS-291](https://mariadb.atlassian.net/browse/MXS-291): Random number generation has flaws
|
||||
* [MXS-342](https://mariadb.atlassian.net/browse/MXS-342): When ini_parse fails to parse config file, no log messages are printed.
|
||||
* [MXS-345](https://mariadb.atlassian.net/browse/MXS-345): maxscale.conf in /etc/init.d prevents puppet from starting maxscale
|
||||
* [MXS-333](https://mariadb.atlassian.net/browse/MXS-333): use_sql_variables_in=master doesn't work
|
||||
* [MXS-260](https://mariadb.atlassian.net/browse/MXS-260): Multiple MaxScale processes
|
||||
* [MXS-184](https://mariadb.atlassian.net/browse/MXS-184): init script issues in CentOS 7
|
||||
* [MXS-280](https://mariadb.atlassian.net/browse/MXS-280): SELECT INTO OUTFILE query succeeds even if backed fails
|
||||
* [MXS-202](https://mariadb.atlassian.net/browse/MXS-202): User password not handled correctly
|
||||
* [MXS-282](https://mariadb.atlassian.net/browse/MXS-282): Add example to "Routing Hints" document
|
||||
* [MXS-220](https://mariadb.atlassian.net/browse/MXS-220): LAST_INSERT_ID() query is redirect to slave if function call is in where clause
|
||||
* [MXS-196](https://mariadb.atlassian.net/browse/MXS-196): DCB state is changed prior to polling operation
|
||||
* [MXS-281](https://mariadb.atlassian.net/browse/MXS-281): SELECT INTO OUTFILE query goes several times to one slave
|
||||
* [MXS-210](https://mariadb.atlassian.net/browse/MXS-210): Check MaxScale user privileges
|
||||
* [MXS-202](https://mariadb.atlassian.net/browse/MXS-202): User password not handled correctly
|
||||
* [MXS-197](https://mariadb.atlassian.net/browse/MXS-197): Incorrect sequence of operations with DCB
|
||||
* [MXS-196](https://mariadb.atlassian.net/browse/MXS-196): DCB state is changed prior to polling operation
|
||||
* [MXS-195](https://mariadb.atlassian.net/browse/MXS-195): maxscaled.c ineffective DCB disposal
|
||||
* [MXS-363](https://mariadb.atlassian.net/browse/MXS-363): rpm building seems to do something wrong with maxscale libraries
|
||||
* [MXS-184](https://mariadb.atlassian.net/browse/MXS-184): init script issues in CentOS 7
|
||||
* [MXS-183](https://mariadb.atlassian.net/browse/MXS-183): MaxScale crash after 'reload config'
|
||||
* [MXS-111](https://mariadb.atlassian.net/browse/MXS-111): maxscale binlog events shown in show services seems to be double-counted for the master connection
|
||||
* [MXS-54](https://mariadb.atlassian.net/browse/MXS-54): Write failed auth attempt to trace log
|
||||
* [MXS-35](https://mariadb.atlassian.net/browse/MXS-35): bugzillaId-451: maxscale main() exit code is always 0 after it daemonizes
|
||||
* [MXS-29](https://mariadb.atlassian.net/browse/MXS-29): bugzillaId-589: detect if MAXSCALE_SCHEMA.HEARTBEAT table is not replicated
|
||||
* [MXS-436](https://mariadb.atlassian.net/browse/MXS-436): Invalid threads argument is ignored and MaxScale starts with one thread
|
||||
* [MXS-427](https://mariadb.atlassian.net/browse/MXS-427): Logging a large string causes a segmentation fault
|
||||
* [MXS-352](https://mariadb.atlassian.net/browse/MXS-352): With no backend connection, services aren't started
|
||||
* [MXS-293](https://mariadb.atlassian.net/browse/MXS-293): Bug in init script, and maxscale --user=maxscale does run as root
|
||||
* [MXS-210](https://mariadb.atlassian.net/browse/MXS-210): Check MaxScale user privileges
|
||||
* [MXS-111](https://mariadb.atlassian.net/browse/MXS-111): maxscale binlog events shown in show services seems to be double-counted for the master connection
|
||||
* [MXS-3](https://mariadb.atlassian.net/browse/MXS-3): Remove code for atomic_add in skygw_utils.cc
|
||||
* [MXS-258](https://mariadb.atlassian.net/browse/MXS-258): ERR_error_string could overflow in future
|
||||
* [MXS-310](https://mariadb.atlassian.net/browse/MXS-310): MaxScale 1.2 does not completely cleanly change to the maxscale user
|
||||
* [MXS-450](https://mariadb.atlassian.net/browse/MXS-450): Syslog default prefix is MaxScale not maxscale
|
||||
* [MXS-297](https://mariadb.atlassian.net/browse/MXS-297): postinstall on debian copies wrong file in /etc/init.d
|
||||
|
||||
## Known Issues and Limitations
|
||||
|
||||
|
@ -77,6 +77,14 @@ When value all is used, queries reading session variables can be routed to any a
|
||||
|
||||
In above-mentioned case the user-defined variable would only be updated in the master where query would be routed due to `INSERT` statement.
|
||||
|
||||
### `weightby`
|
||||
|
||||
This parameter defines the name of the value which is used to calculate the
|
||||
weights of the servers. The value should be the name of a parameter in the
|
||||
server definitions and it should exist in all the servers used by this router.
|
||||
For more information, see the description of the `weightby` parameter in
|
||||
the [Configuration Guide](../Getting-Started/Configuration-Guide.md).
|
||||
|
||||
## Router options
|
||||
|
||||
**`router_options`** may include multiple **readwritesplit**-specific options. All the options are parameter-value pairs. All parameters listed in this section must be configured as a value in `router_options`.
|
||||
@ -135,14 +143,6 @@ disable_sescmd_history=true
|
||||
master_accept_reads=true
|
||||
```
|
||||
|
||||
### `weightby`
|
||||
|
||||
This parameter defines the name of the value which is used to calculate the
|
||||
weights of the servers. The value should be the name of a parameter in the
|
||||
server definitions and it should exist in all the servers used by this router.
|
||||
For more information, see the description of the `weightby` parameter in
|
||||
the [Configuration Guide](../Getting-Started/Configuration-Guide.md).
|
||||
|
||||
## Routing hints
|
||||
|
||||
The readwritesplit router supports routing hints. For a detailed guide on hint syntax and functionality, please read [this](../Reference/Hint-Syntax.md) document.
|
||||
|
@ -33,7 +33,7 @@ Switch|Long Option|Description
|
||||
------|-----------|-----------
|
||||
`-d`|`--nodaemon`|enable running in terminal process (default:disabled)
|
||||
`-f FILE`|`--config=FILE`|relative or absolute pathname of MaxScale configuration file (default:/etc/maxscale.cnf)
|
||||
`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: shm)
|
||||
`-l[file shm]`|`--log=[file shm]`|log to file or shared memory (default: file)
|
||||
`-L PATH`|`--logdir=PATH`|path to log file directory (default: /var/log/maxscale)
|
||||
`-D PATH`|`--datadir=PATH`|path to data directory, stored embedded mysql tables (default: /var/cache/maxscale)
|
||||
`-C PATH`|`--configdir=PATH`|path to configuration file directory (default: /etc/)
|
||||
@ -42,7 +42,7 @@ Switch|Long Option|Description
|
||||
`P PATH`|`--piddir=PATH`|PID file directory
|
||||
`-U USER`|`--user=USER`|run MaxScale as another user. The user ID and group ID of this user are used to run MaxScale.
|
||||
`-s [yes no]`|`--syslog=[yes no]`|log messages to syslog (default:yes)
|
||||
`-S [yes no]`|`--maxscalelog=[yes no]`|log messages to MaxScale log (default: yes)
|
||||
`-S [yes no]`|`--maxlog=[yes no]`|log messages to MaxScale log (default: yes)
|
||||
`-G [0 1]`|`--log_augmentation=[0 1]`|augment messages with the name of the function where the message was logged (default: 0). Primarily for development purposes.
|
||||
`-v`|`--version`|print version info and exit
|
||||
`-V`|`--version-full`|print version info and the commit ID the binary was built from
|
||||
|
@ -79,7 +79,7 @@ On one of the nodes, say node2 run the corosync-keygen utility and follow
|
||||
```
|
||||
[root@node2 ~]# corosync-keygen
|
||||
|
||||
Corosync Cluster Engine Authentication key generator.
Gathering 1024 bits for key from /dev/random.
Press keys on your keyboard to generate entropy.
|
||||
Corosync Cluster Engine Authentication key generator. Gathering 1024 bits for key from /dev/random. Press keys on your keyboard to generate entropy.
|
||||
|
||||
After completion the key will be found in /etc/corosync/authkey.
|
||||
```
|
||||
@ -141,7 +141,7 @@ name: pacemaker
|
||||
}
|
||||
```
|
||||
|
||||
**Please note **in this example:
|
||||
**Please note** in this example:
|
||||
|
||||
- unicast UDP is used
|
||||
|
@ -24,7 +24,7 @@ Run MaxScale in the terminal process
|
||||
Relative or absolute pathname of MaxScale configuration file to load.
|
||||
.TP
|
||||
.BR -l "[\fIfile|shm\fB], --log=[\fIfile|shm\fB]"
|
||||
Log trace and debug logs to file or shared memory. The debug and trace logs are disabled by default and if enabled, will log to shared memory.
|
||||
Log to file or shared memory. The default is to log to file.
|
||||
.TP
|
||||
.BR -L " \fIPATH\fB, --logdir=\fIPATH\fB"
|
||||
Path to log file directory.
|
||||
@ -50,7 +50,7 @@ Run MaxScale as another user. The user ID and group ID of this user are used to
|
||||
.BR -s " [\fIyes\fB|\fIno\fB], --syslog=[\fIyes\fB|\fIno\fB]"
|
||||
Log messages to syslog.
|
||||
.TP
|
||||
.BR -S " [\fIyes\fB|\fIno\fB], \fB--maxscalelog=[\fIyes\fB|\fIno\fB]"
|
||||
.BR -S " [\fIyes\fB|\fIno\fB], \fB--maxlog=[\fIyes\fB|\fIno\fB]"
|
||||
Log messages to MaxScale's own log files.
|
||||
.TP
|
||||
.BR "-v, --version"
|
||||
@ -61,12 +61,27 @@ Print full version information including the Git commit the binary was built fro
|
||||
.TP
|
||||
.BR "-?, --help"
|
||||
Show the help information for MaxScale and exit.
|
||||
|
||||
.SH EXAMPLES
|
||||
Tutorials on GitHub:
|
||||
.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md#tutorials
|
||||
.UE
|
||||
|
||||
.RS
|
||||
.I https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md#tutorials
|
||||
.RE
|
||||
.SH SEE ALSO
|
||||
The MaxScale documentation on the MariaDB Knowledge Base:
|
||||
|
||||
.RS
|
||||
.I https://mariadb.com/kb/en/mariadb-enterprise/mariadb-maxscale/
|
||||
.RE
|
||||
|
||||
The MaxScale documentation on GitHub:
|
||||
.UR https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md
|
||||
.UE
|
||||
|
||||
.RS
|
||||
.I https://github.com/mariadb-corporation/MaxScale/blob/master/Documentation/Documentation-Contents.md
|
||||
.RE
|
||||
.SH BUGS
|
||||
You can see a list of known bugs and report new bugs at:
|
||||
|
||||
.RS
|
||||
.I https://mariadb.atlassian.net/browse/MXS
|
||||
.RE
|
||||
|
@ -12,7 +12,7 @@ macro(set_maxscale_version)
|
||||
set(MAXSCALE_VERSION_MINOR "3" CACHE STRING "Minor version")
|
||||
set(MAXSCALE_VERSION_PATCH "0" CACHE STRING "Patch version")
|
||||
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}")
|
||||
|
||||
# This should be incremented each time a package is rebuilt
|
||||
set(MAXSCALE_BUILD_NUMBER 1 CACHE STRING "Release number")
|
||||
|
@ -48,7 +48,7 @@ _RETVAL_STATUS_NOT_RUNNING=3
|
||||
#################################
|
||||
NAME=maxscale
|
||||
DAEMON=@CMAKE_INSTALL_PREFIX@/@MAXSCALE_BINDIR@/maxscale
|
||||
DAEMON_OPTS='"--user=maxscale" "$MAXSCALE_OPTIONS"'
|
||||
DAEMON_OPTS="--user=maxscale $MAXSCALE_OPTIONS"
|
||||
|
||||
# Source function library.
|
||||
. /lib/lsb/init-functions
|
||||
@ -91,7 +91,7 @@ start() {
|
||||
chmod 0755 @MAXSCALE_VARDIR@/run/maxscale
|
||||
|
||||
log_daemon_msg "Starting MaxScale"
|
||||
start_daemon -p "$MAXSCALE_PIDFILE" "$DAEMON" "$DAEMON_OPTS" 2> /dev/null > /dev/null
|
||||
start_daemon -p "$MAXSCALE_PIDFILE" $DAEMON $DAEMON_OPTS 2> /dev/null > /dev/null
|
||||
|
||||
sleep 2
|
||||
|
||||
|
@ -930,27 +930,24 @@ static void usage(void)
|
||||
fprintf(stderr,
|
||||
"\nUsage : %s [OPTION]...\n\n"
|
||||
" -d, --nodaemon enable running in terminal process (default:disabled)\n"
|
||||
" -f, --config=FILE relative|absolute pathname of MaxScale configuration file\n"
|
||||
" -f, --config=FILE relative or absolute pathname of MaxScale configuration file\n"
|
||||
" (default:/etc/maxscale.cnf)\n"
|
||||
" -l, --log=[file|shm] log to file or shared memory (default: shm)\n"
|
||||
" -L, --logdir=PATH path to log file directory\n"
|
||||
" (default: /var/log/maxscale)\n"
|
||||
" -A, --cachedir=PATH path to cache directory\n"
|
||||
" (default: /var/cache/maxscale)\n"
|
||||
" -B, --libdir=PATH path to module directory\n"
|
||||
" (default: /usr/lib64/maxscale)\n"
|
||||
" -C, --configdir=PATH path to configuration file directory\n"
|
||||
" (default: /etc/)\n"
|
||||
" -l, --log=[file|shm] log to file or shared memory (default: file)\n"
|
||||
" -L, --logdir=PATH path to log file directory (default: /var/log/maxscale)\n"
|
||||
" -A, --cachedir=PATH path to cache directory (default: /var/cache/maxscale)\n"
|
||||
" -B, --libdir=PATH path to module directory (default: /usr/lib64/maxscale)\n"
|
||||
" -C, --configdir=PATH path to configuration file directory (default: /etc/)\n"
|
||||
" -D, --datadir=PATH path to data directory, stored embedded mysql tables\n"
|
||||
" (default: /var/cache/maxscale)\n"
|
||||
" -N, --language=PATH path to errmsg.sys file\n"
|
||||
" (default: /var/lib/maxscale)\n"
|
||||
" -P, --piddir=PATH path to PID file directory\n"
|
||||
" (default: /var/run/maxscale)\n"
|
||||
" -N, --language=PATH path to errmsg.sys file (default: /var/lib/maxscale)\n"
|
||||
" -P, --piddir=PATH path to PID file directory (default: /var/run/maxscale)\n"
|
||||
" -U, --user=USER run MaxScale as another user.\n"
|
||||
" The user ID and group ID of this user are used to run MaxScale.\n"
|
||||
" -s, --syslog=[yes|no] log messages to syslog (default:yes)\n"
|
||||
" -S, --maxlog=[yes|no] log messages to MaxScale log (default: yes)\n"
|
||||
" -G, --log_augmentation=0|1 augment messages with the name of the function where\n"
|
||||
" the message was logged (default: 0). Primarily for \n"
|
||||
" development purposes.\n"
|
||||
" -v, --version print version info and exit\n"
|
||||
" -V, --version-full print full version info and exit\n"
|
||||
" -?, --help show this help\n"
|
||||
@ -1086,7 +1083,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt_long(argc, argv, "dc:f:l:vVs:S:?L:D:C:B:U:A:P:G:",
|
||||
while ((opt = getopt_long(argc, argv, "dc:f:l:vVs:S:?L:D:C:B:U:A:P:G:N:",
|
||||
long_options, &option_index)) != -1)
|
||||
{
|
||||
bool succp = true;
|
||||
|
@ -66,6 +66,7 @@
|
||||
#include <gw.h>
|
||||
#include <gwdirs.h>
|
||||
#include <math.h>
|
||||
#include <version.h>
|
||||
|
||||
static RSA *rsa_512 = NULL;
|
||||
static RSA *rsa_1024 = NULL;
|
||||
|
@ -51,12 +51,11 @@
|
||||
*/
|
||||
#include <modinfo.h>
|
||||
|
||||
MODULE_INFO info =
|
||||
{
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_GA,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The MySQL to backend server protocol"
|
||||
MODULE_INFO info = {
|
||||
MODULE_API_PROTOCOL,
|
||||
MODULE_GA,
|
||||
GWPROTOCOL_VERSION,
|
||||
"The MySQL to backend server protocol"
|
||||
};
|
||||
|
||||
static char *version_str = "V2.0.0";
|
||||
@ -70,8 +69,8 @@ static int gw_backend_hangup(DCB *dcb);
|
||||
static int backend_write_delayqueue(DCB *dcb);
|
||||
static void backend_set_delayqueue(DCB *dcb, GWBUF *queue);
|
||||
static int gw_change_user(DCB *backend_dcb, SERVER *server, SESSION *in_session, GWBUF *queue);
|
||||
static GWBUF* process_response_data (DCB* dcb, GWBUF* readbuf, int nbytes_to_process);
|
||||
extern char* create_auth_failed_msg( GWBUF* readbuf, char* hostaddr, uint8_t* sha1);
|
||||
static GWBUF* process_response_data(DCB* dcb, GWBUF* readbuf, int nbytes_to_process);
|
||||
extern char* create_auth_failed_msg(GWBUF* readbuf, char* hostaddr, uint8_t* sha1);
|
||||
extern char* create_auth_fail_str(char *username, char *hostaddr, char *sha1, char *db, int errcode);
|
||||
static bool sescmd_response_complete(DCB* dcb);
|
||||
|
||||
@ -79,21 +78,20 @@ static bool sescmd_response_complete(DCB* dcb);
|
||||
#if defined(NOT_USED)
|
||||
static int gw_session(DCB *backend_dcb, void *data);
|
||||
#endif
|
||||
static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb);
|
||||
static bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session);
|
||||
|
||||
static GWPROTOCOL MyObject =
|
||||
{
|
||||
gw_read_backend_event, /* Read - EPOLLIN handler */
|
||||
gw_MySQLWrite_backend, /* Write - data from gateway */
|
||||
gw_write_backend_event, /* WriteReady - EPOLLOUT handler */
|
||||
gw_error_backend_event, /* Error - EPOLLERR handler */
|
||||
gw_backend_hangup, /* HangUp - EPOLLHUP handler */
|
||||
NULL, /* Accept */
|
||||
gw_create_backend_connection, /* Connect */
|
||||
gw_backend_close, /* Close */
|
||||
NULL, /* Listen */
|
||||
gw_change_user, /* Authentication */
|
||||
NULL /* Session */
|
||||
static GWPROTOCOL MyObject = {
|
||||
gw_read_backend_event, /* Read - EPOLLIN handler */
|
||||
gw_MySQLWrite_backend, /* Write - data from gateway */
|
||||
gw_write_backend_event, /* WriteReady - EPOLLOUT handler */
|
||||
gw_error_backend_event, /* Error - EPOLLERR handler */
|
||||
gw_backend_hangup, /* HangUp - EPOLLHUP handler */
|
||||
NULL, /* Accept */
|
||||
gw_create_backend_connection, /* Connect */
|
||||
gw_backend_close, /* Close */
|
||||
NULL, /* Listen */
|
||||
gw_change_user, /* Authentication */
|
||||
NULL /* Session */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -127,28 +125,34 @@ GWPROTOCOL* GetModuleObject()
|
||||
return &MyObject;
|
||||
}
|
||||
|
||||
static MYSQL_session* gw_get_shared_session_auth_info(DCB* dcb)
|
||||
/**
|
||||
* Copy shared session authentication info
|
||||
*
|
||||
* @param dcb A backend DCB
|
||||
* @param session Destination where authentication data is copied
|
||||
*/
|
||||
static bool gw_get_shared_session_auth_info(DCB* dcb, MYSQL_session* session)
|
||||
{
|
||||
MYSQL_session* auth_info = NULL;
|
||||
bool rval = true;
|
||||
CHK_DCB(dcb);
|
||||
CHK_SESSION(dcb->session);
|
||||
|
||||
spinlock_acquire(&dcb->session->ses_lock);
|
||||
|
||||
if (dcb->session->state != SESSION_STATE_ALLOC && dcb->session->state != SESSION_STATE_DUMMY)
|
||||
if (dcb->session->state != SESSION_STATE_ALLOC &&
|
||||
dcb->session->state != SESSION_STATE_DUMMY)
|
||||
{
|
||||
auth_info = dcb->session->data;
|
||||
memcpy(session, dcb->session->data, sizeof(MYSQL_session));
|
||||
}
|
||||
else
|
||||
{
|
||||
MXS_ERROR("%lu [gw_get_shared_session_auth_info] Couldn't get "
|
||||
"session authentication info. Session in a wrong state %d.",
|
||||
pthread_self(),
|
||||
dcb->session->state);
|
||||
pthread_self(), dcb->session->state);
|
||||
rval = false;
|
||||
}
|
||||
spinlock_release(&dcb->session->ses_lock);
|
||||
|
||||
return auth_info;
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -160,7 +164,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
{
|
||||
MySQLProtocol *client_protocol = NULL;
|
||||
MySQLProtocol *backend_protocol = NULL;
|
||||
MYSQL_session *current_session = NULL;
|
||||
MYSQL_session local_session;
|
||||
int rc = 0;
|
||||
|
||||
CHK_DCB(dcb);
|
||||
@ -178,8 +182,10 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
CHK_SESSION(dcb->session);
|
||||
|
||||
/*< return only with complete session */
|
||||
current_session = gw_get_shared_session_auth_info(dcb);
|
||||
ss_dassert(current_session != NULL);
|
||||
if (!gw_get_shared_session_auth_info(dcb, &local_session))
|
||||
{
|
||||
goto return_rc;
|
||||
}
|
||||
|
||||
backend_protocol = (MySQLProtocol *) dcb->protocol;
|
||||
CHK_PROTOCOL(backend_protocol);
|
||||
@ -229,9 +235,10 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
* Decode password and send the auth credentials
|
||||
* to backend.
|
||||
*/
|
||||
if (gw_send_authentication_to_backend(current_session->db,
|
||||
current_session->user,
|
||||
current_session->client_sha1,
|
||||
if (gw_send_authentication_to_backend(
|
||||
local_session.db,
|
||||
local_session.user,
|
||||
local_session.client_sha1,
|
||||
backend_protocol) != 0)
|
||||
{
|
||||
backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
|
||||
@ -293,43 +300,43 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
|
||||
switch (receive_rc)
|
||||
{
|
||||
case -1:
|
||||
backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] after "
|
||||
"gw_receive_backend_authentication "
|
||||
"fd %d, state = MYSQL_AUTH_FAILED.",
|
||||
pthread_self(),
|
||||
backend_protocol->owner_dcb->fd);
|
||||
case -1:
|
||||
backend_protocol->protocol_auth_state = MYSQL_AUTH_FAILED;
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] after "
|
||||
"gw_receive_backend_authentication "
|
||||
"fd %d, state = MYSQL_AUTH_FAILED.",
|
||||
pthread_self(),
|
||||
backend_protocol->owner_dcb->fd);
|
||||
|
||||
MXS_ERROR("Backend server didn't "
|
||||
"accept authentication for user "
|
||||
"%s.",
|
||||
current_session->user);
|
||||
break;
|
||||
case 1:
|
||||
backend_protocol->protocol_auth_state = MYSQL_IDLE;
|
||||
MXS_ERROR("Backend server didn't "
|
||||
"accept authentication for user "
|
||||
"%s.",
|
||||
local_session.user);
|
||||
break;
|
||||
case 1:
|
||||
backend_protocol->protocol_auth_state = MYSQL_IDLE;
|
||||
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] "
|
||||
"gw_receive_backend_auth succeed. "
|
||||
"dcb %p fd %d, user %s.",
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
break;
|
||||
default:
|
||||
ss_dassert(receive_rc == 0);
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] "
|
||||
"gw_receive_backend_auth read "
|
||||
"successfully "
|
||||
"nothing. dcb %p fd %d, user %s.",
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
rc = 0;
|
||||
goto return_with_lock;
|
||||
break;
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] "
|
||||
"gw_receive_backend_auth succeed. "
|
||||
"dcb %p fd %d, user %s.",
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
local_session.user);
|
||||
break;
|
||||
default:
|
||||
ss_dassert(receive_rc == 0);
|
||||
MXS_DEBUG("%lu [gw_read_backend_event] "
|
||||
"gw_receive_backend_auth read "
|
||||
"successfully "
|
||||
"nothing. dcb %p fd %d, user %s.",
|
||||
pthread_self(),
|
||||
dcb,
|
||||
dcb->fd,
|
||||
local_session.user);
|
||||
rc = 0;
|
||||
goto return_with_lock;
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
@ -338,9 +345,9 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
{
|
||||
GWBUF* errbuf;
|
||||
bool succp;
|
||||
/**
|
||||
* protocol state won't change anymore,
|
||||
* lock can be freed
|
||||
/**
|
||||
* protocol state won't change anymore,
|
||||
* lock can be freed
|
||||
*/
|
||||
spinlock_release(&dcb->authlock);
|
||||
spinlock_acquire(&dcb->delayqlock);
|
||||
@ -359,7 +366,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
* client session is not stopping. It is possible that authentication
|
||||
* fails because the client has closed the connection before all
|
||||
* backends have done authentication. */
|
||||
if (backend_protocol->protocol_auth_state == MYSQL_AUTH_FAILED &&
|
||||
if (backend_protocol->protocol_auth_state == MYSQL_AUTH_FAILED &&
|
||||
dcb->session->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
service_refresh_users(dcb->session->service);
|
||||
@ -416,7 +423,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
"user %s.",
|
||||
pthread_self(),
|
||||
dcb->fd,
|
||||
current_session->user);
|
||||
local_session.user);
|
||||
|
||||
/* check the delay queue and flush the data */
|
||||
if (dcb->delayq)
|
||||
@ -429,7 +436,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
|
||||
spinlock_release(&dcb->authlock);
|
||||
|
||||
} /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED || MYSQL_HANDSHAKE_FAILED */
|
||||
} /* MYSQL_AUTH_RECV || MYSQL_AUTH_FAILED || MYSQL_HANDSHAKE_FAILED */
|
||||
|
||||
/* reading MySQL command output from backend and writing to the client */
|
||||
{
|
||||
@ -487,7 +494,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
|
||||
if (dcb->dcb_readqueue)
|
||||
{
|
||||
read_buffer = gwbuf_append(dcb->dcb_readqueue,read_buffer);
|
||||
read_buffer = gwbuf_append(dcb->dcb_readqueue, read_buffer);
|
||||
}
|
||||
|
||||
nbytes_read = gwbuf_length(read_buffer);
|
||||
@ -518,7 +525,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
* If protocol has session command set, concatenate whole
|
||||
* response into one buffer.
|
||||
*/
|
||||
if (protocol_get_srv_command((MySQLProtocol *)dcb->protocol, false) != MYSQL_COM_UNDEFINED)
|
||||
if (protocol_get_srv_command((MySQLProtocol *) dcb->protocol, false) != MYSQL_COM_UNDEFINED)
|
||||
{
|
||||
read_buffer = process_response_data(dcb, read_buffer, gwbuf_length(read_buffer));
|
||||
/**
|
||||
@ -537,7 +544,7 @@ static int gw_read_backend_event(DCB *dcb)
|
||||
"Read buffer unexpectedly null, even though response "
|
||||
"not marked as complete. User: %s",
|
||||
pthread_self(),
|
||||
current_session->user);
|
||||
local_session.user);
|
||||
rc = 0;
|
||||
goto return_rc;
|
||||
}
|
||||
@ -610,7 +617,7 @@ static int gw_write_backend_event(DCB *dcb)
|
||||
|
||||
if (dcb->writeq != NULL)
|
||||
{
|
||||
data = (uint8_t *)GWBUF_DATA(dcb->writeq);
|
||||
data = (uint8_t *) GWBUF_DATA(dcb->writeq);
|
||||
|
||||
if (dcb->session->client == NULL)
|
||||
{
|
||||
@ -691,30 +698,30 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
*/
|
||||
switch (backend_protocol->protocol_auth_state)
|
||||
{
|
||||
case MYSQL_HANDSHAKE_FAILED:
|
||||
case MYSQL_AUTH_FAILED:
|
||||
if (dcb->session->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
MXS_ERROR("Unable to write to backend '%s' due to "
|
||||
"%s failure. Server in state %s.",
|
||||
dcb->server->unique_name,
|
||||
backend_protocol->protocol_auth_state == MYSQL_HANDSHAKE_FAILED ?
|
||||
"handshake" : "authentication",
|
||||
STRSRVSTATUS(dcb->server));
|
||||
}
|
||||
/** Consume query buffer */
|
||||
while ((queue = gwbuf_consume(
|
||||
queue,
|
||||
GWBUF_LENGTH(queue))) != NULL)
|
||||
{
|
||||
;
|
||||
}
|
||||
rc = 0;
|
||||
spinlock_release(&dcb->authlock);
|
||||
goto return_rc;
|
||||
break;
|
||||
case MYSQL_HANDSHAKE_FAILED:
|
||||
case MYSQL_AUTH_FAILED:
|
||||
if (dcb->session->state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
MXS_ERROR("Unable to write to backend '%s' due to "
|
||||
"%s failure. Server in state %s.",
|
||||
dcb->server->unique_name,
|
||||
backend_protocol->protocol_auth_state == MYSQL_HANDSHAKE_FAILED ?
|
||||
"handshake" : "authentication",
|
||||
STRSRVSTATUS(dcb->server));
|
||||
}
|
||||
/** Consume query buffer */
|
||||
while ((queue = gwbuf_consume(
|
||||
queue,
|
||||
GWBUF_LENGTH(queue))) != NULL)
|
||||
{
|
||||
;
|
||||
}
|
||||
rc = 0;
|
||||
spinlock_release(&dcb->authlock);
|
||||
goto return_rc;
|
||||
break;
|
||||
|
||||
case MYSQL_IDLE:
|
||||
case MYSQL_IDLE:
|
||||
{
|
||||
uint8_t* ptr = GWBUF_DATA(queue);
|
||||
int cmd = MYSQL_GET_COMMAND(ptr);
|
||||
@ -744,9 +751,9 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
rc = dcb_write(dcb, queue);
|
||||
goto return_rc;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
default:
|
||||
{
|
||||
MXS_DEBUG("%lu [gw_MySQLWrite_backend] delayed write to "
|
||||
"dcb %p fd %d protocol state %s.",
|
||||
@ -776,7 +783,7 @@ static int gw_MySQLWrite_backend(DCB *dcb, GWBUF *queue)
|
||||
rc = 1;
|
||||
goto return_rc;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
return_rc:
|
||||
return rc;
|
||||
@ -823,7 +830,7 @@ static int gw_error_backend_event(DCB *dcb)
|
||||
|
||||
len = sizeof(error);
|
||||
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *) & len) == 0)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
@ -861,7 +868,7 @@ static int gw_error_backend_event(DCB *dcb)
|
||||
int error, len;
|
||||
|
||||
len = sizeof(error);
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *) & len) == 0)
|
||||
{
|
||||
if (error != 0)
|
||||
{
|
||||
@ -914,8 +921,8 @@ retblock:
|
||||
* backend server. Positive fd is copied to protocol and to dcb.
|
||||
* If fails, fd == -1 and socket is closed.
|
||||
*/
|
||||
static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
SERVER *server,
|
||||
static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
SERVER *server,
|
||||
SESSION *session)
|
||||
{
|
||||
MySQLProtocol *protocol = NULL;
|
||||
@ -939,10 +946,10 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
{
|
||||
/** Copy client flags to backend protocol */
|
||||
protocol->client_capabilities =
|
||||
((MySQLProtocol *)(backend_dcb->session->client->protocol))->client_capabilities;
|
||||
((MySQLProtocol *) (backend_dcb->session->client->protocol))->client_capabilities;
|
||||
/** Copy client charset to backend protocol */
|
||||
protocol->charset =
|
||||
((MySQLProtocol *)(backend_dcb->session->client->protocol))->charset;
|
||||
((MySQLProtocol *) (backend_dcb->session->client->protocol))->charset;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -958,51 +965,50 @@ static int gw_create_backend_connection(DCB *backend_dcb,
|
||||
/*< Set protocol state */
|
||||
switch (rv)
|
||||
{
|
||||
case 0:
|
||||
ss_dassert(fd > 0);
|
||||
protocol->fd = fd;
|
||||
protocol->protocol_auth_state = MYSQL_CONNECTED;
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Established "
|
||||
"connection to %s:%i, protocol fd %d client "
|
||||
"fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
case 0:
|
||||
ss_dassert(fd > 0);
|
||||
protocol->fd = fd;
|
||||
protocol->protocol_auth_state = MYSQL_CONNECTED;
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Established "
|
||||
"connection to %s:%i, protocol fd %d client "
|
||||
"fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
ss_dassert(fd > 0);
|
||||
protocol->protocol_auth_state = MYSQL_PENDING_CONNECT;
|
||||
protocol->fd = fd;
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Connection "
|
||||
"pending to %s:%i, protocol fd %d client fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
case 1:
|
||||
ss_dassert(fd > 0);
|
||||
protocol->protocol_auth_state = MYSQL_PENDING_CONNECT;
|
||||
protocol->fd = fd;
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Connection "
|
||||
"pending to %s:%i, protocol fd %d client fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
|
||||
default:
|
||||
ss_dassert(fd == -1);
|
||||
ss_dassert(protocol->protocol_auth_state == MYSQL_ALLOC);
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Connection "
|
||||
"failed to %s:%i, protocol fd %d client fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
default:
|
||||
ss_dassert(fd == -1);
|
||||
ss_dassert(protocol->protocol_auth_state == MYSQL_ALLOC);
|
||||
MXS_DEBUG("%lu [gw_create_backend_connection] Connection "
|
||||
"failed to %s:%i, protocol fd %d client fd %d.",
|
||||
pthread_self(),
|
||||
server->name,
|
||||
server->port,
|
||||
protocol->fd,
|
||||
session->client->fd);
|
||||
break;
|
||||
} /*< switch */
|
||||
|
||||
return_fd:
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Error event handler.
|
||||
* Create error message, pass it to router's error handler and if error
|
||||
@ -1068,7 +1074,7 @@ static int gw_backend_hangup(DCB *dcb)
|
||||
int error, len;
|
||||
|
||||
len = sizeof(error);
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) == 0)
|
||||
if (getsockopt(dcb->fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *) & len) == 0)
|
||||
{
|
||||
if (error != 0 && ses_state != SESSION_STATE_STOPPING)
|
||||
{
|
||||
@ -1238,13 +1244,12 @@ static int backend_write_delayqueue(DCB *dcb)
|
||||
|
||||
if (MYSQL_IS_CHANGE_USER(((uint8_t *)GWBUF_DATA(localq))))
|
||||
{
|
||||
MYSQL_session* mses;
|
||||
GWBUF* new_packet;
|
||||
MYSQL_session mses;
|
||||
GWBUF* new_packet;
|
||||
|
||||
mses = (MYSQL_session *)dcb->session->client->data;
|
||||
new_packet = gw_create_change_user_packet(mses,
|
||||
(MySQLProtocol *)dcb->protocol);
|
||||
/**
|
||||
gw_get_shared_session_auth_info(dcb, &mses);
|
||||
new_packet = gw_create_change_user_packet(&mses, dcb->protocol);
|
||||
/**
|
||||
* Remove previous packet which lacks scramble
|
||||
* and append the new.
|
||||
*/
|
||||
@ -1315,10 +1320,10 @@ static int gw_change_user(DCB *backend,
|
||||
MYSQL_session *current_session = NULL;
|
||||
MySQLProtocol *backend_protocol = NULL;
|
||||
MySQLProtocol *client_protocol = NULL;
|
||||
char username[MYSQL_USER_MAXLEN+1]="";
|
||||
char database[MYSQL_DATABASE_MAXLEN+1]="";
|
||||
char current_database[MYSQL_DATABASE_MAXLEN+1]="";
|
||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN]="";
|
||||
char username[MYSQL_USER_MAXLEN + 1] = "";
|
||||
char database[MYSQL_DATABASE_MAXLEN + 1] = "";
|
||||
char current_database[MYSQL_DATABASE_MAXLEN + 1] = "";
|
||||
uint8_t client_sha1[MYSQL_SCRAMBLE_LEN] = "";
|
||||
uint8_t *client_auth_packet = GWBUF_DATA(queue);
|
||||
unsigned int auth_token_len = 0;
|
||||
uint8_t *auth_token = NULL;
|
||||
@ -1331,7 +1336,7 @@ static int gw_change_user(DCB *backend,
|
||||
|
||||
/* now get the user, after 4 bytes header and 1 byte command */
|
||||
client_auth_packet += 5;
|
||||
strncpy(username, (char *)client_auth_packet,MYSQL_USER_MAXLEN);
|
||||
strncpy(username, (char *)client_auth_packet, MYSQL_USER_MAXLEN);
|
||||
client_auth_packet += strlen(username) + 1;
|
||||
|
||||
/* get the auth token len */
|
||||
@ -1354,7 +1359,7 @@ static int gw_change_user(DCB *backend,
|
||||
}
|
||||
|
||||
/* get new database name */
|
||||
strncpy(database, (char *)client_auth_packet,MYSQL_DATABASE_MAXLEN);
|
||||
strncpy(database, (char *)client_auth_packet, MYSQL_DATABASE_MAXLEN);
|
||||
|
||||
/* get character set */
|
||||
if (strlen(database))
|
||||
@ -1371,45 +1376,48 @@ 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 */
|
||||
strncpy(current_database, current_session->db,MYSQL_DATABASE_MAXLEN);
|
||||
strncpy(current_database, current_session->db, MYSQL_DATABASE_MAXLEN);
|
||||
|
||||
/*
|
||||
* Now clear database name in dcb as we don't do local authentication on db name for change user.
|
||||
* Local authentication only for user@host and if successful the database name change is sent to backend.
|
||||
*/
|
||||
strcpy(current_session->db, "");
|
||||
strncpy(current_session->db, "", MYSQL_DATABASE_MAXLEN);
|
||||
|
||||
/*
|
||||
* decode the token and check the password.
|
||||
* Decode the token and check the password.
|
||||
* Note: if auth_token_len == 0 && auth_token == NULL, user is without password
|
||||
*/
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client,
|
||||
auth_token,
|
||||
auth_token_len,
|
||||
auth_token, auth_token_len,
|
||||
client_protocol->scramble,
|
||||
sizeof(client_protocol->scramble),
|
||||
username,
|
||||
client_sha1);
|
||||
username, client_sha1);
|
||||
strncpy(current_session->db, current_database, MYSQL_DATABASE_MAXLEN);
|
||||
spinlock_release(&in_session->ses_lock);
|
||||
|
||||
if (auth_ret != 0)
|
||||
{
|
||||
if (!service_refresh_users(backend->session->client->service))
|
||||
if (service_refresh_users(backend->session->client->service) == 0)
|
||||
{
|
||||
/* Try authentication again with new repository data */
|
||||
/* Note: if no auth client authentication will fail */
|
||||
auth_ret = gw_check_mysql_scramble_data(backend->session->client,
|
||||
spinlock_acquire(&in_session->ses_lock);
|
||||
strncpy(current_session->db, "", MYSQL_DATABASE_MAXLEN);
|
||||
auth_ret = gw_check_mysql_scramble_data(
|
||||
backend->session->client,
|
||||
auth_token, auth_token_len,
|
||||
client_protocol->scramble,
|
||||
sizeof(client_protocol->scramble),
|
||||
username,
|
||||
client_sha1);
|
||||
username, client_sha1);
|
||||
strncpy(current_session->db, current_database, MYSQL_DATABASE_MAXLEN);
|
||||
spinlock_release(&in_session->ses_lock);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy back current datbase to client session */
|
||||
strcpy(current_session->db, current_database);
|
||||
|
||||
/* let's free the auth_token now */
|
||||
if (auth_token)
|
||||
{
|
||||
@ -1457,7 +1465,9 @@ static int gw_change_user(DCB *backend,
|
||||
MYSQL_COM_CHANGE_USER);
|
||||
modutil_reply_auth_error(backend, message, 0);
|
||||
rv = 1;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
rv = gw_send_change_user_to_backend(database, username, client_sha1, backend_protocol);
|
||||
/*
|
||||
* Now copy new data into user session
|
||||
@ -1473,7 +1483,6 @@ retblock:
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Move packets or parts of packets from readbuf to outbuf as the packet headers
|
||||
* and lengths have been noticed and counted.
|
||||
@ -1486,12 +1495,12 @@ retblock:
|
||||
*
|
||||
* @return GWBUF which includes complete MySQL packet
|
||||
*/
|
||||
static GWBUF* process_response_data(DCB* dcb,
|
||||
static GWBUF* process_response_data(DCB* dcb,
|
||||
GWBUF* readbuf,
|
||||
int nbytes_to_process)
|
||||
int nbytes_to_process)
|
||||
{
|
||||
int npackets_left = 0; /*< response's packet count */
|
||||
ssize_t nbytes_left = 0; /*< nbytes to be read for the packet */
|
||||
ssize_t nbytes_left = 0; /*< nbytes to be read for the packet */
|
||||
MySQLProtocol* p;
|
||||
GWBUF* outbuf = NULL;
|
||||
int initial_packets = npackets_left;
|
||||
@ -1560,7 +1569,7 @@ static GWBUF* process_response_data(DCB* dcb,
|
||||
}
|
||||
nbytes_to_process = 0;
|
||||
}
|
||||
/** Packet was read. All bytes belonged to the last packet. */
|
||||
/** Packet was read. All bytes belonged to the last packet. */
|
||||
else if (nbytes_left == nbytes_to_process)
|
||||
{
|
||||
nbytes_left = 0;
|
||||
@ -1570,12 +1579,12 @@ 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.
|
||||
*/
|
||||
/**
|
||||
* 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 */
|
||||
{
|
||||
ss_dassert(nbytes_left >= 0);
|
||||
@ -1583,8 +1592,8 @@ static GWBUF* process_response_data(DCB* dcb,
|
||||
|
||||
/** 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);
|
||||
gwbuf_clone_portion(readbuf, 0, (size_t) nbytes_left));
|
||||
readbuf = gwbuf_consume(readbuf, (size_t) nbytes_left);
|
||||
ss_dassert(npackets_left > 0);
|
||||
npackets_left -= 1;
|
||||
nbytes_left = 0;
|
||||
@ -1611,7 +1620,7 @@ static GWBUF* process_response_data(DCB* dcb,
|
||||
/** Archive the command */
|
||||
protocol_archive_srv_command(p);
|
||||
}
|
||||
/** Read next packet */
|
||||
/** Read next packet */
|
||||
else
|
||||
{
|
||||
uint8_t* data;
|
||||
@ -1624,19 +1633,19 @@ static GWBUF* process_response_data(DCB* dcb,
|
||||
{
|
||||
MXS_DEBUG("%lu [%s] Read %d packets. Waiting for %d more "
|
||||
"packets for a total of %d packets.",
|
||||
pthread_self(),__FUNCTION__,
|
||||
pthread_self(), __FUNCTION__,
|
||||
initial_packets - npackets_left,
|
||||
npackets_left,initial_packets);
|
||||
npackets_left, initial_packets);
|
||||
|
||||
/** Store the already read data into the readqueue of the DCB
|
||||
* and restore the response status to the initial number of packets */
|
||||
dcb->dcb_readqueue = gwbuf_append(outbuf,dcb->dcb_readqueue);
|
||||
dcb->dcb_readqueue = gwbuf_append(outbuf, dcb->dcb_readqueue);
|
||||
protocol_set_response_status(p, initial_packets, initial_bytes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = GWBUF_DATA(readbuf);
|
||||
nbytes_left = MYSQL_GET_PACKET_LEN(data)+MYSQL_HEADER_LEN;
|
||||
nbytes_left = MYSQL_GET_PACKET_LEN(data) + MYSQL_HEADER_LEN;
|
||||
/** Store new status to protocol structure */
|
||||
protocol_set_response_status(p, npackets_left, nbytes_left);
|
||||
}
|
||||
@ -1645,12 +1654,11 @@ static GWBUF* process_response_data(DCB* dcb,
|
||||
return outbuf;
|
||||
}
|
||||
|
||||
|
||||
static bool sescmd_response_complete(DCB* dcb)
|
||||
{
|
||||
int npackets_left;
|
||||
ssize_t nbytes_left;
|
||||
MySQLProtocol* p;
|
||||
MySQLProtocol* p;
|
||||
bool succp;
|
||||
|
||||
p = DCB_PROTOCOL(dcb, MySQLProtocol);
|
||||
|
@ -1566,8 +1566,6 @@ void check_drop_tmp_table(
|
||||
char** tbl = NULL;
|
||||
char *hkey,*dbname;
|
||||
MYSQL_session* data;
|
||||
|
||||
DCB* master_dcb = NULL;
|
||||
rses_property_t* rses_prop_tmp;
|
||||
|
||||
if(router_cli_ses == NULL || querybuf == NULL)
|
||||
@ -1577,27 +1575,14 @@ void check_drop_tmp_table(
|
||||
return;
|
||||
}
|
||||
|
||||
if(router_cli_ses->rses_master_ref == NULL)
|
||||
if(router_cli_ses->client_dcb == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server reference is NULL.",
|
||||
__FUNCTION__);
|
||||
MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
|
||||
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
|
||||
|
||||
if(master_dcb == NULL || master_dcb->session == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server DBC is NULL. "
|
||||
"This means that the connection to the master server is already "
|
||||
"closed while a query is still being routed.",__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
CHK_DCB(master_dcb);
|
||||
|
||||
data = (MYSQL_session*)master_dcb->session->data;
|
||||
data = (MYSQL_session*)router_cli_ses->client_dcb->session->data;
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
@ -1668,32 +1653,20 @@ static qc_query_type_t is_read_tmp_table(
|
||||
return type;
|
||||
}
|
||||
|
||||
if(router_cli_ses->rses_master_ref == NULL)
|
||||
if(router_cli_ses->client_dcb == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server reference is NULL.",
|
||||
__FUNCTION__);
|
||||
MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__);
|
||||
return type;
|
||||
}
|
||||
|
||||
if (BREF_IS_IN_USE(router_cli_ses->rses_master_ref))
|
||||
{
|
||||
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
|
||||
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
|
||||
|
||||
if(master_dcb == NULL || master_dcb->session == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server DBC is NULL. "
|
||||
"This means that the connection to the master server is already "
|
||||
"closed while a query is still being routed.",__FUNCTION__);
|
||||
return qtype;
|
||||
}
|
||||
CHK_DCB(master_dcb);
|
||||
|
||||
data = (MYSQL_session*)master_dcb->session->data;
|
||||
data = (MYSQL_session*)router_cli_ses->client_dcb->session->data;
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: User data in master server DBC is NULL.",__FUNCTION__);
|
||||
MXS_ERROR("[%s] Error: User data in client DBC is NULL.",__FUNCTION__);
|
||||
return qtype;
|
||||
}
|
||||
|
||||
@ -1765,7 +1738,6 @@ static void check_create_tmp_table(
|
||||
int klen = 0;
|
||||
char *hkey,*dbname;
|
||||
MYSQL_session* data;
|
||||
DCB* master_dcb = NULL;
|
||||
rses_property_t* rses_prop_tmp;
|
||||
HASHTABLE* h;
|
||||
|
||||
@ -1776,28 +1748,15 @@ static void check_create_tmp_table(
|
||||
return;
|
||||
}
|
||||
|
||||
if(router_cli_ses->rses_master_ref == NULL)
|
||||
if(router_cli_ses->client_dcb == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server reference is NULL.",
|
||||
__FUNCTION__);
|
||||
MXS_ERROR("[%s] Error: Client DCB is NULL.", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
router_cli_ses->have_tmp_tables = true;
|
||||
rses_prop_tmp = router_cli_ses->rses_properties[RSES_PROP_TYPE_TMPTABLES];
|
||||
master_dcb = router_cli_ses->rses_master_ref->bref_dcb;
|
||||
|
||||
if(master_dcb == NULL || master_dcb->session == NULL)
|
||||
{
|
||||
MXS_ERROR("[%s] Error: Master server DCB is NULL. "
|
||||
"This means that the connection to the master server is already "
|
||||
"closed while a query is still being routed.",__FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
CHK_DCB(master_dcb);
|
||||
|
||||
data = (MYSQL_session*)master_dcb->session->data;
|
||||
data = (MYSQL_session*)router_cli_ses->client_dcb->session->data;
|
||||
|
||||
if(data == NULL)
|
||||
{
|
||||
@ -2097,10 +2056,10 @@ static bool route_single_stmt(
|
||||
* Read stored master DCB pointer. If master is not set, routing must
|
||||
* be aborted
|
||||
*/
|
||||
if ((master_dcb = rses->rses_master_ref->bref_dcb) == NULL)
|
||||
if ((master_dcb = rses->rses_master_ref->bref_dcb) == NULL ||
|
||||
BREF_IS_CLOSED(rses->rses_master_ref))
|
||||
{
|
||||
char* query_str = modutil_get_query(querybuf);
|
||||
CHK_DCB(master_dcb);
|
||||
MXS_ERROR("Can't route %s:%s:\"%s\" to "
|
||||
"backend server. Session doesn't have a Master "
|
||||
"node",
|
||||
@ -2112,6 +2071,7 @@ static bool route_single_stmt(
|
||||
goto retblock;
|
||||
}
|
||||
|
||||
CHK_DCB(master_dcb);
|
||||
packet = GWBUF_DATA(querybuf);
|
||||
packet_len = gw_mysql_get_byte3(packet);
|
||||
|
||||
@ -2491,7 +2451,6 @@ static bool route_single_stmt(
|
||||
#if defined(SS_EXTRA_DEBUG)
|
||||
MXS_INFO("Found DCB for slave.");
|
||||
#endif
|
||||
|
||||
atomic_add(&inst->stats.n_slave, 1);
|
||||
}
|
||||
else
|
||||
@ -2847,21 +2806,17 @@ static void clientReply (
|
||||
uint8_t* replybuf = (uint8_t *)GWBUF_DATA(writebuf);
|
||||
size_t len = MYSQL_GET_PACKET_LEN(buf);
|
||||
size_t replylen = MYSQL_GET_PACKET_LEN(replybuf);
|
||||
char* cmdstr = strndup(&((char *)buf)[5], len-4);
|
||||
char* err = strndup(&((char *)replybuf)[8], 5);
|
||||
char* replystr = strndup(&((char *)replybuf)[13],
|
||||
replylen-4-5);
|
||||
|
||||
ss_dassert(len+4 == GWBUF_LENGTH(scur->scmd_cur_cmd->my_sescmd_buf));
|
||||
|
||||
MXS_ERROR("Failed to execute %s in %s:%d. %s %s",
|
||||
cmdstr,
|
||||
MXS_ERROR("Failed to execute session command in %s:%d. Error was: %s %s",
|
||||
bref->bref_backend->backend_server->name,
|
||||
bref->bref_backend->backend_server->port,
|
||||
err,
|
||||
replystr);
|
||||
|
||||
free(cmdstr);
|
||||
free(err);
|
||||
free(replystr);
|
||||
}
|
||||
@ -2893,11 +2848,9 @@ static void clientReply (
|
||||
* This applies to session commands only. Counter decrement
|
||||
* for other type of queries is done outside this block.
|
||||
*/
|
||||
if (writebuf != NULL && client_dcb != NULL)
|
||||
{
|
||||
/** Set response status as replied */
|
||||
bref_clear_state(bref, BREF_WAITING_RESULT);
|
||||
}
|
||||
|
||||
/** Set response status as replied */
|
||||
bref_clear_state(bref, BREF_WAITING_RESULT);
|
||||
}
|
||||
/**
|
||||
* Clear BREF_QUERY_ACTIVE flag and decrease waiter counter.
|
||||
@ -3815,8 +3768,8 @@ static GWBUF* sescmd_cursor_process_replies(
|
||||
|
||||
if(bref->reply_cmd != scmd->reply_cmd)
|
||||
{
|
||||
MXS_INFO("Backend server '%s' response differs from master's response. "
|
||||
"Closing connection.",
|
||||
MXS_ERROR("Slave server '%s': response differs from master's response. "
|
||||
"Closing connection due to inconsistent session state.",
|
||||
bref->bref_backend->backend_server->unique_name);
|
||||
sescmd_cursor_set_active(scur,false);
|
||||
bref_clear_state(bref,BREF_QUERY_ACTIVE);
|
||||
|
@ -1767,7 +1767,7 @@ bool send_database_list(ROUTER_INSTANCE* router, ROUTER_CLIENT_SES* client)
|
||||
{
|
||||
bool rval = false;
|
||||
spinlock_acquire(&client->shardmap->lock);
|
||||
if (client->shardmap->state == SHMAP_READY)
|
||||
if (client->shardmap->state != SHMAP_UNINIT)
|
||||
{
|
||||
struct string_array strarray;
|
||||
const int size = hashtable_size(client->shardmap->hash);
|
||||
@ -1849,12 +1849,7 @@ static int routeQuery(ROUTER* instance,
|
||||
char errbuf[26+MYSQL_DATABASE_MAXLEN];
|
||||
CHK_CLIENT_RSES(router_cli_ses);
|
||||
|
||||
/** Dirty read for quick check if router is closed. */
|
||||
if (router_cli_ses->rses_closed)
|
||||
{
|
||||
rses_is_closed = true;
|
||||
}
|
||||
ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf));
|
||||
ss_dassert(!GWBUF_IS_TYPE_UNDEFINED(querybuf));
|
||||
|
||||
if (!rses_begin_locked_router_action(router_cli_ses))
|
||||
{
|
||||
@ -4313,7 +4308,7 @@ int process_show_shards(ROUTER_CLIENT_SES* rses)
|
||||
int rval = 0;
|
||||
|
||||
spinlock_acquire(&rses->shardmap->lock);
|
||||
if (rses->shardmap->state == SHMAP_READY)
|
||||
if(rses->shardmap->state != SHMAP_UNINIT)
|
||||
{
|
||||
HASHITERATOR* iter = hashtable_iterator(rses->shardmap->hash);
|
||||
struct shard_list sl;
|
||||
@ -4380,7 +4375,7 @@ bool handle_default_db(ROUTER_CLIENT_SES *router_cli_ses)
|
||||
char* target = NULL;
|
||||
|
||||
spinlock_acquire(&router_cli_ses->shardmap->lock);
|
||||
if (router_cli_ses->shardmap->state == SHMAP_READY)
|
||||
if(router_cli_ses->shardmap->state != SHMAP_UNINIT)
|
||||
{
|
||||
target = hashtable_fetch(router_cli_ses->shardmap->hash, router_cli_ses->connect_db);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user