Merge branch 'v2.0.0' into v2.0.0_merge_ldap

pull/1847/head
René Cannaò 7 years ago committed by GitHub
commit 49a4dd5fc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,7 +34,7 @@
#define MYHGM_MYSQL_GROUP_REPLICATION_HOSTGROUPS "CREATE TABLE mysql_group_replication_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))"
#define MYHGM_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))"
#define MYHGM_MYSQL_GALERA_HOSTGROUPS "CREATE TABLE mysql_galera_hostgroups (writer_hostgroup INT CHECK (writer_hostgroup>=0) NOT NULL PRIMARY KEY , backup_writer_hostgroup INT CHECK (backup_writer_hostgroup>=0 AND backup_writer_hostgroup<>writer_hostgroup) NOT NULL , reader_hostgroup INT NOT NULL CHECK (reader_hostgroup<>writer_hostgroup AND backup_writer_hostgroup<>reader_hostgroup AND reader_hostgroup>0) , offline_hostgroup INT NOT NULL CHECK (offline_hostgroup<>writer_hostgroup AND offline_hostgroup<>reader_hostgroup AND backup_writer_hostgroup<>offline_hostgroup AND offline_hostgroup>=0) , active INT CHECK (active IN (0,1)) NOT NULL DEFAULT 1 , max_writers INT NOT NULL CHECK (max_writers >= 0) DEFAULT 1 , writer_is_also_reader INT CHECK (writer_is_also_reader IN (0,1,2)) NOT NULL DEFAULT 0 , max_transactions_behind INT CHECK (max_transactions_behind>=0) NOT NULL DEFAULT 0 , comment VARCHAR , UNIQUE (reader_hostgroup) , UNIQUE (offline_hostgroup) , UNIQUE (backup_writer_hostgroup))"
typedef std::unordered_map<std::uint64_t, void *> umap_mysql_errors;

@ -414,6 +414,7 @@ class MySQL_Threads_Handler
int query_processor_iterations;
int query_processor_regex;
int reset_connection_algorithm;
int auto_increment_delay_multiplex;
int long_query_time;
int hostgroup_manager_verbose;
int binlog_reader_connect_retry_msec;

@ -66,6 +66,7 @@ class MySQL_Connection {
unsigned long long creation_time;
unsigned long long last_time_used;
unsigned long long timeout;
int auto_increment_delay_token;
int fd;
MySQL_STMTs_local_v14 *local_stmts; // local view of prepared statements
MYSQL *mysql;
@ -181,5 +182,6 @@ class MySQL_Connection {
void reset();
bool get_gtid(char *buff, uint64_t *trx_id);
void reduce_auto_increment_delay_token() { if (auto_increment_delay_token) auto_increment_delay_token--; };
};
#endif /* __CLASS_MYSQL_CONNECTION_H */

@ -626,6 +626,7 @@ __thread int mysql_thread___query_processor_iterations;
__thread int mysql_thread___query_processor_regex;
__thread int mysql_thread___reset_connection_algorithm;
__thread uint32_t mysql_thread___server_capabilities;
__thread int mysql_thread___auto_increment_delay_multiplex;
__thread uint8_t mysql_thread___default_charset;
__thread int mysql_thread___poll_timeout;
__thread int mysql_thread___poll_timeout_on_failure;
@ -744,6 +745,7 @@ extern __thread int mysql_thread___query_processor_iterations;
extern __thread int mysql_thread___query_processor_regex;
extern __thread int mysql_thread___reset_connection_algorithm;
extern __thread uint32_t mysql_thread___server_capabilities;
extern __thread int mysql_thread___auto_increment_delay_multiplex;
extern __thread uint8_t mysql_thread___default_charset;
extern __thread int mysql_thread___poll_timeout;
extern __thread int mysql_thread___poll_timeout_on_failure;

@ -748,10 +748,16 @@ void MySrvC::connect_error(int err_num) {
break;
}
time_t t=time(NULL);
if (t!=time_last_detected_error) {
if (t > time_last_detected_error) {
time_last_detected_error=t;
connect_ERR_at_time_last_detected_error=1;
} else {
if (t < time_last_detected_error) {
// time_last_detected_error is in the future
// this means that monitor has a ping interval too big and tuned that in the future
return;
}
// same time
int max_failures = ( mysql_thread___shun_on_failures > mysql_thread___connect_retries_on_failure ? mysql_thread___connect_retries_on_failure : mysql_thread___shun_on_failures) ;
if (__sync_add_and_fetch(&connect_ERR_at_time_last_detected_error,1) >= (unsigned int)max_failures) {
bool _shu=false;
@ -2076,7 +2082,7 @@ MySrvC *MyHGC::get_random_MySrvC(char * gtid_uuid, uint64_t gtid_trxid) {
if (max_wait_sec < 1) { // min wait time should be at least 1 second
max_wait_sec = 1;
}
if ((t - mysrvc->time_last_detected_error) > max_wait_sec) {
if (t > mysrvc->time_last_detected_error && (t - mysrvc->time_last_detected_error) > max_wait_sec) {
if (
(mysrvc->shunned_and_kill_all_connections==false) // it is safe to bring it back online
||
@ -2988,6 +2994,18 @@ bool MySQL_HostGroups_Manager::shun_and_killall(char *hostname, int port) {
default:
break;
}
// if Monitor is enabled and mysql-monitor_ping_interval is
// set too high, ProxySQL will unshun hosts that are not
// available. For this reason time_last_detected_error will
// be tuned in the future
if (mysql_thread___monitor_enabled) {
int a = mysql_thread___shun_recovery_time_sec;
int b = mysql_thread___monitor_ping_interval;
b = b/1000;
if (b > a) {
t = t + (b - a);
}
}
mysrvc->time_last_detected_error = t;
}
}
@ -3697,8 +3715,8 @@ void MySQL_HostGroups_Manager::update_galera_set_offline(char *_hostname, int _p
} else { // the server is already offline, but we check if needs to be taken back online
SQLite3_result *numw_result = NULL;
q=(char *)"SELECT 1 FROM mysql_servers WHERE hostgroup_id=%d AND status=0";
query=(char *)malloc(strlen(q)+strlen(_hostname)+32);
sprintf(query,q,_hostname,_port);
query=(char *)malloc(strlen(q) + (sizeof(_writer_hostgroup) * 8 + 1));
sprintf(query,q,_writer_hostgroup);
mydb->execute_statement(query, &error , &cols , &affected_rows , &numw_result);
free(query);
if (numw_result) {

@ -2429,7 +2429,7 @@ __get_pkts_from_client:
if (session_type != PROXYSQL_SESSION_MYSQL) { // only MySQL module supports prepared statement!!
l_free(pkt.size,pkt.ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
break;
@ -2490,7 +2490,7 @@ __get_pkts_from_client:
if (session_type != PROXYSQL_SESSION_MYSQL) { // only MySQL module supports prepared statement!!
l_free(pkt.size,pkt.ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
break;
@ -2516,7 +2516,7 @@ __get_pkts_from_client:
// we couldn't find it
l_free(pkt.size,pkt.ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Prepared statement doesn't exist", true);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Prepared statement doesn't exist", true);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
break;
@ -2534,7 +2534,7 @@ __get_pkts_from_client:
if (stmt_meta==NULL) {
l_free(pkt.size,pkt.ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Error in prepared statement execution", true);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Error in prepared statement execution", true);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
//__sync_fetch_and_sub(&stmt_info->ref_count,1); // decrease reference count
@ -2893,6 +2893,9 @@ handler_again:
if (myconn->mysql->affected_rows) {
if (myconn->mysql->affected_rows != ULLONG_MAX) {
last_HG_affected_rows = current_hostgroup;
if (mysql_thread___auto_increment_delay_multiplex) {
myconn->auto_increment_delay_token = mysql_thread___auto_increment_delay_multiplex + 1;
}
}
}
}
@ -2970,6 +2973,7 @@ handler_again:
}
RequestEnd(myds);
myds->myconn->reduce_auto_increment_delay_token();
if (mysql_thread___multiplexing && (myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) {
if (mysql_thread___connection_delay_multiplex_ms && mirror==false) {
myds->wait_until=thread->curtime+mysql_thread___connection_delay_multiplex_ms*1000;
@ -3239,6 +3243,7 @@ handler_again:
}
RequestEnd(myds);
if (myds->myconn) {
myds->myconn->reduce_auto_increment_delay_token();
if (mysql_thread___multiplexing && (myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) {
myds->DSS=STATE_NOT_INITIALIZED;
if (mysql_thread___autocommit_false_not_reusable && myds->myconn->IsAutoCommit()==false) {
@ -3856,12 +3861,12 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
/* FIXME: temporary */
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported", true);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported", true);
client_myds->DSS=STATE_SLEEP;
} else {
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported", true);
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported", true);
client_myds->DSS=STATE_SLEEP;
}
}
@ -3876,7 +3881,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
} else {
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
}
}
@ -3890,7 +3895,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
} else {
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"#28000",(char *)"Command not supported");
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1045,(char *)"28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
}
}
@ -3898,7 +3903,7 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *pkt) {
l_free(pkt->size,pkt->ptr);
client_myds->setDSS_STATE_QUERY_SENT_NET();
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9003,(char *)"#28000",(char *)"Command not supported");
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,9003,(char *)"28000",(char *)"Command not supported");
client_myds->DSS=STATE_SLEEP;
}
@ -3932,13 +3937,15 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (session_type == PROXYSQL_SESSION_MYSQL) {
__sync_fetch_and_add(&MyHGM->status.frontend_use_db, 1);
char *schemaname=strndup((char *)pkt->ptr+sizeof(mysql_hdr)+5,pkt->size-sizeof(mysql_hdr)-5);
char *schemanameptr=schemaname;
char *schemanameptr=trim_spaces_and_quotes_in_place(schemaname);
/*
//remove leading spaces
while(isspace((unsigned char)*schemanameptr)) schemanameptr++;
// remove trailing semicolon , issue #915
if (schemanameptr[strlen(schemanameptr)-1]==';') {
schemanameptr[strlen(schemanameptr)-1]='\0';
}
*/
// handle cases like "USE `schemaname`
if(schemanameptr[0]=='`' && schemanameptr[strlen(schemanameptr)-1]=='`') {
schemanameptr[strlen(schemanameptr)-1]='\0';
@ -4677,7 +4684,7 @@ void MySQL_Session::SQLite3_to_MySQL(SQLite3_result *result, char *error, int af
} else { // no result set
if (error) {
// there was an error
myprot->generate_pkt_ERR(true,NULL,NULL,sid,1045,(char *)"#28000",error);
myprot->generate_pkt_ERR(true,NULL,NULL,sid,1045,(char *)"28000",error);
} else {
// no error, DML succeeded
unsigned int nTrx=NumActiveTransactions();

@ -285,6 +285,7 @@ static char * mysql_thread_variables_names[]= {
(char *)"query_processor_iterations",
(char *)"query_processor_regex",
(char *)"reset_connection_algorithm",
(char *)"auto_increment_delay_multiplex",
(char *)"long_query_time",
(char *)"query_cache_size_MB",
(char *)"ping_interval_server_msec",
@ -357,7 +358,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.monitor_history=600000;
variables.monitor_connect_interval=120000;
variables.monitor_connect_timeout=600;
variables.monitor_ping_interval=60000;
variables.monitor_ping_interval=8000;
variables.monitor_ping_max_failures=3;
variables.monitor_ping_timeout=1000;
variables.monitor_read_only_interval=1000;
@ -403,6 +404,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.query_processor_iterations=0;
variables.query_processor_regex=1;
variables.reset_connection_algorithm=2;
variables.auto_increment_delay_multiplex=5;
variables.long_query_time=1000;
variables.query_cache_size_MB=256;
variables.init_connect=NULL;
@ -728,6 +730,19 @@ VALGRIND_DISABLE_ERROR_REPORTING;
if (!strcasecmp(name,"binlog_reader_connect_retry_msec")) return (int)variables.binlog_reader_connect_retry_msec;
if (!strcasecmp(name,"wait_timeout")) return (int)variables.wait_timeout;
if (!strcasecmp(name,"reset_connection_algorithm")) return (int)variables.reset_connection_algorithm;
if (!strcasecmp(name,"throttle_max_bytes_per_second_to_client")) return (int)variables.throttle_max_bytes_per_second_to_client;
if (!strcasecmp(name,"throttle_ratio_server_to_client")) return (int)variables.throttle_ratio_server_to_client;
if (!strcasecmp(name,"max_connections")) return (int)variables.max_connections;
if (!strcasecmp(name,"max_stmts_per_connection")) return (int)variables.max_stmts_per_connection;
if (!strcasecmp(name,"max_stmts_cache")) return (int)variables.max_stmts_cache;
if (!strcasecmp(name,"mirror_max_concurrency")) return (int)variables.mirror_max_concurrency;
if (!strcasecmp(name,"mirror_max_queue_length")) return (int)variables.mirror_max_queue_length;
if (!strcasecmp(name,"default_query_delay")) return (int)variables.default_query_delay;
if (!strcasecmp(name,"default_query_timeout")) return (int)variables.default_query_timeout;
if (!strcasecmp(name,"query_processor_iterations")) return (int)variables.query_processor_iterations;
if (!strcasecmp(name,"query_processor_regex")) return (int)variables.query_processor_regex;
if (!strcasecmp(name,"auto_increment_delay_multiplex")) return (int)variables.auto_increment_delay_multiplex;
if (!strcasecmp(name,"default_max_latency_ms")) return (int)variables.default_max_latency_ms;
if (!strcasecmp(name,"long_query_time")) return (int)variables.long_query_time;
if (!strcasecmp(name,"free_connections_pct")) return (int)variables.free_connections_pct;
if (!strcasecmp(name,"have_compress")) return (int)variables.have_compress;
@ -1084,6 +1099,10 @@ VALGRIND_DISABLE_ERROR_REPORTING;
sprintf(intbuf,"%d",variables.reset_connection_algorithm);
return strdup(intbuf);
}
if (!strcasecmp(name,"auto_increment_delay_multiplex")) {
sprintf(intbuf,"%d",variables.auto_increment_delay_multiplex);
return strdup(intbuf);
}
if (!strcasecmp(name,"default_max_latency_ms")) {
sprintf(intbuf,"%d",variables.default_max_latency_ms);
return strdup(intbuf);
@ -1686,6 +1705,15 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t
return false;
}
}
if (!strcasecmp(name,"auto_increment_delay_multiplex")) {
int intv=atoi(value);
if (intv >= 0 && intv <= 1000000) {
variables.auto_increment_delay_multiplex=intv;
return true;
} else {
return false;
}
}
if (!strcasecmp(name,"default_max_latency_ms")) {
int intv=atoi(value);
if (intv >= 0 && intv <= 20*24*3600*1000) {
@ -3556,6 +3584,7 @@ void MySQL_Thread::refresh_variables() {
mysql_thread___query_processor_iterations=GloMTH->get_variable_int((char *)"query_processor_iterations");
mysql_thread___query_processor_regex=GloMTH->get_variable_int((char *)"query_processor_regex");
mysql_thread___reset_connection_algorithm=GloMTH->get_variable_int((char *)"reset_connection_algorithm");
mysql_thread___auto_increment_delay_multiplex=GloMTH->get_variable_int((char *)"auto_increment_delay_multiplex");
mysql_thread___default_max_latency_ms=GloMTH->get_variable_int((char *)"default_max_latency_ms");
mysql_thread___long_query_time=GloMTH->get_variable_int((char *)"long_query_time");
mysql_thread___query_cache_size_MB=GloMTH->get_variable_int((char *)"query_cache_size_MB");

@ -2010,7 +2010,7 @@ void ProxySQL_Admin::flush_configdb() { // see #923
__attach_db(admindb, configdb, (char *)"disk");
// Fully synchronous is not required. See to #1055
// https://sqlite.org/pragma.html#pragma_synchronous
configdb->execute("PRAGMA disk.synchronous=0");
configdb->execute("PRAGMA synchronous=0");
wrunlock();
}

@ -221,6 +221,7 @@ MySQL_Connection::MySQL_Connection() {
MyRS_reuse=NULL;
unknown_transaction_status = false;
creation_time=0;
auto_increment_delay_token = 0;
processing_multi_statement=false;
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "Creating new MySQL_Connection %p\n", this);
local_stmts=new MySQL_STMTs_local_v14(false); // false by default, it is a backend
@ -1628,6 +1629,7 @@ bool MySQL_Connection::MultiplexDisabled() {
if (status_flags & (STATUS_MYSQL_CONNECTION_TRANSACTION|STATUS_MYSQL_CONNECTION_USER_VARIABLE|STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT|STATUS_MYSQL_CONNECTION_LOCK_TABLES|STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE|STATUS_MYSQL_CONNECTION_GET_LOCK|STATUS_MYSQL_CONNECTION_NO_MULTIPLEX|STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0|STATUS_MYSQL_CONNECTION_FOUND_ROWS) ) {
ret=true;
}
if (auto_increment_delay_token) return true;
return ret;
}

@ -71,6 +71,10 @@ static void __dump_pkt(const char *func, unsigned char *_ptr, unsigned int len)
#define queue_destroy(_q) { \
if (_q.buffer) free(_q.buffer); \
_q.buffer=NULL; \
if (_q.pkt.ptr) { \
l_free(_q.pkt.size,_q.pkt.ptr); \
queueOUT.pkt.ptr=NULL; \
} \
}
#define queue_zero(_q) { \

Loading…
Cancel
Save