1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Fixed assert in perfschema/pfs.cc::start_idle_wait_v1 when using performance schema and big packets in debug version.

The bug was that my_real_read() called net_before_header_psi() multiple times for long packets.
Fixed by adding a flag when we are reading a header.
Did also some cleanups to interface of my_net_read() to avoid unnecessary calls if performance schema is not used.

- Added my_net_read_packet() as a replacement for my_net_read(). my_net_read() is still in the client library for old clients.
- Removed THD->m_server_idle (not needed anymore as this is now given as argument to my_net_read_packet()
- Added my_net_read_packet(), which is a new version of my_net_read() with a new parameter if we are doing a read for a new command from the server.
- Added tests for compressed protocol and big packets





include/mysql.h.pp:
  Added my_net_read_packet() as a replacement for my_net_read()
include/mysql_com.h:
  Added my_net_read_packet() as a replacement for my_net_read()
mysql-test/r/mysql_client_test_comp.result:
  New test
mysql-test/t/mysql_client_test-master.opt:
  Added max_allowed_packet to be able to test big packets and packet size overflows.
mysql-test/t/mysql_client_test_comp-master.opt:
  New test
mysql-test/t/mysql_client_test_nonblock-master.opt:
  Added max_allowed_packet to be able to test big packets and packet size overflows.
sql-common/client.c:
  Use my_net_read_packet()
sql/mf_iocache.cc:
  Use my_net_read_packet()
sql/mysqld.cc:
  Removed THD->m_server_idle (not needed anymore as this is now given as argument to my_net_read_packet()
sql/net_serv.cc:
  Added argument to my_real_read() to indicte if we are reading the first block of the next statement and should call performance schema.
  Added 'compatibilty function' my_net_read().
  Added my_net_read_packet(), which is a new version of my_net_read() with a new parameter if we are doing a read for a new command from the server.
sql/sql_class.cc:
  Removed m_server_idle (not needed anymore)
sql/sql_class.h:
  Removed m_server_idle (not needed anymore)
sql/sql_parse.cc:
  Removed m_server_idle (not needed anymore)
tests/mysql_client_test.c:
  Added tests for compressed protocol and big packets
This commit is contained in:
Michael Widenius
2014-07-19 13:38:40 +03:00
parent 54538b481d
commit ff205b25d5
15 changed files with 210 additions and 70 deletions

View File

@@ -1115,65 +1115,60 @@ void net_before_header_psi(struct st_net *net, void *user_data, size_t /* unused
thd= static_cast<THD*> (user_data);
DBUG_ASSERT(thd != NULL);
if (thd->m_server_idle)
{
/*
The server is IDLE, waiting for the next command.
Technically, it is a wait on a socket, which may take a long time,
because the call is blocking.
Disable the socket instrumentation, to avoid recording a SOCKET event.
Instead, start explicitly an IDLE event.
*/
MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_IDLE);
MYSQL_START_IDLE_WAIT(thd->m_idle_psi, &thd->m_idle_state);
}
/*
We only come where when the server is IDLE, waiting for the next command.
Technically, it is a wait on a socket, which may take a long time,
because the call is blocking.
Disable the socket instrumentation, to avoid recording a SOCKET event.
Instead, start explicitly an IDLE event.
*/
MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_IDLE);
MYSQL_START_IDLE_WAIT(thd->m_idle_psi, &thd->m_idle_state);
}
void net_after_header_psi(struct st_net *net, void *user_data, size_t /* unused: count */, my_bool rc)
void net_after_header_psi(struct st_net *net, void *user_data,
size_t /* unused: count */, my_bool rc)
{
THD *thd;
thd= static_cast<THD*> (user_data);
DBUG_ASSERT(thd != NULL);
if (thd->m_server_idle)
/*
The server just got data for a network packet header,
from the network layer.
The IDLE event is now complete, since we now have a message to process.
We need to:
- start a new STATEMENT event
- start a new STAGE event, within this statement,
- start recording SOCKET WAITS events, within this stage.
The proper order is critical to get events numbered correctly,
and nested in the proper parent.
*/
MYSQL_END_IDLE_WAIT(thd->m_idle_psi);
if (! rc)
{
/*
The server just got data for a network packet header,
from the network layer.
The IDLE event is now complete, since we now have a message to process.
We need to:
- start a new STATEMENT event
- start a new STAGE event, within this statement,
- start recording SOCKET WAITS events, within this stage.
The proper order is critical to get events numbered correctly,
and nested in the proper parent.
*/
MYSQL_END_IDLE_WAIT(thd->m_idle_psi);
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
stmt_info_new_packet.m_key,
thd->db, thd->db_length,
thd->charset());
if (! rc)
{
thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
stmt_info_new_packet.m_key,
thd->db, thd->db_length,
thd->charset());
THD_STAGE_INFO(thd, stage_init);
}
/*
TODO: consider recording a SOCKET event for the bytes just read,
by also passing count here.
*/
MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_ACTIVE);
THD_STAGE_INFO(thd, stage_init);
}
/*
TODO: consider recording a SOCKET event for the bytes just read,
by also passing count here.
*/
MYSQL_SOCKET_SET_STATE(net->vio->mysql_socket, PSI_SOCKET_STATE_ACTIVE);
}
void init_net_server_extension(THD *thd)
{
/* Start with a clean state for connection events. */
thd->m_idle_psi= NULL;
thd->m_statement_psi= NULL;
thd->m_server_idle= false;
/* Hook up the NET_SERVER callback in the net layer. */
thd->m_net_server_extension.m_user_data= thd;
thd->m_net_server_extension.m_before_header= net_before_header_psi;