This commit adds a free() to null_auth_free_client_data, which plugs
the memory leak in maxinfo.
Also, this commit fixes some segfaults when multiple threads are
running status_row() or variable_row(). The functions use
statically allocated index variables, which often go out-of-bounds
in concurrent use. This fix changes the indexes to thread-specific
variables, with allocating and deallocating. This does seem to slow
the functions down somewhat.
With the use_sql_variables_in=master option, readwritesplit should route
all user variable modifications and reads with user variables to the
master.
Previously, the modification of user variables was grouped into generic
system variables which caused all modifications to system variables to go
to the master only. The router requires a finer grained distiction between
normal system variable modifications and user variable modifications.
With the improvements to the query classifier, readwritesplit now properly
routes all user variable operations to the master and other system
variable modifications to all servers.
When a connection to the master fails, readwritesplit should always treat
it the same way. Previously, if a connection to the master was lost but it
hadn't lost the master status, the failure would be treated like a slave
server failure.
The backend references now use a common closing function so that all
variables are reset to proper states. The stored queries weren't always
freed and they would leak memory if left open.
The hangup code was refactored into a common function which should only be
used after the server states have been updated. This will remove erroneus
connections to already failed servers.
The master reference used by the readwritesplit sessions needs to be
reassigned if slave reconnection occurs. This happens because the
reference refers to a certain place in the backend reference array
instead of the actual backend reference and those places are mixed
when the array is sorted.
The error logging is now more detailed and tells why the connection is
being closed. This should help the user figure out what is happening when
write fails and the connection is closed.
Some of the master server status checks didn't check whether the server
was actually running. The macros in server.h should always be used instead
of manually inspecting the server status.
If a readwritesplit session is active, it should never connect to a new
master. This will lead to unexpected results as the session states aren't
consistent.
If an illegal DCB close is done with a backend DCB, it will log the server
where it was connected. This allows us to know whether the DCB was
connected to a master or a slave.
Added more debug assertions to readwritesplit code. The DCBs should never
enter the DCB_STATE_DISCONNECTED.
Removed useless debug log messages. The messages usually just flood the
logs with no use to the developers.
A debug assertion failed due to a NULL buffer but a non-zero packet
length. This was caused by a missing reset of the packet length after
freeing the buffers.
Some error messages were logged at INFO level and some had conditions that
prevent the logging. Removed these restrictions that an error situation is
always logged.
If a master_failure_mode was set to error_on_write, a reconnection to the
old master would happen after the following events:
- Master server fails and the connection is closed
- The master server recovers
- A slave fails and the connection is closed
- A replacement for the slave is searched
If these events took place, the master would be taken back into use with
an inconsistent session state.
Binlog server is already configured: if there is no pending transaction
a new binlog file is created after CHANGE MASTER.
If as START SLAVE is issued replication starts as usuale.
If maxscale is restarted the replication starts using the new created
file.
While configuring binlog server for the first time, master.ini not
existent, the specified MASTER_LOG_FILE is created in the $binlogdir.
If START SLAVE command is not issued the replication can start after
restarting maxscale as the binlog file exists.
When a COM_CHANGE_USER statement was executed, the new user credentials
were copied after the authentication message was sent. This caused the
COM_CHANGE_USER to always succeed the first time as it used the current
credentials. The user credentials would always lag behind by one.
When checksum is in use and there is an error in replication stream
master connection the blr_terminate_master_replication has no effect.
MXS-961: The checksum detection calls
blr_master_delayed_connect(router); and connection is scheduled again.
The fix will break the main loop as soon as the error indicator byte is
seen and no other computation will be done (such as checksum)
The default character set should be copied from the server so that
MaxScale appears to be the same. This fixes problems where utf8mb4
couldn't be taken into use because MaxScale would always send latin1 as
the server charset.
When the readwritesplit can't locate the master server when it's checking
the list of available servers, it logs an error if the original master
reference isn't in a valid state. This error should only be logged if the
server is in use but in an unexpected state.
When the authentication string was decoded from hexadecimal to binary, it
was possible that an out of bounds read was done if the length of the data
was not an even number.
The return values of pcre2_match are now properly handled. A positive
match is a return value which is greater than or equal to zero. This fix
should give a small performance boost to as memory is no longer needlessly
allocated.
The backend reference states should be cleared when a reconnection attempt
is made. Should the creation of a new DCB succeed, the backend should no
longer be closed.
Session command responses with multiple packets could be spread across
multiple, non-contiguous buffers. If a buffer contained a complete packet
and some extra data but it wasn't contiguous, the debug assertion in
gwbuf_clone_portion would fail. With release builds, it would cause
eventual out-of-bounds memory access when the response would be sent to
the client.
When a backend causes an error and it should be sent to the client, the
backend reference was closed but the waiting results state was not
cleared. This caused a debug assertion to be hit.
The active operation counters are now closed every time a backend referece
is taken out of use. This should fix a few debug assertions that were hit
in tests.
The `detect_stale_slave` functionality used to only work when MaxScale had
the knowledge that a master server has existed and that replication was
working at some point in time. This might be a "safe" way to do it in
regards to staleness of the data but in practice it is preferrable to
always allow slave to be used for reads.
This change adds the missing functionality to the monitor by assigning
slave status to all servers which are configured as replication slaves
when no master can be found.
The new member variable that was added to the SERVER should be removed in
2.1 where the server_info offers the same functionalty without "polluting"
the SERVER type.
When a client executes commands which do not return results (for example
inserting BLOB data via the C API), readwritesplit expects a result for
each sent packet. This is a somewhat of a false assumption but it clears
itself out when the session is closed normally. If the session is closed
due to an error, the counter is not decremented.
Each sesssion should only increase the number of active operation on a
server by one operation. By checking that the session is not already
executing an operation before incrementing the active operation count the
runtime operation count will be correct.
It's now possible to use both a Unix domain socket and host/port
when connecting with MaxAdmin to MaxScale.
By default MaxAdmin will attempt to use the default Unix domain
socket, but if host and/or port has been specified, then an inet
socket will be used.
maxscaled will authenticate the connection attempt differently
depending on whether a Unix domain socket is used or not. If
a Unix domain socket is used, then the Linux user id will be
used for the authorization, otherwise the 1.4.3 username/password
handshake will be performed.
adminusers has now been extended so that there is one set of
functions for local users (connecting locally over a Unix socket)
and one set of functions for remote users (connecting locally
or remotely over an Inet socket).
The local users are stored in the new .../maxscale-users and the
remote users in .../passwd. That is, the old users of a 1.4
installation will work as such in 2.0.
One difference is that there will be *no* default remote user.
That is, remote users will always have to be added manually using
a local user.
The implementation is shared; the local and remote alternatives
use common functions to which the hashtable and filename to be
used are forwarded.
The commands "[add|remove] user" behave now exactly like they did
in 1.4.3, and also all existing users work out of the box.
In addition there is now the commands "[enable|disable] account"
using which Linux accounts can be enabled for MaxAdmin usage.
The change in readwritesplit routing priorities, where hints have the
highest priority, gives users more options to control how readwritesplit
acts.
For example, this allows read-only stored procedures to be routed to
slaves by adding a hint to the query:
CALL myproc(); -- maxscale route to slave
The readwritesplit documentation also warns the user not to use routing
hints unless they can be absolutely sure that no damage will be done.
Local admins are the ones accessing MaxScale on the same host
over a Unix domain socket, and who are strongly identified), and
optional remote admins are the ones accessing MaxScale potentially
over a tcp socket (potentially over the network), and who are
weakly identified.
These are completely separate and a different set of functions
will be needed for managing them. This initial change merely
renames the functions.
With this change, if two master servers both have equal depths but
different weights, the one with the higher weight is used. If the depths
and weights are equal, the first master listed in the configuration is
used.