PGBENCH(1) PostgreSQL 18.6 Documentation PGBENCH(1)

pgbench - اجرای آزمون محک (benchmark) روی PostgreSQL

pgbench -i [option...] [dbname]

pgbench [option...] [dbname]

ابزار pgbench یک برنامه ساده برای اجرای آزمون‌های محک (benchmark) روی PostgreSQL است. این برنامه توالی یکسانی از دستورهای SQL را به دفعات مکرر، احتمالاً در چندین نشست هم‌زمان پایگاه‌داده اجرا کرده و سپس نرخ میانگین تراکنش‌ها (تراکنش در ثانیه یا TPS) را محاسبه می‌کند. به‌طور پیش‌فرض، 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 (مقداردهی اولیه) فراخوانی شود تا این جدول‌ها ایجاد و مقداردهی شوند. (هنگامی که یک اسکریپت سفارشی را آزمایش می‌کنید، به این مرحله نیازی ندارید، اما در عوض باید هرگونه آماده‌سازی لازم برای آزمون خود را انجام دهید.) مقداردهی اولیه به این صورت است:

pgbench -i [ other-options ] dbname

که در آن dbname نام پایگاه‌داده از قبل ایجادشده برای آزمایش است. (همچنین ممکن است برای تعیین نحوه اتصال به سرور پایگاه‌داده، به گزینه‌های -h، -p یا -U نیاز داشته باشید.)


Caution

دستور pgbench -i چهار جدول pgbench_accounts، pgbench_branches، pgbench_history و pgbench_tellers را ایجاد می‌کند و هرگونه جدول موجود با این نام‌ها را از بین می‌برد. اگر جدول‌هایی با این نام‌ها دارید، بسیار مراقب باشید که از پایگاه‌داده دیگری استفاده کنید!

در مقدار پیش‌فرض “ضریب مقیاس (scale factor)” برابر با ۱، جدول‌ها در ابتدا حاوی این تعداد ردیف هستند:

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 آرگومان‌های خط فرمان مقداردهی اولیه زیر را می‌پذیرد:

[-d] dbname
[--dbname=]dbname

نام پایگاه‌داده مورد آزمون را مشخص می‌کند. اگر این مقدار مشخص نشود، از متغیر محیطی PGDATABASE استفاده می‌شود. در صورت تنظیم نبودن آن، از نام کاربری مشخص‌شده برای اتصال استفاده می‌شود.

-i
--initialize

برای فراخوانی حالت مقداردهی اولیه الزامی است.

-I init_steps
--init-steps=init_steps

فقط مجموعه گزیده‌ای از گام‌های عادی مقداردهی اولیه را انجام می‌دهد. init_steps گام‌های مقداردهی اولیه را که باید انجام شوند با یک نویسه برای هر گام مشخص می‌کند. هر گام به ترتیب تعیین‌شده فراخوانی می‌شود. مقدار پیش‌فرض dtgvp است. گام‌های در دسترس عبارتند از:

d (Drop)

هرگونه جدول موجود pgbench را حذف (Drop) می‌کند.

t (create Tables)

جدول‌های مورد استفاده در سناریوی استاندارد pgbench شامل pgbench_accounts، pgbench_branches، pgbench_history و pgbench_tellers را ایجاد می‌کند.

g یا G (Generate data, client-side or server-side)

داده‌ها را تولید کرده و در جدول‌های استاندارد بارگذاری می‌کند و جایگزین هرگونه داده موجود می‌نماید.

با g (تولید داده در سمت کلاینت)، داده‌ها در کلاینت pgbench تولید شده و سپس به سرور ارسال می‌شوند. این روش پهنای باند کلاینت/سرور را به طور گسترده از طریق یک COPY به کار می‌گیرد. pgbench از گزینه FREEZE برای بارگذاری داده‌ها در جدول‌های معمولی (غیرپارتیشن‌بندی‌شده) در نسخه ۱۴ یا جدیدترِ PostgreSQL استفاده می‌کند تا سرعت VACUUM بعدی را افزایش دهد. استفاده از g باعث می‌شود که هنگام تولید داده برای همه جدول‌ها، گزارش‌گیری به ازای هر ۱۰۰٬۰۰۰ سطر یک پیام چاپ کند.

با 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) داده‌شده ایجاد می‌کند. مقدار پیش‌فرض ۱۰۰ است.

-n
--no-vacuum

در طول مقداردهی اولیه هیچ پاک‌سازی‌ای (Vacuum) انجام نمی‌دهد. (این گزینه گام مقداردهی اولیه v را حتی اگر در -I مشخص شده باشد، نادیده می‌گیرد.)

-q
--quiet

گزارش‌گیری را به حالت بی‌صدا تغییر می‌دهد و تنها هر ۵ ثانیه یک پیام پیشرفت تولید می‌کند. گزارش‌گیری پیش‌فرض به ازای هر ۱۰۰٬۰۰۰ سطر یک پیام چاپ می‌کند که اغلب (به‌ویژه روی سخت‌افزارهای قوی) چندین خط در ثانیه خروجی می‌دهد.

اگر G در -I مشخص شده باشد، این تنظیم هیچ اثری ندارد.

-s scale_factor
--scale=scale_factor

تعداد سطرهای تولیدشده را در ضریب مقیاس (scale factor) ضرب می‌کند. برای نمونه، -s 100 تعداد ۱۰٬۰۰۰٬۰۰۰ سطر در جدول pgbench_accounts ایجاد خواهد کرد. مقدار پیش‌فرض ۱ است. هنگامی که مقیاس ۲۰٬۰۰۰ یا بیشتر باشد، ستون‌های مورد استفاده برای نگهداری شناسه‌های حساب (ستون‌های 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

همه جدول‌ها را به جای جدول‌های دائمی، به عنوان جدول‌های unlogged ایجاد می‌کند.

pgbench آرگومان‌های خط فرمانی زیر را برای بنچ‌مارک می‌پذیرد:

-b scriptname[@weight]
--builtin=scriptname[@weight]

اسکریپت توکار مشخص‌شده را به فهرست اسکریپت‌های در حال اجرا اضافه می‌کند. اسکریپت‌های توکار موجود عبارتند از: tpcb-like، simple-update و select-only. پیشوندهای غیرمبهم از نام‌های توکار نیز پذیرفته می‌شوند. با نام ویژه list، فهرست اسکریپت‌های توکار را نمایش داده و بلافاصله خارج می‌شود.

به صورت اختیاری، یک وزن عدد صحیح پس از @ بنویسید تا احتمال انتخاب این اسکریپت در مقایسه با سایر اسکریپت‌ها تنظیم شود. وزن پیش‌فرض 1 است. برای جزئیات بیشتر به بخش‌های زیر مراجعه کنید.

-c clients
--client=clients

تعداد کلاینت‌های شبیه‌سازی‌شده، یعنی تعداد نشست‌های همزمان پایگاه داده. مقدار پیش‌فرض 1 است.

-C
--connect

به جای برقراری اتصال تنها یک بار در هر نشست کلاینت، برای هر تراکنش یک اتصال جدید برقرار می‌کند. این گزینه برای اندازه‌گیری سربار اتصال مفید است.

-D varname=value
--define=varname=value

متغیری را برای استفاده توسط یک اسکریپت سفارشی تعریف می‌کند (به زیر مراجعه کنید). استفاده از چندین گزینه -D مجاز است.

-f filename[@weight]
--file=filename[@weight]

یک اسکریپت تراکنش خوانده‌شده از filename را به فهرست اسکریپت‌های در حال اجرا اضافه می‌کند.

به صورت اختیاری، یک وزن عدد صحیح پس از @ بنویسید تا احتمال انتخاب این اسکریپت در مقایسه با سایر اسکریپت‌ها تنظیم شود. وزن پیش‌فرض 1 است. (برای استفاده از نام فایل اسکریپتی که شامل کاراکتر @ است، یک وزن به آن اضافه کنید تا ابهامی وجود نداشته باشد، به عنوان مثال filen@me@1.) برای جزئیات بیشتر به بخش‌های زیر مراجعه کنید.

-j threads
--jobs=threads

تعداد نخ‌های پردازشی (worker threads) درون pgbench. استفاده از بیش از یک نخ می‌تواند در سیستم‌های چند پردازنده‌ای مفید باشد. کلاینت‌ها تا حد ممکن به طور یکنواخت بین نخ‌های موجود توزیع می‌شوند. مقدار پیش‌فرض 1 است.

-l
--log

اطلاعات مربوط به هر تراکنش را در یک فایل لاگ ثبت می‌کند. برای جزئیات بیشتر به بخش‌های زیر مراجعه کنید.

-L limit
--latency-limit=limit

تراکنش‌هایی که بیش از limit میلی‌ثانیه طول بکشند شمارش شده و به طور جداگانه به عنوان late گزارش می‌شوند.

هنگامی که محدودسازی نرخ تراکنش (--rate=...) استفاده می‌شود، تراکنش‌هایی که بیش از limit میلی‌ثانیه از زمان‌بندی عقب بیفتند و بنابراین امیدی به رسیدن به سقف تاخیر ندارند، اصلاً به سرور ارسال نمی‌شوند. آن‌ها به طور جداگانه به عنوان skipped شمارش و گزارش می‌شوند.

هنگامی که گزینه --max-tries استفاده می‌شود، تراکنشی که به دلیل ناهنجاری سریال‌سازی (serialization anomaly) یا بن‌بست (deadlock) با شکست مواجه شود، در صورتی که زمان کل تمام تلاش‌های آن بیشتر از limit میلی‌ثانیه باشد، دوباره تلاش نخواهد شد. برای محدود کردن تنها زمان تلاش‌ها و نه تعداد آن‌ها، از --max-tries=0 استفاده کنید. به طور پیش‌فرض، گزینه --max-tries بر روی 1 تنظیم شده است و تراکنش‌های دارای خطاهای سریال‌سازی/بن‌بست دوباره تلاش نمی‌شوند. برای اطلاعات بیشتر درباره تلاش مجدد چنین تراکنش‌هایی، به بخش Failures and Serialization/Deadlock Retries مراجعه کنید.

-M querymode
--protocol=querymode

پروتکل مورد استفاده برای ارسال پرس‌وجوها به سرور:
•simple: استفاده از پروتکل پرس‌وجوی ساده (simple query protocol).
•extended: استفاده از پروتکل پرس‌وجوی گسترده (extended query protocol).
•prepared: استفاده از پروتکل پرس‌وجوی گسترده همراه با دستورات آماده (prepared statements).

در حالت prepared، ابزار pgbench نتیجه تحلیل پارس را از دومین تکرار پرس‌وجو مجدداً استفاده می‌کند، بنابراین pgbench سریع‌تر از سایر حالت‌ها اجرا می‌شود.

حالت پیش‌فرض، پروتکل پرس‌وجوی ساده است. (برای اطلاعات بیشتر به فصل 54 مراجعه کنید.)

-n
--no-vacuum

قبل از اجرای آزمایش هیچ عملیات پاک‌سازی (vacuuming) انجام نمی‌دهد. در صورتی که یک سناریوی آزمایشی سفارشی را اجرا می‌کنید که شامل جدول‌های استاندارد pgbench_accounts، pgbench_branches، pgbench_history و pgbench_tellers نمی‌شود، این گزینه ضروری است.

-N
--skip-some-updates

اسکریپت توکار simple-update را اجرا می‌کند. میان‌بری برای -b simple-update.

-P sec
--progress=sec

گزارش پیشرفت را در هر sec ثانیه نمایش می‌دهد. این گزارش شامل زمان سپری‌شده از ابتدای اجرا، نرخ تراکنش بر ثانیه (TPS) از زمان گزارش قبلی، میانگین تاخیر تراکنش‌ها، انحراف معیار، و تعداد تراکنش‌های ناموفق از زمان گزارش قبلی است. در صورت اعمال کنترل نرخ (-R)، تاخیر نسبت به زمان برنامه‌ریزی‌شده برای شروع تراکنش محاسبه می‌شود و نه زمان واقعی شروع آن؛ بنابراین میانگین زمان تاخیر زمان‌بندی را نیز در بر می‌گیرد. هنگامی که از گزینه --max-tries برای فعال‌سازی تلاش مجدد تراکنش‌ها پس از خطاهای سریال‌سازی/بن‌بست استفاده می‌شود، گزارش شامل تعداد تراکنش‌های مجدداً تلاش‌شده و مجموع تمام تلاش‌های مجدد خواهد بود.

-r
--report-per-command

پس از پایان بنچمارک، آمارهای زیر را برای هر دستور گزارش می‌کند: میانگین تاخیر به ازای هر دستور (زمان اجرا از دید کلاینت)، تعداد شکست‌ها، و تعداد تلاش‌های مجدد پس از خطاهای سریال‌سازی یا بن‌بست در این دستور. این گزارش آمارهای تلاش مجدد را تنها در صورتی نمایش می‌دهد که گزینه --max-tries برابر با ۱ نباشد.

-R rate
--rate=rate

تراکنش‌ها را با هدف‌گذاری نرخ مشخص‌شده اجرا می‌کند، به جای آنکه با حداکثر سرعت ممکن اجرا شوند (حالت پیش‌فرض). این نرخ بر حسب تراکنش در ثانیه مشخص می‌شود. اگر نرخ هدف بالاتر از حداکثر نرخ ممکن باشد، محدودیت نرخ تاثیری بر نتایج نخواهد گذاشت.

هدف‌گذاری نرخ از طریق آغاز تراکنش‌ها در امتداد یک خط زمانی زمان‌بندی با توزیع پواسون (Poisson-distributed) انجام می‌شود. زمان‌بندی زمان شروع مورد انتظار، بر اساس زمان اولین شروع کلاینت به جلو حرکت می‌کند، نه بر اساس زمان پایان تراکنش قبلی. این رویکرد به این معنی است که وقتی تراکنش‌ها از زمان پایان برنامه‌ریزی‌شده اولیه خود فراتر می‌روند، این امکان وجود دارد که تراکنش‌های بعدی دوباره عقب‌افتادگی را جبران کنند.

هنگامی که محدودسازی نرخ (throttling) فعال است، تاخیر تراکنش گزارش‌شده در پایان اجرا از زمان‌های شروع زمان‌بندی‌شده محاسبه می‌شود؛ بنابراین شامل زمانی است که هر تراکنش باید منتظر می‌ماند تا تراکنش قبلی به پایان برسد. به این زمان انتظار، زمان تاخیر زمان‌بندی (schedule lag time) گفته می‌شود و میانگین و حداکثر آن نیز به طور جداگانه گزارش می‌شود. تاخیر تراکنش نسبت به زمان شروع واقعی تراکنش، یعنی زمان صرف‌شده برای اجرای تراکنش در پایگاه داده، می‌تواند با کم کردن زمان تاخیر زمان‌بندی از تاخیر گزارش‌شده محاسبه شود.

اگر --latency-limit همراه با --rate استفاده شود، ممکن است یک تراکنش به قدری عقب بیفتد که در زمان پایان تراکنش قبلی، از حد مجاز تاخیر فراتر رفته باشد، زیرا تاخیر از زمان شروع زمان‌بندی‌شده محاسبه می‌شود. چنین تراکنش‌هایی به سرور ارسال نمی‌شوند، بلکه به طور کامل نادیده گرفته شده و جداگانه شمرده می‌شوند.

بالا بودن زمان تاخیر زمان‌بندی نشان‌دهنده آن است که سیستم با تعداد کلاینت‌ها و ریسمان‌های انتخاب‌شده، قادر به پردازش تراکنش‌ها با نرخ تعیین‌شده نیست. هنگامی که میانگین زمان اجرای تراکنش طولانی‌تر از فاصله زمانی برنامه‌ریزی‌شده میان هر تراکنش باشد، هر تراکنش متوالی بیشتر عقب خواهد افتاد و با طولانی‌تر شدن اجرای آزمون، زمان تاخیر زمان‌بندی مدام افزایش می‌یابد. در چنین شرایطی، باید نرخ تراکنش مشخص‌شده را کاهش دهید.

-s scale_factor
--scale=scale_factor

ضریب مقیاس (scale factor) مشخص‌شده را در خروجی pgbench گزارش می‌کند. در آزمون‌های داخلی، این کار ضروری نیست؛ زیرا ضریب مقیاس صحیح با شمارش تعداد ردیف‌ها در جدول pgbench_branches تشخیص داده می‌شود. با این حال، هنگام آزمایش تنها بنچمارک‌های سفارشی (گزینه -f)، ضریب مقیاس برابر با ۱ گزارش خواهد شد مگر اینکه از این گزینه استفاده شود.

-S
--select-only

اسکریپت داخلی select-only را اجرا می‌کند. میانبری برای -b select-only.

-t transactions
--transactions=transactions

تعداد تراکنش‌هایی که هر کلاینت اجرا می‌کند. مقدار پیش‌فرض ۱۰ است.

-T seconds
--time=seconds

آزمون را به مدت این تعداد ثانیه اجرا می‌کند، به جای اجرای تعداد ثابتی از تراکنش‌ها به ازای هر کلاینت. -t و -T مانعة‌الجمع هستند (همزمان قابل استفاده نیستند).

-v
--vacuum-all

پیش از اجرای آزمون، هر چهار جدول استاندارد را خلاء‌زدایی (vacuum) می‌کند. بدون هیچ‌یک از گزینه‌های -n یا -v، برنامه pgbench جداول pgbench_tellers و pgbench_branches را خلاء‌زدایی (vacuum) کرده و جدول pgbench_history را خالی (truncate) می‌کند.

--aggregate-interval=seconds

طول بازه تجمیع (به ثانیه). فقط با گزینه -l قابل استفاده است. با این گزینه، فایل لاگ حاوی داده‌های خلاصه‌سازی به تفکیک بازه خواهد بود، همان‌طور که در زیر شرح داده شده است.

--exit-on-abort

هنگامی که هر کلاینتی به دلیل بروز خطا متوقف (abort) شود، بلافاصله خارج می‌شود. بدون این گزینه، حتی با متوقف شدن یک کلاینت، سایر کلاینت‌ها می‌توانند بر اساس مشخصات گزینه -t یا -T به اجرای خود ادامه دهند، و در این حالت pgbench نتایج ناقص را چاپ خواهد کرد.

توجه داشته باشید که شکست‌های سریال‌سازی یا بن‌بست باعث متوقف شدن کلاینت نمی‌شوند، بنابراین تحت تأثیر این گزینه قرار نمی‌گیرند. برای اطلاعات بیشتر، بخش Failures and Serialization/Deadlock Retries را ببینید.

--failures-detailed

شکست‌ها را در لاگ‌های تفکیکی تراکنش و تجمیع، و همچنین در گزارش‌های اصلی و تفکیکی اسکریپت، گروه‌بندی‌شده بر اساس انواع زیر گزارش می‌کند:
•شکست‌های سریال‌سازی (serialization failures)؛
•شکست‌های بن‌بست (deadlock failures)؛

برای اطلاعات بیشتر، بخش Failures and Serialization/Deadlock Retries را ببینید.

--log-prefix=prefix

پیشوند نام فایل را برای فایل‌های لاگ ایجادشده توسط --log تنظیم می‌کند. مقدار پیش‌فرض pgbench_log است.

--max-tries=number_of_tries

تلاش مجدد را برای تراکنش‌های دارای خطای سریال‌سازی/بن‌بست فعال کرده و حداکثر تعداد این تلاش‌ها را تعیین می‌کند. این گزینه می‌تواند با گزینه --latency-limit که کل زمان تمام تلاش‌های تراکنش را محدود می‌کند ترکیب شود؛ علاوه بر این، نمی‌توانید از تعداد نامحدود تلاش (--max-tries=0) بدون --latency-limit یا --time استفاده کنید. مقدار پیش‌فرض ۱ است و برای تراکنش‌های دارای خطای سریال‌سازی/بن‌بست تلاش مجدد صورت نمی‌گیرد. برای اطلاعات بیشتر درباره تلاش مجدد چنین تراکنش‌هایی، بخش Failures and Serialization/Deadlock Retries را ببینید.

--progress-timestamp

هنگام نمایش میزان پیشرفت (گزینه -P)، به جای تعداد ثانیه‌ها از شروع اجرا، از برچسب زمانی (Unix epoch) استفاده می‌کند. واحد آن بر حسب ثانیه، با دقت میلی‌ثانیه پس از ممیز است. این به مقایسه لاگ‌های تولیدشده توسط ابزارهای مختلف کمک می‌کند.

--random-seed=seed

دانه (seed) مولد تصادفی را تنظیم می‌کند. این گزینه مولد اعداد تصادفی سیستم را مقداردهی اولیه می‌کند که سپس توالی‌ای از وضعیت‌های اولیه مولد را برای هر ریسمان تولید می‌کند. مقادیر مجاز برای seed عبارتند از: time (حالت پیش‌فرض، دانه بر اساس زمان فعلی است)، rand (استفاده از یک منبع تصادفی قوی، که در صورت عدم دسترسی شکست می‌خورد)، یا یک مقدار عدد صحیح ده‌دهی بدون علامت. مولد تصادفی به صورت صریح از یک اسکریپت pgbench (توابع random..) یا به صورت ضمنی فراخوانی می‌شود (به عنوان مثال گزینه --rate از آن برای زمان‌بندی تراکنش‌ها استفاده می‌کند). هنگام تنظیم صریح، مقدار استفاده‌شده برای دانه در ترمینال نمایش داده می‌شود. هر مقدار مجازی برای seed می‌تواند از طریق متغیر محیطی PGBENCH_RANDOM_SEED نیز ارائه شود. برای اطمینان از اینکه دانه ارائه‌شده بر تمامی کاربردهای ممکن اثر بگذارد، این گزینه را در ابتدای دستور قرار دهید یا از متغیر محیطی استفاده کنید.

تنظیم صریح دانه امکان بازتولید دقیق اجرای pgbench را تا جایی که به اعداد تصادفی مربوط می‌شود، فراهم می‌کند. از آنجا که وضعیت تصادفی به ازای هر ریسمان مدیریت می‌شود، در صورتی که به ازای هر ریسمان یک کلاینت وجود داشته باشد و وابستگی خارجی یا داده‌ای وجود نداشته باشد، این به معنای اجرای دقیقاً یکسان pgbench برای یک فراخوانی مشابه خواهد بود. از دیدگاه آماری، بازتولید دقیق اجراها ایده مناسبی نیست زیرا می‌تواند تغییرپذیری کارایی را پنهان کرده یا عملکرد را به طور غیرواقعی بهبود بخشد؛ مثلاً با دسترسی به همان صفحاتی که در اجرای قبلی استفاده شده بودند. با این حال، می‌تواند برای اشکال‌زدایی، مثلاً اجرای مجدد یک مورد خاص و پیچیده که منجر به خطا شده است، کمک بسیار بزرگی باشد. خردمندانه استفاده کنید.

--sampling-rate=rate

نرخ نمونه‌برداری، هنگام نوشتن داده‌ها در فایل لاگ جهت کاهش حجم لاگ‌های تولیدی استفاده می‌شود. در صورت تعیین این گزینه، تنها کسری مشخص از تراکنش‌ها ثبت می‌شوند. مقدار 1.0 به این معنی است که تمام تراکنش‌ها لاگ می‌شوند، و 0.05 یعنی تنها ۵٪ از تراکنش‌ها ثبت خواهند شد.

به یاد داشته باشید که هنگام پردازش فایل لاگ، نرخ نمونه‌برداری را در نظر بگیرید. برای مثال، هنگام محاسبه مقادیر TPS، باید اعداد را متناسب با آن ضرب کنید (مثلاً با نرخ نمونه‌برداری 0.01، تنها به میزان ۱/۱۰۰ از مقدار واقعی TPS را دریافت خواهید کرد).

--show-script=scriptname

کد واقعی اسکریپت داخلی scriptname را در stderr نمایش داده و بلافاصله خارج می‌شود.

--verbose-errors

پیام‌های مربوط به تمام خطاها و شکست‌ها (خطاهای بدون تلاش مجدد) از جمله اینکه چه محدودیتی برای تلاش‌های مجدد فراتر رفته و تا چه میزان برای شکست‌های سریال‌سازی/بن‌بست فراتر رفته است را چاپ می‌کند. (توجه داشته باشید که در این حالت ممکن است خروجی به میزان قابل توجهی افزایش یابد.) برای اطلاعات بیشتر، بخش Failures and Serialization/Deadlock Retries را ببینید.

دستور pgbench همچنین آرگومان‌های معمول خط فرمان زیر را برای پارامترهای اتصال و سایر تنظیمات عمومی می‌پذیرد:

--debug

چاپ خروجی اشکال‌زدایی.

-h hostname
--host=hostname

نام میزبان سرور پایگاه داده.

-p port
--port=port

شماره پورت سرور پایگاه داده.

-U login
--username=login

نام کاربری برای اتصال به سرور.

-V
--version

چاپ نسخه pgbench و خروج.

-?
--help

نمایش راهنمای آرگومان‌های خط فرمان pgbench و خروج.

اجرای موفقیت‌آمیز با وضعیت 0 خارج می‌شود. کد خروج 1 نشان‌دهنده مشکلات ایستا مانند گزینه‌های نامعتبر خط فرمان یا خطاهای داخلی است که انتظار می‌رود هرگز رخ ندهند. خطاهای اولیه که هنگام شروع بنچ‌مارک رخ می‌دهند (مانند شکست در اتصال اولیه) نیز با وضعیت 1 خارج می‌شوند. خطاهای حین اجرا مانند خطاهای پایگاه داده یا مشکلات موجود در اسکریپت منجر به کد وضعیت خروج 2 خواهند شد. در حالت اخیر، چنانچه گزینه --exit-on-abort مشخص نشده باشد، pgbench نتایج جزئی را چاپ خواهد کرد.

PGDATABASE
PGHOST
PGPORT
PGUSER

پارامترهای پیش‌فرض اتصال.

این ابزار، مانند بیشتر ابزارهای دیگر PostgreSQL، از متغیرهای محیطی پشتیبانی‌شده توسط libpq استفاده می‌کند (به بخش 32.15 مراجعه کنید).

متغیر محیطی PG_COLOR مشخص می‌کند که آیا در پیام‌های تشخیصی از رنگ استفاده شود یا خیر. مقادیر ممکن عبارتند از always، auto و never.

pgbench اسکریپت‌های آزمایشی را که به‌صورت تصادفی از یک فهرست مشخص انتخاب شده‌اند، اجرا می‌کند. این اسکریپت‌ها می‌توانند شامل اسکریپت‌های توکار مشخص‌شده با -b و اسکریپت‌های ارائه‌شده توسط کاربر مشخص‌شده با -f باشند. به هر اسکریپت می‌توان یک وزن نسبی اختصاص داد که پس از علامت @ مشخص می‌شود تا احتمال انتخاب آن تغییر کند. وزن پیش‌فرض 1 است. اسکریپت‌های با وزن 0 نادیده گرفته می‌شوند.

اسکریپت تراکنش توکار پیش‌فرض (که با -b tpcb-like نیز فراخوانی می‌شود) در هر تراکنش هفت دستور را روی مقادیر تصادفی انتخاب‌شده از aid، tid، bid و delta صادر می‌کند. این سناریو از بنچ‌مارک TPC-B الهام گرفته شده است، اما در واقع خود TPC-B نیست، و نام‌گذاری آن نیز به همین دلیل است.

1.BEGIN;
2.UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
3.SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
4.UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
5.UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
6.INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
7.END;

اگر اسکریپت توکار simple-update را انتخاب کنید (همچنین با -N)، مراحل 4 و 5 در تراکنش گنجانده نمی‌شوند. این کار از رقابت به‌روزرسانی بر روی این جدول‌ها جلوگیری می‌کند، اما مورد آزمایشی را حتی کمتر از قبل شبیه TPC-B می‌سازد.

اگر اسکریپت توکار select-only را انتخاب کنید (همچنین با -S)، تنها دستور SELECT صادر می‌شود.

ابزار pgbench از اجرای سناریوهای محک (benchmark) سفارشی از طریق جایگزین کردن اسکریپت تراکنش پیش‌فرض (توصیف‌شده در بالا) با یک اسکریپت تراکنش خوانده‌شده از فایل (گزینه -f) پشتیبانی می‌کند. در این حالت یک “تراکنش” معادل یک بار اجرای فایل اسکریپت در نظر گرفته می‌شود.

یک فایل اسکریپت شامل یک یا چند دستور SQL است که با نقطه-ویرگول خاتمه می‌یابند. خطوط خالی و خطوطی که با -- شروع می‌شوند نادیده گرفته می‌شوند. همچنین فایل‌های اسکریپت می‌توانند شامل “دستورهای متا” باشند که همان‌طور که در ادامه شرح داده شده است توسط خود pgbench تفسیر می‌شوند.


نکته

پیش از PostgreSQL نسخه 9.6، دستورهای SQL در فایل‌های اسکریپت با خطوط جدید خاتمه می‌یافتند و بنابراین نمی‌توانستند در چندین خط ادامه یابند. اکنون برای جداسازی دستورهای متوالی SQL استفاده از نقطه-ویرگول الزامی است (اگرچه در صورتی که پس از یک دستور SQL یک دستور متا بیاید، نیازی به نقطه-ویرگول نیست). اگر نیاز به ایجاد یک فایل اسکریپت دارید که با هر دو نسخه قدیمی و جدید pgbench کار کند، حتماً هر دستور SQL را روی یک خط مجزا و ختم به نقطه-ویرگول بنویسید.

فرض بر این است که اسکریپت‌های pgbench شامل بلوک‌های ناقص از تراکنش‌های SQL نیستند. اگر در زمان اجرا کلاینت بدون تکمیل آخرین بلوک تراکنش به انتهای اسکریپت برسد، لغو (abort) خواهد شد.

یک قابلیت ساده برای جایگزینی متغیرها در فایل‌های اسکریپت وجود دارد. نام متغیرها باید شامل حروف (از جمله حروف غیرلاتین)، ارقام و خط زیر (underscore) باشد، به‌طوری که کاراکتر اول رقم نباشد. متغیرها را می‌توان با گزینه خط فرمان -D که در بالا توضیح داده شد، یا با دستورهای متا که در ادامه شرح داده می‌شوند، مقداردهی کرد. علاوه بر متغیرهایی که از قبل با گزینه‌های خط فرمان -D تنظیم شده‌اند، چند متغیر وجود دارند که به‌طور خودکار مقداردهی اولیه می‌شوند و در Table 301 فهرست شده‌اند. مقداری که با استفاده از -D برای این متغیرها مشخص شود، بر مقادیر خودکار پیش‌فرض تقدم دارد. پس از تنظیم، مقدار یک متغیر را می‌توان با نوشتن :variablename درون یک دستور SQL درج کرد. هنگام اجرای بیش از یک نشست کلاینت، هر نشست مجموعه متغیرهای خاص خود را دارد. pgbench تا ۲۵۵ بار استفاده از متغیر را در یک دستور پشتیبانی می‌کند.

Table 301. pgbench Automatic Variables

Variable توضیحات
client_id شماره یکتای شناسایی نشست کلاینت (از صفر شروع می‌شود)
default_seed سید پیش‌فرض استفاده‌شده در توابع هش و جایگشت شبه‌تصادفی
random_seed سید مولد تصادفی (مگر اینکه با -D بازنویسی شود)
scale ضریب مقیاس فعلی

دستورهای متای فایل اسکریپت با یک بک‌اسلش (\) آغاز می‌شوند و به‌طور معمول تا انتهای خط امتداد می‌یابند، اگرچه می‌توان با نوشتن بک‌اسلش-اینتر (backslash-return) آن‌ها را در خطوط بعدی نیز ادامه داد. آرگومان‌های یک دستور متا با فاصله (white space) از هم جدا می‌شوند. این دستورهای متا پشتیبانی می‌شوند:

\gset [prefix] \aset [prefix]

این دستورها ممکن است برای پایان دادن به پرس‌وجوهای SQL استفاده شوند و جایگزین نقطه-ویرگول پایانی (;) گردند.

هنگامی که دستور \gset استفاده می‌شود، انتظار می‌رود پرس‌وجوی SQL قبلی یک سطر بازگرداند؛ ستون‌های این سطر در متغیرهایی به نام همان ستون‌ها ذخیره می‌شوند و در صورت مشخص شدن prefix، پیشوند مذکور به ابتدای آن‌ها اضافه می‌شود.

هنگامی که دستور \aset استفاده می‌شود، تمام پرس‌وجوهای ترکیبی SQL (که با \; از هم جدا شده‌اند) ستون‌هایشان در متغیرهایی هم‌نام با ستون‌ها ذخیره می‌شود و در صورت تعیین prefix، این پیشوند به ابتدای آن‌ها افزوده می‌شود. اگر یک پرس‌وجو هیچ سطری بازنگرداند، هیچ مقداری تخصیص داده نمی‌شود و برای تشخیص این حالت می‌توان وجود متغیر را بررسی کرد. اگر یک پرس‌وجو بیش از یک سطر بازگرداند، مقدار آخرین سطر حفظ می‌شود.

دستورهای \gset و \aset نمی‌توانند در حالت خط‌لوله‌ای (pipeline mode) استفاده شوند، زیرا نتایج پرس‌وجو در زمانی که دستورها به آن‌ها نیاز دارند هنوز در دسترس نیستند.

مثال زیر موجودی نهایی حساب را از پرس‌وجوی اول در متغیر 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

این گروه از دستورها بلوک‌های شرطی تودرتو را به‌طور مشابه با دستور \if expression در psql پیاده‌سازی می‌کنند. عبارت‌های شرطی با عبارت‌های موجود در \set یکسان هستند و مقادیر غیرصفر به عنوان درست (true) تفسیر می‌شوند.

\set varname expression

متغیر varname را به مقداری محاسبه‌شده از expression تنظیم می‌کند. این عبارت می‌تواند شامل ثابت NULL، ثابت‌های بولی (Boolean) TRUE و FALSE، ثابت‌های عدد صحیح مانند 5432، ثابت‌های ممیز شناور (double) مانند 3.14159، ارجاع به متغیرها به‌صورت :variablename، عملگرها با اولویت و شرکت‌پذیری معمول خود در SQL، فراخوانی توابع، عبارت‌های شرطی عمومی CASE در SQL و پرانتزها باشد.

توابع و اغلب عملگرها در ازای ورودی NULL، مقدار NULL بازمی‌گردانند.

برای مقاصد شرطی، مقادیر عددی غیرصفر معادل TRUE بوده و مقادیر عددی صفر و NULL معادل FALSE هستند.

ثابت‌های عدد صحیح و ممیز شناور (double) بسیار بزرگ یا بسیار کوچک، و همچنین عملگرهای محاسباتی اعداد صحیح (+، -, * و /) در صورت سرریز (overflow) خطا تولید می‌کنند.

هنگامی که هیچ بند پایانی 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 ]

باعث توقف (sleep) اجرای اسکریپت برای مدت زمان مشخص‌شده بر حسب میکروثانیه (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
\syncpipeline
\endpipeline

این گروه از دستورها قابلیت خط‌لوله‌سازی (pipelining) عبارت‌های SQL را پیاده‌سازی می‌کنند. یک خط‌لوله باید با یک \startpipeline شروع شده و با یک \endpipeline خاتمه یابد. در این میان ممکن است هر تعداد دستور \syncpipeline وجود داشته باشد، که یک پیام همگام‌سازی (sync message) را بدون پایان دادن به خط‌لوله جاری و همراه با تخلیه بافر ارسال (flush)، ارسال می‌کند. در حالت خط‌لوله‌ای، عبارت‌ها بدون منتظر ماندن برای دریافت نتایج عبارت‌های قبلی به سرور ارسال می‌شوند. برای جزئیات بیشتر به بخش 32.5 مراجعه کنید. حالت خط‌لوله‌ای مستلزم استفاده از پروتکل پرس‌وجوی توسعه‌یافته (extended query protocol) است.

عملگرهای حسابی، بیتی، مقایسه‌ای و منطقی فهرست‌شده در Table 302 به‌صورت توکار در pgbench پیاده‌سازی شده‌اند و می‌توان از آن‌ها در عبارت‌هایی که در \set می‌آیند استفاده کرد. این عملگرها به ترتیب اولویت صعودی فهرست شده‌اند. به‌جز موارد قید شده، عملگرهایی که دو ورودی عددی می‌گیرند، در صورتی که هر یک از ورودی‌ها از نوع اعشاری (double) باشد، مقداری از نوع double تولید می‌کنند؛ در غیر این صورت، نتیجه از نوع عدد صحیح (integer) خواهد بود.

Table 302. pgbench Operators

Operator .PP توضیحات (Description) .PP Example(s)
boolean OR boolean → boolean .PP OR منطقی .PP 5 or 0 → TRUE
boolean AND boolean → boolean .PP AND منطقی .PP 3 and 0 → FALSE
NOT boolean → boolean .PP NOT منطقی .PP not false → TRUE
boolean IS [NOT] (NULL|TRUE|FALSE) → boolean .PP آزمون‌های مقدار بولی (Boolean) .PP 1 is null → FALSE
value ISNULL|NOTNULL → boolean .PP آزمون‌های تهی بودن (Nullness) .PP 1 notnull → TRUE
number = number → boolean .PP برابر .PP 5 = 4 → FALSE
number <> number → boolean .PP نابرابر .PP 5 <> 4 → TRUE
number != number → boolean .PP نابرابر .PP 5 != 5 → FALSE
number < number → boolean .PP کوچک‌تر از .PP 5 < 4 → FALSE
number <= number → boolean .PP کوچک‌تر یا مساوی با .PP 5 <= 4 → FALSE
number > number → boolean .PP بزرگ‌تر از .PP 5 > 4 → TRUE
number >= number → boolean .PP بزرگ‌تر یا مساوی با .PP 5 >= 4 → TRUE
integer | integer → integer .PP OR بیتی .PP 1 | 2 → 3
integer # integer → integer .PP XOR بیتی .PP 1 # 3 → 2
integer & integer → integer .PP AND بیتی .PP 1 & 3 → 1
~ integer → integer .PP NOT بیتی .PP ~ 1 → -2
integer << integer → integer .PP شیفت بیتی به چپ .PP 1 << 2 → 4
integer >> integer → integer .PP شیفت بیتی به راست .PP 8 >> 2 → 2
number + number → number .PP جمع .PP 5 + 4 → 9
number - number → number .PP تفریق .PP 3 - 2.0 → 1.0
number * number → number .PP ضرب .PP 5 * 4 → 20
number / number → number .PP تقسیم (اگر هر دو ورودی عدد صحیح باشند، نتیجه به سمت صفر قطع می‌شود) .PP 5 / 3 → 1
integer % integer → integer .PP باقی‌مانده (Modulo) .PP 3 % 2 → 1
- number → number .PP قرینه‌سازی (Negation) .PP - 2.0 → -2.0

توابع فهرست‌شده در
Table 303 به‌صورت توکار در pgbench پیاده‌سازی شده‌اند و می‌توان از آن‌ها در عبارت‌هایی که در \set می‌آیند استفاده کرد.

Table 303. pgbench Functions

Function .PP توضیحات (Description) .PP Example(s)
abs ( number ) → same type as input .PP مقدار مطلق .PP abs(-17) → 17
debug ( number ) → same type as input .PP آرگومان را در stderr چاپ کرده و همان آرگومان را برمی‌گرداند. .PP debug(5432.1) → 5432.1
double ( number ) → double .PP به نوع double تبدیل می‌کند. .PP double(5432) → 5432.0
exp ( number ) → double .PP تابع نمایی (عدد e به توان مقدار داده‌شده) .PP exp(1.0) → 2.718281828459045
greatest ( number [, ... ] ) → double if any argument is double, else integer .PP بزرگ‌ترین مقدار را از میان آرگومان‌ها انتخاب می‌کند. .PP greatest(5, 4, 3, 2) → 5
hash ( value [, seed ] ) → integer .PP این یک نام مستعار برای hash_murmur2 است. .PP hash(10, 5432) → -5817877081768721676
hash_fnv1a ( value [, seed ] ) → integer .PP هش FNV-1a را محاسبه می‌کند. .PP hash_fnv1a(10, 5432) → -7793829335365542153
hash_murmur2 ( value [, seed ] ) → integer .PP هش MurmurHash2 را محاسبه می‌کند. .PP hash_murmur2(10, 5432) → -5817877081768721676
int ( number ) → integer .PP به نوع integer تبدیل می‌کند. .PP int(5.4 + 3.8) → 9
least ( number [, ... ] ) → double if any argument is double, else integer .PP کوچک‌ترین مقدار را از میان آرگومان‌ها انتخاب می‌کند. .PP least(5, 4, 3, 2.1) → 2.1
ln ( number ) → double .PP لگاریتم طبیعی .PP ln(2.718281828459045) → 1.0
mod ( integer, integer ) → integer .PP باقی‌مانده تقسیم (Modulo) .PP mod(54, 32) → 22
permute ( i, size [, seed ] ) → integer .PP مقدار جایگشت‌یافته‌ی i در بازه [0, size). این موقعیت جدید i (به پیمانه‌ی size) در یک جایگشت شبه‌تصادفی از اعداد صحیح 0...size-1 با پارامتر seed است؛ به پایین مراجعه کنید. .PP permute(0, 4) → an integer between 0 and 3
pi () → double .PP مقدار تقریبی π .PP pi() → 3.14159265358979323846
pow ( x, y ) → double .PP power ( x, y ) → double .PP x به توان y .PP pow(2.0, 10) → 1024.0
random ( lb, ub ) → integer .PP یک عدد صحیح تصادفی با توزیع یکنواخت در بازه [lb, ub] محاسبه می‌کند. .PP random(1, 10) → an integer between 1 and 10
random_exponential ( lb, ub, parameter ) → integer .PP یک عدد صحیح تصادفی با توزیع نمایی در بازه [lb, ub] محاسبه می‌کند؛ به پایین مراجعه کنید. .PP random_exponential(1, 10, 3.0) → an integer between 1 and 10
random_gaussian ( lb, ub, parameter ) → integer .PP یک عدد صحیح تصادفی با توزیع گاوسی در بازه [lb, ub] محاسبه می‌کند؛ به پایین مراجعه کنید. .PP random_gaussian(1, 10, 2.5) → an integer between 1 and 10
random_zipfian ( lb, ub, parameter ) → integer .PP یک عدد صحیح تصادفی با توزیع زیپف در بازه [lb, ub] محاسبه می‌کند؛ به پایین مراجعه کنید. .PP random_zipfian(1, 10, 1.5) → an integer between 1 and 10
sqrt ( number ) → double .PP ریشه دوم (جذر) .PP sqrt(2.0) → 1.414213562

تابع
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).

به‌طور شهودی، هرچه parameter بزرگ‌تر باشد، مقادیر نزدیک به min با بسامد بیشتری مورد دسترسی قرار می‌گیرند، و مقادیر نزدیک به max با بسامد کمتری دسترسی می‌یابند. هرچه parameter به 0 نزدیک‌تر باشد، توزیع دسترسی مسطح‌تر (یکنواخت‌تر) خواهد بود. یک تقریب سرانگشتی از توزیع این است که ۱٪ پربسامدترین مقادیر در محدوده، نزدیک به min، در parameter٪ از مواقع انتخاب می‌شوند. مقدار parameter باید اکیداً مثبت باشد.

•برای توزیع گاوسی، بازه بر یک توزیع نرمال استاندارد (منحنی زنگوله‌ای کلاسیک گاوسی) که از چپ در -parameter و از راست در +parameter برش خورده است نگاشت می‌شود. مقادیر در میانه بازه با احتمال بیشتری انتخاب می‌شوند. به بیان دقیق، اگر PHI(x) تابع توزیع تجمعی توزیع نرمال استاندارد با میانگین mu تعریف‌شده به‌صورت (max + min) / 2.0 باشد، با فرض:
f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) /
       (2.0 * PHI(parameter) - 1)

آن‌گاه مقدار i بین min و max (شامل هر دو) با احتمال زیر انتخاب می‌شود: f(i + 0.5) - f(i - 0.5). به‌طور شهودی، هرچه parameter بزرگ‌تر باشد، مقادیر نزدیک به میانه بازه با بسامد بیشتری انتخاب می‌شوند، و مقادیر نزدیک به کران‌های min و max با بسامد کمتری انتخاب می‌گردند. حدود ۶۷٪ از مقادیر از میانه 1.0 / parameter، یعنی به نسبت 0.5 / parameter در اطراف میانگین، و ۹۵٪ در میانه 2.0 / parameter، یعنی به نسبت 1.0 / parameter در اطراف میانگین انتخاب می‌شوند؛ برای مثال، اگر parameter برابر 4.0 باشد، ۶۷٪ مقادیر از یک‌چهارم میانی (1.0 / 4.0) بازه (یعنی از 3.0 / 8.0 تا 5.0 / 8.0) و ۹۵٪ از نیمه میانی (2.0 / 4.0) بازه (چارک‌های دوم و سوم) انتخاب می‌شوند. کمترین مقدار مجاز برای parameter برابر 2.0 است.

•random_zipfian یک توزیع زیپف (Zipfian) کران‌دار تولید می‌کند. parameter میزان چولگی توزیع را تعیین می‌کند. هرچه parameter بزرگ‌تر باشد، مقادیر نزدیک‌تر به ابتدای بازه با بسامد بیشتری انتخاب می‌شوند. توزیع به گونه‌ای است که با فرض شروع بازه از ۱، نسبت احتمال انتخاب 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 بر اساس مرجع "Non-Uniform Random Variate Generation" نوشته Luc Devroye، صفحات ۵۵۰-۵۵۱، انتشارات Springer سال ۱۹۸۶ است. به دلیل محدودیت‌های آن الگوریتم، مقدار parameter به بازه [1.001, 1000] محدود شده است.


نکته

هنگام طراحی یک بنچمارک که سطرها را به‌طور غیریکنواخت انتخاب می‌کند، آگاه باشید سطرهای انتخاب‌شده ممکن است با سایر داده‌ها مانند شناسه‌های حاصل از یک دنباله یا ترتیب فیزیکی سطرها همبستگی داشته باشند، که این امر می‌تواند اندازه‌گیری‌های عملکرد را منحرف کند.

برای جلوگیری از این امر، ممکن است بخواهید از تابع permute یا مراحل تکمیلی دیگر با اثری مشابه استفاده کنید تا سطرهای انتخابی را بُر بزنید (shuffle) و چنین همبستگی‌هایی را حذف نمایید.

توابع هش hash، hash_murmur2 و hash_fnv1a یک مقدار ورودی و یک پارامتر بذر (seed) اختیاری می‌پذیرند. در صورتی که بذر تعیین نشود، مقدار :default_seed استفاده می‌شود که به‌طور تصادفی مقداردهی اولیه می‌گردد، مگر اینکه با گزینه -D خط فرمان تنظیم شده باشد.

تابع permute یک مقدار ورودی، یک اندازه، و یک پارامتر بذر اختیاری می‌پذیرد. این تابع یک جایگشت شبه‌تصادفی از اعداد صحیح در محدوده [0, size) تولید کرده و نمایه (index) مقدار ورودی را در میان مقادیر جایگشت‌یافته برمی‌گرداند. جایگشت انتخاب‌شده توسط بذر پارامترسازی می‌شود که در صورت عدم تعیین، به‌طور پیش‌فرض :default_seed است. برخلاف توابع هش، permute تضمین می‌کند که هیچ تداخل (collision) یا شکافی در مقادیر خروجی وجود نداشته باشد. مقادیر ورودی خارج از بازه بر مبنای باقی‌مانده تقسیم بر اندازه (modulo size) تفسیر می‌شوند. اگر اندازه مثبت نباشد، تابع یک خطا صادر می‌کند.

permute می‌تواند برای پراکنده ساختن توزیع توابع تصادفی غیریکنواخت مانند random_zipfian یا random_exponential به‌کار رود تا مقادیری که بیشتر انتخاب می‌شوند همبستگی آشکاری با یکدیگر نداشته باشند. برای مثال، اسکریپت pgbench زیر یک بار کاری واقعی احتمالی را شبیه‌سازی می‌کند که برای شبکه‌های اجتماعی و پلتفرم‌های وبلاگ‌نویسی معمول است؛ جایی که تعداد کمی از حساب‌ها بار کاری بسیار زیادی ایجاد می‌کنند:

\set size 1000000
\set r random_zipfian(1, :size, 1.07)
\set k 1 + permute(:r, :size)

در برخی موارد به چند توزیع متمایز نیاز است که با یکدیگر همبستگی نداشته باشند و در اینجاست که پارامتر بذر اختیاری به کار می‌آید:

\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 تداخل (collision) تولید می‌کند، برخی مقادیر در دسترس نخواهند بود و برخی دیگر با بسامدی بیش از آنچه از توزیع اصلی انتظار می‌رود رخ خواهند داد.

به‌عنوان مثال، تعریف کامل تراکنش پیش‌ساخته مشابه 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 برابر ۲ یا بیشتر باشد، به طوری که چندین رشته کاری (worker threads) وجود داشته باشد، هر کدام فایل لاگ اختصاصی خود را خواهند داشت. اولین worker از همان نامی برای فایل لاگ خود استفاده می‌کند که در حالت استاندارد تک‌worker استفاده می‌شود. فایل‌های لاگ اضافی برای سایر workerها با الگوی prefix.nnn.mmm نام‌گذاری می‌شوند، که در آن mmm یک شماره ترتیبی برای هر worker است که از ۱ آغاز می‌شود.

هر خط در فایل لاگ، یک تراکنش را شرح می‌دهد. این خط شامل فیلدهای زیر است که با فاصله از هم جدا شده‌اند:

client_id

نشست کلاینتی (client session) را که تراکنش را اجرا کرده مشخص می‌کند

transaction_no

تعداد تراکنش‌های اجرا شده توسط آن نشست را می‌شمارد

time

زمان سپری‌شده تراکنش، به میکروثانیه

script_no

فایل اسکریپت مورد استفاده برای تراکنش را مشخص می‌کند (زمانی که چند اسکریپت با -f یا -b تعیین شده باشند کاربرد دارد)

time_epoch

زمان اتمام تراکنش، به صورت برچسب زمانی مبدا یونیکس (Unix-epoch timestamp)

time_us

بخش کسری ثانیه از زمان اتمام تراکنش، به میکروثانیه

schedule_lag

تاخیر در آغاز تراکنش؛ یعنی اختلاف میان زمان زمان‌بندی‌شده آغاز تراکنش و زمانی که عملاً آغاز شده است، به میکروثانیه (تنها در صورتی که --rate تعیین شده باشد وجود دارد)

retries

تعداد تلاش‌های مجدد پس از خطاهای سری‌سازی (serialization) یا بن‌بست (deadlock) در حین تراکنش (تنها در صورتی که --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

در این مثال، تراکنش ۸۲ با تاخیر مواجه شد، زیرا زمان تاخیر آن (۶.۱۷۳ میلی‌ثانیه) فراتر از محدودیت ۵ میلی‌ثانیه بود. دو تراکنش بعدی نادیده گرفته شدند (skipped)، زیرا پیش از آنکه حتی آغاز شوند، بیش از حد به تاخیر افتاده بودند.

مثال زیر بخشی از یک فایل لاگ به همراه خطاها و تلاش‌های مجدد را نشان می‌دهد، که در آن حداکثر تعداد تلاش‌ها روی ۱۰ تنظیم شده است (به ستون اضافی 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 timestamp)

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 برابر با ۱ نباشد.

تمام مقادیر برای هر دستور اجراشده توسط هر کلاینت محاسبه شده و پس از پایان آزمون محک گزارش می‌شوند.

برای اسکریپت پیش‌فرض، خروجی مشابه زیر خواهد بود:

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;

مثال دیگری از خروجی برای اسکریپت پیش‌فرض با استفاده از سطح انزوای پیش‌فرض سریال‌پذیر تراکنش (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;

اگر چندین فایل اسکریپت مشخص شده باشد، تمامی آمارها برای هر فایل اسکریپت به‌طور جداگانه گزارش می‌شوند.

توجه داشته باشید که جمع‌آوری اطلاعات زمان‌بندی اضافی مورد نیاز برای محاسبه تاخیر به ازای هر دستور، مقداری بار اضافی (overhead) تحمیل می‌کند. این امر سرعت میانگین اجرا را کاهش داده و TPS محاسبه‌شده را پایین می‌آورد. میزان این افت سرعت بسته به پلتفرم و سخت‌افزار تفاوت چشمگیری دارد. مقایسه مقادیر میانگین TPS در دو حالت فعال بودن و غیرفعال بودن گزارش تاخیر، روش مناسبی برای ارزیابی قابل‌توجه بودن بار اضافی زمان‌بندی است.

هنگام اجرای pgbench ، سه نوع اصلی از خطاها وجود دارند:

•خطاهای برنامه اصلی. این خطاها جدی‌ترین موارد هستند و همواره به خروج فوری از pgbench همراه با پیام خطای مربوطه منجر می‌شوند. آن‌ها شامل موارد زیر هستند:
•خطاها در آغاز اجرای pgbench (مانند مقدار نامعتبر برای یک گزینه)؛
•خطاها در حالت مقداردهی اولیه (مانند شکست در کوئری ایجاد جدول‌ها برای اسکریپت‌های توکار)؛
•خطاها پیش از شروع نخ‌ها (مانند عدم برقراری اتصال به سرور پایگاه داده، خطای نحوی در متادستور، یا شکست در ایجاد نخ)؛
•خطاهای داخلی pgbench (که فرض بر این است که هرگز رخ نخواهند داد..)؛
•خطاها هنگام مدیریت کلاینت‌ها توسط نخ (مانند عدم توانایی کلاینت در شروع اتصال به سرور پایگاه داده / نامعتبر شدن سوکت اتصال کلاینت به سرور پایگاه داده). در چنین حالتی تمامی کلاینت‌های این نخ متوقف می‌شوند در حالی که سایر نخ‌ها به کار خود ادامه می‌دهند. با این حال، اگر گزینه --exit-on-abort مشخص شده باشد، در این حالت تمامی نخ‌ها بلافاصله متوقف می‌شوند.
•خطاهای مستقیم کلاینت. این خطاها در صورت بروز یک خطای داخلی pgbench (که فرض می‌شود هرگز رخ نخواهند داد..) یا زمانی که گزینه --exit-on-abort مشخص شده باشد، منجر به خروج فوری از pgbench همراه با پیام خطای مربوطه می‌شوند. در غیر این صورت، در بدترین حالت تنها به لغو شدن کلاینت ناموفق منجر می‌شوند در حالی که سایر کلاینت‌ها به کار خود ادامه می‌دهند (اما برخی از خطاهای کلاینت بدون لغو کلاینت مدیریت شده و به‌طور جداگانه گزارش می‌گردند، در ادامه ببینید). در ادامه این بخش فرض می‌شود که خطاهای مورد بحث، فقط خطاهای مستقیم کلاینت بوده و از خطاهای داخلی pgbench نیستند.

اجرای یک کلاینت در صورت بروز یک خطای جدی لغو می‌شود؛ به عنوان مثال، اتصال با سرور پایگاه داده قطع شود یا پایان اسکریپت بدون تکمیل آخرین تراکنش فرا برسد. علاوه بر این، اگر اجرای یک دستور SQL یا یک متادستور به دلایلی غیر از خطاهای سریال‌سازی یا بن‌بست با شکست مواجه شود، کلاینت لغو می‌گردد. در غیر این صورت، چنانچه یک دستور SQL با خطاهای سریال‌سازی یا بن‌بست مواجه شود، کلاینت لغو نخواهد شد. در چنین حالت‌هایی، تراکنش جاری به عقب بازگردانده می‌شود (rollback)، که شامل بازگرداندن متغیرهای کلاینت به وضعیت پیش از اجرای این تراکنش نیز می‌گردد (فرض بر این است که یک اسکریپت تراکنش تنها شامل یک تراکنش است؛ برای اطلاعات بیشتر به «تراکنش» اجرا شده در pgbench دقیقاً چیست؟ (What Is the "Transaction" Actually Performed in pgbench?) مراجعه کنید). تراکنش‌های دارای خطای سریال‌سازی یا بن‌بست پس از rollback تکرار می‌شوند تا زمانی که با موفقیت به پایان برسند یا به حداکثر تعداد تلاش‌ها (مشخص‌شده با گزینه --max-tries ) / حداکثر زمان تلاش‌های مجدد (مشخص‌شده با گزینه --latency-limit ) / پایان آزمون محک (مشخص‌شده با گزینه --time ) برسند. اگر آخرین تلاش برای اجرا شکست بخورد، این تراکنش به عنوان ناموفق گزارش می‌شود اما کلاینت لغو نخواهد شد و به کار خود ادامه می‌دهد.


یادداشت (Note)

بدون تعیین گزینه --max-tries ، یک تراکنش پس از خطای سریال‌سازی یا بن‌بست هرگز دوباره تکرار نخواهد شد، زیرا مقدار پیش‌فرض آن ۱ است. از تعداد نامحدود تلاش (--max-tries=0) و گزینه --latency-limit استفاده کنید تا تنها حداکثر زمان تلاش‌ها را محدود سازید. همچنین می‌توانید از گزینه --time برای محدود کردن مدت‌زمان آزمون محک در شرایط تعداد نامحدود تلاش استفاده نمایید.

هنگام تکرار اسکریپت‌هایی که شامل چندین تراکنش هستند مراقب باشید: اسکریپت همواره به‌طور کامل دوباره اجرا می‌شود، بنابراین ممکن است تراکنش‌های موفق چندین بار انجام شوند.

هنگام تکرار تراکنش‌های دارای دستورات پوسته (shell) مراقب باشید. برخلاف نتایج دستورات SQL، نتایج دستورات پوسته به عقب بازگردانده نمی‌شوند (roll back نمی‌شوند)، به جز مقدار متغیر دستور \setshell .

تاخیر یک تراکنش موفق شامل کل مدت زمان اجرای تراکنش همراه با بازگردانی‌ها (rollbacks) و تلاش‌های مجدد است. تاخیر فقط برای تراکنش‌ها و دستورات موفق اندازه‌گیری می‌شود، نه برای تراکنش‌ها یا دستورات ناموفق.

گزارش اصلی شامل تعداد تراکنش‌های ناموفق است. اگر گزینه --max-tries مخالف ۱ باشد، گزارش اصلی همچنین شامل آمار مربوط به تلاش‌های مجدد خواهد بود: تعداد کل تراکنش‌های بازآزموده‌شده و تعداد کل تلاش‌های مجدد. گزارش به ازای هر اسکریپت تمام این فیلدها را از گزارش اصلی به ارث می‌برد. گزارش به ازای هر دستور آمار تلاش مجدد را تنها در صورتی نمایش می‌دهد که گزینه --max-tries مخالف ۱ باشد.

اگر می‌خواهید شکست‌ها را بر اساس انواع پایه در لاگ‌های به ازای تراکنش و تجمیعی، و همچنین در گزارش‌های اصلی و به ازای اسکریپت دسته‌بندی کنید، از گزینه --failures-detailed استفاده کنید. اگر می‌خواهید همه خطاها و شکست‌ها (خطاهای بدون تلاش مجدد) را بر اساس نوع تفکیک کنید، شامل این‌که کدام حد مجاز برای تلاش‌های مجدد رد شده است و برای شکست‌های سریال‌سازی/بن‌بست چقدر از آن حد فراتر رفته است، از گزینه --verbose-errors استفاده نمایید.

شما می‌توانید روش دسترسی به جدول (Table Access Method) را برای جداول pgbench مشخص کنید. متغیر محیطی PGOPTIONS گزینه‌های پیکربندی پایگاه داده را که از طریق خط فرمان به PostgreSQL ارسال می‌شوند، تعیین می‌کند (بخش Section 19.1.4 را ببینید). برای نمونه، یک روش فرضی دسترسی به جدول پیش‌فرض برای جداولی که pgbench ایجاد می‌کند به نام wuzza را می‌توان با دستور زیر مشخص کرد:

PGOPTIONS='-c default_table_access_method=wuzza'

تولید اعداد و ارقام کاملاً بی‌معنی با استفاده از pgbench بسیار آسان است. در اینجا چند دستورالعمل برای کمک به دریافت نتایج مفید آورده شده است.

در وهله نخست، هرگز به آزمونی که تنها چند ثانیه اجرا می‌شود اعتماد نکنید. از گزینه -t یا -T استفاده کنید تا اجرای آزمون حداقل چند دقیقه طول بکشد و نوسانات و نویزها به صورت میانگین تعدیل شوند. در برخی موارد ممکن است برای دستیابی به اعدادی که تکرارپذیر باشند، به ساعت‌ها زمان نیاز داشته باشید. ایده خوبی است که اجرای آزمون را چند بار امتحان کنید تا مشخص شود که آیا اعداد به‌دست‌آمده تکرارپذیر هستند یا خیر.

برای سناریوی آزمایشی پیش‌فرض مشابه TPC-B، ضریب مقیاس مقداردهی اولیه (-s) باید حداقل به بزرگی بیشترین تعداد کلاینت‌هایی باشد که قصد آزمایش آن‌ها را دارید (-c)؛ در غیر این صورت، عمدتاً در حال اندازه‌گیری رقابت بر سر به‌روزرسانی (update contention) خواهید بود. در جدول pgbench_branches تنها به تعداد -s ردیف وجود دارد، و هر تراکنش می‌خواهد یکی از آن‌ها را به‌روزرسانی کند، بنابراین مقادیر -c بیشتر از -s بدون شک منجر به مسدود شدن بسیاری از تراکنش‌ها در انتظار سایر تراکنش‌ها خواهد شد.

سناریوی آزمون پیش‌فرض همچنین نسبت به مدت‌زمانی که از مقداردهی اولیه جدول‌ها گذشته بسیار حساس است: انباشت ردیف‌های مرده (dead rows) و فضای خالی در جدول‌ها نتایج را تغییر می‌دهد. برای درک درست نتایج، باید تعداد کل به‌روزرسانی‌ها و زمان انجام عملیات پاکسازی (vacuuming) را زیر نظر داشته باشید. در صورت فعال بودن autovacuum، ممکن است تغییرات غیرقابل پیش‌بینی در کارایی اندازه‌گیری‌شده رخ دهد.

یکی از محدودیت‌های pgbench این است که هنگام آزمایش تعداد زیادی از نشست‌های کلاینت، خودش می‌تواند به یک گلوگاه (bottleneck) تبدیل شود. این مشکل را می‌توان با اجرای pgbench روی ماشینی مجزا از سرور پایگاه داده کاهش داد، هرچند تاخیر پایین شبکه (low network latency) در این حالت ضروری خواهد بود. حتی ممکن است اجرای همزمان چندین نمونه از pgbench روی چندین ماشین کلاینت علیه یک سرور پایگاه داده مفید باشد.

اگر کاربران غیرقابل‌اعتماد به پایگاه داده‌ای دسترسی دارند که از الگوی استفاده از شمای امن (secure schema usage pattern) پیروی نکرده است، pgbench را در آن پایگاه داده اجرا نکنید. pgbench از نام‌های واجد شرایط نشده (unqualified names) استفاده می‌کند و مسیر جستجو (search path) را دستکاری نمی‌کند.

2026 PostgreSQL 18.6