diff --git a/include/Base_Session.h b/include/Base_Session.h index 0df62cbb7..2c7a54db5 100644 --- a/include/Base_Session.h +++ b/include/Base_Session.h @@ -126,6 +126,23 @@ class Base_Session { >::type; void update_expired_conns(const std::vector>&); + void set_unhealthy(); + unsigned int NumActiveTransactions(bool check_savpoint=false); + bool HasOfflineBackends(); + bool SetEventInOfflineBackends(); + /** + * @brief Finds one active transaction in the current backend connections. + * @details Since only one connection is returned, if the session holds multiple backend connections with + * potential transactions, the priority is: + * 1. Connections flagged with 'SERVER_STATUS_IN_TRANS', or 'autocommit=0' in combination with + * 'autocommit_false_is_transaction'. + * 2. Connections with 'autocommit=0' holding a 'SAVEPOINT'. + * 3. Connections with 'unknown transaction status', e.g: connections with errors. + * @param check_savepoint Used to also check for connections holding savepoints. See MySQL bug + * https://bugs.mysql.com/bug.php?id=107875. + * @returns The hostgroup in which the connection was found, -1 in case no connection is found. + */ + int FindOneActiveTransaction(bool check_savepoint=false); }; #endif // CLASS_BASE_SESSION_H diff --git a/include/MySQL_Session.h b/include/MySQL_Session.h index 90f481ecf..22d89f258 100644 --- a/include/MySQL_Session.h +++ b/include/MySQL_Session.h @@ -386,7 +386,7 @@ class MySQL_Session: public Base_Session::update_expired_conns(std::vector, std::allocator > > const&); template void Base_Session::update_expired_conns(std::vector, std::allocator > > const&); +template unsigned int Base_Session::NumActiveTransactions(bool); +template unsigned int Base_Session::NumActiveTransactions(bool); + +template void Base_Session::set_unhealthy(); +template void Base_Session::set_unhealthy(); + +template int Base_Session::FindOneActiveTransaction(bool); +template int Base_Session::FindOneActiveTransaction(bool); + +template bool Base_Session::HasOfflineBackends(); +template bool Base_Session::HasOfflineBackends(); + +template bool Base_Session::SetEventInOfflineBackends(); +template bool Base_Session::SetEventInOfflineBackends(); template Base_Session::Base_Session() { @@ -548,3 +562,108 @@ void Base_Session::update_expired_conns(const vector +void Base_Session::set_unhealthy() { + proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p\n", this); + healthy=0; +} + + +template +unsigned int Base_Session::NumActiveTransactions(bool check_savepoint) { + unsigned int ret=0; + if (mybes==0) return ret; + B *_mybe; + unsigned int i; + for (i=0; i < mybes->len; i++) { + _mybe=(B *)mybes->index(i); + if (_mybe->server_myds) { + if (_mybe->server_myds->myconn) { + if (_mybe->server_myds->myconn->IsActiveTransaction()) { + ret++; + } else { + // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due + // to MySQL bug https://bugs.mysql.com/bug.php?id=107875 related to + // SAVEPOINT and autocommit=0 + if (check_savepoint) { + if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { + ret++; + } + } + } + } + } + } + return ret; +} + +template +bool Base_Session::HasOfflineBackends() { + bool ret=false; + if (mybes==0) return ret; + B * _mybe; + unsigned int i; + for (i=0; i < mybes->len; i++) { + _mybe=(B *)mybes->index(i); + if (_mybe->server_myds) + if (_mybe->server_myds->myconn) + if (_mybe->server_myds->myconn->IsServerOffline()) { + ret=true; + return ret; + } + } + return ret; +} + +template +bool Base_Session::SetEventInOfflineBackends() { + bool ret=false; + if (mybes==0) return ret; + B * _mybe; + unsigned int i; + for (i = 0; i < mybes->len; i++) { + _mybe = (B *) mybes->index(i); + if (_mybe->server_myds) + if (_mybe->server_myds->myconn) + if (_mybe->server_myds->myconn->IsServerOffline()) { + _mybe->server_myds->revents |= POLLIN; + ret = true; + } + } + return ret; +} + + +template +int Base_Session::FindOneActiveTransaction(bool check_savepoint) { + int ret=-1; + if (mybes==0) return ret; + B * _mybe; + unsigned int i; + for (i=0; i < mybes->len; i++) { + _mybe = (B *) mybes->index(i); + if (_mybe->server_myds) { + if (_mybe->server_myds->myconn) { + if (_mybe->server_myds->myconn->IsKnownActiveTransaction()) { + return (int)_mybe->server_myds->myconn->parent->myhgc->hid; + } + else if (_mybe->server_myds->myconn->IsActiveTransaction()) { + ret = (int)_mybe->server_myds->myconn->parent->myhgc->hid; + } + else { + // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due + // to MySQL bug https://bugs.mysql.com/bug.php?id=107875 related to + // SAVEPOINT and autocommit=0 + if (check_savepoint) { + if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { + return (int)_mybe->server_myds->myconn->parent->myhgc->hid; + } + } + } + } + } + } + return ret; +} diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index e6d0a117e..41d116620 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -7355,102 +7355,6 @@ void MySQL_Session::SQLite3_to_MySQL(SQLite3_result *result, char *error, int af } } -void MySQL_Session::set_unhealthy() { - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p\n", this); - healthy=0; -} - - -unsigned int MySQL_Session::NumActiveTransactions(bool check_savepoint) { - unsigned int ret=0; - if (mybes==0) return ret; - MySQL_Backend *_mybe; - unsigned int i; - for (i=0; i < mybes->len; i++) { - _mybe=(MySQL_Backend *)mybes->index(i); - if (_mybe->server_myds) { - if (_mybe->server_myds->myconn) { - if (_mybe->server_myds->myconn->IsActiveTransaction()) { - ret++; - } else { - // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due - // to MySQL bug https://bugs.mysql.com/bug.php?id=107875 related to - // SAVEPOINT and autocommit=0 - if (check_savepoint) { - if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { - ret++; - } - } - } - } - } - } - return ret; -} - -bool MySQL_Session::HasOfflineBackends() { - bool ret=false; - if (mybes==0) return ret; - MySQL_Backend *_mybe; - unsigned int i; - for (i=0; i < mybes->len; i++) { - _mybe=(MySQL_Backend *)mybes->index(i); - if (_mybe->server_myds) - if (_mybe->server_myds->myconn) - if (_mybe->server_myds->myconn->IsServerOffline()) { - ret=true; - return ret; - } - } - return ret; -} - -bool MySQL_Session::SetEventInOfflineBackends() { - bool ret=false; - if (mybes==0) return ret; - MySQL_Backend *_mybe; - unsigned int i; - for (i=0; i < mybes->len; i++) { - _mybe=(MySQL_Backend *)mybes->index(i); - if (_mybe->server_myds) - if (_mybe->server_myds->myconn) - if (_mybe->server_myds->myconn->IsServerOffline()) { - _mybe->server_myds->revents|=POLLIN; - ret = true; - } - } - return ret; -} - -int MySQL_Session::FindOneActiveTransaction(bool check_savepoint) { - int ret=-1; - if (mybes==0) return ret; - MySQL_Backend *_mybe; - unsigned int i; - for (i=0; i < mybes->len; i++) { - _mybe=(MySQL_Backend *)mybes->index(i); - if (_mybe->server_myds) { - if (_mybe->server_myds->myconn) { - if (_mybe->server_myds->myconn->IsKnownActiveTransaction()) { - return (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } else if (_mybe->server_myds->myconn->IsActiveTransaction()) { - ret = (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } else { - // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due - // to MySQL bug https://bugs.mysql.com/bug.php?id=107875 related to - // SAVEPOINT and autocommit=0 - if (check_savepoint) { - if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { - return (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } - } - } - } - } - } - return ret; -} - unsigned long long MySQL_Session::IdleTime() { unsigned long long ret = 0; if (client_myds==0) return 0; @@ -7466,7 +7370,6 @@ unsigned long long MySQL_Session::IdleTime() { } - // this is called either from RequestEnd(), or at the end of executing // prepared statements void MySQL_Session::LogQuery(MySQL_Data_Stream *myds) { diff --git a/lib/PgSQL_Session.cpp b/lib/PgSQL_Session.cpp index cc8b7ad0e..be9287df7 100644 --- a/lib/PgSQL_Session.cpp +++ b/lib/PgSQL_Session.cpp @@ -7205,105 +7205,6 @@ void PgSQL_Session::SQLite3_to_MySQL(SQLite3_result* result, char* error, int af } } -void PgSQL_Session::set_unhealthy() { - proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess:%p\n", this); - healthy = 0; -} - - -unsigned int PgSQL_Session::NumActiveTransactions(bool check_savepoint) { - unsigned int ret = 0; - if (mybes == 0) return ret; - PgSQL_Backend* _mybe; - unsigned int i; - for (i = 0; i < mybes->len; i++) { - _mybe = (PgSQL_Backend*)mybes->index(i); - if (_mybe->server_myds) { - if (_mybe->server_myds->myconn) { - if (_mybe->server_myds->myconn->IsActiveTransaction()) { - ret++; - } - else { - // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due - // to MySQL bug https://bugs.pgsql.com/bug.php?id=107875 related to - // SAVEPOINT and autocommit=0 - if (check_savepoint) { - if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { - ret++; - } - } - } - } - } - } - return ret; -} - -bool PgSQL_Session::HasOfflineBackends() { - bool ret = false; - if (mybes == 0) return ret; - PgSQL_Backend* _mybe; - unsigned int i; - for (i = 0; i < mybes->len; i++) { - _mybe = (PgSQL_Backend*)mybes->index(i); - if (_mybe->server_myds) - if (_mybe->server_myds->myconn) - if (_mybe->server_myds->myconn->IsServerOffline()) { - ret = true; - return ret; - } - } - return ret; -} - -bool PgSQL_Session::SetEventInOfflineBackends() { - bool ret = false; - if (mybes == 0) return ret; - PgSQL_Backend* _mybe; - unsigned int i; - for (i = 0; i < mybes->len; i++) { - _mybe = (PgSQL_Backend*)mybes->index(i); - if (_mybe->server_myds) - if (_mybe->server_myds->myconn) - if (_mybe->server_myds->myconn->IsServerOffline()) { - _mybe->server_myds->revents |= POLLIN; - ret = true; - } - } - return ret; -} - -int PgSQL_Session::FindOneActiveTransaction(bool check_savepoint) { - int ret = -1; - if (mybes == 0) return ret; - PgSQL_Backend* _mybe; - unsigned int i; - for (i = 0; i < mybes->len; i++) { - _mybe = (PgSQL_Backend*)mybes->index(i); - if (_mybe->server_myds) { - if (_mybe->server_myds->myconn) { - if (_mybe->server_myds->myconn->IsKnownActiveTransaction()) { - return (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } - else if (_mybe->server_myds->myconn->IsActiveTransaction()) { - ret = (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } - else { - // we use check_savepoint to check if we shouldn't ignore COMMIT or ROLLBACK due - // to MySQL bug https://bugs.pgsql.com/bug.php?id=107875 related to - // SAVEPOINT and autocommit=0 - if (check_savepoint) { - if (_mybe->server_myds->myconn->AutocommitFalse_AndSavepoint() == true) { - return (int)_mybe->server_myds->myconn->parent->myhgc->hid; - } - } - } - } - } - } - return ret; -} - unsigned long long PgSQL_Session::IdleTime() { unsigned long long ret = 0; if (client_myds == 0) return 0;