mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-6536: make --bind=hostname to listen on both IPv6 and IPv4 addresses
Binding to a hostname now makes MariaDB server to listen on all addresses that hostname resolves to. Rebased to 10.6 by Daniel Black Closes: #1668
This commit is contained in:
committed by
Daniel Black
parent
f691d9865b
commit
b3abcf80a1
@ -75,6 +75,15 @@ struct st_mysql_socket
|
|||||||
/** The real socket descriptor. */
|
/** The real socket descriptor. */
|
||||||
my_socket fd;
|
my_socket fd;
|
||||||
|
|
||||||
|
/** Is this a Unix-domain socket? */
|
||||||
|
char is_unix_domain_socket;
|
||||||
|
|
||||||
|
/** Is this a socket opened for the extra port? */
|
||||||
|
char is_extra_port;
|
||||||
|
|
||||||
|
/** Address family of the socket. (See sa_family from struct sockaddr). */
|
||||||
|
unsigned short address_family;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The instrumentation hook.
|
The instrumentation hook.
|
||||||
Note that this hook is not conditionally defined,
|
Note that this hook is not conditionally defined,
|
||||||
@ -105,7 +114,7 @@ typedef struct st_mysql_socket MYSQL_SOCKET;
|
|||||||
static inline MYSQL_SOCKET
|
static inline MYSQL_SOCKET
|
||||||
mysql_socket_invalid()
|
mysql_socket_invalid()
|
||||||
{
|
{
|
||||||
MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
|
MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, 0, 0, 0, NULL};
|
||||||
return mysql_socket;
|
return mysql_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
mysql-test/main/bind_address_resolution.opt
Normal file
1
mysql-test/main/bind_address_resolution.opt
Normal file
@ -0,0 +1 @@
|
|||||||
|
--bind-address=localhost
|
15
mysql-test/main/bind_address_resolution.result
Normal file
15
mysql-test/main/bind_address_resolution.result
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
CREATE TABLE t (a TEXT);
|
||||||
|
connect con1,localhost,root,,test;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a
|
||||||
|
connect con2,127.0.0.1,root,,test;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a
|
||||||
|
connect con3,::1,root,,test;
|
||||||
|
SELECT * FROM t;
|
||||||
|
a
|
||||||
|
connection default;
|
||||||
|
DROP TABLE t;
|
||||||
|
disconnect con1;
|
||||||
|
disconnect con2;
|
||||||
|
disconnect con3;
|
19
mysql-test/main/bind_address_resolution.test
Normal file
19
mysql-test/main/bind_address_resolution.test
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
--source include/check_ipv6.inc
|
||||||
|
--source include/not_embedded.inc
|
||||||
|
|
||||||
|
# The server is started with --bind-address=localhost, and should
|
||||||
|
# listen on all addresses 'localhost' resolves to. With at least
|
||||||
|
# 127.0.0.1 and ::1 amongst them.
|
||||||
|
|
||||||
|
CREATE TABLE t (a TEXT);
|
||||||
|
--connect(con1,localhost,root,,test)
|
||||||
|
SELECT * FROM t;
|
||||||
|
--connect(con2,127.0.0.1,root,,test)
|
||||||
|
SELECT * FROM t;
|
||||||
|
--connect(con3,::1,root,,test)
|
||||||
|
SELECT * FROM t;
|
||||||
|
--connection default
|
||||||
|
DROP TABLE t;
|
||||||
|
--disconnect con1
|
||||||
|
--disconnect con2
|
||||||
|
--disconnect con3
|
@ -80,15 +80,16 @@ Expect 1
|
|||||||
1
|
1
|
||||||
# Characteristics of 'server_tcpip_socket' entry
|
# Characteristics of 'server_tcpip_socket' entry
|
||||||
# Server listening socket, TCP/IP
|
# Server listening socket, TCP/IP
|
||||||
# There is only one entry with 'wait/io/socket/sql/server_tcpip_socket'.
|
# There are two entries with 'wait/io/socket/sql/server_tcpip_socket',
|
||||||
# It shares the same thread id as 'wait/io/socket/sql/server_unix_socket'.
|
# for [::] and for 0.0.0.0.
|
||||||
SELECT COUNT(*) = 1 AS 'Expect 1'
|
# They share the same thread id with 'wait/io/socket/sql/server_unix_socket'.
|
||||||
|
SELECT COUNT(*) = 2 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
||||||
Expect 1
|
Expect 1
|
||||||
1
|
1
|
||||||
# Get the 'server_tcpip_socket' thread id
|
# Get the 'server_tcpip_socket' thread id
|
||||||
SELECT THREAD_ID INTO @thread_id
|
SELECT DISTINCT THREAD_ID INTO @thread_id
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
||||||
# Check the content.
|
# Check the content.
|
||||||
@ -100,6 +101,7 @@ FROM performance_schema.socket_instances
|
|||||||
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
||||||
Expect 1
|
Expect 1
|
||||||
1
|
1
|
||||||
|
1
|
||||||
# Characteristics of 'server_unix_socket' entry
|
# Characteristics of 'server_unix_socket' entry
|
||||||
# Server listening socket, unix domain (socket file)
|
# Server listening socket, unix domain (socket file)
|
||||||
# There is only one entry with 'wait/io/socket/sql/server_unix_socket'.
|
# There is only one entry with 'wait/io/socket/sql/server_unix_socket'.
|
||||||
@ -123,12 +125,12 @@ WHERE EVENT_NAME = 'wait/io/socket/sql/server_unix_socket';
|
|||||||
Expect 1
|
Expect 1
|
||||||
1
|
1
|
||||||
# Server listening sockets (TCP and Unix) are handled on the same thread
|
# Server listening sockets (TCP and Unix) are handled on the same thread
|
||||||
SELECT COUNT(*) = 2 AS 'Expect 1'
|
SELECT COUNT(*) = 3 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE THREAD_ID = @thread_id;
|
WHERE THREAD_ID = @thread_id;
|
||||||
Expect 1
|
Expect 1
|
||||||
1
|
1
|
||||||
SELECT COUNT(*) = 2 AS 'Expect 1'
|
SELECT COUNT(*) = 3 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE THREAD_ID = @thread_id;
|
WHERE THREAD_ID = @thread_id;
|
||||||
Expect 1
|
Expect 1
|
||||||
|
@ -38,6 +38,10 @@ if($my_socket_debug)
|
|||||||
--echo IPV6=$check_ipv6_supported, IPV4_MAPPED=$check_ipv4_mapped_supported, LOCALHOST=$my_localhost
|
--echo IPV6=$check_ipv6_supported, IPV4_MAPPED=$check_ipv4_mapped_supported, LOCALHOST=$my_localhost
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# This test only runs when IPv6 is supported (see include/check_ipv6.inc), so
|
||||||
|
# the server will listen on both IPv4 and IPv6 wildcard addresses. That's why
|
||||||
|
# the expected number of TCP/IP listeners is always 2.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Preserve the current state of SOCKET_INSTANCES
|
# Preserve the current state of SOCKET_INSTANCES
|
||||||
#
|
#
|
||||||
@ -222,17 +226,18 @@ AND PORT = 0 AND THREAD_ID = @thread_id;
|
|||||||
|
|
||||||
--echo # Characteristics of 'server_tcpip_socket' entry
|
--echo # Characteristics of 'server_tcpip_socket' entry
|
||||||
--echo # Server listening socket, TCP/IP
|
--echo # Server listening socket, TCP/IP
|
||||||
--echo # There is only one entry with 'wait/io/socket/sql/server_tcpip_socket'.
|
--echo # There are two entries with 'wait/io/socket/sql/server_tcpip_socket',
|
||||||
--echo # It shares the same thread id as 'wait/io/socket/sql/server_unix_socket'.
|
--echo # for [::] and for 0.0.0.0.
|
||||||
|
--echo # They share the same thread id with 'wait/io/socket/sql/server_unix_socket'.
|
||||||
|
|
||||||
SELECT COUNT(*) = 1 AS 'Expect 1'
|
SELECT COUNT(*) = 2 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
||||||
|
|
||||||
# Store the thread id of server_tcpip_socket
|
# Store the thread id of server_tcpip_socket
|
||||||
--echo # Get the 'server_tcpip_socket' thread id
|
--echo # Get the 'server_tcpip_socket' thread id
|
||||||
|
|
||||||
SELECT THREAD_ID INTO @thread_id
|
SELECT DISTINCT THREAD_ID INTO @thread_id
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
WHERE EVENT_NAME = 'wait/io/socket/sql/server_tcpip_socket';
|
||||||
|
|
||||||
@ -288,14 +293,14 @@ WHERE EVENT_NAME = 'wait/io/socket/sql/server_unix_socket';
|
|||||||
--disable_query_log ONCE
|
--disable_query_log ONCE
|
||||||
eval SET @thread_id = $server_tcpip_thread_id;
|
eval SET @thread_id = $server_tcpip_thread_id;
|
||||||
|
|
||||||
eval SELECT COUNT(*) = 2 AS 'Expect 1'
|
eval SELECT COUNT(*) = 3 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE THREAD_ID = @thread_id;
|
WHERE THREAD_ID = @thread_id;
|
||||||
|
|
||||||
--disable_query_log ONCE
|
--disable_query_log ONCE
|
||||||
eval SET @thread_id = $server_unix_thread_id;
|
eval SET @thread_id = $server_unix_thread_id;
|
||||||
|
|
||||||
eval SELECT COUNT(*) = 2 AS 'Expect 1'
|
eval SELECT COUNT(*) = 3 AS 'Expect 1'
|
||||||
FROM performance_schema.socket_instances
|
FROM performance_schema.socket_instances
|
||||||
WHERE THREAD_ID = @thread_id;
|
WHERE THREAD_ID = @thread_id;
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ log-bin= master-bin
|
|||||||
loose-innodb
|
loose-innodb
|
||||||
|
|
||||||
skip-name-resolve
|
skip-name-resolve
|
||||||
bind-address= ::
|
bind-address= *
|
||||||
|
|
||||||
|
|
||||||
[mysqld.2]
|
[mysqld.2]
|
||||||
@ -38,7 +38,7 @@ report-user= root
|
|||||||
|
|
||||||
skip-slave-start
|
skip-slave-start
|
||||||
skip-name-resolve
|
skip-name-resolve
|
||||||
bind-address= ::
|
bind-address= *
|
||||||
|
|
||||||
# Directory where slaves find the dumps generated by "load data"
|
# Directory where slaves find the dumps generated by "load data"
|
||||||
# on the server. The path need to have constant length otherwise
|
# on the server. The path need to have constant length otherwise
|
||||||
|
@ -22,11 +22,13 @@
|
|||||||
#include <mswsock.h>
|
#include <mswsock.h>
|
||||||
#include <mysql/psi/mysql_socket.h>
|
#include <mysql/psi/mysql_socket.h>
|
||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <handle_connections_win.h>
|
#include <handle_connections_win.h>
|
||||||
|
|
||||||
/* From mysqld.cc */
|
/* From mysqld.cc */
|
||||||
extern MYSQL_SOCKET base_ip_sock, extra_ip_sock;
|
extern HANDLE hEventShutdown;
|
||||||
|
extern std::vector<MYSQL_SOCKET> listen_sockets;
|
||||||
#ifdef HAVE_POOL_OF_THREADS
|
#ifdef HAVE_POOL_OF_THREADS
|
||||||
extern PTP_CALLBACK_ENVIRON get_threadpool_win_callback_environ();
|
extern PTP_CALLBACK_ENVIRON get_threadpool_win_callback_environ();
|
||||||
extern void tp_win_callback_prolog();
|
extern void tp_win_callback_prolog();
|
||||||
@ -128,6 +130,9 @@ struct Socket_Listener: public Listener
|
|||||||
/** Client socket passed to AcceptEx() call.*/
|
/** Client socket passed to AcceptEx() call.*/
|
||||||
SOCKET m_client_socket;
|
SOCKET m_client_socket;
|
||||||
|
|
||||||
|
/** Listening socket. */
|
||||||
|
MYSQL_SOCKET m_listen_socket;
|
||||||
|
|
||||||
/** Buffer for sockaddrs passed to AcceptEx()/GetAcceptExSockaddrs() */
|
/** Buffer for sockaddrs passed to AcceptEx()/GetAcceptExSockaddrs() */
|
||||||
char m_buffer[2 * sizeof(sockaddr_storage) + 32];
|
char m_buffer[2 * sizeof(sockaddr_storage) + 32];
|
||||||
|
|
||||||
@ -162,7 +167,8 @@ struct Socket_Listener: public Listener
|
|||||||
*/
|
*/
|
||||||
Socket_Listener(MYSQL_SOCKET listen_socket, PTP_CALLBACK_ENVIRON callback_environ) :
|
Socket_Listener(MYSQL_SOCKET listen_socket, PTP_CALLBACK_ENVIRON callback_environ) :
|
||||||
Listener((HANDLE)listen_socket.fd,0),
|
Listener((HANDLE)listen_socket.fd,0),
|
||||||
m_client_socket(INVALID_SOCKET)
|
m_client_socket(INVALID_SOCKET),
|
||||||
|
m_listen_socket(listen_socket)
|
||||||
{
|
{
|
||||||
if (callback_environ)
|
if (callback_environ)
|
||||||
{
|
{
|
||||||
@ -184,7 +190,8 @@ struct Socket_Listener: public Listener
|
|||||||
void begin_accept()
|
void begin_accept()
|
||||||
{
|
{
|
||||||
retry :
|
retry :
|
||||||
m_client_socket= socket(server_socket_ai_family, SOCK_STREAM, IPPROTO_TCP);
|
m_client_socket= socket(m_listen_socket.address_family, SOCK_STREAM,
|
||||||
|
IPPROTO_TCP);
|
||||||
if (m_client_socket == INVALID_SOCKET)
|
if (m_client_socket == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
sql_perror("socket() call failed.");
|
sql_perror("socket() call failed.");
|
||||||
@ -233,7 +240,6 @@ retry :
|
|||||||
}
|
}
|
||||||
|
|
||||||
MYSQL_SOCKET s_client{m_client_socket};
|
MYSQL_SOCKET s_client{m_client_socket};
|
||||||
MYSQL_SOCKET s_listen{(SOCKET)m_handle};
|
|
||||||
|
|
||||||
#ifdef HAVE_PSI_SOCKET_INTERFACE
|
#ifdef HAVE_PSI_SOCKET_INTERFACE
|
||||||
/* Parse socket addresses buffer filled by AcceptEx(),
|
/* Parse socket addresses buffer filled by AcceptEx(),
|
||||||
@ -246,7 +252,8 @@ retry :
|
|||||||
&local_addr, &local_addr_len, &remote_addr, &remote_addr_len);
|
&local_addr, &local_addr_len, &remote_addr, &remote_addr_len);
|
||||||
|
|
||||||
s_client.m_psi= PSI_SOCKET_CALL(init_socket)
|
s_client.m_psi= PSI_SOCKET_CALL(init_socket)
|
||||||
(key_socket_client_connection, (const my_socket*)&s_listen.fd, remote_addr, remote_addr_len);
|
(key_socket_client_connection, (const my_socket*)&m_listen_socket.fd,
|
||||||
|
remote_addr, remote_addr_len);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Start accepting new connection. After this point, do not use
|
/* Start accepting new connection. After this point, do not use
|
||||||
@ -255,7 +262,7 @@ retry :
|
|||||||
|
|
||||||
/* Some chores post-AcceptEx() that we need to create a normal socket.*/
|
/* Some chores post-AcceptEx() that we need to create a normal socket.*/
|
||||||
if (setsockopt(s_client.fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
|
if (setsockopt(s_client.fd, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
|
||||||
(char *)&s_listen.fd, sizeof(s_listen.fd)))
|
(char *)&m_listen_socket.fd, sizeof(m_listen_socket.fd)))
|
||||||
{
|
{
|
||||||
if (!abort_loop)
|
if (!abort_loop)
|
||||||
{
|
{
|
||||||
@ -265,7 +272,7 @@ retry :
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new connection.*/
|
/* Create a new connection.*/
|
||||||
handle_accepted_socket(s_client, s_listen);
|
handle_accepted_socket(s_client, m_listen_socket);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Socket_Listener()
|
~Socket_Listener()
|
||||||
@ -280,14 +287,12 @@ retry :
|
|||||||
*/
|
*/
|
||||||
static void init_winsock_extensions()
|
static void init_winsock_extensions()
|
||||||
{
|
{
|
||||||
SOCKET s= mysql_socket_getfd(base_ip_sock);
|
if (listen_sockets.size() == 0) {
|
||||||
if (s == INVALID_SOCKET)
|
|
||||||
s= mysql_socket_getfd(extra_ip_sock);
|
|
||||||
if (s == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
/* --skip-networking was used*/
|
/* --skip-networking was used*/
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SOCKET s= mysql_socket_getfd(listen_sockets[0]);
|
||||||
GUID guid_AcceptEx= WSAID_ACCEPTEX;
|
GUID guid_AcceptEx= WSAID_ACCEPTEX;
|
||||||
GUID guid_GetAcceptExSockaddrs= WSAID_GETACCEPTEXSOCKADDRS;
|
GUID guid_GetAcceptExSockaddrs= WSAID_GETACCEPTEXSOCKADDRS;
|
||||||
|
|
||||||
@ -540,22 +545,24 @@ static void create_shutdown_event()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define MAX_WAIT_HANDLES 32
|
|
||||||
#define NUM_PIPE_LISTENERS 24
|
#define NUM_PIPE_LISTENERS 24
|
||||||
#define SHUTDOWN_IDX 0
|
#define SHUTDOWN_IDX 0
|
||||||
#define LISTENER_START_IDX 1
|
#define LISTENER_START_IDX 1
|
||||||
|
|
||||||
static Listener *all_listeners[MAX_WAIT_HANDLES];
|
static std::vector<Listener *> all_listeners;
|
||||||
static HANDLE wait_events[MAX_WAIT_HANDLES];
|
static std::vector<HANDLE> wait_events;
|
||||||
static int n_listeners;
|
|
||||||
|
|
||||||
void network_init_win()
|
void network_init_win()
|
||||||
{
|
{
|
||||||
Socket_Listener::init_winsock_extensions();
|
Socket_Listener::init_winsock_extensions();
|
||||||
|
|
||||||
/* Listen for TCP connections on "extra-port" (no threadpool).*/
|
/* Listen for TCP connections on "extra-port" (no threadpool).*/
|
||||||
if (extra_ip_sock.fd != INVALID_SOCKET)
|
for (std::vector<MYSQL_SOCKET>::iterator it= listen_sockets.begin();
|
||||||
all_listeners[n_listeners++]= new Socket_Listener(extra_ip_sock, 0);
|
it != listen_sockets.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->is_extra_port)
|
||||||
|
all_listeners.push_back(new Socket_Listener(*it, 0));
|
||||||
|
}
|
||||||
|
|
||||||
/* Listen for named pipe connections */
|
/* Listen for named pipe connections */
|
||||||
if (mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe)
|
if (mysqld_unix_port[0] && !opt_bootstrap && opt_enable_named_pipe)
|
||||||
@ -564,17 +571,22 @@ void network_init_win()
|
|||||||
Use several listeners for pipe, to reduce ERROR_PIPE_BUSY on client side.
|
Use several listeners for pipe, to reduce ERROR_PIPE_BUSY on client side.
|
||||||
*/
|
*/
|
||||||
for (int i= 0; i < NUM_PIPE_LISTENERS; i++)
|
for (int i= 0; i < NUM_PIPE_LISTENERS; i++)
|
||||||
all_listeners[n_listeners++]= new Pipe_Listener();
|
all_listeners.push_back(new Pipe_Listener());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (base_ip_sock.fd != INVALID_SOCKET)
|
for (std::vector<MYSQL_SOCKET>::iterator it= listen_sockets.begin();
|
||||||
|
it != listen_sockets.end(); ++it)
|
||||||
{
|
{
|
||||||
/* Wait for TCP connections.*/
|
if (it->is_extra_port)
|
||||||
SetFileCompletionNotificationModes((HANDLE)base_ip_sock.fd, FILE_SKIP_SET_EVENT_ON_HANDLE);
|
continue;
|
||||||
all_listeners[n_listeners++]= new Socket_Listener(base_ip_sock, get_threadpool_win_callback_environ());
|
/* Wait for TCP connections.*/
|
||||||
|
SetFileCompletionNotificationModes((HANDLE)it->fd,
|
||||||
|
FILE_SKIP_SET_EVENT_ON_HANDLE);
|
||||||
|
all_listeners.push_back(
|
||||||
|
new Socket_Listener(*it, get_threadpool_win_callback_environ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!n_listeners && !opt_bootstrap)
|
if (all_listeners.size() == 0 && !opt_bootstrap)
|
||||||
{
|
{
|
||||||
sql_print_error("Either TCP connections or named pipe connections must be enabled.");
|
sql_print_error("Either TCP connections or named pipe connections must be enabled.");
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
@ -586,26 +598,41 @@ void handle_connections_win()
|
|||||||
int n_waits;
|
int n_waits;
|
||||||
|
|
||||||
create_shutdown_event();
|
create_shutdown_event();
|
||||||
wait_events[SHUTDOWN_IDX]= hEventShutdown;
|
wait_events.push_back(hEventShutdown);
|
||||||
n_waits= 1;
|
n_waits= 1;
|
||||||
|
|
||||||
for (int i= 0; i < n_listeners; i++)
|
for (int i= 0; i < all_listeners.size(); i++)
|
||||||
{
|
{
|
||||||
HANDLE wait_handle= all_listeners[i]->wait_handle();
|
HANDLE wait_handle= all_listeners[i]->wait_handle();
|
||||||
if (wait_handle)
|
if (wait_handle)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT((i == 0) || (all_listeners[i - 1]->wait_handle() != 0));
|
DBUG_ASSERT((i == 0) || (all_listeners[i - 1]->wait_handle() != 0));
|
||||||
wait_events[n_waits++]= wait_handle;
|
wait_events.push_back(wait_handle);
|
||||||
}
|
}
|
||||||
all_listeners[i]->begin_accept();
|
all_listeners[i]->begin_accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
mysqld_win_set_startup_complete();
|
mysqld_win_set_startup_complete();
|
||||||
|
|
||||||
|
// WaitForMultipleObjects can't wait on more than MAXIMUM_WAIT_OBJECTS
|
||||||
|
// handles simultaneously. Since MAXIMUM_WAIT_OBJECTS is only 64, there is
|
||||||
|
// a theoretical possiblity of exceeding that limit on installations where
|
||||||
|
// host name resolves to a lot of addresses.
|
||||||
|
if (wait_events.size() > MAXIMUM_WAIT_OBJECTS)
|
||||||
|
{
|
||||||
|
sql_print_warning(
|
||||||
|
"Too many wait events (%lu). Some connection listeners won't be handled. "
|
||||||
|
"Try to switch \"thread-handling\" to \"pool-of-threads\" and/or disable "
|
||||||
|
"\"extra-port\".", static_cast<ulong>(wait_events.size()));
|
||||||
|
wait_events.resize(MAXIMUM_WAIT_OBJECTS);
|
||||||
|
}
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
DWORD idx = WaitForMultipleObjects(n_waits ,wait_events, FALSE, INFINITE);
|
DBUG_ASSERT(wait_events.size() <= MAXIMUM_WAIT_OBJECTS);
|
||||||
DBUG_ASSERT((int)idx >= 0 && (int)idx < n_waits);
|
DWORD idx = WaitForMultipleObjects((DWORD)wait_events.size(),
|
||||||
|
wait_events.data(), FALSE, INFINITE);
|
||||||
|
DBUG_ASSERT((int)idx >= 0 && (int)idx < (int)wait_events.size());
|
||||||
|
|
||||||
if (idx == SHUTDOWN_IDX)
|
if (idx == SHUTDOWN_IDX)
|
||||||
break;
|
break;
|
||||||
@ -616,7 +643,7 @@ void handle_connections_win()
|
|||||||
mysqld_win_initiate_shutdown();
|
mysqld_win_initiate_shutdown();
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
for (int i= 0; i < n_listeners; i++)
|
for (size_t i= 0; i < all_listeners.size(); i++)
|
||||||
{
|
{
|
||||||
Listener *listener= all_listeners[i];
|
Listener *listener= all_listeners[i];
|
||||||
if (listener->wait_handle())
|
if (listener->wait_handle())
|
||||||
|
304
sql/mysqld.cc
304
sql/mysqld.cc
@ -338,7 +338,6 @@ static char *character_set_filesystem_name;
|
|||||||
static char *lc_messages;
|
static char *lc_messages;
|
||||||
static char *lc_time_names_name;
|
static char *lc_time_names_name;
|
||||||
char *my_bind_addr_str;
|
char *my_bind_addr_str;
|
||||||
int server_socket_ai_family;
|
|
||||||
static char *default_collation_name;
|
static char *default_collation_name;
|
||||||
char *default_storage_engine, *default_tmp_storage_engine;
|
char *default_storage_engine, *default_tmp_storage_engine;
|
||||||
char *enforced_storage_engine=NULL;
|
char *enforced_storage_engine=NULL;
|
||||||
@ -1349,7 +1348,8 @@ static Buffered_logs buffered_logs;
|
|||||||
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
struct my_rnd_struct sql_rand; ///< used by sql_class.cc:THD::THD()
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
#ifndef EMBEDDED_LIBRARY
|
||||||
MYSQL_SOCKET unix_sock, base_ip_sock, extra_ip_sock;
|
std::vector<MYSQL_SOCKET> listen_sockets;
|
||||||
|
bool unix_sock_is_online= false;
|
||||||
/**
|
/**
|
||||||
Error reporter that buffer log messages.
|
Error reporter that buffer log messages.
|
||||||
@param level log message level
|
@param level log message level
|
||||||
@ -1690,28 +1690,15 @@ static void close_connections(void)
|
|||||||
|
|
||||||
/* Abort listening to new connections */
|
/* Abort listening to new connections */
|
||||||
DBUG_PRINT("quit",("Closing sockets"));
|
DBUG_PRINT("quit",("Closing sockets"));
|
||||||
if (!opt_disable_networking )
|
for (std::vector<MYSQL_SOCKET>::iterator sock = listen_sockets.begin();
|
||||||
|
sock != listen_sockets.end(); ++sock)
|
||||||
{
|
{
|
||||||
if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
|
(void) mysql_socket_close(*sock);
|
||||||
{
|
if (sock->is_unix_domain_socket)
|
||||||
(void) mysql_socket_close(base_ip_sock);
|
(void) unlink(mysqld_unix_port);
|
||||||
base_ip_sock= MYSQL_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
(void) mysql_socket_close(extra_ip_sock);
|
|
||||||
extra_ip_sock= MYSQL_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
listen_sockets.clear();
|
||||||
|
|
||||||
#ifdef HAVE_SYS_UN_H
|
|
||||||
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
(void) mysql_socket_close(unix_sock);
|
|
||||||
(void) unlink(mysqld_unix_port);
|
|
||||||
unix_sock= MYSQL_INVALID_SOCKET;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
end_thr_alarm(0); // Abort old alarms.
|
end_thr_alarm(0); // Abort old alarms.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1800,13 +1787,20 @@ static void close_server_sock()
|
|||||||
#ifdef HAVE_CLOSE_SERVER_SOCK
|
#ifdef HAVE_CLOSE_SERVER_SOCK
|
||||||
DBUG_ENTER("close_server_sock");
|
DBUG_ENTER("close_server_sock");
|
||||||
|
|
||||||
close_socket(base_ip_sock, "TCP/IP");
|
for (std::vector<MYSQL_SOCKET>::iterator sock= listen_sockets.begin();
|
||||||
close_socket(extra_ip_sock, "TCP/IP");
|
sock != listen_sockets.end(); ++sock)
|
||||||
close_socket(unix_sock, "unix/IP");
|
{
|
||||||
|
if (sock->is_unix_domain_socket)
|
||||||
if (mysql_socket_getfd(unix_sock) != INVALID_SOCKET)
|
{
|
||||||
(void) unlink(mysqld_unix_port);
|
close_socket(*sock, "unix/IP");
|
||||||
base_ip_sock= extra_ip_sock= unix_sock= MYSQL_INVALID_SOCKET;
|
(void) unlink(mysqld_unix_port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close_socket(*sock, "TCP/IP");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listen_sockets.clear();
|
||||||
|
|
||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
#endif
|
#endif
|
||||||
@ -2241,7 +2235,9 @@ static void set_root(const char *path)
|
|||||||
Activate usage of a tcp port
|
Activate usage of a tcp port
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static MYSQL_SOCKET activate_tcp_port(uint port)
|
static void activate_tcp_port(uint port,
|
||||||
|
std::vector<MYSQL_SOCKET> *listen_sockets,
|
||||||
|
bool is_extra_port= false)
|
||||||
{
|
{
|
||||||
struct addrinfo *ai, *a;
|
struct addrinfo *ai, *a;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
@ -2273,20 +2269,6 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
|
|||||||
unireg_abort(1); /* purecov: tested */
|
unireg_abort(1); /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
special case: for wildcard addresses prefer ipv6 over ipv4,
|
|
||||||
because we later switch off IPV6_V6ONLY, so ipv6 wildcard
|
|
||||||
addresses will work for ipv4 too
|
|
||||||
*/
|
|
||||||
if (!real_bind_addr_str && ai->ai_family == AF_INET && ai->ai_next
|
|
||||||
&& ai->ai_next->ai_family == AF_INET6)
|
|
||||||
{
|
|
||||||
a= ai;
|
|
||||||
ai= ai->ai_next;
|
|
||||||
a->ai_next= ai->ai_next;
|
|
||||||
ai->ai_next= a;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (a= ai; a != NULL; a= a->ai_next)
|
for (a= ai; a != NULL; a= a->ai_next)
|
||||||
{
|
{
|
||||||
ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
|
ip_sock= mysql_socket_socket(key_socket_tcpip, a->ai_family,
|
||||||
@ -2309,99 +2291,98 @@ static MYSQL_SOCKET activate_tcp_port(uint port)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
server_socket_ai_family= a->ai_family;
|
ip_sock.address_family= a->ai_family;
|
||||||
sql_print_information("Server socket created on IP: '%s'.",
|
sql_print_information("Server socket created on IP: '%s'.",
|
||||||
(const char *) ip_addr);
|
(const char *) ip_addr);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
|
if (mysql_socket_getfd(ip_sock) == INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
|
DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
|
||||||
sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
|
sql_perror(ER_DEFAULT(ER_IPSOCK_ERROR)); /* purecov: tested */
|
||||||
unireg_abort(1); /* purecov: tested */
|
unireg_abort(1); /* purecov: tested */
|
||||||
}
|
}
|
||||||
|
|
||||||
mysql_socket_set_thread_owner(ip_sock);
|
mysql_socket_set_thread_owner(ip_sock);
|
||||||
|
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
/*
|
/*
|
||||||
We should not use SO_REUSEADDR on windows as this would enable a
|
We should not use SO_REUSEADDR on windows as this would enable a
|
||||||
user to open two mysqld servers with the same TCP/IP port.
|
user to open two mysqld servers with the same TCP/IP port.
|
||||||
*/
|
*/
|
||||||
arg= 1;
|
arg= 1;
|
||||||
(void) mysql_socket_setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
|
(void) mysql_socket_setsockopt(ip_sock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
sizeof(arg));
|
(char*)&arg, sizeof(arg));
|
||||||
#endif /* __WIN__ */
|
#endif /* __WIN__ */
|
||||||
|
|
||||||
#ifdef IPV6_V6ONLY
|
#ifdef IPV6_V6ONLY
|
||||||
/*
|
/*
|
||||||
For interoperability with older clients, IPv6 socket should
|
If an address name resolves to both IPv4 and IPv6 addresses, the server
|
||||||
listen on both IPv6 and IPv4 wildcard addresses.
|
will listen on them both. With IPV6_V6ONLY unset, listening on an IPv6
|
||||||
Turn off IPV6_V6ONLY option.
|
wildcard address may cause listening on an IPv4 wildcard address
|
||||||
|
to fail. That's why IPV6_V6ONLY needs to be forcefully turned on.
|
||||||
NOTE: this will work starting from Windows Vista only.
|
*/
|
||||||
On Windows XP dual stack is not available, so it will not
|
if (a->ai_family == AF_INET6)
|
||||||
listen on the corresponding IPv4-address.
|
{
|
||||||
*/
|
arg= 1;
|
||||||
if (a->ai_family == AF_INET6)
|
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||||
{
|
(char*)&arg, sizeof(arg));
|
||||||
arg= 0;
|
}
|
||||||
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IPV6, IPV6_V6ONLY,
|
|
||||||
(char*)&arg, sizeof(arg));
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef IP_FREEBIND
|
#ifdef IP_FREEBIND
|
||||||
arg= 1;
|
arg= 1;
|
||||||
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND, (char*) &arg,
|
(void) mysql_socket_setsockopt(ip_sock, IPPROTO_IP, IP_FREEBIND,
|
||||||
sizeof(arg));
|
(char*) &arg, sizeof(arg));
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
Sometimes the port is not released fast enough when stopping and
|
Sometimes the port is not released fast enough when stopping and
|
||||||
restarting the server. This happens quite often with the test suite
|
restarting the server. This happens quite often with the test suite
|
||||||
on busy Linux systems. Retry to bind the address at these intervals:
|
on busy Linux systems. Retry to bind the address at these intervals:
|
||||||
Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
|
Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
|
||||||
Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
|
Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
|
||||||
Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
|
Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
|
||||||
*/
|
*/
|
||||||
int ret;
|
int ret;
|
||||||
uint waited, retry, this_wait;
|
uint waited, retry, this_wait;
|
||||||
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
|
for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
|
||||||
{
|
{
|
||||||
if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 ) ||
|
if (((ret= mysql_socket_bind(ip_sock, a->ai_addr, a->ai_addrlen)) >= 0 )
|
||||||
(socket_errno != SOCKET_EADDRINUSE) ||
|
|| (socket_errno != SOCKET_EADDRINUSE)
|
||||||
(waited >= mysqld_port_timeout))
|
|| (waited >= mysqld_port_timeout))
|
||||||
break;
|
break;
|
||||||
sql_print_information("Retrying bind on TCP/IP port %u", port);
|
sql_print_information("Retrying bind on TCP/IP port %u", port);
|
||||||
this_wait= retry * retry / 3 + 1;
|
this_wait= retry * retry / 3 + 1;
|
||||||
sleep(this_wait);
|
sleep(this_wait);
|
||||||
}
|
}
|
||||||
freeaddrinfo(ai);
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
char buff[100];
|
char buff[100];
|
||||||
sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
|
sprintf(buff, "Can't start server: Bind on TCP/IP port. Got error: %d",
|
||||||
(int) socket_errno);
|
(int) socket_errno);
|
||||||
sql_perror(buff);
|
sql_perror(buff);
|
||||||
sql_print_error("Do you already have another mysqld server running on "
|
sql_print_error("Do you already have another mysqld server running on "
|
||||||
"port: %u ?", port);
|
"port: %u ?", port);
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
}
|
}
|
||||||
if (mysql_socket_listen(ip_sock,(int) back_log) < 0)
|
if (mysql_socket_listen(ip_sock,(int) back_log) < 0)
|
||||||
{
|
{
|
||||||
sql_perror("Can't start server: listen() on TCP/IP port");
|
sql_perror("Can't start server: listen() on TCP/IP port");
|
||||||
sql_print_error("listen() on TCP/IP failed with error %d",
|
sql_print_error("listen() on TCP/IP failed with error %d",
|
||||||
socket_errno);
|
socket_errno);
|
||||||
unireg_abort(1);
|
unireg_abort(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
(void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
|
(void) fcntl(mysql_socket_getfd(ip_sock), F_SETFD, FD_CLOEXEC);
|
||||||
#endif
|
#endif
|
||||||
|
ip_sock.is_extra_port= is_extra_port;
|
||||||
|
listen_sockets->push_back(ip_sock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DBUG_RETURN(ip_sock);
|
freeaddrinfo(ai);
|
||||||
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void network_init(void)
|
static void network_init(void)
|
||||||
@ -2431,9 +2412,11 @@ static void network_init(void)
|
|||||||
if (!opt_disable_networking && !opt_bootstrap)
|
if (!opt_disable_networking && !opt_bootstrap)
|
||||||
{
|
{
|
||||||
if (mysqld_port)
|
if (mysqld_port)
|
||||||
base_ip_sock= activate_tcp_port(mysqld_port);
|
activate_tcp_port(mysqld_port, &listen_sockets,
|
||||||
|
/* is_extra_port= */ false);
|
||||||
if (mysqld_extra_port)
|
if (mysqld_extra_port)
|
||||||
extra_ip_sock= activate_tcp_port(mysqld_extra_port);
|
activate_tcp_port(mysqld_extra_port, &listen_sockets,
|
||||||
|
/* is_extra_port= */ true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SYS_UN_H)
|
#if defined(HAVE_SYS_UN_H)
|
||||||
@ -2442,6 +2425,7 @@ static void network_init(void)
|
|||||||
*/
|
*/
|
||||||
if (mysqld_unix_port[0] && !opt_bootstrap)
|
if (mysqld_unix_port[0] && !opt_bootstrap)
|
||||||
{
|
{
|
||||||
|
MYSQL_SOCKET unix_sock= MYSQL_INVALID_SOCKET;
|
||||||
size_t port_len;
|
size_t port_len;
|
||||||
DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
|
DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
|
||||||
|
|
||||||
@ -2458,6 +2442,9 @@ static void network_init(void)
|
|||||||
unireg_abort(1); /* purecov: inspected */
|
unireg_abort(1); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unix_sock.is_unix_domain_socket= true;
|
||||||
|
listen_sockets.push_back(unix_sock);
|
||||||
|
unix_sock_is_online= true;
|
||||||
mysql_socket_set_thread_owner(unix_sock);
|
mysql_socket_set_thread_owner(unix_sock);
|
||||||
|
|
||||||
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
|
bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
|
||||||
@ -5645,8 +5632,7 @@ int mysqld_main(int argc, char **argv)
|
|||||||
|
|
||||||
if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
|
if (IS_SYSVAR_AUTOSIZE(&server_version_ptr))
|
||||||
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname, server_version,
|
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname, server_version,
|
||||||
((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
|
(unix_sock_is_online ? mysqld_unix_port : (char*) ""),
|
||||||
(char*) "" : mysqld_unix_port),
|
|
||||||
mysqld_port, MYSQL_COMPILATION_COMMENT);
|
mysqld_port, MYSQL_COMPILATION_COMMENT);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -5658,8 +5644,7 @@ int mysqld_main(int argc, char **argv)
|
|||||||
|
|
||||||
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname,
|
sql_print_information(ER_DEFAULT(ER_STARTUP), my_progname,
|
||||||
real_server_version,
|
real_server_version,
|
||||||
((mysql_socket_getfd(unix_sock) == INVALID_SOCKET) ?
|
(unix_sock_is_online ? mysqld_unix_port : (char*) ""),
|
||||||
(char*) "" : mysqld_unix_port),
|
|
||||||
mysqld_port, MYSQL_COMPILATION_COMMENT);
|
mysqld_port, MYSQL_COMPILATION_COMMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5866,8 +5851,7 @@ void handle_accepted_socket(MYSQL_SOCKET new_sock, MYSQL_SOCKET sock)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_LIBWRAP
|
#ifdef HAVE_LIBWRAP
|
||||||
{
|
{
|
||||||
if (mysql_socket_getfd(sock) == mysql_socket_getfd(base_ip_sock) ||
|
if (!sock.is_unix_domain_socket)
|
||||||
mysql_socket_getfd(sock) == mysql_socket_getfd(extra_ip_sock))
|
|
||||||
{
|
{
|
||||||
struct request_info req;
|
struct request_info req;
|
||||||
signal(SIGCHLD, SIG_DFL);
|
signal(SIGCHLD, SIG_DFL);
|
||||||
@ -5910,11 +5894,9 @@ void handle_accepted_socket(MYSQL_SOCKET new_sock, MYSQL_SOCKET sock)
|
|||||||
DBUG_PRINT("info", ("Creating CONNECT for new connection"));
|
DBUG_PRINT("info", ("Creating CONNECT for new connection"));
|
||||||
|
|
||||||
if (auto connect= new CONNECT(new_sock,
|
if (auto connect= new CONNECT(new_sock,
|
||||||
mysql_socket_getfd(sock) ==
|
sock.is_unix_domain_socket ?
|
||||||
mysql_socket_getfd(unix_sock) ?
|
|
||||||
VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
|
VIO_TYPE_SOCKET : VIO_TYPE_TCPIP,
|
||||||
mysql_socket_getfd(sock) ==
|
sock.is_extra_port ?
|
||||||
mysql_socket_getfd(extra_ip_sock) ?
|
|
||||||
extra_thread_scheduler : thread_scheduler))
|
extra_thread_scheduler : thread_scheduler))
|
||||||
create_new_thread(connect);
|
create_new_thread(connect);
|
||||||
else
|
else
|
||||||
@ -5950,36 +5932,30 @@ void handle_connections_sockets()
|
|||||||
struct sockaddr_storage cAddr;
|
struct sockaddr_storage cAddr;
|
||||||
int retval;
|
int retval;
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
int socket_count= 0;
|
std::vector<struct pollfd> fds; // for ip_sock, unix_sock and extra_ip_sock
|
||||||
struct pollfd fds[3]; // for ip_sock, unix_sock and extra_ip_sock
|
|
||||||
MYSQL_SOCKET pfs_fds[3]; // for performance schema
|
|
||||||
#define setup_fds(X) \
|
|
||||||
mysql_socket_set_thread_owner(X); \
|
|
||||||
pfs_fds[socket_count]= (X); \
|
|
||||||
fds[socket_count].fd= mysql_socket_getfd(X); \
|
|
||||||
fds[socket_count].events= POLLIN; \
|
|
||||||
socket_count++
|
|
||||||
#else
|
#else
|
||||||
#define setup_fds(X) FD_SET(mysql_socket_getfd(X),&clientFDs)
|
|
||||||
fd_set readFDs,clientFDs;
|
fd_set readFDs,clientFDs;
|
||||||
FD_ZERO(&clientFDs);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DBUG_ENTER("handle_connections_sockets");
|
DBUG_ENTER("handle_connections_sockets");
|
||||||
|
|
||||||
if (mysql_socket_getfd(base_ip_sock) != INVALID_SOCKET)
|
#ifdef HAVE_POLL
|
||||||
|
fds.resize(listen_sockets.size());
|
||||||
|
for (size_t i= 0; i < listen_sockets.size(); i++)
|
||||||
{
|
{
|
||||||
setup_fds(base_ip_sock);
|
mysql_socket_set_thread_owner(listen_sockets[i]);
|
||||||
set_non_blocking_if_supported(base_ip_sock);
|
fds[i].fd= mysql_socket_getfd(listen_sockets[i]);
|
||||||
|
fds[i].events= POLLIN;
|
||||||
|
set_non_blocking_if_supported(listen_sockets[i]);
|
||||||
}
|
}
|
||||||
if (mysql_socket_getfd(extra_ip_sock) != INVALID_SOCKET)
|
#else
|
||||||
|
FD_ZERO(&clientFDs);
|
||||||
|
for (size_t i= 0; i < listen_sockets.size(); i++)
|
||||||
{
|
{
|
||||||
setup_fds(extra_ip_sock);
|
int fd= mysql_socket_getfd(listen_sockets[i]);
|
||||||
set_non_blocking_if_supported(extra_ip_sock);
|
FD_SET(fd, &clientFDs);
|
||||||
|
set_non_blocking_if_supported(listen_sockets[i]);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_SYS_UN_H
|
|
||||||
setup_fds(unix_sock);
|
|
||||||
set_non_blocking_if_supported(unix_sock);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sd_notify(0, "READY=1\n"
|
sd_notify(0, "READY=1\n"
|
||||||
@ -5989,10 +5965,10 @@ void handle_connections_sockets()
|
|||||||
while (!abort_loop)
|
while (!abort_loop)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
retval= poll(fds, socket_count, -1);
|
retval= poll(fds.data(), fds.size(), -1);
|
||||||
#else
|
#else
|
||||||
readFDs=clientFDs;
|
readFDs=clientFDs;
|
||||||
retval= select((int) 0,&readFDs,0,0,0);
|
retval= select(FD_SETSIZE, &readFDs, NULL, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
@ -6016,22 +5992,23 @@ void handle_connections_sockets()
|
|||||||
|
|
||||||
/* Is this a new connection request ? */
|
/* Is this a new connection request ? */
|
||||||
#ifdef HAVE_POLL
|
#ifdef HAVE_POLL
|
||||||
for (int i= 0; i < socket_count; ++i)
|
for (size_t i= 0; i < fds.size(); ++i)
|
||||||
{
|
{
|
||||||
if (fds[i].revents & POLLIN)
|
if (fds[i].revents & POLLIN)
|
||||||
{
|
{
|
||||||
sock= pfs_fds[i];
|
sock= listen_sockets[i];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else // HAVE_POLL
|
#else // HAVE_POLL
|
||||||
if (FD_ISSET(mysql_socket_getfd(base_ip_sock),&readFDs))
|
for (size_t i=0; i < listen_sockets.size(); i++)
|
||||||
sock= base_ip_sock;
|
{
|
||||||
else
|
if (FD_ISSET(mysql_socket_getfd(listen_sockets[i]), &readFDs))
|
||||||
if (FD_ISSET(mysql_socket_getfd(extra_ip_sock),&readFDs))
|
{
|
||||||
sock= extra_ip_sock;
|
sock= listen_sockets[i];
|
||||||
else
|
break;
|
||||||
sock = unix_sock;
|
}
|
||||||
|
}
|
||||||
#endif // HAVE_POLL
|
#endif // HAVE_POLL
|
||||||
|
|
||||||
for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
|
for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
|
||||||
@ -7514,9 +7491,6 @@ static int mysql_init_variables(void)
|
|||||||
character_set_filesystem= &my_charset_bin;
|
character_set_filesystem= &my_charset_bin;
|
||||||
|
|
||||||
opt_specialflag= SPECIAL_ENGLISH;
|
opt_specialflag= SPECIAL_ENGLISH;
|
||||||
#ifndef EMBEDDED_LIBRARY
|
|
||||||
unix_sock= base_ip_sock= extra_ip_sock= MYSQL_INVALID_SOCKET;
|
|
||||||
#endif
|
|
||||||
mysql_home_ptr= mysql_home;
|
mysql_home_ptr= mysql_home;
|
||||||
log_error_file_ptr= log_error_file;
|
log_error_file_ptr= log_error_file;
|
||||||
protocol_version= PROTOCOL_VERSION;
|
protocol_version= PROTOCOL_VERSION;
|
||||||
|
@ -147,7 +147,6 @@ extern ulong opt_replicate_events_marked_for_skip;
|
|||||||
extern char *default_tz_name;
|
extern char *default_tz_name;
|
||||||
extern Time_zone *default_tz;
|
extern Time_zone *default_tz;
|
||||||
extern char *my_bind_addr_str;
|
extern char *my_bind_addr_str;
|
||||||
extern int server_socket_ai_family;
|
|
||||||
extern char *default_storage_engine, *default_tmp_storage_engine;
|
extern char *default_storage_engine, *default_tmp_storage_engine;
|
||||||
extern char *enforced_storage_engine;
|
extern char *enforced_storage_engine;
|
||||||
extern char *gtid_pos_auto_engines;
|
extern char *gtid_pos_auto_engines;
|
||||||
|
Reference in New Issue
Block a user