30#if defined(WIN32) && FD_SETSIZE < 1024
31#error FD_SETSIZE needs to have been increased
46#if defined(HAVE_PPOLL) && !defined(PGBENCH_USE_SELECT)
47#define POLL_USING_PPOLL
52#define POLL_USING_SELECT
56#include "catalog/pg_class_d.h"
74#define M_PI 3.14159265358979323846
77#define ERRCODE_T_R_SERIALIZATION_FAILURE "40001"
78#define ERRCODE_T_R_DEADLOCK_DETECTED "40P01"
79#define ERRCODE_UNDEFINED_TABLE "42P01"
84#define FNV_PRIME UINT64CONST(0x100000001b3)
85#define FNV_OFFSET_BASIS UINT64CONST(0xcbf29ce484222325)
86#define MM2_MUL UINT64CONST(0xc6a4a7935bd1e995)
87#define MM2_MUL_TIMES_8 UINT64CONST(0x35253c9ade8f4ca8)
94#ifdef POLL_USING_PPOLL
95#define SOCKET_WAIT_METHOD "ppoll"
106#ifdef POLL_USING_SELECT
107#define SOCKET_WAIT_METHOD "select"
124#define GETERRNO() (_dosmaperr(GetLastError()), errno)
125#define THREAD_T HANDLE
126#define THREAD_FUNC_RETURN_TYPE unsigned
127#define THREAD_FUNC_RETURN return 0
128#define THREAD_FUNC_CC __stdcall
129#define THREAD_CREATE(handle, function, arg) \
130 ((*(handle) = (HANDLE) _beginthreadex(NULL, 0, (function), (arg), 0, NULL)) == 0 ? errno : 0)
131#define THREAD_JOIN(handle) \
132 (WaitForSingleObject(handle, INFINITE) != WAIT_OBJECT_0 ? \
133 GETERRNO() : CloseHandle(handle) ? 0 : GETERRNO())
134#define THREAD_BARRIER_T SYNCHRONIZATION_BARRIER
135#define THREAD_BARRIER_INIT(barrier, n) \
136 (InitializeSynchronizationBarrier((barrier), (n), 0) ? 0 : GETERRNO())
137#define THREAD_BARRIER_WAIT(barrier) \
138 EnterSynchronizationBarrier((barrier), \
139 SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY)
140#define THREAD_BARRIER_DESTROY(barrier)
144#define THREAD_T pthread_t
145#define THREAD_FUNC_RETURN_TYPE void *
146#define THREAD_FUNC_RETURN return NULL
147#define THREAD_FUNC_CC
148#define THREAD_CREATE(handle, function, arg) \
149 pthread_create((handle), NULL, (function), (arg))
150#define THREAD_JOIN(handle) \
151 pthread_join((handle), NULL)
152#define THREAD_BARRIER_T pthread_barrier_t
153#define THREAD_BARRIER_INIT(barrier, n) \
154 pthread_barrier_init((barrier), NULL, (n))
155#define THREAD_BARRIER_WAIT(barrier) pthread_barrier_wait((barrier))
156#define THREAD_BARRIER_DESTROY(barrier) pthread_barrier_destroy((barrier))
163#define DEFAULT_INIT_STEPS "dtgvp"
164#define ALL_INIT_STEPS "dtgGvpf"
166#define LOG_STEP_SECONDS 5
167#define DEFAULT_NXACTS 10
169#define MIN_GAUSSIAN_PARAM 2.0
171#define MIN_ZIPFIAN_PARAM 1.001
172#define MAX_ZIPFIAN_PARAM 1000.0
247#define naccounts 100000
256#define SCALE_32BIT_THRESHOLD 20000
312#define VARIABLES_ALLOC_MARGIN 8
349#define MAX_SCRIPTS 128
350#define SHELL_COMMAND_SIZE 256
681#define META_COMMAND 2
716static const char *
const QUERYMODE[] = {
"simple",
"extended",
"prepared"};
786 "<builtin: TPC-B (sort of)>",
790 "\\set delta random(-5000, 5000)\n"
792 "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
793 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
794 "UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
795 "UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
796 "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
801 "<builtin: simple update>",
805 "\\set delta random(-5000, 5000)\n"
807 "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
808 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
809 "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
814 "<builtin: select only>",
816 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
830 StatsData *agg,
bool skipped,
double latency,
double lag);
858 const char *params[1] = {
table};
860 "SELECT relkind FROM pg_catalog.pg_class WHERE oid=$1::pg_catalog.regclass";
862 res =
PQexecParams(con, sql, 1, NULL, params, NULL, NULL, 0);
894#define PG_TIME_GET_DOUBLE(t) (0.000001 * (t))
899 printf(
"%s is a benchmarking tool for PostgreSQL.\n\n"
901 " %s [OPTION]... [DBNAME]\n"
902 "\nInitialization options:\n"
903 " -i, --initialize invokes initialization mode\n"
905 " run selected initialization steps, in the specified order\n"
906 " d: drop any existing pgbench tables\n"
907 " t: create the tables used by the standard pgbench scenario\n"
908 " g: generate data, client-side\n"
909 " G: generate data, server-side\n"
910 " v: invoke VACUUM on the standard tables\n"
911 " p: create primary key indexes on the standard tables\n"
912 " f: create foreign keys between the standard tables\n"
913 " -F, --fillfactor=NUM set fill factor\n"
914 " -n, --no-vacuum do not run VACUUM during initialization\n"
915 " -q, --quiet quiet logging (one message each 5 seconds)\n"
916 " -s, --scale=NUM scaling factor\n"
917 " --foreign-keys create foreign key constraints between tables\n"
918 " --index-tablespace=TABLESPACE\n"
919 " create indexes in the specified tablespace\n"
920 " --partition-method=(range|hash)\n"
921 " partition pgbench_accounts with this method (default: range)\n"
922 " --partitions=NUM partition pgbench_accounts into NUM parts (default: 0)\n"
923 " --tablespace=TABLESPACE create tables in the specified tablespace\n"
924 " --unlogged-tables create tables as unlogged tables\n"
925 "\nOptions to select what to run:\n"
926 " -b, --builtin=NAME[@W] add builtin script NAME weighted at W (default: 1)\n"
927 " (use \"-b list\" to list available scripts)\n"
928 " -f, --file=FILENAME[@W] add script FILENAME weighted at W (default: 1)\n"
929 " -N, --skip-some-updates skip updates of pgbench_tellers and pgbench_branches\n"
930 " (same as \"-b simple-update\")\n"
931 " -S, --select-only perform SELECT-only transactions\n"
932 " (same as \"-b select-only\")\n"
933 "\nBenchmarking options:\n"
934 " -c, --client=NUM number of concurrent database clients (default: 1)\n"
935 " -C, --connect establish new connection for each transaction\n"
936 " -D, --define=VARNAME=VALUE\n"
937 " define variable for use by custom script\n"
938 " -j, --jobs=NUM number of threads (default: 1)\n"
939 " -l, --log write transaction times to log file\n"
940 " -L, --latency-limit=NUM count transactions lasting more than NUM ms as late\n"
941 " -M, --protocol=simple|extended|prepared\n"
942 " protocol for submitting queries (default: simple)\n"
943 " -n, --no-vacuum do not run VACUUM before tests\n"
944 " -P, --progress=NUM show thread progress report every NUM seconds\n"
945 " -r, --report-per-command report latencies, failures, and retries per command\n"
946 " -R, --rate=NUM target rate in transactions per second\n"
947 " -s, --scale=NUM report this scale factor in output\n"
948 " -t, --transactions=NUM number of transactions each client runs (default: 10)\n"
949 " -T, --time=NUM duration of benchmark test in seconds\n"
950 " -v, --vacuum-all vacuum all four standard tables before tests\n"
951 " --aggregate-interval=NUM aggregate data over NUM seconds\n"
952 " --exit-on-abort exit when any client is aborted\n"
953 " --failures-detailed report the failures grouped by basic types\n"
954 " --log-prefix=PREFIX prefix for transaction time log file\n"
955 " (default: \"pgbench_log\")\n"
956 " --max-tries=NUM max number of tries to run transaction (default: 1)\n"
957 " --progress-timestamp use Unix epoch timestamps for progress\n"
958 " --random-seed=SEED set random seed (\"time\", \"rand\", integer)\n"
959 " --sampling-rate=NUM fraction of transactions to log (e.g., 0.01 for 1%%)\n"
960 " --show-script=NAME show builtin script code, then exit\n"
961 " --verbose-errors print messages of all errors\n"
962 "\nCommon options:\n"
963 " --debug print debugging output\n"
964 " -d, --dbname=DBNAME database name to connect to\n"
965 " -h, --host=HOSTNAME database server host or socket directory\n"
966 " -p, --port=PORT database server port number\n"
967 " -U, --username=USERNAME connect as specified database user\n"
968 " -V, --version output version information, then exit\n"
969 " -?, --help show this help, then exit\n"
971 "Report bugs to <%s>.\n"
972 "%s home page: <%s>\n",
980 const char *ptr =
str;
983 while (*ptr && isspace((
unsigned char) *ptr))
987 if (*ptr ==
'+' || *ptr ==
'-')
991 if (*ptr && !isdigit((
unsigned char) *ptr))
995 while (*ptr && isdigit((
unsigned char) *ptr))
1017 const char *ptr =
str;
1030 while (*ptr && isspace((
unsigned char) *ptr))
1039 else if (*ptr ==
'+')
1043 if (
unlikely(!isdigit((
unsigned char) *ptr)))
1044 goto invalid_syntax;
1047 while (*ptr && isdigit((
unsigned char) *ptr))
1049 int8 digit = (*ptr++ -
'0');
1057 while (*ptr !=
'\0' && isspace((
unsigned char) *ptr))
1061 goto invalid_syntax;
1091 *dv = strtod(
str, &end);
1149 cut = exp(-parameter);
1156 Assert((1.0 - cut) != 0.0);
1157 rand = -log(cut + (1.0 - cut) * uniform) / parameter;
1159 return min + (
int64) ((max - min + 1) * rand);
1189 while (stdev < -parameter || stdev >= parameter);
1192 rand = (stdev + parameter) / (parameter * 2.0);
1195 return min + (
int64) ((max - min + 1) * rand);
1217 return (
int64) (-log(uniform) * center + 0.5);
1230 double b = pow(2.0, s - 1.0);
1246 x = floor(pow(u, -1.0 / (s - 1.0)));
1248 t = pow(1.0 + 1.0 /
x, s - 1.0);
1250 if (v *
x * (t - 1.0) / (
b - 1.0) <= t /
b &&
x <= n)
1260 int64 n = max - min + 1;
1278 for (
i = 0;
i < 8; ++
i)
1283 result = result ^ octet;
1313 return (
int64) result;
1352 mask = (((
uint64) 1) << masklen) - 1;
1383 for (
i = 0;
i < 6;
i++)
1394 v = ((v * m) ^ r) & mask;
1395 v = ((v << 1) & mask) | (v >> (masklen - 1));
1404 t = ((t * m) ^ r) & mask;
1405 t = ((t << 1) & mask) | (t >> (masklen - 1));
1432 if (ss->
count == 0 || val < ss->min)
1495 stats->
retries += (tries - 1);
1521 pg_fatal(
"unexpected error status: %d", estatus);
1570#define PARAMS_ARRAY_SIZE 7
1585 keywords[5] =
"fallback_application_name";
1636 if (variables->
nvars <= 0)
1661 char stringform[64];
1673 snprintf(stringform,
sizeof(stringform),
"NULL");
1675 snprintf(stringform,
sizeof(stringform),
1678 snprintf(stringform,
sizeof(stringform),
1681 snprintf(stringform,
sizeof(stringform),
1698 slen = strlen(var->
svalue);
1742 pg_log_error(
"malformed variable \"%s\" value: \"%s\"",
1767 const unsigned char *ptr = (
const unsigned char *)
name;
1775 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1785 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1786 "_0123456789", *ptr) != NULL)
1803 needed += variables->
nvars;
1839 var = &(variables->
vars[variables->
nvars]);
1923 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1924 "_", sql[
i]) != NULL)
1930 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1931 "_0123456789", sql[
i]) != NULL)
1935 memcpy(
name, &sql[1],
i - 1);
1945 int valueln = strlen(
value);
1949 size_t offset = param - *sql;
1952 param = *sql + offset;
1956 memmove(param + valueln, param +
len, strlen(param +
len) + 1);
1957 memcpy(param,
value, valueln);
1959 return param + valueln;
1970 while ((p = strchr(p,
':')) != NULL)
2000 const char **params)
2004 for (
i = 0;
i < command->
argc - 1;
i++)
2035 *bval = pval->
u.
bval;
2058 return pval->
u.
bval;
2060 return pval->
u.
ival != 0;
2062 return pval->
u.
dval != 0.0;
2076 *ival = pval->
u.
ival;
2081 double dval = rint(pval->
u.
dval);
2088 *ival = (
int64) dval;
2104 *dval = pval->
u.
dval;
2109 *dval = (double) pval->
u.
ival;
2254 if (
args->next == NULL)
2284 bool has_null =
false;
2286 for (nargs = 0; nargs <
MAX_FARGS && l != NULL; nargs++, l = l->
next)
2534 double d = varg->
u.
dval;
2549 fprintf(stderr,
"debug(script=%d,command=%d): ",
2555 fprintf(stderr,
"boolean %s\n", varg->
u.
bval ?
"true" :
"false");
2559 fprintf(stderr,
"double %.*g\n", DBL_DIG, varg->
u.
dval);
2618 for (
i = 0;
i < nargs;
i++)
2632 for (
i = 1;
i < nargs;
i++)
2639 extremum =
Min(extremum, dval);
2641 extremum =
Max(extremum, dval);
2651 for (
i = 1;
i < nargs;
i++)
2658 extremum =
Min(extremum, ival);
2660 extremum =
Max(extremum, ival);
2715 pg_log_error(
"gaussian parameter must be at least %f (not %f)",
2722 imin, imax, param));
2728 pg_log_error(
"zipfian parameter must be in range [%.3f, %.0f] (not %f)",
2740 pg_log_error(
"exponential parameter must be greater than zero (not %f)",
2747 imin, imax, param));
2825 pg_log_error(
"permute size parameter must be greater than zero");
2861 switch (expr->
etype)
2882 *retval = var->
value;
2894 pg_fatal(
"unexpected enode type in evaluation: %d", expr->
etype);
2962 for (
i = 0;
i < argc;
i++)
2967 if (argv[
i][0] !=
':')
2971 else if (argv[
i][1] ==
':')
2977 pg_log_error(
"%s: undefined variable \"%s\"", argv[0], argv[
i]);
2981 arglen = strlen(
arg);
2984 pg_log_error(
"%s: shell command is too long", argv[0]);
2989 command[
len++] =
' ';
2990 memcpy(command +
len,
arg, arglen);
2994 command[
len] =
'\0';
3001 if (system(command))
3004 pg_log_error(
"%s: could not launch shell command", argv[0]);
3011 if ((fp = popen(command,
"r")) == NULL)
3013 pg_log_error(
"%s: could not launch shell command", argv[0]);
3016 if (fgets(res,
sizeof(res), fp) == NULL)
3019 pg_log_error(
"%s: could not read result of shell command", argv[0]);
3025 pg_log_error(
"%s: could not run shell command: %m", argv[0]);
3030 retval = (int) strtol(res, &endptr, 10);
3031 while (*endptr !=
'\0' && isspace((
unsigned char) *endptr))
3033 if (*res ==
'\0' || *endptr !=
'\0')
3035 pg_log_error(
"%s: shell command must return an integer (not \"%s\")", argv[0], res);
3041 pg_log_debug(
"%s: shell parameter name: \"%s\", value: \"%s\"", argv[0], argv[1], res);
3052 pg_log_error(
"client %d aborted in command %d (%s) of script %d; %s",
3063 pg_log_info(
"client %d got an error in command %d (SQL) of script %d; %s",
3101 for (numcmds = 0; script->
commands[numcmds] != NULL; numcmds++)
3128 command->
argv[0], command->
argc - 1, NULL);
3163 for (
j = st->
command + 1; commands[
j] != NULL;
j++)
3194 const char *sql = command->
argv[0];
3201 NULL, params, NULL, NULL, 0);
3212 params, NULL, NULL, 0);
3232 if (sqlState != NULL)
3285 is_last = (next_res == NULL);
3293 pg_log_error(
"client %d script %d command %d query %d: expected one row, got %d",
3308 pg_log_error(
"client %d script %d command %d query %d: expected one row, got %d",
3313 else if (meta ==
META_ASET && ntuples <= 0)
3320 for (
int fld = 0; fld <
PQnfields(res); fld++)
3322 char *varname =
PQfname(res, fld);
3325 if (*varprefix !=
'\0')
3326 varname =
psprintf(
"%s%s", varprefix, varname);
3333 pg_log_error(
"client %d script %d command %d query %d: error storing into variable %s",
3339 if (*varprefix !=
'\0')
3347 pg_log_debug(
"client %d pipeline ending, ongoing syncs: %d",
3351 pg_log_error(
"client %d failed to exit pipeline mode: %s", st->
id,
3369 pg_log_error(
"client %d script %d aborted in command %d query %d: %s",
3410 if (*argv[1] ==
':')
3412 if ((var =
getVariable(variables, argv[1] + 1)) == NULL)
3414 pg_log_error(
"%s: undefined variable \"%s\"", argv[0], argv[1] + 1);
3421 if (usec == 0 && !isdigit((
unsigned char) *var))
3423 pg_log_error(
"%s: invalid sleep time \"%s\" for variable \"%s\"",
3424 argv[0], var, argv[1] + 1);
3429 usec = atoi(argv[1]);
3501 pg_log_error(
"client %d aborted: failed to send a pipeline sync",
3524 pg_log_error(
"client %d aborted: failed to exit pipeline mode for rolling back the failed transaction",
3560 pg_log_error(
"unexpected transaction status %d", tx_status);
3584 "repeats the transaction after the error" :
3585 "ends the failed transaction"));
3664 if (st->
con == NULL)
3674 pg_log_error(
"client %d aborted while establishing connection", st->
id);
3782 if (now < st->txn_scheduled)
3799 if (command == NULL)
3805 pg_log_error(
"client %d aborted: end of script reached with pipeline open",
3828 commandFailed(st,
"gset",
"\\gset is not allowed in pipeline mode");
3834 commandFailed(st,
"aset",
"\\aset is not allowed in pipeline mode");
3990 commandFailed(st,
"SQL",
"perhaps the backend died while processing");
4024 if (now < st->sleep_until)
4088 pg_log_error(
"client %d aborted: failed to send sql command for rolling back the failed transaction",
4107 pg_log_error(
"perhaps the backend died while processing");
4109 pg_log_error(
"client %d aborted while receiving the transaction status", st->
id);
4125 pg_log_error(
"client %d aborted while rolling back the transaction after an error; perhaps the backend died while processing",
4154 pg_log_error(
"client %d aborted while rolling back the transaction after an error; %s",
4234 pg_log_error(
"client %d aborted: end of script reached without completing the last transaction",
4242 pg_log_error(
"perhaps the backend died while processing");
4244 pg_log_error(
"client %d aborted while receiving the transaction status", st->
id);
4317 argc = command->
argc;
4318 argv = command->
argv;
4327 for (
int i = 1;
i < argc;
i++)
4347 commandFailed(st,
"sleep",
"execution of meta-command failed");
4362 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4368 commandFailed(st,
"set",
"assignment of meta-command failed");
4381 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4404 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4438 commandFailed(st,
"setshell",
"execution of meta-command failed");
4446 commandFailed(st,
"shell",
"execution of meta-command failed");
4458 commandFailed(st,
"startpipeline",
"cannot use pipeline mode with the simple query protocol");
4474 commandFailed(st,
"startpipeline",
"already in pipeline mode");
4479 commandFailed(st,
"startpipeline",
"failed to enter pipeline mode");
4492 commandFailed(st,
"syncpipeline",
"failed to send a pipeline sync");
4506 commandFailed(st,
"endpipeline",
"failed to send a pipeline sync");
4548 return "serialization";
4553 pg_fatal(
"unexpected error status: %d", estatus);
4571 StatsData *agg,
bool skipped,
double latency,
double lag)
4599 double lag_sum = 0.0;
4600 double lag_sum2 = 0.0;
4601 double lag_min = 0.0;
4602 double lag_max = 0.0;
4604 int64 serialization_failures = 0;
4605 int64 deadlock_failures = 0;
4648 serialization_failures,
4667 now / 1000000,
now % 1000000);
4693 double latency = 0.0,
4718 doLog(thread, st, agg, skipped, latency, lag);
4733 for (
i = 0;
i < length;
i++)
4743 fprintf(stderr,
"dropping old tables...\n");
4750 "pgbench_accounts, "
4751 "pgbench_branches, "
4781 "create%s table pgbench_accounts_%d\n"
4782 " partition of pgbench_accounts\n"
4783 " for values from (",
4808 "create%s table pgbench_accounts_%d\n"
4809 " partition of pgbench_accounts\n"
4810 " for values with (modulus %d, remainder %d)",
4849 const char *bigcols;
4850 int declare_fillfactor;
4852 static const struct ddlinfo DDLs[] = {
4855 "tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)",
4856 "tid int,bid int,aid bigint,delta int,mtime timestamp,filler char(22)",
4861 "tid int not null,bid int,tbalance int,filler char(84)",
4862 "tid int not null,bid int,tbalance int,filler char(84)",
4867 "aid int not null,bid int,abalance int,filler char(84)",
4868 "aid bigint not null,bid int,abalance int,filler char(84)",
4873 "bid int not null,bbalance int,filler char(88)",
4874 "bid int not null,bbalance int,filler char(88)",
4881 fprintf(stderr,
"creating tables...\n");
4887 const struct ddlinfo *ddl = &DDLs[
i];
4899 else if (ddl->declare_fillfactor)
4907 char *escape_tablespace;
4930 "pgbench_accounts, "
4931 "pgbench_branches, "
4973 char copy_statement[256];
4974 const char *copy_statement_fmt =
"copy %s from stdin";
4979 int log_interval = 1;
4982 char eol = isatty(fileno(stderr)) ?
'\r' :
'\n';
4989 copy_statement_fmt =
"copy %s from stdin with (freeze on)";
4992 n =
pg_snprintf(copy_statement,
sizeof(copy_statement), copy_statement_fmt,
table);
4993 if (n >=
sizeof(copy_statement))
4994 pg_fatal(
"invalid buffer size: must be at least %d characters long", n);
4998 res =
PQexec(con, copy_statement);
5006 for (k = 0; k < total; k++)
5024 double remaining_sec = ((double) total -
j) * elapsed_sec /
j;
5028 (
int) ((
j * 100) / total),
5029 table, elapsed_sec, remaining_sec);
5036 if (prev_chars >
chars)
5045 double remaining_sec = ((double) total -
j) * elapsed_sec /
j;
5052 (
int) ((
j * 100) / total),
5053 table, elapsed_sec, remaining_sec);
5060 if (prev_chars >
chars)
5071 if (
chars != 0 && eol !=
'\n')
5075 pg_fatal(
"very last PQputline failed");
5091 fprintf(stderr,
"generating data (client-side)...\n");
5125 fprintf(stderr,
"generating data (server-side)...\n");
5139 "insert into pgbench_branches(bid,bbalance) "
5145 "insert into pgbench_tellers(tid,bid,tbalance) "
5146 "select tid, (tid - 1) / %d + 1, 0 "
5151 "insert into pgbench_accounts(aid,bid,abalance,filler) "
5152 "select aid, (aid - 1) / %d + 1, 0, '' "
5168 fprintf(stderr,
"vacuuming...\n");
5181 static const char *
const DDLINDEXes[] = {
5182 "alter table pgbench_branches add primary key (bid)",
5183 "alter table pgbench_tellers add primary key (tid)",
5184 "alter table pgbench_accounts add primary key (aid)"
5189 fprintf(stderr,
"creating primary keys...\n");
5199 char *escape_tablespace;
5219 static const char *
const DDLKEYs[] = {
5220 "alter table pgbench_tellers add constraint pgbench_tellers_bid_fkey foreign key (bid) references pgbench_branches",
5221 "alter table pgbench_accounts add constraint pgbench_accounts_bid_fkey foreign key (bid) references pgbench_branches",
5222 "alter table pgbench_history add constraint pgbench_history_bid_fkey foreign key (bid) references pgbench_branches",
5223 "alter table pgbench_history add constraint pgbench_history_tid_fkey foreign key (tid) references pgbench_tellers",
5224 "alter table pgbench_history add constraint pgbench_history_aid_fkey foreign key (aid) references pgbench_accounts"
5228 fprintf(stderr,
"creating foreign keys...\n");
5245 if (initialize_steps[0] ==
'\0')
5246 pg_fatal(
"no initialization steps specified");
5248 for (
const char *step = initialize_steps; *step !=
'\0'; step++)
5252 pg_log_error(
"unrecognized initialization step \"%c\"", *step);
5268 double run_time = 0.0;
5274 pg_fatal(
"could not create connection for initialization");
5279 for (step = initialize_steps; *step !=
'\0'; step++)
5291 op =
"create tables";
5295 op =
"client-side generate";
5299 op =
"server-side generate";
5307 op =
"primary keys";
5311 op =
"foreign keys";
5317 pg_log_error(
"unrecognized initialization step \"%c\"", *step);
5333 run_time += elapsed_sec;
5337 fprintf(stderr,
"done in %.2f s (%s).\n", run_time, stats.
data);
5356 res =
PQexec(con,
"select count(*) from pgbench_branches");
5364 pg_log_error_hint(
"Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
5371 pg_fatal(
"invalid count(*) from pgbench_branches: \"%s\"",
5377 pg_log_warning(
"scale option ignored, using count from pgbench_branches table (%d)",
5396 "select o.n, p.partstrat, pg_catalog.count(i.inhparent) "
5397 "from pg_catalog.pg_class as c "
5398 "join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) "
5399 "cross join lateral (select pg_catalog.array_position(pg_catalog.current_schemas(true), n.nspname)) as o(n) "
5400 "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) "
5401 "left join pg_catalog.pg_inherits as i on (c.oid = i.inhparent) "
5402 "where c.relname = 'pgbench_accounts' and o.n is not null "
5419 pg_log_error(
"no pgbench_accounts table found in \"search_path\"");
5420 pg_log_error_hint(
"Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
PQdb(con));
5435 if (strcmp(
ps,
"r") == 0)
5437 else if (strcmp(
ps,
"h") == 0)
5442 pg_fatal(
"unexpected partition method: \"%s\"",
ps);
5465 while ((p = strchr(p,
':')) != NULL)
5487 pg_log_error(
"statement has too many arguments (maximum is %d): %s",
5519 const char *line,
const char *command,
5520 const char *msg,
const char *more,
int column)
5529 if (column >= 0 && line == NULL)
5531 if (command != NULL)
5540 fprintf(stderr,
"%s\n", line);
5542 fprintf(stderr,
"%*c error found here\n", column + 1,
'^');
5556 char *p = sql_command;
5561 if (isspace((
unsigned char) *p))
5563 else if (strncmp(p,
"--", 2) == 0)
5565 p = strchr(p,
'\n');
5604 my_command->
argc = 0;
5607 memset(my_command->
argv, 0,
sizeof(my_command->
argv));
5609 my_command->
expr = NULL;
5622 for (
int i = 0;
i < command->
argc;
i++)
5641 static int prepnum = 0;
5647 buffer[strcspn(buffer,
"\n\r")] =
'\0';
5676 int lineno,
int start_offset)
5696 my_command->
argc = 0;
5701 offsets[
j] = word_offset;
5719 "missing argument", NULL, -1);
5721 offsets[
j] = word_offset;
5728 my_command->
argv[0]);
5758 "too many arguments", NULL, -1);
5760 offsets[
j] = word_offset;
5773 if (my_command->
argc < 2)
5775 "missing argument", NULL, -1);
5777 if (my_command->
argc > 3)
5779 "too many arguments", NULL,
5780 offsets[3] - start_offset);
5788 if (my_command->
argv[1][0] !=
':')
5790 char *
c = my_command->
argv[1];
5791 bool have_digit =
false;
5794 if (*
c ==
'+' || *
c ==
'-')
5798 if (*
c && isdigit((
unsigned char) *
c))
5802 while (*
c && isdigit((
unsigned char) *
c))
5807 if (my_command->
argc == 2 && have_digit)
5809 my_command->
argv[2] =
c;
5810 offsets[2] = offsets[1] + (
c - my_command->
argv[1]);
5811 my_command->
argc = 3;
5820 "invalid sleep time, must be an integer",
5821 my_command->
argv[1], offsets[1] - start_offset);
5826 if (my_command->
argc == 3)
5832 "unrecognized time unit, must be us, ms or s",
5833 my_command->
argv[2], offsets[2] - start_offset);
5838 if (my_command->
argc < 3)
5840 "missing argument", NULL, -1);
5844 if (my_command->
argc < 2)
5846 "missing command", NULL, -1);
5853 if (my_command->
argc != 1)
5855 "unexpected argument", NULL, -1);
5859 if (my_command->
argc > 2)
5861 "too many arguments", NULL, -1);
5867 "invalid command", NULL, -1);
5878 pg_fatal(
"condition error in script \"%s\" command %d: %s",
5892 for (
i = 0;
ps->commands[
i] != NULL;
i++)
5936ParseScript(
const char *script,
const char *desc,
int weight)
5944#define COMMANDS_ALLOC_NUM 128
5979 sr =
psql_scan(sstate, &line_buf, &prompt);
5986 ps.commands[
index++] = command;
5999 lineno, start_offset);
6013 "\\gset must follow an SQL command",
6021 "\\gset must follow an SQL command",
6025 if (command->
argc <= 1 || command->
argv[1][0] ==
'\0')
6040 ps.commands[
index++] = command;
6049 if (
index >= alloc_num)
6080 size_t buflen = BUFSIZ;
6089 nread = fread(
buf + used, 1, BUFSIZ,
fd);
6118 else if ((
fd = fopen(
filename,
"r")) == NULL)
6147 fprintf(stderr,
"Available builtin scripts:\n");
6179 pg_log_error(
"ambiguous builtin name: %d builtin scripts found for prefix \"%s\"", found,
name);
6198 int namelen = sep -
option;
6204 strncpy(*script,
option, namelen);
6205 (*script)[namelen] =
'\0';
6209 wtmp = strtol(sep + 1, &badp, 10);
6210 if (errno != 0 || badp == sep + 1 || *badp !=
'\0')
6211 pg_fatal(
"invalid weight specification: %s", sep);
6212 if (wtmp > INT_MAX || wtmp < 0)
6213 pg_fatal(
"weight specification out of range (0 .. %d): %lld",
6214 INT_MAX, (
long long) wtmp);
6231 pg_fatal(
"empty command list for script \"%s\"", script->
desc);
6285 cur.serialization_failures +=
6291 cnt =
cur.cnt - last->
cnt;
6292 total_run = (
now - test_start) / 1000000.0;
6293 tps = 1000000.0 * cnt / run;
6296 latency = 0.001 * (
cur.latency.sum - last->
latency.
sum) / cnt;
6298 stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency);
6299 lag = 0.001 * (
cur.lag.sum - last->
lag.
sum) / cnt;
6303 latency = sqlat = stdev = lag = 0;
6310 snprintf(tbuf,
sizeof(tbuf),
"%.3f s",
6316 snprintf(tbuf,
sizeof(tbuf),
"%.1f s", total_run);
6320 "progress: %s, %.1f tps, lat %.3f ms stddev %.3f, " INT64_FORMAT " failed",
6321 tbuf, tps, latency, stdev, failures);
6325 fprintf(stderr,
", lag %.3f ms", lag);
6347 double latency = ss->
sum / ss->
count;
6348 double stddev = sqrt(ss->
sum2 / ss->
count - latency * latency);
6350 printf(
"%s average = %.3f ms\n", prefix, 0.001 * latency);
6351 printf(
"%s stddev = %.3f ms\n", prefix, 0.001 * stddev);
6360 int client_ver = PG_VERSION_NUM;
6362 if (server_ver != client_ver)
6373 sverbuf,
sizeof(sverbuf));
6377 printf(
_(
"%s (%s, server %s)\n"),
6382 printf(
"%s (%s)\n",
"pgbench", PG_VERSION);
6398 double tps = total->
cnt / bench_duration;
6401 printf(
"transaction type: %s\n",
6406 printf(
"partition method: %s\npartitions: %d\n",
6417 printf(
"number of transactions per client: %d\n",
nxacts);
6436 failures, 100.0 * failures / total_cnt);
6463 (total->
cnt > 0) ? 100.0 * latency_late / total->
cnt : 0.0);
6470 printf(
"latency average = %.3f ms%s\n",
6471 0.001 * total_duration *
nclients / total_cnt,
6472 failures > 0 ?
" (including failures)" :
"");
6483 printf(
"rate limit schedule lag: avg %.3f (max %.3f) ms\n",
6498 printf(
"average connection time = %.3f ms\n", 0.001 * conn_total_duration / (total->
cnt + failures));
6499 printf(
"tps = %f (including reconnection times)\n", tps);
6503 printf(
"initial connection time = %.3f ms\n", 0.001 * conn_elapsed_duration);
6504 printf(
"tps = %f (without initial connection time)\n", tps);
6518 int64 script_total_cnt =
6519 sstats->
cnt + sstats->
skipped + script_failures;
6521 printf(
"SQL script %d: %s\n"
6522 " - weight: %d (targets %.1f%% of total)\n"
6523 " - " INT64_FORMAT " transactions (%.1f%% of total)\n",
6528 100.0 * script_total_cnt / total_cnt);
6530 if (script_total_cnt > 0)
6532 printf(
" - number of transactions actually processed: " INT64_FORMAT " (tps = %f)\n",
6533 sstats->
cnt, sstats->
cnt / bench_duration);
6537 100.0 * script_failures / script_total_cnt);
6559 100.0 * sstats->
retried / script_total_cnt);
6567 100.0 * sstats->
skipped / script_total_cnt);
6581 printf(
"%sstatement latencies in milliseconds%s:\n",
6585 ", failures and retries"));
6594 printf(
" %11.3f %10" PRId64
" %s\n",
6595 (cstats->
count > 0) ?
6596 1000.0 * cstats->
sum / cstats->
count : 0.0,
6597 (*commands)->failures,
6598 (*commands)->first_line);
6600 printf(
" %11.3f %10" PRId64
" %10" PRId64
" %s\n",
6601 (cstats->
count > 0) ?
6602 1000.0 * cstats->
sum / cstats->
count : 0.0,
6603 (*commands)->failures,
6604 (*commands)->retries,
6605 (*commands)->first_line);
6621 if (seed == NULL || strcmp(seed,
"time") == 0)
6626 else if (strcmp(seed,
"rand") == 0)
6639 if (sscanf(seed,
"%" SCNu64
"%c", &iseed, &garbage) != 1)
6641 pg_log_error(
"unrecognized random seed option \"%s\"", seed);
6648 pg_log_info(
"setting random seed to %" PRIu64, iseed);
6659main(
int argc,
char **argv)
6661 static struct option long_options[] = {
6712 bool is_init_mode =
false;
6713 char *initialize_steps = NULL;
6714 bool foreign_keys =
false;
6715 bool is_no_vacuum =
false;
6716 bool do_vacuum_accounts =
false;
6718 bool scale_given =
false;
6720 bool benchmarking_option_set =
false;
6721 bool initialization_option_set =
false;
6722 bool internal_script_used =
false;
6730 conn_total_duration;
6732 int64 latency_late = 0;
6739#ifdef HAVE_GETRLIMIT
6761 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
6766 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
6768 puts(
"pgbench (PostgreSQL) " PG_VERSION);
6777 pg_fatal(
"error while setting random seed from PGBENCH_RANDOM_SEED environment variable");
6779 while ((
c =
getopt_long(argc, argv,
"b:c:Cd:D:f:F:h:iI:j:lL:M:nNp:P:qrR:s:St:T:U:v", long_options, &optindex)) != -1)
6786 if (strcmp(
optarg,
"list") == 0)
6793 benchmarking_option_set =
true;
6794 internal_script_used =
true;
6797 benchmarking_option_set =
true;
6803#ifdef HAVE_GETRLIMIT
6804 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
6809 pg_log_error(
"need at least %d open files, but system limit is %ld",
6810 nclients + 3, (
long) rlim.rlim_max);
6811 pg_log_error_hint(
"Reduce number of clients, or use limit/ulimit to increase the system limit.");
6818 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1)
6820 pg_log_error(
"need at least %d open files, but couldn't raise the limit: %m",
6822 pg_log_error_hint(
"Reduce number of clients, or use limit/ulimit to increase the system limit.");
6829 benchmarking_option_set =
true;
6839 benchmarking_option_set =
true;
6841 if ((p = strchr(
optarg,
'=')) == NULL || p ==
optarg || *(p + 1) ==
'\0')
6852 benchmarking_option_set =
true;
6855 initialization_option_set =
true;
6864 is_init_mode =
true;
6870 initialization_option_set =
true;
6873 benchmarking_option_set =
true;
6881 benchmarking_option_set =
true;
6886 double limit_ms = atof(
optarg);
6888 if (limit_ms <= 0.0)
6890 benchmarking_option_set =
true;
6895 benchmarking_option_set =
true;
6903 is_no_vacuum =
true;
6907 benchmarking_option_set =
true;
6908 internal_script_used =
true;
6914 benchmarking_option_set =
true;
6920 initialization_option_set =
true;
6924 benchmarking_option_set =
true;
6930 double throttle_value = atof(
optarg);
6932 benchmarking_option_set =
true;
6934 if (throttle_value <= 0.0)
6948 benchmarking_option_set =
true;
6949 internal_script_used =
true;
6952 benchmarking_option_set =
true;
6958 benchmarking_option_set =
true;
6967 benchmarking_option_set =
true;
6968 do_vacuum_accounts =
true;
6971 initialization_option_set =
true;
6975 initialization_option_set =
true;
6979 initialization_option_set =
true;
6983 benchmarking_option_set =
true;
6985 if (sample_rate <= 0.0 || sample_rate > 1.0)
6989 benchmarking_option_set =
true;
6996 benchmarking_option_set =
true;
6999 benchmarking_option_set =
true;
7003 initialization_option_set =
true;
7004 foreign_keys =
true;
7007 benchmarking_option_set =
true;
7009 pg_fatal(
"error while setting random seed from --random-seed option");
7020 initialization_option_set =
true;
7026 initialization_option_set =
true;
7032 pg_fatal(
"invalid partition method, expecting \"range\" or \"hash\", got: \"%s\"",
7036 benchmarking_option_set =
true;
7043 if (max_tries_arg < 0)
7046 benchmarking_option_set =
true;
7051 benchmarking_option_set =
true;
7055 benchmarking_option_set =
true;
7072 benchmarking_option_set =
true;
7073 internal_script_used =
true;
7081 for (
int j = 0; commands[
j] != NULL;
j++)
7090 pg_fatal(
"total script weight must not be zero");
7117 if ((env = getenv(
"PGDATABASE")) != NULL && *env !=
'\0')
7119 else if ((env = getenv(
"PGUSER")) != NULL && *env !=
'\0')
7128 pg_log_error(
"too many command-line arguments (first is \"%s\")",
7136 if (benchmarking_option_set)
7137 pg_fatal(
"some of the specified options cannot be used in initialization (-i) mode");
7140 pg_fatal(
"--partition-method requires greater than zero --partitions");
7146 if (initialize_steps == NULL)
7154 while ((p = strchr(initialize_steps,
'v')) != NULL)
7161 if (strchr(initialize_steps,
'f') == NULL)
7163 initialize_steps = (
char *)
7165 strlen(initialize_steps) + 2);
7166 strcat(initialize_steps,
"f");
7175 if (initialization_option_set)
7176 pg_fatal(
"some of the specified options cannot be used in benchmarking mode");
7180 pg_fatal(
"specify either a number of transactions (-t) or a duration (-T), not both");
7188 pg_fatal(
"log sampling (--sampling-rate) is allowed only when logging transactions (-l)");
7192 pg_fatal(
"log sampling (--sampling-rate) and aggregation (--aggregate-interval) cannot be used at the same time");
7195 pg_fatal(
"log aggregation is allowed only when actually logging transactions");
7198 pg_fatal(
"log file prefix (--log-prefix) is allowed only when logging transactions (-l)");
7207 pg_fatal(
"--progress-timestamp is allowed only under --progress");
7212 pg_fatal(
"an unlimited number of transaction tries can only be used with --latency-limit or a duration (-T)");
7232 for (
j = 0;
j <
state[0].variables.nvars;
j++)
7262 pg_fatal(
"could not create connection for setup");
7267 pg_log_debug(
"pghost: %s pgport: %s nclients: %d %s: %d dbName: %s",
7269 duration <= 0 ?
"nxacts" :
"duration",
7272 if (internal_script_used)
7321 fprintf(stderr,
"starting vacuum...");
7327 if (do_vacuum_accounts)
7329 fprintf(stderr,
"starting vacuum pgbench_accounts...");
7355 nclients_dealt += thread->
nstate;
7370 pg_fatal(
"could not initialize barrier: %m");
7381 pg_fatal(
"could not create thread: %m");
7394 conn_total_duration = 0;
7403 for (
int j = 0;
j < thread->
nstate;
j++)
7420 if (bench_start == 0 || thread->
bench_start < bench_start)
7444 pg_log_error(
"Run was aborted; the above results are incomplete.");
7455 int nstate = thread->
nstate;
7456 int remains = nstate;
7470 if (thread->
tid == 0)
7475 thread->
logfile = fopen(logpath,
"w");
7478 pg_fatal(
"could not open logfile \"%s\": %m", logpath);
7482 for (
int i = 0;
i < nstate;
i++)
7491 last_report = thread_start;
7498 for (
int i = 0;
i < nstate;
i++)
7503 pg_fatal(
"could not create connection for client %d",
7540 for (
int i = 0;
i < nstate;
i++)
7555 if (min_usec > this_usec)
7556 min_usec = this_usec;
7592 if (
now >= next_report)
7594 else if ((next_report -
now) < min_usec)
7595 min_usec = next_report -
now;
7644 for (
int i = 0;
i < nstate;
i++)
7693 if (now2 >= next_report)
7702 &last, &last_report);
7711 }
while (now2 >= next_report);
7722 for (
int i = 0;
i < nstate;
i++)
7726 pg_log_error(
"Run was aborted due to an error in thread %d",
7752 if (st->
con != NULL)
7781win32_timer_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
7793 queue = CreateTimerQueue();
7794 if (seconds > ((DWORD) -1) / 1000 ||
7795 !CreateTimerQueueTimer(&timer, queue,
7796 win32_timer_callback, NULL, seconds * 1000, 0,
7797 WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE))
7839#ifdef POLL_USING_PPOLL
7847 sizeof(
struct pollfd) * count);
7870 sa->pollfds[
idx].events = POLLIN;
7871 sa->pollfds[
idx].revents = 0;
7880 struct timespec timeout;
7882 timeout.tv_sec = usecs / 1000000;
7883 timeout.tv_nsec = (usecs % 1000000) * 1000;
7884 return ppoll(
sa->pollfds,
sa->curfds, &timeout, NULL);
7888 return ppoll(
sa->pollfds,
sa->curfds, NULL, NULL);
7903 if (
sa->curfds == 0)
7907 return (
sa->pollfds[
idx].revents & POLLIN) != 0;
7912#ifdef POLL_USING_SELECT
7938 if (
sa->fds.fd_count + 1 >= FD_SETSIZE)
7940 pg_log_error(
"too many concurrent database clients for this platform: %d",
7941 sa->fds.fd_count + 1);
7945 if (fd < 0 || fd >= FD_SETSIZE)
7947 pg_log_error(
"socket file descriptor out of range for select(): %d",
7953 FD_SET(
fd, &
sa->fds);
7963 struct timeval timeout;
7965 timeout.tv_sec = usecs / 1000000;
7966 timeout.tv_usec = usecs % 1000000;
7967 return select(
sa->maxfd + 1, &
sa->fds, NULL, NULL, &timeout);
7971 return select(
sa->maxfd + 1, &
sa->fds, NULL, NULL, NULL);
7978 return (FD_ISSET(
fd, &
sa->fds) != 0);
Datum idx(PG_FUNCTION_ARGS)
Datum now(PG_FUNCTION_ARGS)
static Datum values[MAXATTR]
#define IS_HIGHBIT_SET(ch)
#define FLEXIBLE_ARRAY_MEMBER
#define FLOAT8_FITS_IN_INT64(num)
volatile sig_atomic_t CancelRequested
void ResetCancelConn(void)
void SetCancelConn(PGconn *conn)
void setup_cancel_handler(void(*query_cancel_callback)(void))
ifState conditional_stack_peek(ConditionalStack cstack)
void conditional_stack_push(ConditionalStack cstack, ifState new_state)
ConditionalStack conditional_stack_create(void)
bool conditional_stack_pop(ConditionalStack cstack)
void conditional_stack_destroy(ConditionalStack cstack)
bool conditional_active(ConditionalStack cstack)
void conditional_stack_reset(ConditionalStack cstack)
bool conditional_stack_poke(ConditionalStack cstack, ifState new_state)
bool conditional_stack_empty(ConditionalStack cstack)
#define fprintf(file, fmt, msg)
bool expr_lex_one_word(PsqlScanState state, PQExpBuffer word_buf, int *offset)
char * expr_scanner_get_substring(PsqlScanState state, int start_offset, bool chomp)
void expr_scanner_finish(yyscan_t yyscanner)
yyscan_t expr_scanner_init(PsqlScanState state, const char *source, int lineno, int start_offset, const char *command)
int PQserverVersion(const PGconn *conn)
char * PQdb(const PGconn *conn)
char * PQport(const PGconn *conn)
PGTransactionStatusType PQtransactionStatus(const PGconn *conn)
char * PQhost(const PGconn *conn)
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
int PQconnectionNeedsPassword(const PGconn *conn)
ConnStatusType PQstatus(const PGconn *conn)
void PQfinish(PGconn *conn)
PGpipelineStatus PQpipelineStatus(const PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
int PQsocket(const PGconn *conn)
PGconn * PQconnectdbParams(const char *const *keywords, const char *const *values, int expand_dbname)
int PQsendQueryParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
void PQfreemem(void *ptr)
PGresult * PQexecParams(PGconn *conn, const char *command, int nParams, const Oid *paramTypes, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
int PQexitPipelineMode(PGconn *conn)
int PQenterPipelineMode(PGconn *conn)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
PGresult * PQgetResult(PGconn *conn)
ExecStatusType PQresultStatus(const PGresult *res)
void PQclear(PGresult *res)
int PQendcopy(PGconn *conn)
int PQsendPipelineSync(PGconn *conn)
int PQntuples(const PGresult *res)
int PQputline(PGconn *conn, const char *string)
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
char * PQfname(const PGresult *res, int field_num)
int PQconsumeInput(PGconn *conn)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
char * PQresultErrorField(const PGresult *res, int fieldcode)
int PQsendQuery(PGconn *conn, const char *query)
int PQpipelineSync(PGconn *conn)
int PQisBusy(PGconn *conn)
PGresult * PQexec(PGconn *conn, const char *query)
int PQsendQueryPrepared(PGconn *conn, const char *stmtName, int nParams, const char *const *paramValues, const int *paramLengths, const int *paramFormats, int resultFormat)
char * PQescapeIdentifier(PGconn *conn, const char *str, size_t len)
int PQnfields(const PGresult *res)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
void * pg_realloc(void *ptr, size_t size)
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
Assert(PointerIsAligned(start, uint64))
static const FormData_pg_attribute a1
static const FormData_pg_attribute a2
#define INSTR_TIME_SET_CURRENT(t)
#define INSTR_TIME_GET_MICROSEC(t)
static bool pg_mul_s64_overflow(int64 a, int64 b, int64 *result)
static bool pg_sub_s64_overflow(int64 a, int64 b, int64 *result)
static bool pg_add_s64_overflow(int64 a, int64 b, int64 *result)
static const JsonPathKeyword keywords[]
void pg_logging_increase_verbosity(void)
void pg_logging_init(const char *argv0)
enum pg_log_level __pg_log_level
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define pg_log_error_detail(...)
#define pg_log_debug(...)
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
static int pg_leftmost_one_pos64(uint64 word)
static int server_version
PGDLLIMPORT char * optarg
static const struct lconv_member_info table[]
double pg_prng_double(pg_prng_state *state)
uint64 pg_prng_uint64_range(pg_prng_state *state, uint64 rmin, uint64 rmax)
uint64 pg_prng_uint64(pg_prng_state *state)
void pg_prng_seed(pg_prng_state *state, uint64 seed)
double pg_prng_double_normal(pg_prng_state *state)
static rewind_source * source
void syntax_error(const char *source, int lineno, const char *line, const char *command, const char *msg, const char *more, int column)
static QueryMode querymode
static char * index_tablespace
static void printResults(StatsData *total, pg_time_usec_t total_duration, pg_time_usec_t conn_total_duration, pg_time_usec_t conn_elapsed_duration, int64 latency_late)
static bool putVariableInt(Variables *variables, const char *context, char *name, int64 value)
static pg_time_usec_t pg_time_now(void)
bool strtodouble(const char *str, bool errorOK, double *dv)
static void accumStats(StatsData *stats, bool skipped, double lat, double lag, EStatus estatus, int64 tries)
#define THREAD_FUNC_RETURN_TYPE
static void initCreatePKeys(PGconn *con)
static void GetTableInfo(PGconn *con, bool scale_given)
static Command * create_sql_command(PQExpBuffer buf, const char *source)
static void printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry)
static void initRandomState(pg_prng_state *state)
static bool isLazyFunc(PgBenchFunction func)
static double throttle_delay
static bool per_script_stats
static char * skip_sql_comments(char *sql_command)
static int64 getZipfianRand(pg_prng_state *state, int64 min, int64 max, double s)
#define THREAD_BARRIER_WAIT(barrier)
static char * read_file_contents(FILE *fd)
static void setIntValue(PgBenchValue *pv, int64 ival)
static int64 latency_limit
static THREAD_FUNC_RETURN_TYPE THREAD_FUNC_CC threadRun(void *arg)
#define SHELL_COMMAND_SIZE
static void setalarm(int seconds)
struct BuiltinScript BuiltinScript
static void initTeller(PQExpBufferData *sql, int64 curr)
static TStatus getTransactionStatus(PGconn *con)
static bool exit_on_abort
static bool coerceToInt(PgBenchValue *pval, int64 *ival)
static void setNullValue(PgBenchValue *pv)
#define SOCKET_WAIT_METHOD
static bool doRetry(CState *st, pg_time_usec_t *now)
static bool evalLazyFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
#define ERRCODE_T_R_DEADLOCK_DETECTED
static int64 getExponentialRand(pg_prng_state *state, int64 min, int64 max, double parameter)
static void free_socket_set(socket_set *sa)
static void CheckConditional(const ParsedScript *ps)
static bool sendCommand(CState *st, Command *command)
static void doLog(TState *thread, CState *st, StatsData *agg, bool skipped, double latency, double lag)
#define COMMANDS_ALLOC_NUM
#define ERRCODE_T_R_SERIALIZATION_FAILURE
static void prepareCommandsInPipeline(CState *st)
int main(int argc, char **argv)
static bool putVariable(Variables *variables, const char *context, char *name, const char *value)
static void finishCon(CState *st)
static int compareVariableNames(const void *v1, const void *v2)
static void printVersion(PGconn *con)
static void initBranch(PQExpBufferData *sql, int64 curr)
struct socket_set socket_set
static bool evaluateExpr(CState *st, PgBenchExpr *expr, PgBenchValue *retval)
static bool parseQuery(Command *cmd)
static void initStats(StatsData *sd, pg_time_usec_t start)
static pg_prng_state base_random_sequence
static void setDoubleValue(PgBenchValue *pv, double dval)
static void checkInitSteps(const char *initialize_steps)
static void createPartitions(PGconn *con)
static char * parseVariable(const char *sql, int *eaten)
static void initDropTables(PGconn *con)
static char * getVariable(Variables *variables, char *name)
static void clear_socket_set(socket_set *sa)
static void free_command(Command *command)
static void postprocess_sql_command(Command *my_command)
static bool progress_timestamp
static const char *const QUERYMODE[]
@ CSTATE_WAIT_ROLLBACK_RESULT
@ CSTATE_PREPARE_THROTTLE
static void handle_sig_alarm(SIGNAL_ARGS)
static double sample_rate
static bool evalFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
static bool runShellCommand(Variables *variables, char *variable, char **argv, int argc)
#define MIN_ZIPFIAN_PARAM
static const BuiltinScript * findBuiltin(const char *name)
#define PARAMS_ARRAY_SIZE
void(* initRowMethod)(PQExpBufferData *sql, int64 curr)
static bool report_per_command
static char * replaceVariable(char **sql, char *param, int len, char *value)
static void initGenerateDataServerSide(PGconn *con)
static bool makeVariableValue(Variable *var)
static MetaCommand getMetaCommand(const char *cmd)
static void mergeSimpleStats(SimpleStats *acc, SimpleStats *ss)
#define THREAD_JOIN(handle)
static void printSimpleStats(const char *prefix, SimpleStats *ss)
#define ERRCODE_UNDEFINED_TABLE
static void listAvailableScripts(void)
static char * logfile_prefix
#define PG_TIME_GET_DOUBLE(t)
static bool set_random_seed(const char *seed)
static void add_socket_to_set(socket_set *sa, int fd, int idx)
static char get_table_relkind(PGconn *con, const char *table)
static int discardUntilSync(CState *st)
static EStatus getSQLErrorStatus(const char *sqlState)
static int64 total_weight
#define THREAD_FUNC_RETURN
static ConnectionStateEnum executeMetaCommand(CState *st, pg_time_usec_t *now)
#define VARIABLES_ALLOC_MARGIN
static void initCreateFKeys(PGconn *con)
static const BuiltinScript builtin_script[]
static int64 getFailures(const StatsData *stats)
static ParsedScript sql_script[MAX_SCRIPTS]
static bool canRetryError(EStatus estatus)
static void runInitSteps(const char *initialize_steps)
static int64 permute(const int64 val, const int64 isize, const int64 seed)
static Command * process_backslash_command(PsqlScanState sstate, const char *source, int lineno, int start_offset)
static void commandFailed(CState *st, const char *cmd, const char *message)
static int chooseScript(TState *thread)
static bool evalStandardFunc(CState *st, PgBenchFunction func, PgBenchExprLink *args, PgBenchValue *retval)
static void addScript(const ParsedScript *script)
static void setBoolValue(PgBenchValue *pv, bool bval)
static void initTruncateTables(PGconn *con)
static Variable * lookupCreateVariable(Variables *variables, const char *context, char *name)
bool strtoint64(const char *str, bool errorOK, int64 *result)
@ ESTATUS_META_COMMAND_ERROR
@ ESTATUS_OTHER_SQL_ERROR
@ ESTATUS_SERIALIZATION_ERROR
struct StatsData StatsData
static int64 computeIterativeZipfian(pg_prng_state *state, int64 n, double s)
static void advanceConnectionState(TState *thread, CState *st, StatsData *agg)
static void ConditionError(const char *desc, int cmdn, const char *msg)
static bool evaluateSleep(Variables *variables, int argc, char **argv, int *usecs)
static void process_builtin(const BuiltinScript *bi, int weight)
static int parseScriptWeight(const char *option, char **script)
struct SimpleStats SimpleStats
struct ParsedScript ParsedScript
static char * valueTypeName(PgBenchValue *pval)
static void initVacuum(PGconn *con)
static bool putVariableValue(Variables *variables, const char *context, char *name, const PgBenchValue *value)
static void initAccount(PQExpBufferData *sql, int64 curr)
static void commandError(CState *st, const char *message)
static void tryExecuteStatement(PGconn *con, const char *sql)
static bool valid_variable_name(const char *name)
static partition_method_t partition_method
static int64 getrand(pg_prng_state *state, int64 min, int64 max)
static const char *const PARTITION_METHOD[]
static void getQueryParams(Variables *variables, const Command *command, const char **params)
static volatile sig_atomic_t timer_exceeded
static const char * pghost
static void enlargeVariables(Variables *variables, int needed)
static THREAD_BARRIER_T barrier
static void printProgressReport(TState *threads, int64 test_start, pg_time_usec_t now, StatsData *last, int64 *last_report)
static void processXactStats(TState *thread, CState *st, pg_time_usec_t *now, bool skipped, StatsData *agg)
static const char * username
static bool unlogged_tables
static void initSimpleStats(SimpleStats *ss)
static int64 getHashMurmur2(int64 val, uint64 seed)
static void process_file(const char *filename, int weight)
static const PsqlScanCallbacks pgbench_callbacks
static void ParseScript(const char *script, const char *desc, int weight)
static char * assignVariables(Variables *variables, char *sql)
static void prepareCommand(CState *st, int command_num)
#define THREAD_BARRIER_INIT(barrier, n)
static bool socket_has_input(socket_set *sa, int fd, int idx)
static PGconn * doConnect(void)
static const char * progname
static bool valueTruth(PgBenchValue *pval)
static bool is_an_int(const char *str)
static void pg_time_now_lazy(pg_time_usec_t *now)
static int64 getGaussianRand(pg_prng_state *state, int64 min, int64 max, double parameter)
static void addToSimpleStats(SimpleStats *ss, double val)
static const char * pgport
static void initPopulateTable(PGconn *con, const char *table, int64 base, initRowMethod init_row)
static void allocCStatePrepared(CState *st)
static void disconnect_all(CState *state, int length)
#define DEFAULT_INIT_STEPS
static void initCreateTables(PGconn *con)
static bool verbose_errors
#define MIN_GAUSSIAN_PARAM
#define SCALE_32BIT_THRESHOLD
static const char * dbName
static int64 getPoissonRand(pg_prng_state *state, double center)
static int wait_on_socket_set(socket_set *sa, int64 usecs)
static void executeStatement(PGconn *con, const char *sql)
#define THREAD_CREATE(handle, function, arg)
static Variable * lookupVariable(Variables *variables, char *name)
static int64 getHashFnv1a(int64 val, uint64 seed)
static bool coerceToDouble(PgBenchValue *pval, double *dval)
static socket_set * alloc_socket_set(int count)
static bool failures_detailed
static void initGenerateDataClientSide(PGconn *con)
static bool readCommandResponse(CState *st, MetaCommand meta, char *varprefix)
static pg_time_usec_t epoch_shift
#define MAX_ZIPFIAN_PARAM
static bool coerceToBool(PgBenchValue *pval, bool *bval)
#define THREAD_BARRIER_DESTROY(barrier)
static const char * getResultString(bool skipped, EStatus estatus)
@ PGBENCH_RANDOM_EXPONENTIAL
@ PGBENCH_RANDOM_GAUSSIAN
int expr_yyparse(PgBenchExpr **expr_parse_result_p, yyscan_t yyscanner)
#define pg_log_warning(...)
int int pg_snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
bool pg_strong_random(void *buf, size_t len)
int pg_strcasecmp(const char *s1, const char *s2)
const char * get_progname(const char *argv0)
#define qsort(a, b, c, d)
size_t strlcpy(char *dst, const char *src, size_t siz)
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
PQExpBuffer createPQExpBuffer(void)
void initPQExpBuffer(PQExpBuffer str)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void appendPQExpBufferChar(PQExpBuffer str, char ch)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void termPQExpBuffer(PQExpBuffer str)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)
enum _promptStatus promptStatus_t
void psql_scan_get_location(PsqlScanState state, int *lineno, int *offset)
void psql_scan_destroy(PsqlScanState state)
PsqlScanResult psql_scan(PsqlScanState state, PQExpBuffer query_buf, promptStatus_t *prompt)
PsqlScanState psql_scan_create(const PsqlScanCallbacks *callbacks)
void psql_scan_setup(PsqlScanState state, const char *line, int line_len, int encoding, bool std_strings)
void psql_scan_finish(PsqlScanState state)
void pg_usleep(long microsec)
char * simple_prompt(const char *prompt, bool echo)
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
pg_time_usec_t txn_scheduled
pg_time_usec_t stmt_begin
pg_time_usec_t sleep_until
pg_prng_state random_state
ConnectionStateEnum state
struct PgBenchExpr::@36::@37 variable
union PgBenchValue::@35 u
int64 serialization_failures
pg_time_usec_t start_time
pg_time_usec_t create_time
pg_prng_state ts_throttle_rs
pg_time_usec_t conn_duration
pg_prng_state ts_choose_rs
pg_time_usec_t bench_start
pg_prng_state ts_sample_rs
pg_time_usec_t started_time
const char * get_user_name_or_exit(const char *progname)
#define select(n, r, w, e, timeout)
int gettimeofday(struct timeval *tp, void *tzp)
static char chars[TZ_MAX_CHARS]