mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Limit pgbench COPY FREEZE to ordinary relations
pgbench client-side data generation uses COPY FREEZE to load data for most tables. COPY FREEZE isn't supported for partitioned tables and since pgbench only supports partitioning pgbench_accounts, pgbench used a hard-coded check to skip COPY FREEZE and use plain COPY for a partitioned pgbench_accounts. If the user has manually partitioned one of the other pgbench tables, this causes client-side data generation to error out with: ERROR: cannot perform COPY FREEZE on a partitioned table Fix this by limiting COPY FREEZE to ordinary tables (RELKIND_RELATION). Author: Sergey Tatarintsev <s.tatarintsev@postgrespro.ru> Reviewed-by: Álvaro Herrera <alvherre@alvh.no-ip.org> Discussion: https://postgr.es/m/flat/97f55fca-8a7b-4da8-b413-7d1c57010676%40postgrespro.ru
This commit is contained in:
@ -231,11 +231,10 @@ pgbench <optional> <replaceable>options</replaceable> </optional> <replaceable>d
|
|||||||
sent to the server. This uses the client/server bandwidth
|
sent to the server. This uses the client/server bandwidth
|
||||||
extensively through a <command>COPY</command>.
|
extensively through a <command>COPY</command>.
|
||||||
<command>pgbench</command> uses the <option>FREEZE</option> option
|
<command>pgbench</command> uses the <option>FREEZE</option> option
|
||||||
with version 14 or later
|
to load data into ordinary (non-partition) tables with version 14
|
||||||
of <productname>PostgreSQL</productname> to speed up
|
or later of <productname>PostgreSQL</productname> to speed up
|
||||||
subsequent <command>VACUUM</command>, except on the
|
subsequent <command>VACUUM</command>.
|
||||||
<literal>pgbench_accounts</literal> table if partitions are
|
Using <literal>g</literal> causes logging to
|
||||||
enabled. Using <literal>g</literal> causes logging to
|
|
||||||
print one message every 100,000 rows while generating data for all
|
print one message every 100,000 rows while generating data for all
|
||||||
tables.
|
tables.
|
||||||
</para>
|
</para>
|
||||||
|
@ -53,6 +53,7 @@
|
|||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "catalog/pg_class_d.h"
|
||||||
#include "common/int.h"
|
#include "common/int.h"
|
||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/pg_prng.h"
|
#include "common/pg_prng.h"
|
||||||
@ -848,6 +849,31 @@ static const PsqlScanCallbacks pgbench_callbacks = {
|
|||||||
NULL, /* don't need get_variable functionality */
|
NULL, /* don't need get_variable functionality */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char
|
||||||
|
get_table_relkind(PGconn *con, const char *table)
|
||||||
|
{
|
||||||
|
PGresult *res;
|
||||||
|
char *val;
|
||||||
|
char relkind;
|
||||||
|
const char *params[1] = {table};
|
||||||
|
const char *sql =
|
||||||
|
"SELECT relkind FROM pg_catalog.pg_class WHERE oid=$1::pg_catalog.regclass";
|
||||||
|
|
||||||
|
res = PQexecParams(con, sql, 1, NULL, params, NULL, NULL, 0);
|
||||||
|
if (PQresultStatus(res) != PGRES_TUPLES_OK)
|
||||||
|
{
|
||||||
|
pg_log_error("query failed: %s", PQerrorMessage(con));
|
||||||
|
pg_log_error_detail("Query was: %s", sql);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
val = PQgetvalue(res, 0, 0);
|
||||||
|
Assert(strlen(val) == 1);
|
||||||
|
relkind = val[0];
|
||||||
|
PQclear(res);
|
||||||
|
|
||||||
|
return relkind;
|
||||||
|
}
|
||||||
|
|
||||||
static inline pg_time_usec_t
|
static inline pg_time_usec_t
|
||||||
pg_time_now(void)
|
pg_time_now(void)
|
||||||
{
|
{
|
||||||
@ -4962,16 +4988,11 @@ initPopulateTable(PGconn *con, const char *table, int64 base,
|
|||||||
|
|
||||||
initPQExpBuffer(&sql);
|
initPQExpBuffer(&sql);
|
||||||
|
|
||||||
/*
|
/* Use COPY with FREEZE on v14 and later for all ordinary tables */
|
||||||
* Use COPY with FREEZE on v14 and later for all the tables except
|
if ((PQserverVersion(con) >= 140000) &&
|
||||||
* pgbench_accounts when it is partitioned.
|
get_table_relkind(con, table) == RELKIND_RELATION)
|
||||||
*/
|
copy_statement_fmt = "copy %s from stdin with (freeze on)";
|
||||||
if (PQserverVersion(con) >= 140000)
|
|
||||||
{
|
|
||||||
if (strcmp(table, "pgbench_accounts") != 0 ||
|
|
||||||
partitions == 0)
|
|
||||||
copy_statement_fmt = "copy %s from stdin with (freeze on)";
|
|
||||||
}
|
|
||||||
|
|
||||||
n = pg_snprintf(copy_statement, sizeof(copy_statement), copy_statement_fmt, table);
|
n = pg_snprintf(copy_statement, sizeof(copy_statement), copy_statement_fmt, table);
|
||||||
if (n >= sizeof(copy_statement))
|
if (n >= sizeof(copy_statement))
|
||||||
|
Reference in New Issue
Block a user