#include #include #include #include /* * A quick and dirty way to generate a lot of pg_multixact/members segments. * First, CREATE TABLE foo AS SELECT 42. Then run with two numeric arguments: * sessions (= number of connections) and loops (= number of repetitions). * * Each loop should generate sessions multixacts (because each session that * share-locks the row creates a new multixact) and sessions * (sessions - 1) * / 2 member entries (because each multixact created gets all the members * from the previous one plus the new one, so we finish up with a total of 1 + * 2 + ... + sessions member entries per loop, a triangular number, probably * order n^2). * * On my Mac laptop, run with 500 100000 (after increasing max_connections and * shared_buffers appropriately), this generates 2^32 multixact members in * under a couple of hours. */ int main(int argc, char **argv) { int i; int sessions; int loop; int loops; PGconn **conns; PGresult *res; const char *conninfo = "dbname = postgres"; assert(argc == 3); sessions = atoi(argv[1]); loops = atoi(argv[2]); conns = malloc(sizeof(PGconn *) * sessions); assert(conns); for (i = 0; i < sessions; ++i) { conns[i] = PQconnectdb(conninfo); assert(PQstatus(conns[i]) == CONNECTION_OK); } printf("%d sessions connected...\n", sessions); for (loop = 0; loop < loops; ++loop) { printf("Loop %d...\n", loop); for (i = 0; i < sessions; ++i) { res = PQexec(conns[i], "BEGIN"); assert(PQresultStatus(res) == PGRES_COMMAND_OK); res = PQexec(conns[i], "SELECT * FROM foo WHERE id = 42 FOR SHARE"); assert(PQresultStatus(res) == PGRES_TUPLES_OK); PQclear(res); } for (i = 0; i < sessions; ++i) { res = PQexec(conns[i], "ROLLBACK"); assert(PQresultStatus(res) == PGRES_COMMAND_OK); PQclear(res); } } for (i = 0; i < sessions; ++i) { PQfinish(conns[i]); } printf("Disconnected.\n"); free(conns); return 0; }