Skip to content

Makes MON$COMPILED_STATEMENTS and MON$STATEMENTS share blobs with text and plan content of the same statement. #8513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 12, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 83 additions & 8 deletions src/jrd/Monitoring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,12 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool)

// Parse the dump

// BlobID's of statement text and plan
struct StmtBlobs { bid text; bid plan; };

// Map compiled statement id to blobs ids
NonPooledMap<FB_UINT64, StmtBlobs> blobsMap(pool);

MonitoringData::Reader reader(pool, temp_space);

SnapshotData::DumpRecord dumpRecord(pool);
Expand Down Expand Up @@ -617,7 +623,71 @@ MonitoringSnapshot::MonitoringSnapshot(thread_db* tdbb, MemoryPool& pool)
}

if (store_record)
{
if (dbb->getEncodedOdsVersion() >= ODS_13_1)
{
// The code below requires that rel_mon_compiled_statements put
// into dump before rel_mon_statements, see also dumpAttachment()

FB_UINT64 stmtId;
StmtBlobs stmtBlobs;
dsc desc;

if ((rid == rel_mon_compiled_statements) && EVL_field(nullptr, record, f_mon_cmp_stmt_id, &desc))
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.dsc_dtype == dtype_int64);

fb_assert(desc.dsc_dtype == dtype_int64);
stmtId = *(FB_UINT64*) desc.dsc_address;

if (EVL_field(nullptr, record, f_mon_cmp_stmt_sql_text, &desc))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.isBlob());

{
fb_assert(desc.isBlob());
stmtBlobs.text = *reinterpret_cast<bid*>(desc.dsc_address);
}
else
stmtBlobs.text.clear();

if (EVL_field(nullptr, record, f_mon_cmp_stmt_expl_plan, &desc))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.isBlob());

{
fb_assert(desc.isBlob());
stmtBlobs.plan = *reinterpret_cast<bid*>(desc.dsc_address);
}
else
stmtBlobs.plan.clear();

if (!stmtBlobs.text.isEmpty() || !stmtBlobs.plan.isEmpty())
blobsMap.put(stmtId, stmtBlobs);
}
else if ((rid == rel_mon_statements) && EVL_field(nullptr, record, f_mon_stmt_cmp_stmt_id, &desc))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add a comment that here we assume that compiled statements are stored in the dump before requests.

{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.dsc_dtype == dtype_int64);

fb_assert(desc.dsc_dtype == dtype_int64);
stmtId = *(FB_UINT64*) desc.dsc_address;

if (blobsMap.get(stmtId, stmtBlobs))
{
if (!stmtBlobs.text.isEmpty())
{
record->clearNull(f_mon_stmt_sql_text);
if (EVL_field(nullptr, record, f_mon_stmt_sql_text, &desc))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.isBlob());

{
fb_assert(desc.isBlob());
*reinterpret_cast<bid*>(desc.dsc_address) = stmtBlobs.text;
}
}
if (!stmtBlobs.plan.isEmpty())
{
record->clearNull(f_mon_stmt_expl_plan);
if (EVL_field(nullptr, record, f_mon_stmt_expl_plan, &desc))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fb_assert(desc.isBlob());

{
fb_assert(desc.isBlob());
*reinterpret_cast<bid*>(desc.dsc_address) = stmtBlobs.plan;
}
}
}
}
}

buffer->store(record);
}
}
}

Expand Down Expand Up @@ -1221,13 +1291,17 @@ void Monitoring::putRequest(SnapshotData::DumpRecord& record, const Request* req

const Statement* const statement = request->getStatement();

// sql text
if (statement->sqlText)
record.storeString(f_mon_stmt_sql_text, *statement->sqlText);
// Since ODS 13.1 statement text and plan is put into mon$compiled_statements
if (dbb->getEncodedOdsVersion() < ODS_13_1)
{
// sql text
if (statement->sqlText)
record.storeString(f_mon_stmt_sql_text, *statement->sqlText);

// explained plan
if (plan.hasData())
record.storeString(f_mon_stmt_expl_plan, plan);
// explained plan
if (plan.hasData())
record.storeString(f_mon_stmt_expl_plan, plan);
}

// statistics
const int stat_id = fb_utils::genUniqueId();
Expand Down Expand Up @@ -1506,7 +1580,7 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment, ULONG g

if (dbb->getEncodedOdsVersion() >= ODS_13_1)
{
// Statement information
// Statement information, must be put into dump before requests

for (const auto statement : attachment->att_statements)
{
Expand All @@ -1526,7 +1600,8 @@ void Monitoring::dumpAttachment(thread_db* tdbb, Attachment* attachment, ULONG g

if (!(statement->flags & (Statement::FLAG_INTERNAL | Statement::FLAG_SYS_TRIGGER)))
{
const string plan = Optimizer::getPlan(tdbb, statement, true);
const string plan = (dbb->getEncodedOdsVersion() >= ODS_13_1) ?
"" : Optimizer::getPlan(tdbb, statement, true);
putRequest(record, request, plan);
}
}
Expand Down
Loading