Skip to content

Commit 4a6ba68

Browse files
authored
Merge pull request #5173 from sysown/v3.0_admin_cmd_5170
Resolved issues with PROXYSQL PAUSE/RESUME/STOP/START
2 parents a308d26 + 9d13105 commit 4a6ba68

File tree

3 files changed

+295
-47
lines changed

3 files changed

+295
-47
lines changed

lib/Admin_Handler.cpp

Lines changed: 107 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -476,26 +476,40 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
476476
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
477477
return false;
478478
}
479-
if (query_no_space_length==strlen("PROXYSQL START") && !strncasecmp("PROXYSQL START",query_no_space, query_no_space_length)) {
479+
if (query_no_space_length == strlen("PROXYSQL START") && !strncasecmp("PROXYSQL START", query_no_space, query_no_space_length)) {
480+
480481
proxy_info("Received PROXYSQL START command\n");
481-
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
482-
bool rc=false;
482+
ProxySQL_Admin* SPA = (ProxySQL_Admin*)pa;
483+
bool rc = false;
484+
483485
if (admin_nostart_) {
484-
rc=__sync_bool_compare_and_swap(&GloVars.global.nostart,1,0);
486+
rc = __sync_bool_compare_and_swap(&GloVars.global.nostart, 1, 0);
485487
}
488+
486489
if (rc) {
487-
// Set the status variable 'threads_initialized' to 0 because it's initialized back
488-
// in main 'init_phase3'. After GloMTH have been initialized again.
490+
// --- MySQL module ---
491+
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Starting ProxySQL MySQL module\n");
489492
__sync_bool_compare_and_swap(&GloMTH->status_variables.threads_initialized, 1, 0);
490-
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Starting ProxySQL following PROXYSQL START command\n");
491-
while(__sync_fetch_and_add(&GloMTH->status_variables.threads_initialized, 0) == 1) {
493+
while (__sync_fetch_and_add(&GloMTH->status_variables.threads_initialized, 0) == 1) {
494+
usleep(1000);
495+
}
496+
497+
// --- PgSQL module ---
498+
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Starting ProxySQL PgSQL module\n");
499+
__sync_bool_compare_and_swap(&GloPTH->status_variables.threads_initialized, 1, 0);
500+
while (__sync_fetch_and_add(&GloPTH->status_variables.threads_initialized, 0) == 1) {
492501
usleep(1000);
493502
}
503+
504+
// --- Common startup logging ---
505+
proxy_info("ProxySQL MySQL and PgSQL modules started successfully\n");
494506
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
495-
} else {
507+
}
508+
else {
496509
proxy_warning("ProxySQL was already started when received PROXYSQL START command\n");
497-
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL already started");
510+
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL already started");
498511
}
512+
499513
return false;
500514
}
501515

@@ -510,36 +524,58 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
510524
return false;
511525
}
512526

513-
if (query_no_space_length==strlen("PROXYSQL STOP") && !strncasecmp("PROXYSQL STOP",query_no_space, query_no_space_length)) {
527+
if (query_no_space_length == strlen("PROXYSQL STOP") && !strncasecmp("PROXYSQL STOP", query_no_space, query_no_space_length)) {
528+
514529
proxy_info("Received PROXYSQL STOP command\n");
515-
// to speed up this process we first change wait_timeout to 0
516-
// MySQL_thread will call poll() with a maximum timeout of 100ms
517-
admin_old_wait_timeout=GloMTH->get_variable_int((char *)"wait_timeout");
518-
GloMTH->set_variable((char *)"wait_timeout",(char *)"0");
530+
ProxySQL_Admin* SPA = (ProxySQL_Admin*)pa;
531+
532+
if (admin_nostart_) {
533+
if (__sync_fetch_and_add((uint8_t*)(&GloVars.global.nostart), 0)) {
534+
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL MySQL and PgSQL modules are not running; cannot stop");
535+
return false;
536+
}
537+
}
538+
539+
char buf[32];
540+
541+
// ----- MySQL module stop -----
542+
int admin_old_wait_timeout = GloMTH->get_variable_int((char*)"wait_timeout");
543+
GloMTH->set_variable((char*)"wait_timeout", (char*)"0");
519544
GloMTH->commit();
520545
GloMTH->signal_all_threads(0);
521546
GloMTH->stop_listeners();
522-
char buf[32];
523-
sprintf(buf,"%d",admin_old_wait_timeout);
524-
GloMTH->set_variable((char *)"wait_timeout",buf);
547+
sprintf(buf, "%d", admin_old_wait_timeout);
548+
GloMTH->set_variable((char*)"wait_timeout", buf);
525549
GloMTH->commit();
526-
glovars.reload=2;
527-
// This function was introduced into 'prometheus::Registry' for being
528-
// able to do a complete reset of all the 'prometheus counters'. It
529-
// shall only be used during ProxySQL shutdown phases.
530-
GloVars.prometheus_registry->ResetCounters();
531-
__sync_bool_compare_and_swap(&glovars.shutdown,0,1);
532-
// After setting the shutdown flag, we should wake all threads and wait for
533-
// the shutdown phase to complete.
550+
551+
// ----- PgSQL module stop -----
552+
admin_old_wait_timeout = GloPTH->get_variable_int((char*)"wait_timeout");
553+
GloPTH->set_variable((char*)"wait_timeout", (char*)"0");
554+
GloPTH->commit();
555+
GloPTH->signal_all_threads(0);
556+
GloPTH->stop_listeners();
557+
sprintf(buf, "%d", admin_old_wait_timeout);
558+
GloPTH->set_variable((char*)"wait_timeout", buf);
559+
GloPTH->commit();
560+
561+
// ----- Common shutdown actions -----
562+
glovars.reload = 2;
563+
564+
// Reset Prometheus counters
565+
if (GloVars.prometheus_registry)
566+
GloVars.prometheus_registry->ResetCounters();
567+
568+
// Signal shutdown and wait for completion
569+
__sync_bool_compare_and_swap(&glovars.shutdown, 0, 1);
534570
GloMTH->signal_all_threads(0);
535-
while (__sync_fetch_and_add(&glovars.shutdown,0)==1) {
571+
GloPTH->signal_all_threads(0);
572+
573+
while (__sync_fetch_and_add(&glovars.shutdown, 0) == 1) {
536574
usleep(1000);
537575
}
538-
// After shutdown phase is completed, we must to send a 'OK' to the
539-
// mysql client, otherwise, since this session might not be drop due
540-
// to the waiting condition, the client wont disconnect and will
541-
// keep forever waiting for acknowledgement.
576+
542577
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
578+
543579
return false;
544580
}
545581

@@ -548,10 +584,16 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
548584
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
549585
if (admin_nostart_) {
550586
if (__sync_fetch_and_add((uint8_t *)(&GloVars.global.nostart),0)) {
551-
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL module not running, impossible to pause");
587+
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL and PgSQL modules are not running; cannot pause");
552588
return false;
553589
}
554590
}
591+
592+
if (admin_proxysql_mysql_paused && admin_proxysql_pgsql_paused) {
593+
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL MySQL and PgSQL modules are already paused; cannot be paused again.");
594+
return false;
595+
}
596+
555597
if (admin_proxysql_mysql_paused==false) {
556598
// to speed up this process we first change poll_timeout to 10
557599
// MySQL_thread will call poll() with a maximum timeout of 10ms
@@ -560,15 +602,12 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
560602
GloMTH->commit();
561603
GloMTH->signal_all_threads(0);
562604
GloMTH->stop_listeners();
563-
admin_proxysql_mysql_paused=true;
564-
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
605+
admin_proxysql_mysql_paused=true;
565606
// we now rollback poll_timeout
566607
char buf[32];
567608
sprintf(buf,"%d",admin_old_wait_timeout);
568609
GloMTH->set_variable((char *)"poll_timeout",buf);
569610
GloMTH->commit();
570-
} else {
571-
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL module is already paused, impossible to pause");
572611
}
573612

574613
if (admin_proxysql_pgsql_paused == false) {
@@ -580,16 +619,17 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
580619
GloPTH->signal_all_threads(0);
581620
GloPTH->stop_listeners();
582621
admin_proxysql_pgsql_paused = true;
583-
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
584622
// we now rollback poll_timeout
585623
char buf[32];
586624
sprintf(buf, "%d", admin_old_wait_timeout);
587625
GloPTH->set_variable((char*)"poll_timeout", buf);
588626
GloPTH->commit();
589627
}
590-
else {
591-
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL PgSQL module is already paused, impossible to pause");
628+
629+
if (admin_proxysql_mysql_paused || admin_proxysql_pgsql_paused) {
630+
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
592631
}
632+
593633
return false;
594634
}
595635

@@ -598,10 +638,16 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
598638
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
599639
if (admin_nostart_) {
600640
if (__sync_fetch_and_add((uint8_t *)(&GloVars.global.nostart),0)) {
601-
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL module not running, impossible to resume");
641+
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL and PgSQL modules are not running; cannot resume.");
602642
return false;
603643
}
604644
}
645+
646+
if (admin_proxysql_mysql_paused == false && admin_proxysql_pgsql_paused == false) {
647+
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL MySQL and PgSQL modules are not paused; cannot resume");
648+
return false;
649+
}
650+
605651
if (admin_proxysql_mysql_paused==true) {
606652
// to speed up this process we first change poll_timeout to 10
607653
// MySQL_thread will call poll() with a maximum timeout of 10ms
@@ -615,14 +661,11 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
615661
//GloMTH->set_variable((char *)"poll_timeout",buf);
616662
//GloMTH->commit();
617663
admin_proxysql_mysql_paused=false;
618-
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
619664
// we now rollback poll_timeout
620665
char buf[32];
621666
sprintf(buf,"%d",admin_old_wait_timeout);
622667
GloMTH->set_variable((char *)"poll_timeout",buf);
623668
GloMTH->commit();
624-
} else {
625-
SPA->send_error_msg_to_client(sess, (char *)"ProxySQL MySQL module is not paused, impossible to resume");
626669
}
627670

628671
if (admin_proxysql_pgsql_paused == true) {
@@ -638,16 +681,17 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
638681
//GloPTH->set_variable((char *)"poll_timeout",buf);
639682
//GloPTH->commit();
640683
admin_proxysql_pgsql_paused = false;
641-
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
642684
// we now rollback poll_timeout
643685
char buf[32];
644686
sprintf(buf, "%d", admin_old_wait_timeout);
645687
GloPTH->set_variable((char*)"poll_timeout", buf);
646688
GloPTH->commit();
647689
}
648-
else {
649-
SPA->send_error_msg_to_client(sess, (char*)"ProxySQL MySQL module is not paused, impossible to resume");
690+
691+
if (admin_proxysql_mysql_paused == false || admin_proxysql_pgsql_paused == false) {
692+
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
650693
}
694+
651695
return false;
652696
}
653697

@@ -711,6 +755,16 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
711755
return false;
712756
}
713757

758+
if (!strcasecmp("PROXYSQL FLUSH PGSQL CLIENT HOSTS", query_no_space)) {
759+
proxy_info("Received PROXYSQL FLUSH PGSQL CLIENT HOSTS command\n");
760+
ProxySQL_Admin* SPA = (ProxySQL_Admin*)pa;
761+
if (GloPTH) {
762+
GloPTH->flush_client_host_cache();
763+
}
764+
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
765+
return false;
766+
}
767+
714768
if (
715769
(query_no_space_length==strlen("PROXYSQL FLUSH CONFIGDB") && !strncasecmp("PROXYSQL FLUSH CONFIGDB",query_no_space, query_no_space_length)) // see #923
716770
) {
@@ -4074,8 +4128,14 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
40744128
pthread_mutex_unlock(&pa->sql_query_global_mutex);
40754129
} else {
40764130
// The admin module may have already been freed in case of "PROXYSQL STOP"
4077-
if (strcasecmp("PROXYSQL STOP",query_no_space))
4131+
if (strcasecmp(query_no_space, "PROXYSQL STOP") == 0) {
4132+
// Command is "PROXYSQL STOP"
4133+
if (admin_nostart_ && __sync_fetch_and_add((uint8_t*)&GloVars.global.nostart, 0)) {
4134+
pthread_mutex_unlock(&pa->sql_query_global_mutex);
4135+
}
4136+
} else {
40784137
pthread_mutex_unlock(&pa->sql_query_global_mutex);
4138+
}
40794139
}
40804140
l_free(pkt->size-sizeof(mysql_hdr),query_no_space); // it is always freed here
40814141
l_free(query_length,query);

lib/ProxySQL_Admin.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,9 @@ void ProxySQL_Admin::flush_logs() {
10871087
if (GloMyLogger) {
10881088
GloMyLogger->flush_log();
10891089
}
1090+
if (GloPgSQL_Logger) {
1091+
GloPgSQL_Logger->flush_log();
1092+
}
10901093
this->flush_error_log();
10911094
proxysql_keylog_close();
10921095
char* ssl_keylog_file = this->get_variable((char*)"ssl_keylog_file");

0 commit comments

Comments
 (0)