Skip to content

Commit

Permalink
Allocate a server extension structure for slave_stats_daemon
Browse files Browse the repository at this point in the history
Summary:
Without allocating the server extension structure, 8.0.20 instances were crashing. This structure maintains compression context information.

Moved

`mysql_extension_set_server_extn(mysql, &mi->server_extn);`

to method `configure_master_connection_options` which is common to both slave stats daemon and replication io thread.

Now both threads will be setting the structure properly.

Reviewed By: hermanlee

Differential Revision: D27486594
  • Loading branch information
Rahul-Singhal authored and inikep committed Aug 6, 2024
1 parent 0753443 commit b1b799d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 7 deletions.
6 changes: 3 additions & 3 deletions include/mysql_com_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ struct compression_attributes {
};

typedef struct NET_SERVER {
before_header_callback_fn m_before_header;
after_header_callback_fn m_after_header;
void *m_user_data;
before_header_callback_fn m_before_header{nullptr};
after_header_callback_fn m_after_header{nullptr};
void *m_user_data{nullptr};
struct compression_attributes compression;
mysql_compress_context compress_ctx;
bool timeout_on_full_packet;
Expand Down
32 changes: 32 additions & 0 deletions mysql-test/r/slave_stats_daemon.result
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,38 @@ select now() - max(timestamp) <= 1 as less_than_1_sec_old_most_recent_stats from
less_than_1_sec_old_most_recent_stats
1
########################################################################################################
### Case 3.6: Test for 8.0.20 crashes. Make sure secondary does not crash when slave_compressed_protocol = 1
########################################################################################################
set @@GLOBAL.write_stats_frequency=1;
set @@GLOBAL.write_stats_count=10;
select sleep(2);
sleep(2)
0
select count(*) > 0 as stats_samples_collected from performance_schema.replica_statistics;
stats_samples_collected
1
include/stop_slave.inc
set @@GLOBAL.slave_compressed_protocol=1;
include/start_slave.inc
select sleep(2);
sleep(2)
0
select 1;
1
1
select sleep(2);
sleep(2)
0
select now() - max(timestamp) <= 1 as less_than_1_sec_old_most_recent_stats from performance_schema.replica_statistics;
less_than_1_sec_old_most_recent_stats
1
create table t(a int) engine=innodb;
insert into t values(1);
drop table t;
include/stop_slave.inc
set @@GLOBAL.slave_compressed_protocol=0;
include/start_slave.inc
########################################################################################################
### Case 4: Promote slave to master and master to slave. Old master(new slave) should be able to send
### stats to new master(old slave)
########################################################################################################
Expand Down
39 changes: 39 additions & 0 deletions mysql-test/t/slave_stats_daemon.test
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,45 @@ select sleep(2);
# Master should be receiving stats every second and it's most recent stat should not be more than 1 sec old
select now() - max(timestamp) <= 1 as less_than_1_sec_old_most_recent_stats from performance_schema.replica_statistics;

--echo ########################################################################################################
--echo ### Case 3.6: Test for 8.0.20 crashes. Make sure secondary does not crash when slave_compressed_protocol = 1
--echo ########################################################################################################
connection slave;
set @@GLOBAL.write_stats_frequency=1;

connection master;
set @@GLOBAL.write_stats_count=10;
select sleep(2);
select count(*) > 0 as stats_samples_collected from performance_schema.replica_statistics;

connection slave;
-- source include/stop_slave.inc
set @@GLOBAL.slave_compressed_protocol=1;
-- source include/start_slave.inc

## make sure secondary does not crash
select sleep(2);
select 1;

# Master should be receiving stats every second and it's most recent stat should not be more than 1 sec old
connection master;
select sleep(2);
select now() - max(timestamp) <= 1 as less_than_1_sec_old_most_recent_stats from performance_schema.replica_statistics;

# Generate some traffic on primary to make sure replication I/O channel is fine
create table t(a int) engine=innodb;
insert into t values(1);


# reset
connection master;
drop table t;
--sync_slave_with_master
connection slave;
-- source include/stop_slave.inc
set @@GLOBAL.slave_compressed_protocol=0;
-- source include/start_slave.inc

--echo ########################################################################################################
--echo ### Case 4: Promote slave to master and master to slave. Old master(new slave) should be able to send
--echo ### stats to new master(old slave)
Expand Down
17 changes: 13 additions & 4 deletions sql/slave_stats_daemon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mysql.h>
#include <mysql/psi/mysql_thread.h>
#include <mysql_com.h>
#include <sql_common.h>
#include <sql_string.h>

#include "sql/log.h"
Expand Down Expand Up @@ -66,7 +67,8 @@ static bool connected_to_master = false;
@retval false otherwise.
*/
static bool safe_connect_slave_stats_thread_to_master(MYSQL *&mysql,
Master_info *active_mi) {
Master_info *active_mi,
NET_SERVER *server_extn) {
if (mysql != nullptr) {
mysql_close(mysql);
}
Expand All @@ -85,7 +87,7 @@ static bool safe_connect_slave_stats_thread_to_master(MYSQL *&mysql,
if (active_mi->get_password(pass, &password_size)) {
return false;
}

mysql_extension_set_server_extn(mysql, server_extn);
if (!mysql_real_connect(mysql, active_mi->host, active_mi->get_user(), pass,
0, active_mi->port, 0, 0)) {
return false;
Expand All @@ -104,6 +106,13 @@ static void *handle_slave_stats_daemon(void *arg MY_ATTRIBUTE((unused))) {
slave_stats_daemon_thread = my_thread_self();

MYSQL *mysql = nullptr;
// allocate server extension structure
NET_SERVER server_extn;
server_extn.m_user_data = nullptr;
server_extn.m_before_header = nullptr;
server_extn.m_after_header = nullptr;
server_extn.compress_ctx.algorithm = MYSQL_UNCOMPRESSED;

Master_info *active_mi;
while (true) {
mysql_mutex_lock(&LOCK_slave_stats_daemon);
Expand Down Expand Up @@ -150,8 +159,8 @@ static void *handle_slave_stats_daemon(void *arg MY_ATTRIBUTE((unused))) {
// successful, try again in next cycle

if (!connected_to_master) {
connected_to_master =
safe_connect_slave_stats_thread_to_master(mysql, active_mi);
connected_to_master = safe_connect_slave_stats_thread_to_master(
mysql, active_mi, &server_extn);
if (connected_to_master) {
DBUG_PRINT("info",
("Slave Stats Daemon: connected to master '%s@%s:%d'",
Expand Down

0 comments on commit b1b799d

Please sign in to comment.