polardbxengine/storage/perfschema/table_replication_connectio...

421 lines
14 KiB
C++

/*
Copyright (c) 2013, 2019, Oracle and/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,
as published by the Free Software Foundation.
This program is also distributed with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have included with MySQL.
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, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
@file storage/perfschema/table_replication_connection_configuration.cc
Table replication_connection_configuration (implementation).
*/
#include "storage/perfschema/table_replication_connection_configuration.h"
#include "my_compiler.h"
#include "my_dbug.h"
#include "sql/field.h"
#include "sql/plugin_table.h"
#include "sql/rpl_info.h"
#include "sql/rpl_mi.h"
#include "sql/rpl_msr.h" /* Multisource replciation */
#include "sql/rpl_rli.h"
#include "sql/rpl_slave.h"
#include "sql/sql_parse.h"
#include "sql/table.h"
#include "storage/perfschema/pfs_instr.h"
#include "storage/perfschema/pfs_instr_class.h"
THR_LOCK table_replication_connection_configuration::m_table_lock;
Plugin_table table_replication_connection_configuration::m_table_def(
/* Schema name */
"performance_schema",
/* Name */
"replication_connection_configuration",
/* Definition */
" CHANNEL_NAME CHAR(64) not null,\n"
" HOST CHAR(255) CHARACTER SET ASCII not null,\n"
" PORT INTEGER not null,\n"
" USER CHAR(32) collate utf8mb4_bin not null,\n"
" NETWORK_INTERFACE CHAR(60) collate utf8mb4_bin not null,\n"
" AUTO_POSITION ENUM('1','0') not null,\n"
" SSL_ALLOWED ENUM('YES','NO','IGNORED') not null,\n"
" SSL_CA_FILE VARCHAR(512) not null,\n"
" SSL_CA_PATH VARCHAR(512) not null,\n"
" SSL_CERTIFICATE VARCHAR(512) not null,\n"
" SSL_CIPHER VARCHAR(512) not null,\n"
" SSL_KEY VARCHAR(512) not null,\n"
" SSL_VERIFY_SERVER_CERTIFICATE ENUM('YES','NO') not null,\n"
" SSL_CRL_FILE VARCHAR(255) not null,\n"
" SSL_CRL_PATH VARCHAR(255) not null,\n"
" CONNECTION_RETRY_INTERVAL INTEGER not null,\n"
" CONNECTION_RETRY_COUNT BIGINT unsigned not null,\n"
" HEARTBEAT_INTERVAL DOUBLE(10,3) unsigned not null\n"
" COMMENT 'Number of seconds after which a heartbeat will be sent .',\n"
" TLS_VERSION VARCHAR(255) not null,\n"
" PUBLIC_KEY_PATH VARCHAR(512) not null,\n"
" GET_PUBLIC_KEY ENUM('YES', 'NO') not null,\n"
" NETWORK_NAMESPACE VARCHAR(64) not null,\n"
" COMPRESSION_ALGORITHM CHAR(64) collate utf8mb4_bin not null\n"
" COMMENT 'Compression algorithm used for data transfer between master "
"and slave.',\n"
" ZSTD_COMPRESSION_LEVEL INTEGER not null\n"
" COMMENT 'Compression level associated with zstd compression "
"algorithm.',\n"
" PRIMARY KEY (channel_name) USING HASH\n",
/* Options */
" ENGINE=PERFORMANCE_SCHEMA",
/* Tablespace */
nullptr);
PFS_engine_table_share table_replication_connection_configuration::m_share = {
&pfs_readonly_acl,
table_replication_connection_configuration::create,
NULL, /* write_row */
NULL, /* delete_all_rows */
table_replication_connection_configuration::get_row_count, /* records */
sizeof(pos_t), /* ref length */
&m_table_lock,
&m_table_def,
true, /* perpetual */
PFS_engine_table_proxy(),
{0},
false /* m_in_purgatory */
};
bool PFS_index_rpl_connection_config::match(Master_info *mi) {
if (m_fields >= 1) {
st_row_connect_config row;
/* Mutex locks not necessary for channel name. */
row.channel_name_length =
mi->get_channel() ? (uint)strlen(mi->get_channel()) : 0;
memcpy(row.channel_name, mi->get_channel(), row.channel_name_length);
if (!m_key.match_not_null(row.channel_name, row.channel_name_length)) {
return false;
}
}
return true;
}
PFS_engine_table *table_replication_connection_configuration::create(
PFS_engine_table_share *) {
return new table_replication_connection_configuration();
}
table_replication_connection_configuration::
table_replication_connection_configuration()
: PFS_engine_table(&m_share, &m_pos), m_pos(0), m_next_pos(0) {}
table_replication_connection_configuration::
~table_replication_connection_configuration() {}
void table_replication_connection_configuration::reset_position(void) {
m_pos.m_index = 0;
m_next_pos.m_index = 0;
}
ha_rows table_replication_connection_configuration::get_row_count() {
/*
We actually give the MAX_CHANNELS rather than the current
number of channels
*/
return channel_map.get_max_channels();
}
int table_replication_connection_configuration::rnd_next(void) {
Master_info *mi;
channel_map.rdlock();
for (m_pos.set_at(&m_next_pos);
m_pos.m_index < channel_map.get_max_channels(); m_pos.next()) {
mi = channel_map.get_mi_at_pos(m_pos.m_index);
if (mi && mi->host[0]) {
make_row(mi);
m_next_pos.set_after(&m_pos);
channel_map.unlock();
return 0;
}
}
channel_map.unlock();
return HA_ERR_END_OF_FILE;
}
int table_replication_connection_configuration::rnd_pos(const void *pos) {
int res = HA_ERR_RECORD_DELETED;
Master_info *mi;
channel_map.rdlock();
set_position(pos);
if ((mi = channel_map.get_mi_at_pos(m_pos.m_index))) {
res = make_row(mi);
}
channel_map.unlock();
return res;
}
int table_replication_connection_configuration::index_init(
uint idx MY_ATTRIBUTE((unused)), bool) {
PFS_index_rpl_connection_config *result = NULL;
DBUG_ASSERT(idx == 0);
result = PFS_NEW(PFS_index_rpl_connection_config);
m_opened_index = result;
m_index = result;
return 0;
}
int table_replication_connection_configuration::index_next(void) {
int res = HA_ERR_END_OF_FILE;
Master_info *mi;
channel_map.rdlock();
for (m_pos.set_at(&m_next_pos);
m_pos.m_index < channel_map.get_max_channels() && res != 0;
m_pos.next()) {
mi = channel_map.get_mi_at_pos(m_pos.m_index);
if (mi && mi->host[0]) {
if (m_opened_index->match(mi)) {
res = make_row(mi);
m_next_pos.set_after(&m_pos);
}
}
}
channel_map.unlock();
return res;
}
int table_replication_connection_configuration::make_row(Master_info *mi) {
const char *temp_store;
DBUG_ASSERT(mi != NULL);
mysql_mutex_lock(&mi->data_lock);
mysql_mutex_lock(&mi->rli->data_lock);
m_row.channel_name_length = strlen(mi->get_channel());
memcpy(m_row.channel_name, (char *)mi->get_channel(),
m_row.channel_name_length);
m_row.host_length = strlen(mi->host);
memcpy(m_row.host, mi->host, m_row.host_length);
m_row.port = (unsigned int)mi->port;
/* can't the user be NULL? */
temp_store = mi->get_user();
m_row.user_length = strlen(temp_store);
memcpy(m_row.user, temp_store, m_row.user_length);
temp_store = (char *)mi->bind_addr;
m_row.network_interface_length = strlen(temp_store);
memcpy(m_row.network_interface, temp_store, m_row.network_interface_length);
if (mi->is_auto_position()) {
m_row.auto_position = PS_RPL_YES;
} else {
m_row.auto_position = PS_RPL_NO;
}
#ifdef HAVE_OPENSSL
m_row.ssl_allowed = mi->ssl ? PS_SSL_ALLOWED_YES : PS_SSL_ALLOWED_NO;
#else
m_row.ssl_allowed = mi->ssl ? PS_SSL_ALLOWED_IGNORED : PS_SSL_ALLOWED_NO;
#endif
temp_store = mi->ssl_ca;
m_row.ssl_ca_file_length = strlen(temp_store);
memcpy(m_row.ssl_ca_file, temp_store, m_row.ssl_ca_file_length);
temp_store = mi->ssl_capath;
m_row.ssl_ca_path_length = strlen(temp_store);
memcpy(m_row.ssl_ca_path, temp_store, m_row.ssl_ca_path_length);
temp_store = mi->ssl_cert;
m_row.ssl_certificate_length = strlen(temp_store);
memcpy(m_row.ssl_certificate, temp_store, m_row.ssl_certificate_length);
temp_store = mi->ssl_cipher;
m_row.ssl_cipher_length = strlen(temp_store);
memcpy(m_row.ssl_cipher, temp_store, m_row.ssl_cipher_length);
temp_store = mi->ssl_key;
m_row.ssl_key_length = strlen(temp_store);
memcpy(m_row.ssl_key, temp_store, m_row.ssl_key_length);
if (mi->ssl_verify_server_cert) {
m_row.ssl_verify_server_certificate = PS_RPL_YES;
} else {
m_row.ssl_verify_server_certificate = PS_RPL_NO;
}
temp_store = mi->ssl_crl;
m_row.ssl_crl_file_length = strlen(temp_store);
memcpy(m_row.ssl_crl_file, temp_store, m_row.ssl_crl_file_length);
temp_store = mi->ssl_crlpath;
m_row.ssl_crl_path_length = strlen(temp_store);
memcpy(m_row.ssl_crl_path, temp_store, m_row.ssl_crl_path_length);
m_row.connection_retry_interval = (unsigned int)mi->connect_retry;
m_row.connection_retry_count = (ulong)mi->retry_count;
m_row.heartbeat_interval = (double)mi->heartbeat_period;
temp_store = mi->tls_version;
m_row.tls_version_length = strlen(temp_store);
memcpy(m_row.tls_version, temp_store, m_row.tls_version_length);
temp_store = mi->public_key_path;
m_row.public_key_path_length = strlen(temp_store);
memcpy(m_row.public_key_path, temp_store, m_row.public_key_path_length);
m_row.get_public_key = mi->get_public_key ? PS_RPL_YES : PS_RPL_NO;
temp_store = mi->network_namespace_str();
m_row.network_namespace_length = strlen(temp_store);
memcpy(m_row.network_namespace, temp_store, m_row.network_namespace_length);
temp_store = mi->compression_algorithm;
m_row.compression_algorithm_length = strlen(temp_store);
memcpy(m_row.compression_algorithm, temp_store,
m_row.compression_algorithm_length);
m_row.zstd_compression_level = mi->zstd_compression_level;
mysql_mutex_unlock(&mi->rli->data_lock);
mysql_mutex_unlock(&mi->data_lock);
return 0;
}
int table_replication_connection_configuration::read_row_values(TABLE *table,
unsigned char *,
Field **fields,
bool read_all) {
Field *f;
for (; (f = *fields); fields++) {
if (read_all || bitmap_is_set(table->read_set, f->field_index)) {
switch (f->field_index) {
case 0: /** channel_name */
set_field_char_utf8(f, m_row.channel_name, m_row.channel_name_length);
break;
case 1: /** host */
set_field_char_utf8(f, m_row.host, m_row.host_length);
break;
case 2: /** port */
set_field_ulong(f, m_row.port);
break;
case 3: /** user */
set_field_char_utf8(f, m_row.user, m_row.user_length);
break;
case 4: /** network_interface */
set_field_char_utf8(f, m_row.network_interface,
m_row.network_interface_length);
break;
case 5: /** auto_position */
set_field_enum(f, m_row.auto_position);
break;
case 6: /** ssl_allowed */
set_field_enum(f, m_row.ssl_allowed);
break;
case 7: /**ssl_ca_file */
set_field_varchar_utf8(f, m_row.ssl_ca_file,
m_row.ssl_ca_file_length);
break;
case 8: /** ssl_ca_path */
set_field_varchar_utf8(f, m_row.ssl_ca_path,
m_row.ssl_ca_path_length);
break;
case 9: /** ssl_certificate */
set_field_varchar_utf8(f, m_row.ssl_certificate,
m_row.ssl_certificate_length);
break;
case 10: /** ssl_cipher */
set_field_varchar_utf8(f, m_row.ssl_cipher, m_row.ssl_cipher_length);
break;
case 11: /** ssl_key */
set_field_varchar_utf8(f, m_row.ssl_key, m_row.ssl_key_length);
break;
case 12: /** ssl_verify_server_certificate */
set_field_enum(f, m_row.ssl_verify_server_certificate);
break;
case 13: /** ssl_crl_file */
set_field_varchar_utf8(f, m_row.ssl_crl_file,
m_row.ssl_crl_file_length);
break;
case 14: /** ssl_crl_path */
set_field_varchar_utf8(f, m_row.ssl_crl_path,
m_row.ssl_crl_path_length);
break;
case 15: /** connection_retry_interval */
set_field_ulong(f, m_row.connection_retry_interval);
break;
case 16: /** connect_retry_count */
set_field_ulonglong(f, m_row.connection_retry_count);
break;
case 17: /** number of seconds after which heartbeat will be sent */
set_field_double(f, m_row.heartbeat_interval);
break;
case 18: /** tls_version */
set_field_varchar_utf8(f, m_row.tls_version,
m_row.tls_version_length);
break;
case 19: /** master_public_key_path */
set_field_varchar_utf8(f, m_row.public_key_path,
m_row.public_key_path_length);
break;
case 20: /** get_master_public_key */
set_field_enum(f, m_row.get_public_key);
break;
case 21: /** network_namespace */
set_field_varchar_utf8(f, m_row.network_namespace,
m_row.network_namespace_length);
break;
case 22: /** compression_algorithm */
set_field_char_utf8(f, m_row.compression_algorithm,
m_row.compression_algorithm_length);
break;
case 23: /** zstd_compression_level */
set_field_ulong(f, m_row.zstd_compression_level);
break;
default:
DBUG_ASSERT(false);
}
}
}
return 0;
}