8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 22:43:04 +01:00

Improvement #6730 : Trace: provide ability to see STATEMENT RESTART events (or their count) [CORE6500].

Implemented new trace event: EXECUTE_STATEMENT_RESTART.
This commit is contained in:
Vlad Khorsun 2022-06-23 22:51:58 +03:00
parent 98a375720f
commit 95b8623adb
8 changed files with 126 additions and 14 deletions

View File

@ -945,6 +945,8 @@ void DsqlDmlRequest::executeReceiveWithRestarts(thread_db* tdbb, jrd_tra** traHa
"\tQuery:\n%s\n", numTries, req_request->getStatement()->sqlText->c_str() );
}
TraceManager::event_dsql_restart(req_dbb->dbb_attachment, req_transaction, this, numTries);
// When restart we must execute query
exec = true;
}

View File

@ -1531,6 +1531,11 @@ interface TracePlugin : ReferenceCounted
[notImplemented(true)]
boolean trace_func_execute (TraceDatabaseConnection connection, TraceTransaction transaction, TraceFunction function,
boolean started, uint func_result);
version: // 4.0.1 -> 4.0.2
boolean trace_dsql_restart(TraceDatabaseConnection connection, TraceTransaction transaction, TraceSQLStatement statement,
uint number);
}
// Trace plugin second level factory (this is what is known to PluginManager as "trace plugin")

View File

@ -5853,6 +5853,7 @@ namespace Firebird
FB_BOOLEAN (CLOOP_CARG *trace_event_error)(ITracePlugin* self, ITraceConnection* connection, ITraceStatusVector* status, const char* function) throw();
FB_BOOLEAN (CLOOP_CARG *trace_event_sweep)(ITracePlugin* self, ITraceDatabaseConnection* connection, ITraceSweepInfo* sweep, unsigned sweep_state) throw();
FB_BOOLEAN (CLOOP_CARG *trace_func_execute)(ITracePlugin* self, ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceFunction* function, FB_BOOLEAN started, unsigned func_result) throw();
FB_BOOLEAN (CLOOP_CARG *trace_dsql_restart)(ITracePlugin* self, ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceSQLStatement* statement, unsigned number) throw();
};
protected:
@ -5866,7 +5867,7 @@ namespace Firebird
}
public:
static const unsigned VERSION = 3;
static const unsigned VERSION = 4;
static const unsigned RESULT_SUCCESS = 0;
static const unsigned RESULT_FAILED = 1;
@ -6001,6 +6002,16 @@ namespace Firebird
FB_BOOLEAN ret = static_cast<VTable*>(this->cloopVTable)->trace_func_execute(this, connection, transaction, function, started, func_result);
return ret;
}
FB_BOOLEAN trace_dsql_restart(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceSQLStatement* statement, unsigned number)
{
if (cloopVTable->version < 4)
{
return 0;
}
FB_BOOLEAN ret = static_cast<VTable*>(this->cloopVTable)->trace_dsql_restart(this, connection, transaction, statement, number);
return ret;
}
};
class ITraceFactory : public IPluginBase
@ -18125,6 +18136,7 @@ namespace Firebird
this->trace_event_error = &Name::clooptrace_event_errorDispatcher;
this->trace_event_sweep = &Name::clooptrace_event_sweepDispatcher;
this->trace_func_execute = &Name::clooptrace_func_executeDispatcher;
this->trace_dsql_restart = &Name::clooptrace_dsql_restartDispatcher;
}
} vTable;
@ -18404,6 +18416,19 @@ namespace Firebird
}
}
static FB_BOOLEAN CLOOP_CARG clooptrace_dsql_restartDispatcher(ITracePlugin* self, ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceSQLStatement* statement, unsigned number) throw()
{
try
{
return static_cast<Name*>(self)->Name::trace_dsql_restart(connection, transaction, statement, number);
}
catch (...)
{
StatusType::catchException(0);
return static_cast<FB_BOOLEAN>(0);
}
}
static void CLOOP_CARG cloopaddRefDispatcher(IReferenceCounted* self) throw()
{
try
@ -18464,6 +18489,7 @@ namespace Firebird
virtual FB_BOOLEAN trace_event_error(ITraceConnection* connection, ITraceStatusVector* status, const char* function) = 0;
virtual FB_BOOLEAN trace_event_sweep(ITraceDatabaseConnection* connection, ITraceSweepInfo* sweep, unsigned sweep_state) = 0;
virtual FB_BOOLEAN trace_func_execute(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceFunction* function, FB_BOOLEAN started, unsigned func_result) = 0;
virtual FB_BOOLEAN trace_dsql_restart(ITraceDatabaseConnection* connection, ITraceTransaction* transaction, ITraceSQLStatement* statement, unsigned number) = 0;
};
template <typename Name, typename StatusType, typename Base>

View File

@ -665,6 +665,7 @@ type
ITracePlugin_trace_event_errorPtr = function(this: ITracePlugin; connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; cdecl;
ITracePlugin_trace_event_sweepPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; cdecl;
ITracePlugin_trace_func_executePtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; cdecl;
ITracePlugin_trace_dsql_restartPtr = function(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; number: Cardinal): Boolean; cdecl;
ITraceFactory_trace_needsPtr = function(this: ITraceFactory): QWord; cdecl;
ITraceFactory_trace_createPtr = function(this: ITraceFactory; status: IStatus; init_info: ITraceInitInfo): ITracePlugin; cdecl;
IUdrFunctionFactory_setupPtr = procedure(this: IUdrFunctionFactory; status: IStatus; context: IExternalContext; metadata: IRoutineMetadata; inBuilder: IMetadataBuilder; outBuilder: IMetadataBuilder); cdecl;
@ -3349,10 +3350,11 @@ type
trace_event_error: ITracePlugin_trace_event_errorPtr;
trace_event_sweep: ITracePlugin_trace_event_sweepPtr;
trace_func_execute: ITracePlugin_trace_func_executePtr;
trace_dsql_restart: ITracePlugin_trace_dsql_restartPtr;
end;
ITracePlugin = class(IReferenceCounted)
const VERSION = 3;
const VERSION = 4;
const RESULT_SUCCESS = Cardinal(0);
const RESULT_FAILED = Cardinal(1);
const RESULT_UNAUTHORIZED = Cardinal(2);
@ -3382,6 +3384,7 @@ type
function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean;
function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean;
function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean;
function trace_dsql_restart(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; number: Cardinal): Boolean;
end;
ITracePluginImpl = class(ITracePlugin)
@ -3410,6 +3413,7 @@ type
function trace_event_error(connection: ITraceConnection; status: ITraceStatusVector; function_: PAnsiChar): Boolean; virtual; abstract;
function trace_event_sweep(connection: ITraceDatabaseConnection; sweep: ITraceSweepInfo; sweep_state: Cardinal): Boolean; virtual; abstract;
function trace_func_execute(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; function_: ITraceFunction; started: Boolean; func_result: Cardinal): Boolean; virtual; abstract;
function trace_dsql_restart(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; number: Cardinal): Boolean; virtual; abstract;
end;
TraceFactoryVTable = class(PluginBaseVTable)
@ -8587,6 +8591,16 @@ begin
Result := TracePluginVTable(vTable).trace_func_execute(Self, connection, transaction, function_, started, func_result);
end;
function ITracePlugin.trace_dsql_restart(connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; number: Cardinal): Boolean;
begin
if (vTable.version < 4) then begin
Result := false;
end
else begin
Result := TracePluginVTable(vTable).trace_dsql_restart(Self, connection, transaction, statement, number);
end;
end;
function ITraceFactory.trace_needs(): QWord;
begin
Result := TraceFactoryVTable(vTable).trace_needs(Self);
@ -14725,6 +14739,15 @@ begin
end
end;
function ITracePluginImpl_trace_dsql_restartDispatcher(this: ITracePlugin; connection: ITraceDatabaseConnection; transaction: ITraceTransaction; statement: ITraceSQLStatement; number: Cardinal): Boolean; cdecl;
begin
try
Result := ITracePluginImpl(this).trace_dsql_restart(connection, transaction, statement, number);
except
on e: Exception do FbException.catchException(nil, e);
end
end;
var
ITracePluginImpl_vTable: TracePluginVTable;
@ -16237,7 +16260,7 @@ initialization
ITraceInitInfoImpl_vTable.getLogWriter := @ITraceInitInfoImpl_getLogWriterDispatcher;
ITracePluginImpl_vTable := TracePluginVTable.create;
ITracePluginImpl_vTable.version := 3;
ITracePluginImpl_vTable.version := 4;
ITracePluginImpl_vTable.addRef := @ITracePluginImpl_addRefDispatcher;
ITracePluginImpl_vTable.release := @ITracePluginImpl_releaseDispatcher;
ITracePluginImpl_vTable.trace_get_error := @ITracePluginImpl_trace_get_errorDispatcher;
@ -16261,6 +16284,7 @@ initialization
ITracePluginImpl_vTable.trace_event_error := @ITracePluginImpl_trace_event_errorDispatcher;
ITracePluginImpl_vTable.trace_event_sweep := @ITracePluginImpl_trace_event_sweepDispatcher;
ITracePluginImpl_vTable.trace_func_execute := @ITracePluginImpl_trace_func_executeDispatcher;
ITracePluginImpl_vTable.trace_dsql_restart := @ITracePluginImpl_trace_dsql_restartDispatcher;
ITraceFactoryImpl_vTable := TraceFactoryVTable.create;
ITraceFactoryImpl_vTable.version := 4;

View File

@ -407,6 +407,16 @@ void TraceManager::event_dsql_execute(Attachment* att, jrd_tra* transaction,
started, req_result);
}
void TraceManager::event_dsql_restart(Attachment* att, jrd_tra* transaction,
const dsql_req* statement, int number)
{
TraceConnectionImpl conn(att);
TraceTransactionImpl tran(transaction);
TraceSQLStatementImpl stmt(statement, NULL);
att->att_trace_manager->event_dsql_restart(&conn, transaction ? &tran : NULL, &stmt,
(unsigned) number);
}
#define EXECUTE_HOOKS(METHOD, PARAMS) \
FB_SIZE_T i = 0; \
@ -502,6 +512,12 @@ void TraceManager::event_dsql_execute(ITraceDatabaseConnection* connection, ITra
(connection, transaction, statement, started, req_result));
}
void TraceManager::event_dsql_restart(ITraceDatabaseConnection* connection, ITraceTransaction* transaction,
ITraceSQLStatement* statement, unsigned number)
{
EXECUTE_HOOKS(trace_dsql_restart,
(connection, transaction, statement, number));
}
void TraceManager::event_blr_compile(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceBLRStatement* statement,

View File

@ -44,6 +44,7 @@ namespace Jrd {
class Database;
class Attachment;
class jrd_tra;
class dsql_req;
class Service;
class TraceManager
@ -157,6 +158,9 @@ public:
static void event_dsql_execute(Attachment* att, jrd_tra* transaction, Firebird::ITraceSQLStatement* statement,
bool started, ntrace_result_t req_result);
static void event_dsql_restart(Attachment* att, jrd_tra* transaction, const dsql_req* statement,
int number);
static void shutdown();
private:
@ -242,6 +246,9 @@ private:
Firebird::ITraceSQLStatement* statement,
bool started, ntrace_result_t req_result);
void event_dsql_restart(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction, Firebird::ITraceSQLStatement* statement,
unsigned number);
static Firebird::GlobalPtr<StorageInstance, Firebird::InstanceControl::PRIORITY_DELETE_FIRST> storageInstance;
ULONG changeNumber;

View File

@ -1685,8 +1685,10 @@ void TracePluginImpl::log_event_dsql_free(ITraceDatabaseConnection* connection,
void TracePluginImpl::log_event_dsql_execute(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceSQLStatement* statement,
bool started, ntrace_result_t req_result)
bool started, unsigned number, ntrace_result_t req_result)
{
const bool restart = started && (number > 0);
if (started && !config.log_statement_start)
return;
@ -1698,6 +1700,13 @@ void TracePluginImpl::log_event_dsql_execute(ITraceDatabaseConnection* connectio
if (config.time_threshold && info && info->pin_time < config.time_threshold)
return;
if (restart)
{
string temp;
temp.printf("Restarted %d time(s)" NEWLINE, number);
record.append(temp);
}
ITraceParams *params = statement->getInputs();
if (params && params->getCount())
{
@ -1716,26 +1725,31 @@ void TracePluginImpl::log_event_dsql_execute(ITraceDatabaseConnection* connectio
appendTableCounts(info);
}
const char* event_type;
string event_type;
if (restart)
event_type = "EXECUTE_STATEMENT_RESTART";
else if (started)
event_type = "EXECUTE_STATEMENT_START";
else
event_type = "EXECUTE_STATEMENT_FINISH";
switch (req_result)
{
case ITracePlugin::RESULT_SUCCESS:
event_type = started ? "EXECUTE_STATEMENT_START" :
"EXECUTE_STATEMENT_FINISH";
break;
case ITracePlugin::RESULT_FAILED:
event_type = started ? "FAILED EXECUTE_STATEMENT_START" :
"FAILED EXECUTE_STATEMENT_FINISH";
event_type.insert(0, "FAILED ");
break;
case ITracePlugin::RESULT_UNAUTHORIZED:
event_type = started ? "UNAUTHORIZED EXECUTE_STATEMENT_START" :
"UNAUTHORIZED EXECUTE_STATEMENT_FINISH";
event_type.insert(0, "UNAUTHORIZED ");
break;
default:
event_type = "Unknown event at executing statement";
break;
}
logRecordStmt(event_type, connection, transaction, statement, true);
logRecordStmt(event_type.c_str(), connection, transaction, statement, true);
}
@ -2520,7 +2534,23 @@ FB_BOOLEAN TracePluginImpl::trace_dsql_execute(ITraceDatabaseConnection* connect
{
try
{
log_event_dsql_execute(connection, transaction, statement, started, req_result);
log_event_dsql_execute(connection, transaction, statement, started, 0, req_result);
return true;
}
catch (const Firebird::Exception& ex)
{
marshal_exception(ex);
return false;
}
}
FB_BOOLEAN TracePluginImpl::trace_dsql_restart(ITraceDatabaseConnection* connection,
ITraceTransaction* transaction, ITraceSQLStatement* statement, unsigned number)
{
try
{
log_event_dsql_execute(connection, transaction, statement, true, number,
ITracePlugin::RESULT_SUCCESS);
return true;
}
catch (const Firebird::Exception& ex)

View File

@ -242,7 +242,7 @@ private:
Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceSQLStatement* statement, unsigned short option);
void log_event_dsql_execute(
Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
Firebird::ITraceSQLStatement* statement, bool started, unsigned req_result);
Firebird::ITraceSQLStatement* statement, bool started, unsigned number, unsigned req_result);
void log_event_blr_compile(
Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
@ -303,6 +303,8 @@ public:
unsigned option);
FB_BOOLEAN trace_dsql_execute(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
Firebird::ITraceSQLStatement* statement, FB_BOOLEAN started, unsigned req_result);
FB_BOOLEAN trace_dsql_restart(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,
Firebird::ITraceSQLStatement* statement, unsigned number);
// BLR requests
FB_BOOLEAN trace_blr_compile(Firebird::ITraceDatabaseConnection* connection, Firebird::ITraceTransaction* transaction,