Hello Michaƫl,
Two rebase attached.
- 15-e: prefix selection for -b
- if (strncmp(builtin_script[i].name, name,
- strlen(builtin_script[i].name)) == 0)
+ if (strncmp(builtin_script[i].name, name, len) == 0)
I agree with Alvaro here: this should remain unchanged. It seems to be
a rebase mistake.
I do not understand. I tested it and it works as expected. If I put the
above strlen instead the suffix detection does not work:
fabien@sto:bin/pgbench> git diff
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 783cbf9..0c33012 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -2684,7 +2684,7 @@ findBuiltin(const char *name, char **desc)
for (i = 0; i < N_BUILTIN; i++)
{
- if (strncmp(builtin_script[i].name, name, len) == 0)
+ if (strncmp(builtin_script[i].name, name,
strlen(builtin_script[i].name)) == 0)
{
*desc = builtin_script[i].desc;
commands = builtin_script[i].commands;
./pgbench -b t
no builtin script found for name "t"
Available builtin scripts:
tpcb-like
simple-update
select-only
Indeed, then it can only match if the provided "name" is as long as the
recorded len. The point of the "suffix" selection is to align to the short
supplied string.
--
Fabien.
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index ade1b53..ca3e158 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -262,11 +262,13 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
<variablelist>
<varlistentry>
- <term><option>-b</> <replaceable>scriptname</></term>
- <term><option>--builtin</> <replaceable>scriptname</></term>
+ <term><option>-b</> <replaceable>scriptname[@weight]</></term>
+ <term><option>--builtin</> <replaceable>scriptname[@weight]</></term>
<listitem>
<para>
Add the specified builtin script to the list of executed scripts.
+ An optional integer weight after <literal>@</> allows to adjust the
+ probability of drawing the test.
Available builtin scripts are: <literal>tpcb-like</>,
<literal>simple-update</> and <literal>select-only</>.
With special name <literal>list</>, show the list of builtin scripts
@@ -321,12 +323,14 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
</varlistentry>
<varlistentry>
- <term><option>-f</> <replaceable>filename</></term>
- <term><option>--file=</><replaceable>filename</></term>
+ <term><option>-f</> <replaceable>filename[@weight]</></term>
+ <term><option>--file=</><replaceable>filename[@weight]</></term>
<listitem>
<para>
Add a transaction script read from <replaceable>filename</> to
the list of executed scripts.
+ An optional integer weight after <literal>@</> allows to adjust the
+ probability of drawing the test.
See below for details.
</para>
</listitem>
@@ -689,6 +693,9 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
Pgbench executes test scripts chosen randomly from a specified list.
They include built-in scripts with <option>-b</> and
user-provided custom scripts with <option>-f</>.
+ Each script may be given a relative weight specified after a
+ <literal>@</> so as to change its drawing probability.
+ The default weight is <literal>1</>.
</para>
<para>
@@ -1137,7 +1144,7 @@ number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 618.764555 (including connections establishing)
tps = 622.977698 (excluding connections establishing)
-SQL script 1: <builtin: TPC-B (sort of)>
+SQL script 1, weight 1: <builtin: TPC-B (sort of)>
- 10000 transactions (100.0% of total, tps = 618.764555)
- latency average = 15.844 ms
- latency stddev = 2.715 ms
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 7eb6a2d..5d24768 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -179,6 +179,8 @@ char *login = NULL;
char *dbName;
const char *progname;
+#define WSEP '@' /* weight separator */
+
volatile bool timer_exceeded = false; /* flag from signal handler */
/* variable definitions */
@@ -299,11 +301,14 @@ typedef struct
static struct
{
const char *name;
+ int weight;
Command **commands;
StatsData stats;
} sql_script[MAX_SCRIPTS]; /* SQL script files */
static int num_scripts; /* number of scripts in sql_script[] */
static int num_commands = 0; /* total number of Command structs */
+static int total_weight = 0;
+
static int debug = 0; /* debug flag */
/* Define builtin test scripts */
@@ -389,9 +394,9 @@ usage(void)
" --tablespace=TABLESPACE create tables in the specified tablespace\n"
" --unlogged-tables create tables as unlogged tables\n"
"\nOptions to select what to run:\n"
- " -b, --builtin=NAME add buitin script (use \"-b list\" to display\n"
- " available scripts)\n"
- " -f, --file=FILENAME add transaction script from FILENAME\n"
+ " -b, --builtin=NAME[@W] add weighted buitin script (use \"-b list\"\n"
+ " to display available scripts)\n"
+ " -f, --file=FILENAME[@W] add weighted transaction script from FILENAME\n"
" -N, --skip-some-updates skip updates of pgbench_tellers and pgbench_branches\n"
" (same as \"-b simple-update\")\n"
" -S, --select-only perform SELECT-only transactions\n"
@@ -1238,10 +1243,17 @@ clientDone(CState *st, bool ok)
static int
chooseScript(TState *thread)
{
+ int i = 0, w = 0, wc;
+
if (num_scripts == 1)
return 0;
- return getrand(thread, 0, num_scripts - 1);
+ wc = (int) getrand(thread, 0, total_weight - 1);
+ do {
+ w += sql_script[i++].weight;
+ } while (w <= wc);
+
+ return i - 1;
}
/* return false iff client should be disconnected */
@@ -2683,8 +2695,41 @@ findBuiltin(const char *name, char **desc)
exit(1);
}
+/* Possiby truncate option and return weight */
+static int
+getWeight(char *option)
+{
+ char *sep;
+ int weight;
+
+ if ((sep = strrchr(option, WSEP)))
+ {
+ char *s;
+ *sep++ = '\0';
+
+ /* check that the weight is a positive integer */
+ s = sep;
+ while ('0' <= *s && *s <= '9')
+ s++;
+ if (*s != '\0' || s == sep)
+ {
+ /* empty or any other char */
+ fprintf(stderr,
+ "weight for script \"%s\" must be an integer, got \"%s\"\n",
+ option, sep);
+ exit(1);
+ }
+
+ weight = atoi(sep);
+ }
+ else
+ weight = 1;
+
+ return weight;
+}
+
static void
-addScript(const char *name, Command **commands)
+addScript(const char *name, Command **commands, int weight)
{
if (commands == NULL)
{
@@ -2699,6 +2744,7 @@ addScript(const char *name, Command **commands)
}
sql_script[num_scripts].name = name;
+ sql_script[num_scripts].weight = weight;
sql_script[num_scripts].commands = commands;
initStats(&sql_script[num_scripts].stats, 0.0);
num_scripts++;
@@ -2791,9 +2837,9 @@ printResults(TState *threads, StatsData *total, instr_time total_time,
for (i = 0; i < num_scripts; i++)
{
- printf("SQL script %d: %s\n"
- " - " INT64_FORMAT " transactions (%.1f%% of total, tps = %f)\n",
- i + 1, sql_script[i].name,
+ printf("SQL script %d, weight %d: %s\n"
+ " - "INT64_FORMAT" transactions (%.1f%% of total, tps = %f)\n",
+ i + 1, sql_script[i].weight, sql_script[i].name,
sql_script[i].stats.cnt,
100.0 * sql_script[i].stats.cnt / total->cnt,
sql_script[i].stats.cnt / time_include);
@@ -2887,6 +2933,7 @@ main(int argc, char **argv)
instr_time conn_total_time;
int64 latency_late = 0;
StatsData stats;
+ int weight;
char *desc;
int i;
@@ -3066,27 +3113,32 @@ main(int argc, char **argv)
exit(0);
}
+ weight = getWeight(optarg);
addScript(desc,
- process_builtin(findBuiltin(optarg, &desc), desc));
+ process_builtin(findBuiltin(optarg, &desc), desc),
+ weight);
benchmarking_option_set = true;
internal_script_used = true;
break;
case 'S':
addScript(desc,
process_builtin(findBuiltin("select-only", &desc),
- desc));
+ desc),
+ 1);
benchmarking_option_set = true;
internal_script_used = true;
break;
case 'N':
addScript(desc,
process_builtin(findBuiltin("simple-update", &desc),
- desc));
+ desc),
+ 1);
benchmarking_option_set = true;
internal_script_used = true;
break;
case 'f':
- addScript(optarg, process_file(optarg));
+ weight = getWeight(optarg);
+ addScript(optarg, process_file(optarg), weight);
benchmarking_option_set = true;
break;
case 'D':
@@ -3225,11 +3277,16 @@ main(int argc, char **argv)
if (num_scripts == 0 && !is_init_mode)
{
addScript(desc,
- process_builtin(findBuiltin("tpcb-like", &desc), desc));
+ process_builtin(findBuiltin("tpcb-like", &desc), desc),
+ 1);
benchmarking_option_set = true;
internal_script_used = true;
}
+ /* compute total_weight */
+ for (i = 0; i < num_scripts; i++)
+ total_weight += sql_script[i].weight;
+
/* show per script stats if several scripts are used */
if (num_scripts > 1)
per_script_stats = true;
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index ca3e158..52dc142 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -271,6 +271,9 @@ pgbench <optional> <replaceable>options</> </optional> <replaceable>dbname</>
probability of drawing the test.
Available builtin scripts are: <literal>tpcb-like</>,
<literal>simple-update</> and <literal>select-only</>.
+ The provided <replaceable>scriptname</> needs only be an unambiguous
+ prefix of the builtin name, hence <literal>si</> would be enough to
+ select <literal>simple-update</>.
With special name <literal>list</>, show the list of builtin scripts
and exit immediately.
</para>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 5d24768..783cbf9 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -2675,22 +2675,32 @@ listAvailableScripts(void)
fprintf(stderr, "\n");
}
+/* return commands for selected builtin script, if unambiguous */
static char *
findBuiltin(const char *name, char **desc)
{
- int i;
+ int i, found = 0, len = strlen(name);
+ char *commands = NULL;
for (i = 0; i < N_BUILTIN; i++)
{
- if (strncmp(builtin_script[i].name, name,
- strlen(builtin_script[i].name)) == 0)
+ if (strncmp(builtin_script[i].name, name, len) == 0)
{
*desc = builtin_script[i].desc;
- return builtin_script[i].commands;
+ commands = builtin_script[i].commands;
+ found++;
}
}
- fprintf(stderr, "no builtin script found for name \"%s\"\n", name);
+ if (found == 1)
+ return commands;
+
+ /* error cases */
+ if (found == 0)
+ fprintf(stderr, "no builtin script found for name \"%s\"\n", name);
+ else /* found > 1 */
+ fprintf(stderr,
+ "%d builtin scripts found for prefix \"%s\"\n", found, name);
listAvailableScripts();
exit(1);
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers