pgbench#
pgbench
pgbench — запустить тест производительности на Tantor BE
Синтаксис
pgbench
-i
[option
...] [dbname
]
pgbench
[option
...] [dbname
]
Описание
pgbench - это простая программа для запуска
тестов производительности на Tantor BE. Она выполняет одну и ту же последовательность SQL
команд снова и снова, возможно, в нескольких параллельных сессиях базы данных,
а затем вычисляет среднюю скорость транзакций (транзакций в секунду).
По умолчанию pgbench тестирует сценарий, который
в общих чертах основан на TPC-B и включает пять команд SELECT
,
UPDATE
и INSERT
на каждую транзакцию.
Однако, легко можно протестировать и другие случаи, написав свои собственные файлы
сценариев транзакций.
Типичный вывод от pgbench выглядит так:
transaction type: <builtin: TPC-B (sort of)> scaling factor: 10 query mode: simple number of clients: 10 number of threads: 1 maximum number of tries: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 number of failed transactions: 0 (0.000%) latency average = 11.013 ms latency stddev = 7.351 ms initial connection time = 45.758 ms tps = 896.967014 (without initial connection time)
Первые семь строк отчета содержат некоторые из наиболее важных настроек параметров.
Шестая строка отчета содержит максимальное количество попыток для транзакций с ошибками сериализации или блокировки (см. Failures and Serialization/Deadlock Retries для получения дополнительной информации).
Восьмая строка отчета содержит количество завершенных и запланированных транзакций (последнее является просто произведением количества клиентов и количества транзакций на клиента); они будут равными, если выполнение завершилось успешно или если не было выполнено ни одной SQL-команды. (В режиме -T
выводится только фактическое количество транзакций).
Следующая строка отчета содержит количество неудачных транзакций из-за ошибок сериализации или блокировки (см. Failures and Serialization/Deadlock Retries для получения дополнительной информации).
Последняя строка отчета содержит количество транзакций в секунду.
Для выполнения теста транзакций TPC-B по умолчанию необходимо предварительно настроить определенные таблицы. pgbench должен быть вызван с опцией -i
(initialize), чтобы создать и заполнить эти таблицы. (Если вы тестируете собственный скрипт, вам не понадобится этот шаг, но вместо этого вам потребуется выполнить все необходимые настройки для вашего теста). Процесс инициализации выглядит следующим образом:
pgbench -i [other-options
]dbname
где dbname
- это имя уже созданной базы данных для тестирования. (Возможно, вам также понадобятся опции -h
, -p
и/или -U
для указания способа подключения к серверу баз данных).
Предостережение
pgbench -i
создает четыре таблицы pgbench_accounts
,
pgbench_branches
, pgbench_history
и
pgbench_tellers
,
уничтожая любые существующие таблицы с такими именами.
Будьте очень осторожны, используйте другую базу данных, если у вас есть таблицы с такими
именами!
При стандартном “коэффициенте масштабирования” равном 1, таблицы изначально содержат следующее количество строк:
table # of rows --------------------------------- pgbench_branches 1 pgbench_tellers 10 pgbench_accounts 100000 pgbench_history 0
Вы можете (и, скорее всего, должны) увеличить количество строк, используя опцию -s
(масштабный коэффициент). Опцию -F
(fillfactor) также можно использовать в этом случае.
После выполнения необходимой настройки вы можете запустить свой бенчмарк с помощью команды, которая не включает -i
, то есть
pgbench [options
]dbname
В почти всех случаях вам понадобятся некоторые параметры, чтобы создать полезный тест.
Самые важные параметры - это -c
(количество клиентов),
-t
(количество транзакций), -T
(ограничение по времени),
и -f
(указать пользовательский файл сценария).
См. ниже полный список.
Опции
Следующий текст разделен на три подраздела. Различные параметры используются при инициализации базы данных и при выполнении бенчмарков, но некоторые параметры полезны в обоих случаях.
Опции инициализации
pgbench принимает следующие аргументы командной строки для инициализации:
dbname
#Указывает имя базы данных для тестирования. Если это не указано, используется переменная среды
PGDATABASE
. Если она не установлена, используется имя пользователя, указанное для подключения.-i
--initialize
#Необходимо вызвать режим инициализации.
-I
init_steps
--init-steps=
#init_steps
Выполняйте только выбранный набор обычных шагов инициализации.
init_steps
указывает шаги инициализации, которые должны быть выполнены, используя один символ для каждого шага. Каждый шаг вызывается в указанном порядке. По умолчанию используетсяdtgvp
. Доступные шаги:d
(Drop) #Удалите все существующие таблицы pgbench.
t
(create Tables) #Создайте таблицы, используемые в стандартном сценарии pgbench, а именно
pgbench_accounts
,pgbench_branches
,pgbench_history
иpgbench_tellers
.g
orG
(Generate data, client-side or server-side) #Сгенерируйте данные и загрузите их в стандартные таблицы, заменив любые уже существующие данные.
С использованием
g
(генерация данных на стороне клиента), данные генерируются в клиентеpgbench
и затем отправляются на сервер. Это интенсивно использует пропускную способность клиента/сервера черезCOPY
.pgbench
использует опцию FREEZE с версии 14 или более поздней PostgreSQL для ускорения последующегоVACUUM
, если включены разделы. Использованиеg
приводит к печати одного сообщения каждые 100 000 строк при генерации данных для таблицыpgbench_accounts
.С использованием
G
(генерация данных на стороне сервера) отправляются только небольшие запросы от клиентаpgbench
, а затем данные фактически генерируются на сервере. Для этого варианта не требуется значительная пропускная способность, но сервер будет выполнять больше работы. ИспользованиеG
приводит к тому, что при генерации данных не выводится никаких сообщений о прогрессе в журнале.По умолчанию используется поведение инициализации, основанное на генерации данных на стороне клиента (эквивалентно
g
).v
(Vacuum) #Выполните
VACUUM
на стандартных таблицах.p
(create Primary keys) #Создайте индексы первичных ключей на стандартных таблицах.
f
(create Foreign keys) #Создайте внешние ключи между стандартными таблицами. (Обратите внимание, что этот шаг не выполняется по умолчанию).
-F
fillfactor
--fillfactor=
fillfactor
#Создайте таблицы
pgbench_accounts
,pgbench_tellers
иpgbench_branches
с заданным fillfactor. По умолчанию равен 100.-n
--no-vacuum
#Не выполнять очистку во время инициализации. (Этот параметр подавляет шаг инициализации
v
, даже если он был указан в-I
).-q
--quiet
#Переключите режим журналирования в тихий режим, выводя только одно сообщение о прогрессе каждые 5 секунд. По умолчанию ведение журнала печатает одно сообщение для каждых 100 000 строк, что часто приводит к выводу множества строк в секунду (особенно на хорошем оборудовании).
Эта настройка не имеет эффекта, если
G
указано в-I
.-s
scale_factor
--scale=
scale_factor
#Умножьте количество генерируемых строк на коэффициент масштабирования. Например,
-s 100
создаст 10 000 000 строк в таблицеpgbench_accounts
. Значение по умолчанию - 1. Когда масштаб достигает 20 000 или больше, столбцы, используемые для хранения идентификаторов учетных записей (столбцыaid
), переключаются на использование более крупных целых чисел (bigint
), чтобы быть достаточно большими для хранения диапазона идентификаторов учетных записей.--foreign-keys
#Создайте внешние ключевые ограничения между стандартными таблицами. (Этот параметр добавляет шаг
f
к последовательности шагов инициализации, если он еще не присутствует).--index-tablespace=
#index_tablespace
Создавайте индексы в указанном табличном пространстве, а не в табличном пространстве по умолчанию.
--partition-method=
#NAME
Создайте секционированную таблицу
pgbench_accounts
с методомNAME
. Ожидаемые значения:range
илиhash
. Для этой опции требуется, чтобы--partitions
было установлено на ненулевое значение. Если не указано, используется значение по умолчанию -range
.--partitions=
#NUM
Создайте секционированную таблицу
pgbench_accounts
сNUM
секциями примерно одинакового размера для масштабированного количества учетных записей. По умолчанию0
, что означает отсутствие секционирования.--tablespace=
#tablespace
Создавайте таблицы в указанном табличном пространстве, а не в табличном пространстве по умолчанию.
--unlogged-tables
#Создайте все таблицы как незарегистрированные таблицы, а не постоянные таблицы.
Опции для тестирования производительности
pgbench принимает следующие аргументы командной строки для проведения бенчмарков:
-b
scriptname[@weight]
--builtin
=scriptname[@weight]
#Добавьте указанный встроенный сценарий в список сценариев для выполнения. Доступные встроенные сценарии:
tpcb-like
,simple-update
иselect-only
. Префиксы встроенных имен без неоднозначности принимаются. С помощью специального имениlist
показывается список встроенных сценариев и немедленно завершается выполнение.При желании, после
@
можно указать целочисленный вес, чтобы настроить вероятность выбора этого сценария по сравнению с другими. По умолчанию вес равен 1. Подробности см. ниже.-c
clients
--client=
clients
#Количество имитируемых клиентов, то есть количество одновременных сессий работы с базой данных. По умолчанию - 1.
-C
--connect
#Устанавливайте новое соединение для каждой транзакции, а не только один раз для каждой сессии клиента. Это полезно для измерения издержек на соединение.
-d
--debug
#Вывод отладочной информации.
-D
varname
=
value
--define=
varname
=
value
#Определите переменную для использования в пользовательском скрипте (см. ниже). Разрешается использование нескольких параметров
-D
.-f
filename[@weight]
--file=
filename[@weight]
#Добавьте транзакционный скрипт, прочитанный из
filename
, в список скриптов, которые будут выполнены.При желании, после
@
можно указать целочисленный вес, чтобы настроить вероятность выбора этого сценария по сравнению с другими. По умолчанию вес равен 1. (Чтобы использовать имя файла сценария, которое содержит символ@
, добавьте вес, чтобы исключить неоднозначность, напримерfilen@me@1
). Подробности см. ниже.-j
threads
--jobs=
threads
#Количество рабочих потоков внутри pgbench. Использование более одного потока может быть полезным на многоядерных машинах. Клиенты распределяются как можно равномерно между доступными потоками. По умолчанию установлено значение 1.
-l
--log
#Запишите информацию о каждой транзакции в файл журнала. См. ниже для получения более подробной информации.
-L
limit
--latency-limit=
limit
#Все транзакции, которые длительностью более
limit
миллисекунд, считаются и отображаются отдельно, как поздние.Когда используется ограничение скорости (
--rate=...
), транзакции, отставающие от графика более чем наlimit
мс и, следовательно, не имеющие никаких шансов соответствовать ограничению задержки, вообще не отправляются на сервер. Они подсчитываются и отдельно отображаются как прне указанные.Когда используется опция
--max-tries
, транзакция, которая не удалась из-за сериализационной аномалии или из-за блокировки, не будет повторно попытаться, если общее время всех попыток превышаетlimit
мс. Чтобы ограничить только время попыток, а не их количество, используйте--max-tries=0
. По умолчанию опция--max-tries
установлена на 1, и транзакции с ошибками сериализации/блокировки не повторяются. См. Failures and Serialization/Deadlock Retries для получения дополнительной информации о повторных попытках таких транзакций.-M
querymode
--protocol=
querymode
#Протокол, используемый для отправки запросов на сервер:
simple
: использовать простой протокол запросов.extended
: использовать расширенный протокол запросов.prepared
: использовать расширенный протокол запросов с подготовленными операторами.
В режиме запроса
prepared
, pgbench повторно использует результат анализа разбора, начиная со второй итерации запроса, поэтому pgbench работает быстрее, чем в других режимах.Сохраняется протокол простого запроса по умолчанию. (См. Глава 52 для получения дополнительной информации).
-n
--no-vacuum
#Не выполняйте очистку перед запуском теста. Эта опция необходима если вы запускаете пользовательский сценарий тестирования, который не включает стандартные таблицы
pgbench_accounts
,pgbench_branches
,pgbench_history
иpgbench_tellers
.-N
--skip-some-updates
#Запустите встроенный сценарий простого обновления. Сокращенная форма для
-b simple-update
.-P
sec
--progress=
sec
#Показывать отчет о ходе выполнения каждые
sec
секунд. Отчет включает время с начала выполнения, TPS с момента последнего отчета, среднюю задержку транзакции, стандартное отклонение и количество неудачных транзакций с момента последнего отчета. При ограничении (-R
) задержка вычисляется относительно запланированного времени начала транзакции, а не фактического времени начала, поэтому она также включает среднее время задержки планирования. Когда используется--max-tries
для включения повторных попыток выполнения транзакций после ошибок сериализации/блокировки, отчет включает количество повторных попыток и сумму всех повторных попыток.-r
--report-per-command
#Сообщите следующую статистику для каждой команды после завершения тестирования: среднюю задержку на каждый оператор (время выполнения с точки зрения клиента), количество ошибок и количество повторных попыток после ошибок сериализации или блокировки в этой команде. Отчет отображает статистику повторных попыток только если опция
--max-tries
не равна 1.-R
rate
--rate=
rate
#Выполняйте транзакции с заданной скоростью, а не максимально быстро (по умолчанию). Скорость указывается в транзакциях в секунду. Если целевая скорость превышает максимально возможную скорость, ограничение скорости не повлияет на результаты.
Скорость определяется путем запуска транзакций в соответствии с распределением Пуассона по временной шкале графика. Ожидаемое время начала графика сдвигается вперед на основе времени, когда клиент впервые начал работу, а не на основе времени окончания предыдущей транзакции. Такой подход означает, что когда транзакции превышают свое первоначально запланированное время окончания, возможно, что позднее они снова догонят.
Когда активна регулировка пропускной способности, задержка транзакции, сообщаемая в конце выполнения, рассчитывается на основе запланированных времен начала, поэтому она включает время ожидания каждой транзакции до завершения предыдущей транзакции. Время ожидания называется временем задержки планирования, и его среднее и максимальное значения также сообщаются отдельно. Задержка транзакции относительно фактического времени начала транзакции, то есть время, затраченное на выполнение транзакции в базе данных, можно вычислить, вычитая время задержки планирования из сообщаемой задержки.
Если используется параметр
--latency-limit
вместе с параметром--rate
, транзакция может отставать настолько, что она уже превышает предельное значение задержки, когда предыдущая транзакция завершается, поскольку задержка рассчитывается от запланированного времени начала. Такие транзакции не отправляются на сервер, а полностью пропускаются и отдельно учитываются.Высокое время отставания по расписанию является признаком того, что система не может обрабатывать транзакции с заданной скоростью, с выбранным количеством клиентов и потоков. Когда среднее время выполнения транзакции превышает запланированный интервал между каждой транзакцией, каждая последующая транзакция будет отставать все больше, и время отставания по расписанию будет увеличиваться с увеличением продолжительности тестового запуска. Когда это происходит, вам придется уменьшить заданную скорость транзакций.
-s
scale_factor
--scale=
scale_factor
#Сообщите указанный коэффициент масштабирования в выводе pgbench. При использовании встроенных тестов это необязательно; правильный коэффициент масштабирования будет определен путем подсчета количества строк в таблице
pgbench_branches
. Однако, при тестировании только пользовательских бенчмарков (-f
опция), коэффициент масштабирования будет указан как 1, если не использовать эту опцию.-S
--select-only
#Выполните встроенный сценарий только для выборки. Сокращение для
-b select-only
.-t
transactions
--transactions=
transactions
#Количество транзакций, которые выполняет каждый клиент. По умолчанию - 10.
-T
seconds
--time=
seconds
#Запустите тест в течение указанного количества секунд, а не фиксированного количества транзакций на клиента. Опции
-t
и-T
взаимоисключающие.-v
--vacuum-all
#Выполните очистку всех четырех стандартных таблиц перед запуском теста. Если не указаны ни параметр
-n
, ни параметр-v
, pgbench выполнит очистку таблицpgbench_tellers
иpgbench_branches
, а также очистит таблицуpgbench_history
.--aggregate-interval=
#seconds
Длина интервала агрегации (в секундах). Может использоваться только с опцией
-l
. С этой опцией журнал содержит сводные данные по интервалам, описанные ниже.--failures-detailed
#Сообщайте о сбоях в журналах по транзакциям и агрегации, а также в основных и отдельных отчетах по скриптам, сгруппированных по следующим типам:
сбои сериализации;
сбои взаимоблокировки;
См. Failures and Serialization/Deadlock Retries для получения дополнительной информации.
--log-prefix=
#prefix
Установите префикс имени файла для журнальных файлов, создаваемых с помощью опции
--log
. По умолчанию используется значениеpgbench_log
.--max-tries=
#number_of_tries
Включите повторные попытки для транзакций с ошибками сериализации/взаимной блокировки и установите максимальное количество таких попыток. Этот параметр можно комбинировать с параметром
--latency-limit
, который ограничивает общее время всех попыток транзакции; кроме того, нельзя использовать неограниченное количество попыток (--max-tries=0
) без параметра--latency-limit
или--time
. Значение по умолчанию равно 1, и транзакции с ошибками сериализации/взаимной блокировки не повторяются. См. Failures and Serialization/Deadlock Retries для получения дополнительной информации о повторных попытках таких транзакций.--progress-timestamp
#При отображении прогресса (опция
-P
) используйте временную метку (Unix-эпоху) вместо количества секунд с начала выполнения. Единица измерения - секунды, с точностью до миллисекунд после точки. Это помогает сравнивать журналы, созданные различными инструментами.--random-seed=
seed
#Установите начальное значение генератора случайных чисел. Задает начальное состояние генератора случайных чисел системы, который затем создает последовательность начальных состояний генератора, по одному для каждого потока. Значения для
seed
могут быть:time
(по умолчанию, seed основан на текущем времени),rand
(используйте надежный источник случайных чисел, с ошибкой, если ни один не доступен) или беззнаковое десятичное целое значение. Генератор случайных чисел вызывается явно из скрипта pgbench (функцииrandom...
) или неявно (например, опция--rate
использует его для планирования транзакций). Когда значение явно установлено, используемое для инициализации значение отображается на терминале. Любое значение, разрешенное дляseed
, также может быть предоставлено через переменную окруженияPGBENCH_RANDOM_SEED
. Чтобы гарантировать, что предоставленное значение seed влияет на все возможные использования, поместите эту опцию первой или используйте переменную окружения.Сохранение явно заданного начального значения позволяет воспроизвести выполнение
pgbench
точно так же, что касается случайных чисел. Поскольку состояние генератора случайных чисел управляется для каждого потока, это означает, что выполнение точно такого жеpgbench
возможно при идентичном вызове, если на каждый поток приходится один клиент и нет внешних или зависимостей от данных. С точки зрения статистики, точное воспроизведение выполнения является плохой идеей, поскольку это может скрывать изменчивость производительности или необоснованно улучшать производительность, например, попадая на те же страницы, что и в предыдущем выполнении. Однако, это также может быть очень полезно для отладки, например, повторного выполнения сложного случая, который приводит к ошибке. Используйте с умом.--sampling-rate=
#rate
Частота выборки, используемая при записи данных в журнал, для сокращения объема генерируемого журнала. Если задан этот параметр, в журнал будут записываться только указанная доля транзакций. Значение 1.0 означает, что все транзакции будут записаны в журнал, а значение 0.05 означает, что в журнал будут записаны только 5% транзакций.
Не забудьте учитывать частоту выборки при обработке файла журнала. Например, при вычислении значений TPS необходимо умножать числа соответствующим образом (например, при частоте выборки 0,01 вы получите только 1/100 от фактического значения TPS).
--show-script=
scriptname
#Показать фактический код встроенного сценария
scriptname
на stderr и немедленно завершить выполнение.--verbose-errors
#Печатать сообщения обо всех ошибках и сбоях (ошибки без повторных попыток) включая, какой лимит для повторных попыток был превышен и насколько он был превышен для сбоев сериализации/взаимоблокировки. (Обратите внимание, что в этом случае вывод может быть значительно увеличен.) См. Failures and Serialization/Deadlock Retries для получения дополнительной информации.
Общие параметры
pgbench также принимает следующие общие аргументы командной строки для параметров подключения:
-h
hostname
--host=
hostname
#Имя хоста сервера базы данных
-p
port
--port=
port
#Номер порта сервера базы данных
-U
login
--username=
login
#Имя пользователя для подключения
-V
--version
#Вывести версию pgbench и завершить работу.
-?
--help
#Показать справку о командной строке для приложения pgbench и выйти.
Статус выхода
В случае успешного выполнения, программа завершится со статусом 0. Статус 1 указывает на статические проблемы, такие как неверные параметры командной строки или внутренние ошибки, которые не должны возникать. Ранние ошибки, возникающие при запуске теста, такие как сбои при установлении начального соединения, также приводят к завершению с статусом 1. Ошибки, возникающие во время выполнения, такие как ошибки базы данных или проблемы в скрипте, приведут к завершению с статусом 2. В последнем случае, pgbench выведет частичные результаты.
Окружение
PGDATABASE
PGHOST
PGPORT
PGUSER
#Параметры подключения по умолчанию.
Эта утилита, как и большинство других утилит Tantor BE, использует переменные среды, поддерживаемые libpq (см. Раздел 31.15).
Переменная среды PG_COLOR
определяет, следует ли использовать цвет в диагностических сообщениях. Возможные значения: always
, auto
и never
.
Примечания
Что на самом деле выполняется в pgbench в “транзакции”?
pgbench выполняет тестовые скрипты, выбранные случайным образом
из указанного списка.
Скрипты могут включать встроенные скрипты, указанные с помощью -b
,
а также пользовательские скрипты, указанные с помощью -f
.
Каждому скрипту может быть присвоена относительная весовая коэффициент, указанный после
@
, чтобы изменить вероятность его выбора.
По умолчанию вес равен 1
.
Скрипты с весом 0
игнорируются.
Стандартный встроенный транзакционный скрипт (также вызывается с помощью -b tpcb-like
) выполняет семь команд на транзакцию над случайно выбранными aid
, tid
, bid
и delta
. Сценарий вдохновлен бенчмарком TPC-B, но на самом деле не является TPC-B, отсюда и название.
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;
Если вы выберете встроенную команду simple-update
(также -N
),
шаги 4 и 5 не будут включены в транзакцию.
Это избежит конфликтов при обновлении этих таблиц, но
это делает тестовый случай еще менее похожим на TPC-B.
Если вы выберете встроенную команду select-only
(также -S
),
будет выполняться только команда SELECT
.
Пользовательские сценарии
pgbench поддерживает запуск пользовательских сценариев тестирования путем замены стандартного сценария транзакций (описанного выше) сценарием транзакций, считываемым из файла (опция -f
). В этом случае “транзакция” считается одним выполнением файла сценария.
Файл сценария содержит одну или несколько SQL-команд, завершающихся точкой с запятой. Пустые строки и строки, начинающиеся с --
, игнорируются. Файлы сценариев также могут содержать “метакоманды”, которые интерпретируются самим pgbench, как описано ниже.
Примечание
До PostgreSQL 9.6 SQL-команды в файлах скриптов завершались переводами строк, поэтому их нельзя было продолжать на следующей строке. Теперь точка с запятой обязательна для разделения последовательных SQL-команд (хотя SQL-команда не требует точки с запятой, если за ней следует метакоманда). Если вам нужно создать файл скрипта, который будет работать как с старыми, так и с новыми версиями pgbench, убедитесь, что каждая SQL-команда записана на одной строке и заканчивается точкой с запятой.
Предполагается, что скрипты pgbench не содержат неполных блоков SQL-транзакций. Если во время выполнения клиент достигает конца скрипта без завершения последнего блока транзакций, он будет прерван.
Существует простой механизм подстановки переменных для файлов сценариев.
Имена переменных должны состоять из букв (включая нелатинские буквы),
цифр и подчеркиваний, при этом первый символ не может быть цифрой.
Переменные могут быть установлены с помощью командной строки -D
,
как объяснялось выше, или с помощью метакоманд, объясненных ниже.
В дополнение к любым переменным, предустановленным с помощью командной строки -D
,
существует несколько переменных, которые предустановлены автоматически, перечисленных в
Таблица 292. Значение, указанное для этих
переменных с помощью -D
, имеет приоритет над автоматическими предустановками.
После установки значение переменной может быть вставлено в SQL-команду, написав
:
variablename
. При выполнении более чем
одной клиентской сессии каждая сессия имеет свой набор переменных.
pgbench поддерживает до 255 использований переменных в одном
операторе.
Таблица 292. pgbench Автоматические переменные
Переменная | Описание |
---|---|
client_id | уникальный номер, идентифицирующий сессию клиента (начинается с нуля) |
default_seed | используется по умолчанию в хеш-функциях и псевдослучайных перестановках |
random_seed | Начальное значение генератора случайных чисел (если не перезаписано с помощью -D ) |
scale | текущий коэффициент масштабирования |
Все метакоманды скриптового файла начинаются с обратной косой черты (\
) и обычно распространяются до конца строки, хотя их можно продолжать на дополнительные строки, написав обратную косую черту-возврат.
Аргументы метакоманды разделяются пробелами.
Поддерживаются следующие метакоманды:
-
\gset [
prefix
]\aset [
#prefix
] Эти команды могут быть использованы для завершения SQL-запросов, заменяя конечную точку с запятой (
;
).Когда используется команда
\gset
, ожидается, что предыдущий SQL-запрос вернет одну строку, столбцы которой будут сохранены в переменные с именами, соответствующими именам столбцов, и с префиксомprefix
, если он указан.Когда используется команда
\aset
, все объединенные SQL-запросы (разделенные\;
) имеют свои столбцы сохранены в переменных с именами столбцов, и префиксированы с помощьюprefix
, если предоставлено. Если запрос не возвращает ни одной строки, присваивание не выполняется и переменная может быть проверена на существование для обнаружения этого. Если запрос возвращает более одной строки, сохраняется последнее значение.\gset
и\aset
не могут быть использованы в режиме конвейера, так как результаты запроса еще не доступны к моменту, когда команды их потребуют.Следующий пример помещает конечный баланс счета из первого запроса в переменную
abalance
и заполняет переменныеp_two
иp_three
целыми числами из третьего запроса. Результат второго запроса отбрасывается. Результат двух последних объединенных запросов сохраняется в переменныхfour
иfive
.UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid RETURNING abalance \gset -- compound of two queries SELECT 1 \; SELECT 2 AS two, 3 AS three \gset p_ SELECT 4 AS four \; SELECT 5 AS five \aset
\if
expression
\elif
expression
\else
\endif
#Эта группа команд реализует вложенные условные блоки, аналогично
psql
's\if
expression
. Условные выражения идентичны тем, что используются с\set
, где ненулевые значения интерпретируются как true.-
\set
#varname
expression
Устанавливает переменную
varname
в значение, вычисленное изexpression
. Выражение может содержать константуNULL
, логические константыTRUE
иFALSE
, целочисленные константы, такие как5432
, вещественные константы, такие как3.14159
, ссылки на переменные:
variablename
, операторы с их обычным приоритетом и ассоциативностью в SQL, вызовы функций, SQL условные выраженияCASE
и скобки.Все функции и большинство операторов возвращают
NULL
при вводеNULL
.Для условных целей, ненулевые числовые значения являются
TRUE
, нулевые числовые значения иNULL
являютсяFALSE
.Слишком большие или маленькие целые и вещественные константы, а также операторы целочисленной арифметики (
+
,-
,*
и/
) вызывают ошибки при переполнении.Когда не предоставляется конечная фраза
ELSE
в оператореCASE
, значение по умолчанию -NULL
.Примеры:
\set ntellers 10 * :scale \set aid (1021 * random(1, 100000 * :scale)) % \ (100000 * :scale) + 1 \set divx CASE WHEN :x <> 0 THEN :y/:x ELSE NULL END
-
\sleep
#number
[ us | ms | s ] Заставляет выполнение скрипта заснуть на указанную продолжительность в микросекундах (
us
), миллисекундах (ms
) или секундах (s
). Если единица измерения не указана, то по умолчанию используются секунды.number
может быть либо целочисленной константой, либо ссылкой на переменную:
variablename
, имеющую целочисленное значение.Пример:
\sleep 10 ms
-
\setshell
#varname
command
[argument
... ] Устанавливает переменную
varname
в результат выполнения команды оболочкиcommand
с заданным набором аргументовargument
. Команда должна возвращать целочисленное значение через стандартный вывод.command
и каждыйargument
может быть либо текстовой константой, либо ссылкой на переменную:
variablename
. Если нужно использоватьargument
, начинающийся с двоеточия, напишите дополнительное двоеточие в началеargument
.Пример:
\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
-
\shell
#command
[argument
... ] То же самое, что и
\setshell
, но результат команды отбрасывается.Пример:
\shell command literal_argument :variable ::literal_starting_with_colon
\startpipeline
\endpipeline
#Эти команды ограничивают начало и конец конвейера SQL-операторов. В режиме конвейера, операторы отправляются на сервер без ожидания результатов предыдущих операторов. См. Раздел 31.5 для получения дополнительной информации. Режим конвейера требует использования расширенного протокола запросов.
Встроенные операторы
Все арифметические, побитовые, сравнительные и логические операторы, перечисленные в Таблица 293, встроены в pgbench и могут использоваться в выражениях, появляющихся в \set
. Операторы перечислены в порядке возрастания приоритета. За исключением указанных случаев, операторы, принимающие два числовых входа, будут производить значение типа double, если хотя бы один из входов является double, в противном случае они будут производить целочисленный результат.
Таблица 293. Операторы pgbench
Оператор Описание Пример(ы) |
---|
Логическое ИЛИ
|
Логическое И
|
Логическое НЕ
|
Тесты логических значений
|
Тесты на нулевое значение
|
Равно
|
Не равно
|
Не равно
|
Меньше чем
|
Меньше или равно
|
Больше чем
|
Больше или равно
|
Побитовое ИЛИ
|
Побитовое исключающее ИЛИ
|
Побитовое И
|
Побитовое НЕ
|
Побитовый сдвиг влево
|
Побитовый сдвиг вправо
|
Дополнение
|
Вычитание
|
Умножение
|
Division (обрезает результат к нулю, если оба входных значения являются целыми числами)
|
Модуло (остаток)
|
Отрицание
|
Встроенные функции
Все функции, перечисленные в Таблица 294, встроены в pgbench и могут использоваться в выражениях, появляющихся в \set
.
Таблица 294. Функции pgbench
Функция Описание Пример(ы) |
---|
Абсолютное значение
|
Печатает аргумент в stderr и возвращает аргумент.
|
Сasts to double.
|
Экспонента (
|
Выбирает наибольшее значение среди аргументов.
|
Это псевдоним для
|
Вычисляет хеш FNV-1a FNV-1a hash..
|
Вычисляет хеш MurmurHash2 MurmurHash2 hash.
|
Приведение к целому числу.
|
Выбирает наименьшее значение из аргументов.
|
Натуральный логарифм
|
Модуло (остаток)
|
Переставленное значение
|
Приблизительное значение π
|
|
Вычисляет равномерно распределенное случайное целое число в диапазоне
|
Вычисляет случайное целое число, распределенное экспоненциально в интервале
|
Вычисляет целое число, распределенное по Гауссу в интервале
|
Вычисляет случайное целое число, распределенное по закону Ципфа в интервале
|
Квадратный корень
|
Функция random
генерирует значения с использованием равномерного распределения, то есть все значения выбираются в указанном диапазоне с равной вероятностью. Функции random_exponential
, random_gaussian
и random_zipfian
требуют дополнительный параметр типа double, который определяет точную форму распределения.
Для экспоненциального распределения параметр
parameter
контролирует распределение, обрезая быстро убывающее экспоненциальное распределение наparameter
, а затем проецируя на целые числа между границами. Чтобы быть точным, сf(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))
Затем значение
i
междуmin
иmax
включительно выбирается с вероятностью:f(i) - f(i + 1)
.Intuitively, the larger the
parameter
, the more frequently values close tomin
are accessed, and the less frequently values close tomax
are accessed. The closer to 0parameter
is, the flatter (more uniform) the access distribution. A crude approximation of the distribution is that the most frequent 1% values in the range, close tomin
, are drawnparameter
% of the time. Theparameter
value must be strictly positive.Для гауссового распределения интервал отображается на стандартное нормальное распределение (классическая колоколообразная гауссова кривая), обрезанное слева на
-parameter
и справа на+parameter
. Значения в середине интервала более вероятно будут выбраны. А именно, еслиPHI(x)
является накопленной функцией распределения стандартизированного нормального распределения, среднее значениеmu
определяется как(max + min) / 2.0
, сf(x) = PHI(2.0 * параметр * (x - среднее) / (максимальное - минимальное + 1)) /
(2.0 * PHI(параметр) - 1)Затем значение
i
междуmin
иmax
включительно выбирается с вероятностью:f(i + 0.5) - f(i - 0.5)
. Интуитивно, чем большеparameter
, тем чаще выбираются значения, близкие к середине интервала, и тем реже выбираются значения, близкие к границамmin
иmax
. Около 67% значений выбираются из среднего1.0 / parameter
, то есть относительно0.5 / parameter
вокруг среднего значения, и 95% значений выбираются из среднего2.0 / parameter
, то есть относительно1.0 / parameter
вокруг среднего значения; например, еслиparameter
равен 4.0, 67% значений выбираются из средней четверти (1.0 / 4.0) интервала (т.е. от3.0 / 8.0
до5.0 / 8.0
), а 95% значений из средней половины (2.0 / 4.0
) интервала (второй и третий квартили). Минимально допустимое значениеparameter
равно 2.0.random_zipfian
генерирует ограниченное распределение Zipfian.parameter
определяет степень смещения распределения. Чем большеparameter
, тем чаще выбираются значения, близкие к началу интервала. Распределение таково, что при условии, что диапазон начинается с 1, отношение вероятности выбораk
к выборуk+1
равно((
. Например,k
+1)/k
)**parameter
random_zipfian(1, ..., 2.5)
производит значение1
примерно(2/1)**2.5 = 5.66
раз чаще, чем2
, который сам производится(3/2)**2.5 = 2.76
раз чаще, чем3
, и так далее.Реализация pgbench основана на "Генерации неоднородных случайных величин", Люк Деврой, стр. 550-551, Springer 1986. Из-за ограничений этого алгоритма, значение
parameter
ограничено диапазоном [1.001, 1000].
Примечание
Когда разрабатывается бенчмарк, который выбирает строки неоднородно, следует учитывать, что выбранные строки могут быть коррелированы с другими данными, такими как идентификаторы из последовательности или физический порядок строк, что может исказить измерения производительности.
Чтобы избежать этого, вы можете воспользоваться функцией permute
или другим дополнительным шагом с аналогичным эффектом, чтобы перемешать выбранные строки и устранить такие корреляции.
Все хеш-функции hash
, hash_murmur2
и hash_fnv1a
принимают входное значение и необязательный параметр seed.
В случае, если seed не указан, используется значение :default_seed
, которое инициализируется случайным образом, если не установлено с помощью опции командной строки -D
.
permute
принимает входное значение, размер и необязательный
параметр seed. Он генерирует псевдослучайную перестановку целых чисел в
диапазоне [0, size)
и возвращает индекс входного
значения в переставленных значениях. Перестановка выбирается с помощью
seed, который по умолчанию равен :default_seed
, если не
указан. В отличие от хеш-функций, permute
гарантирует,
что в выходных значениях нет коллизий или пропусков. Входные значения
за пределами интервала интерпретируются по модулю размера. Функция вызывает
ошибку, если размер не является положительным. permute
может использоваться для разброса распределения неоднородных случайных функций,
таких как random_zipfian
или random_exponential
,
чтобы значения, выбираемые чаще, не были тривиально коррелированы. Например,
следующий сценарий pgbench моделирует возможную
реальную нагрузку, типичную для социальных сетей и платформ блогов, где
некоторые аккаунты генерируют избыточную нагрузку:
\set size 1000000 \set r random_zipfian(1, :size, 1.07) \set k 1 + permute(:r, :size)
В некоторых случаях требуется несколько отдельных распределений, которые не коррелируют друг с другом, и вот тогда пригодится необязательный параметр seed:
\set k1 1 + permute(:r, :size, :default_seed + 123) \set k2 1 + permute(:r, :size, :default_seed + 321)
Подобное поведение также можно приблизительно получить с помощью функции hash
:
\set size 1000000 \set r random_zipfian(1, 100 * :size, 1.07) \set k 1 + abs(hash(:r)) % :size
Однако, поскольку функция hash
генерирует коллизии, некоторые значения
не будут доступны, а другие будут встречаться чаще, чем ожидалось из
исходного распределения.
В качестве примера, полное определение встроенной транзакции, подобной TPC-B, выглядит следующим образом:
\set aid random(1, 100000 * :scale) \set bid random(1, 1 * :scale) \set tid random(1, 10 * :scale) \set delta random(-5000, 5000) BEGIN; UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; SELECT abalance FROM pgbench_accounts WHERE aid = :aid; UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); END;
Этот скрипт позволяет каждой итерации транзакции ссылаться на разные, случайно выбранные строки. (Этот пример также показывает, почему важно, чтобы каждая сессия клиента имела свои собственные переменные - в противном случае они бы не независимо воздействовали на разные строки).
Периодическое ведение журнала транзакций
С помощью опции -l
(но без опции --aggregate-interval
) pgbench записывает информацию о каждой транзакции в файл журнала. Имя файла журнала будет
, где prefix
.nnn
prefix
по умолчанию равен pgbench_log
, а nnn
- это PID процесса pgbench. Префикс можно изменить с помощью опции --log-prefix
. Если опция -j
равна 2 или больше, то есть есть несколько рабочих потоков, каждый из них будет иметь свой собственный файл журнала. Первый рабочий поток будет использовать то же имя файла журнала, что и в случае стандартного однопоточного режима. Дополнительные файлы журнала для других рабочих процессов будут называться
, где prefix
.nnn
.mmm
mmm
- это последовательный номер для каждого рабочего процесса, начиная с 1.
Каждая строка в файле журнала описывает одну транзакцию. Она содержит следующие поля, разделенные пробелами:
client_id
идентифицирует клиентскую сессию, которая выполнила транзакцию
transaction_no
подсчитывает, сколько транзакций было выполнено этой сессией
time
время выполнения транзакции в микросекундах
script_no
идентифицирует файл сценария, который использовался для транзакции (полезно, когда указано несколько сценариев с помощью
-f
или-b
)time_epoch
время завершения транзакции в формате Unix-эпохи
time_us
дробная часть времени завершения транзакции, в микросекундах
schedule_lag
задержка начала транзакции, то есть разница между запланированным временем начала транзакции и временем ее фактического запуска, в микросекундах (присутствует только если указана опция
--rate
)retries
количество повторных попыток после ошибок сериализации или блокировки во время транзакции (присутствует только если
--max-tries
не равно одному)
Когда используются оба параметра --rate
и --latency-limit
,
время time
прне указанной транзакции будет отображаться как
skipped
.
Если транзакция завершается неудачно, ее время time
будет отображаться как failed
. Если вы используете
параметр --failures-detailed
, time
неудачной транзакции будет отображаться как
serialization
или
deadlock
в зависимости от типа сбоя (см.
Failures and Serialization/Deadlock Retries для получения дополнительной информации).
Вот отрывок из файла журнала, сгенерированного в одиночном режиме работы клиента:
0 199 2241 0 1175850568 995598 0 200 2465 0 1175850568 998079 0 201 2513 0 1175850569 608 0 202 2038 0 1175850569 2663
Еще один пример с --rate=100
и --latency-limit=5
(обратите внимание на дополнительный столбец schedule_lag
):
0 81 4621 0 1412881037 912698 3005 0 82 6173 0 1412881037 914578 4304 0 83 skipped 0 1412881037 914578 5217 0 83 skipped 0 1412881037 914578 5099 0 83 4722 0 1412881037 916203 3108 0 84 4142 0 1412881037 918023 2333 0 85 2465 0 1412881037 919759 740
В этом примере транзакция 82 была задержана, потому что ее задержка (6,173 мс) превысила лимит в 5 мс. Следующие две транзакции были прне указаны, потому что они уже были задержаны до того, как они были запущены.
Следующий пример показывает фрагмент файла журнала с ошибками и повторными попытками, с максимальным количеством попыток, установленным на 10 (обратите внимание на дополнительный столбец retries
):
3 0 47423 0 1499414498 34501 3 3 1 8333 0 1499414498 42848 0 3 2 8358 0 1499414498 51219 0 4 0 72345 0 1499414498 59433 6 1 3 41718 0 1499414498 67879 4 1 4 8416 0 1499414498 76311 0 3 3 33235 0 1499414498 84469 3 0 0 failed 0 1499414498 84905 9 2 0 failed 0 1499414498 86248 9 3 4 8307 0 1499414498 92788 0
Если используется опция --failures-detailed
, тип сбоя будет отображаться в time
следующим образом:
3 0 47423 0 1499414498 34501 3 3 1 8333 0 1499414498 42848 0 3 2 8358 0 1499414498 51219 0 4 0 72345 0 1499414498 59433 6 1 3 41718 0 1499414498 67879 4 1 4 8416 0 1499414498 76311 0 3 3 33235 0 1499414498 84469 3 0 0 serialization 0 1499414498 84905 9 2 0 serialization 0 1499414498 86248 9 3 4 8307 0 1499414498 92788 0
При выполнении длительного теста на оборудовании, способном обрабатывать большое количество транзакций, журнальные файлы могут стать очень большими. Опция --sampling-rate
может быть использована для записи только случайной выборки транзакций.
Агрегированное ведение журнала
С помощью опции --aggregate-interval
используется другой формат для файлов журнала. Каждая строка журнала описывает один интервал агрегации. Она содержит следующие поля, разделенные пробелами:
interval_start
начальное время интервала в виде временной метки Unix-epoch
num_transactions
количество транзакций внутри интервала
sum_latency
сумма задержек транзакций
sum_latency_2
Сумма квадратов задержек транзакций
min_latency
минимальная задержка транзакции
max_latency
максимальная задержка транзакции
sum_lag
Сумма задержек начала транзакций (нулевая, если не указана опция
--rate
)sum_lag_2
Сумма квадратов задержек начала транзакций (нулевая, если не указана опция
--rate
)min_lag
минимальная задержка начала транзакции (нулевая, если не указана опция
--rate
)max_lag
максимальная задержка начала транзакции (нулевая, если не указана опция
--rate
)skipped
количество прне указанных транзакций, которые должны были начаться слишком поздно (ноль, если не указаны параметры
--rate
и--latency-limit
)retried
количество повторных транзакций (ноль, если
--max-tries
не равно одному)retries
количество повторных попыток после ошибок сериализации или блокировки (ноль, если
--max-tries
не равно одному)serialization_failures
количество транзакций, которые получили ошибку сериализации и не были повторно запущены после этого (ноль, если не указана опция
--failures-detailed
)deadlock_failures
количество транзакций, которые получили ошибку дедлока и не были повторно запущены после этого (ноль, если не указана опция
--failures-detailed
)
Вот пример вывода, сгенерированного с этими параметрами:
pgbench --aggregate-interval=10 --time=20 --client=10 --log --rate=1000 --latency-limit=10 --failures-detailed --max-tries=10 test
1650260552 5178 26171317 177284491527 1136 44462 2647617 7321113867 0 9866 64 7564 28340 4148 0
1650260562 4808 25573984 220121792172 1171 62083 3037380 9666800914 0 9998 598 7392 26621 4527 0
Обратите внимание, что в то время как обычный (неагрегированный) формат журнала показывает, какой скрипт использовался для каждой транзакции, агрегированный формат этой информации не содержит. Поэтому, если вам нужны данные по каждому скрипту, необходимо самостоятельно агрегировать данные.
Отчет по каждому оператору
С помощью опции -r
pgbench собирает следующую статистику для каждого оператора:
latency
— прошедшее время выполнения каждого оператора. pgbench сообщает среднее значение всех успешных запусков оператора.Количество ошибок в данном операторе. См. Failures and Serialization/Deadlock Retries для получения дополнительной информации.
Количество повторных попыток после возникновения ошибки сериализации или блокировки в данном операторе. См. Failures and Serialization/Deadlock Retries для получения дополнительной информации.
Отчет отображает статистику повторных попыток только если опция --max-tries
не равна 1.
Все значения вычисляются для каждого выполненного оператора каждым клиентом и сообщаются после завершения тестирования.
Для скрипта по умолчанию вывод будет выглядеть примерно так:
starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 maximum number of tries: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 number of failed transactions: 0 (0.000%) number of transactions above the 50.0 ms latency limit: 1311/10000 (13.110 %) latency average = 28.488 ms latency stddev = 21.009 ms initial connection time = 69.068 ms tps = 346.224794 (without initial connection time) statement latencies in milliseconds and failures: 0.012 0 \set aid random(1, 100000 * :scale) 0.002 0 \set bid random(1, 1 * :scale) 0.002 0 \set tid random(1, 10 * :scale) 0.002 0 \set delta random(-5000, 5000) 0.319 0 BEGIN; 0.834 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 0.641 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 11.126 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 12.961 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 0.634 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 1.957 0 END;
Еще один пример вывода для скрипта по умолчанию с использованием уровня изоляции транзакций serializable (PGOPTIONS='-c default_transaction_isolation=serializable' pgbench ...
):
starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 maximum number of tries: 10 number of transactions per client: 1000 number of transactions actually processed: 6317/10000 number of failed transactions: 3683 (36.830%) number of transactions retried: 7667 (76.670%) total number of retries: 45339 number of transactions above the 50.0 ms latency limit: 106/6317 (1.678 %) latency average = 17.016 ms latency stddev = 13.283 ms initial connection time = 45.017 ms tps = 186.792667 (without initial connection time) statement latencies in milliseconds, failures and retries: 0.006 0 0 \set aid random(1, 100000 * :scale) 0.001 0 0 \set bid random(1, 1 * :scale) 0.001 0 0 \set tid random(1, 10 * :scale) 0.001 0 0 \set delta random(-5000, 5000) 0.385 0 0 BEGIN; 0.773 0 1 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 0.624 0 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 1.098 320 3762 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 0.582 3363 41576 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 0.465 0 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 1.933 0 0 END;
Если указано несколько файлов сценариев, все статистические данные отображаются отдельно для каждого файла сценария.
Обратите внимание, что сбор дополнительной информации о времени выполнения, необходимой для вычисления задержки для каждого оператора, добавляет некоторую нагрузку. Это замедлит среднюю скорость выполнения и снизит вычисленное значение TPS. Скорость замедления значительно варьируется в зависимости от платформы и оборудования. Сравнение средних значений TPS с включенной и отключенной отчетностью о задержке - хороший способ измерить, насколько значительны издержки на замер времени.
Сбои и повторы сериализации/блокировки
При выполнении pgbench возникают три основных типа ошибок:
Ошибки основной программы. Они являются наиболее серьезными и всегда приводят к немедленному завершению pgbench с соответствующим сообщением об ошибке. Они включают в себя:
ошибки в начале pgbench (например, недопустимое значение параметра);
ошибки в режиме инициализации (например, запрос на создание таблиц для встроенных сценариев не выполняется);
ошибки перед запуском потоков (например, не удалось подключиться к серверу базы данных, синтаксическая ошибка в метакоманде, сбой создания потока);
внутренние ошибки pgbench (которые, как предполагается, никогда не должны возникать....)
Ошибки возникают, когда поток управляет своими клиентами (например, клиент не может установить соединение с сервером базы данных / сокет для соединения клиента с сервером базы данных стал недействительным). В таких случаях все клиенты этого потока останавливаются, в то время как другие потоки продолжают работу.
Прямые ошибки клиента. Они приводят к немедленному завершению работы pgbench с соответствующим сообщением об ошибке только в случае внутренней ошибки pgbench (которые, как предполагается, никогда не возникают....) В противном случае, в худшем случае, они только приводят к прерыванию работы неудачного клиента, в то время как другие клиенты продолжают свою работу (но некоторые ошибки клиента обрабатываются без прерывания работы клиента и отдельно сообщаются, см. ниже). Позже в этом разделе предполагается, что обсуждаемые ошибки - это только прямые ошибки клиента и они не являются внутренними ошибками pgbench.
Запуск клиента прерывается в случае серьезной ошибки; например, если соединение с сервером базы данных было потеряно или достигнут конец скрипта без завершения последней транзакции. Кроме того, если выполнение SQL-команды или метакоманды завершается неудачно по причинам, отличным от ошибок сериализации или дедлока, клиент прерывается. В противном случае, если SQL-команда завершается неудачно из-за ошибок сериализации или дедлока, клиент не прерывается. В таких случаях текущая транзакция откатывается, что также включает установку клиентских переменных такими, какими они были до запуска этой транзакции (предполагается, что в одном транзакционном скрипте содержится только одна транзакция; см. What Is the "Transaction" Actually Performed in pgbench? для получения дополнительной информации).
Транзакции с ошибками сериализации или дедлока повторяются после откатов, пока они не завершатся успешно или не достигнут максимальное количество попыток (указанное опцией --max-tries
) / максимальное время повторов (указанное опцией --latency-limit
) / конец тестирования (указанный опцией --time
). Если последняя попытка завершается неудачно, эта транзакция будет отмечена как неудачная, но клиент не прерывается и продолжает работать.
Примечание
Без указания опции --max-tries
транзакция никогда не будет повторена после ошибки сериализации или блокировки, поскольку ее значение по умолчанию равно 1. Используйте неограниченное количество попыток (--max-tries=0
) и опцию --latency-limit
только для ограничения максимального времени попыток. Также можно использовать опцию --time
для ограничения длительности тестирования при неограниченном количестве попыток.
Будьте осторожны при повторении скриптов, содержащих несколько транзакций: скрипт всегда будет полностью повторен, поэтому успешные транзакции могут быть выполнены несколько раз.
Будьте осторожны при повторении транзакций с помощью команд оболочки. В отличие от результатов SQL-команд, результаты команд оболочки не откатываются, за исключением значения переменной команды \setshell
.
Задержка успешной транзакции включает в себя полное время выполнения транзакции с откатами и повторами. Задержка измеряется только для успешных транзакций и команд, но не для неудачных транзакций или команд.
Основной отчет содержит количество неудачных транзакций. Если опция --max-tries
не равна 1, то в основном отчете также содержатся статистические данные о повторных попытках: общее количество повторных транзакций и общее количество повторов. Отчет по скрипту наследует все эти поля из основного отчета. Отчет по оператору отображает статистику повторных попыток только если опция --max-tries
не равна 1.
Если нужно группировать сбои по основным типам в журналах по транзакциям и агрегации, а также в основных и отдельных отчетах по скриптам, используйте опцию --failures-detailed
. Если вы также хотите различать все ошибки и сбои (ошибки без повторной попытки) по типу, включая информацию о том, какой предел для повторных попыток был превышен и насколько, для сбоев сериализации/блокировки, используйте опцию --verbose-errors
.
Методы доступа к таблицам
Вы можете указать метод доступа к таблице
для таблиц pgbench. Переменная окружения PGOPTIONS
задает параметры конфигурации базы данных, которые передаются в PostgreSQL через
командную строку (См. Раздел 18.1.4).
Например, гипотетический метод доступа к таблице по умолчанию для таблиц, которые
создает pgbench, называемый wuzza
, можно указать с помощью:
PGOPTIONS='-c default_table_access_method=wuzza'
Хорошие практики
Использование pgbench для получения абсолютно бессмысленных чисел очень просто. Вот несколько рекомендаций, которые помогут вам получить полезные результаты.
В первую очередь, никогда не верьте тесту, который выполняется всего несколько секунд. Используйте опцию -t
или -T
, чтобы продолжительность выполнения составляла несколько минут, чтобы усреднить шум. В некоторых случаях вам может потребоваться несколько часов, чтобы получить воспроизводимые числа. Хорошей идеей будет несколько раз запустить тест, чтобы выяснить, воспроизводимы ли ваши числа или нет.
Для сценария тестирования, похожего на TPC-B, масштабный коэффициент инициализации (-s
) должен быть не меньше, чем наибольшее количество клиентов, которых вы собираетесь тестировать (-c
); иначе вы будете в основном измерять конкуренцию обновлений. В таблице pgbench_branches
всего -s
строк, и каждая транзакция хочет обновить одну из них, поэтому значения -c
, превышающие -s
, неизбежно приведут к блокировке множества транзакций, ожидающих других транзакций.
Стандартный тестовый сценарий также довольно чувствителен к тому, как долго прошло с момента инициализации таблиц: накопление мертвых строк и мертвого пространства в таблицах изменяет результаты. Чтобы понять результаты, необходимо отслеживать общее количество обновлений и время выполнения очистки. Включение автоочистки может привести к непредсказуемым изменениям в измеряемой производительности.
Ограничением pgbench является то, что оно само может стать узким местом при попытке тестирования большого количества клиентских сессий. Это можно устранить, запустив pgbench на другой машине от сервера базы данных, хотя низкая задержка сети будет необходима. Может быть полезно запустить несколько экземпляров pgbench одновременно на нескольких клиентских машинах против одного и того же сервера базы данных.
Безопасность
Если ненадежные пользователи имеют доступ к базе данных, которая не приняла безопасный шаблон использования схем, не запускайте pgbench в этой базе данных. pgbench использует неопределенные имена и не изменяет путь поиска.