export proxysql configuration to resultset

pull/2413/head
Valentin Rakush 7 years ago
parent 9430cabee3
commit 52b5ee9486

@ -276,9 +276,13 @@ class ProxySQL_Admin {
int Read_Scheduler_from_configfile();
int Read_ProxySQL_Servers_from_configfile();
void addField(std::string& data, const char* name, const char* value, const char* dq="\"");
int Write_Global_Variables_to_configfile(std::string& data);
int Write_MySQL_Users_from_configfile(std::string& data);
int Write_MySQL_Query_Rules_from_configfile(std::string& data);
int Write_MySQL_Users_to_configfile(std::string& data);
int Write_MySQL_Query_Rules_to_configfile(std::string& data);
int Write_MySQL_Servers_to_configfile(std::string& data);
int Write_Scheduler_to_configfile(std::string& data);
int Write_ProxySQL_Servers_to_configfile(std::string& data);
void flush_error_log();
bool GenericRefreshStatistics(const char *query_no_space, unsigned int query_no_space_length, bool admin);

@ -100,6 +100,36 @@ static char * load_file (const char *filename) {
return buffer;
}
const char* config_header = "########################################################################################\n"
"# This config file is parsed using libconfig , and its grammar is described in:\n"
"# http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-File-Grammar\n"
"# Grammar is also copied at the end of this file\n"
"########################################################################################\n"
"\n"
"########################################################################################\n"
"# IMPORTANT INFORMATION REGARDING THIS CONFIGURATION FILE:\n"
"########################################################################################\n"
"# On startup, ProxySQL reads its config file (if present) to determine its datadir.\n"
"# What happens next depends on if the database file (disk) is present in the defined\n"
"# datadir (i.e. \"/var/lib/proxysql/proxysql.db\").\n"
"#\n"
"# If the database file is found, ProxySQL initializes its in-memory configuration from\n"
"# the persisted on-disk database. So, disk configuration gets loaded into memory and\n"
"# then propagated towards the runtime configuration.\n"
"#\n"
"# If the database file is not found and a config file exists, the config file is parsed\n"
"# and its content is loaded into the in-memory database, to then be both saved on-disk\n"
"# database and loaded at runtime.\n"
"#\n"
"# IMPORTANT: If a database file is found, the config file is NOT parsed. In this case\n"
"# ProxySQL initializes its in-memory configuration from the persisted on-disk\n"
"# database ONLY. In other words, the configuration found in the proxysql.cnf\n"
"# file is only used to initial the on-disk database read on the first startup.\n"
"#\n"
"# In order to FORCE a re-initialise of the on-disk database from the configuration file\n"
"# the ProxySQL service should be started with \"service proxysql initial\".\n"
"#\n"
"########################################################################################\n";
/*
int sqlite3_json_init(
@ -3781,10 +3811,20 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) {
std::string data;
data.reserve(100000);
run_query = false;
data += config_header;
if (pa->Write_Global_Variables_to_configfile(data))
goto __run_query;
if (pa->Write_MySQL_Users_from_configfile(data))
if (pa->Write_MySQL_Users_to_configfile(data))
goto __run_query;
if (pa->Write_MySQL_Query_Rules_to_configfile(data))
goto __run_query;
if (pa->Write_MySQL_Servers_to_configfile(data))
goto __run_query;
if (pa->Write_Scheduler_to_configfile(data))
goto __run_query;
if (pa->Write_ProxySQL_Servers_to_configfile(data))
goto __run_query;
proxy_warning("TRACE: config is saved\n");
char *pta[1];
pta[0]=NULL;
pta[0]=(char*)data.c_str();
@ -9684,6 +9724,13 @@ char * ProxySQL_Admin::load_mysql_query_rules_to_runtime() {
return NULL;
}
void ProxySQL_Admin::addField(std::string& data, const char* name, const char* value, const char* dq) {
char strBuf[10000] = {0};
if (!value || !strlen(value)) return;
snprintf(strBuf, sizeof(strBuf), "\t\t%s=%s%s%s\n", name, dq, value, dq);
data += strBuf;
}
int ProxySQL_Admin::Write_Global_Variables_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
@ -9711,9 +9758,9 @@ int ProxySQL_Admin::Write_Global_Variables_to_configfile(std::string& data) {
data += "}\n\n" + prefix + "_variables = \n{\n";
}
}
if (strlen(r->fields[1])) {
char strBuf[256];
snprintf(strBuf, sizeof(strBuf), "\t%s = %s\n",r->fields[0] + p1.size() + 1, r->fields[1]);
if (r->fields[1] && strlen(r->fields[1])) {
char strBuf[10000];
snprintf(strBuf, sizeof(strBuf), "\t%s=\"%s\"\n",r->fields[0] + p1.size() + 1, r->fields[1]);
data += strBuf;
}
}
@ -9760,6 +9807,7 @@ int ProxySQL_Admin::Read_Global_Variables_from_configfile(const char *prefix) {
}
//fprintf(stderr,"%s = %s\n", n, value_string.c_str());
char *query=(char *)malloc(strlen(q)+strlen(prefix)+strlen(n)+strlen(value_string.c_str()));
fprintf(stderr, "irefix %s, name %s, value %s\n", prefix, n, value_string.c_str());
sprintf(query,q, prefix, n, value_string.c_str());
//fprintf(stderr, "%s\n", query);
admindb->execute(query);
@ -9770,7 +9818,7 @@ int ProxySQL_Admin::Read_Global_Variables_from_configfile(const char *prefix) {
return i;
}
int ProxySQL_Admin::Write_MySQL_Users_from_configfile(std::string& data) {
int ProxySQL_Admin::Write_MySQL_Users_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
int affected_rows = 0;
@ -9779,7 +9827,7 @@ int ProxySQL_Admin::Write_MySQL_Users_from_configfile(std::string& data) {
char *query=(char *)"SELECT * FROM mysql_users";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from global_variables : %s\n", error);
proxy_error("Error on read from mysql_users: %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
@ -9791,36 +9839,19 @@ int ProxySQL_Admin::Write_MySQL_Users_from_configfile(std::string& data) {
if (isNext)
data += ",\n";
data += "\t{\n";
snprintf(strBuf, sizeof(strBuf), "\t\tusername = \"%s\"\n", r->fields[0]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tpassword = \"%s\"\n", r->fields[1]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tactive = %s\n", r->fields[2]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tuse_ssl = %s\n", r->fields[3]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tdefault_hostgroup = %s\n", r->fields[4]);
data += strBuf;
if (strlen(r->fields[5])) {
snprintf(strBuf, sizeof(strBuf), "\t\tdefault_schema = %s\n", r->fields[5]);
data += strBuf;
}
snprintf(strBuf, sizeof(strBuf), "\t\tschema_locked = %s\n", r->fields[6]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\ttransaction_persistent = %s\n", r->fields[7]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tfast_forward = %s\n", r->fields[8]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tbackend = %s\n", r->fields[9]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tfrontend = %s\n", r->fields[10]);
data += strBuf;
snprintf(strBuf, sizeof(strBuf), "\t\tmax_connections = %s\n", r->fields[11]);
data += strBuf;
if (strlen(r->fields[12])) {
snprintf(strBuf, sizeof(strBuf), "\t\tcomment = %s\n", r->fields[12]);
data += strBuf;
}
addField(data, "username", r->fields[0]);
addField(data, "password", r->fields[1]);
addField(data, "active", r->fields[2], "");
addField(data, "use_ssl", r->fields[3], "");
addField(data, "default_hostgroup", r->fields[4], "");
addField(data, "default_schema", r->fields[5]);
addField(data, "schema_locked", r->fields[6], "");
addField(data, "transaction_persistent", r->fields[7], "");
addField(data, "fast_forward", r->fields[8], "");
addField(data, "backend", r->fields[9], "");
addField(data, "frontend", r->fields[10], "");
addField(data, "max_connections", r->fields[11], "");
addField(data, "comment", r->fields[12], "");
data += "\t}";
isNext = true;
}
@ -9883,6 +9914,50 @@ int ProxySQL_Admin::Read_MySQL_Users_from_configfile() {
return rows;
}
int ProxySQL_Admin::Write_Scheduler_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
int affected_rows = 0;
SQLite3_result* sqlite_resultset = NULL;
char *query=(char *)"SELECT * FROM scheduler";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from scheduler: %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "scheduler:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "id", r->fields[0], "");
addField(data, "active", r->fields[1], "");
addField(data, "interval_ms", r->fields[2], "");
addField(data, "filename", r->fields[3]);
addField(data, "arg1", r->fields[4]);
addField(data, "arg2", r->fields[5]);
addField(data, "arg3", r->fields[6]);
addField(data, "arg4", r->fields[7]);
addField(data, "arg5", r->fields[8]);
addField(data, "comment", r->fields[9]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
return 0;
}
int ProxySQL_Admin::Read_Scheduler_from_configfile() {
const Setting& root = GloVars.confFile->cfg.getRoot();
if (root.exists("scheduler")==false) return 0;
@ -9983,6 +10058,74 @@ int ProxySQL_Admin::Read_Scheduler_from_configfile() {
return rows;
}
int ProxySQL_Admin::Write_MySQL_Query_Rules_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
int affected_rows = 0;
SQLite3_result* sqlite_resultset = NULL;
char *query=(char *)"SELECT * FROM mysql_query_rules";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_query_rules : %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_query_rules:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "rule_id", r->fields[0], "");
addField(data, "active", r->fields[1], "");
addField(data, "username", r->fields[2]);
addField(data, "schemaname", r->fields[3]);
addField(data, "flagIN", r->fields[4], "");
addField(data, "client_addr", r->fields[5]);
addField(data, "proxy_addr", r->fields[6]);
addField(data, "proxy_port", r->fields[7], "");
addField(data, "digest", r->fields[8]);
addField(data, "match_digest", r->fields[9]);
addField(data, "match_pattern", r->fields[10]);
addField(data, "negate_match_pattern", r->fields[11], "");
addField(data, "re_modifiers", r->fields[12]);
addField(data, "flagOUT", r->fields[13], "");
addField(data, "replace_pattern", r->fields[14]);
addField(data, "destination_hostgroup", r->fields[15], "");
addField(data, "cache_ttl", r->fields[16], "");
addField(data, "cache_empty_result", r->fields[17], "");
addField(data, "cache_timeout", r->fields[18], "");
addField(data, "reconnect", r->fields[19], "");
addField(data, "timeout", r->fields[20], "");
addField(data, "retries", r->fields[21], "");
addField(data, "delay", r->fields[22], "");
addField(data, "next_query_flagIN", r->fields[23], "");
addField(data, "mirror_flagOUT", r->fields[24], "");
addField(data, "mirror_hostgroup", r->fields[25], "");
addField(data, "error_msg", r->fields[26]);
addField(data, "OK_msg", r->fields[27]);
addField(data, "sticky_conn", r->fields[28], "");
addField(data, "multiplex", r->fields[29], "");
addField(data, "gtid_from_hostgroup", r->fields[30], "");
addField(data, "log", r->fields[31], "");
addField(data, "apply", r->fields[32], "");
addField(data, "comment", r->fields[33]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
return 0;
}
int ProxySQL_Admin::Read_MySQL_Query_Rules_from_configfile() {
const Setting& root = GloVars.confFile->cfg.getRoot();
if (root.exists("mysql_query_rules")==false) return 0;
@ -10242,9 +10385,190 @@ int ProxySQL_Admin::Read_MySQL_Query_Rules_from_configfile() {
rows++;
}
admindb->execute("PRAGMA foreign_keys = ON");
fprintf(stderr, "TRACE: rows %d\n", rows);
return rows;
}
int ProxySQL_Admin::Write_MySQL_Servers_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
int affected_rows = 0;
SQLite3_result* sqlite_resultset = NULL;
char *query=(char *)"SELECT * FROM mysql_servers";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_query_rules : %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_servers:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "hostgroup_id", r->fields[0], "");
addField(data, "hostname", r->fields[1]);
addField(data, "port", r->fields[2], "");
addField(data, "gtid_port", r->fields[3], "");
addField(data, "status", r->fields[4]);
addField(data, "weight", r->fields[5], "");
addField(data, "compression", r->fields[6], "");
addField(data, "max_connections", r->fields[7], "");
addField(data, "max_replication_lag", r->fields[8], "");
addField(data, "use_ssl", r->fields[9], "");
addField(data, "max_latency_ms", r->fields[10], "");
addField(data, "comment", r->fields[11]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
query=(char *)"SELECT * FROM mysql_replication_hostgroups";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_replication_hostgroups : %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_replication_hostgroups:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "writer_hostgroup", r->fields[0], "");
addField(data, "reader_hostgroup", r->fields[1], "");
addField(data, "check_type", r->fields[2]);
addField(data, "comment", r->fields[3]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
query=(char *)"SELECT * FROM mysql_group_replication_hostgroups";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_group_replication_hostgroups : %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_group_replication_hostgroups:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "writer_hostgroup", r->fields[0], "");
addField(data, "backup_writer_hostgroup", r->fields[1], "");
addField(data, "reader_hostgroup", r->fields[2], "");
addField(data, "offline_hostgroup", r->fields[3], "");
addField(data, "active", r->fields[4], "");
addField(data, "max_writers", r->fields[5], "");
addField(data, "writer_is_also_reader", r->fields[6], "");
addField(data, "max_transactions_behind", r->fields[7], "");
addField(data, "comment", r->fields[8]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
query=(char *)"SELECT * FROM mysql_galera_hostgroups";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_galera_hostgroups: %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_galera_hostgroups:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "writer_hostgroup", r->fields[0], "");
addField(data, "backup_writer_hostgroup", r->fields[1], "");
addField(data, "reader_hostgroup", r->fields[2], "");
addField(data, "offline_hostgroup", r->fields[3], "");
addField(data, "active", r->fields[4], "");
addField(data, "max_writers", r->fields[5], "");
addField(data, "writer_is_also_reader", r->fields[6], "");
addField(data, "max_transactions_behind", r->fields[7], "");
addField(data, "comment", r->fields[8]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
query=(char *)"SELECT * FROM mysql_aws_aurora_hostgroups";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from mysql_aws_aurora_hostgroups: %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "mysql_aws_aurora_hostgroups:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "writer_hostgroup", r->fields[0], "");
addField(data, "reader_hostgroup", r->fields[1], "");
addField(data, "active", r->fields[2], "");
addField(data, "aurora_port", r->fields[3], "");
addField(data, "domain_name", r->fields[4]);
addField(data, "max_lag_ms", r->fields[5], "");
addField(data, "check_interval_ms", r->fields[6], "");
addField(data, "check_timeout_ms", r->fields[7], "");
addField(data, "writer_is_also_reader", r->fields[8], "");
addField(data, "new_reader_weight", r->fields[9], "");
addField(data, "comment", r->fields[10]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
return 0;
}
int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
const Setting& root = GloVars.confFile->cfg.getRoot();
int i;
@ -10271,6 +10595,7 @@ int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
std::string comment="";
if (server.lookupValue("address", address)==false) {
if (server.lookupValue("hostname", address)==false) {
proxy_warning("Mandatory field \"mysql_servers::hostname\" has not been found\n");
continue;
}
}
@ -10278,6 +10603,7 @@ int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
server.lookupValue("gtid_port", gtid_port);
if (server.lookupValue("hostgroup", hostgroup)==false) {
if (server.lookupValue("hostgroup_id", hostgroup)==false) {
proxy_warning("Mandatory field \"mysql_servers::hostgroup_id\" has not been found\n");
continue;
}
}
@ -10319,8 +10645,14 @@ int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
int reader_hostgroup;
std::string comment="";
std::string check_type="";
if (line.lookupValue("writer_hostgroup", writer_hostgroup)==false) continue;
if (line.lookupValue("reader_hostgroup", reader_hostgroup)==false) continue;
if (line.lookupValue("writer_hostgroup", writer_hostgroup)==false) {
proxy_warning("Mandatory field \"mysql_replication_hostgroups::writer_hostgroup\" has not been found\n");
continue;
}
if (line.lookupValue("reader_hostgroup", reader_hostgroup)==false) {
proxy_warning("Mandatory field \"mysql_replication_hostgroups::reader_hostgroup\" has not been found\n");
continue;
}
line.lookupValue("comment", comment);
char *o1=strdup(comment.c_str());
char *o=escape_string_single_quotes(o1, false);
@ -10466,9 +10798,48 @@ int ProxySQL_Admin::Read_MySQL_Servers_from_configfile() {
}
}
admindb->execute("PRAGMA foreign_keys = ON");
fprintf(stderr, "TRACE: mysql servers rows %d\n", rows);
return rows;
}
int ProxySQL_Admin::Write_ProxySQL_Servers_to_configfile(std::string& data) {
char* error = NULL;
int cols = 0;
int affected_rows = 0;
SQLite3_result* sqlite_resultset = NULL;
char *query=(char *)"SELECT * FROM proxysql_servers";
admindb->execute_statement(query, &error, &cols, &affected_rows, &sqlite_resultset);
if (error) {
proxy_error("Error on read from proxysql_servers: %s\n", error);
return -1;
} else {
if (sqlite_resultset) {
std::string prefix;
data += "proxysql_servers:\n(\n";
bool isNext = false;
for (auto r : sqlite_resultset->rows) {
if (isNext)
data += ",\n";
data += "\t{\n";
addField(data, "hostname", r->fields[0]);
addField(data, "port", r->fields[1], "");
addField(data, "weight", r->fields[2], "");
addField(data, "comment", r->fields[3]);
data += "\t}";
isNext = true;
}
data += "\n)\n";
}
}
if (sqlite_resultset)
delete sqlite_resultset;
return 0;
}
int ProxySQL_Admin::Read_ProxySQL_Servers_from_configfile() {
const Setting& root = GloVars.confFile->cfg.getRoot();
int i;

Loading…
Cancel
Save