Server creation and allocation are now the same apart from the fact that
allocation only adds the server to the running configuration where as the
creation of a server also persist it to disk.
The server serialization should not be seen through the server.h API. This
allows the serialization method to change without actually having to
change the interfaces.
The MySQL Monitor did not reset the pointer to the root master reference
which would lead to a crash if the master was removed.
When service details were shown, it listed all servers that existed. Only
servers that haven't been removed or destroyed should be shown.
If a server were to be destroyed, it should not show up among
non-destroyed servers. Even though the servers aren't actually destroyed,
it hides unnecessary information from the user.
Previously, negative values were allowed for persistpoolmax and
persistmaxtime. Now they cause an error. Also, monitor_interval
allowed negative (or zero) values, which were then implicitly cast to
unsigned, causing unintended behaviour. Now this causes a warning
and the default value is used.
When a server is created via MaxAdmin, it will be serialized to disk. This
allows created servers to be retained through a restart of MaxScale.
Currently, all serialized objects are stored in one folder and there is no
structure in the created files. In the future, servers could be created
under a `servers` subdirectory so that it is easier to see what was
added. Whether there is a need for this will be seen.
The server credentials are only used if both the monuser and monpw
parameters are defined. This is a sort of a bugfix as a monitor connection
could use a username from server but a password from the monitor.
The server monuser and monpw members were used with the assumption that
they could be NULL. This is no longer true since they were converted to
arrays.
The name member of the server was freed leading to a crash when the server
unit test was run.
The persisted configuration directory is created and/or read when MaxScale
starts. This allows the servers created at runtime to be recreated when
MaxScale is restarted.
The persisted configuration subdirectory will be used to store changes to
the configuration. The gwdirs.h header now supports setting and getting
the value for this directory.
The address, port, monuser and monpw parameters of an existing server can
be changed at runtime. The support for enabling SSL will come in a later
commit.
Allowing servers to be modified could also be done by destroying and
recreating them. Since the servers are never actually destroyed, it is
better to allow the alteration of the existing ones.
MaxScale can now start without any defined monitors. This allows the core
services to be configured beforehand. With the changes to dynamic
modifications to servers, automatic scaling of slaves is possible.
The `add server` command accepts a server name and either a service name
or a monitor name. It will add servers to services and monitors. Since all
monitors use the MONITOR_SERVER structures directly, the monitors need
to be stopped before new servers are added to them
The debugcmd parameter processing didn't actually allow the maximum number
of parameters to be passed to the function. The detailed help text was
never printed and most of them were only duplicates of the short
description.
Before a query is routed to a backend, the status of the server reference
is checked. This allows the servers that are removed from a service to be
ejected from the list of active servers for active sessions.
The function serializes a server to a file. This is intended to be used
with dynamically created servers. The output of the server serialization
will eventually be stored in the configuration file directory (default is
/etc/maxscale.cnf.d/) so that created servers persist even after a
restart.
The createInstace, newSession, closeSession and freeSession functions were
cleaned up and reorganized to be a bit clearer for the reader. Removed
unnecessary comments and replaced them with ones that explain what's
happening in the code.
Removed unused linked lists from both sessions and instances and replaced
them with better alternatives. This should improve performance since new
session don't have to acquire the instance level lock to put themselves
into the session list.
Removed the use of the BACKEND structure and replaced it with the use of
the SERVER_REF structure of the service. This allows dynamic changes to be
made to the list of servers.
Cleaned up parts of the code and removed obsolete or useless
functions. The schemarouter module could do with some refactoring since it
derives from readwritesplit.
The BACKEND structure in readconnroute is now replaced with the use of the
SERVER_REF structure of the service. This allows dynamic changes to the
list of servers to be made.
The readwritesplit now understands that the amount of servers can change
and some of the items in the list of server references aren't in use. This
allows dynamic changes to the number of servers used by readwritesplit.
Servers can now be added and removed from services which allows routers to
use them with new sessions. The routers don't fully use the new
functionality in the server references which prevents new servers from
being taken into use.
If shutdown has been initiated (via maxadmin or by sending a
SIGINT or SIGTERM) and a SIGTERM is received, the process
is terminated.
If shutdown has been initiated (via maxadmin or by sending a
SIGINT or SIGTERM) and a SIGINT (Ctrl-C) is received, a warning
is printed that shutdown is in progess. Then, if an additional
SIGINT is received, the process is terminated.
So, in practice:
- If MaxScale is running as a daemon, the first SIGTERM initiates
shutdown and a second one unconditionally terminates the process.
- If MaxScale is running in the console, the first Ctrl-C initiates
shutdown, the second prints a warning and the third terminates
the process.
This is to ensure that MaxScale can be forced to exit, in
case some thread is hung for whatever reason, and is thus preventing
the controlled shutdown.
If the user running MaxScale could open the .secrets-file and the
file permissions were anything other than owner:read, the
secrets_readkeys() would fail with error message
"Ignoring secrets file <path>, invalid permissions." Now the
message is more accurate in stating the expected permissions.
The qlafilter now has an option to log all messages to a single
file instead of session-specific files. Session ids are printed
to the beginning of the line when using this mode. Documentation
updated to match. Also, added an option to flush after every
write.
When persistent connections were used, it was possible that the injection
of COM_CHANGE_USER statements caused a crash when a DCB in the wrong state
was accessed.
For MySQL protocol modules, the `data` member of the client DCB points to
the shared session data, a MYSQL_session struct, but for sessions in the
persistent pool, it points to NULL. The boolean, `was_persistent`, tells
whether a DCB was just taken from the pool or it has been in use.
The `was_persistent` status wasn't properly reset for connections that
were put into the pool which caused a COM_CHANGE_USER statement to be
injected for stale connections in the pool which caused a crash when the
NULL `data` member was accessed.
Previously the session_id incrementation was done after creating
filters, giving the filters a constant zero value for session_id.
Now the incrementation happens before filter creation.
This allows safer lock-free reads to be done on lists that never shrink in
size. The main use-case for this is to allow servers to be added to a
service without locking the service each time a new session is created.
Synchronizing the memory before adding new components into a list
guarantees that if a session reads from the list and sees the new list
item, the memory pointed by the item is valid.