/* $PostgreSQL:$ */ Diagnostic Trace Facilities Various facilities are available for tracing internal database server activity. These are primarily intended for use by database developers to diagnose undesirable dynamic behaviour. Some of these facilities have been advocated for wider use, though such use is not yet common. You should start by referring to the production monitoring facilities in . Note that all of the features described here require special source compilation flags to work at all, so they may not be available to you if you are using installed binary programs. Developer Trace and Debug Parameters The following parameters are intended for work on the PostgreSQL source. There should be no reason to use them in a production database setup. As such, they have been excluded from the sample postgresql.conf file. debug_assertions (boolean) debug_assertions configuration parameter Turns on various assertion checks. This is a debugging aid. If you are experiencing strange problems or crashes you might want to turn this on, as it might expose programming mistakes. To use this parameter, the macro USE_ASSERT_CHECKING must be defined when PostgreSQL is built (accomplished by the configure option ). Note that debug_assertions defaults to on if PostgreSQL has been built with assertions enabled. post_auth_delay (integer) post_auth_delay configuration parameter If nonzero, a delay of this many seconds occurs when a new server process is started, after it conducts the authentication procedure. This is intended to give an opportunity to attach to the server process with a debugger. This parameter cannot be changed after session start. pre_auth_delay (integer) pre_auth_delay configuration parameter If nonzero, a delay of this many seconds occurs just after a new server process is forked, before it conducts the authentication procedure. This is intended to give an opportunity to attach to the server process with a debugger to trace down misbehavior in authentication. This parameter can only be set in the postgresql.conf file or on the server command line. trace_notify (boolean) trace_notify configuration parameter Generates a great amount of debugging output for the LISTEN and NOTIFY commands. or must be DEBUG1 or lower to send this output to the client or server log, respectively. trace_sort (boolean) trace_sort configuration parameter If on, emit information about resource usage during sort operations. This parameter is only available if the TRACE_SORT macro was defined when PostgreSQL was compiled. (However, TRACE_SORT is currently defined by default.) trace_locks (boolean) trace_lwlocks (boolean) trace_userlocks (boolean) trace_lock_oidmin (boolean) trace_lock_table (boolean) debug_deadlocks (boolean) log_btree_build_stats (boolean) Various other code tracing and debugging options. Only superusers can change these settings. wal_debug (boolean) wal_debug configuration parameter If on, emit WAL-related debugging output. This parameter is only available if the WAL_DEBUG macro was defined when PostgreSQL was compiled. Only superusers can change this setting. Dynamic Tracing PostgreSQL provides facilities to enable dynamic tracing utilities on the database server. This allows an external utility to be called at specific points in the code and thereby trace execution. A number of trace points, often called probes, are already inserted into the source code. By default PG_TRACE probes are disabled, and the user needs to explicitly tell the configure script to make the probes available in PostgreSQL. Currently, probes are only defined when using the DTrace utility, so enabling DTrace only makes sense on certain Operating Systems. Currently DTrace works with both Solaris Express and Solaris 10+, though the above probes do not yet work with Solaris 10+. It is expected that DTrace will be available in the future on FreeBSD and Mac OS X. Well-known Trace Points The following trace points are placed within the code to allow dynamic tracing of certain events related to locking and performance. These are: Trace Point Definition Overview transaction__start (int transactionId) The start of a new transaction. transaction__commit (int transactionId) The successful completion of a transaction. transaction__abort (int transactionId) The unsuccessful completion of a transaction. lwlock__acquire (int lockid, int mode) An shared resource has been locked. lwlock__release (int lockid, int mode) An shared resource has been released. lwlock__startwait (int lockid, int mode) An shared resource was not immediately available and a backend has begun to wait in a queue for the resource to become available. lwlock__endwait (int lockid, int mode) A backend has reached the head of the queue and the resource is now available. lwlock__condacquire (int lockid, int mode) A resource was requested only on condition that no wait was required. The resource has now been successfully locked. lwlock__condacquire__fail (int lockid, int mode) A resource was requested only on condition that no wait was required. The resource was busy, so has not been locked. lock__startwait (int locktag_field2, int lockmode) A request for a lock on user data has started to wait in a priority queue for access to that data. Meaning of the locktag varies according to the lock type requested. lock__endwait (int locktag_field2, int lockmode) A request for a lock on user data has now reached the head of the priority queue for access to that data. Meaning of the locktag varies according to the lock type requested. Compiling for Dynamic Trace By default, trace points are disabled, so you will need to explicitly tell the configure script to make the probes available in PostgreSQL. To include trace points in a 32 bit binary, specify --enable-dtrace to configure. For example: $ configure --enable-dtrace ... To include DTrace probes in a 64 bit binary, specify --enable-dtrace and DTRACEFLAGS="-64" to configure. For example: Using gcc compiler: $ configure CC='gcc -m64' --enable-dtrace DTRACEFLAGS='-64' ... Using Sun compiler: $ configure CC='/path_to_sun_compiler/cc -xtarget=native64' --enable-dtrace DTRACEFLAGS='-64' ... Using Trace Points Existing trace points can be utilised by the dynamic tracing utility. The example below shows a DTrace script for analyzing transaction counts on the system, as an alternative to snapshotting pg_stat_database before and after a performance test. #!/usr/sbin/dtrace -qs postgresql$1:::transaction-start { @start["Start"] = count(); self->ts = timestamp; } postgresql$1:::transaction-abort { @abort["Abort"] = count(); } postgresql$1:::transaction-commit /self->ts/ { @commit["Commit"] = count(); @commit["Abort"] = count(); @time["Total time (ns)"] = sum(timestamp - self->ts); self->ts=0; } Note how the double underline in trace point names needs to be replaced by a hyphen when using D script. When executed, the example D script gives the following output: # ./txn_count.d `pgrep -n postgres` ^C Start 71 Commit 70 Abort 1 Total time (ns) 2312105013 You should remember that trace programs need to be carefully written and debugged prior to their use, otherwise the trace information collected may be meaningless. In most cases where problems are found it is the instrumentation that is at fault, not the underlying system. When discussing information found using dynamic tracing, be sure to enclose the script used to allow that too to be checked and discussed. Defining Trace Points New trace points can be defined within the code wherever the developer desires, though this will require a re-compile. A trace point can be inserted in a single line by using one of the trace macros. These are chosen according to how many variables will be made available for inspection at that trace point. Tracing the occurrence of an event can be achieved with a single line, using just the trace point name, e.g. PG_TRACE (my__new__trace__point); More complex trace points can be provided with one or more variables for inspection by the dynamic tracing utility by using the PG_TRACE macro that corresponds to the number of parameters after the trace point name. PG_TRACE3 (my__complex__event, varX, varY, varZ); The definition of the transaction__start trace point is shown below: static void StartTransaction(void) { ... /* * generate a new transaction id */ s->transactionId = GetNewTransactionId(false); XactLockTableInsert(s->transactionId); PG_TRACE1(transaction__start, s->transactionId); ... } Note how the variable is made available to the dynamic tracing utility. The dynamic tracing utility may require you to further define these trace points. For example, DTrace requires you to add new probes to the file src/backend/utils/probes.d as shown here: provider postgresql { ... probe transaction__start(int); ... }; You should take care that the datatype of the probe arguments match the datatypes of the variables defined in the PG_TRACE macro. This is not checked at compile time of the source. You can check that your newly added trace point is available by recompiling, then run the new binary, and as root, execute a DTrace command such as: dtrace -l -n transaction-start Supporting new dynamic tracing utilities is possible by changing the definitions for the PG_TRACE macros in src/include/pg_trace.h