Bug #112255 empty vio->signal_mask in the x plugin causes MySQL cannot handle signal
Submitted: 5 Sep 2023 0:58 Modified: 9 Oct 2023 13:43
Reporter: Jinyou Ma Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Document Store: X Plugin Severity:S3 (Non-critical)
Version:8.0.33, 8.0.34 OS:Linux
Assigned to: CPU Architecture:Any

[5 Sep 2023 0:58] Jinyou Ma
Description:

Sending a SIGTERM signal to MySQL that has connections from the x plugin, the MySQL will be terminated rather than a normal shutdown.

In the strace log,
sudo strace -ff -e ppoll -p 197945
[pid 198030] ppoll([{fd=36, events=POLLIN|POLLPRI}], 1, {tv_sec=0, tv_nsec=500000000}, [], 8) = 1 ([{fd=36, revents=POLLIN}], left {tv_sec=0, tv_nsec=35652
7081})

When the mysqlsh connects to MySQL, the _ss in the ppoll syscall is empty.
When MySQL receives a single, It cannot handle the single.

How to repeat:
- 1. start a mysql
$ /usr/sbin/mysqld --defaults-file=/etc/my.cnf
- 2. start a mysqlsh session
$ mysqlsh "mysqlx://root@127.0.0.1:33060" -uroot -p123
MySQL Shell 8.0.34
Server version: 8.0.34-0ubuntu0.23.04.1 (Ubuntu)
 MySQL  ubuntu > 127.0.0.1:33060+  JS
- 3. kill mysql process
$ pgrep mysqld
195438
$ kill -15 195438

# The MySQL will be terminated.

Suggested fix:
When accept a connect from x plugin, the MySQL should set the vio->signal_mask.

diff --git a/plugin/x/src/ngs/socket_events.cc b/plugin/x/src/ngs/socket_events.cc
index 582e5b451c2..fb15f8f0fe2 100644
--- a/plugin/x/src/ngs/socket_events.cc
+++ b/plugin/x/src/ngs/socket_events.cc
@@ -34,6 +34,7 @@
 #include "plugin/x/src/ngs/memory.h"
 #include "plugin/x/src/ngs/socket_events.h"
 #include "plugin/x/src/operations_factory.h"
+#include "sql/mysqld.h"

 // Surpressing numerous warnings generated by libevent on Windows.
 #ifdef WIN32
@@ -93,6 +94,15 @@ class Connection_acceptor_socket : public xpl::iface::Connection_acceptor {
                                is_tcpip ? VIO_TYPE_TCPIP : VIO_TYPE_SOCKET, 0);
     if (!vio) throw std::bad_alloc();

+#ifdef USE_PPOLL_IN_VIO
+    if (vio != nullptr) {
+      // Unset thread_id, to ensure that all shutdowns explicitly set the
+      // current real_id from the THD.
+      vio->thread_id.reset();
+      vio->signal_mask = mysqld_signal_mask;
+    }
+#endif
+
     // enable TCP_NODELAY
     vio_fastsend(vio);
     vio_keepalive(vio, true);
[6 Sep 2023 4:45] MySQL Verification Team
Hello jin ma,

Thank you for the report and test case.
Verified as described.

regards,
Umesh
[9 Oct 2023 13:43] Stefan Hinz
Posted by developer:
 
Fixed in 8.3.0.
Code cleanup. No changelog entry required.