diff options
Diffstat (limited to 'src/bin/pgbench/pgbench.c')
-rw-r--r-- | src/bin/pgbench/pgbench.c | 172 |
1 files changed, 90 insertions, 82 deletions
diff --git a/src/bin/pgbench/pgbench.c b/src/bin/pgbench/pgbench.c index 02f250f5119..79c0cd374d3 100644 --- a/src/bin/pgbench/pgbench.c +++ b/src/bin/pgbench/pgbench.c @@ -277,9 +277,9 @@ bool progress_timestamp = false; /* progress report with Unix time */ int nclients = 1; /* number of clients */ int nthreads = 1; /* number of threads */ bool is_connect; /* establish connection for each transaction */ -bool report_per_command = false; /* report per-command latencies, retries - * after errors and failures (errors - * without retrying) */ +bool report_per_command = false; /* report per-command latencies, + * retries after errors and failures + * (errors without retrying) */ int main_pid; /* main process id used in log filename */ /* @@ -302,8 +302,8 @@ int main_pid; /* main process id used in log filename */ */ uint32 max_tries = 1; -bool failures_detailed = false; /* whether to group failures in reports - * or logs by basic types */ +bool failures_detailed = false; /* whether to group failures in + * reports or logs by basic types */ const char *pghost = NULL; const char *pgport = NULL; @@ -349,8 +349,8 @@ typedef struct /* * The maximum number of variables that we can currently store in 'vars' - * without having to reallocate more space. We must always have max_vars >= - * nvars. + * without having to reallocate more space. We must always have max_vars + * >= nvars. */ int max_vars; @@ -390,17 +390,17 @@ typedef struct StatsData { pg_time_usec_t start_time; /* interval start time, for aggregates */ - /* - * Transactions are counted depending on their execution and outcome. First - * a transaction may have started or not: skipped transactions occur under - * --rate and --latency-limit when the client is too late to execute them. - * Secondly, a started transaction may ultimately succeed or fail, possibly - * after some retries when --max-tries is not one. Thus + /*---------- + * Transactions are counted depending on their execution and outcome. + * First a transaction may have started or not: skipped transactions occur + * under --rate and --latency-limit when the client is too late to execute + * them. Secondly, a started transaction may ultimately succeed or fail, + * possibly after some retries when --max-tries is not one. Thus * * the number of all transactions = * 'skipped' (it was too late to execute them) + * 'cnt' (the number of successful transactions) + - * failed (the number of failed transactions). + * 'failed' (the number of failed transactions). * * A successful transaction can have several unsuccessful tries before a * successful run. Thus @@ -419,11 +419,11 @@ typedef struct StatsData * failed (the number of failed transactions) = * 'serialization_failures' (they got a serialization error and were not * successfully retried) + - * 'deadlock_failures' (they got a deadlock error and were not successfully - * retried). + * 'deadlock_failures' (they got a deadlock error and were not + * successfully retried). * - * If the transaction was retried after a serialization or a deadlock error - * this does not guarantee that this retry was successful. Thus + * If the transaction was retried after a serialization or a deadlock + * error this does not guarantee that this retry was successful. Thus * * 'retries' (number of retries) = * number of retries in all retried transactions = @@ -433,18 +433,20 @@ typedef struct StatsData * 'retried' (number of all retried transactions) = * successfully retried transactions + * failed transactions. + *---------- */ int64 cnt; /* number of successful transactions, not * including 'skipped' */ int64 skipped; /* number of transactions skipped under --rate * and --latency-limit */ - int64 retries; /* number of retries after a serialization or a - * deadlock error in all the transactions */ - int64 retried; /* number of all transactions that were retried - * after a serialization or a deadlock error - * (perhaps the last try was unsuccessful) */ - int64 serialization_failures; /* number of transactions that were not - * successfully retried after a + int64 retries; /* number of retries after a serialization or + * a deadlock error in all the transactions */ + int64 retried; /* number of all transactions that were + * retried after a serialization or a deadlock + * error (perhaps the last try was + * unsuccessful) */ + int64 serialization_failures; /* number of transactions that were + * not successfully retried after a * serialization error */ int64 deadlock_failures; /* number of transactions that were not * successfully retried after a deadlock @@ -559,16 +561,15 @@ typedef enum * States for failed commands. * * If the SQL/meta command fails, in CSTATE_ERROR clean up after an error: - * - clear the conditional stack; - * - if we have an unterminated (possibly failed) transaction block, send - * the rollback command to the server and wait for the result in - * CSTATE_WAIT_ROLLBACK_RESULT. If something goes wrong with rolling back, - * go to CSTATE_ABORTED. + * (1) clear the conditional stack; (2) if we have an unterminated + * (possibly failed) transaction block, send the rollback command to the + * server and wait for the result in CSTATE_WAIT_ROLLBACK_RESULT. If + * something goes wrong with rolling back, go to CSTATE_ABORTED. * - * But if everything is ok we are ready for future transactions: if this is - * a serialization or deadlock error and we can re-execute the transaction - * from the very beginning, go to CSTATE_RETRY; otherwise go to - * CSTATE_FAILURE. + * But if everything is ok we are ready for future transactions: if this + * is a serialization or deadlock error and we can re-execute the + * transaction from the very beginning, go to CSTATE_RETRY; otherwise go + * to CSTATE_FAILURE. * * In CSTATE_RETRY report an error, set the same parameters for the * transaction execution as in the previous tries and process the first @@ -622,7 +623,7 @@ typedef struct int command; /* command number in script */ /* client variables */ - Variables variables; + Variables variables; /* various times about current transaction in microseconds */ pg_time_usec_t txn_scheduled; /* scheduled start time of transaction */ @@ -633,19 +634,20 @@ typedef struct bool prepared[MAX_SCRIPTS]; /* whether client prepared the script */ /* - * For processing failures and repeating transactions with serialization or - * deadlock errors: + * For processing failures and repeating transactions with serialization + * or deadlock errors: */ - EStatus estatus; /* the error status of the current transaction - * execution; this is ESTATUS_NO_ERROR if there were - * no errors */ - pg_prng_state random_state; /* random state */ - uint32 tries; /* how many times have we already tried the + EStatus estatus; /* the error status of the current transaction + * execution; this is ESTATUS_NO_ERROR if + * there were no errors */ + pg_prng_state random_state; /* random state */ + uint32 tries; /* how many times have we already tried the * current transaction? */ /* per client collected stats */ - int64 cnt; /* client transaction count, for -t; skipped and - * failed transactions are also counted here */ + int64 cnt; /* client transaction count, for -t; skipped + * and failed transactions are also counted + * here */ } CState; /* @@ -771,7 +773,7 @@ static ParsedScript sql_script[MAX_SCRIPTS]; /* SQL script files */ static int num_scripts; /* number of scripts in sql_script[] */ static int64 total_weight = 0; -static bool verbose_errors = false; /* print verbose messages of all errors */ +static bool verbose_errors = false; /* print verbose messages of all errors */ /* Builtin test scripts */ typedef struct BuiltinScript @@ -3050,7 +3052,7 @@ commandError(CState *st, const char *message) { Assert(sql_script[st->use_file].commands[st->command]->type == SQL_COMMAND); pg_log_info("client %d got an error in command %d (SQL) of script %d; %s", - st->id, st->command, st->use_file, message); + st->id, st->command, st->use_file, message); } /* return a script number with a weighted choice. */ @@ -3289,8 +3291,8 @@ readCommandResponse(CState *st, MetaCommand meta, char *varprefix) case PGRES_NONFATAL_ERROR: case PGRES_FATAL_ERROR: - st->estatus = getSQLErrorStatus( - PQresultErrorField(res, PG_DIAG_SQLSTATE)); + st->estatus = getSQLErrorStatus(PQresultErrorField(res, + PG_DIAG_SQLSTATE)); if (canRetryError(st->estatus)) { if (verbose_errors) @@ -3397,13 +3399,15 @@ doRetry(CState *st, pg_time_usec_t *now) Assert(max_tries || latency_limit || duration > 0); /* - * We cannot retry the error if we have reached the maximum number of tries. + * We cannot retry the error if we have reached the maximum number of + * tries. */ if (max_tries && st->tries >= max_tries) return false; /* - * We cannot retry the error if we spent too much time on this transaction. + * We cannot retry the error if we spent too much time on this + * transaction. */ if (latency_limit) { @@ -3432,14 +3436,15 @@ discardUntilSync(CState *st) if (!PQpipelineSync(st->con)) { pg_log_error("client %d aborted: failed to send a pipeline sync", - st->id); + st->id); return 0; } /* receive PGRES_PIPELINE_SYNC and null following it */ - for(;;) + for (;;) { - PGresult *res = PQgetResult(st->con); + PGresult *res = PQgetResult(st->con); + if (PQresultStatus(res) == PGRES_PIPELINE_SYNC) { PQclear(res); @@ -3484,9 +3489,10 @@ getTransactionStatus(PGconn *con) /* fall through */ case PQTRANS_ACTIVE: default: + /* - * We cannot find out whether we are in a transaction block or not. - * Internal error which should never occur. + * We cannot find out whether we are in a transaction block or + * not. Internal error which should never occur. */ pg_log_error("unexpected transaction status %d", tx_status); return TSTATUS_OTHER_ERROR; @@ -3513,8 +3519,8 @@ printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry) printfPQExpBuffer(buf, "client %d ", st->id); appendPQExpBuffer(buf, "%s", (is_retry ? - "repeats the transaction after the error" : - "ends the failed transaction")); + "repeats the transaction after the error" : + "ends the failed transaction")); appendPQExpBuffer(buf, " (try %u", st->tries); /* Print max_tries if it is not unlimitted. */ @@ -3522,8 +3528,8 @@ printVerboseErrorMessages(CState *st, pg_time_usec_t *now, bool is_retry) appendPQExpBuffer(buf, "/%u", max_tries); /* - * If the latency limit is used, print a percentage of the current transaction - * latency from the latency limit. + * If the latency limit is used, print a percentage of the current + * transaction latency from the latency limit. */ if (latency_limit) { @@ -3619,8 +3625,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) /* * It is the first try to run this transaction. Remember the - * random state: maybe it will get an error and we will need to - * run it again. + * random state: maybe it will get an error and we will need + * to run it again. */ st->random_state = st->cs_func_rs; @@ -3998,8 +4004,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) } /* - * Check if we have a (failed) transaction block or not, and - * roll it back if any. + * Check if we have a (failed) transaction block or not, + * and roll it back if any. */ tstatus = getTransactionStatus(st->con); if (tstatus == TSTATUS_IN_BLOCK) @@ -4017,9 +4023,9 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) else if (tstatus == TSTATUS_IDLE) { /* - * If time is over, we're done; - * otherwise, check if we can retry the error. - */ + * If time is over, we're done; otherwise, check if we + * can retry the error. + */ st->state = timer_exceeded ? CSTATE_FINISHED : doRetry(st, &now) ? CSTATE_RETRY : CSTATE_FAILURE; } @@ -4039,7 +4045,7 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) */ case CSTATE_WAIT_ROLLBACK_RESULT: { - PGresult *res; + PGresult *res; pg_log_debug("client %d receiving", st->id); if (!PQconsumeInput(st->con)) @@ -4050,7 +4056,7 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) break; } if (PQisBusy(st->con)) - return; /* don't have the whole result yet */ + return; /* don't have the whole result yet */ /* * Read and discard the query result; @@ -4066,8 +4072,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) Assert(res == NULL); /* - * If time is over, we're done; - * otherwise, check if we can retry the error. + * If time is over, we're done; otherwise, check + * if we can retry the error. */ st->state = timer_exceeded ? CSTATE_FINISHED : doRetry(st, &now) ? CSTATE_RETRY : CSTATE_FAILURE; @@ -4089,7 +4095,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) command = sql_script[st->use_file].commands[st->command]; /* - * Inform that the transaction will be retried after the error. + * Inform that the transaction will be retried after the + * error. */ if (verbose_errors) printVerboseErrorMessages(st, &now, true); @@ -4099,8 +4106,8 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) command->retries++; /* - * Reset the random state as they were at the beginning - * of the transaction. + * Reset the random state as they were at the beginning of the + * transaction. */ st->cs_func_rs = st->random_state; @@ -4188,8 +4195,9 @@ advanceConnectionState(TState *thread, CState *st, StatsData *agg) st->state = CSTATE_CHOOSE_SCRIPT; /* - * Ensure that we always return on this point, so as to avoid - * an infinite loop if the script only contains meta commands. + * Ensure that we always return on this point, so as to + * avoid an infinite loop if the script only contains meta + * commands. */ return; } @@ -4518,10 +4526,10 @@ doLog(TState *thread, CState *st, lag_max = agg->lag.max; } fprintf(logfile, " %.0f %.0f %.0f %.0f", - lag_sum, - lag_sum2, - lag_min, - lag_max); + lag_sum, + lag_sum2, + lag_min, + lag_max); if (latency_limit) skipped = agg->skipped; @@ -4588,7 +4596,7 @@ processXactStats(TState *thread, CState *st, pg_time_usec_t *now, double latency = 0.0, lag = 0.0; bool detailed = progress || throttle_delay || latency_limit || - use_log || per_script_stats; + use_log || per_script_stats; if (detailed && !skipped && st->estatus == ESTATUS_NO_ERROR) { @@ -4838,7 +4846,7 @@ initGenerateDataClientSide(PGconn *con) PGresult *res; int i; int64 k; - char *copy_statement; + char *copy_statement; /* used to track elapsed time and estimate of the remaining time */ pg_time_usec_t start; @@ -6365,7 +6373,7 @@ printResults(StatsData *total, StatsData *sstats = &sql_script[i].stats; int64 script_failures = getFailures(sstats); int64 script_total_cnt = - sstats->cnt + sstats->skipped + script_failures; + sstats->cnt + sstats->skipped + script_failures; printf("SQL script %d: %s\n" " - weight: %d (targets %.1f%% of total)\n" |