pg-lock-tracer 0.5.4__tar.gz → 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/PKG-INFO +76 -6
- pg_lock_tracer-0.5.4/src/pg_lock_tracer.egg-info/PKG-INFO → pg_lock_tracer-0.6.0/README.md +71 -23
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/setup.cfg +1 -0
- pg_lock_tracer-0.6.0/src/pg_lock_tracer/__init__.py +1 -0
- pg_lock_tracer-0.6.0/src/pg_lock_tracer/bpf/pg_row_lock_tracer.c +121 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/helper.py +56 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/pg_lock_tracer.py +149 -69
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/pg_lw_lock_tracer.py +12 -19
- pg_lock_tracer-0.6.0/src/pg_lock_tracer/pg_row_lock_tracer.py +372 -0
- pg_lock_tracer-0.5.4/README.md → pg_lock_tracer-0.6.0/src/pg_lock_tracer.egg-info/PKG-INFO +93 -5
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/SOURCES.txt +2 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/entry_points.txt +1 -0
- pg_lock_tracer-0.5.4/src/pg_lock_tracer/__init__.py +0 -1
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/LICENSE +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/pyproject.toml +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/setup.py +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/animate_lock_graph.py +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/__init__.py +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/pg_lock_tracer.c +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/pg_lw_lock_tracer.c +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/oid_resolver.py +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/dependency_links.txt +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/requires.txt +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/top_level.txt +0 -0
- {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/tests/test_helper.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: pg_lock_tracer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.6.0
|
|
4
4
|
Summary: A BPF based lock tracer for the PostgreSQL database
|
|
5
5
|
Home-page: https://github.com/jnidzwetzki/pg-lock-tracer
|
|
6
6
|
Author: Jan Nidzwetzki
|
|
@@ -15,6 +15,10 @@ Classifier: License :: OSI Approved :: Apache Software License
|
|
|
15
15
|
Requires-Python: >=3.6
|
|
16
16
|
Description-Content-Type: text/markdown
|
|
17
17
|
License-File: LICENSE
|
|
18
|
+
Requires-Dist: graphviz
|
|
19
|
+
Requires-Dist: igraph
|
|
20
|
+
Requires-Dist: prettytable
|
|
21
|
+
Requires-Dist: psycopg2
|
|
18
22
|
|
|
19
23
|
# Lock tracing tools for PostgreSQL
|
|
20
24
|
[](http://makeapullrequest.com)
|
|
@@ -26,11 +30,12 @@ License-File: LICENSE
|
|
|
26
30
|
|
|
27
31
|
This project provides tools that allow you to gain deep insights into PostgreSQL's locking activities and troubleshoot locking-related issues (e.g., performance problems or deadlocks).
|
|
28
32
|
|
|
29
|
-
* `pg_lock_tracer` - is a lock tracer
|
|
30
|
-
* `pg_lw_lock_tracer` -
|
|
33
|
+
* `pg_lock_tracer` - is a PostgreSQL table level lock tracer.
|
|
34
|
+
* `pg_lw_lock_tracer` - is a tracer for PostgreSQL lightweight locks (LWLocks).
|
|
35
|
+
* `pg_row_lock_tracer` - is a tracer for PostgreSQL row locks.
|
|
31
36
|
* `animate_lock_graph` - creates animated locks graphs based on the `pg_lock_tracer` output.
|
|
32
37
|
|
|
33
|
-
__Note:__
|
|
38
|
+
__Note:__ These tools employ the [eBPF](https://ebpf.io/) (_Extended Berkeley Packet Filter_) technology. At the moment, PostgreSQL 12, 13, 14, 15, and 16 are supported (see additional information below).
|
|
34
39
|
|
|
35
40
|
# pg_lock_tracer
|
|
36
41
|
`pg_lock_tracer` observes the locking activity of a running PostgreSQL process (using _eBPF_ and _UProbes_). In contrast to the information that is present in the table `pg_locks` (which provides information about which locks are _currently_ requested), `pg_lock_tracer` gives you a continuous view of the locking activity and collects statistics and timings.
|
|
@@ -682,7 +687,7 @@ pg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_2_DEBUG/bin/postgres -
|
|
|
682
687
|
### Animated Lock Graphs
|
|
683
688
|
See the content of the [examples](examples/) directory for examples.
|
|
684
689
|
|
|
685
|
-
#
|
|
690
|
+
# pg_lw_lock_tracer
|
|
686
691
|
|
|
687
692
|
`pg_lw_lock_trace` allows to trace lightweight locks ([LWLocks](https://github.com/postgres/postgres/blob/c8e1ba736b2b9e8c98d37a5b77c4ed31baf94147/src/backend/storage/lmgr/lwlock.c)) in a PostgreSQL process via _Userland Statically Defined Tracing_ (USDT).
|
|
688
693
|
|
|
@@ -801,8 +806,73 @@ Locks per type
|
|
|
801
806
|
+--------------+----------+
|
|
802
807
|
```
|
|
803
808
|
|
|
804
|
-
#
|
|
809
|
+
# pg_row_lock_tracer
|
|
810
|
+
|
|
811
|
+
`pg_row_lock_tracer` allows to trace row locks (see the PostgreSQL [documentation](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS)) of a PostgreSQL process using _eBPF_ and _UProbes_
|
|
812
|
+
|
|
813
|
+
## Usage Examples
|
|
814
|
+
```
|
|
815
|
+
# Trace the row locks of the given PostgreSQL binary
|
|
816
|
+
pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
817
|
+
|
|
818
|
+
# Trace the row locks of the PID 1234
|
|
819
|
+
pg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
820
|
+
|
|
821
|
+
# Trace the row locks of the PID 1234 and 5678
|
|
822
|
+
pg_row_lock_tracer -p 1234 -p 5678 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
823
|
+
|
|
824
|
+
# Trace the row locks of the PID 1234 and be verbose
|
|
825
|
+
pg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres -v
|
|
826
|
+
|
|
827
|
+
# Trace the row locks and show statistics
|
|
828
|
+
pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics
|
|
829
|
+
```
|
|
830
|
+
|
|
831
|
+
## Example output
|
|
832
|
+
|
|
833
|
+
SQL Query: `SELECT * FROM temperature FOR UPDATE;`
|
|
805
834
|
|
|
835
|
+
CLI: `sudo pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics`
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
Tracer output:
|
|
839
|
+
|
|
840
|
+
```
|
|
841
|
+
[...]
|
|
842
|
+
2783502701862408 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13100 ns
|
|
843
|
+
2783502701877081 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 143) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
844
|
+
2783502701972367 [Pid 2604491] LOCK_TUPLE_END TM_OK in 95286 ns
|
|
845
|
+
2783502701988387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 144) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
846
|
+
2783502702001690 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13303 ns
|
|
847
|
+
2783502702016387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 145) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
848
|
+
2783502702029375 [Pid 2604491] LOCK_TUPLE_END TM_OK in 12988 ns
|
|
849
|
+
^C
|
|
850
|
+
Lock statistics:
|
|
851
|
+
================
|
|
852
|
+
|
|
853
|
+
Used wait policies:
|
|
854
|
+
+---------+-----------------+----------------+-----------------+
|
|
855
|
+
| PID | LOCK_WAIT_BLOCK | LOCK_WAIT_SKIP | LOCK_WAIT_ERROR |
|
|
856
|
+
+---------+-----------------+----------------+-----------------+
|
|
857
|
+
| 2604491 | 1440 | 0 | 0 |
|
|
858
|
+
+---------+-----------------+----------------+-----------------+
|
|
859
|
+
|
|
860
|
+
Lock modes:
|
|
861
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
862
|
+
| PID | LOCK_TUPLE_KEYSHARE | LOCK_TUPLE_SHARE | LOCK_TUPLE_NOKEYEXCLUSIVE | LOCK_TUPLE_EXCLUSIVE |
|
|
863
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
864
|
+
| 2604491 | 0 | 0 | 0 | 1440 |
|
|
865
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
866
|
+
|
|
867
|
+
Lock results:
|
|
868
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
869
|
+
| PID | TM_OK | TM_INVISIBLE | TM_SELFMODIFIED | TM_UPDATED | TM_DELETED | TM_BEINGMODIFIED | TM_WOULDBLOCK |
|
|
870
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
871
|
+
| 2604491 | 1440 | 0 | 0 | 0 | 0 | 0 | 0 |
|
|
872
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
873
|
+
```
|
|
874
|
+
|
|
875
|
+
# Additional Information
|
|
806
876
|
|
|
807
877
|
## Installation
|
|
808
878
|
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: pg-lock-tracer
|
|
3
|
-
Version: 0.5.4
|
|
4
|
-
Summary: A BPF based lock tracer for the PostgreSQL database
|
|
5
|
-
Home-page: https://github.com/jnidzwetzki/pg-lock-tracer
|
|
6
|
-
Author: Jan Nidzwetzki
|
|
7
|
-
Project-URL: Bug Tracker, https://github.com/jnidzwetzki/pg-lock-tracer/issues
|
|
8
|
-
Keywords: postgresql bpf lock locktracer
|
|
9
|
-
Classifier: Development Status :: 4 - Beta
|
|
10
|
-
Classifier: Intended Audience :: Developers
|
|
11
|
-
Classifier: Operating System :: POSIX :: Linux
|
|
12
|
-
Classifier: Programming Language :: Python
|
|
13
|
-
Classifier: Topic :: Software Development :: Debuggers
|
|
14
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
-
Requires-Python: >=3.6
|
|
16
|
-
Description-Content-Type: text/markdown
|
|
17
|
-
License-File: LICENSE
|
|
18
|
-
|
|
19
1
|
# Lock tracing tools for PostgreSQL
|
|
20
2
|
[](http://makeapullrequest.com)
|
|
21
3
|
[](https://github.com/jnidzwetzki/pg-lock-tracer/actions/workflows/tests.yml)
|
|
@@ -26,11 +8,12 @@ License-File: LICENSE
|
|
|
26
8
|
|
|
27
9
|
This project provides tools that allow you to gain deep insights into PostgreSQL's locking activities and troubleshoot locking-related issues (e.g., performance problems or deadlocks).
|
|
28
10
|
|
|
29
|
-
* `pg_lock_tracer` - is a lock tracer
|
|
30
|
-
* `pg_lw_lock_tracer` -
|
|
11
|
+
* `pg_lock_tracer` - is a PostgreSQL table level lock tracer.
|
|
12
|
+
* `pg_lw_lock_tracer` - is a tracer for PostgreSQL lightweight locks (LWLocks).
|
|
13
|
+
* `pg_row_lock_tracer` - is a tracer for PostgreSQL row locks.
|
|
31
14
|
* `animate_lock_graph` - creates animated locks graphs based on the `pg_lock_tracer` output.
|
|
32
15
|
|
|
33
|
-
__Note:__
|
|
16
|
+
__Note:__ These tools employ the [eBPF](https://ebpf.io/) (_Extended Berkeley Packet Filter_) technology. At the moment, PostgreSQL 12, 13, 14, 15, and 16 are supported (see additional information below).
|
|
34
17
|
|
|
35
18
|
# pg_lock_tracer
|
|
36
19
|
`pg_lock_tracer` observes the locking activity of a running PostgreSQL process (using _eBPF_ and _UProbes_). In contrast to the information that is present in the table `pg_locks` (which provides information about which locks are _currently_ requested), `pg_lock_tracer` gives you a continuous view of the locking activity and collects statistics and timings.
|
|
@@ -682,7 +665,7 @@ pg_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_2_DEBUG/bin/postgres -
|
|
|
682
665
|
### Animated Lock Graphs
|
|
683
666
|
See the content of the [examples](examples/) directory for examples.
|
|
684
667
|
|
|
685
|
-
#
|
|
668
|
+
# pg_lw_lock_tracer
|
|
686
669
|
|
|
687
670
|
`pg_lw_lock_trace` allows to trace lightweight locks ([LWLocks](https://github.com/postgres/postgres/blob/c8e1ba736b2b9e8c98d37a5b77c4ed31baf94147/src/backend/storage/lmgr/lwlock.c)) in a PostgreSQL process via _Userland Statically Defined Tracing_ (USDT).
|
|
688
671
|
|
|
@@ -801,8 +784,73 @@ Locks per type
|
|
|
801
784
|
+--------------+----------+
|
|
802
785
|
```
|
|
803
786
|
|
|
804
|
-
#
|
|
787
|
+
# pg_row_lock_tracer
|
|
788
|
+
|
|
789
|
+
`pg_row_lock_tracer` allows to trace row locks (see the PostgreSQL [documentation](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-ROWS)) of a PostgreSQL process using _eBPF_ and _UProbes_
|
|
790
|
+
|
|
791
|
+
## Usage Examples
|
|
792
|
+
```
|
|
793
|
+
# Trace the row locks of the given PostgreSQL binary
|
|
794
|
+
pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
795
|
+
|
|
796
|
+
# Trace the row locks of the PID 1234
|
|
797
|
+
pg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
798
|
+
|
|
799
|
+
# Trace the row locks of the PID 1234 and 5678
|
|
800
|
+
pg_row_lock_tracer -p 1234 -p 5678 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres
|
|
801
|
+
|
|
802
|
+
# Trace the row locks of the PID 1234 and be verbose
|
|
803
|
+
pg_row_lock_tracer -p 1234 -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres -v
|
|
804
|
+
|
|
805
|
+
# Trace the row locks and show statistics
|
|
806
|
+
pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics
|
|
807
|
+
```
|
|
808
|
+
|
|
809
|
+
## Example output
|
|
805
810
|
|
|
811
|
+
SQL Query: `SELECT * FROM temperature FOR UPDATE;`
|
|
812
|
+
|
|
813
|
+
CLI: `sudo pg_row_lock_tracer -x /home/jan/postgresql-sandbox/bin/REL_14_9_DEBUG/bin/postgres --statistics`
|
|
814
|
+
|
|
815
|
+
|
|
816
|
+
Tracer output:
|
|
817
|
+
|
|
818
|
+
```
|
|
819
|
+
[...]
|
|
820
|
+
2783502701862408 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13100 ns
|
|
821
|
+
2783502701877081 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 143) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
822
|
+
2783502701972367 [Pid 2604491] LOCK_TUPLE_END TM_OK in 95286 ns
|
|
823
|
+
2783502701988387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 144) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
824
|
+
2783502702001690 [Pid 2604491] LOCK_TUPLE_END TM_OK in 13303 ns
|
|
825
|
+
2783502702016387 [Pid 2604491] LOCK_TUPLE (Tablespace 1663 database 305234 relation 313419) - (Block and offset 7 145) - LOCK_TUPLE_EXCLUSIVE LOCK_WAIT_BLOCK
|
|
826
|
+
2783502702029375 [Pid 2604491] LOCK_TUPLE_END TM_OK in 12988 ns
|
|
827
|
+
^C
|
|
828
|
+
Lock statistics:
|
|
829
|
+
================
|
|
830
|
+
|
|
831
|
+
Used wait policies:
|
|
832
|
+
+---------+-----------------+----------------+-----------------+
|
|
833
|
+
| PID | LOCK_WAIT_BLOCK | LOCK_WAIT_SKIP | LOCK_WAIT_ERROR |
|
|
834
|
+
+---------+-----------------+----------------+-----------------+
|
|
835
|
+
| 2604491 | 1440 | 0 | 0 |
|
|
836
|
+
+---------+-----------------+----------------+-----------------+
|
|
837
|
+
|
|
838
|
+
Lock modes:
|
|
839
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
840
|
+
| PID | LOCK_TUPLE_KEYSHARE | LOCK_TUPLE_SHARE | LOCK_TUPLE_NOKEYEXCLUSIVE | LOCK_TUPLE_EXCLUSIVE |
|
|
841
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
842
|
+
| 2604491 | 0 | 0 | 0 | 1440 |
|
|
843
|
+
+---------+---------------------+------------------+---------------------------+----------------------+
|
|
844
|
+
|
|
845
|
+
Lock results:
|
|
846
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
847
|
+
| PID | TM_OK | TM_INVISIBLE | TM_SELFMODIFIED | TM_UPDATED | TM_DELETED | TM_BEINGMODIFIED | TM_WOULDBLOCK |
|
|
848
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
849
|
+
| 2604491 | 1440 | 0 | 0 | 0 | 0 | 0 | 0 |
|
|
850
|
+
+---------+-------+--------------+-----------------+------------+------------+------------------+---------------+
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
# Additional Information
|
|
806
854
|
|
|
807
855
|
## Installation
|
|
808
856
|
|
|
@@ -48,6 +48,7 @@ pg_lock_tracer.bpf =
|
|
|
48
48
|
console_scripts =
|
|
49
49
|
pg_lock_tracer = pg_lock_tracer.pg_lock_tracer:main
|
|
50
50
|
pg_lw_lock_tracer = pg_lock_tracer.pg_lw_lock_tracer:main
|
|
51
|
+
pg_row_lock_tracer = pg_lock_tracer.pg_row_lock_tracer:main
|
|
51
52
|
animate_lock_graph = pg_lock_tracer.animate_lock_graph:main
|
|
52
53
|
|
|
53
54
|
[egg_info]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.0"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#include <uapi/linux/ptrace.h>
|
|
2
|
+
|
|
3
|
+
/* Placeholder for auto generated defines */
|
|
4
|
+
__DEFINES__
|
|
5
|
+
|
|
6
|
+
typedef struct RowLockEvent_t {
|
|
7
|
+
u32 pid;
|
|
8
|
+
u64 timestamp;
|
|
9
|
+
u32 event_type;
|
|
10
|
+
|
|
11
|
+
/* See RelFileNode - Oid is u32 */
|
|
12
|
+
u32 tablespace;
|
|
13
|
+
u32 database;
|
|
14
|
+
u32 relation;
|
|
15
|
+
|
|
16
|
+
/* LockTupleMode */
|
|
17
|
+
u8 locktuplemode;
|
|
18
|
+
|
|
19
|
+
/* LockWaitPolicy */
|
|
20
|
+
u8 lockwaitpolicy;
|
|
21
|
+
|
|
22
|
+
/* Locked tuple */
|
|
23
|
+
u32 blockid;
|
|
24
|
+
u16 offset;
|
|
25
|
+
|
|
26
|
+
/* TM_Result */
|
|
27
|
+
int lockresult;
|
|
28
|
+
} RowLockEvent;
|
|
29
|
+
|
|
30
|
+
BPF_PERF_OUTPUT(lockevents);
|
|
31
|
+
|
|
32
|
+
static void fill_and_submit(struct pt_regs *ctx, RowLockEvent *event) {
|
|
33
|
+
event->pid = bpf_get_current_pid_tgid();
|
|
34
|
+
event->timestamp = bpf_ktime_get_ns();
|
|
35
|
+
|
|
36
|
+
// sudo cat /sys/kernel/debug/tracing/trace_pipe
|
|
37
|
+
// bpf_trace_printk("LW lock event for trance: %s\\n", tranche);
|
|
38
|
+
|
|
39
|
+
lockevents.perf_submit(ctx, event, sizeof(RowLockEvent));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/*
|
|
43
|
+
* Acquire a tuple lock
|
|
44
|
+
*
|
|
45
|
+
* Arguments:
|
|
46
|
+
* 1. Relation relation (1st member RelFileNode)
|
|
47
|
+
* 2. ItemPointer tid
|
|
48
|
+
* 3. Snapshot snapshot,
|
|
49
|
+
* 4. TupleTableSlot *slot,
|
|
50
|
+
* 5. CommandId cid,
|
|
51
|
+
* 6. LockTupleMode mode,
|
|
52
|
+
* 7. LockWaitPolicy wait_policy,
|
|
53
|
+
* 8. uint8 flags,
|
|
54
|
+
* 9. TM_FailureData *tmfd
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
int heapam_tuple_lock(struct pt_regs *ctx) {
|
|
58
|
+
RowLockEvent event = {.event_type = EVENT_LOCK_TUPLE};
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* (gdb) ptype /o RelFileNode
|
|
62
|
+
* 0 | 4 Oid spcNode;
|
|
63
|
+
* 4 | 4 Oid dbNode;
|
|
64
|
+
* 8 | 4 Oid relNode;
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
char buffer_relation[12];
|
|
68
|
+
bpf_probe_read_user(buffer_relation, sizeof(buffer_relation),
|
|
69
|
+
(void *)PT_REGS_PARM1(ctx));
|
|
70
|
+
bpf_probe_read_kernel(&(event.tablespace), sizeof(event.tablespace),
|
|
71
|
+
&(buffer_relation[0]));
|
|
72
|
+
bpf_probe_read_kernel(&(event.database), sizeof(event.database),
|
|
73
|
+
&(buffer_relation[4]));
|
|
74
|
+
bpf_probe_read_kernel(&(event.relation), sizeof(event.relation),
|
|
75
|
+
&(buffer_relation[8]));
|
|
76
|
+
|
|
77
|
+
/* Locked tuple */
|
|
78
|
+
char buffer_item_pointer[6];
|
|
79
|
+
u16 bi_hi;
|
|
80
|
+
u16 bi_lo;
|
|
81
|
+
|
|
82
|
+
bpf_probe_read_user(buffer_item_pointer, sizeof(buffer_item_pointer),
|
|
83
|
+
(void *)PT_REGS_PARM2(ctx));
|
|
84
|
+
bpf_probe_read_kernel(&(bi_hi), sizeof(bi_hi), &(buffer_item_pointer[0]));
|
|
85
|
+
bpf_probe_read_kernel(&(bi_lo), sizeof(bi_lo), &(buffer_item_pointer[2]));
|
|
86
|
+
bpf_probe_read_kernel(&(event.offset), sizeof(event.offset),
|
|
87
|
+
&(buffer_item_pointer[4]));
|
|
88
|
+
|
|
89
|
+
/* See #define BlockIdGetBlockNumber(blockId) */
|
|
90
|
+
event.blockid = (bi_hi) << 16 | bi_lo;
|
|
91
|
+
|
|
92
|
+
/* Locking options */
|
|
93
|
+
bpf_probe_read_kernel(&(event.locktuplemode), sizeof(event.locktuplemode),
|
|
94
|
+
&(PT_REGS_PARM6(ctx)));
|
|
95
|
+
|
|
96
|
+
/* Only the first six function parameters are passed via register. All
|
|
97
|
+
* remaining parameters are stored on the stack.
|
|
98
|
+
*
|
|
99
|
+
* See: System V Application Binary Interface—AMD64 Architecture Processor
|
|
100
|
+
* Supplement.
|
|
101
|
+
*/
|
|
102
|
+
void *ptr = 0;
|
|
103
|
+
bpf_probe_read(&ptr, sizeof(ptr), (void *)(PT_REGS_SP(ctx) + (1 * 8)));
|
|
104
|
+
bpf_probe_read_kernel(&(event.lockwaitpolicy), sizeof(event.lockwaitpolicy),
|
|
105
|
+
&ptr);
|
|
106
|
+
|
|
107
|
+
fill_and_submit(ctx, &event);
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/*
|
|
112
|
+
* Acquire a tuple lock - Function done
|
|
113
|
+
*/
|
|
114
|
+
int heapam_tuple_lock_end(struct pt_regs *ctx) {
|
|
115
|
+
RowLockEvent event = {.event_type = EVENT_LOCK_TUPLE_END};
|
|
116
|
+
|
|
117
|
+
event.lockresult = PT_REGS_RC(ctx);
|
|
118
|
+
|
|
119
|
+
fill_and_submit(ctx, &event);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
@@ -6,6 +6,8 @@ import os
|
|
|
6
6
|
|
|
7
7
|
from pathlib import Path
|
|
8
8
|
|
|
9
|
+
from bcc import BPF
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
class PostgreSQLLockHelper:
|
|
11
13
|
|
|
@@ -91,6 +93,9 @@ class PostgreSQLLockHelper:
|
|
|
91
93
|
|
|
92
94
|
|
|
93
95
|
class BPFHelper:
|
|
96
|
+
# The size of the kernel ring buffer
|
|
97
|
+
page_cnt = 2048
|
|
98
|
+
|
|
94
99
|
@staticmethod
|
|
95
100
|
def enum_to_defines(enum_instance, prefix):
|
|
96
101
|
"""
|
|
@@ -115,3 +120,54 @@ class BPFHelper:
|
|
|
115
120
|
|
|
116
121
|
with program_file.open("r") as bpf_program:
|
|
117
122
|
return bpf_program.read()
|
|
123
|
+
|
|
124
|
+
@staticmethod
|
|
125
|
+
def check_pid_exe(pids, executable):
|
|
126
|
+
"""
|
|
127
|
+
Do the given PIDs belong to the executable
|
|
128
|
+
"""
|
|
129
|
+
if not pids:
|
|
130
|
+
return
|
|
131
|
+
|
|
132
|
+
for pid in pids:
|
|
133
|
+
if not os.path.isdir(f"/proc/{pid}"):
|
|
134
|
+
raise ValueError(
|
|
135
|
+
f"/proc entry for pid {pid} not found, does the process exist?"
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
binary = os.readlink(f"/proc/{pid}/exe")
|
|
139
|
+
|
|
140
|
+
if binary != executable:
|
|
141
|
+
raise ValueError(
|
|
142
|
+
f"Pid {pid} does not belong to binary {executable}. Executable is {binary}"
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
@staticmethod
|
|
146
|
+
def register_ebpf_probe(
|
|
147
|
+
path, bpf_instance, function_regex, bpf_fn_name, verbose, probe_on_enter=True
|
|
148
|
+
):
|
|
149
|
+
"""
|
|
150
|
+
Register a BPF probe
|
|
151
|
+
"""
|
|
152
|
+
addresses = set()
|
|
153
|
+
func_and_addr = BPF.get_user_functions_and_addresses(path, function_regex)
|
|
154
|
+
|
|
155
|
+
if not func_and_addr:
|
|
156
|
+
raise ValueError(f"Unable to locate function {function_regex}")
|
|
157
|
+
|
|
158
|
+
# Handle address duplicates
|
|
159
|
+
for function, address in func_and_addr:
|
|
160
|
+
if address in addresses:
|
|
161
|
+
continue
|
|
162
|
+
addresses.add(address)
|
|
163
|
+
|
|
164
|
+
if probe_on_enter:
|
|
165
|
+
bpf_instance.attach_uprobe(name=path, sym=function, fn_name=bpf_fn_name)
|
|
166
|
+
if verbose:
|
|
167
|
+
print(f"Attaching to {function} at address {address} on enter")
|
|
168
|
+
else:
|
|
169
|
+
bpf_instance.attach_uretprobe(
|
|
170
|
+
name=path, sym=function, fn_name=bpf_fn_name
|
|
171
|
+
)
|
|
172
|
+
if verbose:
|
|
173
|
+
print(f"Attaching to {function} at address {address} on return")
|