pgbench - allow to create partitioned tables
Hello devs,
While doing some performance tests and reviewing patches, I needed to
create partitioned tables. Given the current syntax this is time
consumming.
The attached patch adds two options to create a partitioned "account"
table in pgbench.
It allows to answer quickly simple questions, eg "what is the overhead of
hash partitioning on a simple select on my laptop"? Answer:
# N=0..?
sh> pgench -i -s 1 --partition-number=$N --partition-type=hash
# then run
sh> pgench -S -M prepared -P 1 -T 10
# and look at latency:
# no parts = 0.071 ms
# 1 hash = 0.071 ms (did someone optimize this case?!)
# 2 hash ~ 0.126 ms (+ 0.055 ms)
# 50 hash ~ 0.155 ms
# 100 hash ~ 0.178 ms
# 150 hash ~ 0.232 ms
# 200 hash ~ 0.279 ms
# overhead ~ (0.050 + [0.0005-0.0008] * nparts) ms
--
Fabien.
Attachments:
pgbench-init-partitioned-1.patchtext/x-diff; name=pgbench-init-partitioned-1.patchDownload
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index 816f9cc4c7..c10789262c 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -306,6 +306,32 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--partition-number=<replaceable>NUM</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table with
+ <replaceable>NUM</replaceable> partitions of nearly equal size for
+ the scaled number of accounts.
+ Default is <literal>0</literal>, meaning no partitioning.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--partition-type=<replaceable>TYPE</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table of type
+ <replaceable>TYPE</replaceable>.
+ Expected values are <literal>range</literal> or <literal>hash</literal>.
+ This option is only taken into account if
+ <option>--partition-number</option> is non-zero.
+ Default is <literal>range</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--tablespace=<replaceable>tablespace</replaceable></option></term>
<listitem>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 570cf3306a..0b262eff13 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -186,6 +186,11 @@ int64 latency_limit = 0;
char *tablespace = NULL;
char *index_tablespace = NULL;
+/* partitioning for pgbench_accounts table, 0 for no partitioning */
+int partition_number = 0;
+enum { PART_RANGE, PART_HASH }
+ partition_type = PART_RANGE;
+
/* random seed used to initialize base_random_sequence */
int64 random_seed = -1;
@@ -617,6 +622,8 @@ usage(void)
" --foreign-keys create foreign key constraints between tables\n"
" --index-tablespace=TABLESPACE\n"
" create indexes in the specified tablespace\n"
+ " --partition-number=NUM partition account table in NUM parts (defaults: 0)\n"
+ " --partition-type=TYPE partition type (range or hash; default: range)\n"
" --tablespace=TABLESPACE create tables in the specified tablespace\n"
" --unlogged-tables create tables as unlogged tables\n"
"\nOptions to select what to run:\n"
@@ -3601,6 +3608,17 @@ initDropTables(PGconn *con)
"pgbench_tellers");
}
+/*
+ * add fillfactor percent option if not 100.
+ */
+static void
+append_fillfactor(char *opts, int len)
+{
+ if (fillfactor < 100)
+ snprintf(opts + strlen(opts), len - strlen(opts),
+ " with (fillfactor=%d)", fillfactor);
+}
+
/*
* Create pgbench's standard tables
*/
@@ -3625,6 +3643,7 @@ initCreateTables(PGconn *con)
const char *bigcols; /* column decls if accountIDs are 64 bits */
int declare_fillfactor;
};
+
static const struct ddlinfo DDLs[] = {
{
"pgbench_history",
@@ -3651,11 +3670,10 @@ initCreateTables(PGconn *con)
1
}
};
- int i;
fprintf(stderr, "creating tables...\n");
- for (i = 0; i < lengthof(DDLs); i++)
+ for (int i = 0; i < lengthof(DDLs); i++)
{
char opts[256];
char buffer[256];
@@ -3664,9 +3682,17 @@ initCreateTables(PGconn *con)
/* Construct new create table statement. */
opts[0] = '\0';
- if (ddl->declare_fillfactor)
+
+ /* Partition pgbench_accounts table */
+ if (partition_number >= 1 && strcmp(ddl->table, "pgbench_accounts") == 0)
+ {
snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
- " with (fillfactor=%d)", fillfactor);
+ " partition by %s (aid)",
+ partition_type == PART_RANGE ? "range" : "hash");
+ }
+ else if (ddl->declare_fillfactor)
+ append_fillfactor(opts, sizeof(opts));
+
if (tablespace != NULL)
{
char *escape_tablespace;
@@ -3686,6 +3712,54 @@ initCreateTables(PGconn *con)
executeStatement(con, buffer);
}
+
+ if (partition_number >= 1)
+ {
+ int64 part_size = (naccounts * (int64) scale + partition_number - 1) / partition_number;
+ char ff[64];
+ ff[0] = '\0';
+ append_fillfactor(ff, sizeof(ff));
+
+ fprintf(stderr, "creating %d partitions...\n", partition_number);
+
+ for (int p = 1; p <= partition_number; p++)
+ {
+ char query[256];
+
+ if (partition_type == PART_RANGE)
+ {
+ char minvalue[32], maxvalue[32];
+
+ if (p == 1)
+ sprintf(minvalue, "MINVALUE");
+ else
+ sprintf(minvalue, INT64_FORMAT, (p-1) * part_size + 1);
+
+ if (p < partition_number)
+ sprintf(maxvalue, INT64_FORMAT, p * part_size + 1);
+ else
+ sprintf(maxvalue, "MAXVALUE");
+
+ snprintf(query, sizeof(query),
+ "create%s table pgbench_accounts_%d\n"
+ " partition of pgbench_accounts\n"
+ " for values from (%s) to (%s)%s\n",
+ unlogged_tables ? " unlogged" : "", p,
+ minvalue, maxvalue, ff);
+ }
+ else if (partition_type == PART_HASH)
+ snprintf(query, sizeof(query),
+ "create%s table pgbench_accounts_%d\n"
+ " partition of pgbench_accounts\n"
+ " for values with (modulus %d, remainder %d)%s\n",
+ unlogged_tables ? " unlogged" : "", p,
+ partition_number, p-1, ff);
+ else /* cannot get there */
+ Assert(0);
+
+ executeStatement(con, query);
+ }
+ }
}
/*
@@ -5126,6 +5200,8 @@ main(int argc, char **argv)
{"foreign-keys", no_argument, NULL, 8},
{"random-seed", required_argument, NULL, 9},
{"show-script", required_argument, NULL, 10},
+ {"partition-number", required_argument, NULL, 11},
+ {"partition-type", required_argument, NULL, 12},
{NULL, 0, NULL, 0}
};
@@ -5486,6 +5562,29 @@ main(int argc, char **argv)
exit(0);
}
break;
+ case 11: /* partition-number */
+ initialization_option_set = true;
+ partition_number = atoi(optarg);
+ if (partition_number < 0)
+ {
+ fprintf(stderr, "invalid number of partitions: \"%s\"\n",
+ optarg);
+ exit(1);
+ }
+ break;
+ case 12: /* partition-type */
+ initialization_option_set = true;
+ if (strcasecmp(optarg, "range") == 0)
+ partition_type = PART_RANGE;
+ else if (strcasecmp(optarg, "hash") == 0)
+ partition_type = PART_HASH;
+ else
+ {
+ fprintf(stderr, "invalid partition type, expecting \"range\" or \"hash\","
+ " got: \"%s\"\n", optarg);
+ exit(1);
+ }
+ break;
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 5a2fdb9acb..0d1fd1f043 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -58,6 +58,18 @@ sub pgbench
return;
}
+# tablespace for testing
+my $ts = $node->basedir . '/regress_pgbench_tap_1_ts_dir';
+mkdir $ts or die "cannot create directory $ts";
+
+# escape
+my $ets = $ts;
+$ets =~ s/'/''/;
+
+$node->safe_psql('postgres',
+ "CREATE TABLESPACE regress_pgbench_tap_1_ts LOCATION '$ets';"
+);
+
# Test concurrent OID generation via pg_enum_oid_index. This indirectly
# exercises LWLock and spinlock concurrency.
my $labels = join ',', map { "'l$_'" } 1 .. 1000;
@@ -98,30 +110,32 @@ pgbench(
],
'pgbench scale 1 initialization',);
-# Again, with all possible options
+# Again, with all possible options but tablespace
pgbench(
- '--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=pg_default --index-tablespace=pg_default',
+ '--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=regress_pgbench_tap_1_ts --index-tablespace=regress_pgbench_tap_1_ts --partition-number=2 --partition-type=hash',
0,
[qr{^$}i],
[
qr{dropping old tables},
qr{creating tables},
+ qr{creating 2 partitions},
qr{vacuuming},
qr{creating primary keys},
qr{creating foreign keys},
qr{(?!vacuuming)}, # no vacuum
qr{done in \d+\.\d\d s }
],
- 'pgbench scale 1 initialization');
+ 'pgbench scale 1 initialization with options');
# Test interaction of --init-steps with legacy step-selection options
pgbench(
- '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables',
+ '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables --partition-number=3',
0,
[qr{^$}],
[
qr{dropping old tables},
qr{creating tables},
+ qr{creating 3 partitions},
qr{creating primary keys},
qr{.* of .* tuples \(.*\) done},
qr{creating foreign keys},
@@ -833,7 +847,6 @@ pgbench(
'pgbench throttling');
pgbench(
-
# given the expected rate and the 2 ms tx duration, at most one is executed
'-t 10 --rate=100000 --latency-limit=1 -n -r',
0,
@@ -909,6 +922,8 @@ pgbench(
check_pgbench_logs($bdir, '001_pgbench_log_3', 1, 10, 10,
qr{^\d \d{1,2} \d+ \d \d+ \d+$});
+$node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts');
+
# done
$node->stop;
done_testing();
diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl
index f7fa18418b..fc6bd2e50e 100644
--- a/src/bin/pgbench/t/002_pgbench_no_server.pl
+++ b/src/bin/pgbench/t/002_pgbench_no_server.pl
@@ -157,6 +157,8 @@ my @options = (
qr{error while setting random seed from --random-seed option}
]
],
+ [ 'bad partition type', '-i --partition-type=BAD', [qr{"range"}, qr{"hash"}, qr{"BAD"}] ],
+ [ 'bad partition number', '-i --partition-number -1', [ qr{invalid number of partitions: "-1"} ] ],
# logging sub-options
[
On Tue, 23 Jul 2019 at 19:26, Fabien COELHO <coelho@cri.ensmp.fr> wrote:
Hello devs,
While doing some performance tests and reviewing patches, I needed to
create partitioned tables. Given the current syntax this is time
consumming.
Good idea. I wonder why we didn't have it already.
The attached patch adds two options to create a partitioned "account"
table in pgbench.It allows to answer quickly simple questions, eg "what is the overhead of
hash partitioning on a simple select on my laptop"? Answer:# N=0..?
sh> pgench -i -s 1 --partition-number=$N --partition-type=hash
Given current naming of options, I would call this
--partitions=number-of-partitions and --partition-method=hash
# then run
sh> pgench -S -M prepared -P 1 -T 10# and look at latency:
# no parts = 0.071 ms
# 1 hash = 0.071 ms (did someone optimize this case?!)
# 2 hash ~ 0.126 ms (+ 0.055 ms)
# 50 hash ~ 0.155 ms
# 100 hash ~ 0.178 ms
# 150 hash ~ 0.232 ms
# 200 hash ~ 0.279 ms
# overhead ~ (0.050 + [0.0005-0.0008] * nparts) ms
It is linear?
--
Simon Riggs http://www.2ndQuadrant.com/
<http://www.2ndquadrant.com/>
PostgreSQL Solutions for the Enterprise
Hello Simon,
While doing some performance tests and reviewing patches, I needed to
create partitioned tables. Given the current syntax this is time
consumming.Good idea. I wonder why we didn't have it already.
Probably because I did not have to create partitioned table for some
testing:-)
sh> pgench -i -s 1 --partition-number=$N --partition-type=hash
Given current naming of options, I would call this
--partitions=number-of-partitions and --partition-method=hash
Ok.
# then run
sh> pgench -S -M prepared -P 1 -T 10# and look at latency:
# no parts = 0.071 ms
# 1 hash = 0.071 ms (did someone optimize this case?!)
# 2 hash ~ 0.126 ms (+ 0.055 ms)
# 50 hash ~ 0.155 ms
# 100 hash ~ 0.178 ms
# 150 hash ~ 0.232 ms
# 200 hash ~ 0.279 ms
# overhead ~ (0.050 + [0.0005-0.0008] * nparts) msIt is linear?
Good question. I would have hoped affine, but this is not very clear on
these data, which are the median of about five runs, hence the bracket on
the slope factor. At least it is increasing with the number of partitions.
Maybe it would be clearer on the minimum of five runs.
--
Fabien.
Attachments:
pgbench-init-partitioned-2.patchtext/x-diff; name=pgbench-init-partitioned-2.patchDownload
diff --git a/doc/src/sgml/ref/pgbench.sgml b/doc/src/sgml/ref/pgbench.sgml
index 816f9cc4c7..3e8e292e39 100644
--- a/doc/src/sgml/ref/pgbench.sgml
+++ b/doc/src/sgml/ref/pgbench.sgml
@@ -306,6 +306,32 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>--partitions=<replaceable>NUM</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table with
+ <replaceable>NUM</replaceable> partitions of nearly equal size for
+ the scaled number of accounts.
+ Default is <literal>0</literal>, meaning no partitioning.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--partition-method=<replaceable>NAME</replaceable></option></term>
+ <listitem>
+ <para>
+ Create a partitioned <literal>pgbench_accounts</literal> table with
+ <replaceable>NAME</replaceable> method.
+ Expected values are <literal>range</literal> or <literal>hash</literal>.
+ This option is only taken into account if
+ <option>--partitions</option> is non-zero.
+ Default is <literal>range</literal>.
+ </para>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><option>--tablespace=<replaceable>tablespace</replaceable></option></term>
<listitem>
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c
index 570cf3306a..6819b4e433 100644
--- a/src/bin/pgbench/pgbench.c
+++ b/src/bin/pgbench/pgbench.c
@@ -186,6 +186,11 @@ int64 latency_limit = 0;
char *tablespace = NULL;
char *index_tablespace = NULL;
+/* partitioning for pgbench_accounts table, 0 for no partitioning */
+int partitions = 0;
+enum { PART_RANGE, PART_HASH }
+ partition_method = PART_RANGE;
+
/* random seed used to initialize base_random_sequence */
int64 random_seed = -1;
@@ -617,6 +622,9 @@ usage(void)
" --foreign-keys create foreign key constraints between tables\n"
" --index-tablespace=TABLESPACE\n"
" create indexes in the specified tablespace\n"
+ " --partitions=NUM partition account table in NUM parts (defaults: 0)\n"
+ " --partition-method=(range|hash)\n"
+ " partition account table with this method (default: range)\n"
" --tablespace=TABLESPACE create tables in the specified tablespace\n"
" --unlogged-tables create tables as unlogged tables\n"
"\nOptions to select what to run:\n"
@@ -3601,6 +3609,17 @@ initDropTables(PGconn *con)
"pgbench_tellers");
}
+/*
+ * add fillfactor percent option if not 100.
+ */
+static void
+append_fillfactor(char *opts, int len)
+{
+ if (fillfactor < 100)
+ snprintf(opts + strlen(opts), len - strlen(opts),
+ " with (fillfactor=%d)", fillfactor);
+}
+
/*
* Create pgbench's standard tables
*/
@@ -3625,6 +3644,7 @@ initCreateTables(PGconn *con)
const char *bigcols; /* column decls if accountIDs are 64 bits */
int declare_fillfactor;
};
+
static const struct ddlinfo DDLs[] = {
{
"pgbench_history",
@@ -3651,11 +3671,10 @@ initCreateTables(PGconn *con)
1
}
};
- int i;
fprintf(stderr, "creating tables...\n");
- for (i = 0; i < lengthof(DDLs); i++)
+ for (int i = 0; i < lengthof(DDLs); i++)
{
char opts[256];
char buffer[256];
@@ -3664,9 +3683,17 @@ initCreateTables(PGconn *con)
/* Construct new create table statement. */
opts[0] = '\0';
- if (ddl->declare_fillfactor)
+
+ /* Partition pgbench_accounts table */
+ if (partitions >= 1 && strcmp(ddl->table, "pgbench_accounts") == 0)
+ {
snprintf(opts + strlen(opts), sizeof(opts) - strlen(opts),
- " with (fillfactor=%d)", fillfactor);
+ " partition by %s (aid)",
+ partition_method == PART_RANGE ? "range" : "hash");
+ }
+ else if (ddl->declare_fillfactor)
+ append_fillfactor(opts, sizeof(opts));
+
if (tablespace != NULL)
{
char *escape_tablespace;
@@ -3686,6 +3713,54 @@ initCreateTables(PGconn *con)
executeStatement(con, buffer);
}
+
+ if (partitions >= 1)
+ {
+ int64 part_size = (naccounts * (int64) scale + partitions - 1) / partitions;
+ char ff[64];
+ ff[0] = '\0';
+ append_fillfactor(ff, sizeof(ff));
+
+ fprintf(stderr, "creating %d partitions...\n", partitions);
+
+ for (int p = 1; p <= partitions; p++)
+ {
+ char query[256];
+
+ if (partition_method == PART_RANGE)
+ {
+ char minvalue[32], maxvalue[32];
+
+ if (p == 1)
+ sprintf(minvalue, "MINVALUE");
+ else
+ sprintf(minvalue, INT64_FORMAT, (p-1) * part_size + 1);
+
+ if (p < partitions)
+ sprintf(maxvalue, INT64_FORMAT, p * part_size + 1);
+ else
+ sprintf(maxvalue, "MAXVALUE");
+
+ snprintf(query, sizeof(query),
+ "create%s table pgbench_accounts_%d\n"
+ " partition of pgbench_accounts\n"
+ " for values from (%s) to (%s)%s\n",
+ unlogged_tables ? " unlogged" : "", p,
+ minvalue, maxvalue, ff);
+ }
+ else if (partition_method == PART_HASH)
+ snprintf(query, sizeof(query),
+ "create%s table pgbench_accounts_%d\n"
+ " partition of pgbench_accounts\n"
+ " for values with (modulus %d, remainder %d)%s\n",
+ unlogged_tables ? " unlogged" : "", p,
+ partitions, p-1, ff);
+ else /* cannot get there */
+ Assert(0);
+
+ executeStatement(con, query);
+ }
+ }
}
/*
@@ -5126,6 +5201,8 @@ main(int argc, char **argv)
{"foreign-keys", no_argument, NULL, 8},
{"random-seed", required_argument, NULL, 9},
{"show-script", required_argument, NULL, 10},
+ {"partitions", required_argument, NULL, 11},
+ {"partition-method", required_argument, NULL, 12},
{NULL, 0, NULL, 0}
};
@@ -5486,6 +5563,29 @@ main(int argc, char **argv)
exit(0);
}
break;
+ case 11: /* partition-number */
+ initialization_option_set = true;
+ partitions = atoi(optarg);
+ if (partitions < 0)
+ {
+ fprintf(stderr, "invalid number of partitions: \"%s\"\n",
+ optarg);
+ exit(1);
+ }
+ break;
+ case 12: /* partition-type */
+ initialization_option_set = true;
+ if (strcasecmp(optarg, "range") == 0)
+ partition_method = PART_RANGE;
+ else if (strcasecmp(optarg, "hash") == 0)
+ partition_method = PART_HASH;
+ else
+ {
+ fprintf(stderr, "invalid partition type, expecting \"range\" or \"hash\","
+ " got: \"%s\"\n", optarg);
+ exit(1);
+ }
+ break;
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 5a2fdb9acb..ef6aafb3f9 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -58,6 +58,18 @@ sub pgbench
return;
}
+# tablespace for testing
+my $ts = $node->basedir . '/regress_pgbench_tap_1_ts_dir';
+mkdir $ts or die "cannot create directory $ts";
+
+# escape
+my $ets = $ts;
+$ets =~ s/'/''/;
+
+$node->safe_psql('postgres',
+ "CREATE TABLESPACE regress_pgbench_tap_1_ts LOCATION '$ets';"
+);
+
# Test concurrent OID generation via pg_enum_oid_index. This indirectly
# exercises LWLock and spinlock concurrency.
my $labels = join ',', map { "'l$_'" } 1 .. 1000;
@@ -98,30 +110,32 @@ pgbench(
],
'pgbench scale 1 initialization',);
-# Again, with all possible options
+# Again, with all possible options but tablespace
pgbench(
- '--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=pg_default --index-tablespace=pg_default',
+ '--initialize --init-steps=dtpvg --scale=1 --unlogged-tables --fillfactor=98 --foreign-keys --quiet --tablespace=regress_pgbench_tap_1_ts --index-tablespace=regress_pgbench_tap_1_ts --partitions=2 --partition-method=hash',
0,
[qr{^$}i],
[
qr{dropping old tables},
qr{creating tables},
+ qr{creating 2 partitions},
qr{vacuuming},
qr{creating primary keys},
qr{creating foreign keys},
qr{(?!vacuuming)}, # no vacuum
qr{done in \d+\.\d\d s }
],
- 'pgbench scale 1 initialization');
+ 'pgbench scale 1 initialization with options');
# Test interaction of --init-steps with legacy step-selection options
pgbench(
- '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables',
+ '--initialize --init-steps=dtpvgvv --no-vacuum --foreign-keys --unlogged-tables --partitions=3',
0,
[qr{^$}],
[
qr{dropping old tables},
qr{creating tables},
+ qr{creating 3 partitions},
qr{creating primary keys},
qr{.* of .* tuples \(.*\) done},
qr{creating foreign keys},
@@ -833,7 +847,6 @@ pgbench(
'pgbench throttling');
pgbench(
-
# given the expected rate and the 2 ms tx duration, at most one is executed
'-t 10 --rate=100000 --latency-limit=1 -n -r',
0,
@@ -909,6 +922,8 @@ pgbench(
check_pgbench_logs($bdir, '001_pgbench_log_3', 1, 10, 10,
qr{^\d \d{1,2} \d+ \d \d+ \d+$});
+$node->safe_psql('postgres', 'DROP TABLESPACE regress_pgbench_tap_1_ts');
+
# done
$node->stop;
done_testing();
diff --git a/src/bin/pgbench/t/002_pgbench_no_server.pl b/src/bin/pgbench/t/002_pgbench_no_server.pl
index f7fa18418b..a097c18ee6 100644
--- a/src/bin/pgbench/t/002_pgbench_no_server.pl
+++ b/src/bin/pgbench/t/002_pgbench_no_server.pl
@@ -157,6 +157,8 @@ my @options = (
qr{error while setting random seed from --random-seed option}
]
],
+ [ 'bad partition type', '-i --partition-method=BAD', [qr{"range"}, qr{"hash"}, qr{"BAD"}] ],
+ [ 'bad partition number', '-i --partitions -1', [ qr{invalid number of partitions: "-1"} ] ],
# logging sub-options
[
# and look at latency:
# no parts = 0.071 ms
# 1 hash = 0.071 ms (did someone optimize this case?!)
# 2 hash ~ 0.126 ms (+ 0.055 ms)
# 50 hash ~ 0.155 ms
# 100 hash ~ 0.178 ms
# 150 hash ~ 0.232 ms
# 200 hash ~ 0.279 ms
# overhead ~ (0.050 + [0.0005-0.0008] * nparts) msIt is linear?
Good question. I would have hoped affine, but this is not very clear on these
data, which are the median of about five runs, hence the bracket on the slope
factor. At least it is increasing with the number of partitions. Maybe it
would be clearer on the minimum of five runs.
Here is a fellow up.
On the minimum of all available runs the query time on hash partitions is
about:
0.64375 nparts + 118.30979 (in ᅵs).
So the overhead is about 47.30979 + 0.64375 nparts, and it is indeed
pretty convincingly linear as suggested by the attached figure.
--
Fabien.
Attachments:
regression.pngimage/png; name=regression.pngDownload
�PNG
IHDR � y `�� pHYs � ��+ tIME�:���� iTXtComment Created with GIMPd.e IDATx����sg~&�o��We��:p /�%����m��mOL���O�c��cc�;;�Y����z��>l�[�$Ro\���++3+���@R�D�p=���
�Y@>�f>�+\[ �A"b
� �&Y { ��
� �
� � �
��X� �� ��#c ��
� �
;�����1��6������Y����l��[YR�x��(�����9�~@ABD$(����,{�VsO|�^� �p@�+��k�O7n�w�s����?�����*O����;�����7�o}�M�.�P��������?_��U��� �}@I�a�s�����y-��,I�0n���.$<gK%c�2)�����;��]��z{��K�����Q���gb�o����R2d]_a{ @@�0p:�A��~����3*d���W������W~�e/�[(Y�'tR"�p����_��\��`&����><y�L�o������|�y��B>����7tEy�� �HV���j���Gze�B��A��?�/?�}���������D,��w��umm�iI����{ri��YQ��[
9W?��v76�S���j�f������[� P�(k����c.�iuVR����Z���r}�U��I�����"�\���;���p��U}�^��4U�I?eV�������w��F�?��$���=�:
�j^V��c��<��H�l&#*E�tL^���7v2�q�P�L����dD���bK����������OyvO�e�2xC � G�38���Ns+����j��VH�% �N���d����*����=l�����9J�/��$I��=Q�w ������H���:�;�w�X��Z�f�����f���AY"�����=���bk��3Y~5D1�dsI|?q������=l���H$<��|��tZ#gA�&��]��lV��r�RI�t�,�Y�2"�$Qp�G
p�����8a� *��$�����1�X@��l^��?���W�]�a����~������|�(K�$��|w�&��_/eT=W7rC)����c�!k���=��'oB�tZ������|����<�����^.���=���`fz�V�$A������H���D�3
Y)�+��/E8*�R H����2���� �YSF&��8�(d���w_�(��l.����0�1C�{�>��qzbg>���4��G����� �4�#"R3Z6�#�#8^�K�8x��4���p4�*Q���.����G�.�~|{������Z���2m��N�;������������0���a�8�}�3Q�����j5�X����������b��x/��;�� !A��+qG#��D�j����|���X���g7����3������R&��(�(�EqE�ht��I���g��lF�Y�f��}&C��S7�Y�9��{N��yWW�|>����;p�e�Y"�uG
G
p���0fr&#�t�.���dU�+�����:�z+���}yog������nf%��$���<z4��&�?jz�vge)o�����=lo�$a� ���G�(����%r����=7�Q�(��zN46b_��0�(I|o4��A���e�Z��2Zn��
�� �M�8�*�a��U�3���$D^����Q&-���e�C����'��n @@!�$��a+f��)k�2�I����:I��eE�Td��,%�.�l�F�a���yU3f���B��mG�X�����Z�Pu��{��e= ���p_�����_�������O~BI����^�~#���:Y�-�������^W���i�2���{�n�m�\? R�����������g����L]V�=m� �7��~�gDI������1T����I������-7,�*��;??y�j�T"Q!���gf..�hses��J7�f�I����h�$U�O.�83[,��io��� ���{/�G���W>]ixL�HJ��ke�����8y����0{�BVv��zy����I�~>X������f���JR�f�Zf�Gs���pv��+n (DD$��Q��w������b��|i����~�x���
U,v,)�>��^�q�K�9��D]"�Zi�v��S�/���W� Pv'g��'�lu���?�����*�mN�Z��c*Q���.����O��#�v���SS9�,��m pD<\�e�j�����D$��"��J/=c|�(�Z9��t��l��G ��$�}8mar1 8pP P P ��>M��� �M�obQ����
�*g�w#( p� � ����; pXNX�xW���% ���A � P P P P P P P ��Pp� �K����,�� /*�0�
� �
� �
���d�i.Ys� ��%�w
#( p� �
���� �))��4N(f�$��5�1� O����� �'b���� #( @D�0%�G|4�����J�)��� "��yl��n4��^���!���>��P �/�9c$4���:#�=d�1O���&������1
�FaB-��l��\�����p�������/?
�q%�
�(�C��F|��~�3�q�,�$l�i�������C@y��� n�W:l��n�X�h��R���`��� �D)����,�|��� v9 ���{:m�o
X��QJFV�Y���T��9U �$$�a}G�=( ��<�����
�p�&M�B^MUP3�GE@ 8����CD�&L��� �d
�H�x���P �t@���N�K�`k��d��v�
������TA4��"�#P ���t4E���|( GG��p����{:
��&�����L����� � ez:19�y���� zO �HFaB;[n���\�g|O ����8Q�p/���|�����1��B9'.LH��p�{:( G.�1FN���l��nt��n�'JR����S-C���� pt<���|8��7�����q3+�����T�D3{��}C@ 8Lv{:�{��N����C�P��sb^����s;
�A�lOg�a����0]�NV��!���NX ��P���9Yy0-��fVE��KF@ 8����3_~�=�}L<( 2����~eY�[ � 9h=�}�
Ay� ��VOg�N[2�� ��q�2
b�y�?`=���
A �)#?��~��6������ p��t��{!w�����]�tP ��������N��e[}�9Uma�|D��A@ 8Lv{:^��c�����=��Ta2/���tP ����z��j����*�L���8a��ZO ����h�x~%I�8�QQdY�U%o����g����cr�������8�
�(R����BY*��tP �����,�m4:��q�����l���d���so#���t���H�,L���R��`��q�z:( DD�8����X_��P����R�+�(
��D�7�����8�3ba���3!����2�
KI{��7�WmN�����7��c$q�������m�tE*���!Z��eHqpP ��b�EQ(����[��~85�4�>c�C����4a� �(���h��V3>F\^ 8����mM0�B�������:m�8_ �G���/Q#( oz:(%c
��p��vF^����rjq2g����+_�z��p��8����gn�R;71����Jg�aDI�
�Nc���c
v[iYC�U-����&� 8���A@y��O�+�����_����y������G�����.����]�p����77�_��M��>��Js����_����X!�|i�\�������q���&5]""�� .������T�j&�F �7��������(�[��W�_����v<����������/&TU�g3�G#"I8�w�m����+���/O�-[�~�^H�A8X�^�������{����S7�R���R�n��Y��q 8�"Q /�6�J���m���h��
I�����|�qY�p�tP���h{����/>_k����vn���
U�A�+����_W~��(�y�U�e���^���>8w�>Ad���x�V��4ZW������3�������� ��ww����/���>+�c�~j� h@H�A ���q�����A"�� �\��q�z7��L��[�P>l=�����d�su����V�/]�P��Q3����}������\t� =>��h��O�����.LY�~gR����������Z���������� A��[
��t��������bM���� ]Sg�k�EIPa���"��le���I]���;0�F��F�y������$�� ��R�j��z�gs��&f��#q�K5����I������I����%���}���{����k������rF�O������Hm8�������O���� �w�T��������f,&��aEI��R���'Fn��~s;m9,J��
K�r����CO�H&2U�T��'>�$
�(`<e��q�cO�CNmxw�����6��l+'
�k����Nf�/J��z1�*����U�R���w:�fwht� ���x7 �}����z��qC>�y�����*9���T���L2z:(��m���s��s3o=x>��q�����_���_�Z�(���s�j������9�o'�av�dub�fjO6��8�M'V/H<��M G�nOg8��Zl���Um��%M���!Z���I<����}��^>B�P Q��;w��w�#90m��s�"�O�)�V������%uw&�(l��8b��Z9j'�p���D
5[3������I��b*�*�^��q���>y����v��0H���u���E{rrR������<��}�?�7p��x��q*�������w����A��r[�&TqBu�xL���0��g���J@���WW>]]����
Zyv�:1Y}z�#71{v�����~ZWn�]���~����M��e��f-�}w���$I���2����sCY��t�y��S��M(�v�W������v���~%c��s���b�e�����~��`r]��Cp���q"�i�S�U?&U�r��fE��Z$$.�B�9������IJ�������"/�V��;w���v�g����fk����g�Z�6���&�����K���
�W�e�z/]�����K�jUdq�Q��s�K3J6�d
AJ�8�bb�������� �z6���|���|
���1�%�hUC��RN!��1���_�����s���������1-�|�����5����U���������f���|'U�r��3�������ya��-��^��D�G�����A��%�(��A�T����k��X������a�!8RpL�W�����m����&�����R�DK�z��2�����#���q�$I������v�,�ll\�y���MG�r����'��E���eY�������sY#W�36ckQ�EQ��(���*�$�#�FQ�D����8��p�OmQT���dH|r�A�0
�9�������M���|.�;k���g�0p�p��h�'z:����������0����]O'JX6��(�����H��$.�w���������B�����s�OU�����E�����YI^�����K�� ��8�F
o�I� Y�M#c�$c�@ ���X�t��~ReDI����/6o]Y����'*��/\�4W?W3s��OH�3�ik�n��A:bGPv�1I|�q|?HUC�lC�
Ix7 �O����3b[6�9�di�t^��z:(���"r����g����'���A�d���N~������cw��}�|=#m�H}���������l�u�Pe��M) p<��N���X���-�M���� ��j>S�tvV�o��v��Ylzn����K�S�'�>y�y0AB�6+e��J
�����(I�i�E�Td�$���f��y�D��������HNz������X3����z��t�
���`=��;�y�=z���,
EC�.�s%��c=����uk�q����J����Kg&�,���O��F���iy�S�k���X�B��+�;+����PKS���z��T����Z�ONk���j�nh��fN����7�^��9v<{��S����9S�
�a�l��
�V��h�;#�2�����\���.�T�P���k����`�^�j����[��KQ������aL��L�i9;_�X�f� �����m��o���C�B�h�_���ZoT\���-��:W5sY"Q!���gf/.v����=�*����&�������j��N�X�-u, p�q��(!/��1��|�a]�� Y�����&D����k����?��"��������~���e�d�M��,}�g�����9�U3��;�Vo�������?�����ke�����?���\�=U��E&2�����i�}>X�r�w��j��������zf����s����� ���8%��>_i��{�1`�tA�N�eS(������|���5��S�%6�T��]*v3��~�;��!*���������NU��`��HQ� �xo����3�ns����K��K�9}ain���x \q�����|�vys��cND�&L���X4D]�� ����i����N��'
���^��eC6ecZ_����Y���G����91kY���<�Yd-�&-�,�� �@bj�z7��b^�m]���T^�0��&����9����M�6U{���_���(�].Py��= ���z:;�q�8��DEC�)�e�h�r
�;�xO�5b�SN�f�JN�u!�
&�^C@ x����RN���0!V-�tP ��o���l��
���������q2b��?��� oz:o����� �=�#
�tP �t�a?�K�qC
�z:n��c�CO�]&�}( ��nO����mv����L��9�P ���S>�����;.o�0= �}4����mt�J+������X���)���� ����')��=�o;�5bAL�DeS�-Jse1��r
�;���|���i�e�H�&\��',!��*��
���xOg����v�����QN���P+9�tP ��'z:=�r�$�tA��b����S��A@ xW�����L(��%i�(�uA�`��"�� <����TA���eS�4ASE�N��s����d�K ����`"$<��~�FP `��( pP0NaB�'>COP `�qR.|v?H�Q�� � �~�S�G�5�M'��@B�� � ���#��c����-=H�dIFOP `��G)�#>
x���!k�X���,��( �?��>�������1I�Br��O����V)���
����� ����3b��{<e�����m�&rb�"c'�� ����tno��>��L���X��rN�0�����W�vJ2���G���H����+�eaR��A�eHT�yUW� �����(��1o�xs�F�D*���8U���B�aW�[
(a��W:��7�Y2��7o�*����.�w;��o��(S��������M��x ������u�j;
^2���X���)��=���p���m)�����(����i8�[���n����ui�h(Q�����p��h�s~�pb 8z�����t&r�lI�-���{M�����$D��Y^���-��g���=�M>!Y]}�OD�+�Ne����7�����Q x[����u����DN�5!��t�����q$���d<�QQ!���*�zq�f���w( �����N�OU���(�$����?T��Ey���F�����������^N�UK-NZ�Y60A%r IDAT� pD���S�Sd�N�]�HQ��bT
D'�� �����`=��� ����t �;����w��F�q���WSL!W�l{*�Z� �z��q������������������������m"��M����������r��a ��g����c������,���P����?���7�Qb�� A �s�(Lh���;.�����\=8�%���b
������w���'j���%�k �CP� �F��v�5`�+2�(�UK,�b=8�E)��|��-3g/�NO�2FQ �(�~���|�v�����K"t�DI�.��*d���P�U�2�N�=����R�'S'R�S -?�k��M7�,N��NU��%M�R]d�t��""J���ht�{W':;���- ����N�e���<JI�P�gK�t^����CP�1��F�n�^�jm����5��.��� p�=����<+S�OW��)�u��
z:p�
�D���'*]�d
p�������y���XFOe@�����wN���;~��m�� 8���z:�X���d���CPd�d����}g8�l9�OD�nj��h��ITr��nkY�i ��=8�eW���������\^^:w������2�n�7�����}0kk���~�`���#����rw-�N�smmuy��8�������"f)���7��9%���!�g `��������Lu���������k��.������i��B�Ty�����/]w��N/�
fH��� �z:p�N[��?q���G����i�����u�KH���^�s������x���TP ����N��h�>�z���a�(�3�����O���D1W��C�d�Q)C�MY����Gq� �������n6��>s�<�AO��u�j�������4)�v+ �w)J��Q��>o�������z:pL��I���+�6l_:���h:�����~�j��0oXeP� xG���t�z'������%.���%
�t�8Y%������F�wVo�B�n�e�/l-�[i���z~�j�Y ��(a<J���h��.��������P��%��s*FM�X��S�y�����|�����;�;IgD$�+�X3�3��:s����u�l"� �EQB=�mt��F:s#+�lM�0��.���f����1KJV/����F�3����k�AS�������B��-�� ��=�����3��C6s"�5a*/.LH%S@O�Y@������z�/g����^�G�,�8iY; xk���Nc�FW3t�*U-�d
�&����
(�F�f���$v&