Skip to content

Commit

Permalink
Merge remote-tracking branch 'Master/v2.2.0-sqliteserver_read_only' i…
Browse files Browse the repository at this point in the history
…nto v2.x_refactor_read_only_action_with_simulator
  • Loading branch information
rahim-kanji committed Feb 17, 2023
2 parents 7710fcb + a843aed commit 1e0a1cf
Show file tree
Hide file tree
Showing 8 changed files with 244 additions and 21 deletions.
15 changes: 13 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ testgalera: build_deps_debug build_lib_testgalera build_src_testgalera
.PHONY: testgrouprep
testgrouprep: build_deps_debug build_lib_testgrouprep build_src_testgrouprep

.PHONY: testreadonly
testreadonly: build_deps_debug build_lib_testreadonly build_src_testreadonly

.PHONY: testall
testall: build_deps_debug build_lib_testall build_src_testall

Expand Down Expand Up @@ -140,13 +143,21 @@ build_src_testgrouprep: build_deps build_lib_testgrouprep
build_lib_testgrouprep: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_GROUPREP" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_testreadonly
build_src_testreadonly: build_deps build_lib_testreadonly
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_READONLY" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_testreadonly
build_lib_testreadonly: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_READONLY" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_src_testall
build_src_testall: build_deps build_lib_testall
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP" CC=${CC} CXX=${CXX} ${MAKE}
cd src && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_lib_testall
build_lib_testall: build_deps_debug
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP" CC=${CC} CXX=${CXX} ${MAKE}
cd lib && OPTZ="${O0} -ggdb -DDEBUG -DTEST_AURORA -DTEST_GALERA -DTEST_GROUPREP -DTEST_READONLY" CC=${CC} CXX=${CXX} ${MAKE}

.PHONY: build_tap_test
build_tap_test: build_src
Expand Down
29 changes: 29 additions & 0 deletions Read_Only_Testing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@


### Compiling

To run `read_only` automated testing, ProxySQL needs to be compiled with `make testreadonly`.



### shutdown mysqld

When running automated testing, ProxySQL will listen on many IPs (30) an on port 3306.
You need to make sure that MySQL server is not running, or not listening on port 3306.


### Running proxysql

`proxysql` needs to be executed with `--sqlite3-server` .
For example, to run it under `gdb`: `run -f -D . --sqlite3-server`


### Similate failover

To simulate failover is enough to connect to sqlite3 server interface and update the `READONLY_STATUS` table.
Note that to connect it is necessary to use a user configured in `mysql_users` table.
To simulate a lot of failover at the same time, a query like the follow can be executed:

```
UPDATE READONLY_STATUS SET read_only=1; CREATE TABLE t1 AS SELECT hostname FROM READONLY_STATUS ORDER BY RANDOM() LIMIT 50; UPDATE READONLY_STATUS SET read_only=0 WHERE hostname IN (SELECT hostname FROM t1); DROP TABLE t1;
```
14 changes: 13 additions & 1 deletion include/SQLite3_Server.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ class SQLite3_Server {
std::unordered_map<std::string, group_rep_status> grouprep_map;
std::vector<table_def_t *> *tables_defs_grouprep;
#endif // TEST_GROUPREP
#if defined(TEST_AURORA) || defined(TEST_GALERA) || defined(TEST_GROUPREP)
#ifdef TEST_READONLY
std::unordered_map<std::string, bool> readonly_map;
std::vector<table_def_t *> *tables_defs_readonly;
#endif // TEST_READONLY
#if defined(TEST_AURORA) || defined(TEST_GALERA) || defined(TEST_GROUPREP) || defined(TEST_READONLY)
void insert_into_tables_defs(std::vector<table_def_t *> *, const char *table_name, const char *table_def);
void drop_tables_defs(std::vector<table_def_t *> *tables_defs);
void check_and_build_standard_tables(SQLite3DB *db, std::vector<table_def_t *> *tables_defs);
Expand Down Expand Up @@ -80,6 +84,14 @@ class SQLite3_Server {
void init_grouprep_ifaces_string(std::string& s);
group_rep_status grouprep_test_value(const std::string& srv_addr);
#endif // TEST_GROUPREP
#ifdef TEST_READONLY
pthread_mutex_t test_readonly_mutex;
void load_readonly_table(MySQL_Session *sess);
int readonly_test_value(char *p);
int readonly_map_size() {
return readonly_map.size();
}
#endif // TEST_READONLY
SQLite3_Server();
~SQLite3_Server();
char **get_variables_list();
Expand Down
35 changes: 34 additions & 1 deletion include/proxysql_admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,11 @@ class ProxySQL_Admin {
void flush_ldap_variables___database_to_runtime(SQLite3DB *db, bool replace, const std::string& checksum = "", const time_t epoch = 0);

public:
/**
* @brief Mutex taken by 'ProxySQL_Admin::admin_session_handler'. It's used prevent multiple
* ProxySQL_Admin 'sessions' from running in parallel, or for preventing collisions between
* modules performing operations over the internal SQLite database and 'ProxySQL_Admin' sessions.
*/
pthread_mutex_t sql_query_global_mutex;
struct {
void *opt;
Expand Down Expand Up @@ -345,7 +350,31 @@ class ProxySQL_Admin {
void init_mysql_firewall();
void init_proxysql_servers();
void save_mysql_users_runtime_to_database(bool _runtime);
void save_mysql_servers_runtime_to_database(bool);
/**
* @brief Save the current MySQL servers reported by 'MySQL_HostGroups_Manager', scanning the
* current MySQL servers structures for all hostgroups, into either the
* 'main.runtime_mysql_servers' or 'main.mysql_servers' table.
* @param _runtime If true the servers reported by 'MySQL_HostGroups_Manager' are stored into
* 'main.runtime_mysql_servers', otherwise into 'main.runtime_mysql_servers'.
* @details This functions requires the caller to have locked `mysql_servers_wrlock()`, but it
* doesn't start a transaction as other function that perform several operations over the
* database. This is because, it's not required doing so, and also because if a transaction
* was started in the following fashion:
*
* ```
* admindb->execute("BEGIN IMMEDIATE");
* ```
*
* ProxySQL would lock in 'MySQL_HostGroups_Manager::dump_table_mysql_servers()', or in any
* other operation from 'MySQL_HostGroups_Manager' that would try to modify the database.
* Reason being is that trying to modify an attached database during a transaction. Database
* is only attached for `DEBUG` builds as part of `MySQL_Admin::init()`. Line:
*
* ```
* admindb->execute("ATTACH DATABASE 'file:mem_mydb?mode=memory&cache=shared' AS myhgm");
* ```
*/
void save_mysql_servers_runtime_to_database(bool _runtime);
void admin_shutdown();
bool is_command(std::string);
void send_MySQL_OK(MySQL_Protocol *myprot, char *msg, int rows=0);
Expand Down Expand Up @@ -505,6 +534,10 @@ class ProxySQL_Admin {
void enable_grouprep_testing();
#endif // TEST_GROUPREP

#ifdef TEST_READONLY
void enable_readonly_testing();
#endif // TEST_READONLY

unsigned int ProxySQL_Test___GenerateRandom_mysql_query_rules_fast_routing(unsigned int, bool);
bool ProxySQL_Test___Verify_mysql_query_rules_fast_routing(int *ret1, int *ret2, int cnt, int dual);
void ProxySQL_Test___MySQL_HostGroups_Manager_generate_many_clusters();
Expand Down
11 changes: 6 additions & 5 deletions lib/MySQL_HostGroups_Manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1833,11 +1833,12 @@ bool MySQL_HostGroups_Manager::commit(
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "DELETE FROM mysql_servers_incoming\n");
mydb->execute("DELETE FROM mysql_servers_incoming");

proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "DELETE FROM mysql_replication_hostgroups\n");
mydb->execute("DELETE FROM mysql_replication_hostgroups");

generate_mysql_replication_hostgroups_table();

// replication
if (incoming_replication_hostgroups) { // this IF is extremely important, otherwise replication hostgroups may disappear
proxy_debug(PROXY_DEBUG_MYSQL_CONNPOOL, 4, "DELETE FROM mysql_replication_hostgroups\n");
mydb->execute("DELETE FROM mysql_replication_hostgroups");
generate_mysql_replication_hostgroups_table();
}

// group replication
if (incoming_group_replication_hostgroups) {
Expand Down
22 changes: 22 additions & 0 deletions lib/MySQL_Monitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ void MySQL_Monitor_State_Data::init_async() {
task_timeout_ = mysql_thread___monitor_ping_timeout;
task_handler_ = &MySQL_Monitor_State_Data::ping_handler;
break;
#ifndef TEST_READONLY
case MON_READ_ONLY:
query_ = "SELECT @@global.read_only read_only";
async_state_machine_ = ASYNC_QUERY_START;
Expand Down Expand Up @@ -596,6 +597,19 @@ void MySQL_Monitor_State_Data::init_async() {
task_timeout_ = mysql_thread___monitor_read_only_timeout;
task_handler_ = &MySQL_Monitor_State_Data::read_only_handler;
break;
#else // TEST_READONLY
case MON_READ_ONLY:
case MON_INNODB_READ_ONLY:
case MON_SUPER_READ_ONLY:
case MON_READ_ONLY__AND__INNODB_READ_ONLY:
case MON_READ_ONLY__OR__INNODB_READ_ONLY:
query_ = "SELECT @@global.read_only read_only ";
query_ += std::string(hostname) + ":" + std::to_string(port);
async_state_machine_ = ASYNC_QUERY_START;
task_timeout_ = mysql_thread___monitor_read_only_timeout;
task_handler_ = &MySQL_Monitor_State_Data::read_only_handler;
break;
#endif // TEST_READONLY
case MON_GROUP_REPLICATION:
async_state_machine_ = ASYNC_QUERY_START;
#ifdef TEST_GROUPREP
Expand Down Expand Up @@ -1573,6 +1587,7 @@ void * monitor_read_only_thread(void *arg) {

mmsd->t1=monotonic_time();
mmsd->interr=0; // reset the value
#ifndef TEST_READONLY
if (mmsd->get_task_type() == MON_INNODB_READ_ONLY) {
mmsd->async_exit_status=mysql_query_start(&mmsd->interr,mmsd->mysql,"SELECT @@global.innodb_read_only read_only");
} else if (mmsd->get_task_type() == MON_SUPER_READ_ONLY) {
Expand All @@ -1584,6 +1599,13 @@ void * monitor_read_only_thread(void *arg) {
} else { // default
mmsd->async_exit_status=mysql_query_start(&mmsd->interr,mmsd->mysql,"SELECT @@global.read_only read_only");
}
#else // TEST_READONLY
{
std::string s = "SELECT @@global.read_only read_only";
s += " " + std::string(mmsd->hostname) + ":" + std::to_string(mmsd->port);
mmsd->async_exit_status=mysql_query_start(&mmsd->interr,mmsd->mysql,s.c_str());
}
#endif // TEST_READONLY
while (mmsd->async_exit_status) {
mmsd->async_exit_status=wait_for_mysql(mmsd->mysql, mmsd->async_exit_status);
#ifdef DEBUG
Expand Down
32 changes: 31 additions & 1 deletion lib/ProxySQL_Admin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11574,7 +11574,7 @@ void ProxySQL_Admin::save_mysql_servers_runtime_to_database(bool _runtime) {
rc=(*proxy_sqlite3_bind_int64)(statement1, 10, atoi(r1->fields[9])); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_bind_int64)(statement1, 11, atoi(r1->fields[10])); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_bind_text)(statement1, 12, r1->fields[11], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, admindb);
SAFE_SQLITE3_STEP(statement1);
SAFE_SQLITE3_STEP2(statement1);
rc=(*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, admindb);
rc=(*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, admindb);
}
Expand Down Expand Up @@ -13399,6 +13399,36 @@ void ProxySQL_Admin::enable_grouprep_testing() {
}
#endif // TEST_GROUPREP

#ifdef TEST_READONLY
void ProxySQL_Admin::enable_readonly_testing() {
proxy_info("Admin is enabling Read Only Testing using SQLite3 Server and HGs from 4201 to 4800\n");
mysql_servers_wrlock();
string q;
q = "DELETE FROM mysql_servers WHERE hostgroup_id BETWEEN 4201 AND 4800";
admindb->execute(q.c_str());

/*
* NOTE: This section can be uncomment for manual testing. It populates the `mysql_servers`
* and `mysql_replication_hostgroups`.
*/
// **************************************************************************************
// for (int i=1; i < 4; i++) {
// for (int j=2; j<100; j+=2) {
// for (int k=1; k<5; k++) {
// q = "INSERT INTO mysql_servers (hostgroup_id, hostname, use_ssl, comment) VALUES (" + std::to_string(4000+i*200+j) + ", '127.5."+ std::to_string(i) +"." + std::to_string(j*2+k) + "', 0, '')";
// admindb->execute(q.c_str());
// }
// q = "INSERT INTO mysql_replication_hostgroups(writer_hostgroup, reader_hostgroup) VALUES (" + std::to_string(4000+i*200+j-1) + "," + std::to_string(4000+i*200+j) + ")";
// admindb->execute(q.c_str());
// }
// }
// **************************************************************************************

load_mysql_servers_to_runtime();
mysql_servers_wrunlock();
}
#endif // TEST_READONLY

void ProxySQL_Admin::ProxySQL_Test___MySQL_HostGroups_Manager_generate_many_clusters() {
mysql_servers_wrlock();
admindb->execute("DELETE FROM mysql_servers WHERE hostgroup_id BETWEEN 10001 AND 20000");
Expand Down
Loading

0 comments on commit 1e0a1cf

Please sign in to comment.