Authentication plugins

MariaDB also supports authentication plugins. These plugins can implement different methods for login and logout. Generally, this is useful to prevent an external program from authenticating users into a MariaDB server. Some plugins require the client to interact with them using appropriate client plugins. The client plugins are dynamically loaded and need not be installed, but this requires the client to be built dynamically.

Currently, MariaDB 10.0 comes with four authentication plugins:

  • mysql_native_password: This is the default MariaDB authentication plugin
  • mysql_old_password: This is the old (less secure) password hashing used in MySQL 4.0 and even in MySQL 3.23 (they had 20-byte and 9-byte shadowed passwords, respectively)
  • unix_socket: This plugin uses the credentials of the Unix user
  • pam: This plugin uses Unix Pluggable Authentication Modules (PAM)

The last two plugins are not installed by default. They can be installed with the following statements:

INSTALL SONAME 'auth_socket';
INSTALL SONAME 'auth_pam';

Other plugins may be added to the MariaDB packages in the future, or developed by companies that need them and have the internal skills to develop authentication plugins. The exact list of authentication plugins can be obtained with the following query:

SELECT PLUGIN_NAME, PLUGIN_STATUS
  FROM information_schema.PLUGINS
  WHERE PLUGIN_TYPE = 'AUTHENTICATION';

It is possible that you may require an account to connect MariaDB using a particular authentication plugin. To do this, both CREATE USER and GRANT can be used, like in the following examples:

CREATE USER federico IDENTIFIED VIA 'mysql_native_password';
GRANT USAGE ON *.* TO federico IDENTIFIED VIA 'unix_socket';

In the preceding example, first the user federico was created specifying explicitly that he uses the default MariaDB authentication (this is not necessary when creating a user, but can be done). Then, we require that the user connects via the unix_socket plugin, shown as follows:

MariaDB [(none)]> CREATE USER federico IDENTIFIED VIA 'mysql_native_password';
Query OK, 0 rows affected (0.00 sec) 
MariaDB [(none)]> GRANT USAGE ON *.* TO federico IDENTIFIED VIA 'unix_socket';
Query OK, 0 rows affected (0.03 sec)

The USAGE command is a virtual permission. It can be specified when we don't want to grant any real permission. Simply omitting the permissions list will cause a syntax error. In the preceding example, we used USAGE so that the user federico connects using unix_socket.

To complete the example, let's see how this user can connect to MariaDB.

Let's use a shell as federico, and start the mysql command-line client:

federico@this:/usr/local/mysql$ bin/mysql
Welcome to the MariaDB monitor.  Commands end with ; or g.

It works because we are already logged in as federico. The unix_socket plugin verifies whether the thread belongs to federico and accepts the connection.

Now, let's use the shell as the root, and start mysql:

root@this:/usr/local/mysql# bin/mysql
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 

As the user of the current system is root and not federico, the connection is not accepted. However, we can use the --user option, which starts the client as the specified user:

root@this:/usr/local/mysql# bin/mysql --user federico
Welcome to the MariaDB monitor.  Commands end with ; or g. 

With the client running as the appropriate user, the connection is accepted.

Note

Note that this feature cannot be used to run mysql as another user if you don't have the permissions to do so. Instead, it is useful if you are logged in as root and need to start mysql as a normal user.

Limiting user resources, MariaDB allows us to limit the amount of system resources an account can consume. This is done with the GRANT statement. The following are the limits that can be set:

  • MAX_QUERIES_PER_HOUR: This limit sets the number of queries (statements that return data but do not modify them) that can be executed in an hour. It does not affect queries that use the query cache.
  • MAX_UPDATES_PER_HOUR: This limit sets the number of statements that modify the data that can be executed in an hour.
  • MAX_CONNECTIONS_PER_HOUR: This limit sets the number of connections that the account can establish in an hour.
  • MAX_USER_CONNECTIONS: This limit sets the number of simultaneous connections that the account can establish.

For all these values, the default is 0, which means that the limit does not apply to the account. However, MAX_USER_CONNECTIONS is an exception; if it is set to 0, the limit is set to the global value of the max_user_connections server variable. Its default value is 0, which means that the limit does not apply. The user can query the session value of this variable to know the maximum number of simultaneous connections that this account can establish.

An example of how to assign a resource limit is shown as follows:

MariaDB [(none)]> GRANT USAGE ON TABLE *.* TO 'u1'@'%' WITH MAX_QUERIES_PER_HOUR 100 MAX_UPDATES_PER_HOUR 50;
Query OK, 0 rows affected (0.00 sec) 

The GRANT statement has some mandatory clauses; this means that we cannot execute a GRANT statement that does not assign any permission. Since our purpose is not to assign permission, we specify USAGE, which is a virtual right; it does not allow us to do anything. Then, we specify the WITH keyword, followed by the resource limits we want to set.

An example of how to know which account we are using and how many simultaneous connections it is allowed to establish is shown as follows:

MariaDB [(none)]> SELECT CURRENT_USER(), @@session.max_user_connections;
+----------------+--------------------------------+ 
| CURRENT_USER() | @@session.max_user_connections | 
+----------------+--------------------------------+ 
| root@localhost |                              0 | 
+----------------+--------------------------------+ 
1 row in set (0.00 sec) 

Tip

If an account has reached one of its limits, and we want to temporarily enable it to continue doing its work, we can reset all hourly resource limits. This does not apply to MAX_USER_CONNECTIONS, which is not an hourly limit. Note that there is no way to reset these limits for a single user. To reset the limits, the FLUSH USER_RESOURCES statement can be used. The FLUSH PRIVILEGES or mysqladmin reload commands can also be used because they entirely reload the privilege tables handling threads.

Traditionally, MariaDB and MySQL create a new thread every time a client connects to the server. This thread handling method is called one thread per connection. It is still the default method on most systems, with the only exception of Windows (starting from Vista).

In most cases, MariaDB is used for the workloads described with the On Line Transaction Processing (OLTP). This includes all cases where data is often modified, such as most websites and desktop applications. In such workloads, usually a client connects, executes a few fast statements, and closes the connection. If there are many users, this means that many clients connect to the server for a very short time. The one thread per connection method is not good for such workloads, because creating and destroying a thread has a cost in terms of CPU and memory, and the execution of a small series of fast operations may not be worth that cost.

In MariaDB 5.1, a new thread handling method was added called the pool of threads. The idea is that each thread can handle multiple connections. Each thread is part of a group. In MariaDB 5.1, the total number of threads is fixed. The pool of threads method has been refactored in MariaDB 5.5. This method now creates new threads when the current number of threads is insufficient and destroys threads when they are not useful anymore. It always tries to keep the number of threads reasonable; if it is too low, this method is not beneficial and if it is too high, there is a wastage of resources.

Note that the pool of threads method can queue several threads in the same group. This means that while this method avoids the overhead of a thread's creation and destruction, and generally speeds up the global performance of an OLTP workload, the individual statements or transactions may be slower. For example, a trivial query such as SELECT VERSION() should immediately return one row, but with the pool of threads method, it may have to wait for more complex queries to be executed.

The pool of threads is a bit different on Windows, because it uses the native threadpool implementation. On all other systems, MariaDB uses its own threadpool implementation. From a user's point of view, this mainly means that on Windows, the available configuration variables are not the same that are available on other systems. On Windows versions older than Vista, this feature does not work, and the one thread per connection method is always used.

Activating the pool of threads

To enable the pool of threads, the configuration file should contain the following line:

thread_handling=pool-of-threads

On Windows versions older than Vista, this option is silently ignored. On Vista and more recent versions, the pool of threads is the default method (this differs from all other systems).

If this line is written in a global configuration file, it is possible to override it for an individual MariaDB installation by adding the following line to its own configuration file:

thread_handling=one-thread-per-connection

Monitoring the pool of threads

To see which connection handling method is used, the thread_handling variable can be queried:

MariaDB [(none)]> SELECT @@global.thread_handling;
+--------------------------+ 
| @@global.thread_handling | 
+--------------------------+ 
| pool-of-threads          | 
+--------------------------+ 
1 row in set (0.00 sec) 

The pool of threads has two status variables that can be used to monitor the threads' activities:

  • threadpool_threads: This variable helps the thread determine the total number of threads.
  • threadpool_idle_threads: This variable helps the thread determine the number of threads that are doing nothing—because they are idle, or because they are waiting for a lock to be released. This value is not monitored on Windows.

If the one pool per connection method is used, both these values are 0, as seen in the following example:

MariaDB [(none)]> SHOW STATUS LIKE 'threadpool%';
+-------------------------+-------+ 
| Variable_name           | Value | 
+-------------------------+-------+ 
| Threadpool_idle_threads | 0     | 
| Threadpool_threads      | 0     | 
+-------------------------+-------+ 
2 rows in set (0.00 sec) 

Configuring the threadpool implementation

As explained previously, MariaDB uses the Windows' native threadpool implementation and an ad hoc implementation on all other systems. These two implementations expose different details about how the pool of threads works; so the variables that can be used on Windows are different from the variables that can be used on a Unix-like system. The ad hoc implementation exposes more details.

The list of pool of threads configuration variables can be obtained with the following query:

SHOW VARIABLES LIKE 'thread_pool%';

Configuring the pool of threads on Unix

The following variables can be used to configure the pool of threads on Unix:

  • thread_pool_size: This variable gives the number of thread groups. Since normally one thread per group is working, this is also the approximated number of concurrent threads. By default, it is equal to the number of server CPUs. Note, however, that MariaDB never executes a single query on multiple CPUs. This is a very important parameter to tune under some circumstances. Incrementing it should not lead to any performance gain. However, if MariaDB does not run on a dedicated server, we may want it to use only a limited number of CPUs. For example, if we have a machine with four CPUs running MariaDB and a web server, we might want MariaDB to only use three CPUs. This can be done by setting thread_pool_size to 3.
  • thread_pool_stall_limit: This variable gives a timeout, expressed in milliseconds, after which a thread is considered stalled. When this happens, the pool of threads will try to wake the thread up, or create another one. This mechanism prevents long running queries from stopping the queued queries for a long time. However, if thread_pool_max_threads is also reached, no new thread can be created. The default value is 500.
  • thread_pool_max_threads: This variable gives the maximum number of threads. It refers to the total number and not a per-group limit. When this limit is reached, no new thread can be created. The default value is 500. This variable is available for all systems.
  • thread_pool_idle_timeout: This variable gives a time-out, expressed in seconds, after which idle threads are terminated. The default value is 60.
  • thread_pool_oversubscribe: This variable gives a variable for internal use and should not be changed by the user. It is mentioned here just because it appears in the output of the SHOW VARIABLES LIKE 'thread_pool%' statement.

Configuring the pool of threads on Windows

The following variables can be used to configure the pool of threads on Unix:

  • thread_pool_min_threads: This variable gives the minimum number of threads. Windows can retire threads when they are not needed, unless the minimum limit has been reached.
  • thread_pool_max_threads: This variable gives the maximum number of threads. It refers to the total number; it is not a per-group limit. When this limit is reached, no new thread can be created. The default value is 500. This variable is available for all systems.

Tuning the configuration variables

Now, we will list some possible problems that may rise on a server that uses the pool of threads, and explain how to use the configuration variables to improve the performance.

Sometimes, a thread may lock several tables to perform some action. For example, it may issue a FLUSH TABLES … WITH READ LOCK statement to perform a physical backup of non-transactional tables (this technique will be discussed in Chapter 8, Backup and Disaster Recovery). In such cases, all threads (or several threads) will be blocked. Usually, it causes the pool of threads to create new threads, but in this case the new threads will not solve the problem and will consume more resources. Setting thread_pool_max_threads to a sufficiently low value prevents the creation of such threads.

Some workloads are not equally distributed in time. They may burst for a given period, during which a high number of connections are established. After that period, they may return to a state of very low activity. Such workloads do not benefit from the pool of threads method during the period in which several connections are established because it has to create several threads, which takes some time. To avoid this problem, we want MariaDB to preserve more threads during the low activity periods. On Unix, we can achieve this by increasing thread_pool_idle_timeout, so that the timeout is higher than the time that separates the interval between two high activity periods. On Windows, we will simply increase thread_pool_min_threads.

While data warehouse workloads are not likely to benefit from the pool of threads method, even on an OLTP database, reports may be periodically generated from a nontrivial quantity of data. Such queries probably don't lock (see Chapter 4, Transactions and Locks) but can block the queued statements for an amount of time that is not acceptable. To avoid this problem on Unix, we can set thread_pool_stall_limit to a lower value.

Unblocking a blocked pool of threads

What happens if the pool of threads method is used and one client obtains a lock on all the tables to perform a very long operation? The other threads will be blocked. To solve this problem, MariaDB will create more threads, but this does not help because each new thread will still have to wait for the lock to be released. Also, we may reach the thread_pool_max_threads limit. In this case, the server will refuse new connections and the DBA will not be able to connect to the server to investigate what is happening. To avoid this, one can consider increasing the limit, but this might lead to a high number of threads in all situations, making the pool of threads useless.

The solution is to reserve an extra port for connections that will use the one thread per connection method. The number of such connections is limited, usually one is enough. The variables that control this feature are as follows:

  • extra_port: This variable gives the number of the port that will accept connections using the one thread per connection method
  • extra_max_connections: This variable gives the maximum number of simultaneous connections that the extra port will accept

Note

Note that this technique can also be used to allow some connections to work in the one thread per connection mode (so that they are never queued in a group), while others run in the pool of threads. However, in this case, extra_max_connections should be high enough to always accept an extra connection to solve lock problems.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.45.5