Remove DESCRIBE statement cache option

Remove the `DESCRIBE` (statement) cache option and related cache code.
v3.0_extended_query_protocol_phase_2
Rahim Kanji 6 months ago
parent 71e8a2e8d5
commit 38841bf189

@ -22,22 +22,14 @@ public:
uint64_t statement_id;
char* first_comment;
uint64_t total_mem_usage;
PgSQL_Describe_Prepared_Info* stmt_metadata;
bool is_select_NOT_for_update;
Parse_Param_Types parse_param_types;// array of parameter types, used for prepared statements
PgSQL_STMT_Global_info(uint64_t id, char* u, char* d, char* q, unsigned int ql, char* fc, Parse_Param_Types&& ppt, uint64_t _h);
~PgSQL_STMT_Global_info();
void update_stmt_metadata(PgSQL_Describe_Prepared_Info** new_stmt_metadata);
void calculate_mem_usage();
void unlock() { pthread_rwlock_unlock(&rwlock_); }
void wrlock() { pthread_rwlock_wrlock(&rwlock_); }
void rdlock() { pthread_rwlock_rdlock(&rwlock_); }
private:
pthread_rwlock_t rwlock_;
void compute_hash();
};

@ -306,7 +306,7 @@
#define STATS_SQLITE_TABLE_PGSQL_COMMANDS_COUNTERS "CREATE TABLE stats_pgsql_commands_counters (Command VARCHAR NOT NULL PRIMARY KEY , Total_Time_us INT NOT NULL , Total_cnt INT NOT NULL , cnt_100us INT NOT NULL , cnt_500us INT NOT NULL , cnt_1ms INT NOT NULL , cnt_5ms INT NOT NULL , cnt_10ms INT NOT NULL , cnt_50ms INT NOT NULL , cnt_100ms INT NOT NULL , cnt_500ms INT NOT NULL , cnt_1s INT NOT NULL , cnt_5s INT NOT NULL , cnt_10s INT NOT NULL , cnt_INFs)"
#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST "CREATE TABLE stats_pgsql_query_digest (hostgroup INT , database VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, database, username, client_address, digest))"
#define STATS_SQLITE_TABLE_PGSQL_QUERY_DIGEST_RESET "CREATE TABLE stats_pgsql_query_digest_reset (hostgroup INT , database VARCHAR NOT NULL , username VARCHAR NOT NULL , client_address VARCHAR NOT NULL , digest VARCHAR NOT NULL , digest_text VARCHAR NOT NULL , count_star INTEGER NOT NULL , first_seen INTEGER NOT NULL , last_seen INTEGER NOT NULL , sum_time INTEGER NOT NULL , min_time INTEGER NOT NULL , max_time INTEGER NOT NULL , sum_rows_affected INTEGER NOT NULL , sum_rows_sent INTEGER NOT NULL , PRIMARY KEY(hostgroup, database, username, client_address, digest))"
#define STATS_SQLITE_TABLE_PGSQL_PREPARED_STATEMENTS_INFO "CREATE TABLE stats_pgsql_prepared_statements_info (global_stmt_id INT NOT NULL , database VARCHAR NOT NULL , username VARCHAR NOT NULL , digest VARCHAR NOT NULL , ref_count_client INT NOT NULL , ref_count_server INT NOT NULL , num_columns INT NOT NULL, num_params INT NOT NULL, query VARCHAR NOT NULL)"
#define STATS_SQLITE_TABLE_PGSQL_PREPARED_STATEMENTS_INFO "CREATE TABLE stats_pgsql_prepared_statements_info (global_stmt_id INT NOT NULL , database VARCHAR NOT NULL , username VARCHAR NOT NULL , digest VARCHAR NOT NULL , ref_count_client INT NOT NULL , ref_count_server INT NOT NULL , num_param_types INT NOT NULL , query VARCHAR NOT NULL)"
//#define STATS_SQLITE_TABLE_MEMORY_METRICS "CREATE TABLE stats_memory_metrics (Variable_Name VARCHAR NOT NULL PRIMARY KEY , Variable_Value VARCHAR NOT NULL)"

@ -11,7 +11,7 @@
extern PgSQL_STMT_Manager_v14 *GloPgStmt;
const int PS_GLOBAL_STATUS_FIELD_NUM = 9;
const int PS_GLOBAL_STATUS_FIELD_NUM = 8;
static uint64_t stmt_compute_hash(const char *user,
const char *database, const char *query, unsigned int query_length, const Parse_Param_Types& param_types) {
@ -69,13 +69,11 @@ PgSQL_STMT_Global_info::PgSQL_STMT_Global_info(uint64_t id,
char *fc,
Parse_Param_Types&& ppt,
uint64_t _h) {
pthread_rwlock_init(&rwlock_, NULL);
total_mem_usage = 0;
statement_id = id;
ref_count_client = 0;
ref_count_server = 0;
digest_text = nullptr;
stmt_metadata = nullptr;
username = strdup(u);
dbname = strdup(d);
query = (char *)malloc(ql + 1);
@ -162,81 +160,6 @@ __exit_PgSQL_STMT_Global_info___search_select:
calculate_mem_usage();
}
void PgSQL_STMT_Global_info::calculate_mem_usage() {
total_mem_usage = sizeof(PgSQL_STMT_Global_info) +
query_length + 1;
// NOSONAR: strlen is safe here
if (username) total_mem_usage += strlen(username) + 1; // NOSONAR
if (dbname) total_mem_usage += strlen(dbname) + 1; // NOSONAR
if (first_comment) total_mem_usage += strlen(first_comment) + 1; // NOSONAR
if (digest_text) total_mem_usage += strlen(digest_text) + 1; // NOSONAR
if (stmt_metadata) {
total_mem_usage += sizeof(PgSQL_Describe_Prepared_Info);
total_mem_usage += stmt_metadata->parameter_types_count * sizeof(uint32_t) ;
total_mem_usage += stmt_metadata->columns_count * sizeof(ColumnMetadata);
for (uint16_t i = 0; i < stmt_metadata->columns_count; i++) {
if (stmt_metadata->columns[i].name)
// NOSONAR: strlen is safe here
total_mem_usage += strlen(stmt_metadata->columns[i].name) + 1; // NOSONAR
}
}
}
void PgSQL_STMT_Global_info::update_stmt_metadata(PgSQL_Describe_Prepared_Info** new_stmt_metadata) {
bool need_refresh = false;
pthread_rwlock_wrlock(&rwlock_);
if (stmt_metadata == nullptr) {
stmt_metadata = *new_stmt_metadata;
*new_stmt_metadata = nullptr;
pthread_rwlock_unlock(&rwlock_);
return;
}
if (stmt_metadata->parameter_types_count != (*new_stmt_metadata)->parameter_types_count) {
need_refresh = true;
} else {
for (size_t i = 0; i < (*new_stmt_metadata)->parameter_types_count; i++) {
if (stmt_metadata->parameter_types[i] != (*new_stmt_metadata)->parameter_types[i]) {
need_refresh = true;
break;
}
}
}
if (need_refresh == false) {
if (stmt_metadata->columns_count != (*new_stmt_metadata)->columns_count) {
need_refresh = true;
} else {
for (size_t i = 0; i < (*new_stmt_metadata)->columns_count; ++i) {
const auto& current_col = stmt_metadata->columns[i];
const auto& update_col = (*new_stmt_metadata)->columns[i];
if (strcmp(current_col.name, update_col.name) || // NOSONAR: strcmp is safe here
current_col.table_oid != update_col.table_oid ||
current_col.column_index != update_col.column_index ||
current_col.type_oid != update_col.type_oid ||
current_col.length != update_col.length ||
current_col.type_modifier != update_col.type_modifier ||
current_col.format != update_col.format) {
need_refresh = true;
break;
}
}
}
}
if (need_refresh) {
delete stmt_metadata;
stmt_metadata = *new_stmt_metadata;
*new_stmt_metadata = nullptr;
calculate_mem_usage();
}
pthread_rwlock_unlock(&rwlock_);
}
PgSQL_STMT_Global_info::~PgSQL_STMT_Global_info() {
free(username);
free(dbname);
@ -246,9 +169,17 @@ PgSQL_STMT_Global_info::~PgSQL_STMT_Global_info() {
if (digest_text)
free(digest_text);
parse_param_types.clear(); // clear the parameter types vector
if (stmt_metadata)
delete stmt_metadata;
pthread_rwlock_destroy(&rwlock_);
}
void PgSQL_STMT_Global_info::calculate_mem_usage() {
total_mem_usage = sizeof(PgSQL_STMT_Global_info) +
query_length + 1;
// NOSONAR: strlen is safe here
if (username) total_mem_usage += strlen(username) + 1; // NOSONAR
if (dbname) total_mem_usage += strlen(dbname) + 1; // NOSONAR
if (first_comment) total_mem_usage += strlen(first_comment) + 1; // NOSONAR
if (digest_text) total_mem_usage += strlen(digest_text) + 1; // NOSONAR
}
void PgSQL_STMTs_local_v14::backend_insert(uint64_t global_stmt_id, uint32_t backend_stmt_id) {
@ -608,10 +539,9 @@ class PgSQL_PS_global_stats {
unsigned long long ref_count_client;
unsigned long long ref_count_server;
char *query;
int num_columns;
int num_params;
int num_param_types;
PgSQL_PS_global_stats(uint64_t stmt_id, const char *d, const char *u, uint64_t dig, const char *q,
unsigned long long ref_c, unsigned long long ref_s, int columns, int params) {
unsigned long long ref_c, unsigned long long ref_s, int params) {
statement_id = stmt_id;
digest = dig;
query = strndup(q, pgsql_thread___query_digests_max_digest_length);
@ -619,8 +549,7 @@ class PgSQL_PS_global_stats {
dbname = strdup(d);
ref_count_client = ref_c;
ref_count_server = ref_s;
num_columns = columns;
num_params = params;
num_param_types = params;
}
~PgSQL_PS_global_stats() {
if (query)
@ -647,10 +576,8 @@ class PgSQL_PS_global_stats {
pta[5]=strdup(buf);
snprintf(buf,sizeof(buf),"%llu",ref_count_server);
pta[6]=strdup(buf);
snprintf(buf,sizeof(buf),"%d",num_columns);
snprintf(buf,sizeof(buf),"%d",num_param_types);
pta[7]=strdup(buf);
snprintf(buf,sizeof(buf),"%d",num_params);
pta[8]=strdup(buf);
return pta;
}
@ -668,7 +595,6 @@ class PgSQL_PS_global_stats {
SQLite3_result* PgSQL_STMT_Manager_v14::get_prepared_statements_global_infos() {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "Dumping current prepared statements global info\n");
auto result = std::make_unique<SQLite3_result>(PS_GLOBAL_STATUS_FIELD_NUM);
rdlock();
result->add_column_definition(SQLITE_TEXT,"stmt_id");
result->add_column_definition(SQLITE_TEXT,"database");
result->add_column_definition(SQLITE_TEXT,"username");
@ -676,25 +602,15 @@ SQLite3_result* PgSQL_STMT_Manager_v14::get_prepared_statements_global_infos() {
result->add_column_definition(SQLITE_TEXT,"query");
result->add_column_definition(SQLITE_TEXT,"ref_count_client");
result->add_column_definition(SQLITE_TEXT,"ref_count_server");
result->add_column_definition(SQLITE_TEXT,"num_columns");
result->add_column_definition(SQLITE_TEXT,"num_params");
result->add_column_definition(SQLITE_TEXT,"num_param_types");
rdlock();
for (auto it = map_stmt_id_to_info.begin(); it != map_stmt_id_to_info.end(); ++it) {
int columns_count = -1;
int parameter_types_count = -1;
PgSQL_STMT_Global_info *a = it->second;
a->rdlock();
if (const PgSQL_Describe_Prepared_Info* stmt_metadata = a->stmt_metadata; stmt_metadata != nullptr) {
columns_count = stmt_metadata->columns_count;
parameter_types_count = stmt_metadata->parameter_types_count;
}
a->unlock();
PgSQL_STMT_Global_info *stmt_global_info = it->second;
auto pgs = std::make_unique<PgSQL_PS_global_stats>(a->statement_id,
a->dbname, a->username, a->hash, a->query,
a->ref_count_client, a->ref_count_server,
columns_count,
parameter_types_count);
auto pgs = std::make_unique<PgSQL_PS_global_stats>(stmt_global_info->statement_id,
stmt_global_info->dbname, stmt_global_info->username, stmt_global_info->hash, stmt_global_info->query,
stmt_global_info->ref_count_client, stmt_global_info->ref_count_server, stmt_global_info->parse_param_types.size());
char **pta = pgs->get_row();
result->add_row(pta);
pgs->free_row(pta);

@ -5769,25 +5769,6 @@ int PgSQL_Session::handle_post_sync_describe_message(PgSQL_Describe_Message* des
(begint.tv_sec * 1000000000 + begint.tv_nsec);
}
}
// Use cached stmt_metadata only for statements; for portals, forward the describe request to backend.
if (extended_query_info.stmt_type == 'S') {
stmt_info->rdlock();
if (stmt_info->stmt_metadata) {
// we have the metadata, so we can send it to the client
client_myds->setDSS_STATE_QUERY_SENT_NET();
bool send_ready_packet = is_extended_query_ready_for_query();
unsigned int nTxn = NumActiveTransactions();
const char txn_state = (nTxn ? 'T' : 'I');
client_myds->myprot.generate_describe_completion_packet(true, send_ready_packet, stmt_info->stmt_metadata,
extended_query_info.stmt_type, txn_state);
stmt_info->unlock();
//LogQuery(NULL);
//CurrentQuery.end_time = thread->curtime;
RequestEnd(NULL, false);
return 0;
}
stmt_info->unlock();
}
// setting 'prepared' to prevent fetching results from the cache if the digest matches
if (extended_query_exec_qp) {
@ -6361,26 +6342,12 @@ void PgSQL_Session::handler___rc0_PROCESSING_STMT_DESCRIBE_PREPARE(PgSQL_Data_St
bool send_ready_packet = is_extended_query_ready_for_query();
char txn_state = myds->myconn->get_transaction_status_char();
if (extended_query_info.stmt_type == 'S') {
GloPgStmt->wrlock();
extended_query_info.stmt_info->update_stmt_metadata(&myds->myconn->stmt_metadata_result);
client_myds->myprot.generate_describe_completion_packet(true, send_ready_packet, extended_query_info.stmt_info->stmt_metadata,
extended_query_info.stmt_type, txn_state);
LogQuery(myds);
GloPgStmt->unlock();
if (myds->myconn->stmt_metadata_result) {
delete myds->myconn->stmt_metadata_result;
myds->myconn->stmt_metadata_result = NULL;
}
} else {
// For portals, we don't cache metadata
client_myds->myprot.generate_describe_completion_packet(true, send_ready_packet, myds->myconn->stmt_metadata_result,
extended_query_info.stmt_type, txn_state);
LogQuery(myds);
if (myds->myconn->stmt_metadata_result) {
delete myds->myconn->stmt_metadata_result;
myds->myconn->stmt_metadata_result = NULL;
}
client_myds->myprot.generate_describe_completion_packet(true, send_ready_packet, myds->myconn->stmt_metadata_result,
extended_query_info.stmt_type, txn_state);
LogQuery(myds);
if (myds->myconn->stmt_metadata_result) {
delete myds->myconn->stmt_metadata_result;
myds->myconn->stmt_metadata_result = NULL;
}
}

@ -2324,8 +2324,8 @@ void ProxySQL_Admin::stats___pgsql_prepared_statements_info() {
char* query32 = NULL;
std::string query32s = "";
statsdb->execute("DELETE FROM stats_pgsql_prepared_statements_info");
query1 = (char*)"INSERT INTO stats_pgsql_prepared_statements_info VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)";
query32s = "INSERT INTO stats_pgsql_prepared_statements_info VALUES " + generate_multi_rows_query(32, 9);
query1 = (char*)"INSERT INTO stats_pgsql_prepared_statements_info VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)";
query32s = "INSERT INTO stats_pgsql_prepared_statements_info VALUES " + generate_multi_rows_query(32, 8);
query32 = (char*)query32s.c_str();
//rc=(*proxy_sqlite3_prepare_v2)(mydb3, query1, -1, &statement1, 0);
//rc=sqlite3_prepare_v2(mydb3, query1, -1, &statement1, 0);
@ -2341,15 +2341,14 @@ void ProxySQL_Admin::stats___pgsql_prepared_statements_info() {
SQLite3_row* r1 = *it;
int idx = row_idx % 32;
if (row_idx < max_bulk_row_idx) { // bulk
rc = sqlite3_bind_int64(statement32, (idx * 9) + 1, atoll(r1->fields[0])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 9) + 2, r1->fields[1], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 9) + 3, r1->fields[2], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 9) + 4, r1->fields[3], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 9) + 5, atoll(r1->fields[5])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 9) + 6, atoll(r1->fields[6])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 9) + 7, atoll(r1->fields[7])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 9) + 8, atoll(r1->fields[8])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 9) + 9, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 8) + 1, atoll(r1->fields[0])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 8) + 2, r1->fields[1], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 8) + 3, r1->fields[2], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 8) + 4, r1->fields[3], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 8) + 5, atoll(r1->fields[5])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 8) + 6, atoll(r1->fields[6])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement32, (idx * 8) + 7, atoll(r1->fields[7])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement32, (idx * 8) + 8, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
if (idx == 31) {
SAFE_SQLITE3_STEP2(statement32);
rc = (*proxy_sqlite3_clear_bindings)(statement32); ASSERT_SQLITE_OK(rc, statsdb);
@ -2363,8 +2362,7 @@ void ProxySQL_Admin::stats___pgsql_prepared_statements_info() {
rc = sqlite3_bind_int64(statement1, 5, atoll(r1->fields[5])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement1, 6, atoll(r1->fields[6])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement1, 7, atoll(r1->fields[7])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_int64(statement1, 8, atoll(r1->fields[8])); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement1, 9, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
rc = sqlite3_bind_text(statement1, 8, r1->fields[4], -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb);
SAFE_SQLITE3_STEP2(statement1);
rc = (*proxy_sqlite3_clear_bindings)(statement1); ASSERT_SQLITE_OK(rc, statsdb);
rc = (*proxy_sqlite3_reset)(statement1); ASSERT_SQLITE_OK(rc, statsdb);

Loading…
Cancel
Save