Cluster: Speed up processing of MySQL Query Rules

Multiple changes:
- Query_Processor stored the resultset of query rules loaded to runtime
  (previously this was only for query rules fast routing)
- Admin returns the stored resultset (query rules and fast routing)
  when queries by Cluster
- In khash replaced the hashing function from the built-in
  __ac_X31_hash_string to CityHash32
- When Cluster is used, it calls load_mysql_query_rules_to_runtime() passing
  the resultsets retrieved by the remote peer
- Increased SQLite cache_size to ~50MB: this seems to be a very small optimization
  and probably it will be reverted
- pull_mysql_query_rules_from_peer() uses transactions to write
  to mysql_query_rules_fast_routing
- (important change) pull_mysql_query_rules_from_peer() verifies the checksum
  of MySQL Query ules before loading them to runtime
pull/3930/head
René Cannaò 4 years ago
parent 2a5f364fd5
commit 5e68075edf

@ -14,6 +14,12 @@
#define CLUSTER_QUERY_MYSQL_SERVERS "SELECT hostgroup_id, hostname, port, gtid_port, status, weight, compression, max_connections, max_replication_lag, use_ssl, max_latency_ms, comment FROM runtime_mysql_servers WHERE status<>'OFFLINE_HARD'"
#define CLUSTER_QUERY_MYSQL_REPLICATION_HOSTGROUPS "SELECT writer_hostgroup, reader_hostgroup, comment FROM runtime_mysql_replication_hostgroups"
// the following two queries are the same used in ProxySQL_Admin::load_mysql_query_rules_to_runtime() , but on runtime_ tables.
// It is important to note that the queries in ProxySQL_Admin::load_mysql_query_rules_to_runtime() are used to compute the checksum,
// and are the same resultset saved. Therefore it Cluster can retrieve the same resultset saved it can easily compute the checksum before loading.
#define CLUSTER_QUERY_MYSQL_QUERY_RULES "SELECT rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, cache_empty_result, cache_timeout, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, gtid_from_hostgroup, log, apply, attributes, comment FROM runtime_mysql_query_rules ORDER BY rule_id"
#define CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING "SELECT username, schemaname, flagIN, destination_hostgroup, comment FROM runtime_mysql_query_rules_fast_routing ORDER BY username, schemaname, flagIN"
class ProxySQL_Checksum_Value_2: public ProxySQL_Checksum_Value {
public:
time_t last_updated;
@ -368,7 +374,7 @@ class ProxySQL_Cluster {
void p_update_metrics();
void thread_ending(pthread_t);
void join_term_thread();
void pull_mysql_query_rules_from_peer();
void pull_mysql_query_rules_from_peer(const char *expected_checksum);
void pull_mysql_servers_from_peer();
void pull_mysql_users_from_peer();
/**

@ -1,6 +1,10 @@
#ifndef __CLASS_PTR_ARRAY_H
#define __CLASS_PTR_ARRAY_H
#include <memory>
#include "proxysql.h"
#include "sqlite3db.h"
#define MIN_ARRAY_LEN 8
#define MIN_ARRAY_DELETE_RATIO 8
@ -240,3 +244,10 @@ int remove_spaces(const char *);
char *trim_spaces_in_place(char *str);
char *trim_spaces_and_quotes_in_place(char *str);
bool mywildcmp(const char *p, const char *str);
/**
* @brief Helper function that converts a MYSQL_RES into a 'SQLite3_result'.
* @param resultset The resultset to be converted into a 'SQLite3_result'.
* @return the resulting 'SQLite3_result'.
*/
SQLite3_result * get_SQLite3_resulset(MYSQL_RES* resultset);

@ -117,6 +117,7 @@ int main() {
#ifndef __AC_KHASH_H
#define __AC_KHASH_H
#include "../deps/cityhash/cityhash/src/city.h"
/*!
@header
@ -398,12 +399,23 @@ static kh_inline khint_t __ac_X31_hash_string(const char *s)
if (h) for (++s ; *s; ++s) h = (h << 5) - h + (khint_t)*s;
return h;
}
/*! @function
@abstract const char* hash function
@param s Pointer to a null terminated string
@return The hash value
*/
static kh_inline khint_t __cityhash_hash_string(const char *s)
{
size_t l = strlen(s);
return CityHash32(s,l);
}
/*! @function
@abstract Another interface to const char* hash function
@param key Pointer to a null terminated string [const char*]
@return The hash value [khint_t]
*/
#define kh_str_hash_func(key) __ac_X31_hash_string(key)
//#define kh_str_hash_func(key) __ac_X31_hash_string(key)
#define kh_str_hash_func(key) __cityhash_hash_string(key)
/*! @function
@abstract Const char* comparison function
*/

@ -341,7 +341,7 @@ class ProxySQL_Admin {
void flush_ldap_variables__from_memory_to_disk();
void load_mysql_servers_to_runtime();
void save_mysql_servers_from_runtime();
char * load_mysql_query_rules_to_runtime();
char * load_mysql_query_rules_to_runtime(SQLite3_result *SQLite3_query_rules_resultset=NULL, SQLite3_result *SQLite3_query_rules_fast_routing_resultset=NULL);
void save_mysql_query_rules_from_runtime(bool);
void save_mysql_query_rules_fast_routing_from_runtime(bool);
char * load_mysql_firewall_to_runtime();

@ -328,10 +328,15 @@ class Query_Processor {
unsigned long long get_rules_mem_used();
unsigned long long get_new_req_conns_count();
SQLite3_result * query_rules_resultset; // here we save a copy of resultset for query rules
void save_query_rules(SQLite3_result *resultset);
SQLite3_result * get_current_query_rules_inner();
// fast routing
SQLite3_result * fast_routing_resultset;
SQLite3_result * fast_routing_resultset; // here we save a copy of resultset for query rules fast routing
void load_fast_routing(SQLite3_result *resultset);
SQLite3_result * get_current_query_rules_fast_routing();
SQLite3_result * get_current_query_rules_fast_routing_inner();
int get_current_query_rules_fast_routing_count();
int testing___find_HG_in_mysql_query_rules_fast_routing(char *username, char *schemaname, int flagIN);
int testing___find_HG_in_mysql_query_rules_fast_routing_dual(char *username, char *schemaname, int flagIN);

@ -57,6 +57,11 @@ extern "C" void __gcov_dump();
extern "C" void __gcov_reset();
#endif
#ifdef DEBUG
//#define BENCHMARK_FASTROUTING_LOAD
#endif // DEBUG
//#define MYSQL_THREAD_IMPLEMENTATION
#define SELECT_VERSION_COMMENT "select @@version_comment limit 1"
@ -3717,6 +3722,49 @@ void admin_session_handler(MySQL_Session *sess, void *_pa, PtrSize_t *pkt) {
}
}
if (sess->session_type == PROXYSQL_SESSION_ADMIN) { // no stats
if (!strncasecmp(CLUSTER_QUERY_MYSQL_QUERY_RULES, query_no_space, strlen(CLUSTER_QUERY_MYSQL_QUERY_RULES))) {
GloQPro->wrlock();
resultset = GloQPro->get_current_query_rules_inner();
if (resultset == NULL) {
GloQPro->wrunlock(); // unlock first
resultset = GloQPro->get_current_query_rules();
if (resultset) {
sess->SQLite3_to_MySQL(resultset, error, affected_rows, &sess->client_myds->myprot);
delete resultset;
run_query=false;
goto __run_query;
}
} else {
sess->SQLite3_to_MySQL(resultset, error, affected_rows, &sess->client_myds->myprot);
//delete resultset; // DO NOT DELETE . This is the inner resultset of Query_Processor
GloQPro->wrunlock();
run_query=false;
goto __run_query;
}
}
if (!strncasecmp(CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING, query_no_space, strlen(CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING))) {
GloQPro->wrlock();
resultset = GloQPro->get_current_query_rules_fast_routing_inner();
if (resultset == NULL) {
GloQPro->wrunlock(); // unlock first
resultset = GloQPro->get_current_query_rules_fast_routing();
if (resultset) {
sess->SQLite3_to_MySQL(resultset, error, affected_rows, &sess->client_myds->myprot);
delete resultset;
run_query=false;
goto __run_query;
}
} else {
sess->SQLite3_to_MySQL(resultset, error, affected_rows, &sess->client_myds->myprot);
//delete resultset; // DO NOT DELETE . This is the inner resultset of Query_Processor
GloQPro->wrunlock();
run_query=false;
goto __run_query;
}
}
}
// if the client simply executes:
// SELECT COUNT(*) FROM runtime_mysql_query_rules_fast_routing
// we just return the count
@ -5779,6 +5827,7 @@ 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);
admindb->execute("PRAGMA cache_size = -50000");
//sqlite3_enable_load_extension(admindb->get_db(),1);
//sqlite3_auto_extension( (void(*)(void))sqlite3_json_init);
statsdb=new SQLite3DB();
@ -11833,26 +11882,43 @@ char * ProxySQL_Admin::load_mysql_firewall_to_runtime() {
return NULL;
}
char * ProxySQL_Admin::load_mysql_query_rules_to_runtime() {
char * ProxySQL_Admin::load_mysql_query_rules_to_runtime(SQLite3_result *SQLite3_query_rules_resultset, SQLite3_result *SQLite3_query_rules_fast_routing_resultset) {
// About the queries used here, see notes about CLUSTER_QUERY_MYSQL_QUERY_RULES and
// CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING in ProxySQL_Cluster.hpp
char *error=NULL;
int cols=0;
int affected_rows=0;
if (GloQPro==NULL) return (char *)"Global Query Processor not started: command impossible to run";
SQLite3_result *resultset=NULL;
char *query=(char *)"SELECT rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, cache_empty_result, cache_timeout, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, gtid_from_hostgroup, log, apply, attributes, comment FROM main.mysql_query_rules WHERE active=1 ORDER BY rule_id";
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
if (SQLite3_query_rules_resultset==NULL) {
admindb->execute_statement(query, &error , &cols , &affected_rows , &resultset);
} else {
// Cluster can pass SQLite3_query_rules_resultset , to absolutely speed up
// the process and therefore there is no need to run any query
resultset = SQLite3_query_rules_resultset;
}
char *error2 = NULL;
int cols2 = 0;
int affected_rows2 = 0;
SQLite3_result *resultset2 = NULL;
char *query2=(char *)"SELECT username, schemaname, flagIN, destination_hostgroup, comment FROM main.mysql_query_rules_fast_routing ORDER BY username, schemaname, flagIN";
admindb->execute_statement(query2, &error2 , &cols2 , &affected_rows2 , &resultset2);
if (SQLite3_query_rules_fast_routing_resultset==NULL) {
admindb->execute_statement(query2, &error2 , &cols2 , &affected_rows2 , &resultset2);
} else {
// Cluster can pass SQLite3_query_rules_fast_routing_resultset , to absolutely speed up
// the process and therefore there is no need to run any query
resultset2 = SQLite3_query_rules_fast_routing_resultset;
}
if (error) {
proxy_error("Error on %s : %s\n", query, error);
} else if (error2) {
proxy_error("Error on %s : %s\n", query2, error2);
} else {
GloQPro->wrlock();
#ifdef BENCHMARK_FASTROUTING_LOAD
for (int i=0; i<10; i++) {
#endif // BENCHMARK_FASTROUTING_LOAD
if (checksum_variables.checksum_mysql_query_rules) {
pthread_mutex_lock(&GloVars.checksum_mutex);
uint64_t hash1 = resultset->raw_checksum();
@ -11931,11 +11997,24 @@ char * ProxySQL_Admin::load_mysql_query_rules_to_runtime() {
GloQPro->insert(nqpr, false);
}
GloQPro->sort(false);
#ifdef BENCHMARK_FASTROUTING_LOAD
// load a copy of resultset and resultset2
SQLite3_result *resultset3 = new SQLite3_result(resultset);
GloQPro->save_query_rules(resultset3);
SQLite3_result *resultset4 = new SQLite3_result(resultset2);
GloQPro->load_fast_routing(resultset4);
#else
// load the original resultset and resultset2
GloQPro->save_query_rules(resultset);
GloQPro->load_fast_routing(resultset2);
#endif // BENCHMARK_FASTROUTING_LOAD
GloQPro->commit();
#ifdef BENCHMARK_FASTROUTING_LOAD
}
#endif // BENCHMARK_FASTROUTING_LOAD
GloQPro->wrunlock();
}
if (resultset) delete resultset;
// if (resultset) delete resultset; // never delete it. GloQPro saves it
// if (resultset2) delete resultset2; // never delete it. GloQPro saves it
return NULL;
}

@ -598,6 +598,7 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
unsigned long long own_epoch = __sync_fetch_and_add(&GloVars.checksums_values.mysql_query_rules.epoch,0);
char* own_checksum = __sync_fetch_and_add(&GloVars.checksums_values.mysql_query_rules.checksum,0);
v = &checksums_values.mysql_query_rules;
char* v_exp_checksum = strdup(v->checksum);
if (v->version > 1) {
if (
(own_version == 1) // we just booted
@ -606,7 +607,7 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
) {
if (v->diff_check >= diff_mqr) {
proxy_info("Cluster: detected a peer %s:%d with mysql_query_rules version %llu, epoch %llu, diff_check %u. Own version: %llu, epoch: %llu. Proceeding with remote sync\n", hostname, port, v->version, v->epoch, v->diff_check, own_version, own_epoch);
GloProxyCluster->pull_mysql_query_rules_from_peer();
GloProxyCluster->pull_mysql_query_rules_from_peer((const char *)v_exp_checksum);
if (strncmp(v->checksum, GloVars.checksums_values.mysql_query_rules.checksum, 20)==0) {
// we copied from the remote server, let's also copy the same epoch
GloVars.checksums_values.mysql_query_rules.epoch = v->epoch;
@ -826,7 +827,7 @@ void ProxySQL_Node_Entry::set_checksums(MYSQL_RES *_r) {
}
}
void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
void ProxySQL_Cluster::pull_mysql_query_rules_from_peer(const char *expected_checksum) {
char * hostname = NULL;
uint16_t port = 0;
pthread_mutex_lock(&GloProxyCluster->update_mysql_query_rules_mutex);
@ -851,20 +852,38 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
//mysql_options(conn, MYSQL_OPT_READ_TIMEOUT, &timeout_long);
//mysql_options(conn, MYSQL_OPT_WRITE_TIMEOUT, &timeout);
{ unsigned char val = 1; mysql_options(conn, MYSQL_OPT_SSL_ENFORCE, &val); }
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d started\n", hostname, port);
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d started. Expected checksum: %s\n", hostname, port, expected_checksum);
rc_conn = mysql_real_connect(conn, hostname, username, password, NULL, port, NULL, 0);
if (rc_conn) {
MYSQL_RES *result1 = NULL;
MYSQL_RES *result2 = NULL;
rc_query = mysql_query(conn,"SELECT rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, cache_empty_result, cache_timeout, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, gtid_from_hostgroup, log, apply, attributes, comment FROM runtime_mysql_query_rules");
//rc_query = mysql_query(conn,"SELECT rule_id, username, schemaname, flagIN, client_addr, proxy_addr, proxy_port, digest, match_digest, match_pattern, negate_match_pattern, re_modifiers, flagOUT, replace_pattern, destination_hostgroup, cache_ttl, cache_empty_result, cache_timeout, reconnect, timeout, retries, delay, next_query_flagIN, mirror_flagOUT, mirror_hostgroup, error_msg, ok_msg, sticky_conn, multiplex, gtid_from_hostgroup, log, apply, attributes, comment FROM runtime_mysql_query_rules");
rc_query = mysql_query(conn,CLUSTER_QUERY_MYSQL_QUERY_RULES);
if ( rc_query == 0 ) {
MYSQL_RES *result1 = mysql_store_result(conn);
rc_query = mysql_query(conn,"SELECT username, schemaname, flagIN, destination_hostgroup, comment FROM runtime_mysql_query_rules_fast_routing");
rc_query = mysql_query(conn,CLUSTER_QUERY_MYSQL_QUERY_RULES_FAST_ROUTING);
if ( rc_query == 0) {
result2 = mysql_store_result(conn);
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d completed\n", hostname, port);
// we pass these to load_mysql_query_rules_to_runtime()
// do not delete them
SQLite3_result * SQLite3_query_rules_resultset = get_SQLite3_resulset(result1);
SQLite3_result * SQLite3_query_rules_fast_routing_resultset = get_SQLite3_resulset(result2);
uint64_t hash1 = SQLite3_query_rules_resultset->raw_checksum();
uint64_t hash2 = SQLite3_query_rules_fast_routing_resultset->raw_checksum();
hash1 += hash2;
uint32_t d32[2];
char buf[20] = { 0 };
memcpy(&d32, &hash1, sizeof(hash1));
sprintf(buf,"0x%0X%0X", d32[0], d32[1]);
replace_checksum_zeros(buf);
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d completed. Computed checksum: %s\n", hostname, port, buf);
if (strcmp(buf, expected_checksum)==0) {
proxy_info("Cluster: Loading to runtime MySQL Query Rules from peer %s:%d\n", hostname, port);
pthread_mutex_lock(&GloAdmin->sql_query_global_mutex);
//GloAdmin->admindb->execute("PRAGMA quick_check");
GloAdmin->admindb->execute("DELETE FROM mysql_query_rules");
GloAdmin->admindb->execute("DELETE FROM mysql_query_rules_fast_routing");
MYSQL_ROW row;
@ -874,6 +893,7 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
//rc=(*proxy_sqlite3_prepare_v2)(mydb3, q, -1, &statement1, 0);
rc = GloAdmin->admindb->prepare_v2(q, &statement1);
ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
GloAdmin->admindb->execute("BEGIN TRANSACTION");
while ((row = mysql_fetch_row(result1))) {
rc=(*proxy_sqlite3_bind_int64)(statement1, 1, atoll(row[0])); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // rule_id
rc=(*proxy_sqlite3_bind_int64)(statement1, 2, 1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb); // active
@ -914,6 +934,9 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, GloAdmin->admindb);
}
GloAdmin->admindb->execute("COMMIT");
std::string query32frs = "INSERT INTO mysql_query_rules_fast_routing(username, schemaname, flagIN, destination_hostgroup, comment) VALUES " + generate_multi_rows_query(32,5);
char *q1fr = (char *)"INSERT INTO mysql_query_rules_fast_routing(username, schemaname, flagIN, destination_hostgroup, comment) VALUES (?1, ?2, ?3, ?4, ?5)";
char *q32fr = (char *)query32frs.c_str();
@ -928,6 +951,7 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
int row_idx=0;
int max_bulk_row_idx=mysql_num_rows(result2)/32;
max_bulk_row_idx=max_bulk_row_idx*32;
GloAdmin->admindb->execute("BEGIN TRANSACTION");
while ((row = mysql_fetch_row(result2))) {
int idx=row_idx%32;
if (row_idx<max_bulk_row_idx) { // bulk
@ -953,7 +977,9 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
}
row_idx++;
}
GloAdmin->load_mysql_query_rules_to_runtime();
//GloAdmin->admindb->execute("PRAGMA integrity_check");
GloAdmin->admindb->execute("COMMIT");
GloAdmin->load_mysql_query_rules_to_runtime(SQLite3_query_rules_resultset, SQLite3_query_rules_fast_routing_resultset);
if (GloProxyCluster->cluster_mysql_query_rules_save_to_disk == true) {
proxy_info("Cluster: Saving to disk MySQL Query Rules from peer %s:%d\n", hostname, port);
GloAdmin->flush_mysql_query_rules__from_memory_to_disk();
@ -962,6 +988,13 @@ void ProxySQL_Cluster::pull_mysql_query_rules_from_peer() {
}
pthread_mutex_unlock(&GloAdmin->sql_query_global_mutex);
metrics.p_counter_array[p_cluster_counter::pulled_mysql_query_rules_success]->Increment();
} else {
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d failed because of mismatching checksum. Expected: %s , Computed: %s\n", hostname, port, expected_checksum, buf);
metrics.p_counter_array[p_cluster_counter::pulled_mysql_query_rules_failure]->Increment();
// only in this case we delete these resultset, otherwise they are just passed to Query Processor
delete SQLite3_query_rules_resultset;
delete SQLite3_query_rules_fast_routing_resultset;
}
} else {
proxy_info("Cluster: Fetching MySQL Query Rules from peer %s:%d failed: %s\n", hostname, port, mysql_error(conn));
metrics.p_counter_array[p_cluster_counter::pulled_mysql_query_rules_failure]->Increment();

@ -521,6 +521,7 @@ Query_Processor::Query_Processor() {
rand_del[13] = '-';
rand_del[14] = 0;
}
query_rules_resultset = NULL;
fast_routing_resultset = NULL;
rules_fast_routing = kh_init(khStrInt); // create a hashtable
rules_fast_routing___keys_values = NULL;
@ -546,6 +547,10 @@ Query_Processor::~Query_Processor() {
}
digest_umap.erase(digest_umap.begin(),digest_umap.end());
digest_text_umap.erase(digest_text_umap.begin(),digest_text_umap.end());
if (query_rules_resultset) {
delete query_rules_resultset;
query_rules_resultset = NULL;
}
if (fast_routing_resultset) {
delete fast_routing_resultset;
fast_routing_resultset = NULL;
@ -848,6 +853,17 @@ int Query_Processor::get_current_query_rules_fast_routing_count() {
return result;
}
// we return the resultset fast_routing_resultset
// the caller of this function must lock Query Processor
SQLite3_result * Query_Processor::get_current_query_rules_fast_routing_inner() {
return fast_routing_resultset;
}
// we return the resultset query_rules_resultset
// the caller of this function must lock Query Processor
SQLite3_result * Query_Processor::get_current_query_rules_inner() {
return query_rules_resultset;
}
SQLite3_result * Query_Processor::get_current_query_rules_fast_routing() {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Dumping current query rules fast_routing, using Global version %d\n", version);
SQLite3_result *result=new SQLite3_result(5);
@ -2729,6 +2745,11 @@ void Query_Processor::load_mysql_firewall_rules(SQLite3_result *resultset) {
global_mysql_firewall_whitelist_rules_map___size = tot_size;
}
void Query_Processor::save_query_rules(SQLite3_result *resultset) {
delete query_rules_resultset;
query_rules_resultset = resultset; // save it
}
void Query_Processor::load_fast_routing(SQLite3_result *resultset) {
unsigned long long tot_size = 0;
size_t rand_del_size = strlen(rand_del);

@ -1,5 +1,10 @@
#include <vector>
#include "gen_utils.h"
using std::vector;
char *escape_string_single_quotes(char *input, bool free_it) {
int i,j,l;
char *o=NULL; // output string, if any
@ -220,3 +225,30 @@ bool Proxy_file_regular(const char *path) {
return false;
}
SQLite3_result * get_SQLite3_resulset(MYSQL_RES* resultset) {
if (resultset == nullptr) {
return nullptr;
}
uint32_t num_fields = mysql_num_fields(resultset);
MYSQL_FIELD* fields = mysql_fetch_fields(resultset);
SQLite3_result * sqlite_result { new SQLite3_result(num_fields) };
for (uint32_t i = 0; i < num_fields; i++) {
sqlite_result->add_column_definition(SQLITE_TEXT, fields[i].name);
}
vector<char*> pta(static_cast<size_t>(num_fields));
while (MYSQL_ROW row = mysql_fetch_row(resultset)) {
for (uint32_t i = 0; i < num_fields; i++) {
pta[i] = row[i];
}
sqlite_result->add_row(&pta[0]);
}
// restore the initial resulset index
mysql_data_seek(resultset, 0);
return sqlite_result;
}

@ -0,0 +1,267 @@
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <string>
#include <sstream>
#include <mysql.h>
#include "tap.h"
#include "command_line.h"
#include "utils.h"
/*
This test includes a lot of repetitive checks that could have been organized into functions.
But they have been left in this way to easily identify the failed check
*/
int main(int argc, char** argv) {
CommandLine cl;
if(cl.getEnv())
return exit_status();
plan(96);
diag("Testing mysql-enforce_autocommit_on_reads");
MYSQL* mysqladmin = mysql_init(NULL);
if (!mysqladmin)
return exit_status();
if (!mysql_real_connect(mysqladmin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) {
fprintf(stderr, "File %s, line %d, Error: %s\n",
__FILE__, __LINE__, mysql_error(mysqladmin));
return exit_status();
}
MYSQL_QUERY(mysqladmin, "SET mysql-enforce_autocommit_on_reads=0");
MYSQL_QUERY(mysqladmin, "load mysql variables to runtime");
MYSQL* mysql = mysql_init(NULL);
if (!mysql)
return exit_status();
if (!mysql_real_connect(mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) {
fprintf(stderr, "Failed to connect to database: Error: %s\n",
mysql_error(mysql));
return exit_status();
}
MYSQL_RES *res;
if (create_table_test_sbtest1(100,mysql)) {
fprintf(stderr, "File %s, line %d, Error: create_table_test_sbtest1() failed\n", __FILE__, __LINE__);
return exit_status();
}
diag("Waiting few seconds for replication...");
sleep(2);
MYSQL_QUERY(mysql, "USE test");
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=1");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 FOR UPDATE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 LOCK IN SHARE MODE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=1");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 FOR UPDATE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 LOCK IN SHARE MODE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "UPDATE sbtest1 SET k=k+1 WHERE id=2");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "UPDATE sbtest1 SET k=k+1 WHERE id=2");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysqladmin, "SET mysql-enforce_autocommit_on_reads=1");
MYSQL_QUERY(mysqladmin, "load mysql variables to runtime");
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=1");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 FOR UPDATE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 LOCK IN SHARE MODE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=1");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 FOR UPDATE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "SELECT * FROM sbtest1 WHERE id=2 LOCK IN SHARE MODE");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=0");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "UPDATE sbtest1 SET k=k+1 WHERE id=2");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 1) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "set autocommit=1");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysql, "UPDATE sbtest1 SET k=k+1 WHERE id=2");
res = mysql_store_result(mysql);
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
mysql_free_result(res);
MYSQL_QUERY(mysql, "COMMIT");
ok(((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 2) , "Line: %d: server_status: %u , AUTOCOMMIT %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_AUTOCOMMIT);
ok(((mysql->server_status & SERVER_STATUS_IN_TRANS) == 0) , "Line: %d, server_status: %u , IN_TRANS = %d", __LINE__ , mysql->server_status, mysql->server_status & SERVER_STATUS_IN_TRANS);
MYSQL_QUERY(mysqladmin, "SET mysql-enforce_autocommit_on_reads=0");
MYSQL_QUERY(mysqladmin, "load mysql variables to runtime");
mysql_close(mysql);
mysql_close(mysqladmin);
return exit_status();
}
Loading…
Cancel
Save