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
688#define META_COMMAND 2
723static const char *
const QUERYMODE[] = {
"simple",
"extended",
"prepared"};
794 "<builtin: TPC-B (sort of)>",
798 "\\set delta random(-5000, 5000)\n"
800 "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
801 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
802 "UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;\n"
803 "UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;\n"
804 "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
809 "<builtin: simple update>",
813 "\\set delta random(-5000, 5000)\n"
815 "UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;\n"
816 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
817 "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);\n"
822 "<builtin: select only>",
824 "SELECT abalance FROM pgbench_accounts WHERE aid = :aid;\n"
838 StatsData *agg,
bool skipped,
double latency,
double lag);
866 const char *params[1] = {
table};
868 "SELECT relkind FROM pg_catalog.pg_class WHERE oid=$1::pg_catalog.regclass";
870 res =
PQexecParams(con, sql, 1, NULL, params, NULL, NULL, 0);
902#define PG_TIME_GET_DOUBLE(t) (0.000001 * (t))
907 printf(
"%s is a benchmarking tool for PostgreSQL.\n\n"
909 " %s [OPTION]... [DBNAME]\n"
910 "\nInitialization options:\n"
911 " -i, --initialize invokes initialization mode\n"
913 " run selected initialization steps, in the specified order\n"
914 " d: drop any existing pgbench tables\n"
915 " t: create the tables used by the standard pgbench scenario\n"
916 " g: generate data, client-side\n"
917 " G: generate data, server-side\n"
918 " v: invoke VACUUM on the standard tables\n"
919 " p: create primary key indexes on the standard tables\n"
920 " f: create foreign keys between the standard tables\n"
921 " -F, --fillfactor=NUM set fill factor\n"
922 " -n, --no-vacuum do not run VACUUM during initialization\n"
923 " -q, --quiet quiet logging (one message each 5 seconds)\n"
924 " -s, --scale=NUM scaling factor\n"
925 " --foreign-keys create foreign key constraints between tables\n"
926 " --index-tablespace=TABLESPACE\n"
927 " create indexes in the specified tablespace\n"
928 " --partition-method=(range|hash)\n"
929 " partition pgbench_accounts with this method (default: range)\n"
930 " --partitions=NUM partition pgbench_accounts into NUM parts (default: 0)\n"
931 " --tablespace=TABLESPACE create tables in the specified tablespace\n"
932 " --unlogged-tables create tables as unlogged tables\n"
933 "\nOptions to select what to run:\n"
934 " -b, --builtin=NAME[@W] add builtin script NAME weighted at W (default: 1)\n"
935 " (use \"-b list\" to list available scripts)\n"
936 " -f, --file=FILENAME[@W] add script FILENAME weighted at W (default: 1)\n"
937 " -N, --skip-some-updates skip updates of pgbench_tellers and pgbench_branches\n"
938 " (same as \"-b simple-update\")\n"
939 " -S, --select-only perform SELECT-only transactions\n"
940 " (same as \"-b select-only\")\n"
941 "\nBenchmarking options:\n"
942 " -c, --client=NUM number of concurrent database clients (default: 1)\n"
943 " -C, --connect establish new connection for each transaction\n"
944 " -D, --define=VARNAME=VALUE\n"
945 " define variable for use by custom script\n"
946 " -j, --jobs=NUM number of threads (default: 1)\n"
947 " -l, --log write transaction times to log file\n"
948 " -L, --latency-limit=NUM count transactions lasting more than NUM ms as late\n"
949 " -M, --protocol=simple|extended|prepared\n"
950 " protocol for submitting queries (default: simple)\n"
951 " -n, --no-vacuum do not run VACUUM before tests\n"
952 " -P, --progress=NUM show thread progress report every NUM seconds\n"
953 " -r, --report-per-command report latencies, failures, and retries per command\n"
954 " -R, --rate=NUM target rate in transactions per second\n"
955 " -s, --scale=NUM report this scale factor in output\n"
956 " -t, --transactions=NUM number of transactions each client runs (default: 10)\n"
957 " -T, --time=NUM duration of benchmark test in seconds\n"
958 " -v, --vacuum-all vacuum all four standard tables before tests\n"
959 " --aggregate-interval=NUM aggregate data over NUM seconds\n"
960 " --continue-on-error continue running after an SQL error\n"
961 " --exit-on-abort exit when any client is aborted\n"
962 " --failures-detailed report the failures grouped by basic types\n"
963 " --log-prefix=PREFIX prefix for transaction time log file\n"
964 " (default: \"pgbench_log\")\n"
965 " --max-tries=NUM max number of tries to run transaction (default: 1)\n"
966 " --progress-timestamp use Unix epoch timestamps for progress\n"
967 " --random-seed=SEED set random seed (\"time\", \"rand\", integer)\n"
968 " --sampling-rate=NUM fraction of transactions to log (e.g., 0.01 for 1%%)\n"
969 " --show-script=NAME show builtin script code, then exit\n"
970 " --verbose-errors print messages of all errors\n"
971 "\nCommon options:\n"
972 " --debug print debugging output\n"
973 " -d, --dbname=DBNAME database name to connect to\n"
974 " -h, --host=HOSTNAME database server host or socket directory\n"
975 " -p, --port=PORT database server port number\n"
976 " -U, --username=USERNAME connect as specified database user\n"
977 " -V, --version output version information, then exit\n"
978 " -?, --help show this help, then exit\n"
980 "Report bugs to <%s>.\n"
981 "%s home page: <%s>\n",
993 const char *ptr =
str;
996 while (*ptr && isspace((
unsigned char) *ptr))
1000 if (*ptr ==
'+' || *ptr ==
'-')
1004 if (*ptr && !isdigit((
unsigned char) *ptr))
1008 while (*ptr && isdigit((
unsigned char) *ptr))
1012 return *ptr ==
'\0';
1030 *result = strtoi64(
str, &end, 10);
1039 if (
unlikely(errno != 0 || end ==
str || *end !=
'\0'))
1055 *dv = strtod(
str, &end);
1064 if (
unlikely(errno != 0 || end ==
str || *end !=
'\0'))
1113 cut = exp(-parameter);
1120 Assert((1.0 - cut) != 0.0);
1121 rand = -log(cut + (1.0 - cut) * uniform) / parameter;
1123 return min + (
int64) ((max - min + 1) * rand);
1153 while (stdev < -parameter || stdev >= parameter);
1156 rand = (stdev + parameter) / (parameter * 2.0);
1159 return min + (
int64) ((max - min + 1) * rand);
1181 return (
int64) (-log(uniform) * center + 0.5);
1194 double b = pow(2.0, s - 1.0);
1210 x = floor(pow(u, -1.0 / (s - 1.0)));
1212 t = pow(1.0 + 1.0 /
x, s - 1.0);
1214 if (v *
x * (t - 1.0) / (
b - 1.0) <= t /
b &&
x <= n)
1224 int64 n = max - min + 1;
1242 for (
i = 0;
i < 8; ++
i)
1247 result = result ^ octet;
1277 return (
int64) result;
1316 mask = (((
uint64) 1) << masklen) - 1;
1347 for (
i = 0;
i < 6;
i++)
1358 v = ((v * m) ^ r) & mask;
1359 v = ((v << 1) & mask) | (v >> (masklen - 1));
1368 t = ((t * m) ^ r) & mask;
1369 t = ((t << 1) & mask) | (t >> (masklen - 1));
1396 if (ss->
count == 0 || val < ss->min)
1460 stats->
retries += (tries - 1);
1489 pg_fatal(
"unexpected error status: %d", estatus);
1538#define PARAMS_ARRAY_SIZE 7
1553 keywords[5] =
"fallback_application_name";
1604 if (variables->
nvars <= 0)
1629 char stringform[64];
1641 snprintf(stringform,
sizeof(stringform),
"NULL");
1643 snprintf(stringform,
sizeof(stringform),
1646 snprintf(stringform,
sizeof(stringform),
1649 snprintf(stringform,
sizeof(stringform),
1666 slen = strlen(var->
svalue);
1710 pg_log_error(
"malformed variable \"%s\" value: \"%s\"",
1735 const unsigned char *ptr = (
const unsigned char *)
name;
1743 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1753 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1754 "_0123456789", *ptr) != NULL)
1771 needed += variables->
nvars;
1807 var = &(variables->
vars[variables->
nvars]);
1891 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1892 "_", sql[
i]) != NULL)
1898 strchr(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"
1899 "_0123456789", sql[
i]) != NULL)
1903 memcpy(
name, &sql[1],
i - 1);
1913 int valueln = strlen(
value);
1917 size_t offset = param - *sql;
1920 param = *sql + offset;
1924 memmove(param + valueln, param +
len, strlen(param +
len) + 1);
1925 memcpy(param,
value, valueln);
1927 return param + valueln;
1938 while ((p = strchr(p,
':')) != NULL)
1968 const char **params)
1972 for (
i = 0;
i < command->
argc - 1;
i++)
2003 *bval = pval->
u.
bval;
2026 return pval->
u.
bval;
2028 return pval->
u.
ival != 0;
2030 return pval->
u.
dval != 0.0;
2044 *ival = pval->
u.
ival;
2049 double dval = rint(pval->
u.
dval);
2056 *ival = (
int64) dval;
2072 *dval = pval->
u.
dval;
2077 *dval = (double) pval->
u.
ival;
2222 if (
args->next == NULL)
2252 bool has_null =
false;
2254 for (nargs = 0; nargs <
MAX_FARGS && l != NULL; nargs++, l = l->
next)
2502 double d = varg->
u.
dval;
2517 fprintf(stderr,
"debug(script=%d,command=%d): ",
2523 fprintf(stderr,
"boolean %s\n", varg->
u.
bval ?
"true" :
"false");
2527 fprintf(stderr,
"double %.*g\n", DBL_DIG, varg->
u.
dval);
2586 for (
i = 0;
i < nargs;
i++)
2600 for (
i = 1;
i < nargs;
i++)
2607 extremum =
Min(extremum, dval);
2609 extremum =
Max(extremum, dval);
2619 for (
i = 1;
i < nargs;
i++)
2626 extremum =
Min(extremum, ival);
2628 extremum =
Max(extremum, ival);
2683 pg_log_error(
"gaussian parameter must be at least %f (not %f)",
2690 imin, imax, param));
2696 pg_log_error(
"zipfian parameter must be in range [%.3f, %.0f] (not %f)",
2708 pg_log_error(
"exponential parameter must be greater than zero (not %f)",
2715 imin, imax, param));
2793 pg_log_error(
"permute size parameter must be greater than zero");
2829 switch (expr->
etype)
2850 *retval = var->
value;
2862 pg_fatal(
"unexpected enode type in evaluation: %d", expr->
etype);
2930 for (
i = 0;
i < argc;
i++)
2935 if (argv[
i][0] !=
':')
2939 else if (argv[
i][1] ==
':')
2945 pg_log_error(
"%s: undefined variable \"%s\"", argv[0], argv[
i]);
2949 arglen = strlen(
arg);
2952 pg_log_error(
"%s: shell command is too long", argv[0]);
2957 command[
len++] =
' ';
2958 memcpy(command +
len,
arg, arglen);
2962 command[
len] =
'\0';
2969 if (system(command))
2972 pg_log_error(
"%s: could not launch shell command", argv[0]);
2979 if ((fp = popen(command,
"r")) == NULL)
2981 pg_log_error(
"%s: could not launch shell command", argv[0]);
2984 if (fgets(res,
sizeof(res), fp) == NULL)
2987 pg_log_error(
"%s: could not read result of shell command", argv[0]);
2993 pg_log_error(
"%s: could not run shell command: %m", argv[0]);
2998 retval = (int) strtol(res, &endptr, 10);
2999 while (*endptr !=
'\0' && isspace((
unsigned char) *endptr))
3001 if (*res ==
'\0' || *endptr !=
'\0')
3003 pg_log_error(
"%s: shell command must return an integer (not \"%s\")", argv[0], res);
3009 pg_log_debug(
"%s: shell parameter name: \"%s\", value: \"%s\"", argv[0], argv[1], res);
3020 pg_log_error(
"client %d aborted in command %d (%s) of script %d; %s",
3038 pg_log_info(
"client %d got an error in command %d (SQL) of script %d; %s",
3076 for (numcmds = 0; script->
commands[numcmds] != NULL; numcmds++)
3103 command->
argv[0], command->
argc - 1, NULL);
3138 for (
j = st->
command + 1; commands[
j] != NULL;
j++)
3169 const char *sql = command->
argv[0];
3176 NULL, params, NULL, NULL, 0);
3187 params, NULL, NULL, 0);
3239 if (sqlState != NULL)
3303 is_last = (next_res == NULL);
3311 pg_log_error(
"client %d script %d command %d query %d: expected one row, got %d",
3326 pg_log_error(
"client %d script %d command %d query %d: expected one row, got %d",
3331 else if (meta ==
META_ASET && ntuples <= 0)
3338 for (
int fld = 0; fld <
PQnfields(res); fld++)
3340 char *varname =
PQfname(res, fld);
3343 if (*varprefix !=
'\0')
3344 varname =
psprintf(
"%s%s", varprefix, varname);
3351 pg_log_error(
"client %d script %d command %d query %d: error storing into variable %s",
3357 if (*varprefix !=
'\0')
3365 pg_log_debug(
"client %d pipeline ending, ongoing syncs: %d",
3369 pg_log_error(
"client %d failed to exit pipeline mode: %s", st->
id,
3376 pg_log_error(
"COPY is not supported in pgbench, aborting");
3401 pg_log_error(
"client %d script %d aborted in command %d query %d: %s",
3438 if (*argv[1] ==
':')
3440 if ((var =
getVariable(variables, argv[1] + 1)) == NULL)
3442 pg_log_error(
"%s: undefined variable \"%s\"", argv[0], argv[1] + 1);
3449 if (usec == 0 && !isdigit((
unsigned char) *var))
3451 pg_log_error(
"%s: invalid sleep time \"%s\" for variable \"%s\"",
3452 argv[0], var, argv[1] + 1);
3457 usec = atoi(argv[1]);
3526 bool received_sync =
false;
3535 pg_log_error(
"client %d aborted: failed to send a pipeline sync",
3550 pg_log_error(
"client %d aborted while rolling back the transaction after an error; perhaps the backend died while processing",
3557 received_sync =
true;
3558 else if (received_sync && res == NULL)
3574 received_sync =
false;
3582 pg_log_error(
"client %d aborted: failed to exit pipeline mode for rolling back the failed transaction",
3618 pg_log_error(
"unexpected transaction status %d", tx_status);
3642 "repeats the transaction after the error" :
3643 "ends the failed transaction"));
3722 if (st->
con == NULL)
3732 pg_log_error(
"client %d aborted while establishing connection", st->
id);
3840 if (now < st->txn_scheduled)
3857 if (command == NULL)
3863 pg_log_error(
"client %d aborted: end of script reached with pipeline open",
3886 commandFailed(st,
"gset",
"\\gset is not allowed in pipeline mode");
3892 commandFailed(st,
"aset",
"\\aset is not allowed in pipeline mode");
4048 commandFailed(st,
"SQL",
"perhaps the backend died while processing");
4082 if (now < st->sleep_until)
4146 pg_log_error(
"client %d aborted: failed to send sql command for rolling back the failed transaction",
4165 pg_log_error(
"perhaps the backend died while processing");
4167 pg_log_error(
"client %d aborted while receiving the transaction status", st->
id);
4183 pg_log_error(
"client %d aborted while rolling back the transaction after an error; perhaps the backend died while processing",
4212 pg_log_error(
"client %d aborted while rolling back the transaction after an error; %s",
4292 pg_log_error(
"client %d aborted: end of script reached without completing the last transaction",
4300 pg_log_error(
"perhaps the backend died while processing");
4302 pg_log_error(
"client %d aborted while receiving the transaction status", st->
id);
4375 argc = command->
argc;
4376 argv = command->
argv;
4385 for (
int i = 1;
i < argc;
i++)
4405 commandFailed(st,
"sleep",
"execution of meta-command failed");
4420 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4426 commandFailed(st,
"set",
"assignment of meta-command failed");
4439 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4462 commandFailed(st, argv[0],
"evaluation of meta-command failed");
4496 commandFailed(st,
"setshell",
"execution of meta-command failed");
4504 commandFailed(st,
"shell",
"execution of meta-command failed");
4516 commandFailed(st,
"startpipeline",
"cannot use pipeline mode with the simple query protocol");
4532 commandFailed(st,
"startpipeline",
"already in pipeline mode");
4537 commandFailed(st,
"startpipeline",
"failed to enter pipeline mode");
4550 commandFailed(st,
"syncpipeline",
"failed to send a pipeline sync");
4564 commandFailed(st,
"endpipeline",
"failed to send a pipeline sync");
4607 return "serialization";
4614 pg_fatal(
"unexpected error status: %d", estatus);
4632 StatsData *agg,
bool skipped,
double latency,
double lag)
4660 double lag_sum = 0.0;
4661 double lag_sum2 = 0.0;
4662 double lag_min = 0.0;
4663 double lag_max = 0.0;
4665 int64 serialization_failures = 0;
4666 int64 deadlock_failures = 0;
4667 int64 other_sql_failures = 0;
4711 serialization_failures,
4713 other_sql_failures);
4731 now / 1000000,
now % 1000000);
4757 double latency = 0.0,
4782 doLog(thread, st, agg, skipped, latency, lag);
4797 for (
i = 0;
i < length;
i++)
4807 fprintf(stderr,
"dropping old tables...\n");
4814 "pgbench_accounts, "
4815 "pgbench_branches, "
4845 "create%s table pgbench_accounts_%d\n"
4846 " partition of pgbench_accounts\n"
4847 " for values from (",
4872 "create%s table pgbench_accounts_%d\n"
4873 " partition of pgbench_accounts\n"
4874 " for values with (modulus %d, remainder %d)",
4913 const char *bigcols;
4914 int declare_fillfactor;
4916 static const struct ddlinfo DDLs[] = {
4919 "tid int,bid int,aid int,delta int,mtime timestamp,filler char(22)",
4920 "tid int,bid int,aid bigint,delta int,mtime timestamp,filler char(22)",
4925 "tid int not null,bid int,tbalance int,filler char(84)",
4926 "tid int not null,bid int,tbalance int,filler char(84)",
4931 "aid int not null,bid int,abalance int,filler char(84)",
4932 "aid bigint not null,bid int,abalance int,filler char(84)",
4937 "bid int not null,bbalance int,filler char(88)",
4938 "bid int not null,bbalance int,filler char(88)",
4945 fprintf(stderr,
"creating tables...\n");
4951 const struct ddlinfo *ddl = &DDLs[
i];
4963 else if (ddl->declare_fillfactor)
4971 char *escape_tablespace;
4994 "pgbench_accounts, "
4995 "pgbench_branches, "
5037 char copy_statement[256];
5038 const char *copy_statement_fmt =
"copy %s from stdin";
5043 int log_interval = 1;
5046 char eol = isatty(fileno(stderr)) ?
'\r' :
'\n';
5053 copy_statement_fmt =
"copy %s from stdin with (freeze on)";
5056 n =
pg_snprintf(copy_statement,
sizeof(copy_statement), copy_statement_fmt,
table);
5057 if (n >=
sizeof(copy_statement))
5058 pg_fatal(
"invalid buffer size: must be at least %d characters long", n);
5062 res =
PQexec(con, copy_statement);
5070 for (k = 0; k < total; k++)
5088 double remaining_sec = ((double) total -
j) * elapsed_sec /
j;
5092 (
int) ((
j * 100) / total),
5093 table, elapsed_sec, remaining_sec);
5100 if (prev_chars >
chars)
5109 double remaining_sec = ((double) total -
j) * elapsed_sec /
j;
5116 (
int) ((
j * 100) / total),
5117 table, elapsed_sec, remaining_sec);
5124 if (prev_chars >
chars)
5135 if (
chars != 0 && eol !=
'\n')
5139 pg_fatal(
"very last PQputline failed");
5155 fprintf(stderr,
"generating data (client-side)...\n");
5189 fprintf(stderr,
"generating data (server-side)...\n");
5203 "insert into pgbench_branches(bid,bbalance) "
5209 "insert into pgbench_tellers(tid,bid,tbalance) "
5210 "select tid, (tid - 1) / %d + 1, 0 "
5215 "insert into pgbench_accounts(aid,bid,abalance,filler) "
5216 "select aid, (aid - 1) / %d + 1, 0, '' "
5232 fprintf(stderr,
"vacuuming...\n");
5245 static const char *
const DDLINDEXes[] = {
5246 "alter table pgbench_branches add primary key (bid)",
5247 "alter table pgbench_tellers add primary key (tid)",
5248 "alter table pgbench_accounts add primary key (aid)"
5253 fprintf(stderr,
"creating primary keys...\n");
5263 char *escape_tablespace;
5283 static const char *
const DDLKEYs[] = {
5284 "alter table pgbench_tellers add constraint pgbench_tellers_bid_fkey foreign key (bid) references pgbench_branches",
5285 "alter table pgbench_accounts add constraint pgbench_accounts_bid_fkey foreign key (bid) references pgbench_branches",
5286 "alter table pgbench_history add constraint pgbench_history_bid_fkey foreign key (bid) references pgbench_branches",
5287 "alter table pgbench_history add constraint pgbench_history_tid_fkey foreign key (tid) references pgbench_tellers",
5288 "alter table pgbench_history add constraint pgbench_history_aid_fkey foreign key (aid) references pgbench_accounts"
5292 fprintf(stderr,
"creating foreign keys...\n");
5309 if (initialize_steps[0] ==
'\0')
5310 pg_fatal(
"no initialization steps specified");
5312 for (
const char *step = initialize_steps; *step !=
'\0'; step++)
5316 pg_log_error(
"unrecognized initialization step \"%c\"", *step);
5332 double run_time = 0.0;
5338 pg_fatal(
"could not create connection for initialization");
5343 for (step = initialize_steps; *step !=
'\0'; step++)
5355 op =
"create tables";
5359 op =
"client-side generate";
5363 op =
"server-side generate";
5371 op =
"primary keys";
5375 op =
"foreign keys";
5381 pg_log_error(
"unrecognized initialization step \"%c\"", *step);
5397 run_time += elapsed_sec;
5401 fprintf(stderr,
"done in %.2f s (%s).\n", run_time, stats.
data);
5420 res =
PQexec(con,
"select count(*) from pgbench_branches");
5428 pg_log_error_hint(
"Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
5435 pg_fatal(
"invalid count(*) from pgbench_branches: \"%s\"",
5441 pg_log_warning(
"scale option ignored, using count from pgbench_branches table (%d)",
5460 "select o.n, p.partstrat, pg_catalog.count(i.inhparent) "
5461 "from pg_catalog.pg_class as c "
5462 "join pg_catalog.pg_namespace as n on (n.oid = c.relnamespace) "
5463 "cross join lateral (select pg_catalog.array_position(pg_catalog.current_schemas(true), n.nspname)) as o(n) "
5464 "left join pg_catalog.pg_partitioned_table as p on (p.partrelid = c.oid) "
5465 "left join pg_catalog.pg_inherits as i on (c.oid = i.inhparent) "
5466 "where c.relname = 'pgbench_accounts' and o.n is not null "
5483 pg_log_error(
"no pgbench_accounts table found in \"search_path\"");
5484 pg_log_error_hint(
"Perhaps you need to do initialization (\"pgbench -i\") in database \"%s\".",
PQdb(con));
5499 if (strcmp(
ps,
"r") == 0)
5501 else if (strcmp(
ps,
"h") == 0)
5506 pg_fatal(
"unexpected partition method: \"%s\"",
ps);
5529 while ((p = strchr(p,
':')) != NULL)
5551 pg_log_error(
"statement has too many arguments (maximum is %d): %s",
5583 const char *line,
const char *command,
5584 const char *msg,
const char *more,
int column)
5593 if (column >= 0 && line == NULL)
5595 if (command != NULL)
5604 fprintf(stderr,
"%s\n", line);
5606 fprintf(stderr,
"%*c error found here\n", column + 1,
'^');
5620 char *p = sql_command;
5625 if (isspace((
unsigned char) *p))
5627 else if (strncmp(p,
"--", 2) == 0)
5629 p = strchr(p,
'\n');
5668 my_command->
argc = 0;
5671 memset(my_command->
argv, 0,
sizeof(my_command->
argv));
5673 my_command->
expr = NULL;
5686 for (
int i = 0;
i < command->
argc;
i++)
5705 static int prepnum = 0;
5711 buffer[strcspn(buffer,
"\n\r")] =
'\0';
5740 int lineno,
int start_offset)
5760 my_command->
argc = 0;
5765 offsets[
j] = word_offset;
5783 "missing argument", NULL, -1);
5785 offsets[
j] = word_offset;
5792 my_command->
argv[0]);
5822 "too many arguments", NULL, -1);
5824 offsets[
j] = word_offset;
5837 if (my_command->
argc < 2)
5839 "missing argument", NULL, -1);
5841 if (my_command->
argc > 3)
5843 "too many arguments", NULL,
5844 offsets[3] - start_offset);
5852 if (my_command->
argv[1][0] !=
':')
5854 char *
c = my_command->
argv[1];
5855 bool have_digit =
false;
5858 if (*
c ==
'+' || *
c ==
'-')
5862 if (*
c && isdigit((
unsigned char) *
c))
5866 while (*
c && isdigit((
unsigned char) *
c))
5871 if (my_command->
argc == 2 && have_digit)
5873 my_command->
argv[2] =
c;
5874 offsets[2] = offsets[1] + (
c - my_command->
argv[1]);
5875 my_command->
argc = 3;
5884 "invalid sleep time, must be an integer",
5885 my_command->
argv[1], offsets[1] - start_offset);
5890 if (my_command->
argc == 3)
5896 "unrecognized time unit, must be us, ms or s",
5897 my_command->
argv[2], offsets[2] - start_offset);
5902 if (my_command->
argc < 3)
5904 "missing argument", NULL, -1);
5908 if (my_command->
argc < 2)
5910 "missing command", NULL, -1);
5917 if (my_command->
argc != 1)
5919 "unexpected argument", NULL, -1);
5923 if (my_command->
argc > 2)
5925 "too many arguments", NULL, -1);
5931 "invalid command", NULL, -1);
5942 pg_fatal(
"condition error in script \"%s\" command %d: %s",
5956 for (
i = 0;
ps->commands[
i] != NULL;
i++)
6000ParseScript(
const char *script,
const char *desc,
int weight)
6008#define COMMANDS_ALLOC_NUM 128
6043 sr =
psql_scan(sstate, &line_buf, &prompt);
6050 ps.commands[
index++] = command;
6063 lineno, start_offset);
6077 "\\gset must follow an SQL command",
6085 "\\gset must follow an SQL command",
6089 if (command->
argc <= 1 || command->
argv[1][0] ==
'\0')
6104 ps.commands[
index++] = command;
6113 if (
index >= alloc_num)
6144 size_t buflen = BUFSIZ;
6153 nread = fread(
buf + used, 1, BUFSIZ,
fd);
6182 else if ((
fd = fopen(
filename,
"r")) == NULL)
6211 fprintf(stderr,
"Available builtin scripts:\n");
6243 pg_log_error(
"ambiguous builtin name: %d builtin scripts found for prefix \"%s\"", found,
name);
6262 int namelen = sep -
option;
6268 strncpy(*script,
option, namelen);
6269 (*script)[namelen] =
'\0';
6273 wtmp = strtol(sep + 1, &badp, 10);
6274 if (errno != 0 || badp == sep + 1 || *badp !=
'\0')
6275 pg_fatal(
"invalid weight specification: %s", sep);
6276 if (wtmp > INT_MAX || wtmp < 0)
6277 pg_fatal(
"weight specification out of range (0 .. %d): %lld",
6278 INT_MAX, (
long long) wtmp);
6295 pg_fatal(
"empty command list for script \"%s\"", script->
desc);
6349 cur.serialization_failures +=
6356 cnt =
cur.cnt - last->
cnt;
6357 total_run = (
now - test_start) / 1000000.0;
6358 tps = 1000000.0 * cnt / run;
6361 latency = 0.001 * (
cur.latency.sum - last->
latency.
sum) / cnt;
6363 stdev = 0.001 * sqrt(sqlat - 1000000.0 * latency * latency);
6364 lag = 0.001 * (
cur.lag.sum - last->
lag.
sum) / cnt;
6368 latency = sqlat = stdev = lag = 0;
6375 snprintf(tbuf,
sizeof(tbuf),
"%.3f s",
6381 snprintf(tbuf,
sizeof(tbuf),
"%.1f s", total_run);
6385 "progress: %s, %.1f tps, lat %.3f ms stddev %.3f, " INT64_FORMAT " failed",
6386 tbuf, tps, latency, stdev, failures);
6390 fprintf(stderr,
", lag %.3f ms", lag);
6412 double latency = ss->
sum / ss->
count;
6413 double stddev = sqrt(ss->
sum2 / ss->
count - latency * latency);
6415 printf(
"%s average = %.3f ms\n", prefix, 0.001 * latency);
6416 printf(
"%s stddev = %.3f ms\n", prefix, 0.001 * stddev);
6425 int client_ver = PG_VERSION_NUM;
6427 if (server_ver != client_ver)
6438 sverbuf,
sizeof(sverbuf));
6442 printf(
_(
"%s (%s, server %s)\n"),
6447 printf(
"%s (%s)\n",
"pgbench", PG_VERSION);
6463 double tps = total->
cnt / bench_duration;
6466 printf(
"transaction type: %s\n",
6471 printf(
"partition method: %s\npartitions: %d\n",
6482 printf(
"number of transactions per client: %d\n",
nxacts);
6502 failures, 100.0 * failures / total_cnt);
6532 (total->
cnt > 0) ? 100.0 * latency_late / total->
cnt : 0.0);
6539 printf(
"latency average = %.3f ms%s\n",
6540 0.001 * total_duration *
nclients / total_cnt,
6541 failures > 0 ?
" (including failures)" :
"");
6552 printf(
"rate limit schedule lag: avg %.3f (max %.3f) ms\n",
6567 printf(
"average connection time = %.3f ms\n", 0.001 * conn_total_duration / (total->
cnt + failures));
6568 printf(
"tps = %f (including reconnection times)\n", tps);
6572 printf(
"initial connection time = %.3f ms\n", 0.001 * conn_elapsed_duration);
6573 printf(
"tps = %f (without initial connection time)\n", tps);
6587 int64 script_total_cnt =
6588 sstats->
cnt + sstats->
skipped + script_failures;
6590 printf(
"SQL script %d: %s\n"
6591 " - weight: %d (targets %.1f%% of total)\n"
6592 " - " INT64_FORMAT " transactions (%.1f%% of total)\n",
6597 100.0 * script_total_cnt / total_cnt);
6599 if (script_total_cnt > 0)
6601 printf(
" - number of transactions actually processed: " INT64_FORMAT " (tps = %f)\n",
6602 sstats->
cnt, sstats->
cnt / bench_duration);
6606 100.0 * script_failures / script_total_cnt);
6632 100.0 * sstats->
retried / script_total_cnt);
6640 100.0 * sstats->
skipped / script_total_cnt);
6654 printf(
"%sstatement latencies in milliseconds%s:\n",
6658 ", failures and retries"));
6667 printf(
" %11.3f %10" PRId64
" %s\n",
6668 (cstats->
count > 0) ?
6669 1000.0 * cstats->
sum / cstats->
count : 0.0,
6670 (*commands)->failures,
6671 (*commands)->first_line);
6673 printf(
" %11.3f %10" PRId64
" %10" PRId64
" %s\n",
6674 (cstats->
count > 0) ?
6675 1000.0 * cstats->
sum / cstats->
count : 0.0,
6676 (*commands)->failures,
6677 (*commands)->retries,
6678 (*commands)->first_line);
6694 if (seed == NULL || strcmp(seed,
"time") == 0)
6699 else if (strcmp(seed,
"rand") == 0)
6712 if (sscanf(seed,
"%" SCNu64
"%c", &iseed, &garbage) != 1)
6714 pg_log_error(
"unrecognized random seed option \"%s\"", seed);
6721 pg_log_info(
"setting random seed to %" PRIu64, iseed);
6732main(
int argc,
char **argv)
6734 static struct option long_options[] = {
6786 bool is_init_mode =
false;
6787 char *initialize_steps = NULL;
6788 bool foreign_keys =
false;
6789 bool is_no_vacuum =
false;
6790 bool do_vacuum_accounts =
false;
6792 bool scale_given =
false;
6794 bool benchmarking_option_set =
false;
6795 bool initialization_option_set =
false;
6796 bool internal_script_used =
false;
6804 conn_total_duration;
6806 int64 latency_late = 0;
6813#ifdef HAVE_GETRLIMIT
6835 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
6840 if (strcmp(argv[1],
"--version") == 0 || strcmp(argv[1],
"-V") == 0)
6842 puts(
"pgbench (PostgreSQL) " PG_VERSION);
6851 pg_fatal(
"error while setting random seed from PGBENCH_RANDOM_SEED environment variable");
6853 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)
6860 if (strcmp(
optarg,
"list") == 0)
6867 benchmarking_option_set =
true;
6868 internal_script_used =
true;
6871 benchmarking_option_set =
true;
6877#ifdef HAVE_GETRLIMIT
6878 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1)
6883 pg_log_error(
"need at least %d open files, but system limit is %ld",
6884 nclients + 3, (
long) rlim.rlim_max);
6885 pg_log_error_hint(
"Reduce number of clients, or use limit/ulimit to increase the system limit.");
6892 if (setrlimit(RLIMIT_NOFILE, &rlim) == -1)
6894 pg_log_error(
"need at least %d open files, but couldn't raise the limit: %m",
6896 pg_log_error_hint(
"Reduce number of clients, or use limit/ulimit to increase the system limit.");
6903 benchmarking_option_set =
true;
6913 benchmarking_option_set =
true;
6915 if ((p = strchr(
optarg,
'=')) == NULL || p ==
optarg || *(p + 1) ==
'\0')
6926 benchmarking_option_set =
true;
6929 initialization_option_set =
true;
6938 is_init_mode =
true;
6944 initialization_option_set =
true;
6947 benchmarking_option_set =
true;
6955 benchmarking_option_set =
true;
6960 double limit_ms = atof(
optarg);
6962 if (limit_ms <= 0.0)
6964 benchmarking_option_set =
true;
6969 benchmarking_option_set =
true;
6977 is_no_vacuum =
true;
6981 benchmarking_option_set =
true;
6982 internal_script_used =
true;
6988 benchmarking_option_set =
true;
6994 initialization_option_set =
true;
6998 benchmarking_option_set =
true;
7004 double throttle_value = atof(
optarg);
7006 benchmarking_option_set =
true;
7008 if (throttle_value <= 0.0)
7022 benchmarking_option_set =
true;
7023 internal_script_used =
true;
7026 benchmarking_option_set =
true;
7032 benchmarking_option_set =
true;
7041 benchmarking_option_set =
true;
7042 do_vacuum_accounts =
true;
7045 initialization_option_set =
true;
7049 initialization_option_set =
true;
7053 initialization_option_set =
true;
7057 benchmarking_option_set =
true;
7059 if (sample_rate <= 0.0 || sample_rate > 1.0)
7063 benchmarking_option_set =
true;
7070 benchmarking_option_set =
true;
7073 benchmarking_option_set =
true;
7077 initialization_option_set =
true;
7078 foreign_keys =
true;
7081 benchmarking_option_set =
true;
7083 pg_fatal(
"error while setting random seed from --random-seed option");
7094 initialization_option_set =
true;
7100 initialization_option_set =
true;
7106 pg_fatal(
"invalid partition method, expecting \"range\" or \"hash\", got: \"%s\"",
7110 benchmarking_option_set =
true;
7117 if (max_tries_arg < 0)
7120 benchmarking_option_set =
true;
7125 benchmarking_option_set =
true;
7129 benchmarking_option_set =
true;
7136 benchmarking_option_set =
true;
7150 benchmarking_option_set =
true;
7151 internal_script_used =
true;
7159 for (
int j = 0; commands[
j] != NULL;
j++)
7168 pg_fatal(
"total script weight must not be zero");
7195 if ((env = getenv(
"PGDATABASE")) != NULL && *env !=
'\0')
7197 else if ((env = getenv(
"PGUSER")) != NULL && *env !=
'\0')
7206 pg_log_error(
"too many command-line arguments (first is \"%s\")",
7214 if (benchmarking_option_set)
7215 pg_fatal(
"some of the specified options cannot be used in initialization (-i) mode");
7218 pg_fatal(
"--partition-method requires greater than zero --partitions");
7224 if (initialize_steps == NULL)
7232 while ((p = strchr(initialize_steps,
'v')) != NULL)
7239 if (strchr(initialize_steps,
'f') == NULL)
7241 initialize_steps = (
char *)
7243 strlen(initialize_steps) + 2);
7244 strcat(initialize_steps,
"f");
7253 if (initialization_option_set)
7254 pg_fatal(
"some of the specified options cannot be used in benchmarking mode");
7258 pg_fatal(
"specify either a number of transactions (-t) or a duration (-T), not both");
7266 pg_fatal(
"log sampling (--sampling-rate) is allowed only when logging transactions (-l)");
7270 pg_fatal(
"log sampling (--sampling-rate) and aggregation (--aggregate-interval) cannot be used at the same time");
7273 pg_fatal(
"log aggregation is allowed only when actually logging transactions");
7276 pg_fatal(
"log file prefix (--log-prefix) is allowed only when logging transactions (-l)");
7285 pg_fatal(
"--progress-timestamp is allowed only under --progress");
7290 pg_fatal(
"an unlimited number of transaction tries can only be used with --latency-limit or a duration (-T)");
7310 for (
j = 0;
j <
state[0].variables.nvars;
j++)
7340 pg_fatal(
"could not create connection for setup");
7345 pg_log_debug(
"pghost: %s pgport: %s nclients: %d %s: %d dbName: %s",
7347 duration <= 0 ?
"nxacts" :
"duration",
7350 if (internal_script_used)
7399 fprintf(stderr,
"starting vacuum...");
7405 if (do_vacuum_accounts)
7407 fprintf(stderr,
"starting vacuum pgbench_accounts...");
7433 nclients_dealt += thread->
nstate;
7448 pg_fatal(
"could not initialize barrier: %m");
7459 pg_fatal(
"could not create thread: %m");
7472 conn_total_duration = 0;
7481 for (
int j = 0;
j < thread->
nstate;
j++)
7499 if (bench_start == 0 || thread->
bench_start < bench_start)
7523 pg_log_error(
"Run was aborted; the above results are incomplete.");
7534 int nstate = thread->
nstate;
7535 int remains = nstate;
7549 if (thread->
tid == 0)
7554 thread->
logfile = fopen(logpath,
"w");
7557 pg_fatal(
"could not open logfile \"%s\": %m", logpath);
7561 for (
int i = 0;
i < nstate;
i++)
7570 last_report = thread_start;
7577 for (
int i = 0;
i < nstate;
i++)
7582 pg_fatal(
"could not create connection for client %d",
7619 for (
int i = 0;
i < nstate;
i++)
7634 if (min_usec > this_usec)
7635 min_usec = this_usec;
7671 if (
now >= next_report)
7673 else if ((next_report -
now) < min_usec)
7674 min_usec = next_report -
now;
7723 for (
int i = 0;
i < nstate;
i++)
7772 if (now2 >= next_report)
7781 &last, &last_report);
7790 }
while (now2 >= next_report);
7801 for (
int i = 0;
i < nstate;
i++)
7805 pg_log_error(
"Run was aborted due to an error in thread %d",
7831 if (st->
con != NULL)
7860win32_timer_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
7872 queue = CreateTimerQueue();
7873 if (seconds > ((DWORD) -1) / 1000 ||
7874 !CreateTimerQueueTimer(&timer, queue,
7875 win32_timer_callback, NULL, seconds * 1000, 0,
7876 WT_EXECUTEINTIMERTHREAD | WT_EXECUTEONLYONCE))
7918#ifdef POLL_USING_PPOLL
7926 sizeof(
struct pollfd) * count);
7949 sa->pollfds[
idx].events = POLLIN;
7950 sa->pollfds[
idx].revents = 0;
7959 struct timespec timeout;
7961 timeout.tv_sec = usecs / 1000000;
7962 timeout.tv_nsec = (usecs % 1000000) * 1000;
7963 return ppoll(
sa->pollfds,
sa->curfds, &timeout, NULL);
7967 return ppoll(
sa->pollfds,
sa->curfds, NULL, NULL);
7982 if (
sa->curfds == 0)
7986 return (
sa->pollfds[
idx].revents & POLLIN) != 0;
7991#ifdef POLL_USING_SELECT
8017 if (
sa->fds.fd_count + 1 >= FD_SETSIZE)
8019 pg_log_error(
"too many concurrent database clients for this platform: %d",
8020 sa->fds.fd_count + 1);
8024 if (fd < 0 || fd >= FD_SETSIZE)
8026 pg_log_error(
"socket file descriptor out of range for select(): %d",
8032 FD_SET(
fd, &
sa->fds);
8042 struct timeval timeout;
8044 timeout.tv_sec = usecs / 1000000;
8045 timeout.tv_usec = usecs % 1000000;
8046 return select(
sa->maxfd + 1, &
sa->fds, NULL, NULL, &timeout);
8050 return select(
sa->maxfd + 1, &
sa->fds, NULL, NULL, NULL);
8057 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)
int PQendcopy(PGconn *conn)
int PQsendPipelineSync(PGconn *conn)
int PQputline(PGconn *conn, const char *string)
PGresult * PQprepare(PGconn *conn, const char *stmtName, const char *query, int nParams, const Oid *paramTypes)
int PQconsumeInput(PGconn *conn)
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)
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[]
#define PQresultErrorMessage
#define PQresultErrorField
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 void discardAvailableResults(CState *st)
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 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 Command * create_sql_command(PQExpBuffer buf)
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 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 bool continue_on_error
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
static bool canContinueOnError(EStatus estatus)
#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 EStatus getSQLErrorStatus(CState *st, const char *sqlState)
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::@38::@39 variable
union PgBenchValue::@37 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]