diff --git a/include/MySQL_Data_Stream.h b/include/MySQL_Data_Stream.h index 48c941681..b65b3d280 100644 --- a/include/MySQL_Data_Stream.h +++ b/include/MySQL_Data_Stream.h @@ -188,12 +188,14 @@ class MySQL_Data_Stream void attach_connection(MySQL_Connection *mc) { statuses.myconnpoll_get++; myconn=mc; + myconn->statuses.myconnpoll_get++; mc->myds=this; } // safe way to detach a MySQL Connection void detach_connection() { assert(myconn); + myconn->statuses.myconnpoll_put++; statuses.myconnpoll_put++; myconn->myds=NULL; myconn=NULL; diff --git a/include/MySQL_HostGroups_Manager.h b/include/MySQL_HostGroups_Manager.h index cb94a90a0..800cc7c85 100644 --- a/include/MySQL_HostGroups_Manager.h +++ b/include/MySQL_HostGroups_Manager.h @@ -537,6 +537,7 @@ class MySQL_HostGroups_Manager { void drop_all_idle_connections(); int get_multiple_idle_connections(int, unsigned long long, MySQL_Connection **, int); SQLite3_result * SQL3_Connection_Pool(bool _reset); + SQLite3_result * SQL3_Free_Connections(); void push_MyConn_to_pool(MySQL_Connection *, bool _lock=true); void push_MyConn_to_pool_array(MySQL_Connection **, unsigned int); diff --git a/include/mysql_connection.h b/include/mysql_connection.h index fb3b4771d..2b5aead88 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -84,6 +84,14 @@ class MySQL_Connection { MySQL_Connection_userinfo *userinfo; MySQL_Data_Stream *myds; enum MySerStatus server_status; // this to solve a side effect of #774 + + bytes_stats_t bytes_info; // bytes statistics + struct { + unsigned long long questions; + unsigned long long myconnpoll_get; + unsigned long long myconnpoll_put; + } statuses; + unsigned long largest_query_length; uint32_t status_flags; int async_exit_status; // exit status of MariaDB Client Library Non blocking API diff --git a/include/proxysql_admin.h b/include/proxysql_admin.h index 4228699e6..6bf34d740 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -243,6 +243,7 @@ class ProxySQL_Admin { //void stats___mysql_query_digests_reset(); void stats___mysql_commands_counters(); void stats___mysql_processlist(); + void stats___mysql_free_connections(); void stats___mysql_connection_pool(bool _reset); void stats___mysql_errors(bool reset); void stats___memory_metrics(); diff --git a/lib/MySQL_HostGroups_Manager.cpp b/lib/MySQL_HostGroups_Manager.cpp index ac27ce4f7..fbbb5d220 100644 --- a/lib/MySQL_HostGroups_Manager.cpp +++ b/lib/MySQL_HostGroups_Manager.cpp @@ -2636,6 +2636,115 @@ void MySQL_HostGroups_Manager::set_incoming_galera_hostgroups(SQLite3_result *s) incoming_galera_hostgroups=s; } +SQLite3_result * MySQL_HostGroups_Manager::SQL3_Free_Connections() { + const int colnum=13; + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 4, "Dumping Free Connections in Pool\n"); + SQLite3_result *result=new SQLite3_result(colnum); + result->add_column_definition(SQLITE_TEXT,"fd"); + result->add_column_definition(SQLITE_TEXT,"hostgroup"); + result->add_column_definition(SQLITE_TEXT,"srv_host"); + result->add_column_definition(SQLITE_TEXT,"srv_port"); + result->add_column_definition(SQLITE_TEXT,"user"); + result->add_column_definition(SQLITE_TEXT,"schema"); + result->add_column_definition(SQLITE_TEXT,"init_connect"); + result->add_column_definition(SQLITE_TEXT,"time_zone"); + result->add_column_definition(SQLITE_TEXT,"sql_mode"); + result->add_column_definition(SQLITE_TEXT,"autocommit"); + result->add_column_definition(SQLITE_TEXT,"idle_ms"); + result->add_column_definition(SQLITE_TEXT,"statistics"); + result->add_column_definition(SQLITE_TEXT,"mysql_info"); + unsigned long long curtime = monotonic_time(); + wrlock(); + int i,j, k, l; + for (i=0; i<(int)MyHostGroups->len; i++) { + MyHGC *myhgc=(MyHGC *)MyHostGroups->index(i); + for (j=0; j<(int)myhgc->mysrvs->cnt(); j++) { + MySrvC *mysrvc=(MySrvC *)myhgc->mysrvs->servers->index(j); + if (mysrvc->status!=MYSQL_SERVER_STATUS_ONLINE) { + proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 5, "Server %s:%d is not online\n", mysrvc->address, mysrvc->port); + mysrvc->ConnectionsFree->drop_all_connections(); + } + // drop idle connections if beyond max_connection + while (mysrvc->ConnectionsFree->conns_length() && mysrvc->ConnectionsUsed->conns_length()+mysrvc->ConnectionsFree->conns_length() > mysrvc->max_connections) { + //MySQL_Connection *conn=(MySQL_Connection *)mysrvc->ConnectionsFree->conns->remove_index_fast(0); + MySQL_Connection *conn=mysrvc->ConnectionsFree->remove(0); + delete conn; + } + char buf[1024]; + for (l=0; lConnectionsFree->conns_length(); l++) { + char **pta=(char **)malloc(sizeof(char *)*colnum); + MySQL_Connection *conn = mysrvc->ConnectionsFree->index(l); + sprintf(buf,"%d", conn->fd); + pta[0]=strdup(buf); + sprintf(buf,"%d", (int)myhgc->hid); + pta[1]=strdup(buf); + pta[2]=strdup(mysrvc->address); + sprintf(buf,"%d", mysrvc->port); + pta[3]=strdup(buf); + pta[4] = strdup(conn->userinfo->username); + pta[5] = strdup(conn->userinfo->schemaname); + pta[6] = NULL; + if (conn->options.init_connect) { + pta[6] = strdup(conn->options.init_connect); + } + pta[7] = NULL; + if (conn->options.time_zone) { + pta[7] = strdup(conn->options.time_zone); + } + pta[8] = NULL; + if (conn->options.sql_mode) { + pta[8] = strdup(conn->options.sql_mode); + } + sprintf(buf,"%d", conn->options.autocommit); + pta[9]=strdup(buf); + sprintf(buf,"%llu", (curtime-conn->last_time_used)/1000); + pta[10]=strdup(buf); + { + json j; + j["bytes_recv"] = conn->bytes_info.bytes_recv; + j["bytes_sent"] = conn->bytes_info.bytes_sent; + j["myconnpoll_get"] = conn->statuses.myconnpoll_get; + j["myconnpoll_put"] = conn->statuses.myconnpoll_put; + j["questions"] = conn->statuses.questions; + string s = j.dump(); + pta[11] = strdup(s.c_str()); + } + { + MYSQL *_my = conn->mysql; + json j; + j["host"] = _my->host; + j["host_info"] = _my->host_info; + j["port"] = _my->port; + j["server_version"] = _my->server_version; + j["user"] = _my->user; + j["unix_socket"] = (_my->unix_socket ? _my->unix_socket : ""); + j["db"] = (_my->db ? _my->db : ""); + j["affected_rows"] = _my->affected_rows; + j["insert_id"] = _my->insert_id; + j["server_status"] = _my->server_status; + j["charset"] = _my->charset->nr; + j["options"]["charset_name"] = _my->options.charset_name; + j["options"]["use_ssl"] = _my->options.use_ssl; + j["net"]["last_errno"] = _my->net.last_errno; + j["net"]["fd"] = _my->net.fd; + j["net"]["max_packet_size"] = _my->net.max_packet_size; + j["net"]["sqlstate"] = _my->net.sqlstate; + string s = j.dump(); + pta[12] = strdup(s.c_str()); + } + result->add_row(pta); + for (k=0; kbytes_info.bytes_sent; if (_myds->myconn) { MySQL_Connection * _myconn = _myds->myconn; + j["backends"][i]["conn"]["bytes_recv"] = _myconn->bytes_info.bytes_recv; + j["backends"][i]["conn"]["bytes_sent"] = _myconn->bytes_info.bytes_sent; + j["backends"][i]["conn"]["questions"] = _myconn->statuses.questions; + j["backends"][i]["conn"]["myconnpoll_get"] = _myconn->statuses.myconnpoll_get; + j["backends"][i]["conn"]["myconnpoll_put"] = _myconn->statuses.myconnpoll_put; 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 diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index bf8d5908c..53f7df93b 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -316,6 +316,8 @@ static int http_handler(void *cls, struct MHD_Connection *connection, const char #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)" +#define STATS_SQLITE_TABLE_MYSQL_FREE_CONNECTIONS "CREATE TABLE stats_mysql_free_connections (fd INT NOT NULL , hostgroup INT NOT NULL , srv_host VARCHAR NOT NULL , srv_port INT NOT NULL , user VARCHAR NOT NULL , schema VARCHAR , init_connect VARCHAR , time_zone VARCHAR , sql_mode VARCHAR , autocommit VARCHAR , idle_ms INT , statistics VARCHAR , mysql_info VARCHAR)" + #define STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST "CREATE TABLE stats_mysql_query_digest (hostgroup INT , schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , PRIMARY KEY(hostgroup, schemaname, username, client_address, digest))" #define STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST_RESET "CREATE TABLE stats_mysql_query_digest_reset (hostgroup INT , schemaname VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , PRIMARY KEY(hostgroup, schemaname, username, client_address, digest))" @@ -2029,6 +2031,7 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign bool ret=false; bool refresh=false; bool stats_mysql_processlist=false; + bool stats_mysql_free_connections=false; bool stats_mysql_connection_pool=false; bool stats_mysql_connection_pool_reset=false; bool stats_mysql_query_digest=false; @@ -2092,6 +2095,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign if (strstr(query_no_space,"stats_mysql_connection_pool")) { stats_mysql_connection_pool=true; refresh=true; } } + if (strstr(query_no_space,"stats_mysql_free_connections")) + { stats_mysql_free_connections=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_commands_counters")) { stats_mysql_commands_counters=true; refresh=true; } if (strstr(query_no_space,"stats_mysql_query_rules")) @@ -2185,6 +2190,8 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign if (stats_mysql_connection_pool) stats___mysql_connection_pool(false); } + if (stats_mysql_free_connections) + stats___mysql_free_connections(); if (stats_mysql_global) stats___mysql_global(); if (stats_memory_metrics) @@ -2278,7 +2285,7 @@ bool ProxySQL_Admin::GenericRefreshStatistics(const char *query_no_space, unsign stats_mysql_query_digest || stats_mysql_query_digest_reset || stats_mysql_errors || stats_mysql_errors_reset || stats_mysql_global || stats_memory_metrics || stats_mysql_commands_counters || stats_mysql_query_rules || stats_mysql_users || - stats_mysql_gtid_executed + stats_mysql_gtid_executed || stats_mysql_free_connections ) { ret = true; } @@ -3292,6 +3299,7 @@ void ProxySQL_Admin::vacuum_stats(bool is_admin) { } if (is_admin) { admindb->execute("DELETE FROM stats.stats_mysql_commands_counters"); + admindb->execute("DELETE FROM stats.stats_mysql_free_connections"); admindb->execute("DELETE FROM stats.stats_mysql_connection_pool"); admindb->execute("DELETE FROM stats.stats_mysql_connection_pool_reset"); admindb->execute("DELETE FROM stats.stats_mysql_prepared_statements_info"); @@ -3306,6 +3314,7 @@ void ProxySQL_Admin::vacuum_stats(bool is_admin) { admindb->execute("VACUUM stats"); } else { statsdb->execute("DELETE FROM stats_mysql_commands_counters"); + statsdb->execute("DELETE FROM stats_mysql_free_connections"); statsdb->execute("DELETE FROM stats_mysql_connection_pool"); statsdb->execute("DELETE FROM stats_mysql_connection_pool_reset"); statsdb->execute("DELETE FROM stats_mysql_prepared_statements_info"); @@ -3878,6 +3887,7 @@ bool ProxySQL_Admin::init() { insert_into_tables_defs(tables_defs_stats,"stats_mysql_processlist", STATS_SQLITE_TABLE_MYSQL_PROCESSLIST); insert_into_tables_defs(tables_defs_stats,"stats_mysql_connection_pool", STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL); insert_into_tables_defs(tables_defs_stats,"stats_mysql_connection_pool_reset", STATS_SQLITE_TABLE_MYSQL_CONNECTION_POOL_RESET); + insert_into_tables_defs(tables_defs_stats,"stats_mysql_free_connections", STATS_SQLITE_TABLE_MYSQL_FREE_CONNECTIONS); insert_into_tables_defs(tables_defs_stats,"stats_mysql_query_digest", STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST); insert_into_tables_defs(tables_defs_stats,"stats_mysql_query_digest_reset", STATS_SQLITE_TABLE_MYSQL_QUERY_DIGEST_RESET); insert_into_tables_defs(tables_defs_stats,"stats_mysql_errors", STATS_SQLITE_TABLE_MYSQL_ERRORS); @@ -5744,8 +5754,6 @@ void ProxySQL_Admin::stats___mysql_processlist() { sqlite3 *mydb3=statsdb->get_db(); char *query1=NULL; char *query32=NULL; - statsdb->execute("BEGIN"); - statsdb->execute("DELETE FROM stats_mysql_processlist"); 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)"; @@ -5775,6 +5783,9 @@ CREATE TABLE stats_mysql_processlist ( extended_info VARCHAR) */ + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_mysql_processlist"); + int row_idx=0; int max_bulk_row_idx=resultset->rows_count/32; max_bulk_row_idx=max_bulk_row_idx*32; @@ -5907,6 +5918,103 @@ void ProxySQL_Admin::stats___mysql_connection_pool(bool _reset) { delete resultset; } +void ProxySQL_Admin::stats___mysql_free_connections() { + + if (!MyHGM) return; + SQLite3_result * resultset=MyHGM->SQL3_Free_Connections(); + if (resultset==NULL) return; + + sqlite3_stmt *statement1=NULL; + sqlite3_stmt *statement32=NULL; + sqlite3 *mydb3=statsdb->get_db(); + char *query1=NULL; + char *query32=NULL; + + query1 = (char *)"INSERT INTO stats_mysql_free_connections VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)"; + query32 = (char *)"INSERT INTO stats_mysql_free_connections 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)"; + + + 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); + + statsdb->execute("BEGIN"); + statsdb->execute("DELETE FROM stats_mysql_free_connections"); + + 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::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) { + SQLite3_row *r1=*it; + int idx=row_idx%32; + if (row_idxfields[0])); assert(rc==SQLITE_OK); // FD + rc=sqlite3_bind_int64(statement32, (idx*13)+2, atoll(r1->fields[1])); assert(rc==SQLITE_OK); // hostgroup + rc=sqlite3_bind_text(statement32, (idx*13)+3, r1->fields[2], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // srv_host + if (r1->fields[3]) { + rc=sqlite3_bind_int64(statement32, (idx*13)+4, atoll(r1->fields[3])); assert(rc==SQLITE_OK); // srv_port + } else { + rc = sqlite3_bind_null(statement32, (idx*13)+4); assert(rc==SQLITE_OK); + } + rc=sqlite3_bind_text(statement32, (idx*13)+5, r1->fields[4], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // user + rc=sqlite3_bind_text(statement32, (idx*13)+6, r1->fields[5], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // db + rc=sqlite3_bind_text(statement32, (idx*13)+7, r1->fields[6], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // init_connect + rc=sqlite3_bind_text(statement32, (idx*13)+8, r1->fields[7], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // time_zone + rc=sqlite3_bind_text(statement32, (idx*13)+9, r1->fields[8], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // sql_mode + if (r1->fields[9]) { + rc=sqlite3_bind_int64(statement32, (idx*13)+10, atoll(r1->fields[9])); assert(rc==SQLITE_OK); // autocommit + } else { + rc = sqlite3_bind_null(statement32, (idx*13)+10); assert(rc==SQLITE_OK); + } + if (r1->fields[10]) { + rc=sqlite3_bind_int64(statement32, (idx*13)+11, atoll(r1->fields[10])); assert(rc==SQLITE_OK); // idle_ms + } else { + rc = sqlite3_bind_null(statement32, (idx*13)+11); assert(rc==SQLITE_OK); + } + rc=sqlite3_bind_text(statement32, (idx*13)+12, r1->fields[11], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // statistics + rc=sqlite3_bind_text(statement32, (idx*13)+13, r1->fields[12], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // mysql_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); // FD + rc=sqlite3_bind_int64(statement1, 2, atoll(r1->fields[1])); assert(rc==SQLITE_OK); // hostgroup + rc=sqlite3_bind_text(statement1, 3, r1->fields[2], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // srv_host + if (r1->fields[3]) { + rc=sqlite3_bind_int64(statement1, 4, atoll(r1->fields[3])); assert(rc==SQLITE_OK); // srv_port + } else { + rc = sqlite3_bind_null(statement1, 4); assert(rc==SQLITE_OK); + } + rc=sqlite3_bind_text(statement1, 5, r1->fields[4], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // user + rc=sqlite3_bind_text(statement1, 6, r1->fields[5], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // db + rc=sqlite3_bind_text(statement1, 7, r1->fields[6], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // init_connect + rc=sqlite3_bind_text(statement1, 8, r1->fields[7], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // time_zone + rc=sqlite3_bind_text(statement1, 9, r1->fields[8], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // sql_mode + if (r1->fields[9]) { + rc=sqlite3_bind_int64(statement1, 10, atoll(r1->fields[9])); assert(rc==SQLITE_OK); // autocommit + } else { + rc = sqlite3_bind_null(statement1, 10); assert(rc==SQLITE_OK); + } + if (r1->fields[10]) { + rc=sqlite3_bind_int64(statement1, 11, atoll(r1->fields[10])); assert(rc==SQLITE_OK); // idle_ms + } 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); // statistics + rc=sqlite3_bind_text(statement1, 13, r1->fields[12], -1, SQLITE_TRANSIENT); assert(rc==SQLITE_OK); // mysql_info + SAFE_SQLITE3_STEP2(statement1); + rc=sqlite3_clear_bindings(statement1); assert(rc==SQLITE_OK); + rc=sqlite3_reset(statement1); assert(rc==SQLITE_OK); + } + row_idx++; + } + statsdb->execute("COMMIT"); + delete resultset; +} + void ProxySQL_Admin::stats___mysql_commands_counters() { if (!GloQPro) return; SQLite3_result * resultset=GloQPro->get_stats_commands_counters(); diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index ae3b366cf..a74f4b0df 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -230,6 +230,12 @@ MySQL_Connection::MySQL_Connection() { 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 + bytes_info.bytes_recv = 0; + bytes_info.bytes_sent = 0; + statuses.questions = 0; + statuses.myconnpoll_get = 0; + statuses.myconnpoll_put = 0; + }; MySQL_Connection::~MySQL_Connection() { @@ -791,8 +797,10 @@ handler_again: real_query_start(); __sync_fetch_and_add(&parent->queries_sent,1); __sync_fetch_and_add(&parent->bytes_sent,query.length); + statuses.questions++; myds->sess->thread->status_variables.queries_backends_bytes_sent+=query.length; myds->bytes_info.bytes_sent += query.length; + bytes_info.bytes_sent += query.length; if (myds->sess->with_gtid == true) { __sync_fetch_and_add(&parent->queries_gtid_sync,1); } @@ -825,6 +833,7 @@ handler_again: __sync_fetch_and_add(&parent->bytes_sent,query.length); myds->sess->thread->status_variables.queries_backends_bytes_sent+=query.length; myds->bytes_info.bytes_sent += query.length; + bytes_info.bytes_sent += query.length; if (async_exit_status) { next_event(ASYNC_STMT_PREPARE_CONT); } else { @@ -858,6 +867,7 @@ handler_again: __sync_fetch_and_add(&parent->bytes_sent,query.stmt_meta->size); myds->sess->thread->status_variables.queries_backends_bytes_sent+=query.stmt_meta->size; myds->bytes_info.bytes_sent += query.stmt_meta->size; + bytes_info.bytes_sent += query.stmt_meta->size; if (async_exit_status) { next_event(ASYNC_STMT_EXECUTE_CONT); } else { @@ -921,6 +931,7 @@ handler_again: __sync_fetch_and_add(&parent->bytes_recv,total_size); myds->sess->thread->status_variables.queries_backends_bytes_recv+=total_size; myds->bytes_info.bytes_recv += total_size; + bytes_info.bytes_recv += total_size; } } /* @@ -1044,6 +1055,7 @@ handler_again: __sync_fetch_and_add(&parent->bytes_recv,br); myds->sess->thread->status_variables.queries_backends_bytes_recv+=br; myds->bytes_info.bytes_recv += br; + bytes_info.bytes_recv += br; processed_bytes+=br; // issue #527 : this variable will store the amount of bytes processed during this event if ( (processed_bytes > (unsigned int)mysql_thread___threshold_resultset_size*8)