Skip to content

Commit bb139df

Browse files
committed
Remote attachment profiling.
1 parent a0ade0c commit bb139df

File tree

9 files changed

+721
-66
lines changed

9 files changed

+721
-66
lines changed

doc/sql.extensions/README.profiler.md

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,13 @@ This documentation treats the engine and plugin parts as a single thing, in the
88

99
The `RDB$PROFILER` package allows to profile execution of PSQL code collecting statistics of how many times each line was executed along with its minimum, maximum and accumulated execution times (with nanoseconds precision), as well open and fetch statistics of implicit and explicit SQL cursors.
1010

11-
To collect profile data, an user must first start a profile session with `RDB$PROFILER.START_SESSION`. This function returns an profile session ID which is later stored in the profiler snapshot tables to be queried and analyzed by the user.
11+
To collect profile data, an user must first start a profile session with `RDB$PROFILER.START_SESSION`. This function returns an profile session ID which is later stored in the profiler snapshot tables to be queried and analyzed by the user. A profiler session may be local (same attachment) or remote (another attachment).
1212

13-
After a session is started, PSQL and SQL statements statistics starts to be collected in memory. Note that a profile session collects data only of statements executed in the same attachment where the session was started.
13+
Remote profiling just forwards commands to the remote attachment. So it's possible that a client simultaneous profile multiple attachments. It's also possible that a locally or remotely started profile session have commands issued by another attachment.
14+
15+
Remote issued commands needs that the target attachment be in an idle state, i.e., not executing others requests. When they are not idle the call blocks waiting for that state.
16+
17+
After a session is started, PSQL and SQL statements statistics starts to be collected in memory. Note that a profile session collects data only of statements executed in the same attachment associated with the session.
1418

1519
Data is aggregated and stored per requests (i.e. a statement execution). When querying snapshot tables, user may do extra aggregation per statements or use the auxiliary views that do that automatically.
1620

@@ -120,67 +124,84 @@ select pstat.*
120124

121125
## Function `START_SESSION`
122126

123-
`RDB$PROFILER.START_SESSION` starts a new profiler session, turns it the current session and return its identifier.
127+
`RDB$PROFILER.START_SESSION` starts a new profiler session, turns it the current session (of the given `ATTACHMENT_ID`) and return its identifier.
124128

125129
If `PLUGIN_NAME` is `NULL` (the default) it uses the database configuration `DefaultProfilerPlugin`.
126130

127131
`PLUGIN_OPTIONS` is plugin specific options and currently should be `NULL` for `Default_Profiler` plugin.
128132

129133
Input parameters:
130134
- `DESCRIPTION` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
135+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
131136
- `PLUGIN_NAME` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
132137
- `PLUGIN_OPTIONS` type `VARCHAR(255) CHARACTER SET UTF8` default `NULL`
133138

134139
Return type: `BIGINT NOT NULL`.
135140

136141
## Procedure `PAUSE_SESSION`
137142

138-
`RDB$PROFILER.PAUSE_SESSION` pauses the current profiler session so the next executed statements statistics are not collected.
143+
`RDB$PROFILER.PAUSE_SESSION` pauses the current profiler session (of the given `ATTACHMENT_ID`) so the next executed statements statistics are not collected.
139144

140145
If `FLUSH` is `TRUE` the snapshot tables are updated with data up to the current moment. Otherwise data remains only in memory for later update.
141146

142-
Calling `RDB$PROFILER.PAUSE_SESSION(TRUE)` has the same semantics of calling `RDB$PROFILER.PAUSE_SESSION(FALSE)` followed by `RDB$PROFILER.FLUSH`.
147+
Calling `RDB$PROFILER.PAUSE_SESSION(TRUE)` has the same semantics of calling `RDB$PROFILER.PAUSE_SESSION(FALSE)` followed by `RDB$PROFILER.FLUSH` (using the same `ATTACHMENT_ID`).
143148

144149
Input parameters:
145150
- `FLUSH` type `BOOLEAN NOT NULL` default `FALSE`
151+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
146152

147153
## Procedure `RESUME_SESSION`
148154

149-
`RDB$PROFILER.RESUME_SESSION` resumes the current profiler session if it was paused so the next executed statements statistics are collected again.
155+
`RDB$PROFILER.RESUME_SESSION` resumes the current profiler session (of the given `ATTACHMENT_ID`) if it was paused so the next executed statements statistics are collected again.
156+
157+
Input parameters:
158+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
150159

151160
## Procedure `FINISH_SESSION`
152161

153-
`RDB$PROFILER.FINISH_SESSION` finishes the current profiler session.
162+
`RDB$PROFILER.FINISH_SESSION` finishes the current profiler session (of the given `ATTACHMENT_ID`).
154163

155164
If `FLUSH` is `TRUE` the snapshot tables are updated with data of the finished session (and old finished sessions not yet present in the snapshot). Otherwise data remains only in memory for later update.
156165

157-
Calling `RDB$PROFILER.FINISH_SESSION(TRUE)` has the same semantics of calling `RDB$PROFILER.FINISH_SESSION(FALSE)` followed by `RDB$PROFILER.FLUSH`.
166+
Calling `RDB$PROFILER.FINISH_SESSION(TRUE)` has the same semantics of calling `RDB$PROFILER.FINISH_SESSION(FALSE)` followed by `RDB$PROFILER.FLUSH` (using the same `ATTACHMENT_ID`).
158167

159168
Input parameters:
160169
- `FLUSH` type `BOOLEAN NOT NULL` default `TRUE`
170+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
161171

162172
## Procedure `CANCEL_SESSION`
163173

164-
`RDB$PROFILER.CANCEL_SESSION` cancels the current profiler session.
174+
`RDB$PROFILER.CANCEL_SESSION` cancels the current profiler session (of the given `ATTACHMENT_ID`).
165175

166176
All session data present in the profiler plugin is discarded and will not be flushed.
167177

168178
Data already flushed is not deleted automatically.
169179

180+
Input parameters:
181+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
182+
170183
## Procedure `DISCARD`
171184

172-
`RDB$PROFILER.DISCARD` removes all sessions from memory, without flushing them.
185+
`RDB$PROFILER.DISCARD` removes all sessions (of the given `ATTACHMENT_ID`) from memory, without flushing them.
173186

174187
If there is a active session, it is cancelled.
175188

189+
Input parameters:
190+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
191+
176192
## Procedure `FLUSH`
177193

178-
`RDB$PROFILER.FLUSH` updates the snapshot tables with data from the profile sessions in memory.
194+
`RDB$PROFILER.FLUSH` updates the snapshot tables with data from the profile sessions (of the given `ATTACHMENT_ID`) in memory.
179195

180196
After update data is stored in tables `PLG$PROF_SESSIONS`, `PLG$PROF_STATEMENTS`, `PLG$PROF_RECORD_SOURCES`, `PLG$PROF_REQUESTS`, `PLG$PROF_PSQL_STATS` and `PLG$PROF_RECORD_SOURCE_STATS` and may be read and analyzed by the user.
181197

182198
It also removes finished sessions from memory.
183199

200+
If a remote `ATTACHMENT_ID` is used the data is updated in an autonomous transaction.
201+
202+
Input parameters:
203+
- `ATTACHMENT_ID` type `BIGINT NOT NULL` default `CURRENT_CONNECTION`
204+
184205
# Snapshot tables
185206

186207
Snapshot tables (as well views and sequence) are automatically created in the first usage of the profiler. They are owned by the current user with read/write permissions for `PUBLIC`.

src/common/file_params.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ static const char* const TRACE_FILE = "fb" COMMON_FILE_PREFIX "_trace";
4646
static const char* const USER_MAP_FILE = "fb" COMMON_FILE_PREFIX "_user_mapping";
4747
static const char* const FB_TRACE_LOG_MUTEX = "fb_trace_log_mutex";
4848

49+
static const char* const PROFILER_FILE = "fb_profiler_%s_%" UQUADFORMAT;
50+
4951
#ifdef UNIX
5052
static const char* const INIT_FILE = "fb_init";
5153
static const char* const SEM_FILE = "fb_sem";

src/common/isc_s_proto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,8 @@ class SharedMemoryBase
313313
SRAM_TPC_HEADER = 0xF9,
314314
SRAM_TPC_BLOCK = 0xF8,
315315
SRAM_TPC_SNAPSHOTS = 0xF7,
316-
SRAM_CHANGELOG_STATE = 0xF6
316+
SRAM_CHANGELOG_STATE = 0xF6,
317+
SRAM_PROFILER = 0XF5
317318
};
318319

319320
protected:

src/jrd/Attachment.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,12 @@ void Jrd::Attachment::initLocks(thread_db* tdbb)
727727
lock = FB_NEW_RPT(*att_pool, 0)
728728
Lock(tdbb, 0, LCK_repl_tables, this, blockingAstReplSet);
729729
att_repl_lock = lock;
730+
731+
lock = FB_NEW_RPT(*att_pool, 0)
732+
Lock(tdbb, sizeof(AttNumber), LCK_profiler_listener, this, ProfilerManager::blockingAst);
733+
att_profiler_listener_lock = lock;
734+
lock->setKey(att_attachment_id);
735+
LCK_lock(tdbb, lock, LCK_EX, LCK_WAIT);
730736
}
731737
}
732738

@@ -844,6 +850,9 @@ void Jrd::Attachment::releaseLocks(thread_db* tdbb)
844850
if (att_repl_lock)
845851
LCK_release(tdbb, att_repl_lock);
846852

853+
if (att_profiler_listener_lock)
854+
LCK_release(tdbb, att_profiler_listener_lock);
855+
847856
// And release the system requests
848857

849858
for (JrdStatement** itr = att_internal.begin(); itr != att_internal.end(); ++itr)

src/jrd/Attachment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,7 @@ class Attachment : public pool_alloc<type_att>
552552
AttNumber att_attachment_id; // Attachment ID
553553
Lock* att_cancel_lock; // Lock to cancel the active request
554554
Lock* att_monitor_lock; // Lock for monitoring purposes
555+
Lock* att_profiler_listener_lock; // Lock for remote profiler listener
555556
const ULONG att_lock_owner_id; // ID for the lock manager
556557
SLONG att_lock_owner_handle; // Handle for the lock manager
557558
ULONG att_backup_state_counter; // Counter of backup state locks for attachment

0 commit comments

Comments
 (0)