Skip to content

Commit

Permalink
Refactor MYSQL_PROXY (#118)
Browse files Browse the repository at this point in the history
* EFM PROXY

* complete EFM PROXY

* fix unit tests

* fix include

* generate node keys after setting next proxy for EFM_PROXY

* fix unit tests

* stop monitoring init() and options()

* replace MYSQL_MONITOR_PROXY with MYSQL_PROXY

* fix unit tests

* stop monitoring ping()

* stop monitoring ssl_set and option4

* stop monitoring autocommit

* comment out aws code

* stop monitoring client_find_plugin

* newline at eof

* free monitor connection before getting a new one

* fix unit tests

* test

* disable failover and monitoring for monitor thread

* fix memory leak in unit test

* needs connection handler for monitor

* add null check in monitor service start monitoring

* fix env handle still used after deleting

* comment out mysql_library_init

* move connection handler to its own header file
  • Loading branch information
yanw-bq authored Mar 16, 2023
1 parent 01cff38 commit 00542dd
Show file tree
Hide file tree
Showing 31 changed files with 1,300 additions and 672 deletions.
8 changes: 4 additions & 4 deletions driver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT})
base_metrics_holder.cc catalog.cc catalog_no_i_s.cc cluster_topology_info.cc
cluster_aware_hit_metrics_holder.cc cluster_aware_metrics_container.cc
cluster_aware_metrics.cc cluster_aware_time_metrics_holder.cc
connect.cc cursor.cc desc.cc dll.cc driver.cc
error.cc execute.cc failover_connection_handler.cc failover_handler.cc
connect.cc connection_handler.cc cursor.cc desc.cc dll.cc driver.cc efm_proxy.cc
error.cc execute.cc failover_handler.cc
failover_reader_handler.cc failover_writer_handler.cc handle.cc host_info.cc info.cc
monitor.cc monitor_connection_context.cc monitor_service.cc monitor_thread_container.cc
my_prepared_stmt.cc my_stmt.cc mylog.cc mysql_proxy.cc options.cc parse.cc prepare.cc query_parsing.cc
Expand All @@ -83,8 +83,8 @@ WHILE(${DRIVER_INDEX} LESS ${DRIVERS_COUNT})
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/driver/driver.rc.cmake ${CMAKE_SOURCE_DIR}/driver/driver${CONNECTOR_DRIVER_TYPE_SHORT}.rc @ONLY)
SET(DRIVER_SRCS ${DRIVER_SRCS} driver${CONNECTOR_DRIVER_TYPE_SHORT}.def driver${CONNECTOR_DRIVER_TYPE_SHORT}.rc
base_metrics_holder.h catalog.h cluster_aware_hit_metrics_holder.h cluster_aware_metrics_container.h
cluster_aware_metrics.h cluster_aware_time_metrics_holder.h cluster_topology_info.h
driver.h error.h failover.h host_info.h monitor.h monitor_connection_context.h monitor_service.h
cluster_aware_metrics.h cluster_aware_time_metrics_holder.h cluster_topology_info.h connection_handler.h
driver.h efm_proxy.h error.h failover.h host_info.h monitor.h monitor_connection_context.h monitor_service.h
monitor_thread_container.h mylog.h mysql_proxy.h myutil.h parse.h query_parsing.h topology_service.h
../MYODBC_MYSQL.h ../MYODBC_CONF.h ../MYODBC_ODBC.h)
ENDIF(WIN32)
Expand Down
11 changes: 7 additions & 4 deletions driver/connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@ SQLRETURN DBC::connect(DataSource *dsrc, bool failover_enabled)
ds_set_strnattr(&dsrc->server8, (SQLCHAR*)host, strlen(host));
dsrc->port = port;

Aws::SDKOptions options;
//Aws::SDKOptions options;
//Aws::InitAPI(options); TODO: causing SSL connection error: SSL_CTX_new failed
//Aws::ShutdownAPI(options);

Expand Down Expand Up @@ -1056,7 +1056,8 @@ SQLRETURN SQL_API MySQLConnect(SQLHDBC hdbc,
if (ds->save_queries && !dbc->log_file)
dbc->log_file = init_log_file();

dbc->mysql_proxy = new MYSQL_PROXY(dbc, ds);
dbc->init_proxy_chain(ds);
dbc->connection_handler = std::make_shared<CONNECTION_HANDLER>(dbc);
dbc->fh = new FAILOVER_HANDLER(dbc, ds);
rc = dbc->fh->init_cluster_info();
if (!dbc->ds)
Expand Down Expand Up @@ -1173,7 +1174,8 @@ SQLRETURN SQL_API MySQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd,
if (ds->save_queries && !dbc->log_file)
dbc->log_file = init_log_file();

dbc->mysql_proxy = new MYSQL_PROXY(dbc, ds);
dbc->init_proxy_chain(ds);
dbc->connection_handler = std::make_shared<CONNECTION_HANDLER>(dbc);
dbc->fh = new FAILOVER_HANDLER(dbc, ds);
rc = dbc->fh->init_cluster_info();
if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
Expand Down Expand Up @@ -1352,7 +1354,8 @@ SQLRETURN SQL_API MySQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd,
if (ds->save_queries && !dbc->log_file)
dbc->log_file = init_log_file();

dbc->mysql_proxy = new MYSQL_PROXY(dbc, ds);
dbc->init_proxy_chain(ds);
dbc->connection_handler = std::make_shared<CONNECTION_HANDLER>(dbc);
dbc->fh = new FAILOVER_HANDLER(dbc, ds);
rc = dbc->fh->init_cluster_info();
if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,13 @@
// http://www.gnu.org/licenses/gpl-2.0.html.

/**
@file failover_connection_handler.c
@brief Failover connection functions.
@file connection_handler.c
@brief connection functions.
*/

#include "connection_handler.h"
#include "driver.h"
#include "failover.h"
#include "mysql_proxy.h"

#include <codecvt>
#include <locale>
Expand All @@ -51,32 +52,36 @@
}
#endif

FAILOVER_CONNECTION_HANDLER::FAILOVER_CONNECTION_HANDLER(DBC* dbc) : dbc{dbc} {}
CONNECTION_HANDLER::CONNECTION_HANDLER(DBC* dbc) : dbc{dbc} {}

FAILOVER_CONNECTION_HANDLER::~FAILOVER_CONNECTION_HANDLER() {}
CONNECTION_HANDLER::~CONNECTION_HANDLER() = default;

SQLRETURN FAILOVER_CONNECTION_HANDLER::do_connect(DBC* dbc_ptr, DataSource* ds, bool failover_enabled) {
SQLRETURN CONNECTION_HANDLER::do_connect(DBC* dbc_ptr, DataSource* ds, bool failover_enabled) {
return dbc_ptr->connect(ds, failover_enabled);
}

MYSQL_PROXY* FAILOVER_CONNECTION_HANDLER::connect(const std::shared_ptr<HOST_INFO>& host_info) {
MYSQL_PROXY* CONNECTION_HANDLER::connect(const std::shared_ptr<HOST_INFO>& host_info, DataSource* ds) {

if (dbc == nullptr || dbc->ds == nullptr || host_info == nullptr) {
if (dbc == nullptr || host_info == nullptr) {
return nullptr;
}

DataSource* ds_to_use = ds_new();
ds_copy(ds_to_use, ds ? ds : dbc->ds);

const auto new_host = to_sqlwchar_string(host_info->get_host());

DBC* dbc_clone = clone_dbc(dbc);
ds_set_wstrnattr(&dbc_clone->ds->server, (SQLWCHAR*)new_host.c_str(), new_host.size());
DBC* dbc_clone = clone_dbc(dbc, ds_to_use);
ds_set_wstrnattr(&ds_to_use->server, (SQLWCHAR*)new_host.c_str(), new_host.size());

MYSQL_PROXY* new_connection = nullptr;
CLEAR_DBC_ERROR(dbc_clone);
const SQLRETURN rc = do_connect(dbc_clone, dbc_clone->ds, true);
const SQLRETURN rc = do_connect(dbc_clone, ds_to_use, ds_to_use->enable_cluster_failover);

if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO) {
new_connection = dbc_clone->mysql_proxy;
dbc_clone->mysql_proxy = nullptr;
// postpone the deletion of ds_to_use/dbc_clone->ds until we are done with new_connection
dbc_clone->ds = nullptr;
}

Expand All @@ -85,7 +90,7 @@ MYSQL_PROXY* FAILOVER_CONNECTION_HANDLER::connect(const std::shared_ptr<HOST_INF
return new_connection;
}

void FAILOVER_CONNECTION_HANDLER::update_connection(
void CONNECTION_HANDLER::update_connection(
MYSQL_PROXY* new_connection, const std::string& new_host_name) {

if (new_connection->is_connected()) {
Expand All @@ -102,7 +107,7 @@ void FAILOVER_CONNECTION_HANDLER::update_connection(
}
}

DBC* FAILOVER_CONNECTION_HANDLER::clone_dbc(DBC* source_dbc) {
DBC* CONNECTION_HANDLER::clone_dbc(DBC* source_dbc, DataSource* ds) {

DBC* dbc_clone = nullptr;

Expand All @@ -114,11 +119,9 @@ DBC* FAILOVER_CONNECTION_HANDLER::clone_dbc(DBC* source_dbc) {
status = my_SQLAllocConnect(henv, &hdbc);
if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) {
dbc_clone = static_cast<DBC*>(hdbc);
dbc_clone->ds = ds_new();
ds_copy(dbc_clone->ds, source_dbc->ds);
dbc_clone->mysql_proxy = new MYSQL_PROXY(dbc_clone, dbc_clone->ds);
dbc_clone->init_proxy_chain(ds);
} else {
const char* err = "Cannot allocate connection handle when cloning DBC in writer failover process";
const char* err = "Cannot allocate connection handle when cloning DBC";
MYLOG_DBC_TRACE(dbc, err);
throw std::runtime_error(err);
}
Expand Down
64 changes: 64 additions & 0 deletions driver/connection_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0
// (GPLv2), as published by the Free Software Foundation, with the
// following additional permissions:
//
// This program is distributed with certain software that is licensed
// under separate terms, as designated in a particular file or component
// or in the license documentation. Without limiting your rights under
// the GPLv2, the authors of this program hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have included with the program.
//
// Without limiting the foregoing grant of rights under the GPLv2 and
// additional permission as to separately licensed software, this
// program is also subject to the Universal FOSS Exception, version 1.0,
// a copy of which can be found along with its FAQ at
// http://oss.oracle.com/licenses/universal-foss-exception.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License, version 2.0, for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see
// http://www.gnu.org/licenses/gpl-2.0.html.

#ifndef __CONNECTION_HANDLER_H__
#define __CONNECTION_HANDLER_H__

#include "host_info.h"

#include <memory>

#ifdef __linux__
typedef std::u16string sqlwchar_string;
#else
typedef std::wstring sqlwchar_string;
#endif

sqlwchar_string to_sqlwchar_string(const std::string& src);

struct DBC;
struct DataSource;
class MYSQL_PROXY;
typedef short SQLRETURN;

class CONNECTION_HANDLER {
public:
CONNECTION_HANDLER(DBC* dbc);
virtual ~CONNECTION_HANDLER();

virtual SQLRETURN do_connect(DBC* dbc_ptr, DataSource* ds, bool failover_enabled);
virtual MYSQL_PROXY* connect(const std::shared_ptr<HOST_INFO>& host_info, DataSource* ds);
void update_connection(MYSQL_PROXY* new_connection, const std::string& new_host_name);

private:
DBC* dbc;
DBC* clone_dbc(DBC* source_dbc, DataSource* ds);
};

#endif /* __CONNECTION_HANDLER_H__ */
6 changes: 5 additions & 1 deletion driver/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@
#include "../MYODBC_MYSQL.h"
#include "../MYODBC_CONF.h"
#include "../MYODBC_ODBC.h"
#include "util/installer.h"
#include "connection_handler.h"
#include "efm_proxy.h"
#include "failover.h"
#include "mysql_proxy.h"
#include "util/installer.h"

/* Disable _attribute__ on non-gcc compilers. */
#if !defined(__attribute__) && !defined(__GNUC__)
Expand Down Expand Up @@ -643,6 +645,7 @@ struct DBC
fido_callback_func fido_callback = nullptr;

FAILOVER_HANDLER *fh = nullptr; /* Failover handler */
std::shared_ptr<CONNECTION_HANDLER> connection_handler = nullptr;

DBC(ENV *p_env);
void free_explicit_descriptors();
Expand All @@ -654,6 +657,7 @@ struct DBC
SQLRETURN connect(DataSource *dsrc, bool failover_enabled);
void execute_prep_stmt(MYSQL_STMT *pstmt, std::string &query,
MYSQL_BIND *param_bind, MYSQL_BIND *result_bind);
void init_proxy_chain(DataSource *dsrc);

inline bool transactions_supported() {
return mysql_proxy->get_server_capabilities() & CLIENT_TRANSACTIONS;
Expand Down
Loading

0 comments on commit 00542dd

Please sign in to comment.