8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-02-02 10:00:38 +01:00

Add table MON$COMPILED_STATEMENTS and columns (#7050)

Add table MON$COMPILED_STATEMENTS and columns MON$STATEMENTS.MON$COMPILED_STATEMENT_ID and MON$CALL_STACK.MON$COMPILED_STATEMENT_ID.
This commit is contained in:
Adriano dos Santos Fernandes 2022-02-06 21:41:11 -03:00 committed by GitHub
parent f1447fc0c0
commit 1a072f43d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 147 additions and 21 deletions

View File

@ -2206,7 +2206,9 @@ static void sql_info(thread_db* tdbb,
{
const bool detailed = (item == isc_info_sql_explain_plan);
string plan = tdbb->getAttachment()->stringToUserCharSet(tdbb,
OPT_get_plan(tdbb, request->req_request, detailed));
OPT_get_plan(tdbb,
(request->req_request ? request->req_request->getStatement() : nullptr),
detailed));
if (plan.hasData())
{

View File

@ -225,6 +225,7 @@ Jrd::Attachment::Attachment(MemoryPool* pool, Database* dbb, JProvider* provider
att_ss_user(NULL),
att_user_ids(*pool),
att_active_snapshots(*pool),
att_statements(*pool),
att_requests(*pool),
att_lock_owner_id(Database::getLockOwnerId()),
att_backup_state_counter(0),

View File

@ -545,6 +545,7 @@ private:
StableAttachmentPart* att_stable;
public:
Firebird::SortedArray<JrdStatement*> att_statements; // Statements belonging to attachment
Firebird::SortedArray<jrd_req*> att_requests; // Requests belonging to attachment
Lock* att_id_lock; // Attachment lock (if any)
AttNumber att_attachment_id; // Attachment ID

View File

@ -59,6 +59,7 @@
#include "../jrd/RandomGenerator.h"
#include "../common/os/guid.h"
#include "../common/os/os_utils.h"
#include "../jrd/ods.h"
#include "../jrd/sbm.h"
#include "../jrd/flu.h"
#include "../jrd/RuntimeStatistics.h"
@ -582,6 +583,11 @@ public:
return (dbb_replica_mode == mode);
}
USHORT getEncodedOdsVersion() const
{
return ENCODE_ODS(dbb_ods_version, dbb_minor_version);
}
private:
Database(MemoryPool* p, Firebird::IPluginConfig* pConf, bool shared)
: dbb_permanent(p),

View File

@ -304,6 +304,8 @@ JrdStatement* JrdStatement::makeStatement(thread_db* tdbb, CompilerScratch* csb,
if (internalFlag)
statement->flags |= FLAG_INTERNAL;
tdbb->getAttachment()->att_statements.add(statement);
return statement;
}
@ -407,7 +409,6 @@ jrd_req* JrdStatement::getRequest(thread_db* tdbb, USHORT level)
// Create the request.
jrd_req* const request = FB_NEW_POOL(*pool) jrd_req(attachment, this, parentStats);
request->setRequestId(dbb->generateStatementId());
requests[level] = request;
@ -645,14 +646,19 @@ void JrdStatement::release(thread_db* tdbb)
for (jrd_req** instance = requests.begin(); instance != requests.end(); ++instance)
EXE_release(tdbb, *instance);
const auto attachment = tdbb->getAttachment();
FB_SIZE_T pos;
if (attachment->att_statements.find(this, pos))
attachment->att_statements.remove(pos);
else
fb_assert(false);
sqlText = NULL;
// Sub statement pool is the same of the main statement, so don't delete it.
if (!parentStatement)
{
Jrd::Attachment* const att = tdbb->getAttachment();
att->deletePool(pool);
}
attachment->deletePool(pool);
}
// Check that we have enough rights to access all resources this list of triggers touches.

View File

@ -48,6 +48,13 @@ public:
static JrdStatement* makeStatement(thread_db* tdbb, CompilerScratch* csb, bool internalFlag);
static jrd_req* makeRequest(thread_db* tdbb, CompilerScratch* csb, bool internalFlag);
StmtNumber getStatementId() const
{
if (!id)
id = JRD_get_thread_data()->getDatabase()->generateStatementId();
return id;
}
const Routine* getRoutine() const;
bool isActive() const;
@ -68,6 +75,7 @@ public:
unsigned flags; // statement flags
unsigned blrVersion;
ULONG impureSize; // Size of impure area
mutable StmtNumber id; // statement identifier
Firebird::Array<record_param> rpbsSetup;
Firebird::Array<jrd_req*> requests; // vector of requests
ExternalAccessList externalList; // Access to procedures/triggers to be checked

View File

@ -446,6 +446,9 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool)
RecordBuffer* const dbb_buffer = allocBuffer(tdbb, pool, rel_mon_database);
RecordBuffer* const att_buffer = allocBuffer(tdbb, pool, rel_mon_attachments);
RecordBuffer* const tra_buffer = allocBuffer(tdbb, pool, rel_mon_transactions);
RecordBuffer* const cmp_stmt_buffer = dbb->getEncodedOdsVersion() >= ODS_13_1 ?
allocBuffer(tdbb, pool, rel_mon_compiled_statements) :
nullptr;
RecordBuffer* const stmt_buffer = allocBuffer(tdbb, pool, rel_mon_statements);
RecordBuffer* const call_buffer = allocBuffer(tdbb, pool, rel_mon_calls);
RecordBuffer* const io_stat_buffer = allocBuffer(tdbb, pool, rel_mon_io_stats);
@ -561,6 +564,9 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool)
case rel_mon_transactions:
buffer = tra_buffer;
break;
case rel_mon_compiled_statements:
buffer = cmp_stmt_buffer;
break;
case rel_mon_statements:
buffer = stmt_buffer;
break;
@ -1039,7 +1045,7 @@ void Monitoring::putAttachment(SnapshotData::DumpRecord& record, const Jrd::Atta
// statement timeout, milliseconds
record.storeInteger(f_mon_att_stmt_timeout, attachment->getStatementTimeout());
if (ENCODE_ODS(dbb->dbb_ods_version, dbb->dbb_minor_version) >= ODS_13_1)
if (dbb->getEncodedOdsVersion() >= ODS_13_1)
{
char timeZoneBuffer[TimeZoneUtil::MAX_SIZE];
TimeZoneUtil::format(timeZoneBuffer, sizeof(timeZoneBuffer), attachment->att_current_timezone);
@ -1134,11 +1140,49 @@ void Monitoring::putTransaction(SnapshotData::DumpRecord& record, const jrd_tra*
}
void Monitoring::putStatement(SnapshotData::DumpRecord& record, const JrdStatement* statement, const string& plan)
{
fb_assert(statement);
record.reset(rel_mon_compiled_statements);
// compiled statement id
record.storeInteger(f_mon_cmp_stmt_id, statement->getStatementId());
// sql text
if (statement->sqlText)
record.storeString(f_mon_cmp_stmt_sql_text, *statement->sqlText);
// explained plan
if (plan.hasData())
record.storeString(f_mon_cmp_stmt_expl_plan, plan);
// object name/type
if (const auto routine = statement->getRoutine())
{
if (routine->getName().package.hasData())
record.storeString(f_mon_cmp_stmt_pkg_name, routine->getName().package);
record.storeString(f_mon_cmp_stmt_name, routine->getName().identifier);
record.storeInteger(f_mon_cmp_stmt_type, routine->getObjectType());
}
else if (!statement->triggerName.isEmpty())
{
record.storeString(f_mon_cmp_stmt_name, statement->triggerName);
record.storeInteger(f_mon_cmp_stmt_type, obj_trigger);
}
record.write();
}
void Monitoring::putRequest(SnapshotData::DumpRecord& record, const jrd_req* request,
const string& plan)
{
fb_assert(request);
const auto dbb = request->req_attachment->att_database;
record.reset(rel_mon_statements);
// request id
@ -1181,6 +1225,10 @@ void Monitoring::putRequest(SnapshotData::DumpRecord& record, const jrd_req* req
// statement timeout, milliseconds
record.storeInteger(f_mon_stmt_timeout, request->req_timeout);
if (dbb->getEncodedOdsVersion() >= ODS_13_1)
record.storeInteger(f_mon_stmt_cmp_stmt_id, statement->getStatementId());
record.write();
putStatistics(record, request->req_stats, stat_id, stat_statement);
@ -1192,7 +1240,9 @@ void Monitoring::putCall(SnapshotData::DumpRecord& record, const jrd_req* reques
{
fb_assert(request);
const auto dbb = request->req_attachment->att_database;
const jrd_req* initialRequest = request->req_caller;
while (initialRequest->req_caller)
{
initialRequest = initialRequest->req_caller;
@ -1241,6 +1291,9 @@ void Monitoring::putCall(SnapshotData::DumpRecord& record, const jrd_req* reques
record.storeInteger(f_mon_call_src_column, request->req_src_column);
}
if (dbb->getEncodedOdsVersion() >= ODS_13_1)
record.storeInteger(f_mon_call_cmp_stmt_id, statement->getStatementId());
// statistics
const int stat_id = fb_utils::genUniqueId();
record.storeGlobalId(f_mon_call_stat_id, getGlobalId(stat_id));
@ -1432,18 +1485,29 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment)
}
}
if (dbb->getEncodedOdsVersion() >= ODS_13_1)
{
// Statement information
for (const auto statement : attachment->att_statements)
{
if (!(statement->flags & (JrdStatement::FLAG_INTERNAL | JrdStatement::FLAG_SYS_TRIGGER)))
{
const string plan = OPT_get_plan(tdbb, statement, true);
putStatement(record, statement, plan);
}
}
}
// Request information
for (const jrd_req* const* i = attachment->att_requests.begin();
i != attachment->att_requests.end();
++i)
for (const auto request : attachment->att_requests)
{
const jrd_req* const request = *i;
const auto statement = request->getStatement();
if (!(request->getStatement()->flags &
(JrdStatement::FLAG_INTERNAL | JrdStatement::FLAG_SYS_TRIGGER)))
if (!(statement->flags & (JrdStatement::FLAG_INTERNAL | JrdStatement::FLAG_SYS_TRIGGER)))
{
const string plan = OPT_get_plan(tdbb, request, true);
const string plan = OPT_get_plan(tdbb, statement, true);
putRequest(record, request, plan);
}
}

View File

@ -389,6 +389,7 @@ private:
static void putAttachment(SnapshotData::DumpRecord&, const Attachment*);
static void putTransaction(SnapshotData::DumpRecord&, const jrd_tra*);
static void putStatement(SnapshotData::DumpRecord&, const JrdStatement*, const Firebird::string&);
static void putRequest(SnapshotData::DumpRecord&, const jrd_req*, const Firebird::string&);
static void putCall(SnapshotData::DumpRecord&, const jrd_req*);
static void putStatistics(SnapshotData::DumpRecord&, const RuntimeStatistics&, int, int);

View File

@ -860,7 +860,14 @@ void EXE_start(thread_db* tdbb, jrd_req* request, jrd_tra* transaction)
if (transaction->tra_flags & TRA_prepared)
ERR_post(Arg::Gds(isc_req_no_trans));
JrdStatement* statement = request->getStatement();
const auto dbb = tdbb->getDatabase();
const auto statement = request->getStatement();
// Generate request id.
request->setRequestId(
request->isRequestIdUnassigned() && request->isRoot() ?
statement->getStatementId() :
dbb->generateStatementId());
/* Post resources to transaction block. In particular, the interest locks
on relations/indices are copied to the transaction, which is very

View File

@ -457,3 +457,6 @@ NAME("MON$SESSION_TIMEZONE", nam_mon_session_tz)
NAME("RDB$KEYWORDS", nam_keywords)
NAME("RDB$KEYWORD_NAME", nam_keyword_name)
NAME("RDB$KEYWORD_RESERVED", nam_keyword_reserved)
NAME("MON$COMPILED_STATEMENTS", nam_mon_compiled_statements)
NAME("MON$COMPILED_STATEMENT_ID", nam_mon_cmp_stmt_id)

View File

@ -439,7 +439,7 @@ static const UCHAR sort_dtypes[] =
};
string OPT_get_plan(thread_db* tdbb, const jrd_req* request, bool detailed)
string OPT_get_plan(thread_db* tdbb, const JrdStatement* statement, bool detailed)
{
/**************************************
*
@ -453,9 +453,9 @@ string OPT_get_plan(thread_db* tdbb, const jrd_req* request, bool detailed)
**************************************/
string plan;
if (request)
if (statement)
{
const Array<const RecordSource*>& fors = request->getStatement()->fors;
const Array<const RecordSource*>& fors = statement->fors;
for (FB_SIZE_T i = 0; i < fors.getCount(); i++)
{

View File

@ -41,7 +41,7 @@ namespace Jrd {
class MapNode;
}
Firebird::string OPT_get_plan(Jrd::thread_db* tdbb, const Jrd::jrd_req* request, bool detailed);
Firebird::string OPT_get_plan(Jrd::thread_db* tdbb, const Jrd::JrdStatement* statement, bool detailed);
Jrd::RecordSource* OPT_compile(Jrd::thread_db* tdbb, Jrd::CompilerScratch* csb,
Jrd::RseNode* rse, Jrd::BoolExprNodeStack* parent_stack);
void OPT_compile_relation(Jrd::thread_db* tdbb, Jrd::jrd_rel* relation, Jrd::CompilerScratch* csb,

View File

@ -561,6 +561,7 @@ RELATION(nam_mon_statements, rel_mon_statements, ODS_11_1, rel_virtual)
FIELD(f_mon_stmt_expl_plan, nam_mon_expl_plan, fld_source, 0, ODS_11_1)
FIELD(f_mon_stmt_timeout, nam_stmt_timeout, fld_stmt_timeout, 0, ODS_13_0)
FIELD(f_mon_stmt_timer, nam_stmt_timer, fld_stmt_timer, 0, ODS_13_0)
FIELD(f_mon_stmt_cmp_stmt_id, nam_mon_cmp_stmt_id, fld_stmt_id, 0, ODS_13_1)
END_RELATION
// Relation 37 (MON$CALL_STACK)
@ -575,6 +576,7 @@ RELATION(nam_mon_calls, rel_mon_calls, ODS_11_1, rel_virtual)
FIELD(f_mon_call_src_column, nam_mon_src_column, fld_src_info, 0, ODS_11_1)
FIELD(f_mon_call_stat_id, nam_mon_stat_id, fld_stat_id, 0, ODS_11_1)
FIELD(f_mon_call_pkg_name, nam_mon_pkg_name, fld_pkg_name, 0, ODS_12_0)
FIELD(f_mon_call_cmp_stmt_id, nam_mon_cmp_stmt_id, fld_stmt_id, 0, ODS_13_1)
END_RELATION
// Relation 38 (MON$IO_STATS)
@ -741,3 +743,13 @@ RELATION(nam_keywords, rel_keywords, ODS_13_1, rel_virtual)
FIELD(f_keyword_name, nam_keyword_name, fld_keyword_name, 0, ODS_13_1)
FIELD(f_keyword_reserved, nam_keyword_reserved, fld_keyword_reserved, 0, ODS_13_1)
END_RELATION
// Relation 55 (MON$COMPILED_STATEMENTS)
RELATION(nam_mon_compiled_statements, rel_mon_compiled_statements, ODS_13_1, rel_virtual)
FIELD(f_mon_cmp_stmt_id, nam_mon_cmp_stmt_id, fld_stmt_id, 0, ODS_13_1)
FIELD(f_mon_cmp_stmt_sql_text, nam_mon_sql_text, fld_source, 0, ODS_13_1)
FIELD(f_mon_cmp_stmt_expl_plan, nam_mon_expl_plan, fld_source, 0, ODS_13_1)
FIELD(f_mon_cmp_stmt_name, nam_mon_obj_name, fld_gnr_name, 0, ODS_13_1)
FIELD(f_mon_cmp_stmt_type, nam_mon_obj_type, fld_obj_type, 0, ODS_13_1)
FIELD(f_mon_cmp_stmt_pkg_name, nam_mon_pkg_name, fld_pkg_name, 0, ODS_13_1)
END_RELATION

View File

@ -317,10 +317,25 @@ public:
CS_METADATA : req_attachment->att_charset;
}
bool isRoot() const
{
return statement->requests.hasData() && this == statement->requests[0];
}
bool isRequestIdUnassigned() const
{
return req_id == 0;
}
StmtNumber getRequestId() const
{
if (!req_id)
req_id = JRD_get_thread_data()->getDatabase()->generateStatementId();
{
req_id = isRoot() ?
statement->getStatementId() :
JRD_get_thread_data()->getDatabase()->generateStatementId();
}
return req_id;
}

View File

@ -212,7 +212,7 @@ void TraceSQLStatementImpl::fillPlan(bool explained)
{
m_planExplained = explained;
if (m_stmt->req_request)
m_plan = OPT_get_plan(JRD_get_thread_data(), m_stmt->req_request, m_planExplained);
m_plan = OPT_get_plan(JRD_get_thread_data(), m_stmt->req_request->getStatement(), m_planExplained);
}
}