mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 01:23:03 +01:00
Fixed CORE-2017: I/O statistics for stored procedures is not accounted in monitoring tables.
This patch adds lazy statistics increments to the whole request call stack.
This commit is contained in:
parent
4a3c3dde3e
commit
ea6fbf9e6b
@ -838,6 +838,24 @@ ClumpletReader* DatabaseSnapshot::dumpData(thread_db* tdbb, bool broadcast)
|
||||
putTransaction(transaction, *writer, dbb->generateId());
|
||||
}
|
||||
|
||||
// Call stack information
|
||||
|
||||
for (transaction = attachment->att_transactions;
|
||||
transaction; transaction = transaction->tra_next)
|
||||
{
|
||||
for (request = transaction->tra_requests; request;
|
||||
request = request->req_caller)
|
||||
{
|
||||
request->adjustCallerStats();
|
||||
|
||||
if (!(request->req_flags & (req_internal | req_sys_trigger)) &&
|
||||
request->req_caller)
|
||||
{
|
||||
putCall(request, *writer, dbb->generateId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Request information
|
||||
|
||||
for (request = attachment->att_requests;
|
||||
@ -848,22 +866,6 @@ ClumpletReader* DatabaseSnapshot::dumpData(thread_db* tdbb, bool broadcast)
|
||||
putRequest(request, *writer, dbb->generateId());
|
||||
}
|
||||
}
|
||||
|
||||
// Call stack information
|
||||
|
||||
for (transaction = attachment->att_transactions;
|
||||
transaction; transaction = transaction->tra_next)
|
||||
{
|
||||
for (request = transaction->tra_requests;
|
||||
request; request = request->req_tra_next)
|
||||
{
|
||||
if (!(request->req_flags & (req_internal | req_sys_trigger)) &&
|
||||
request->req_caller)
|
||||
{
|
||||
putCall(request, *writer, dbb->generateId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1159,8 +1161,7 @@ void DatabaseSnapshot::putCall(const jrd_req* request,
|
||||
writer.insertInt(f_mon_call_caller_id, 0);
|
||||
}
|
||||
else {
|
||||
writer.insertInt(f_mon_call_caller_id,
|
||||
request->req_caller->req_id);
|
||||
writer.insertInt(f_mon_call_caller_id, request->req_caller->req_id);
|
||||
}
|
||||
// object name/type
|
||||
if (request->req_procedure) {
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../jrd/RuntimeStatistics.h"
|
||||
|
||||
using namespace Firebird;
|
||||
|
||||
namespace Jrd {
|
||||
|
||||
RuntimeStatistics RuntimeStatistics::dummy;
|
||||
@ -34,4 +35,40 @@ void RuntimeStatistics::reset()
|
||||
memset(values, 0, sizeof values);
|
||||
}
|
||||
|
||||
bool RuntimeStatistics::operator==(const RuntimeStatistics& other) const
|
||||
{
|
||||
return !memcmp(values, other.values, sizeof(values));
|
||||
}
|
||||
|
||||
bool RuntimeStatistics::operator!=(const RuntimeStatistics& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
RuntimeStatistics& RuntimeStatistics::operator+=(const RuntimeStatistics& other)
|
||||
{
|
||||
for (size_t i = 0; i < TOTAL_ITEMS; ++i)
|
||||
values[i] += other.values[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RuntimeStatistics& RuntimeStatistics::operator-=(const RuntimeStatistics& other)
|
||||
{
|
||||
for (size_t i = 0; i < TOTAL_ITEMS; ++i)
|
||||
values[i] -= other.values[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
RuntimeStatistics RuntimeStatistics::operator+(const RuntimeStatistics& other) const
|
||||
{
|
||||
return RuntimeStatistics(*this) += other;
|
||||
}
|
||||
|
||||
RuntimeStatistics RuntimeStatistics::operator-(const RuntimeStatistics& other) const
|
||||
{
|
||||
return RuntimeStatistics(*this) -= other;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -74,17 +74,23 @@ public:
|
||||
++values[index];
|
||||
}
|
||||
|
||||
bool operator==(const RuntimeStatistics& other) const;
|
||||
bool operator!=(const RuntimeStatistics& other) const;
|
||||
|
||||
RuntimeStatistics& operator+=(const RuntimeStatistics& other);
|
||||
RuntimeStatistics& operator-=(const RuntimeStatistics& other);
|
||||
|
||||
RuntimeStatistics operator+(const RuntimeStatistics& other) const;
|
||||
RuntimeStatistics operator-(const RuntimeStatistics& other) const;
|
||||
|
||||
static RuntimeStatistics* getDummy()
|
||||
{
|
||||
return &dummy;
|
||||
}
|
||||
|
||||
private:
|
||||
// copying is prohibited
|
||||
RuntimeStatistics(const RuntimeStatistics&);
|
||||
RuntimeStatistics& operator= (const RuntimeStatistics&);
|
||||
|
||||
SINT64 values[TOTAL_ITEMS];
|
||||
|
||||
// This dummy RuntimeStatistics is used instead of missing elements in tdbb,
|
||||
// helping us avoid conditional checks in time-critical places of code.
|
||||
// Values of it contain actually garbage - don't be surprised when debugging.
|
||||
|
@ -681,6 +681,7 @@ jrd_req* EXE_find_request(thread_db* tdbb, jrd_req* request, bool validate)
|
||||
}
|
||||
clone->req_attachment = tdbb->getAttachment();
|
||||
clone->req_stats.reset();
|
||||
clone->req_base_stats.reset();
|
||||
clone->req_flags |= req_in_use;
|
||||
dbb->dbb_mutexes[DBB_MUTX_clone].leave();
|
||||
return clone;
|
||||
@ -2729,11 +2730,15 @@ static jrd_nod* looper(thread_db* tdbb, jrd_req* request, jrd_nod* in_node)
|
||||
BUGCHECK(168); /* msg 168 looper: action not yet implemented */
|
||||
}
|
||||
|
||||
request->adjustCallerStats();
|
||||
|
||||
} // try
|
||||
catch (const Firebird::Exception& ex) {
|
||||
|
||||
Firebird::stuff_exception(tdbb->tdbb_status_vector, ex);
|
||||
|
||||
request->adjustCallerStats();
|
||||
|
||||
// Skip this handling for errors coming from the nested looper calls,
|
||||
// as they're already handled properly. The only need is to undo
|
||||
// our own savepoints.
|
||||
|
@ -232,6 +232,7 @@ public:
|
||||
ULONG req_records_updated; /* count of records updated by request */
|
||||
ULONG req_records_deleted; /* count of records deleted by request */
|
||||
RuntimeStatistics req_stats;
|
||||
RuntimeStatistics req_base_stats;
|
||||
AffectedRows req_records_affected; /* records affected by the last statement */
|
||||
|
||||
USHORT req_view_flags; /* special flags for virtual ops on views */
|
||||
@ -282,6 +283,15 @@ public:
|
||||
StatusXcp req_last_xcp; /* last known exception */
|
||||
|
||||
record_param req_rpb[1]; /* record parameter blocks */
|
||||
|
||||
void adjustCallerStats()
|
||||
{
|
||||
if (req_caller)
|
||||
{
|
||||
req_caller->req_stats += req_stats - req_base_stats;
|
||||
}
|
||||
req_base_stats = req_stats;
|
||||
}
|
||||
};
|
||||
|
||||
// Size of request without rpb items at the tail. Used to calculate impure area size
|
||||
|
Loading…
Reference in New Issue
Block a user