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.
Files changed (25) hide show
  1. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/PKG-INFO +76 -6
  2. pg_lock_tracer-0.5.4/src/pg_lock_tracer.egg-info/PKG-INFO → pg_lock_tracer-0.6.0/README.md +71 -23
  3. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/setup.cfg +1 -0
  4. pg_lock_tracer-0.6.0/src/pg_lock_tracer/__init__.py +1 -0
  5. pg_lock_tracer-0.6.0/src/pg_lock_tracer/bpf/pg_row_lock_tracer.c +121 -0
  6. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/helper.py +56 -0
  7. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/pg_lock_tracer.py +149 -69
  8. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/pg_lw_lock_tracer.py +12 -19
  9. pg_lock_tracer-0.6.0/src/pg_lock_tracer/pg_row_lock_tracer.py +372 -0
  10. pg_lock_tracer-0.5.4/README.md → pg_lock_tracer-0.6.0/src/pg_lock_tracer.egg-info/PKG-INFO +93 -5
  11. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/SOURCES.txt +2 -0
  12. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/entry_points.txt +1 -0
  13. pg_lock_tracer-0.5.4/src/pg_lock_tracer/__init__.py +0 -1
  14. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/LICENSE +0 -0
  15. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/pyproject.toml +0 -0
  16. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/setup.py +0 -0
  17. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/animate_lock_graph.py +0 -0
  18. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/__init__.py +0 -0
  19. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/pg_lock_tracer.c +0 -0
  20. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/bpf/pg_lw_lock_tracer.c +0 -0
  21. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer/oid_resolver.py +0 -0
  22. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/dependency_links.txt +0 -0
  23. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/requires.txt +0 -0
  24. {pg_lock_tracer-0.5.4 → pg_lock_tracer-0.6.0}/src/pg_lock_tracer.egg-info/top_level.txt +0 -0
  25. {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.5.4
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
  [![Make a PR](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](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 for PostgreSQL.
30
- * `pg_lw_lock_tracer` - is a tracer for PostgreSQL lightweight locks (LWLocks).
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:__ Most of these tools employ the [BPF / eBPF](https://ebpf.io/) (_Extended Berkeley Packet Filter_) technology. At the moment, PostgreSQL 12, 13, 14, and 15 are supported (see additional information below).
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
- # pg_lw_lock_trace
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
- # Additional Information
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
  [![Make a PR](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](http://makeapullrequest.com)
21
3
  [![Build Status](https://github.com/jnidzwetzki/pg-lock-tracer/actions/workflows/tests.yml/badge.svg)](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 for PostgreSQL.
30
- * `pg_lw_lock_tracer` - is a tracer for PostgreSQL lightweight locks (LWLocks).
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:__ Most of these tools employ the [BPF / eBPF](https://ebpf.io/) (_Extended Berkeley Packet Filter_) technology. At the moment, PostgreSQL 12, 13, 14, and 15 are supported (see additional information below).
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
- # pg_lw_lock_trace
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
- # Additional Information
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")