fix dblink bugs

This commit is contained in:
cqliang1995 2023-07-13 14:23:58 +00:00 committed by ob-robot
parent f1bcb57e3a
commit 59a7f93a3f
23 changed files with 509 additions and 300 deletions

View File

@ -16,6 +16,7 @@
#include "lib/ob_define.h"
#include "lib/mysqlclient/ob_isql_client.h"
#include "lib/timezone/ob_timezone_info.h"
#include "lib/mysqlclient/ob_isql_connection_pool.h"
namespace oceanbase
{
@ -41,7 +42,7 @@ public:
//dblink
virtual int free_dblink_session(uint32_t sessid) = 0;
virtual int release(common::sqlclient::ObISQLConnection *connection, const bool succ, uint32_t sessid = 0) = 0;
virtual int release(common::sqlclient::ObISQLConnection *connection, const bool succ) = 0;
TO_STRING_KV(K_(free_conn_count), K_(busy_conn_count));
protected:
volatile uint64_t free_conn_count_;
@ -74,20 +75,26 @@ class ObISQLConnection
public:
ObISQLConnection() :
oracle_mode_(false),
is_init_remote_env_(false),
is_inited_(false),
dblink_id_(OB_INVALID_ID),
dblink_driver_proto_(-1),
dblink_driver_proto_(DBLINK_UNKNOWN),
sessid_(-1),
consumer_group_id_(0),
has_reverse_link_credentials_(false),
usable_(true),
last_set_sql_mode_cstr_(NULL),
last_set_sql_mode_cstr_buf_size_(0)
last_set_sql_mode_cstr_buf_size_(0),
last_set_client_charset_cstr_(NULL),
last_set_connection_charset_cstr_(NULL),
last_set_results_charset_cstr_(NULL)
{}
virtual ~ObISQLConnection() {
allocator_.reset();
last_set_sql_mode_cstr_buf_size_ = 0;
last_set_sql_mode_cstr_ = NULL;
last_set_client_charset_cstr_ = NULL;
last_set_connection_charset_cstr_ = NULL;
last_set_results_charset_cstr_ = NULL;
}
// sql execute interface
@ -127,8 +134,8 @@ public:
uint64_t get_dblink_id() { return dblink_id_; }
void set_sessid(uint32_t sessid) { sessid_ = sessid; }
uint32_t get_sessid() { return sessid_; }
void set_dblink_driver_proto(int64_t dblink_driver_proto) { dblink_driver_proto_ = dblink_driver_proto; }
int64_t get_dblink_driver_proto() { return dblink_driver_proto_; }
void set_dblink_driver_proto(DblinkDriverProto dblink_driver_proto) { dblink_driver_proto_ = dblink_driver_proto; }
DblinkDriverProto get_dblink_driver_proto() { return dblink_driver_proto_; }
void set_mysql_compat_mode() { oracle_mode_ = false; }
void set_oracle_compat_mode() { oracle_mode_ = true; }
@ -140,20 +147,24 @@ public:
virtual void set_force_remote_exec(bool v) { UNUSED(v); }
virtual void set_use_external_session(bool v) { UNUSED(v); }
virtual int64_t get_cluster_id() const { return common::OB_INVALID_ID; }
void set_init_remote_env(bool flag) { is_init_remote_env_ = flag;}
int is_session_inited(const char * sql_mode_cstr, bool &is_inited) {
void set_session_init_status(bool status) { is_inited_ = status;}
int is_session_inited(const sqlclient::dblink_param_ctx &param_ctx, bool &is_inited)
{
int ret = OB_SUCCESS;
is_inited = false;
int64_t sql_mode_len = 0;
const char *sql_mode_cstr = param_ctx.set_sql_mode_cstr_;
if (lib::is_oracle_mode()) {
is_inited = is_init_remote_env_;
} else if (OB_ISNULL(sql_mode_cstr)) {
ret = OB_ERR_UNEXPECTED;
is_inited = is_inited_;
} else if (FALSE_IT([&]{
is_inited = (0 == ObString(sql_mode_cstr).compare(last_set_sql_mode_cstr_));
sql_mode_len = STRLEN(sql_mode_cstr);
if (OB_NOT_NULL(sql_mode_cstr)) {
is_inited = (0 == ObString(sql_mode_cstr).compare(last_set_sql_mode_cstr_));
sql_mode_len = STRLEN(sql_mode_cstr);
} else {
is_inited = true;
}
}())) {
} else if (!is_inited) {
} else if (!is_inited && OB_NOT_NULL(sql_mode_cstr)) {
if (sql_mode_len >= last_set_sql_mode_cstr_buf_size_) {
void *buf = NULL;
if (OB_ISNULL(buf = allocator_.alloc((sql_mode_len * 2)))) {
@ -168,6 +179,14 @@ public:
last_set_sql_mode_cstr_[sql_mode_len] = 0;
}
}
if (param_ctx.set_client_charset_cstr_ != last_set_client_charset_cstr_ ||
param_ctx.set_connection_charset_cstr_ != last_set_connection_charset_cstr_ ||
param_ctx.set_results_charset_cstr_ != last_set_results_charset_cstr_) {
is_inited = false;
last_set_client_charset_cstr_ = param_ctx.set_client_charset_cstr_;
last_set_connection_charset_cstr_ = param_ctx.set_connection_charset_cstr_;
last_set_results_charset_cstr_ = param_ctx.set_results_charset_cstr_;
}
return ret;
}
void set_group_id(const int64_t v) {consumer_group_id_ = v; }
@ -179,15 +198,18 @@ public:
virtual int ping() { return OB_SUCCESS; }
protected:
bool oracle_mode_;
bool is_init_remote_env_; // for oracle dblink, we have to init remote env with some sql
bool is_inited_; // for oracle dblink, we have to init remote env with some sql
uint64_t dblink_id_; // for dblink, record dblink_id of a connection used by dblink
int64_t dblink_driver_proto_; //for dblink, record DblinkDriverProto of a connection used by dblink
DblinkDriverProto dblink_driver_proto_; //for dblink, record DblinkDriverProto of a connection used by dblink
uint32_t sessid_;
int64_t consumer_group_id_; //for resource isolation
bool has_reverse_link_credentials_; // for dblink, mark if this link has credentials set
bool usable_; // usable_ = false: connection is unusable, should not execute query again.
char *last_set_sql_mode_cstr_; // for mysql dblink to set sql mode
int64_t last_set_sql_mode_cstr_buf_size_;
const char *last_set_client_charset_cstr_;
const char *last_set_connection_charset_cstr_;
const char *last_set_results_charset_cstr_;
common::ObArenaAllocator allocator_;
};

View File

@ -56,7 +56,7 @@ enum DblinkDriverProto{
DBLINK_DRV_OCI,
};
enum DblinkPoolType{
enum DblinkPoolType {
DBLINK_POOL_UNKNOW = -1,
DBLINK_POOL_DEF = 0, // for link scan read write
DBLINK_POOL_SCHEMA = 1, // for schema read
@ -66,12 +66,41 @@ struct dblink_param_ctx{
uint16_t charset_id_; // this link expected charset id for string column
uint16_t ncharset_id_; // this link expected national charset id for nvarchar
DblinkPoolType pool_type_;
DblinkDriverProto link_type_;
uint32_t sessid_;
uint64_t tenant_id_;
uint64_t dblink_id_;
int64_t sql_request_level_;
const char *set_sql_mode_cstr_;
const char *set_client_charset_cstr_;
const char *set_connection_charset_cstr_;
const char *set_results_charset_cstr_;
dblink_param_ctx() :
charset_id_(static_cast<uint16_t>(common::ObNlsCharsetId::CHARSET_AL32UTF8_ID)), //utf8, deault value, don't modify it cause dblink pull meta need it
ncharset_id_(static_cast<uint16_t>(common::ObNlsCharsetId::CHARSET_AL32UTF8_ID)), //utf8, deault value, don't modify it cause dblink pull meta need it
pool_type_(DBLINK_POOL_DEF)
pool_type_(DBLINK_POOL_DEF),
link_type_(DblinkDriverProto::DBLINK_UNKNOWN),
sessid_(0),
tenant_id_(OB_INVALID_ID),
dblink_id_(OB_INVALID_ID),
sql_request_level_(0),
set_sql_mode_cstr_(NULL),
set_client_charset_cstr_(NULL),
set_connection_charset_cstr_(NULL),
set_results_charset_cstr_(NULL)
{ }
TO_STRING_KV(K_(charset_id), K_(ncharset_id), K_(pool_type));
TO_STRING_KV(K_(charset_id),
K_(ncharset_id),
K_(pool_type),
K_(link_type),
K_(sessid),
K_(tenant_id),
K_(dblink_id),
K_(sql_request_level),
K_(set_sql_mode_cstr),
K_(set_client_charset_cstr),
K_(set_connection_charset_cstr),
K_(set_results_charset_cstr));
};
class ObISQLConnectionPool
@ -90,24 +119,20 @@ public:
return this->acquire(OB_INVALID_TENANT_ID, conn, client_addr);
}
virtual int acquire(const uint64_t tenant_id, ObISQLConnection *&conn, ObISQLClient *client_addr) = 0;
virtual int release(ObISQLConnection *conn, const bool success, uint32_t sessid = 0) = 0;
virtual int release(ObISQLConnection *conn, const bool success) = 0;
virtual int on_client_inactive(ObISQLClient *client_addr) = 0;
virtual ObSQLConnPoolType get_type() = 0;
virtual DblinkDriverProto get_pool_link_driver_proto() = 0;
// for dblink
virtual int create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const dblink_param_ctx &param_ctx) = 0;
virtual int acquire_dblink(uint64_t tenant_id, uint64_t dblink_id, const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn, uint32_t sessid,
int64_t sql_request_level = 0) = 0;
virtual int release_dblink(ObISQLConnection *dblink_conn, uint32_t sessid = 0) = 0;
virtual int do_acquire_dblink(uint64_t tenant_id, uint64_t dblink_id, const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn, uint32_t sessid) = 0;
virtual int create_dblink_pool(const dblink_param_ctx &param_ctx, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str) = 0;
virtual int acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn) = 0;
virtual int release_dblink(ObISQLConnection *dblink_conn) = 0;
virtual int do_acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn) = 0;
virtual int try_connect_dblink(ObISQLConnection *dblink_conn, int64_t sql_request_level = 0) = 0;
virtual int clean_dblink_connection(uint64_t tenant_id) = 0;
};

View File

@ -263,7 +263,7 @@ void ObMySQLConnection::close()
closed_ = true;
sessid_ = 0;
memset(&mysql_, 0, sizeof(MYSQL));
set_init_remote_env(false);
set_session_init_status(false);
}
}

View File

@ -573,7 +573,7 @@ int ObMySQLConnectionPool::execute_init_sql(ObMySQLConnection *connection)
return ret;
}
int ObMySQLConnectionPool::release(ObMySQLConnection *connection, const bool succ, uint32_t sessid)
int ObMySQLConnectionPool::release(ObMySQLConnection *connection, const bool succ)
{
int ret = OB_SUCCESS;
obsys::ObRLockGuard lock(get_lock_);
@ -592,7 +592,7 @@ int ObMySQLConnectionPool::release(ObMySQLConnection *connection, const bool suc
if (OB_ISNULL(pool = connection->get_root())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to release connection. connection pool not set", K(ret));
} else if (OB_FAIL(pool->release(connection, succ, sessid))) {
} else if (OB_FAIL(pool->release(connection, succ))) {
LOG_WARN("fail to release connection", K(ret));
}
}
@ -601,7 +601,7 @@ int ObMySQLConnectionPool::release(ObMySQLConnection *connection, const bool suc
ATOMIC_DEC((uint64_t *)&busy_conn_count_);
}
LOG_TRACE("release connection to mysql connection pool", K(this), K(busy_conn_count_),
KP(connection), K(connection->is_closed()), K(pool), K(ret), K(sessid), K(lbt()));
KP(connection), K(connection->is_closed()), K(pool), K(ret), K(connection->get_sessid()), K(lbt()));
return ret;
}
@ -711,7 +711,7 @@ int ObMySQLConnectionPool::acquire(const uint64_t tenant_id, ObISQLConnection *&
return ret;
}
int ObMySQLConnectionPool::release(ObISQLConnection *conn, const bool success, uint32_t sessid)
int ObMySQLConnectionPool::release(ObISQLConnection *conn, const bool success)
{
int ret = OB_SUCCESS;
if (NULL != conn) {
@ -720,7 +720,7 @@ int ObMySQLConnectionPool::release(ObISQLConnection *conn, const bool success, u
if (OB_ISNULL(mysql_conn)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("ObMySQLConnectionPool only release ObMySQLConnection", K(ret));
} else if (OB_FAIL(release(mysql_conn, success, sessid))) {
} else if (OB_FAIL(release(mysql_conn, success))) {
LOG_WARN("release connection failed", K(ret));
}
}
@ -750,19 +750,18 @@ int ObMySQLConnectionPool::escape(const char *from, const int64_t from_size,
}
return ret;
}
int ObMySQLConnectionPool::create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const dblink_param_ctx &param_ctx)
int ObMySQLConnectionPool::create_dblink_pool(const dblink_param_ctx &param_ctx, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str)
{
UNUSEDx(param_ctx);
int ret = OB_SUCCESS;
ObServerConnectionPool *dblink_pool = NULL;
if (OB_FAIL(get_dblink_pool(tenant_id, dblink_id, dblink_pool))) {
LOG_WARN("fail to get dblink connection pool", K(dblink_id));
if (OB_FAIL(get_dblink_pool(param_ctx, dblink_pool))) {
LOG_WARN("fail to get dblink connection pool", K(param_ctx));
} else if (OB_NOT_NULL(dblink_pool)) {
// nothing.
} else {
@ -770,14 +769,15 @@ int ObMySQLConnectionPool::create_dblink_pool(uint64_t tenant_id, uint64_t dblin
// can not use obsys::ObWLockGuard lock(get_lock_), cause it will have dead lock
// use a new lock for create_dblink_pool
obsys::ObWLockGuard lock(dblink_pool_lock_);
if (OB_FAIL(get_dblink_pool(tenant_id, dblink_id, dblink_pool))) { //get again
LOG_WARN("fail to get dblink connection pool", K(dblink_id));
if (OB_FAIL(get_dblink_pool(param_ctx, dblink_pool))) { //get again
LOG_WARN("fail to get dblink connection pool", K(param_ctx));
} else if (OB_NOT_NULL(dblink_pool)) {
// nothing.
} else if (OB_ISNULL(dblink_pool = server_pool_.alloc())) {
ret = OB_ALLOCATE_MEMORY_FAILED;
LOG_ERROR("out of memory", K(ret));
} else if (OB_FAIL(dblink_pool->init_dblink(tenant_id, dblink_id, server, db_tenant, db_user, db_pass,
} else if (OB_FAIL(dblink_pool->init_dblink(param_ctx.tenant_id_, param_ctx.dblink_id_,
server, db_tenant, db_user, db_pass,
db_name, conn_str, cluster_str,
this, config_.sqlclient_per_observer_conn_limit_))) {
LOG_WARN("fail to init dblink connection pool", K(ret));
@ -794,37 +794,33 @@ int ObMySQLConnectionPool::create_dblink_pool(uint64_t tenant_id, uint64_t dblin
return ret;
}
int ObMySQLConnectionPool::acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn,
uint32_t sessid, int64_t sql_request_level)
int ObMySQLConnectionPool::acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn)
{
int ret = OB_SUCCESS;
if (OB_FAIL(do_acquire_dblink(tenant_id, dblink_id, param_ctx, dblink_conn, sessid))) {
LOG_WARN("fail to acquire dblink", K(ret), K(dblink_id));
} else if (OB_FAIL(try_connect_dblink(dblink_conn, sql_request_level))) {
LOG_WARN("fail to try connect dblink", K(ret), K(dblink_id));
int release_ret = release_dblink(dblink_conn, sessid);
if (OB_FAIL(do_acquire_dblink(param_ctx, dblink_conn))) {
LOG_WARN("fail to acquire dblink", K(ret), K(param_ctx));
} else if (OB_FAIL(try_connect_dblink(dblink_conn, param_ctx.sql_request_level_))) {
LOG_WARN("fail to try connect dblink", K(ret), K(param_ctx));
int release_ret = release_dblink(dblink_conn);
if (release_ret != OB_SUCCESS) {
LOG_WARN("fail to release dblink conn", K(release_ret), K(dblink_id));
LOG_WARN("fail to release dblink conn", K(release_ret), K(param_ctx));
}
dblink_conn = NULL;
}
return ret;
}
int ObMySQLConnectionPool::release_dblink(ObISQLConnection *dblink_conn, uint32_t sessid)
int ObMySQLConnectionPool::release_dblink(ObISQLConnection *dblink_conn)
{
int ret = OB_SUCCESS;
const bool succ = OB_NOT_NULL(dblink_conn) ? dblink_conn->usable() : false;
if (OB_FAIL(release(dynamic_cast<ObMySQLConnection *>(dblink_conn), succ, sessid))) {
if (OB_FAIL(release(dynamic_cast<ObMySQLConnection *>(dblink_conn), succ))) {
LOG_WARN("fail to release dblink conn", K(ret));
}
return ret;
}
int ObMySQLConnectionPool::get_dblink_pool(uint64_t tenant_id, uint64_t dblink_id,
ObServerConnectionPool *&dblink_pool)
int ObMySQLConnectionPool::get_dblink_pool(const dblink_param_ctx &param_ctx, ObServerConnectionPool *&dblink_pool)
{
int ret = OB_SUCCESS;
ObServerConnectionPool *pool = NULL;
@ -834,7 +830,8 @@ int ObMySQLConnectionPool::get_dblink_pool(uint64_t tenant_id, uint64_t dblink_i
if (OB_ISNULL(pool = *iter)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("pool is null", K(ret));
} else if (dblink_id == pool->get_dblink_id() && pool->get_tenant_id() == tenant_id) {
} else if (param_ctx.dblink_id_ == pool->get_dblink_id() &&
param_ctx.tenant_id_ == pool->get_tenant_id()) {
dblink_pool = pool;
break;
}
@ -842,20 +839,17 @@ int ObMySQLConnectionPool::get_dblink_pool(uint64_t tenant_id, uint64_t dblink_i
return ret;
}
int ObMySQLConnectionPool::do_acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn, uint32_t sessid)
int ObMySQLConnectionPool::do_acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn)
{
UNUSED(param_ctx);
int ret = OB_SUCCESS;
ObServerConnectionPool *dblink_pool = NULL;
ObMySQLConnection *dblink_conn1 = NULL;
if (OB_FAIL(get_dblink_pool(tenant_id, dblink_id, dblink_pool))) {
LOG_WARN("failed to get dblink pool", K(ret), K(dblink_id));
if (OB_FAIL(get_dblink_pool(param_ctx, dblink_pool))) {
LOG_WARN("failed to get dblink pool", K(ret), K(param_ctx));
} else if (OB_ISNULL(dblink_pool)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dblink pool is NULL", K(ret));
} else if (OB_FAIL(dblink_pool->acquire(dblink_conn1, sessid))) {
} else if (OB_FAIL(dblink_pool->acquire(dblink_conn1, param_ctx.sessid_))) {
LOG_WARN("failed to acquire dblink conn", K(ret));
} else if (OB_ISNULL(dblink_conn1)) {
ret = OB_ERR_UNEXPECTED;
@ -866,10 +860,10 @@ int ObMySQLConnectionPool::do_acquire_dblink(uint64_t tenant_id, uint64_t dblink
} else {
ATOMIC_INC((uint64_t *)&busy_conn_count_);
dblink_conn1->set_busy(true);
dblink_conn1->set_dblink_id(dblink_id);
dblink_conn1->set_dblink_id(param_ctx.dblink_id_);
dblink_conn1->set_timestamp(::oceanbase::common::ObTimeUtility::current_time());
dblink_conn = static_cast<ObISQLConnection *>(dblink_conn1);
LOG_TRACE("acquire connection from mysql connection pool", K(this), K(busy_conn_count_), KP(dblink_conn), K(dblink_conn1->is_closed()), K(dblink_pool), K(sessid));
LOG_TRACE("acquire connection from mysql connection pool", K(this), K(busy_conn_count_), KP(dblink_conn), K(dblink_conn1->is_closed()), K(dblink_pool), K(param_ctx));
}
return ret;
}

View File

@ -138,7 +138,7 @@ public:
char *to, const int64_t to_size, int64_t &out_size);
virtual int acquire(const uint64_t tenant_id, ObISQLConnection *&conn, ObISQLClient *client_addr) override;
virtual int release(ObISQLConnection *conn, const bool success, uint32_t sessid = 0) override;
virtual int release(ObISQLConnection *conn, const bool success) override;
virtual int on_client_inactive(ObISQLClient *client_addr) override
{
@ -156,24 +156,16 @@ public:
virtual DblinkDriverProto get_pool_link_driver_proto() { return DBLINK_DRV_OB; }
// dblink
virtual int create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const dblink_param_ctx &param_ctx);
virtual int acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn,
uint32_t sessid = 0, int64_t
sql_request_level = 0);
virtual int release_dblink(ObISQLConnection *dblink_conn, uint32_t sessid = 0);
virtual int do_acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn,
uint32_t sessid);
virtual int create_dblink_pool(const dblink_param_ctx &param_ctx, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str);
virtual int acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn);
virtual int release_dblink(ObISQLConnection *dblink_conn);
virtual int do_acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn);
virtual int try_connect_dblink(ObISQLConnection *dblink_conn, int64_t sql_request_level = 0);
int get_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, ObServerConnectionPool *&dblink_pool);
int get_dblink_pool(const dblink_param_ctx &param_ctx, ObServerConnectionPool *&dblink_pool);
void set_check_read_consistency(bool need_check) { check_read_consistency_ = need_check; }
virtual int clean_dblink_connection(uint64_t tenant_id);
protected:
@ -191,7 +183,7 @@ protected:
protected:
int execute_init_sql(ObMySQLConnection *connection);
int try_connect(ObMySQLConnection *connection);
int release(ObMySQLConnection *connection, const bool succ, uint32_t sessid = 0);
int release(ObMySQLConnection *connection, const bool succ);
int get_pool(const uint64_t tenant_id, ObServerConnectionPool *&pool);
int get_tenant_server_pool(const uint64_t tenant_id, ObTenantServerConnectionPool *&tenant_server_pool);
int purge_connection_pool();

View File

@ -423,118 +423,112 @@ int ObDbLinkProxy::switch_dblink_conn_pool(DblinkDriverProto type, ObISQLConnect
return ret;
}
int ObDbLinkProxy::create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, DblinkDriverProto dblink_type, const ObAddr &server,
int ObDbLinkProxy::create_dblink_pool(const dblink_param_ctx &param_ctx, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const dblink_param_ctx &param_ctx)
const common::ObString &cluster_str)
{
int ret = OB_SUCCESS;
ObISQLConnectionPool *dblink_pool = NULL;
if (!is_inited()) {
ret = OB_NOT_INIT;
LOG_WARN("mysql proxy not inited");
} else if (OB_FAIL(switch_dblink_conn_pool(dblink_type, dblink_pool))) {
} else if (OB_FAIL(switch_dblink_conn_pool(param_ctx.link_type_, dblink_pool))) {
LOG_WARN("failed to get dblink interface", K(ret));
} else if (OB_FAIL(dblink_pool->create_dblink_pool(tenant_id, dblink_id, server, db_tenant,
} else if (OB_FAIL(dblink_pool->create_dblink_pool(param_ctx, server, db_tenant,
db_user, db_pass, db_name,
conn_str, cluster_str, param_ctx))) {
LOG_WARN("create dblink pool failed", K(ret), K(dblink_id), K(server),
conn_str, cluster_str))) {
LOG_WARN("create dblink pool failed", K(ret), K(param_ctx), K(server),
K(db_tenant), K(db_user), K(db_pass), K(db_name));
}
return ret;
}
int ObDbLinkProxy::acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
DblinkDriverProto dblink_type,
const dblink_param_ctx &param_ctx,
ObISQLConnection *&dblink_conn,
uint32_t sessid,
int64_t sql_request_level,
const char *set_sql_mode_cstr)
int ObDbLinkProxy::acquire_dblink(const dblink_param_ctx &param_ctx, ObISQLConnection *&dblink_conn)
{
int ret = OB_SUCCESS;
ObISQLConnectionPool *dblink_pool = NULL;
if (!is_inited()) {
ret = OB_NOT_INIT;
LOG_WARN("dblink proxy not inited");
} else if (OB_FAIL(switch_dblink_conn_pool(dblink_type, dblink_pool))) {
LOG_WARN("failed to get dblink interface", K(ret), K(dblink_type));
} else if (OB_FAIL(dblink_pool->acquire_dblink(tenant_id, dblink_id, param_ctx, dblink_conn,
sessid, sql_request_level))) {
LOG_WARN("acquire dblink failed", K(ret), K(dblink_id), K(dblink_type));
} else if (OB_FAIL(prepare_enviroment(dblink_conn, dblink_type, set_sql_mode_cstr))) {
} else if (OB_FAIL(switch_dblink_conn_pool(param_ctx.link_type_, dblink_pool))) {
LOG_WARN("failed to get dblink interface", K(ret), K(param_ctx));
} else if (OB_FAIL(dblink_pool->acquire_dblink(param_ctx, dblink_conn))) {
LOG_WARN("acquire dblink failed", K(ret), K(param_ctx));
} else if (OB_FAIL(prepare_enviroment(param_ctx, dblink_conn))) {
LOG_WARN("failed to prepare dblink env", K(ret));
} else {
dblink_conn->set_dblink_id(dblink_id);
dblink_conn->set_dblink_driver_proto(static_cast<int64_t>(dblink_type));
dblink_conn->set_dblink_id(param_ctx.dblink_id_);
dblink_conn->set_dblink_driver_proto(param_ctx.link_type_);
}
return ret;
}
int ObDbLinkProxy::prepare_enviroment(ObISQLConnection *dblink_conn, int link_type, const char *set_sql_mode_cstr)
int ObDbLinkProxy::prepare_enviroment(const sqlclient::dblink_param_ctx &param_ctx, ObISQLConnection *dblink_conn)
{
int ret = OB_SUCCESS;
bool is_inited = false;
if (OB_ISNULL(dblink_conn)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("dblink is null", K(ret));
} else if (OB_FAIL(dblink_conn->is_session_inited(set_sql_mode_cstr, is_inited))) {
} else if (OB_FAIL(dblink_conn->is_session_inited(param_ctx, is_inited))) {
LOG_WARN("failed to get init status", K(ret));
} else if (is_inited) {
// do nothing
} else {
if (OB_FAIL(execute_init_sql(dblink_conn, link_type, set_sql_mode_cstr))) {
if (OB_FAIL(execute_init_sql(param_ctx, dblink_conn))) {
LOG_WARN("failed to execute init sql", K(ret));
} else {
LOG_DEBUG("set session variable nls_date_format");
dblink_conn->set_init_remote_env(true);
dblink_conn->set_session_init_status(true);
}
}
return ret;
}
int ObDbLinkProxy::execute_init_sql(ObISQLConnection *dblink_conn, int link_type, const char *set_sql_mode_cstr)
int ObDbLinkProxy::execute_init_sql(const sqlclient::dblink_param_ctx &param_ctx,
ObISQLConnection *dblink_conn)
{
int ret = OB_SUCCESS;
typedef const char * sql_ptr_type;
if (!lib::is_oracle_mode()) {
const int64_t sql_ptr_count = 2;
sql_ptr_type sql_ptr[sql_ptr_count] = {set_sql_mode_cstr,
"set character_set_results = NULL"};
if (OB_ISNULL(set_sql_mode_cstr)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret), KP(set_sql_mode_cstr));
} else {
ObMySQLStatement stmt;
ObMySQLConnection *mysql_conn = static_cast<ObMySQLConnection *>(dblink_conn);
for (int i = 0; OB_SUCC(ret) && i < sql_ptr_count; ++i) {
if (OB_FAIL(stmt.init(*mysql_conn, sql_ptr[i]))) {
LOG_WARN("create statement failed", K(ret), K(link_type));
} else if (OB_FAIL(stmt.execute_update())) {
LOG_WARN("execute sql failed", K(ret), K(link_type));
} else {
// do nothing
}
sql_ptr_type sql_ptr[] = {param_ctx.set_sql_mode_cstr_,
param_ctx.set_client_charset_cstr_,
param_ctx.set_connection_charset_cstr_,
param_ctx.set_results_charset_cstr_};
ObMySQLStatement stmt;
ObMySQLConnection *mysql_conn = static_cast<ObMySQLConnection *>(dblink_conn);
for (int i = 0; OB_SUCC(ret) && i < sizeof(sql_ptr) / sizeof(sql_ptr_type); ++i) {
if (OB_ISNULL(sql_ptr[i])) {
//do nothing
} else if (OB_FAIL(stmt.init(*mysql_conn, sql_ptr[i]))) {
LOG_WARN("create statement failed", K(ret), K(param_ctx));
} else if (OB_FAIL(stmt.execute_update())) {
LOG_WARN("execute sql failed", K(ret), K(param_ctx));
} else {
// do nothing
}
}
} else if (DBLINK_DRV_OB == link_type) {
} else if (DBLINK_DRV_OB == param_ctx.link_type_) {
static sql_ptr_type sql_ptr[] = {
"set character_set_results = NULL",
param_ctx.set_client_charset_cstr_,
param_ctx.set_connection_charset_cstr_,
param_ctx.set_results_charset_cstr_,
"set nls_date_format='YYYY-MM-DD HH24:MI:SS'",
"set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF'",
"set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF TZR TZD'"
};
int64_t sql_ptr_count = sizeof(sql_ptr) / sizeof(sql_ptr_type);
// todo statement may different
ObMySQLStatement stmt;
ObMySQLConnection *mysql_conn = static_cast<ObMySQLConnection *>(dblink_conn);
for (int i = 0; OB_SUCC(ret) && i < sql_ptr_count; ++i) {
if (OB_FAIL(stmt.init(*mysql_conn, sql_ptr[i]))) {
LOG_WARN("create statement failed", K(ret), K(link_type));
for (int i = 0; OB_SUCC(ret) && i < sizeof(sql_ptr) / sizeof(sql_ptr_type); ++i) {
if (OB_ISNULL(sql_ptr[i])) {
//do nothing
} else if (OB_FAIL(stmt.init(*mysql_conn, sql_ptr[i]))) {
LOG_WARN("create statement failed", K(ret), K(param_ctx));
} else if (OB_FAIL(stmt.execute_update())) {
LOG_WARN("execute sql failed", K(ret), K(link_type));
LOG_WARN("execute sql failed", K(ret), K(param_ctx));
} else {
// do nothing
}
@ -543,7 +537,7 @@ int ObDbLinkProxy::execute_init_sql(ObISQLConnection *dblink_conn, int link_type
return ret;
}
int ObDbLinkProxy::release_dblink(/*uint64_t dblink_id,*/ DblinkDriverProto dblink_type, ObISQLConnection *dblink_conn, uint32_t sessid)
int ObDbLinkProxy::release_dblink(/*uint64_t dblink_id,*/ DblinkDriverProto dblink_type, ObISQLConnection *dblink_conn)
{
int ret = OB_SUCCESS;
ObISQLConnectionPool *dblink_pool = NULL;
@ -552,8 +546,8 @@ int ObDbLinkProxy::release_dblink(/*uint64_t dblink_id,*/ DblinkDriverProto dbli
LOG_WARN("dblink proxy not inited");
} else if (OB_FAIL(switch_dblink_conn_pool(dblink_type, dblink_pool))) {
LOG_WARN("failed to get dblink interface", K(ret));
} else if (OB_FAIL(dblink_pool->release_dblink(dblink_conn, sessid))) {
LOG_WARN("release dblink failed", K(ret), K(sessid));
} else if (OB_FAIL(dblink_pool->release_dblink(dblink_conn))) {
LOG_WARN("release dblink failed", K(ret), K(dblink_conn));
}
return ret;
}

View File

@ -166,20 +166,15 @@ class ObDbLinkProxy : public ObCommonSqlProxy
public:
virtual bool is_oracle_mode() const override { return true; }
virtual int init(sqlclient::ObDbLinkConnectionPool *pool);
int create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, sqlclient::DblinkDriverProto dblink_type, const ObAddr &server,
int create_dblink_pool(const sqlclient::dblink_param_ctx &param_ctx,
const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const sqlclient::dblink_param_ctx &param_ctx);
int acquire_dblink(uint64_t tenant_id, uint64_t dblink_id,
sqlclient::DblinkDriverProto dblink_type,
const sqlclient::dblink_param_ctx &param_ctx,
sqlclient::ObISQLConnection *&dblink_conn,
uint32_t sessid = 0,
int64_t sql_request_level = 0,
const char *set_sql_mode_cstr = NULL);
int release_dblink(/*uint64_t dblink_id,*/sqlclient::DblinkDriverProto dblink_type, sqlclient::ObISQLConnection *dblink_conn, uint32_t sessid = 0);
const common::ObString &cluster_str);
int acquire_dblink(const sqlclient::dblink_param_ctx &param_ctx,
sqlclient::ObISQLConnection *&dblink_conn);
int release_dblink(sqlclient::DblinkDriverProto dblink_type, sqlclient::ObISQLConnection *dblink_conn);
int dblink_read(sqlclient::ObISQLConnection *dblink_conn, ReadResult &result, const char *sql);
int dblink_write(sqlclient::ObISQLConnection *dblink_conn, int64_t &affected_rows, const char *sql);
int rollback(sqlclient::ObISQLConnection *dblink_conn);
@ -187,11 +182,12 @@ public:
int set_dblink_pool_charset(uint64_t dblink_id);
inline sqlclient::ObDbLinkConnectionPool *get_dblink_conn_pool() { return link_pool_; }
int clean_dblink_connection(uint64_t tenant_id);
static int execute_init_sql(sqlclient::ObISQLConnection *dblink_conn, int link_type,
const char *set_sql_mode_cstr = NULL);
static int execute_init_sql(const sqlclient::dblink_param_ctx &param_ctx,
sqlclient::ObISQLConnection *dblink_conn);
private:
int prepare_enviroment(const sqlclient::dblink_param_ctx &param_ctx,
sqlclient::ObISQLConnection *dblink_conn);
private:
int prepare_enviroment(sqlclient::ObISQLConnection *dblink_conn, int link_type,
const char *set_sql_mode_cstr = NULL);
sqlclient::ObDbLinkConnectionPool *link_pool_;
};

View File

@ -82,20 +82,24 @@ int ObMySQLResult::format_precision_scale_length(int16_t &precision, int16_t &sc
int16_t tmp_scale = scale;
int32_t tmp_length = length;
int64_t mbmaxlen = 0;
LOG_DEBUG("dblink pull meta", K(precision), K(scale), K(length), K(ret), K(ob_type));
// format precision from others to oceanbase
if (!lib::is_oracle_mode()) {
switch (ob_type) {
case ObUNumberType:
case ObNumberType: { // for mysql decimal
if (2 == length) {
precision = 1;
} else {
precision = length - 2;
precision = length - 1;
}
length = -1;
break;
}
case ObDoubleType: // for mysql double type and float type
case ObFloatType: {
case ObUFloatType:
case ObUDoubleType:
case ObDoubleType:
case ObFloatType: {// for mysql double type and float type
precision = length;
length = -1;
if (scale > precision) {
@ -119,12 +123,24 @@ int ObMySQLResult::format_precision_scale_length(int16_t &precision, int16_t &sc
case ObSmallIntType:
case ObInt32Type:
case ObIntType:
case ObUTinyIntType:
case ObUSmallIntType:
case ObUInt32Type:
case ObUInt64Type:
case ObBitType: {
precision = length;
length = -1;
scale = -1;
break;
}
case ObTinyTextType:
case ObTextType:
case ObMediumTextType:
case ObLongTextType: {
precision = -1;
scale = -1;
break;
}
default:
break;
}
@ -180,6 +196,7 @@ int ObMySQLResult::format_precision_scale_length(int16_t &precision, int16_t &sc
}
}
}
LOG_DEBUG("dblink pull meta after format", K(precision), K(scale), K(length), K(ret));
return ret;
}

View File

@ -651,10 +651,18 @@ int ObMySQLResultImpl::get_ob_type(ObObjType &ob_type, obmysql::EMySQLFieldType
}
break;
case obmysql::EMySQLFieldType::MYSQL_TYPE_FLOAT:
ob_type = ObFloatType;
if (is_unsigned_type) {
ob_type = ObFloatType;
} else {
ob_type = ObUFloatType;
}
break;
case obmysql::EMySQLFieldType::MYSQL_TYPE_DOUBLE:
ob_type = ObDoubleType;
if (is_unsigned_type) {
ob_type = ObDoubleType;
} else {
ob_type = ObUDoubleType;
}
break;
case obmysql::EMySQLFieldType::MYSQL_TYPE_TIMESTAMP:
ob_type = ObTimestampType;
@ -703,7 +711,13 @@ int ObMySQLResultImpl::get_ob_type(ObObjType &ob_type, obmysql::EMySQLFieldType
ob_type = ObRawType;
break;
case obmysql::EMySQLFieldType::MYSQL_TYPE_NEWDECIMAL:
ob_type = ObNumberType;
if (is_unsigned_type) {
// for decimal type , is_unsigned_type == 1 means signed
// is_unsigned_type comes from obmysql::EMySQLFieldType::fields_ UNSIGNED_FLAG
ob_type = ObUNumberType;
} else {
ob_type = ObNumberType;
}
break;
case obmysql::EMySQLFieldType::MYSQL_TYPE_OB_NUMBER_FLOAT:
ob_type = ObNumberFloatType;

View File

@ -102,7 +102,7 @@ int ObServerConnectionPool::acquire(ObMySQLConnection *&conn, uint32_t sessid)
return ret;
}
int ObServerConnectionPool::release(common::sqlclient::ObISQLConnection *conn, const bool succ, uint32_t sessid)
int ObServerConnectionPool::release(common::sqlclient::ObISQLConnection *conn, const bool succ)
{
int ret = OB_SUCCESS;
ObMySQLConnection *connection = static_cast<ObMySQLConnection *>(conn);
@ -119,7 +119,7 @@ int ObServerConnectionPool::release(common::sqlclient::ObISQLConnection *conn, c
connection->error_times_++;
connection->close();
}
if (OB_FAIL(connection_pool_ptr_->put_cached(connection, sessid))) {
if (OB_FAIL(connection_pool_ptr_->put_cached(connection, connection->get_sessid()))) {
ATOMIC_DEC(&busy_conn_count_);
LOG_WARN("connection object failed to put to cache. destroyed", K(ret));
} else {
@ -127,7 +127,14 @@ int ObServerConnectionPool::release(common::sqlclient::ObISQLConnection *conn, c
ATOMIC_INC(&free_conn_count_);
}
}
LOG_TRACE("release connection to server conn pool", KP(this), K(busy_conn_count_), K(free_conn_count_), KP(connection), K(sessid), K(succ), K(ret), K(lbt()));
LOG_TRACE("release connection to server conn pool", KP(this),
K(busy_conn_count_),
K(free_conn_count_),
KP(connection),
K(connection->get_sessid()),
K(succ),
K(ret),
K(lbt()));
return ret;
}

View File

@ -31,7 +31,7 @@ public:
ObServerConnectionPool();
~ObServerConnectionPool();
int acquire(ObMySQLConnection *&connection, uint32_t sessid);
int release(common::sqlclient::ObISQLConnection *conn, const bool succ, uint32_t sessid = 0) override;
int release(common::sqlclient::ObISQLConnection *conn, const bool succ) override;
uint64_t get_busy_count(void) const;
public:
int init(ObMySQLConnectionPool *root,

View File

@ -209,11 +209,10 @@ int ObInnerSQLConnectionPool::acquire(
return ret;
}
int ObInnerSQLConnectionPool::release(common::sqlclient::ObISQLConnection *conn,
const bool success, uint32_t sessid)
int ObInnerSQLConnectionPool::release(common::sqlclient::ObISQLConnection *conn, const bool success)
{
// alway try to destroy connection, ignore success flag.
UNUSEDx(success, sessid);
UNUSEDx(success);
int ret = OB_SUCCESS;
if (!inited_) {
ret = OB_NOT_INIT;

View File

@ -75,7 +75,7 @@ public:
// acquired connection must be released
virtual int acquire(const uint64_t tenant_id, common::sqlclient::ObISQLConnection *&conn, ObISQLClient *client_addr) override;
virtual int release(common::sqlclient::ObISQLConnection *conn, const bool success, uint32_t sessid = 0);
virtual int release(common::sqlclient::ObISQLConnection *conn, const bool success);
int acquire_spi_conn(sql::ObSQLSessionInfo *session_info, observer::ObInnerSQLConnection *&conn);
int acquire(sql::ObSQLSessionInfo *session_info,
common::sqlclient::ObISQLConnection *&conn,
@ -85,19 +85,18 @@ public:
virtual common::sqlclient::ObSQLConnPoolType get_type() override { return common::sqlclient::INNER_POOL; }
virtual common::sqlclient::DblinkDriverProto get_pool_link_driver_proto() override { return common::sqlclient::DBLINK_DRV_OB; }
// for dblink
virtual int create_dblink_pool(uint64_t tenant_id, uint64_t dblink_id, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str,
const common::sqlclient::dblink_param_ctx &param_ctx) override
{ UNUSEDx(tenant_id, dblink_id, server, db_tenant, db_user, db_pass, db_name, conn_str, param_ctx); return OB_SUCCESS; }
virtual int acquire_dblink(uint64_t tenant_id, uint64_t dblink_id, const sqlclient::dblink_param_ctx &param_ctx, common::sqlclient::ObISQLConnection *&dblink_conn, uint32_t sessid = 0, int64_t timeout_sec = 0)
{ UNUSEDx(tenant_id, dblink_id, param_ctx, dblink_conn, sessid, timeout_sec); return OB_SUCCESS; }
virtual int release_dblink(common::sqlclient::ObISQLConnection *dblink_conn, uint32_t sessid = 0)
{ UNUSEDx(dblink_conn, sessid); return OB_SUCCESS; }
virtual int do_acquire_dblink(uint64_t tenant_id, uint64_t dblink_id, const sqlclient::dblink_param_ctx &param_ctx, common::sqlclient::ObISQLConnection *&dblink_conn, uint32_t sessid = 0)
{ UNUSEDx(tenant_id, dblink_id, param_ctx, dblink_conn, sessid); return OB_SUCCESS; }
virtual int create_dblink_pool(const common::sqlclient::dblink_param_ctx &param_ctx, const ObAddr &server,
const ObString &db_tenant, const ObString &db_user,
const ObString &db_pass, const ObString &db_name,
const common::ObString &conn_str,
const common::ObString &cluster_str) override
{ UNUSEDx(param_ctx, server, db_tenant, db_user, db_pass, db_name, conn_str); return OB_SUCCESS; }
virtual int acquire_dblink(const sqlclient::dblink_param_ctx &param_ctx, common::sqlclient::ObISQLConnection *&dblink_conn)
{ UNUSEDx(param_ctx, dblink_conn); return OB_SUCCESS; }
virtual int release_dblink(common::sqlclient::ObISQLConnection *dblink_conn)
{ UNUSEDx(dblink_conn); return OB_SUCCESS; }
virtual int do_acquire_dblink(const sqlclient::dblink_param_ctx &param_ctx, common::sqlclient::ObISQLConnection *&dblink_conn)
{ UNUSEDx(param_ctx, dblink_conn); return OB_SUCCESS; }
virtual int try_connect_dblink(common::sqlclient::ObISQLConnection *dblink_conn, int64_t timeout_sec = 0) { UNUSEDx(dblink_conn, timeout_sec); return OB_SUCCESS; }
virtual int clean_dblink_connection(uint64_t tenant_id)
{ UNUSED(tenant_id); return OB_SUCCESS; }

View File

@ -8329,12 +8329,10 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
uint64_t dblink_id = OB_INVALID_ID;
DblinkDriverProto link_type = DBLINK_DRV_OB;
dblink_param_ctx param_ctx;
param_ctx.pool_type_ = DblinkPoolType::DBLINK_POOL_SCHEMA;
// don't need set param_ctx.charset_id_ and param_ctx.ncharset_id_, default value is what we need.
sql::DblinkGetConnType conn_type = sql::DblinkGetConnType::DBLINK_POOL;
ObReverseLink *reverse_link = NULL;
ObString dblink_name_for_meta;
int64_t next_sql_req_level = 0;
int64_t sql_request_level = 0;
if (NULL != dblink_schema) {
tenant_id = dblink_schema->get_tenant_id();
dblink_id = dblink_schema->get_dblink_id();
@ -8346,10 +8344,10 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
} else if (OB_ISNULL(dblink_proxy_) || OB_ISNULL(session_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(dblink_proxy_), KP(session_info));
} else if (FALSE_IT(next_sql_req_level = session_info->get_next_sql_request_level())) {
} else if (next_sql_req_level < 1 || next_sql_req_level > 3) {
} else if (FALSE_IT(sql_request_level = session_info->get_next_sql_request_level())) {
} else if (sql_request_level < 1 || sql_request_level > 3) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("invalid next_sql_req_level", K(next_sql_req_level), K(ret));
LOG_WARN("invalid sql_request_level", K(sql_request_level), K(ret));
} else if (is_reverse_link) { // RM process sql within @! and @xxxx! send by TM
if (OB_FAIL(session_info->get_dblink_context().get_reverse_link(reverse_link))) {
LOG_WARN("failed to get reverse link info", KP(reverse_link), K(session_info->get_sessid()), K(ret));
@ -8359,7 +8357,7 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
} else {
LOG_DEBUG("link schema, RM process sql within @! and @xxxx! send by TM", K(*reverse_link));
conn_type = sql::DblinkGetConnType::TEMP_CONN;
if (OB_FAIL(reverse_link->open(next_sql_req_level))) {
if (OB_FAIL(reverse_link->open(sql_request_level))) {
LOG_WARN("failed to open reverse_link", K(ret));
} else {
tenant_id = session_info->get_effective_tenant_id(); //avoid tenant_id is OB_INVALID_ID
@ -8368,6 +8366,12 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
}
}
}
// don't need set param_ctx.charset_id_ and param_ctx.ncharset_id_, default value is what we need.
param_ctx.pool_type_ = DblinkPoolType::DBLINK_POOL_SCHEMA;
param_ctx.sql_request_level_ = sql_request_level;
param_ctx.tenant_id_ = tenant_id;
param_ctx.dblink_id_ = dblink_id;
param_ctx.link_type_ = link_type;
// skip to process TM process sql within @xxxx send by RM, cause here can not get DBLINK_INFO hint(still unresolved).
LOG_DEBUG("get link table schema", K(table_name), K(database_name), KP(dblink_schema), KP(reverse_link), K(is_reverse_link), K(conn_type), K(ret));
if (OB_FAIL(ret)) {// process normal dblink request
@ -8375,23 +8379,29 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
} else if (sql::DblinkGetConnType::DBLINK_POOL == conn_type && OB_ISNULL(dblink_schema)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null", K(ret), KP(dblink_schema));
} else if (!lib::is_oracle_mode() &&
OB_FAIL(ObDblinkService::get_set_sql_mode_cstr(session_info, param_ctx.set_sql_mode_cstr_, alloctor))) {
LOG_WARN("failed to get sql mode cstr", K(ret));
} else if (sql::DblinkGetConnType::DBLINK_POOL == conn_type &&
OB_FAIL(dblink_proxy_->create_dblink_pool(tenant_id,
dblink_id,
link_type,
OB_FAIL(dblink_proxy_->create_dblink_pool(param_ctx,
dblink_schema->get_host_addr(),
dblink_schema->get_tenant_name(),
dblink_schema->get_user_name(),
dblink_schema->get_plain_password(),
database_name,
dblink_schema->get_conn_string(),
dblink_schema->get_cluster_name(),
param_ctx))) {
LOG_WARN("create dblink pool failed", K(ret));
} else if (OB_FAIL(fetch_link_table_info(tenant_id, dblink_id, link_type, conn_type, database_name, table_name,
alloctor, tmp_schema, session_info, dblink_name_for_meta, reverse_link,
param_ctx,
next_sql_req_level, current_scn))) {
dblink_schema->get_cluster_name()))) {
LOG_WARN("create dblink pool failed", K(ret), K(param_ctx));
} else if (OB_FAIL(fetch_link_table_info(param_ctx,
conn_type,
database_name,
table_name,
alloctor,
tmp_schema,
session_info,
dblink_name_for_meta,
reverse_link,
current_scn))) {
LOG_WARN("fetch link table info failed", K(ret), K(dblink_schema), K(database_name), K(table_name));
} else if (OB_ISNULL(tmp_schema)) {
ret = OB_ERR_UNEXPECTED;
@ -8408,9 +8418,7 @@ int ObSchemaServiceSQLImpl::get_link_table_schema(const ObDbLinkSchema *dblink_s
}
template<typename T>
int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
uint64_t dblink_id,
DblinkDriverProto &link_type,
int ObSchemaServiceSQLImpl::fetch_link_table_info(dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
const ObString &database_name,
const ObString &table_name,
@ -8419,8 +8427,6 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
sql::ObSQLSessionInfo *session_info,
const ObString &dblink_name,
sql::ObReverseLink *reverse_link,
const dblink_param_ctx &param_ctx,
int64_t &next_sql_req_level,
uint64_t *current_scn)
{
int ret = OB_SUCCESS;
@ -8428,7 +8434,7 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
const char *dblink_read_errmsg = NULL;
ObMySQLResult *result = NULL;
ObSqlString sql;
const char *set_sql_mode_sql = NULL;
int64_t sql_request_level = param_ctx.sql_request_level_;
static const char * sql_str_fmt_array[] = { // for Oracle mode dblink
"/*$BEFPARSEdblink_req_level=1*/ SELECT * FROM \"%.*s\".\"%.*s\"%c%.*s WHERE ROWNUM < 1",
"/*$BEFPARSEdblink_req_level=2*/ SELECT * FROM \"%.*s\".\"%.*s\"%c%.*s WHERE ROWNUM < 1",
@ -8448,8 +8454,8 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
ret = OB_INVALID_ARGUMENT;
LOG_WARN("table name or database name is empty", K(ret), K(database_name), K(table_name));
} else if (OB_FAIL(sql.append_fmt(lib::is_oracle_mode() ?
sql_str_fmt_array[next_sql_req_level - 1] :
sql_str_fmt_array_mysql_mode[next_sql_req_level - 1],
sql_str_fmt_array[sql_request_level - 1] :
sql_str_fmt_array_mysql_mode[sql_request_level - 1],
database_name.length(), database_name.ptr(),
table_name.length(), table_name.ptr(),
dblink_name.empty() ? ' ' : '@',
@ -8464,18 +8470,14 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
} else {
LOG_DEBUG("succ to read table meta by reverse_link");
}
} else if (!is_oracle_mode() && OB_FAIL(ObDblinkService::get_set_sql_mode_cstr(session_info, set_sql_mode_sql, alloctor))) {
LOG_WARN("failed to get set_sql_mode_sql", K(ret));
} else if (OB_FAIL(dblink_proxy_->acquire_dblink(tenant_id, dblink_id, link_type, param_ctx,
dblink_conn,
session_info->get_sessid(),
next_sql_req_level,
set_sql_mode_sql))) {
LOG_WARN("failed to acquire dblink", K(ret), K(dblink_id));
} else if (FALSE_IT(param_ctx.sessid_ = session_info->get_sessid())) {
} else if (OB_FAIL(dblink_proxy_->acquire_dblink(param_ctx,
dblink_conn))) {
LOG_WARN("failed to acquire dblink", K(ret), K(param_ctx));
} else if (OB_FAIL(session_info->get_dblink_context().register_dblink_conn_pool(dblink_conn->get_common_server_pool()))) {
LOG_WARN("failed to register dblink conn pool to current session", K(ret));
} else if (OB_FAIL(dblink_proxy_->dblink_read(dblink_conn, res, sql.ptr()))) {
LOG_WARN("read link failed", K(ret), K(dblink_id), K(sql.ptr()));
LOG_WARN("read link failed", K(ret), K(param_ctx), K(sql.ptr()));
}
if (OB_FAIL(ret)) {
// do nothing
@ -8486,9 +8488,15 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
static_cast<uint16_t>(common::ObNlsCharsetId::CHARSET_AL32UTF8_ID)))) {
// dblink will convert the result to AL32UTF8 when pulling schema meta
LOG_WARN("failed to set expected charset id", K(ret));
} else if (OB_FAIL(generate_link_table_schema(tenant_id, dblink_id, link_type, conn_type,
database_name, table_name, alloctor, table_schema, session_info,
dblink_conn, result, next_sql_req_level))) {
} else if (OB_FAIL(generate_link_table_schema(param_ctx,
conn_type,
database_name,
table_name,
alloctor,
table_schema,
session_info,
dblink_conn,
result))) {
LOG_WARN("generate link table schema failed", K(ret));
} else if (OB_ISNULL(table_schema)) {
ret = OB_ERR_UNEXPECTED;
@ -8498,20 +8506,24 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
} else {
table_schema->set_table_organization_mode(ObTableOrganizationMode::TOM_HEAP_ORGANIZED);
}
if (OB_SUCC(ret) && DBLINK_DRV_OB == link_type && NULL != current_scn) {
if (OB_FAIL(fetch_link_current_scn(tenant_id, dblink_id, conn_type, alloctor, dblink_conn,
reverse_link, next_sql_req_level, *current_scn))) {
if (OB_SUCC(ret) && DBLINK_DRV_OB == param_ctx.link_type_ && NULL != current_scn) {
if (OB_FAIL(fetch_link_current_scn(param_ctx,
conn_type,
alloctor,
dblink_conn,
reverse_link,
*current_scn))) {
LOG_WARN("fetch link current scn failed", K(ret));
}
}
if (NULL != dblink_conn) {
int tmp_ret = OB_SUCCESS;
if (DBLINK_DRV_OB == link_type &&
if (DBLINK_DRV_OB == param_ctx.link_type_ &&
NULL != result &&
OB_SUCCESS != (tmp_ret = result->close())) {
LOG_WARN("failed to close result", K(tmp_ret));
}
if (OB_SUCCESS != (tmp_ret = dblink_proxy_->release_dblink(link_type, dblink_conn, session_info->get_sessid()))) {
if (OB_SUCCESS != (tmp_ret = dblink_proxy_->release_dblink(param_ctx.link_type_, dblink_conn))) {
LOG_WARN("failed to relese connection", K(tmp_ret));
}
if (OB_SUCC(ret)) {
@ -8523,32 +8535,31 @@ int ObSchemaServiceSQLImpl::fetch_link_table_info(uint64_t tenant_id,
}
template<typename T>
int ObSchemaServiceSQLImpl::generate_link_table_schema(uint64_t tenant_id, uint64_t dblink_id,
DblinkDriverProto link_type,
sql::DblinkGetConnType conn_type,
const ObString &database_name,
const ObString &table_name,
ObIAllocator &allocator,
T *&table_schema,
const sql::ObSQLSessionInfo *session_info,
common::sqlclient::ObISQLConnection *dblink_conn,
const ObMySQLResult *col_meta_result,
int64_t &next_sql_req_level)
int ObSchemaServiceSQLImpl::generate_link_table_schema(const dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
const ObString &database_name,
const ObString &table_name,
ObIAllocator &allocator,
T *&table_schema,
const sql::ObSQLSessionInfo *session_info,
common::sqlclient::ObISQLConnection *dblink_conn,
const ObMySQLResult *col_meta_result)
{
int ret = OB_SUCCESS;
const char * desc_sql_str_fmt = "/*$BEFPARSEdblink_req_level=1*/ desc \"%.*s\".\"%.*s\"";
ObSqlString desc_sql;
int64_t desc_res_row_idx = -1;
bool need_desc = (next_sql_req_level == 1) && DBLINK_DRV_OB == link_type
&& sql::DblinkGetConnType::TEMP_CONN != conn_type;
bool need_desc = param_ctx.sql_request_level_ == 1 &&
DBLINK_DRV_OB == param_ctx.link_type_ &&
sql::DblinkGetConnType::TEMP_CONN != conn_type;
ObMySQLResult *desc_result = NULL;
SMART_VAR(ObMySQLProxy::MySQLResult, desc_res) {
T tmp_table_schema;
table_schema = NULL;
int64_t column_count = col_meta_result->get_column_count();
tmp_table_schema.set_tenant_id(tenant_id);
tmp_table_schema.set_tenant_id(param_ctx.tenant_id_);
tmp_table_schema.set_table_id(1); //no use
tmp_table_schema.set_dblink_id(dblink_id);
tmp_table_schema.set_dblink_id(param_ctx.dblink_id_);
tmp_table_schema.set_collation_type(CS_TYPE_UTF8MB4_BIN);
tmp_table_schema.set_charset_type(ObCharset::charset_type_by_coll(tmp_table_schema.get_collation_type()));
if (OB_FAIL(tmp_table_schema.set_table_name(table_name))) {
@ -8573,7 +8584,7 @@ int ObSchemaServiceSQLImpl::generate_link_table_schema(uint64_t tenant_id, uint6
scale = data_type.get_scale();
length = data_type.get_length();
column_schema.set_table_id(tmp_table_schema.get_table_id());
column_schema.set_tenant_id(tenant_id);
column_schema.set_tenant_id(param_ctx.tenant_id_);
column_schema.set_column_id(i + OB_END_RESERVED_COLUMN_ID_NUM);
column_schema.set_meta_type(data_type.get_meta_type());
column_schema.set_charset_type(ObCharset::charset_type_by_coll(column_schema.get_collation_type()));
@ -8591,7 +8602,7 @@ int ObSchemaServiceSQLImpl::generate_link_table_schema(uint64_t tenant_id, uint6
database_name.ptr(), table_name.length(), table_name.ptr()))) {
LOG_WARN("append desc sql failed", K(ret));
} else if (OB_FAIL(dblink_proxy_->dblink_read(dblink_conn, desc_res, desc_sql.ptr()))) {
LOG_WARN("read link failed", K(ret), K(dblink_id), K(desc_sql.ptr()));
LOG_WARN("read link failed", K(ret), K(param_ctx), K(desc_sql.ptr()));
} else if (OB_ISNULL(desc_result = desc_res.get_result())) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("fail to get result", K(ret));
@ -8654,13 +8665,11 @@ int ObSchemaServiceSQLImpl::generate_link_table_schema(uint64_t tenant_id, uint6
return ret;
}
int ObSchemaServiceSQLImpl::fetch_link_current_scn(uint64_t tenant_id,
uint64_t dblink_id,
int ObSchemaServiceSQLImpl::fetch_link_current_scn(const dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
ObIAllocator &allocator,
common::sqlclient::ObISQLConnection *dblink_conn,
sql::ObReverseLink *reverse_link,
int64_t next_sql_req_level,
uint64_t &current_scn)
{
int ret = OB_SUCCESS;
@ -8672,10 +8681,11 @@ int ObSchemaServiceSQLImpl::fetch_link_current_scn(uint64_t tenant_id,
SMART_VAR(ObMySQLProxy::MySQLResult, res) {
ObSqlString sql;
ObMySQLResult *result = NULL;
if (OB_UNLIKELY(next_sql_req_level <= 0 || next_sql_req_level > 3)) {
int64_t sql_request_level = param_ctx.sql_request_level_;
if (OB_UNLIKELY(sql_request_level <= 0 || sql_request_level > 3)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected sql req level", K(ret), K(next_sql_req_level));
} else if (OB_FAIL(sql.assign(sql_str_fmt_array[next_sql_req_level - 1]))) {
LOG_WARN("unexpected sql req level", K(ret), K(sql_request_level));
} else if (OB_FAIL(sql.assign(sql_str_fmt_array[sql_request_level - 1]))) {
LOG_WARN("append sql failed",K(ret));
} else if (sql::DblinkGetConnType::TEMP_CONN == conn_type) {
if (OB_ISNULL(reverse_link)) {
@ -8691,7 +8701,7 @@ int ObSchemaServiceSQLImpl::fetch_link_current_scn(uint64_t tenant_id,
ret = OB_ERR_UNEXPECTED;
LOG_WARN("link conn is NULL", K(ret));
} else if (OB_FAIL(dblink_proxy_->dblink_read(dblink_conn, res, sql.ptr()))) {
LOG_WARN("read link failed", K(ret), K(dblink_id), K(sql.ptr()));
LOG_WARN("read link failed", K(ret), K(param_ctx), K(sql.ptr()));
ret = OB_SUCCESS;
} else {
result = res.get_result();

View File

@ -877,9 +877,7 @@ private:
ObTablegroupSchema *&tablegroup_schema);
template<typename T>
int fetch_link_table_info(uint64_t tenant_id,
uint64_t dblink_id,
common::sqlclient::DblinkDriverProto &link_type,
int fetch_link_table_info(common::sqlclient::dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
const common::ObString &database_name,
const common::ObString &table_name,
@ -888,12 +886,9 @@ private:
sql::ObSQLSessionInfo *session_info,
const ObString &dblink_name,
sql::ObReverseLink *reverse_link,
const common::sqlclient::dblink_param_ctx &param_ctx,
int64_t &next_sql_req_level,
uint64_t *current_scn);
template<typename T>
int generate_link_table_schema(uint64_t tenant_id, uint64_t dblink_id,
common::sqlclient::DblinkDriverProto link_type,
int generate_link_table_schema(const common::sqlclient::dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
const ObString &database_name,
const ObString &table_name,
@ -901,15 +896,12 @@ private:
T *&table_schema,
const sql::ObSQLSessionInfo *session_info,
common::sqlclient::ObISQLConnection *dblink_conn,
const common::sqlclient::ObMySQLResult *col_meta_result,
int64_t &next_sql_req_level);
int fetch_link_current_scn(uint64_t tenant_id,
uint64_t dblink_id,
const common::sqlclient::ObMySQLResult *col_meta_result);
int fetch_link_current_scn(const common::sqlclient::dblink_param_ctx &param_ctx,
sql::DblinkGetConnType conn_type,
ObIAllocator &allocator,
common::sqlclient::ObISQLConnection *dblink_conn,
sql::ObReverseLink *reverse_link,
int64_t next_sql_req_level,
uint64_t &current_scn);
int try_mock_link_table_column(ObTableSchema &table_schema);

View File

@ -120,6 +120,90 @@ int ObDblinkService::get_set_sql_mode_cstr(sql::ObSQLSessionInfo *session_info,
return ret;
}
int ObDblinkService::get_set_names_cstr(sql::ObSQLSessionInfo *session_info,
const char *&set_client_charset,
const char *&set_connection_charset,
const char *&set_results_charset)
{
int ret = OB_SUCCESS;
int64_t client = -1;
int64_t connection = -1;
int64_t results = -1;
set_client_charset = NULL;
set_connection_charset = NULL;
set_results_charset = "set character_set_results = NULL";
if (OB_ISNULL(session_info)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (OB_FAIL(session_info->get_sys_variable(share::SYS_VAR_CHARACTER_SET_CLIENT, client))) {
LOG_WARN("failed to get client characterset", K(ret));
} else if (OB_FAIL(session_info->get_sys_variable(share::SYS_VAR_CHARACTER_SET_CONNECTION, connection))) {
LOG_WARN("failed to get connection characterset", K(ret));
} else if (OB_FAIL(session_info->get_sys_variable(share::SYS_VAR_CHARACTER_SET_CLIENT, results))) {
LOG_WARN("failed to get results characterset", K(ret));
} else {
switch(ObCharset::charset_type_by_coll(ObCollationType(client))) {
case ObCharsetType::CHARSET_UTF8MB4:
set_client_charset = "set character_set_client = utf8mb4";
break;
case ObCharsetType::CHARSET_GBK:
set_client_charset = "set character_set_client = gbk";
break;
case ObCharsetType::CHARSET_BINARY:
set_client_charset = "set character_set_client = binary";
break;
default:
// do nothing
break;
}
switch(ObCharset::charset_type_by_coll(ObCollationType(connection))) {
case ObCharsetType::CHARSET_UTF8MB4:
set_connection_charset = "set character_set_connection = utf8mb4";
break;
case ObCharsetType::CHARSET_GBK:
set_connection_charset = "set character_set_connection = gbk";
break;
case ObCharsetType::CHARSET_BINARY:
set_connection_charset = "set character_set_connection = binary";
break;
default:
// do nothing
break;
}
switch(ObCharset::charset_type_by_coll(ObCollationType(results))) {
case ObCharsetType::CHARSET_UTF8MB4:
set_results_charset = "set character_set_results = utf8mb4";
break;
case ObCharsetType::CHARSET_GBK:
set_results_charset = "set character_set_results = gbk";
break;
case ObCharsetType::CHARSET_BINARY:
set_results_charset = "set character_set_results = binary";
break;
default:
// do nothing
break;
}
}
return ret;
}
int ObDblinkService::get_local_session_vars(sql::ObSQLSessionInfo *session_info,
ObIAllocator &allocator,
common::sqlclient::dblink_param_ctx &param_ctx)
{
int ret = OB_SUCCESS;
if (lib::is_mysql_mode() && OB_FAIL(get_set_sql_mode_cstr(session_info, param_ctx.set_sql_mode_cstr_, allocator))) {
LOG_WARN("failed to get set_sql_mode_cstr", K(ret));
} else if (OB_FAIL(get_set_names_cstr(session_info,
param_ctx.set_client_charset_cstr_,
param_ctx.set_connection_charset_cstr_,
param_ctx.set_results_charset_cstr_))) {
LOG_WARN("failed to get set_names_cstr", K(ret));
}
return ret;
}
ObReverseLink::ObReverseLink()
: user_(),
tenant_(),
@ -228,7 +312,11 @@ const int64_t ObReverseLink::LONG_QUERY_TIMEOUT = 120*1000*1000; //120 seconds
int ObReverseLink::open(int64_t session_sql_req_level)
{
int ret = OB_SUCCESS;
if (!is_close_) {
common::sqlclient::dblink_param_ctx param_ctx;
if (OB_ISNULL(session_info_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (!is_close_) {
// nothing to do
} else if (tenant_.empty() || user_.empty() || passwd_.empty() /*|| db_name.empty()*/
|| OB_UNLIKELY(cluster_.length() >= OB_MAX_CLUSTER_NAME_LENGTH)
@ -238,6 +326,8 @@ int ObReverseLink::open(int64_t session_sql_req_level)
ret = OB_INVALID_ARGUMENT;
LOG_WARN("invalid argument", K(ret),
K(cluster_), K(tenant_), K(user_), K(passwd_));
} else if (OB_FAIL(ObDblinkService::get_local_session_vars(session_info_, allocator_, param_ctx))) {
LOG_WARN("failed to get local session vars", K(ret));
} else {
if (cluster_.empty()) {
(void)snprintf(db_user_, sizeof(db_user_), "%.*s@%.*s", user_.length(), user_.ptr(),
@ -249,11 +339,12 @@ int ObReverseLink::open(int64_t session_sql_req_level)
}
(void)snprintf(db_pass_, sizeof(db_pass_), "%.*s", passwd_.length(), passwd_.ptr());
LOG_DEBUG("open reverse link connection", K(ret), K(db_user_), K(db_pass_), K(addr_));
param_ctx.link_type_ = common::sqlclient::DBLINK_DRV_OB;
if (OB_FAIL(reverse_conn_.connect(db_user_, db_pass_, "", addr_, 10, true, session_sql_req_level))) { //just set connect timeout to 10s, read and write have not timeout
LOG_WARN("failed to open reverse link connection", K(ret), K(db_user_), K(db_pass_), K(addr_));
} else if (OB_FAIL(reverse_conn_.set_timeout_variable(LONG_QUERY_TIMEOUT, common::sqlclient::ObMySQLConnectionPool::DEFAULT_TRANSACTION_TIMEOUT_US))) {
LOG_WARN("failed to set reverse link connection's timeout", K(ret));
} else if (OB_FAIL(ObDbLinkProxy::execute_init_sql(&reverse_conn_, common::sqlclient::DBLINK_DRV_OB))) {
} else if (OB_FAIL(ObDbLinkProxy::execute_init_sql(param_ctx, &reverse_conn_))) {
LOG_WARN("failed to init reverse link connection", K(ret));
} else {
is_close_ = false;
@ -281,6 +372,18 @@ int ObReverseLink::read(const char *sql, ObISQLClient::ReadResult &res)
return ret;
}
int ObReverseLink::ping()
{
int ret = OB_SUCCESS;
if (is_close_) {
ret = OB_NOT_INIT;
LOG_WARN("reverse link connection is closed", K(ret));
} else if (OB_FAIL(reverse_conn_.ping())) {
LOG_WARN("faild to ping reverse link connection", K(ret));
}
return ret;
}
int ObReverseLink::close()
{
int ret = OB_SUCCESS;
@ -452,7 +555,7 @@ int ObDblinkCtxInSession::clean_dblink_conn(const bool force_disconnect)
LOG_WARN("server_conn_pool of dblink connection is NULL", K(this), K(dblink_conn), K(i), K(ret));
} else {
const bool need_disconnect = force_disconnect || !dblink_conn->usable();
if (OB_FAIL(server_conn_pool->release(dblink_conn, !need_disconnect, session_info_->get_sessid()))) {
if (OB_FAIL(server_conn_pool->release(dblink_conn, !need_disconnect))) {
LOG_WARN("session failed to release dblink connection", K(session_info_->get_sessid()), K(this), KP(dblink_conn), K(i), K(ret));
} else {
LOG_TRACE("session succ to release dblink connection", K(session_info_->get_sessid()), K(this), KP(dblink_conn), K(i), K(ret));
@ -507,6 +610,7 @@ int ObDblinkCtxInSession::get_reverse_link(ObReverseLink *&reverse_dblink)
} else if (OB_FAIL(reverse_dblink_->deserialize(new_buff, new_size, pos))) {
LOG_WARN("failed to deserialize reverse_dblink_", K(new_size), K(ret));
} else {
reverse_dblink_->set_session_info(session_info_);
reverse_dblink = reverse_dblink_;
LOG_DEBUG("succ to get reverse link from seesion", K(session_info_->get_sessid()), K(*reverse_dblink), KP(reverse_dblink));
}

View File

@ -32,7 +32,16 @@ class ObDblinkService
public:
static int check_lob_in_result(common::sqlclient::ObMySQLResult *result, bool &have_lob);
static int get_length_from_type_text(ObString &type_text, int32_t &length);
static int get_set_sql_mode_cstr(sql::ObSQLSessionInfo *session_info, const char *&set_sql_mode_cstr, ObIAllocator &allocator);
static int get_local_session_vars(sql::ObSQLSessionInfo *session_info,
ObIAllocator &allocator,
common::sqlclient::dblink_param_ctx &param_ctx);
static int get_set_sql_mode_cstr(sql::ObSQLSessionInfo *session_info,
const char *&set_sql_mode_cstr,
ObIAllocator &allocator);
static int get_set_names_cstr(sql::ObSQLSessionInfo *session_info,
const char *&set_client_charset,
const char *&set_connection_charset,
const char *&set_results_charset);
};
enum DblinkGetConnType {
@ -55,6 +64,7 @@ public:
inline void set_self_addr(common::ObAddr addr) { self_addr_ = addr; }
inline void set_tx_id(int64_t tx_id) { tx_id_ = tx_id; }
inline void set_tm_sessid(uint32_t tm_sessid) { tm_sessid_ = tm_sessid; }
inline void set_session_info(sql::ObSQLSessionInfo *session_info) { session_info_ = session_info; }
const ObString &get_user() { return user_; }
const ObString &get_tenant() { return tenant_; }
const ObString &get_cluster() { return cluster_; }
@ -66,6 +76,7 @@ public:
int open(int64_t session_sql_req_level);
int read(const char *sql, ObISQLClient::ReadResult &res);
int ping();
int close();
TO_STRING_KV(K_(user),
K_(tenant),
@ -95,6 +106,7 @@ private:
common::sqlclient::ObMySQLConnection reverse_conn_; // ailing.lcq to do, ObReverseLink can be used by serval connection, not just one
char db_user_[OB_MAX_USER_NAME_LENGTH + OB_MAX_TENANT_NAME_LENGTH + OB_MAX_CLUSTER_NAME_LENGTH];
char db_pass_[OB_MAX_PASSWORD_LENGTH];
sql::ObSQLSessionInfo *session_info_; // reverse link belongs to which session
};
class ObDblinkUtils

View File

@ -109,6 +109,7 @@ int ObLinkOp::init_dblink(uint64_t dblink_id, ObDbLinkProxy *dblink_proxy, bool
my_session = ctx_.get_my_session();
ObPhysicalPlanCtx *plan_ctx = GET_PHY_PLAN_CTX(ctx_);
in_xa_trascaction_ = in_xa_trascaction;
dblink_id_ = dblink_id;
if (OB_NOT_NULL(dblink_proxy_)) {
ret = OB_INIT_TWICE;
LOG_WARN("link scan ctx already inited", K(ret));
@ -128,36 +129,25 @@ int ObLinkOp::init_dblink(uint64_t dblink_id, ObDbLinkProxy *dblink_proxy, bool
LOG_WARN("dblink schema is NULL", K(ret), K(dblink_id));
} else if (FALSE_IT(set_link_driver_proto(static_cast<DblinkDriverProto>(dblink_schema_->get_driver_proto())))) {
// do nothing
} else if (OB_FAIL(ObLinkOp::init_dblink_param_ctx(ctx_, param_ctx))) {
} else if (OB_FAIL(ObLinkOp::init_dblink_param_ctx(param_ctx))) {
LOG_WARN("failed to init dblink param ctx", K(ret));
} else if (OB_FAIL(dblink_proxy->create_dblink_pool(tenant_id_,
dblink_id,
link_type_,
} else if (OB_FAIL(dblink_proxy->create_dblink_pool(param_ctx,
dblink_schema_->get_host_addr(),
dblink_schema_->get_tenant_name(),
dblink_schema_->get_user_name(),
dblink_schema_->get_plain_password(),
dblink_schema_->get_database_name(),
dblink_schema_->get_conn_string(),
dblink_schema_->get_cluster_name(),
param_ctx))) {
dblink_schema_->get_cluster_name()))) {
LOG_WARN("failed to create dblink pool", K(ret));
} else if (OB_FAIL(my_session->get_dblink_context().get_dblink_conn(dblink_id, dblink_conn))) {
LOG_WARN("failed to get dblink connection from session", K(my_session), K(sessid_), K(ret));
} else {
if (NULL == dblink_conn) {
const char *set_sql_mode_sql = NULL;
if (!is_oracle_mode() && OB_FAIL(ObDblinkService::get_set_sql_mode_cstr(my_session, set_sql_mode_sql, allocator_))) {
LOG_WARN("failed to get set_sql_mode_sql", K(ret));
} else if (OB_FAIL(dblink_proxy->acquire_dblink(tenant_id_,
dblink_id,
link_type_,
param_ctx,
dblink_conn_,
sessid_,
next_sql_req_level_,
set_sql_mode_sql))) {
LOG_WARN("failed to acquire dblink", K(ret), K(dblink_id));
if (OB_FAIL(ObDblinkService::get_local_session_vars(my_session, allocator_, param_ctx))) {
LOG_WARN("failed to get local session vars", K(ret));
} else if (OB_FAIL(dblink_proxy->acquire_dblink(param_ctx, dblink_conn_))) {
LOG_WARN("failed to acquire dblink", K(ret), K(param_ctx));
} else if (OB_FAIL(my_session->get_dblink_context().register_dblink_conn_pool(dblink_conn_->get_common_server_pool()))) {
LOG_WARN("failed to register dblink conn pool to current session", K(ret));
} else if (in_xa_trascaction_ && lib::is_oracle_mode() &&
@ -172,7 +162,6 @@ int ObLinkOp::init_dblink(uint64_t dblink_id, ObDbLinkProxy *dblink_proxy, bool
LOG_TRACE("link op get connection from xa trasaction", K(dblink_id), KP(dblink_conn_));
}
if (OB_SUCC(ret)) {
dblink_id_ = dblink_id;
dblink_proxy_ = dblink_proxy;
}
}
@ -367,23 +356,28 @@ int ObLinkSpec::set_param_infos(const ObIArray<ObParamPosIdx> &param_infos)
return ret;
}
int ObLinkOp::init_dblink_param_ctx(ObExecContext &exec_ctx, dblink_param_ctx &param_ctx)
int ObLinkOp::init_dblink_param_ctx(dblink_param_ctx &param_ctx)
{
int ret = OB_SUCCESS;
uint16_t charset_id = 0;
uint16_t ncharset_id = 0;
if (OB_FAIL(get_charset_id(exec_ctx, charset_id, ncharset_id))) {
if (OB_FAIL(get_charset_id(ctx_, charset_id, ncharset_id))) {
LOG_WARN("failed to get session charset id", K(ret));
} else {
param_ctx.charset_id_ = charset_id;
param_ctx.ncharset_id_ = ncharset_id;
param_ctx.pool_type_ = DblinkPoolType::DBLINK_POOL_DEF;
param_ctx.tenant_id_ = tenant_id_;
param_ctx.dblink_id_ = dblink_id_;
param_ctx.link_type_ = link_type_;
param_ctx.sessid_ = sessid_;
}
return ret;
}
int ObLinkOp::get_charset_id(ObExecContext &exec_ctx,
uint16_t &charset_id, uint16_t &ncharset_id)
uint16_t &charset_id,
uint16_t &ncharset_id)
{
int ret = OB_SUCCESS;
ObSQLSessionInfo *sess_info = NULL;

View File

@ -48,7 +48,7 @@ public:
const ObParamStore &param_store,
ObReverseLink *reverse_link = NULL);
virtual int inner_execute_link_stmt(const char *link_stmt) = 0;
static int init_dblink_param_ctx(ObExecContext &exec_ctx, common::sqlclient::dblink_param_ctx &param_ctx);
int init_dblink_param_ctx(common::sqlclient::dblink_param_ctx &param_ctx);
static int get_charset_id(ObExecContext &exec_ctx, uint16_t &charset_id, uint16_t &ncharset_id);
protected:
int combine_link_stmt(const common::ObString &link_stmt_fmt,

View File

@ -94,9 +94,9 @@ int ObLinkScanOp::inner_execute_link_stmt(const char *link_stmt)
LOG_WARN("unexpected NULL", K(ret), KP(link_stmt));
} else if (sql::DblinkGetConnType::TM_CONN == conn_type_) {
if (OB_FAIL(tm_rm_connection_->execute_read(OB_INVALID_TENANT_ID, link_stmt, res_))) {
LOG_WARN("failed to read table data by tm_rm_connection", K(ret), K(link_stmt), K(DblinkDriverProto(tm_rm_connection_->get_dblink_driver_proto())));
LOG_WARN("failed to read table data by tm_rm_connection", K(ret), K(link_stmt), K(tm_rm_connection_->get_dblink_driver_proto()));
} else {
LOG_DEBUG("succ to read table data by tm_rm_connection", K(link_stmt), K(DblinkDriverProto(tm_rm_connection_->get_dblink_driver_proto())));
LOG_DEBUG("succ to read table data by tm_rm_connection", K(link_stmt), K(tm_rm_connection_->get_dblink_driver_proto()));
}
} else if (sql::DblinkGetConnType::TEMP_CONN == conn_type_) {
if (OB_FAIL(reverse_link_->read(link_stmt, res_))) {
@ -125,7 +125,7 @@ int ObLinkScanOp::inner_execute_link_stmt(const char *link_stmt)
LOG_USER_ERROR(OB_NOT_SUPPORTED, "dblink fetch lob type data");
} else if (OB_FAIL(ObLinkOp::get_charset_id(ctx_, charset_id, ncharset_id))) {
LOG_WARN("failed to get charset id", K(ret));
} else if (OB_FAIL(result_->set_expected_charset_id(charset_id, ncharset_id))) {
} else if (OB_FAIL(result_->set_expected_charset_id(charset_id, ncharset_id))) {// for oci dblink set expected result charset, actually useless...
LOG_WARN("failed to set result set expected charset", K(ret), K(charset_id), K(ncharset_id));
} else {
LOG_DEBUG("succ to dblink read", K(link_stmt), KP(dblink_conn_));
@ -137,7 +137,7 @@ void ObLinkScanOp::reset_dblink()
{
int tmp_ret = OB_SUCCESS;
if (OB_NOT_NULL(dblink_proxy_) && OB_NOT_NULL(dblink_conn_) && !in_xa_trascaction_ &&
OB_SUCCESS != (tmp_ret = dblink_proxy_->release_dblink(link_type_, dblink_conn_, sessid_))) {
OB_SUCCESS != (tmp_ret = dblink_proxy_->release_dblink(link_type_, dblink_conn_))) {
LOG_WARN_RET(tmp_ret, "failed to release connection", K(tmp_ret));
}
if (OB_NOT_NULL(reverse_link_)) {
@ -302,6 +302,32 @@ int ObLinkScanOp::fetch_row()
if (OB_ITER_END != ret) {
LOG_WARN("failed to get next row", K(ret));
} else {
// check if connection is alive, if not, then OB_ITER_END is a fake errno
if (sql::DblinkGetConnType::TM_CONN == conn_type_) {
if (OB_ISNULL(tm_rm_connection_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (OB_FAIL(tm_rm_connection_->ping())) {
LOG_WARN("failed to ping tm_rm_connection_", K(ret));
}
} else if (sql::DblinkGetConnType::TEMP_CONN == conn_type_) {
if (OB_ISNULL(reverse_link_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (OB_FAIL(reverse_link_->ping())) {
LOG_WARN("failed to ping reverse_link_", K(ret));
}
} else {
if (OB_ISNULL(dblink_conn_)) {
ret = OB_ERR_UNEXPECTED;
LOG_WARN("unexpected null ptr", K(ret));
} else if (OB_FAIL(dblink_conn_->ping())) {
LOG_WARN("failed to ping dblink_conn_", K(ret));
}
}
if (OB_SUCC(ret)) {
ret = OB_ITER_END;
}
reset_result();
}
} else {
@ -366,6 +392,7 @@ int ObLinkScanOp::inner_rescan()
reset_link_sql();
iter_end_ = false;
iterated_rows_ = -1;
int tmp_ret = OB_SUCCESS;
return ObOperator::inner_rescan();
}

View File

@ -84,6 +84,7 @@
#include "sql/ob_optimizer_trace_impl.h"
#include "sql/monitor/ob_sql_plan.h"
#include "sql/optimizer/ob_explain_log_plan.h"
#include "sql/dblink/ob_dblink_utils.h"
namespace oceanbase
{
@ -4752,6 +4753,8 @@ int ObSql::check_batched_multi_stmt_after_resolver(ObPlanCacheCtx &pc_ctx,
int ret = OB_SUCCESS;
ObPhysicalPlanCtx *plan_ctx = NULL;
is_valid = true;
bool has_dblink = false;
bool has_any_dblink = false;
bool is_ps_ab_opt = pc_ctx.sql_ctx_.multi_stmt_item_.is_ab_batch_opt();
if (OB_ISNULL(plan_ctx = pc_ctx.exec_ctx_.get_physical_plan_ctx())
|| OB_ISNULL(pc_ctx.sql_ctx_.session_info_)) {
@ -4774,6 +4777,12 @@ int ObSql::check_batched_multi_stmt_after_resolver(ObPlanCacheCtx &pc_ctx,
is_valid = false;
}
if (OB_FAIL(ObDblinkUtils::has_reverse_link_or_any_dblink(&delupd_stmt, has_dblink, has_any_dblink))) {
LOG_WARN("failed to check dblink in stmt", K(delupd_stmt), K(ret));
} else if (has_any_dblink) {
is_valid = false;
}
// make sure type of all the parameters are the same
if (OB_SUCC(ret) && is_valid) {
if (!is_ps_ab_opt) {

View File

@ -938,8 +938,8 @@ int ObStmtComparer::compare_basic_table_item(const ObDMLStmt *first,
|| OB_ISNULL(second) || OB_ISNULL(second_table)) {
ret = OB_INVALID_ARGUMENT;
LOG_WARN("param has null", K(first), K(first_table), K(second), K(second_table));
} else if (first_table->is_basic_table() &&
second_table->is_basic_table() &&
} else if ((first_table->is_basic_table() || first_table->is_link_table()) &&
(second_table->is_basic_table() || second_table->is_link_table()) &&
first_table->ref_id_ == second_table->ref_id_ &&
first_table->flashback_query_type_ == second_table->flashback_query_type_ &&
(first_table->flashback_query_expr_ == second_table->flashback_query_expr_ ||
@ -1093,7 +1093,8 @@ int ObStmtComparer::compare_table_item(const ObDMLStmt *first,
} else {
relation = QueryRelation::QUERY_UNCOMPARABLE;
}
} else if (first_table->is_basic_table() && second_table->is_basic_table()) {
} else if ((first_table->is_basic_table() || first_table->is_link_table()) &&
(second_table->is_basic_table() || second_table->is_link_table())) {
if (OB_FAIL(compare_basic_table_item(first,
first_table,
second,

View File

@ -551,6 +551,7 @@ int ObTransformJoinElimination::create_missing_select_items(ObSelectStmt *source
ret = OB_ERR_UNEXPECTED;
LOG_WARN("get unexpected null", K(temp_source_table), K(temp_target_table), K(ret));
} else if ((temp_source_table->is_basic_table() && temp_target_table->is_basic_table()) ||
(temp_source_table->is_link_table() && temp_target_table->is_link_table()) ||
(temp_source_table->is_temp_table() && temp_target_table->is_temp_table()) ||
(temp_source_table->is_generated_table() && temp_target_table->is_generated_table())) {
if (OB_FAIL(ObTransformUtils::merge_table_items(source_stmt,