Th discarding of connections in maintenance mode must be done after any
results have been written to them. This prevents closing of the connection
before the actual result is returned.
The candidate selection code used default values that would cause reads
past buffers. The code could also dereference the end iterator which
causes undefined behavior.
This fixes some situations where MaxAdmin/MaxCtrl would block and wait
until a monitor operation or tick is complete. This also fixes a deadlock
caused by calling monitor diagnostics inside a monitor script.
Concurrency is enabled by adding one mutex per server object to protect
array-like fields from concurrent reading/writing.
Queries in the query queue need to be explicitly parsed since they are
stored in a single buffer and thus share the query classification
information. In the next major version this should be changed into an
array of individual buffers instead of a shared buffer.
If a DCB was closed and a hangup event was sent to it via
dcb_hangup_foreach shortly after it was closed, the DCB would still
receive it even if it was closed. To prevent this, events must only be
delivered to DCBs if they haven't been closed.
The protocol should not track the session state as the parsing is quite
expensive with the current code. This change is a workaround that enables
the parsing only when required. A proper way to handle this would be to do
all the response processing in one place thus avoiding the duplication of
work.
Given the fact that there exist only three possible categories, the map
can be replaced with a static array that needs no memory
allocations. Making this array thread-local allows it to be reused which
places an upper limit on the number of memory allocations.
The monitor now continuously updates a list of enabled server events. When
promoting a new master in failover/switchover, only events that were enabled
on the previous master are enabled on the new. This avoids enabling events
that may have been disabled on the master yet stayed in the SLAVESIDE_DISABLED-
state on the slave.
In the case of reset-replication command, events on the new master are only
enabled if the monitor had a master when the command was launched. Otherwise
all events remain disabled.
The documentation stated that at most `max_sescmd_history` commands were
kept but in reality the number of commands kept in the history was one
command smaller than what was documented.
If an ignorable packet was followed by more than one queued packets, they
would all get routed in the same batch. This would cause unexpected
replies from the server if multiple ignorable packets were queued up.
The default ECMAScript syntax appears to be broken on CentOS 7 which
effectively prevents its use in most cases. A more reliable alternative
would be to use the bundled PCRE2 library but the basic POSIX regular
expressions seem to work.
The script generates the required .avsc files without requiring a direct
connection to the database. This makes it easier to generate schemas in
more secure installations where direct access and installing dependencies
might not be easy.
This commit adds a new parameter that, when enabled, prunes the session
command history to a known length. This makes it possible to keep a
client-side pooled connection open indefinitely at the cost of making
reconnections theoretically unsafe. In practice the maximum history length
can be set to a value that encompasses a single session using the pooled
connection with no risk to session state integrity. The default history
length of 50 commands is quite likely to be adequate for the majority of
use-cases.
When the connection state is reset by executing a COM_CHANGE_USER or
COM_RESET_CONNECTION, readwritesplit does not need to store the session
command history that was executed before it. With this, pooled connections
will effectively behave like normal connections if the pooling mechanism
is smart enough to reset the connection. This also prevents unwanted
visibility into the session states of other connections.
If the routing of a session command fails due to problems with the backend
connections, a more verbose error message is logged. The added status
information in the Backend class makes tracking the original cause of the
problem a lot easier due to knowing where, when and why the connection was
closed.
If a server was not chosen as the target of a routing hint, the server
status would not be logged. By logging the server state in the message, it
is easier to figure out why a server wasn't chosen as the routing target.
Both the replication lag and the message printing state are saved in SERVER,
although the values are mostly used by readwritesplit. A log message is printed
both when a server goes over the limit and when it comes back below.
Because of concurrency issues, a message may be printed multiple times before
different threads detect the new message state.
Documentation updated to explain the change.
There is a race condition between the addition of the DCB into epoll and
the execution of the event that initiates the protocol pointer for the DCB
and sends the handshake to the client. If a hangup event would occur
before the handshake would be sent, it would be possible that the DCB
would get freed before the code that sends the handshake is executed.
By picking the worker who owns the DCB before the DCB is placed into the
owner's epoll instance, we make sure no events arrive on the DCB while the
control is transferred from the accepting worker to the owning
worker.
If the connection to the master is lost, knowing what type of an error
caused the call to handleError helps deduce what was the real reason for
it. Logging the idle time of the connection helps detect when the
wait_timeout of a connection is exceeded.
The code used a rather questionable method for parsing SQL statements
instead of using the query classifier for detecting transaction start and
stop events.