maria:bb-10.10-nikita

Last commit made on 2022-06-19
Get this branch:
git clone -b bb-10.10-nikita https://git.launchpad.net/maria

Branch merges

Branch information

Name:
bb-10.10-nikita
Repository:
lp:maria

Recent commits

7bffc4f... by Nikita Malyavin

Add tests and code instrumentations

2946e51... by Nikita Malyavin

APC tpool: Windows concept

722f11c... by Nikita Malyavin

APC tpool: An obstruction-free algorithm

The approach is epoch-based. Each time we enter and exit the task, we
increase the epoch. This way, we can tell either we are in the task
processing or we are finished and standing by, or going to, by checking
epoch oddity. Besides, if the task ran several times, we can know that apc
requests have been guaranteedly processed.

However, if the last apc request processing happens before exit epoch
increase, we cannot tell, whether it's been processed or not, and should
wait in the busy loop until either the task runs again (epoch changes),
or we remove fd from poll.

To prevent long busy loop, apc request processing should happen right
before start_io() and after epoch exit increase.

We can still end up busy-waiting until all the requests will be processed.
But since the request queue is guarded by LOCK_thd_kill, we'll end up in a
deadlock.

To prevent this, another epoch counter is introduced inside apc.
It increases once before the mutex lock (LOCK_thd_kill), and before it
unlocks in the end.

So by checking the oddity of this new counter we can tell, whether are we
hanging on the lock, or not. It is safe to consider that the request will
be processed if the epoch is odd.

This way, we

8729e20... by Nikita Malyavin

APC tpool implementation

c4bfe13... by Nikita Malyavin

APC thread per connection impl

To have a guaranteed wakeup with no lost signal, the folowing approaches
are applied on different platforms:
* Linux/FreeBSD:
This applies to any platform with _GNU_SOURCE defined.
  1. set a signal mask to ignore the signal (namely, SIGUSR1. It is better
  not to interfer with the signals that can be used by OS)
  2. call ppoll instead of poll, that applies the signal mask atomically
  with polling.
  3. hopefully, if the signal is received before the ppoll call
  (i.e. masked out) will be still set to pending, so the next ppoll call
  (as well as any unmasking) will force it to be handled. We will receive
  EINTR and the read will be retried.

* Solaris, other POSIX
There is no ppoll function on Solaris, but it has differently handled
opened files limitation, which allows to freely open new file descriptors
as needed.
Here we will use the self-pipe trick to wake up:
  1. A thread-local pipe is created. Its read end will be additionally used
  by poll.
  2. A signal handler will write to this pipe to wake up from poll.
Linux is not safe for using this method, because its file limits are rather
low, especially the default ones.
Solaris has the per-process restriction rather than per-user:
https://support.oracle.com/knowledge/Sun%20Microsystems/1005979_1.html
> A process can have up to rlim_fd_cur file descriptors and can increase
> the number up to rlim_fd_max.
The latter is 1024 on Solaris 7 by default.

We can't say about other POSIX'es limitations, but it is assumed they have
no ppoll function.
pselect is not assumed because of the silly limitations.
So the only way for them can be self-piping.

* Windows
Self-pipe trick is used as well, but instead of poll, select is used,
and QueueUserAPC is used instead of signals.

Caveats:
* It is possible that the connection will hang on write for long.
  The requestor should wait until the write ends, or fail with timeout.
* The connection can hang in other commands for long, for example, on
  sleep().

We generally can't assume it is safe to handle the apc during both of these
cases, but maybe some safe zones can be marked. Anyway it is considered to
be out of the scope of this task.

637e1af... by Nikita Malyavin

APC API: Fix race condition cond_timedwait() vs mutex_destroy via LOCK_thd_kill

Basically, when we begin waiting on condition, the mutex is unlocked,
so the protection inside ~THD
  mysql_mutex_lock(&LOCK_thd_kill);
  mysql_mutex_unlock(&LOCK_thd_kill);

doesn't work. The mutex is freely acquired and it is skipped.
Then mysql_mutex_destroy can be called.

Meanwhile, another thread can receive the signal and acquire the mutex
back, which is UB, since it was already destroyed.

In particalar, safe_cond_timedwait tries to update some statistics on mutex
that were freed by safe_mutex_destroy, as well as mp->global, which is
tried to acquire.

fb922c2... by Nikita Malyavin

Split Apc_target::make_apc_call into two functions.

In pfs_variable.cc we will have to make an additional step between
enqueue_request and wait_for_completion. These two functions will be called
directly and therefore both should have a public interface

b96afca... by Nikita Malyavin

MDEV-16440 merge 5.7 P_S sysvars instrumentation and tables

37e1ccb... by Nikita Malyavin

Set thread name to con_%d in debug mode

d371e35... by Marko Mäkelä

Merge 10.9 into 10.10