Add checksum function to SQLite3_result

pull/493/head
ethanblackburn 10 years ago
parent d91ed1d467
commit 2ab4833498

@ -120,8 +120,6 @@ class ProxySQL_Admin {
void load_mysql_variables_to_runtime() { flush_mysql_variables___database_to_runtime(admindb, true); }
void save_mysql_variables_from_runtime() { flush_mysql_variables___runtime_to_database(admindb, true, true, false); }
char *table_checksum(char *tablename, char *source, char **err);
void stats___mysql_query_rules();
void stats___mysql_query_digests();
void stats___mysql_query_digests_reset();

@ -3,8 +3,6 @@
#include "proxysql.h"
#include "cpp.h"
//struct _sqlite3row_t {
//};
@ -85,11 +83,15 @@ class SQLite3_result {
public:
int columns;
int rows_count;
char *checksum();
int64_t raw_checksum();
std::vector<SQLite3_column *> column_definition;
std::vector<SQLite3_row *> rows;
SQLite3_result() {
columns=0;
};
void add_column_definition(int a, const char *b) {
SQLite3_column *cf=new SQLite3_column(a,b);
column_definition.push_back(cf);
@ -111,6 +113,7 @@ class SQLite3_result {
rows_count++;
return SQLITE_ROW;
};
SQLite3_result(sqlite3_stmt *stmt) {
rows_count=0;
columns=sqlite3_column_count(stmt);

@ -1116,6 +1116,7 @@ SQLite3_result * ProxySQL_Admin::generate_show_table_status(const char *tablenam
*err=strdup(error);
free(error);
if (resultset) delete resultset;
free(tn);
return NULL;
}
@ -1173,24 +1174,6 @@ SQLite3_result * ProxySQL_Admin::generate_show_table_status(const char *tablenam
return result;
}
char *parse_destination(char *query){
char *method=(char *)"TO";
char *pch=strstr(query, method);
if (pch){
return pch+3;
}
return NULL;
}
char *parse_source(char *query){
char *method=(char *)"FROM";
char *pch=strstr(query, method);
if (pch){
return pch+5;
}
return NULL;
}
void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *pkt) {
char *error=NULL;
@ -1356,27 +1339,92 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p
}
}
if(!strncasecmp("CHECKSUM TABLE ", query_no_space, 15)){
if(!strncasecmp("CHECKSUM ", query_no_space, 9)){
proxy_debug(PROXYSQL_DEBUG_ADMIN, 4, "Received CHECKSUM command\n");
char *source=parse_source(query_no_space);
char *tablename;
if (source){
int tablename_length=query_no_space_length-strlen(source)-20;
tablename=(char *)malloc(tablename_length);
strncpy(tablename, query_no_space+15, tablename_length);
} else {
tablename=query_no_space+15;
}
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SQLite3_result *resultset=NULL;
char *tablename=NULL;
char *error=NULL;
char *checksum_result=SPA->table_checksum(tablename, source, &error);
int affected_rows=0;
int cols=0;
if (strlen(query_no_space)==strlen("CHECKSUM DISK MYSQL SERVERS") && !strncasecmp("CHECKSUM DISK MYSQL SERVERS", query_no_space, strlen(query_no_space))){
char *q=(char *)"SELECT * FROM mysql_servers ORDER BY hostgroup_id, hostname, port";
tablename=(char *)"MYSQL SERVERS";
SPA->configdb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if (strlen(query_no_space)==strlen("CHECKSUM DISK MYSQL USERS") && !strncasecmp("CHECKSUM DISK MYSQL USERS", query_no_space, strlen(query_no_space))){
char *q=(char *)"SELECT * FROM mysql_users ORDER BY username";
tablename=(char *)"MYSQL USERS";
SPA->configdb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if (strlen(query_no_space)==strlen("CHECKSUM DISK MYSQL QUERY RULES") && !strncasecmp("CHECKSUM DISK MYSQL QUERY RULES", query_no_space, strlen(query_no_space))){
char *q=(char *)"SELECT * FROM mysql_query_rules ORDER BY rule_id";
tablename=(char *)"MYSQL QUERY RULES";
SPA->configdb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if (strlen(query_no_space)==strlen("CHECKSUM DISK MYSQL VARIABLES") && !strncasecmp("CHECKSUM DISK MYSQL VARIABLES", query_no_space, strlen(query_no_space))){
char *q=(char *)"SELECT * FROM global_variables ORDER BY variable_name";
tablename=(char *)"MYSQL VARIABLES";
SPA->configdb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if ((strlen(query_no_space)==strlen("CHECKSUM MEMORY MYSQL SERVERS") && !strncasecmp("CHECKSUM MEMORY MYSQL SERVERS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MEM MYSQL SERVERS") && !strncasecmp("CHECKSUM MEM MYSQL SERVERS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MYSQL SERVERS") && !strncasecmp("CHECKSUM MYSQL SERVERS", query_no_space, strlen(query_no_space)))){
char *q=(char *)"SELECT * FROM mysql_servers ORDER BY hostgroup_id, hostname, port";
tablename=(char *)"MYSQL SERVERS";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if ((strlen(query_no_space)==strlen("CHECKSUM MEMORY MYSQL USERS") && !strncasecmp("CHECKSUM MEMORY MYSQL USERS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MEM MYSQL USERS") && !strncasecmp("CHECKSUM MEM MYSQL USERS", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MYSQL USERS") && !strncasecmp("CHECKSUM MYSQL USERS", query_no_space, strlen(query_no_space)))){
char *q=(char *)"SELECT * FROM mysql_users ORDER BY username";
tablename=(char *)"MYSQL USERS";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if ((strlen(query_no_space)==strlen("CHECKSUM MEMORY MYSQL QUERY RULES") && !strncasecmp("CHECKSUM MEMORY MYSQL QUERY RULES", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MEM MYSQL QUERY RULES") && !strncasecmp("CHECKSUM MEM MYSQL QUERY RULES", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MYSQL QUERY RULES") && !strncasecmp("CHECKSUM MYSQL QUERY RULES", query_no_space, strlen(query_no_space)))){
char *q=(char *)"SELECT * FROM mysql_query_rules ORDER BY rule_id";
tablename=(char *)"MYSQL QUERY RULES";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if ((strlen(query_no_space)==strlen("CHECKSUM MEMORY MYSQL VARIABLES") && !strncasecmp("CHECKSUM MEMORY MYSQL VARIABLES", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MEM MYSQL VARIABLES") && !strncasecmp("CHECKSUM MEM MYSQL VARIABLES", query_no_space, strlen(query_no_space)))
||
(strlen(query_no_space)==strlen("CHECKSUM MYSQL VARIABLES") && !strncasecmp("CHECKSUM MYSQL VARIABLES", query_no_space, strlen(query_no_space)))){
char *q=(char *)"SELECT * FROM global_variables ORDER BY variable_name";
tablename=(char *)"MYSQL VARIABLES";
SPA->admindb->execute_statement(q, &error, &cols, &affected_rows, &resultset);
}
if (error) {
SPA->send_MySQL_ERR(&sess->client_myds->myprot, error);
} else {
proxy_error("Error: %s\n", error);
char buf[1024];
sprintf(buf,"%s", error);
SPA->send_MySQL_ERR(&sess->client_myds->myprot, buf);
run_query=false;
} else if (resultset) {
char *q=(char *)"SELECT '%s' AS 'table', '%s' AS 'checksum'";
query=(char *)malloc(strlen(q)+strlen(tablename)+strlen(checksum_result)+20);
sprintf(query,q,tablename,checksum_result);
goto __run_query;
char *checksum=(char *)resultset->checksum();
query=(char *)malloc(strlen(q)+strlen(tablename)+strlen(checksum)+1);
sprintf(query,q,tablename,checksum);
}
goto __run_query;
}
if (strncasecmp("SHOW ", query_no_space, 5)) {
@ -2300,68 +2348,6 @@ void ProxySQL_Admin::flush_mysql_variables___runtime_to_database(SQLite3DB *db,
free(varnames);
}
char *ProxySQL_Admin::table_checksum(char *tablename, char *source, char **err){
char *error=NULL;
int cols=0;
int affected_rows=0;
char *q1=(char *)"SELECT * FROM %s ORDER BY rowid";
char *q2=(char *)malloc(strlen(q1)+strlen(tablename));
SQLite3_result *resultset=NULL;
sprintf(q2, q1, tablename);
if (source && !strncasecmp(source,"DISK", 4)){
configdb->execute_statement(q2, &error, &cols, &affected_rows, &resultset);
} else{
admindb->execute_statement(q2, &error, &cols, &affected_rows, &resultset);
}
if (error) {
*err=strdup(error);
proxy_error("Error on %s: %s\n", q2, error);
free(error);
return (char *)"NULL";
} else if (resultset->rows_count>0) {
int tot_l=0;
int tot_s=0;
char *large_buff[resultset->rows_count];
int column_length=resultset->columns;
for (std::vector<SQLite3_row *>::iterator it = resultset->rows.begin() ; it != resultset->rows.end(); ++it) {
SQLite3_row *r=*it;
char *buffs[column_length];
int local_s=0;
for (int i=0; i<column_length;i++){
if (r->fields[i]){
int l=strlen(r->fields[i]);
local_s+=l;
buffs[i]=(char *)malloc(strlen(r->fields[i])+1);
strncpy(buffs[i], r->fields[i], strlen(r->fields[i]));
} else {
buffs[i]=(char *)"";
local_s+=1;
}
}
large_buff[tot_l]=(char *)malloc(local_s+1);
for (int i=0; i<column_length; i++){
strncat(large_buff[tot_l], buffs[i], strlen(buffs[i]));
}
tot_s+=local_s;
tot_l++;
}
char *result_str=(char *)malloc(tot_s+1);
for (int i=0; i<tot_l; i++){
strncat(result_str, large_buff[i], strlen(large_buff[i]));
}
if (resultset) delete resultset;
uint32 hash=SpookyHash::Hash32(result_str,strlen(result_str),0);
free(result_str);
char *checksum=(char *)malloc(16);
sprintf(checksum, "%x", hash);
return checksum;
} else {
free(error);
return (char *)"NULL";
}
}
char **ProxySQL_Admin::get_variables_list() {
size_t l=sizeof(admin_variables_names)/sizeof(char *);
unsigned int i;

@ -1,5 +1,6 @@
#include "proxysql.h"
#include "cpp.h"
#include "SpookyV2.h"
#define USLEEP_SQLITE_LOCKED 100
@ -177,3 +178,33 @@ void SQLite3DB::wrlock() {
void SQLite3DB::wrunlock() {
spin_wrunlock(&rwlock);
}
int64_t SQLite3_result::raw_checksum() {
if (this->rows_count==0) return 0;
uint64_t hash1, hash2;
SpookyHash myhash;
myhash.Init(19,3);
for (std::vector<SQLite3_row *>::iterator it=rows.begin() ; it!=rows.end(); ++it) {
SQLite3_row *r=*it;
for (int i=0; i<columns;i++) {
if (r->fields[i]) {
myhash.Update(r->fields[i],r->sizes[i]);
} else {
myhash.Update("",0);
}
}
}
myhash.Final(&hash1, &hash2);
return hash1;
}
char *SQLite3_result::checksum() {
uint64_t hash1=raw_checksum();
char buf[128];
uint32_t d32[2];
memcpy(&d32,&hash1,sizeof(hash1));
sprintf(buf,"0x%X%X", d32[0], d32[1]);
return strdup(buf);
}

Loading…
Cancel
Save