Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion include/mysql_com_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ typedef struct NET_SERVER {
struct compression_attributes compression;
mysql_compress_context compress_ctx;
bool timeout_on_full_packet;

/** Number of consecutive requests to shrink NET::buff. */
unsigned int shrink_requests;
} NET_SERVER;

inline void net_server_ext_init(NET_SERVER *ns) {
Expand All @@ -71,6 +74,7 @@ inline void net_server_ext_init(NET_SERVER *ns) {
ns->m_after_header = nullptr;
ns->compress_ctx.algorithm = MYSQL_UNCOMPRESSED;
ns->timeout_on_full_packet = false;
ns->shrink_requests = 0;
}

bool net_shrink(struct NET *net, size_t length);
#endif
8 changes: 4 additions & 4 deletions mysql-test/r/all_persisted_variables.result
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,17 @@ include/assert.inc [Expect 500+ variables in the table. Due to open Bugs, we are

# Test SET PERSIST

include/assert.inc [Expect 451 persisted variables in the table.]
include/assert.inc [Expect 452 persisted variables in the table.]

************************************************************
* 3. Restart server, it must preserve the persisted variable
* settings. Verify persisted configuration.
************************************************************
# restart

include/assert.inc [Expect 451 persisted variables in persisted_variables table.]
include/assert.inc [Expect 451 persisted variables shown as PERSISTED in variables_info table.]
include/assert.inc [Expect 451 persisted variables with matching peristed and global values.]
include/assert.inc [Expect 452 persisted variables in persisted_variables table.]
include/assert.inc [Expect 452 persisted variables shown as PERSISTED in variables_info table.]
include/assert.inc [Expect 452 persisted variables with matching peristed and global values.]

************************************************************
* 4. Test RESET PERSIST IF EXISTS. Verify persisted variable
Expand Down
7 changes: 7 additions & 0 deletions mysql-test/r/mysqld--help-notwin.result
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,12 @@ The following options may be given as the first argument:
--myisam-use-mmap Use memory mapping for reading and writing MyISAM tables
--net-buffer-length=#
Buffer length for TCP/IP and socket communication
--net-buffer-shrink-threshold=#
If the size currently required for net buffer is less
than half of the allocated size, a shrink is requested.
Once the number of consecutive requests reaches this
threshold, the buffer is halved, but never below
net_buffer_length. A value of 0 disables shrink
--net-read-timeout=#
Number of seconds to wait for more data from a connection
before aborting the read
Expand Down Expand Up @@ -1867,6 +1873,7 @@ myisam-sort-buffer-size 8388608
myisam-stats-method nulls_unequal
myisam-use-mmap FALSE
net-buffer-length 16384
net-buffer-shrink-threshold 5
net-read-timeout 30
net-retry-count 10
net-write-timeout 60
Expand Down
36 changes: 36 additions & 0 deletions mysql-test/r/shrink_net_buffer.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
SHOW VARIABLES LIKE 'net_buffer_length';
Variable_name Value
net_buffer_length 16384
CREATE USER 'shrink_test_user'@'localhost';
SET GLOBAL net_buffer_shrink_threshold = 5;
[connection con1]
[connection default]
"NET::buff after a large query; capacity should have grown."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 36864
[connection con1]
[connection default]
"NET::buff after four small queries; capacity should not be shrunk."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 36864
[connection con1]
[connection default]
"NET::buff after five small queries; capacity should be about half."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 20480
[connection con1]
[connection default]
"NET::buff after ten small queries; capacity should reach its minimum."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 16384
[connection con1]
[connection default]
"NET::buff remains at its minimum after five more small queries."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 16384
[connection con1]
[connection default]
"NET::buff after another large query; capacity should grow again."
CURRENT_ALLOCATIONS CURRENT_NUMBER_OF_BYTES_USED - 39
1 36864
DROP USER 'shrink_test_user'@'localhost';
6 changes: 6 additions & 0 deletions mysql-test/r/variables.result
Original file line number Diff line number Diff line change
Expand Up @@ -245,24 +245,28 @@ set global net_buffer_length=1024, net_write_timeout=200, net_read_timeout=300;
show global variables like 'net_%';
Variable_name Value
net_buffer_length 1024
net_buffer_shrink_threshold 5
net_read_timeout 300
net_retry_count 10
net_write_timeout 200
select * from performance_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
net_buffer_length 1024
net_buffer_shrink_threshold 5
net_read_timeout 300
net_retry_count 10
net_write_timeout 200
show session variables like 'net_%';
Variable_name Value
net_buffer_length 16384
net_buffer_shrink_threshold 5
net_read_timeout 30
net_retry_count 10
net_write_timeout 60
select * from performance_schema.session_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
net_buffer_length 16384
net_buffer_shrink_threshold 5
net_read_timeout 30
net_retry_count 10
net_write_timeout 60
Expand All @@ -272,12 +276,14 @@ Warning 1292 Truncated incorrect net_buffer_length value: '8000'
show global variables like 'net_%';
Variable_name Value
net_buffer_length 7168
net_buffer_shrink_threshold 5
net_read_timeout 900
net_retry_count 10
net_write_timeout 1000
select * from performance_schema.global_variables where variable_name like 'net_%' order by 1;
VARIABLE_NAME VARIABLE_VALUE
net_buffer_length 7168
net_buffer_shrink_threshold 5
net_read_timeout 900
net_retry_count 10
net_write_timeout 1000
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/suite/sys_vars/r/all_vars.result
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ master_verify_checksum
master_verify_checksum
max_length_for_sort_data
max_length_for_sort_data
net_buffer_shrink_threshold
net_buffer_shrink_threshold
optimizer_max_subgraph_pairs
optimizer_max_subgraph_pairs
partial_revokes
Expand Down
2 changes: 1 addition & 1 deletion mysql-test/t/all_persisted_variables.test
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ let $total_global_vars=`SELECT COUNT(*)
AND variable_name NOT LIKE '%pqc%'
AND variable_name NOT LIKE '%tls_kex%'`;

let $total_persistent_vars=451;
let $total_persistent_vars=452;

--echo ***************************************************************
--echo * 0. Verify that variables present in performance_schema.global
Expand Down
173 changes: 173 additions & 0 deletions mysql-test/t/shrink_net_buffer.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
# Test NET::buff shrinking for classic protocol connections.
#
# The test verifies that:
# 1. A query larger than net_buffer_length grows NET::buff.
# 2. Five consecutive small queries shrink the buffer by approximately half.
# 3. Further small queries shrink it to, but never below, net_buffer_length.
# 4. A later large query can grow the buffer again after it was shrunk.
#
# Expected result: PFS allocation statistics show grow, gradual shrink, a
# stable lower bound, and successful regrowth in that order.

--source include/have_nodebug.inc

# =============================================================================
# Prerequisites
# =============================================================================

if (`SELECT @@GLOBAL.performance_schema = FALSE`) {
skip Test requires @@GLOBAL.performance_schema = TRUE.;
}

let $instrument = `SELECT ENABLED FROM performance_schema.setup_instruments
WHERE NAME = 'memory/sql/NET::buff'`;
if ($instrument != YES) {
skip Test requires memory/sql/NET::buff instrumentation.;
}

# =============================================================================
# Setup
# =============================================================================

let $old_net_buffer_shrink_threshold = query_get_value(
SHOW VARIABLES LIKE "net_buffer_shrink_threshold", Value, 1);
SHOW VARIABLES LIKE 'net_buffer_length';

# Generate padding for a query larger than net_buffer_length. The padding is
# produced on the default connection so setup cannot affect con1's shrink count.
let $query_padding = `SELECT REPEAT('x', 32768)`;

CREATE USER 'shrink_test_user'@'localhost';
SET GLOBAL net_buffer_shrink_threshold = 5;
--connect(con1, localhost, shrink_test_user, , )
let $con1_processlist_id = `SELECT CONNECTION_ID()`;
--connection default
--disable_query_log
--eval SET @con1_processlist_id = $con1_processlist_id

# Extra 39 bytes are allocated for
# PSI header (32 B), net header (4 B), compression header (4 B)
# They are not counted.

let $pfs_net_buff_stmt =
SELECT COUNT_ALLOC - COUNT_FREE AS CURRENT_ALLOCATIONS,
CURRENT_NUMBER_OF_BYTES_USED - 39
FROM performance_schema.memory_summary_by_thread_by_event_name
WHERE EVENT_NAME = 'memory/sql/NET::buff'
AND THREAD_ID = (SELECT THREAD_ID
FROM performance_schema.threads
WHERE PROCESSLIST_ID = @con1_processlist_id);

# =============================================================================
# Test 1: A large incoming query grows NET::buff
# =============================================================================

--connection con1
--echo [connection con1]
--disable_result_log
--eval SELECT 1 /* $query_padding */
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff after a large query; capacity should have grown."
--eval $pfs_net_buff_stmt

# =============================================================================

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kindly add test to verify behavior with small queries less than net_buffer_shrink_threshold.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For test2 and test3, I added query to show the allocated buffer, just after the forth SELECT 1. the allocated buffer should no change.

# Test 2: Five small queries shrink the grown buffer by about half
# =============================================================================

--connection con1
--echo [connection con1]
--disable_result_log
SELECT 1;
SELECT 1;
SELECT 1;
SELECT 1;
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff after four small queries; capacity should not be shrunk."
--eval $pfs_net_buff_stmt

--connection con1
--echo [connection con1]
--disable_result_log
SELECT 1;
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff after five small queries; capacity should be about half."
--eval $pfs_net_buff_stmt

# =============================================================================
# Test 3: Five more small queries reach net_buffer_length
# =============================================================================

--connection con1
--echo [connection con1]
--disable_result_log
SELECT 1;
SELECT 1;
SELECT 1;
SELECT 1;
SELECT 1;
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff after ten small queries; capacity should reach its minimum."
--eval $pfs_net_buff_stmt

let $net_buffer_length = query_get_value(
SHOW VARIABLES LIKE 'net_buffer_length', Value, 1);
let $current_buffer_capacity = `$pfs_net_buff_stmt`;

if ($current_buffer_capacity == $net_buffer_length) {
--echo NET::buff capacity is equal to net_buffer_length.
}

# =============================================================================
# Test 4: Further small queries do not shrink below net_buffer_length
# =============================================================================

--connection con1
--echo [connection con1]
--disable_result_log
SELECT 1;
SELECT 1;
SELECT 1;
SELECT 1;
SELECT 1;
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff remains at its minimum after five more small queries."
--eval $pfs_net_buff_stmt

# =============================================================================
# Test 5: A later large query grows the buffer again
# =============================================================================

--connection con1
--echo [connection con1]
--disable_result_log
--eval SELECT 1 /* $query_padding */
--enable_result_log

--connection default
--echo [connection default]
--echo "NET::buff after another large query; capacity should grow again."
--eval $pfs_net_buff_stmt

# =============================================================================
# Cleanup
# =============================================================================

--disconnect con1
--eval SET GLOBAL net_buffer_shrink_threshold = $old_net_buffer_shrink_threshold
--enable_query_log
DROP USER 'shrink_test_user'@'localhost';
30 changes: 30 additions & 0 deletions sql-common/net_serv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,36 @@ bool net_realloc(NET *net, size_t length) {
return false;
}

#ifdef MYSQL_SERVER
/**
Shrink net buffer.

@param net NET handler
@param length shrink net buffer to length. length should smaller
than the original buffer size

@retval true failed to shrink
@retval false Shrunk to length successfully
*/
bool net_shrink(NET *net, size_t length) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fold it into try_shrink_net_buffer() or define a separate function within server layer itself.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added #ifdef MYSQL_SERVER to make it server only.

uchar *buff;
size_t pkt_length;

assert(length < net->max_packet);
pkt_length = (length + IO_SIZE - 1) & ~(IO_SIZE - 1);

if (!(buff = (uchar *)my_realloc(
key_memory_NET_buff, (char *)net->buff,
pkt_length + NET_HEADER_SIZE + COMP_HEADER_SIZE, MYF(0))))
return true;

net->buff = net->write_pos = buff;
net->buff_end = buff + pkt_length;
net->max_packet = ulong(pkt_length);
return false;
}
#endif

/**
Clear (reinitialize) the NET structure for a new command.

Expand Down
1 change: 1 addition & 0 deletions sql/conn_handler/init_net_server_extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ void init_net_server_extension(THD *thd) {
thd->m_net_server_extension.m_after_header = net_after_header_psi;
thd->m_net_server_extension.compress_ctx.algorithm = MYSQL_UNCOMPRESSED;
thd->m_net_server_extension.timeout_on_full_packet = false;
thd->m_net_server_extension.shrink_requests = 0;
/* Activate this private extension for the mysqld server. */
thd->get_protocol_classic()->get_net()->extension =
&thd->m_net_server_extension;
Expand Down
Loading
Loading