Improved debugging

Added new command `PROXYSQL INTERNAL SESSION` that clients can execute to
receive internal information about their own connection in JSON format.

Added JSON library.

Recompiled SQLite3 to support JSON.

Added new column `extended_info` in `stats_mysql_processlist`.

Added new mysql variable `mysql-show_processlist_extended` that determine the
content of `stats_mysql_processlist.extended_info`:
- 0 : no info
- 1 : JSON format
- 2 : JSON format with pretty printing
pull/2030/head
René Cannaò 7 years ago
parent bee49892bc
commit 528d8cac38

2
deps/Makefile vendored

@ -118,7 +118,7 @@ sqlite3/sqlite3/sqlite3.o:
cd sqlite3 && rm -rf sqlite-amalgamation-3190200
cd sqlite3 && tar -zxf sqlite-amalgamation-3190200.tar.gz
cd sqlite3/sqlite3 && patch sqlite3.c < ../from_unixtime.patch
cd sqlite3/sqlite3 && ${CC} ${MYCFLAGS} -c -o sqlite3.o sqlite3.c -DSQLITE_ENABLE_MEMORY_MANAGEMENT
cd sqlite3/sqlite3 && ${CC} ${MYCFLAGS} -c -o sqlite3.o sqlite3.c -DSQLITE_ENABLE_MEMORY_MANAGEMENT -DSQLITE_ENABLE_JSON1
sqlite3: sqlite3/sqlite3/sqlite3.o

20842
deps/json/json.hpp vendored

File diff suppressed because it is too large Load Diff

@ -181,6 +181,9 @@ class MySQL_STMTs_meta {
class MySQL_STMTs_local_v14 {
private:
bool is_client_;
std::stack<uint32_t> free_client_ids;
uint32_t local_max_stmt_id;
public:
// this map associate client_stmt_id to global_stmt_id : this is used only for client connections
std::map<uint32_t, uint64_t> client_stmt_to_global_ids;
// this multimap associate global_stmt_id to client_stmt_id : this is used only for client connections
@ -193,9 +196,6 @@ class MySQL_STMTs_local_v14 {
std::map<uint64_t, MYSQL_STMT *> global_stmt_to_backend_stmt;
std::stack<uint32_t> free_client_ids;
uint32_t local_max_stmt_id;
public:
MySQL_Session *sess;
MySQL_STMTs_local_v14(bool _ic) {
local_max_stmt_id = 0;

@ -3,6 +3,9 @@
#include "proxysql.h"
#include "cpp.h"
#include "../deps/json/json.hpp"
using json = nlohmann::json;
enum proxysql_session_type {
PROXYSQL_SESSION_MYSQL,
PROXYSQL_SESSION_ADMIN,
@ -85,6 +88,7 @@ class MySQL_Session
void handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED__get_connection();
void return_proxysql_internal(PtrSize_t *);
bool handler_special_queries(PtrSize_t *);
bool handler_CommitRollback(PtrSize_t *);
bool handler_SetAutocommit(PtrSize_t *);
@ -226,6 +230,7 @@ class MySQL_Session
void create_new_session_and_reset_connection(MySQL_Data_Stream *_myds);
bool handle_command_query_kill(PtrSize_t *);
void finishQuery(MySQL_Data_Stream *myds, MySQL_Connection *myconn, bool);
void generate_proxysql_internal_session_json(json &);
};
#define KILL_QUERY 1

@ -369,6 +369,7 @@ class MySQL_Threads_Handler
int connect_timeout_server;
int connect_timeout_server_max;
int free_connections_pct;
int show_processlist_extended;
#ifdef IDLE_THREADS
int session_idle_ms;
bool session_idle_show_processlist;

@ -102,6 +102,7 @@ class ProxySQL_Admin {
int stats_mysql_query_cache;
int stats_system_cpu;
int stats_system_memory;
int mysql_show_processlist_extended;
bool web_enabled;
bool web_enabled_old;
int web_port;

@ -650,6 +650,7 @@ __thread bool mysql_thread___query_digests_normalize_digest_text;
__thread bool mysql_thread___query_digests_track_hostname;
__thread int mysql_thread___query_digests_max_digest_length;
__thread int mysql_thread___query_digests_max_query_length;
__thread int mysql_thread___show_processlist_extended;
__thread bool mysql_thread___default_reconnect;
__thread bool mysql_thread___session_idle_show_processlist;
__thread bool mysql_thread___sessions_sort;
@ -773,6 +774,7 @@ extern __thread bool mysql_thread___query_digests_normalize_digest_text;
extern __thread bool mysql_thread___query_digests_track_hostname;
extern __thread int mysql_thread___query_digests_max_digest_length;
extern __thread int mysql_thread___query_digests_max_query_length;
extern __thread int mysql_thread___show_processlist_extended;
extern __thread bool mysql_thread___default_reconnect;
extern __thread bool mysql_thread___session_idle_show_processlist;
extern __thread bool mysql_thread___sessions_sort;

@ -703,8 +703,127 @@ __ret_autocommit_OK:
return false;
}
void MySQL_Session::generate_proxysql_internal_session_json(json &j) {
j["autocommit"] = autocommit;
j["thread_session_id"] = thread_session_id;
j["current_hostgroup"] = current_hostgroup;
j["default_hostgroup"] = default_hostgroup;
j["autocommit_on_hostgroup"] = autocommit_on_hostgroup;
j["last_insert_id"] = last_insert_id;
j["last_HG_affected_rows"] = last_HG_affected_rows;
j["client"]["userinfo"]["username"] = client_myds->myconn->userinfo->username;
j["client"]["userinfo"]["password"] = client_myds->myconn->userinfo->password;
j["client"]["stream"]["pkts_recv"] = client_myds->pkts_recv;
j["client"]["stream"]["pkts_sent"] = client_myds->pkts_sent;
j["client"]["stream"]["bytes_recv"] = client_myds->bytes_info.bytes_recv;
j["client"]["stream"]["bytes_sent"] = client_myds->bytes_info.bytes_sent;
j["client"]["client_addr"]["address"] = client_myds->addr.addr;
j["client"]["client_addr"]["port"] = client_myds->addr.port;
j["client"]["proxy_addr"]["address"] = client_myds->proxy_addr.addr;
j["client"]["proxy_addr"]["port"] = client_myds->proxy_addr.port;
j["client"]["encrypted"] = client_myds->encrypted;
j["default_schema"] = default_schema;
j["transaction_persistent"] = transaction_persistent;
j["conn"]["sql_mode"] = ( client_myds->myconn->options.sql_mode ? client_myds->myconn->options.sql_mode : "") ;
j["conn"]["time_zone"] = ( client_myds->myconn->options.time_zone ? client_myds->myconn->options.time_zone : "") ;
j["conn"]["charset"] = client_myds->myconn->options.charset;
j["conn"]["sql_log_bin"] = client_myds->myconn->options.sql_log_bin;
j["conn"]["autocommit"] = client_myds->myconn->options.autocommit;
j["conn"]["no_backslash_escapes"] = client_myds->myconn->options.no_backslash_escapes;
j["conn"]["status"]["compression"] = client_myds->myconn->get_status_compression();
j["conn"]["status"]["transaction"] = client_myds->myconn->get_status_transaction();
j["conn"]["ps"]["client_stmt_to_global_ids"] = client_myds->myconn->local_stmts->client_stmt_to_global_ids;
for (unsigned int i=0; i<mybes->len; i++) {
MySQL_Backend *_mybe = NULL;
_mybe=(MySQL_Backend *)mybes->index(i);
j["backends"][i]["hostgroup_id"] = _mybe->hostgroup_id;
if (_mybe->server_myds) {
MySQL_Data_Stream *_myds=_mybe->server_myds;
/* when fast_forward is not used, these metrics are always 0. Explicitly disabled
j["backend"][i]["stream"]["pkts_recv"] = _myds->pkts_recv;
j["backend"][i]["stream"]["pkts_sent"] = _myds->pkts_sent;
j["backend"][i]["stream"]["bytes_recv"] = _myds->bytes_info.bytes_recv;
j["backend"][i]["stream"]["bytes_sent"] = _myds->bytes_info.bytes_sent;
*/
if (_myds->myconn) {
MySQL_Connection * _myconn = _myds->myconn;
j["backends"][i]["conn"]["sql_mode"] = ( _myconn->options.sql_mode ? _myconn->options.sql_mode : "") ;
j["backends"][i]["conn"]["time_zone"] = ( _myconn->options.time_zone ? _myconn->options.time_zone : "") ;
//j["backend"][i]["conn"]["charset"] = _myds->myconn->options.charset; // not used for backend
j["backends"][i]["conn"]["sql_log_bin"] = _myconn->options.sql_log_bin;
j["backends"][i]["conn"]["init_connect"] = ( _myconn->options.init_connect ? _myconn->options.init_connect : "");
j["backends"][i]["conn"]["init_connect_sent"] = _myds->myconn->options.init_connect_sent;
j["backends"][i]["conn"]["autocommit"] = _myds->myconn->options.autocommit;
j["backends"][i]["conn"]["last_set_autocommit"] = _myds->myconn->options.last_set_autocommit;
j["backends"][i]["conn"]["no_backslash_escapes"] = _myconn->options.no_backslash_escapes;
j["backends"][i]["conn"]["status"]["get_lock"] = _myconn->get_status_get_lock();
j["backends"][i]["conn"]["status"]["lock_tables"] = _myconn->get_status_lock_tables();
j["backends"][i]["conn"]["status"]["temporary_table"] = _myconn->get_status_temporary_table();
j["backends"][i]["conn"]["status"]["user_variable"] = _myconn->get_status_user_variable();
j["backends"][i]["conn"]["status"]["found_rows"] = _myconn->get_status_found_rows();
j["backends"][i]["conn"]["status"]["no_multiplex"] = _myconn->get_status_no_multiplex();
j["backends"][i]["conn"]["MultiplexDisabled"] = _myconn->MultiplexDisabled();
j["backends"][i]["conn"]["ps"]["backend_stmt_to_global_ids"] = _myconn->local_stmts->backend_stmt_to_global_ids;
j["backends"][i]["conn"]["ps"]["global_stmt_to_backend_ids"] = _myconn->local_stmts->global_stmt_to_backend_ids;
if (_myconn->mysql) {
MYSQL * _my = _myconn->mysql;
j["backends"][i]["conn"]["mysql"]["host"] = _my->host;
j["backends"][i]["conn"]["mysql"]["host_info"] = _my->host_info;
j["backends"][i]["conn"]["mysql"]["port"] = _my->port;
j["backends"][i]["conn"]["mysql"]["server_version"] = _my->server_version;
j["backends"][i]["conn"]["mysql"]["user"] = _my->user;
j["backends"][i]["conn"]["mysql"]["unix_socket"] = (_my->unix_socket ? _my->unix_socket : "");
j["backends"][i]["conn"]["mysql"]["db"] = (_my->db ? _my->db : "");
j["backends"][i]["conn"]["mysql"]["affected_rows"] = _my->affected_rows;
j["backends"][i]["conn"]["mysql"]["insert_id"] = _my->insert_id;
j["backends"][i]["conn"]["mysql"]["server_status"] = _my->server_status;
j["backends"][i]["conn"]["mysql"]["charset"] = _my->charset->nr;
//j["backends"][i]["conn"]["mysql"][""] = _my->;
//j["backends"][i]["conn"]["mysql"][""] = _my->;
j["backends"][i]["conn"]["mysql"]["options"]["charset_name"] = _my->options.charset_name;
j["backends"][i]["conn"]["mysql"]["options"]["use_ssl"] = _my->options.use_ssl;
j["backends"][i]["conn"]["mysql"]["net"]["last_errno"] = _my->net.last_errno;
j["backends"][i]["conn"]["mysql"]["net"]["fd"] = _my->net.fd;
j["backends"][i]["conn"]["mysql"]["net"]["max_packet_size"] = _my->net.max_packet_size;
j["backends"][i]["conn"]["mysql"]["net"]["sqlstate"] = _my->net.sqlstate;
//j["backends"][i]["conn"]["mysql"]["net"][""] = _my->net.;
//j["backends"][i]["conn"]["mysql"]["net"][""] = _my->net.;
}
}
}
}
}
void MySQL_Session::return_proxysql_internal(PtrSize_t *pkt) {
int l = 0;
l = strlen((char *)"PROXYSQL INTERNAL SESSION");
if (pkt->size==(5+l) && strncasecmp((char *)"PROXYSQL INTERNAL SESSION", (char *)pkt->ptr+5, l)==0) {
json j;
generate_proxysql_internal_session_json(j);
std::string s = j.dump(4);
SQLite3_result *resultset = new SQLite3_result(1);
resultset->add_column_definition(SQLITE_TEXT,"session_info");
char *pta[1];
pta[0] = (char *)s.c_str();
resultset->add_row(pta);
SQLite3_to_MySQL(resultset, NULL, 0, &client_myds->myprot);
delete resultset;
return;
}
// default
client_myds->DSS=STATE_QUERY_SENT_NET;
client_myds->myprot.generate_pkt_ERR(true,NULL,NULL,1,1064,(char *)"42000",(char *)"Unknown PROXYSQL INTERNAL command",true);
client_myds->DSS=STATE_SLEEP;
status=WAITING_CLIENT_DATA;
l_free(pkt->size,pkt->ptr);
}
bool MySQL_Session::handler_special_queries(PtrSize_t *pkt) {
if (pkt->size>(5+18) && strncasecmp((char *)"PROXYSQL INTERNAL ",(char *)pkt->ptr+5,18)==0) {
return_proxysql_internal(pkt);
return true;
}
if (mysql_thread___forward_autocommit == false) {
if (handler_SetAutocommit(pkt) == true) {
return true;

@ -301,6 +301,7 @@ static char * mysql_thread_variables_names[]= {
#ifdef IDLE_THREADS
(char *)"session_idle_show_processlist",
#endif // IDLE_THREADS
(char *)"show_processlist_extended",
(char *)"commands_stats",
(char *)"query_digests",
(char *)"query_digests_lowercase",
@ -453,6 +454,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
variables.session_idle_ms=1000;
variables.session_idle_show_processlist=true;
#endif // IDLE_THREADS
variables.show_processlist_extended = 0;
variables.servers_stats=true;
variables.default_reconnect=true;
variables.ssl_p2s_ca=NULL;
@ -700,6 +702,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
#ifdef IDLE_THREADS
if (!strcmp(name,"session_idle_show_processlist")) return (int)variables.session_idle_show_processlist;
#endif // IDLE_THREADS
if (!strcmp(name,"show_processlist_extended")) return (int)variables.show_processlist_extended;
if (!strcmp(name,"servers_stats")) return (int)variables.servers_stats;
if (!strcmp(name,"stacksize")) return ( stacksize ? stacksize : DEFAULT_STACK_SIZE);
}
@ -786,6 +789,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
#ifdef IDLE_THREADS
if (!strcmp(name,"session_idle_show_processlist")) return (int)variables.session_idle_show_processlist;
#endif // IDLE_THREADS
if (!strcmp(name,"show_processlist_extended")) return (int)variables.show_processlist_extended;
if (!strcmp(name,"servers_stats")) return (int)variables.servers_stats;
if (!strcmp(name,"default_reconnect")) return (int)variables.default_reconnect;
if (!strcmp(name,"poll_timeout")) return variables.poll_timeout;
@ -1234,6 +1238,10 @@ char * MySQL_Threads_Handler::get_variable(char *name) { // this is the public f
return strdup((variables.session_idle_show_processlist ? "true" : "false"));
}
#endif // IDLE_THREADS
if (!strcasecmp(name,"show_processlist_extended")) {
sprintf(intbuf,"%d",variables.show_processlist_extended);
return strdup(intbuf);
}
if (!strcasecmp(name,"servers_stats")) {
return strdup((variables.servers_stats ? "true" : "false"));
}
@ -2345,6 +2353,16 @@ bool MySQL_Threads_Handler::set_variable(char *name, char *value) { // this is t
return false;
}
#endif // IDLE_THREADS
if (!strcasecmp(name,"show_processlist_extended")) {
int intv=atoi(value);
if (intv >= 0 && intv <= 2) {
variables.show_processlist_extended=intv;
return true;
} else {
return false;
}
return false;
}
if (!strcasecmp(name,"sessions_sort")) {
if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
variables.sessions_sort=true;
@ -3783,6 +3801,7 @@ void MySQL_Thread::refresh_variables() {
#ifdef IDLE_THREADS
mysql_thread___session_idle_show_processlist=(bool)GloMTH->get_variable_int((char *)"session_idle_show_processlist");
#endif // IDLE_THREADS
mysql_thread___show_processlist_extended=GloMTH->get_variable_int((char *)"show_processlist_extended");
mysql_thread___servers_stats=(bool)GloMTH->get_variable_int((char *)"servers_stats");
mysql_thread___default_reconnect=(bool)GloMTH->get_variable_int((char *)"default_reconnect");
#ifdef DEBUG
@ -4410,7 +4429,7 @@ void MySQL_Threads_Handler::Get_Memory_Stats() {
}
SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() {
const int colnum=15;
const int colnum=16;
char port[NI_MAXSERV];
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping MySQL Processlist\n");
SQLite3_result *result=new SQLite3_result(colnum);
@ -4429,6 +4448,7 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() {
result->add_column_definition(SQLITE_TEXT,"time_ms");
result->add_column_definition(SQLITE_TEXT,"info");
result->add_column_definition(SQLITE_TEXT,"status_flags");
result->add_column_definition(SQLITE_TEXT,"extended_info");
unsigned int i;
unsigned int i2;
// signal_all_threads(1);
@ -4659,6 +4679,18 @@ SQLite3_result * MySQL_Threads_Handler::SQL3_Processlist() {
}
pta[12]=strdup(buf);
pta[15]=NULL;
if (mysql_thread___show_processlist_extended) {
json j;
sess->generate_proxysql_internal_session_json(j);
if (mysql_thread___show_processlist_extended == 2) {
std::string s = j.dump(4);
pta[15] = strdup(s.c_str());
} else {
std::string s = j.dump();
pta[15] = strdup(s.c_str());
}
}
result->add_row(pta);
unsigned int k;
for (k=0; k<colnum; k++) {

@ -48,6 +48,14 @@ struct MHD_Daemon *Admin_HTTP_Server;
extern ProxySQL_Statistics *GloProxyStats;
/*
int sqlite3_json_init(
sqlite3 *db,
char **pzErrMsg,
const sqlite3_api_routines *pApi
);
*/
#ifdef __APPLE__
#ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0
@ -303,7 +311,7 @@ static int http_handler(void *cls, struct MHD_Connection *connection, const char
#define STATS_SQLITE_TABLE_MYSQL_QUERY_RULES "CREATE TABLE stats_mysql_query_rules (rule_id INTEGER PRIMARY KEY , hits INT NOT NULL)"
#define STATS_SQLITE_TABLE_MYSQL_USERS "CREATE TABLE stats_mysql_users (username VARCHAR PRIMARY KEY , frontend_connections INT NOT NULL , frontend_max_connections INT NOT NULL)"
#define STATS_SQLITE_TABLE_MYSQL_COMMANDS_COUNTERS "CREATE TABLE stats_mysql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)"
#define STATS_SQLITE_TABLE_MYSQL_PROCESSLIST "CREATE TABLE stats_mysql_processlist (ThreadID INT NOT NULL , SessionID INTEGER PRIMARY KEY , user VARCHAR , db VARCHAR , cli_host VARCHAR , cli_port INT , hostgroup INT , l_srv_host VARCHAR , l_srv_port INT , srv_host VARCHAR , srv_port INT , command VARCHAR , time_ms INT NOT NULL , info VARCHAR, status_flags INT)"
#define STATS_SQLITE_TABLE_MYSQL_PROCESSLIST "CREATE TABLE stats_mysql_processlist (ThreadID INT NOT NULL , SessionID INTEGER PRIMARY KEY , user VARCHAR , db VARCHAR , cli_host VARCHAR , cli_port INT , hostgroup INT , l_srv_host VARCHAR , l_srv_port INT , srv_host VARCHAR , srv_port INT , command VARCHAR , time_ms INT NOT NULL , info VARCHAR , status_flags INT , extended_info VARCHAR)"
#define STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL "CREATE TABLE stats_mysql_connection_pool (hostgroup INT , srv_host VARCHAR , srv_port INT , status VARCHAR , ConnUsed INT , ConnFree INT , ConnOK INT , ConnERR INT , MaxConnUsed INT , Queries INT , Queries_GTID_sync INT , Bytes_data_sent INT , Bytes_data_recv INT , Latency_us INT)"
#define STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL_RESET "CREATE TABLE stats_mysql_connection_pool_reset (hostgroup INT , srv_host VARCHAR , srv_port INT , status VARCHAR , ConnUsed INT , ConnFree INT , ConnOK INT , ConnERR INT , MaxConnUsed INT , Queries INT , Queries_GTID_sync INT , Bytes_data_sent INT , Bytes_data_recv INT , Latency_us INT)"
@ -3645,6 +3653,7 @@ ProxySQL_Admin::ProxySQL_Admin() {
variables.telnet_admin_ifaces=NULL;
variables.telnet_stats_ifaces=NULL;
variables.refresh_interval=2000;
variables.mysql_show_processlist_extended = false;
variables.hash_passwords=true; // issue #676
variables.vacuum_stats=true; // issue #1011
variables.admin_read_only=false; // by default, the admin interface accepts writes
@ -3780,6 +3789,8 @@ bool ProxySQL_Admin::init() {
admindb=new SQLite3DB();
admindb->open((char *)"file:mem_admindb?mode=memory&cache=shared", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX);
//sqlite3_enable_load_extension(admindb->get_db(),1);
//sqlite3_auto_extension( (void(*)(void))sqlite3_json_init);
statsdb=new SQLite3DB();
statsdb->open((char *)"file:mem_statsdb?mode=memory&cache=shared", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FULLMUTEX);
@ -4275,6 +4286,9 @@ void ProxySQL_Admin::flush_mysql_variables___database_to_runtime(SQLite3DB *db,
}
} else {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Set variable %s with value \"%s\"\n", r->fields[0],r->fields[1]);
if (strcmp(r->fields[0],(char *)"show_processlist_extended")==0) {
variables.mysql_show_processlist_extended = atoi(r->fields[1]);
}
}
}
GloMTH->commit();
@ -5721,51 +5735,147 @@ void ProxySQL_Admin::stats___mysql_global() {
void ProxySQL_Admin::stats___mysql_processlist() {
if (!GloMTH) return;
mysql_thread___show_processlist_extended = variables.mysql_show_processlist_extended;
SQLite3_result * resultset=GloMTH->SQL3_Processlist();
if (resultset==NULL) return;
sqlite3_stmt *statement1=NULL;
sqlite3_stmt *statement32=NULL;
sqlite3 *mydb3=statsdb->get_db();
char *query1=NULL;
char *query32=NULL;
statsdb->execute("BEGIN");
statsdb->execute("DELETE FROM stats_mysql_processlist");
char *a=(char *)"INSERT OR IGNORE INTO stats_mysql_processlist VALUES ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s','%s')";
query1 = (char *)"INSERT OR IGNORE INTO stats_mysql_processlist VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16)";
query32 = (char *)"INSERT OR IGNORE INTO stats_mysql_processlist VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16), (?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32), (?33, ?34, ?35, ?36, ?37, ?38, ?39, ?40, ?41, ?42, ?43, ?44, ?45, ?46, ?47, ?48), (?49, ?50, ?51, ?52, ?53, ?54, ?55, ?56, ?57, ?58, ?59, ?60, ?61, ?62, ?63, ?64), (?65, ?66, ?67, ?68, ?69, ?70, ?71, ?72, ?73, ?74, ?75, ?76, ?77, ?78, ?79, ?80), (?81, ?82, ?83, ?84, ?85, ?86, ?87, ?88, ?89, ?90, ?91, ?92, ?93, ?94, ?95, ?96), (?97, ?98, ?99, ?100, ?101, ?102, ?103, ?104, ?105, ?106, ?107, ?108, ?109, ?110, ?111, ?112), (?113, ?114, ?115, ?116, ?117, ?118, ?119, ?120, ?121, ?122, ?123, ?124, ?125, ?126, ?127, ?128), (?129, ?130, ?131, ?132, ?133, ?134, ?135, ?136, ?137, ?138, ?139, ?140, ?141, ?142, ?143, ?144), (?145, ?146, ?147, ?148, ?149, ?150, ?151, ?152, ?153, ?154, ?155, ?156, ?157, ?158, ?159, ?160), (?161, ?162, ?163, ?164, ?165, ?166, ?167, ?168, ?169, ?170, ?171, ?172, ?173, ?174, ?175, ?176), (?177, ?178, ?179, ?180, ?181, ?182, ?183, ?184, ?185, ?186, ?187, ?188, ?189, ?190, ?191, ?192), (?193, ?194, ?195, ?196, ?197, ?198, ?199, ?200, ?201, ?202, ?203, ?204, ?205, ?206, ?207, ?208), (?209, ?210, ?211, ?212, ?213, ?214, ?215, ?216, ?217, ?218, ?219, ?220, ?221, ?222, ?223, ?224), (?225, ?226, ?227, ?228, ?229, ?230, ?231, ?232, ?233, ?234, ?235, ?236, ?237, ?238, ?239, ?240), (?241, ?242, ?243, ?244, ?245, ?246, ?247, ?248, ?249, ?250, ?251, ?252, ?253, ?254, ?255, ?256), (?257, ?258, ?259, ?260, ?261, ?262, ?263, ?264, ?265, ?266, ?267, ?268, ?269, ?270, ?271, ?272), (?273, ?274, ?275, ?276, ?277, ?278, ?279, ?280, ?281, ?282, ?283, ?284, ?285, ?286, ?287, ?288), (?289, ?290, ?291, ?292, ?293, ?294, ?295, ?296, ?297, ?298, ?299, ?300, ?301, ?302, ?303, ?304), (?305, ?306, ?307, ?308, ?309, ?310, ?311, ?312, ?313, ?314, ?315, ?316, ?317, ?318, ?319, ?320), (?321, ?322, ?323, ?324, ?325, ?326, ?327, ?328, ?329, ?330, ?331, ?332, ?333, ?334, ?335, ?336), (?337, ?338, ?339, ?340, ?341, ?342, ?343, ?344, ?345, ?346, ?347, ?348, ?349, ?350, ?351, ?352), (?353, ?354, ?355, ?356, ?357, ?358, ?359, ?360, ?361, ?362, ?363, ?364, ?365, ?366, ?367, ?368), (?369, ?370, ?371, ?372, ?373, ?374, ?375, ?376, ?377, ?378, ?379, ?380, ?381, ?382, ?383, ?384), (?385, ?386, ?387, ?388, ?389, ?390, ?391, ?392, ?393, ?394, ?395, ?396, ?397, ?398, ?399, ?400), (?401, ?402, ?403, ?404, ?405, ?406, ?407, ?408, ?409, ?410, ?411, ?412, ?413, ?414, ?415, ?416), (?417, ?418, ?419, ?420, ?421, ?422, ?423, ?424, ?425, ?426, ?427, ?428, ?429, ?430, ?431, ?432), (?433, ?434, ?435, ?436, ?437, ?438, ?439, ?440, ?441, ?442, ?443, ?444, ?445, ?446, ?447, ?448), (?449, ?450, ?451, ?452, ?453, ?454, ?455, ?456, ?457, ?458, ?459, ?460, ?461, ?462, ?463, ?464), (?465, ?466, ?467, ?468, ?469, ?470, ?471, ?472, ?473, ?474, ?475, ?476, ?477, ?478, ?479, ?480), (?481, ?482, ?483, ?484, ?485, ?486, ?487, ?488, ?489, ?490, ?491, ?492, ?493, ?494, ?495, ?496), (?497, ?498, ?499, ?500, ?501, ?502, ?503, ?504, ?505, ?506, ?507, ?508, ?509, ?510, ?511, ?512)";
rc=sqlite3_prepare_v2(mydb3, query1, -1, &statement1, 0);
assert(rc==SQLITE_OK);
rc=sqlite3_prepare_v2(mydb3, query32, -1, &statement32, 0);
assert(rc==SQLITE_OK);
/* for reference
CREATE TABLE stats_mysql_processlist (
ThreadID INT NOT NULL,
SessionID INTEGER PRIMARY KEY,
user VARCHAR,
db VARCHAR,
cli_host VARCHAR,
cli_port INT,
hostgroup INT,
l_srv_host VARCHAR,
l_srv_port INT,
srv_host VARCHAR,
srv_port INT,
command VARCHAR,
time_ms INT NOT NULL,
info VARCHAR,
status_flags INT,
extended_info VARCHAR)
*/
int row_idx=0;
int max_bulk_row_idx=resultset->rows_count/32;
max_bulk_row_idx=max_bulk_row_idx*32;
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
int arg_len=0;
char *o_info=NULL;
for (int i=0; i<15; i++) { // info (field 13) is left out! See #746
if(i == 13) continue;
if (r->fields[i])
arg_len+=strlen(r->fields[i]);
}
if (r->fields[13]) { // this is just for info column (field 13) . See #746
o_info=escape_string_single_quotes(r->fields[13],false);
int l=strlen(o_info)+4;
arg_len+=l;
}
char *query=(char *)malloc(strlen(a)+arg_len+32);
sprintf(query,a,
(r->fields[0] ? r->fields[0] : ""),
(r->fields[1] ? r->fields[1] : ""),
(r->fields[2] ? r->fields[2] : ""),
(r->fields[3] ? r->fields[3] : ""),
(r->fields[4] ? r->fields[4] : ""),
(r->fields[5] ? r->fields[5] : ""),
(r->fields[6] ? r->fields[6] : ""),
(r->fields[7] ? r->fields[7] : ""),
(r->fields[8] ? r->fields[8] : ""),
(r->fields[9] ? r->fields[9] : ""),
(r->fields[10] ? r->fields[10] : ""),
(r->fields[11] ? r->fields[11] : ""),
(r->fields[12] ? r->fields[12] : ""),
(r->fields[13] ? o_info : ""),
(r->fields[14] ? r->fields[14] : "")
);
statsdb->execute(query);
free(query);
if (o_info) {
if (o_info!=r->fields[13]) { // there was a copy
free(o_info);
SQLite3_row *r1=*it;
int idx=row_idx%32;
if (row_idx<max_bulk_row_idx) { // bulk
rc=sqlite3_bind_int64(statement32, (idx*16)+1, atoll(r1->fields[0])); assert(rc==SQLITE_OK); // ThreadID
rc=sqlite3_bind_int64(statement32, (idx*16)+2, atoll(r1->fields[1])); assert(rc==SQLITE_OK); // SessionID
rc=sqlite3_bind_text(statement32, (idx*16)+3, r1->fields[2], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // user
rc=sqlite3_bind_text(statement32, (idx*16)+4, r1->fields[3], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // db
rc=sqlite3_bind_text(statement32, (idx*16)+5, r1->fields[4], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // cli_host
if (r1->fields[5]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+6, atoll(r1->fields[5])); assert(rc==SQLITE_OK); // cli_port
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+6); assert(rc==SQLITE_OK);
}
if (r1->fields[6]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+7, atoll(r1->fields[6])); assert(rc==SQLITE_OK); // hostgroup
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+8); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement32, (idx*16)+8, r1->fields[7], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // l_srv_host
if (r1->fields[8]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+9, atoll(r1->fields[8])); assert(rc==SQLITE_OK); // l_srv_port
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+9); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement32, (idx*16)+10, r1->fields[9], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // srv_host
if (r1->fields[10]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+11, atoll(r1->fields[10])); assert(rc==SQLITE_OK); // srv_port
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+11); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement32, (idx*16)+12, r1->fields[11], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // command
if (r1->fields[12]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+13, atoll(r1->fields[12])); assert(rc==SQLITE_OK); // time_ms
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+13); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement32, (idx*16)+14, r1->fields[13], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // info
if (r1->fields[14]) {
rc=sqlite3_bind_int64(statement32, (idx*16)+15, atoll(r1->fields[14])); assert(rc==SQLITE_OK); // status_flags
} else {
rc = sqlite3_bind_null(statement32, (idx*16)+15); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement32, (idx*16)+16, r1->fields[15], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // extended_info
if (idx==31) {
SAFE_SQLITE3_STEP2(statement32);
rc=sqlite3_clear_bindings(statement32); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement32); assert(rc==SQLITE_OK);
}
} else { // single row
rc=sqlite3_bind_int64(statement1, 1, atoll(r1->fields[0])); assert(rc==SQLITE_OK); // ThreadID
rc=sqlite3_bind_int64(statement1, 2, atoll(r1->fields[1])); assert(rc==SQLITE_OK); // SessionID
rc=sqlite3_bind_text(statement1, 3, r1->fields[2], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // user
rc=sqlite3_bind_text(statement1, 4, r1->fields[3], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // db
rc=sqlite3_bind_text(statement1, 5, r1->fields[4], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // cli_host
if (r1->fields[5]) {
rc=sqlite3_bind_int64(statement1, 6, atoll(r1->fields[5])); assert(rc==SQLITE_OK); // cli_port
} else {
rc = sqlite3_bind_null(statement1, 6); assert(rc==SQLITE_OK);
}
if (r1->fields[6]) {
rc=sqlite3_bind_int64(statement1, 7, atoll(r1->fields[6])); assert(rc==SQLITE_OK); // hostgroup
} else {
rc = sqlite3_bind_null(statement1, 8); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement1, 8, r1->fields[7], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // l_srv_host
if (r1->fields[8]) {
rc=sqlite3_bind_int64(statement1, 9, atoll(r1->fields[8])); assert(rc==SQLITE_OK); // l_srv_port
} else {
rc = sqlite3_bind_null(statement1, 9); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement1, 10, r1->fields[9], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // srv_host
if (r1->fields[10]) {
rc=sqlite3_bind_int64(statement1, 11, atoll(r1->fields[10])); assert(rc==SQLITE_OK); // srv_port
} else {
rc = sqlite3_bind_null(statement1, 11); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement1, 12, r1->fields[11], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // command
if (r1->fields[12]) {
rc=sqlite3_bind_int64(statement1, 13, atoll(r1->fields[12])); assert(rc==SQLITE_OK); // time_ms
} else {
rc = sqlite3_bind_null(statement1, 13); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement1, 14, r1->fields[13], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // info
if (r1->fields[14]) {
rc=sqlite3_bind_int64(statement1, 15, atoll(r1->fields[14])); assert(rc==SQLITE_OK); // status_flags
} else {
rc = sqlite3_bind_null(statement1, 15); assert(rc==SQLITE_OK);
}
rc=sqlite3_bind_text(statement1, 16, r1->fields[15], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // extended_info
SAFE_SQLITE3_STEP2(statement1);
rc=sqlite3_clear_bindings(statement1); assert(rc==SQLITE_OK);
rc=sqlite3_reset(statement1); assert(rc==SQLITE_OK);
}
row_idx++;
}
sqlite3_finalize(statement1);
sqlite3_finalize(statement32);
statsdb->execute("COMMIT");
delete resultset;
}

Loading…
Cancel
Save