Hi,
When writing / debugging an isolation test it's sometimes useful to see which
session holds what lock etc. I find it kind of painful to map pg_stat_activity
/ pg_locks / log output to the isolationtester spec. Sometimes its easy enough
to infer identity based on a statement, but far from all the time.
I found it very helpful to have each session's setup step do something like
SET application_name = 'isolation/prune-recently-dead/vac';
These days isolationtester.c already prefixes log output with the session
name. How about doing the same for application_name? It's a *tad* more
complicated than I'd like because isolationtester.c currently doesn't know the
name of the test its executing.
The attached patch executes
SELECT set_config('application_name', current_setting('application_name') ||
'/' || $1, false);
when establishing connections to deal with that.
As attached this appends "control connection" for the control connection, but
perhaps we should just not append anything for that?
Greetings,
Andres Freund
>From fce722b66ae2a727c0300b3ece843e49f61e0359 Mon Sep 17 00:00:00 2001
From: Andres Freund <[email protected]>
Date: Fri, 10 Dec 2021 17:17:21 -0800
Subject: [PATCH] isolationtester: append session name to application_name.
Author: Andres Freund <[email protected]>
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:
---
.../expected/insert-conflict-specconflict.out | 20 ++++++-------
src/test/isolation/isolationtester.c | 28 +++++++++++++++++--
.../specs/insert-conflict-specconflict.spec | 5 +---
3 files changed, 37 insertions(+), 16 deletions(-)
diff --git a/src/test/isolation/expected/insert-conflict-specconflict.out b/src/test/isolation/expected/insert-conflict-specconflict.out
index bb8f950f2cf..e34a821c403 100644
--- a/src/test/isolation/expected/insert-conflict-specconflict.out
+++ b/src/test/isolation/expected/insert-conflict-specconflict.out
@@ -490,15 +490,15 @@ step controller_print_speculative_locks:
WHERE
locktype IN ('spectoken', 'transactionid')
AND pa.datname = current_database()
- AND pa.application_name LIKE 'isolation/insert-conflict-specconflict-s%'
+ AND pa.application_name LIKE 'isolation/insert-conflict-specconflict/s%'
ORDER BY 1, 2, 3, 4;
application_name |locktype |mode |granted
-----------------------------------------+-------------+-------------+-------
-isolation/insert-conflict-specconflict-s1|spectoken |ShareLock |f
-isolation/insert-conflict-specconflict-s1|transactionid|ExclusiveLock|t
-isolation/insert-conflict-specconflict-s2|spectoken |ExclusiveLock|t
-isolation/insert-conflict-specconflict-s2|transactionid|ExclusiveLock|t
+isolation/insert-conflict-specconflict/s1|spectoken |ShareLock |f
+isolation/insert-conflict-specconflict/s1|transactionid|ExclusiveLock|t
+isolation/insert-conflict-specconflict/s2|spectoken |ExclusiveLock|t
+isolation/insert-conflict-specconflict/s2|transactionid|ExclusiveLock|t
(4 rows)
step controller_unlock_2_4: SELECT pg_advisory_unlock(2, 4);
@@ -517,14 +517,14 @@ step controller_print_speculative_locks:
WHERE
locktype IN ('spectoken', 'transactionid')
AND pa.datname = current_database()
- AND pa.application_name LIKE 'isolation/insert-conflict-specconflict-s%'
+ AND pa.application_name LIKE 'isolation/insert-conflict-specconflict/s%'
ORDER BY 1, 2, 3, 4;
application_name |locktype |mode |granted
-----------------------------------------+-------------+-------------+-------
-isolation/insert-conflict-specconflict-s1|transactionid|ExclusiveLock|t
-isolation/insert-conflict-specconflict-s1|transactionid|ShareLock |f
-isolation/insert-conflict-specconflict-s2|transactionid|ExclusiveLock|t
+isolation/insert-conflict-specconflict/s1|transactionid|ExclusiveLock|t
+isolation/insert-conflict-specconflict/s1|transactionid|ShareLock |f
+isolation/insert-conflict-specconflict/s2|transactionid|ExclusiveLock|t
(3 rows)
step s2_commit: COMMIT;
@@ -544,7 +544,7 @@ step controller_print_speculative_locks:
WHERE
locktype IN ('spectoken', 'transactionid')
AND pa.datname = current_database()
- AND pa.application_name LIKE 'isolation/insert-conflict-specconflict-s%'
+ AND pa.application_name LIKE 'isolation/insert-conflict-specconflict/s%'
ORDER BY 1, 2, 3, 4;
application_name|locktype|mode|granted
diff --git a/src/test/isolation/isolationtester.c b/src/test/isolation/isolationtester.c
index 88594a3cb5d..c49c0519b32 100644
--- a/src/test/isolation/isolationtester.c
+++ b/src/test/isolation/isolationtester.c
@@ -154,10 +154,14 @@ main(int argc, char **argv)
for (i = 0; i < nconns; i++)
{
+ const char *sessionname;
+
if (i == 0)
- conns[i].sessionname = "control connection";
+ sessionname = "control connection";
else
- conns[i].sessionname = testspec->sessions[i - 1]->name;
+ sessionname = testspec->sessions[i - 1]->name;
+
+ conns[i].sessionname = sessionname;
conns[i].conn = PQconnectdb(conninfo);
if (PQstatus(conns[i].conn) != CONNECTION_OK)
@@ -182,6 +186,26 @@ main(int argc, char **argv)
blackholeNoticeProcessor,
NULL);
+ /*
+ * Similarly, append the session name to application_name to make it
+ * easier to map spec file sesions to log output and
+ * pg_stat_activity. The reason to append instead of just setting the
+ * name is that we don't know the name of the test currently running.
+ */
+ res = PQexecParams(conns[i].conn,
+ "SELECT set_config('application_name',\n"
+ " current_setting('application_name') || '/' || $1,\n"
+ " false)",
+ 1, NULL,
+ &sessionname,
+ NULL, NULL, 0);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ fprintf(stderr, "setting of application name failed: %s",
+ PQerrorMessage(conns[i].conn));
+ exit(1);
+ }
+
/* Save each connection's backend PID for subsequent use. */
conns[i].backend_pid = PQbackendPID(conns[i].conn);
conns[i].backend_pid_str = psprintf("%d", conns[i].backend_pid);
diff --git a/src/test/isolation/specs/insert-conflict-specconflict.spec b/src/test/isolation/specs/insert-conflict-specconflict.spec
index 55b8bb100f4..0d55a015b6e 100644
--- a/src/test/isolation/specs/insert-conflict-specconflict.spec
+++ b/src/test/isolation/specs/insert-conflict-specconflict.spec
@@ -47,7 +47,6 @@ session controller
setup
{
SET default_transaction_isolation = 'read committed';
- SET application_name = 'isolation/insert-conflict-specconflict-controller';
}
step controller_locks {SELECT pg_advisory_lock(sess, lock), sess, lock FROM generate_series(1, 2) a(sess), generate_series(1,3) b(lock);}
step controller_unlock_1_1 { SELECT pg_advisory_unlock(1, 1); }
@@ -66,7 +65,7 @@ step controller_print_speculative_locks {
WHERE
locktype IN ('spectoken', 'transactionid')
AND pa.datname = current_database()
- AND pa.application_name LIKE 'isolation/insert-conflict-specconflict-s%'
+ AND pa.application_name LIKE 'isolation/insert-conflict-specconflict/s%'
ORDER BY 1, 2, 3, 4;
}
@@ -75,7 +74,6 @@ setup
{
SET default_transaction_isolation = 'read committed';
SET spec.session = 1;
- SET application_name = 'isolation/insert-conflict-specconflict-s1';
}
step s1_begin { BEGIN; }
step s1_create_non_unique_index { CREATE INDEX upserttest_key_idx ON upserttest((blurt_and_lock_4(key))); }
@@ -90,7 +88,6 @@ setup
{
SET default_transaction_isolation = 'read committed';
SET spec.session = 2;
- SET application_name = 'isolation/insert-conflict-specconflict-s2';
}
step s2_begin { BEGIN; }
step s2_upsert { INSERT INTO upserttest(key, data) VALUES('k1', 'inserted s2') ON CONFLICT (blurt_and_lock_123(key)) DO UPDATE SET data = upserttest.data || ' with conflict update s2'; }
--
2.34.0