1. Overview
PostgreSQL is a great open source database developed and maintained by many great software engineers around the world. In each release, there are many features added to this open source database. For example, one feature is very helpful for developer is backtrace_functions
introduced in PostgreSQL 13 , which allows a developer to dump out the backtrace
when certain errors happened on the server. In this blog, I am going to explain it in a little bit more detail.
2. What is backtrace_functions
?
The backtrace_functions
option is an option introduced for developers as it is described here. You can specify a list of c function names separated by comma, if an error is raised and matches any c function in the given list, then the backtrace will be logged into the logfile. This is very useful for debugging some specific areas of the source code, especially when the error happens randomly. As the document also mentioned, this option is not available on all platforms, and quality of the backtraces depends on the compilation options. For this reason, all the examples used in this blog were tested on Ubuntu 18.04 with gcc version 7.5.0.
3. How to make it work?
This feature was first committed in Nov, 2019 as showing below.
1 | commit 71a8a4f6e36547bb060dbcc961ea9b57420f7190 |
To use this feature, you need to add the key word backtrace_functions
to postgresql.conf
file with the c function names. It can be either a single c function name or a list of c function names separated by comma. In this blog, we use circle_in
as an example. Here is what I added to my postgresql.conf
file.
1 | $ tail -n1 $PGDATA/postgresql.conf |
After restart the server, use psql
connect to the server and enter below SQL queries (The postgresql source code used in this example is based on PostgreSQL13 development branch in March 2020, you can create your own error if you want to test this feature).
1 | postgres=# create temp table src (f1 text); |
An error is raised, now, if you dump the logfile, $ cat logfile
you should see something like below,
1 | 2020-12-14 13:43:22.541 PST [25220] ERROR: invalid input syntax for type circle: "( 1 , 1 ) , 5" at character 34 |
As we can see the error is happening in circle_in
function, which is called by function InputFunctionCall
, so on and so forth. This is exactly like the backtrace when you are debugging the source code using gdb, but you may also find that some function names are showing up as a hex string, such as 0x3c531f
. The reason some function names are not showing up is because they are static functions. For these functions, we need to use the addr2line
to convert the addresses into file names and line numbers. For example,
1 | addr2line 0x3c531f -f -e `which postgres` |
, where -f
displays the function names as well as file and line number, -e
used to specify the name of the executable for which addresses should be translated.
It depends on the compilation parameters, if you compile the postgre with default CFLAG, you may get something like below,
1 | $ addr2line 0x3c531f -f -e `which postgres` |
Where the line number doesn’t show up. To get the line number and file name, let’s add the option -ggdb
to CFLAGS
and then recompile the source code.
1 | ./configure '--prefix=/home/david/pgapp' 'CFLAGS=-ggdb' |
Now, if you repeat the above test, then you should get a similar backtrace like below,
1 | 2020-12-14 13:56:28.780 PST [3459] ERROR: invalid input syntax for type circle: "( 1 , 1 ) , 5" at character 34 |
Let’s run the command addr2line
with the new hex address string again,
1 | $ addr2line 0x52c2b5 -f -e `which postgres` |
Now, we get the function name, file name and the line number.
4. Summary
This blog simply discussed one very useful option introduced to PostgreSQL 13 for developers. I use this option a lot during my daily development work, and it helps me quickly locate the errors. I also use this feature when someone reports an error which happens randomly. To debug such issue, I simply enable it with the c function names. When the error happens again, then I can get the exactly backtrace. The backtrace_functions
does make my work much easier when tracing a bug.
Reference: