In principle it would be better if the qc information were
obtained via a specific query_classifier resource. However,
there are multiple problems with that (e.g. the qc has no way
of safely accessing information of another thread) and hence
the worker specific qc cache statistics is reported as part of
the worker statistics.
The Session class now contains all of the C++ objects that were previously
in the MXS_SESSION struct. It is also allocated with new but all
initialization is still done outside of the Session in session_alloc_body.
This commit will not compile as it is a part of a set of commits that make
parts of the session private.
The most relevant string variables of a service are now duplicated as C++
strings. This should ease the eventual transition to a fully C++ internal
representation of the service. The array of refresh rates was also wrapped
inside a std::vector to remove the need to manually manage memory.
Separated the SERVICE_USER struct into its individual components as there
was no real need to have them inside a struct.
The service now has a private std::mutex that is used for
synchronization.
Renamed the vector of services to use snake_case.
Use lock guards with mutexes to make usage easier and safer. This makes
the code smaller as well as slightly easier to read.
The service now uses a std::vector<SFilterDef> to store the filters it
uses. Most internal parts deal with the SFilterDef but debugcmd.cc still
moves raw pointers around (needs to be changed).
The function has use outside of the monitors as it makes execution of
worker tasks much more convenient. Currently, this change only moves the
code and takes it into use: there should be no functional changes.
Uses mostly the status functions for reading the flags. Strickly
speaking this breaks the REST API since in some cases (status combinations)
the printed string is different from what was printed before.
The signal handler no longer acquires the service list lock which removes
a number of deadlock possibilities from the shutdown process. Instead, a
global shutdown flag is set that serves the same purpose as the individual
service shutdown flags did.
The cache now enforces the defined maximum size by evicting some
entries in case the insertion of a new entry would cause the max
size to be exceeded. Currently the eviction algorithm simply
removes a random element.
The result set mechanism was ill-suited for iteration over
lists. Converting it into a class and inverting it by pushing rows into
the result set instead the result set asking for rows makes it very easy
to use with lists. It also solves some of the consistency problems that
existed with the previous implementation.
The monitor can now differentiate between slaves with a running
series of slave connections to the master from slaves with broken
links. Both still get the SERVER_SLAVE-flag if 'detect_stale_slave'
is on.
Also, relay servers must be running.
Data can now be stored on thread-local storage of the worker. By acquiring
a unique handle from the worker, a module can store a thread-local
value.
This functionality will be used to store configurations that are sometimes
updated at runtime but are largely read-only. By avoiding shared data
altogether, performance is not affected. The only synchronization that is
done is on update.
Also added a helper functions for broadcasting tasks on all routing
workers. With the old mxs_rworker_broadcast_message function, if a
function call was broadcasted it was always queued for execution. The
mxs_rworker_broadcast will immediately execute the task on the local
worker and queue it for execution of other routing workers.
Converted the internal service header to a C++ header and moved all
functions there that are for internal use only.
Added the new Service type that inherits the SERVICE struct. This is to
distinct the opaque external C interface from the C++ internals.
The filter implementation is now fully hidden. Also converted it to a C++
struct allocated with new and stored the filters in a global list instead
of embedding the list in the object itself.
When a session is closed, it releases a reference on the service and
checks if it was the last session for a destroyed service. The state of
the service was loaded after the reference count was decremented. This
behavior introduced a race condition where it was possible for a service
to be freed twice, first by the thread that marked the service as
destroyed and again by the last session for that service. By always
loading the service state before decrementing the reference count, we
avoid this race condition.
Currently, the memory ordering used for the reference counting is too
strict and could be relaxed. By default, all atomic operations use
sequentially consistent memory ordering. This guarantees correct behavior
but imposes a performance penalty. Incrementing the reference counts could
be done with a relaxed memory order as long as as we know the reference
we're incrementing is valid. Releasing a reference must use an
acquire-release order to guarantee the read-modify-write operation is
successful.
The initialization and starting of the housekeeper is now done
separately. This allows housekeeper tasks to be created when the services
are being created while still preventing the execution of the task before
the startup is complete.
Services can now be destroyed if they have no active listeners and they
are not linked to servers. When these conditions are met, the service will
be destroyed when the last session for the service is closed.
The closing of a service will close all listeners that were once assigned
to the service. This allows closing of the ports at runtime which
previously was done only on shutdown.
Exposed the command through the REST API but not through MaxAdmin as it is
deprecated.
When the query queue does not contain a complete packet
(i.e. modutil_get_next_MySQL_packet return NULL), an informative dump of
how many bytes and what is stored is logged.
By aborting the process if memory runs out when a buffer needs to be made
contiguous, we rule out other, more subtle, errors. Failing as soon as a
possible when memory allocation fails gives better error messages.
The LocalClient micro-client required a reference to the session that was
valid at construction time. This is the reason why the previous
implementation used dcb_foreach to first gather the targets and then
execute queries on them. By replacing this reference with pointers to the
raw data it requires, we lift the requirement of the orignating session
being alive at construction time.
Now that the LocalClient no longer holds a reference to the session, the
killing of the connection does not have to be done on the same thread that
started the process. This prevents the deadlock that occurred when
concurrect dcb_foreach calls were made.
Replaced the unused dcb_foreach_parallel with a version of dcb_foreach
that allows iteration of DCBs local to this worker. The dcb_foreach_local
is the basis upon which all DCB access outside of administrative tasks
should be built on.
This change will introduce a regression in functionality: The client will
no longer receive an error if no connections match the KILL query
criteria. This is done to avoid having to synchronize the workers after
they have performed the killing of their own connections.
The dcb_foreach function is not safe to use from multiple threads at the
same time. This should be asserted by checking that the function is called
only from the main worker.
The addition of this assertion also implies that only administrative
operations should use the dcb_foreach function. To accommodate this
change, the KILL command iteration needs to be adjusted.
MariaDBMonitor diagnostics printing is unsafe as some of the read
fields are arrays. To be on the safe side, the fields are now read
in the monitor worker thread.
Since diagnostics must work even for stopped monitors, a worker task
is used. In practice, it usually runs when the monitor is sleeping.
With the removal of the old session command implementation, the code that
used it can be removed or replaced with newer constructs. As a result, the
backend protocol no longer does any session command processing.
The three buffer types, GWBUF_TYPE_SESCMD_RESPONSE,
GWBUF_TYPE_RESPONSE_END and GWBUF_TYPE_SESCMD as well as their related
macros are no longer used and can be removed.