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:
parent
f1447fc0c0
commit
1a072f43d8
@ -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())
|
||||
{
|
||||
|
@ -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),
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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++)
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user