
Предисловие
Производительность СУБД — ключевой фактор , однако спонтанные проверки часто искажают реальную картину. PG_EXPECTO — это не просто набор скриптов, а чёткая методология, превращающая анализ PostgreSQL из хаотичного поиска проблем в структурированный, воспроизводимый эксперимент.
Задача
Используя классическую задачу о влиянии значения параметра shared_buffers на производительность СУБД, подготовить и протестировать общую методологию проведения экспериментов по анализу производительности СУБД PostgerSQL c использованием нейросети для анализа статистических данных, собранных комплексом pg_expecto в ходе нагрузочного тестирования.
Методология исследования
Тестовая среда, инструменты и конфигурация СУБД:
СУБД: PostgreSQL 17
Тестовая база данных: "Демобаза 2.0" (большой размер, сложная схема)
Условия тестирования: параллельная нагрузка от 5 до 22 сессий по каждому тестовому сценарию.
Сценарий-1 (Select by PK) - plan1.sql
--scenario1
--SELECT BY PK
EXPLAIN (ANALYZE, BUFFERS , COSTS , SUMMARY )
SELECT *
FROM bookings.airports_data
WHERE airport_code = (
SELECT airport_code
FROM bookings.airports_data
ORDER BY random()
LIMIT 1
);
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using idx_airports_data_code_timezone on airports_data (cost=143.04..145.26 rows=1 width=190) (actual time=2.557..2.559 rows=1 loops=1)
Index Cond: (airport_code = (InitPlan 1).col1)
Buffers: shared hit=23
InitPlan 1
-> Limit (cost=142.75..142.76 rows=1 width=12) (actual time=2.468..2.469 rows=1 loops=1)
Buffers: shared hit=20
-> Sort (cost=142.75..156.51 rows=5501 width=12) (actual time=2.467..2.467 rows=1 loops=1)
Sort Key: (random())
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=20
-> Index Only Scan using airports_data_pkey on airports_data airports_data_1 (cost=0.28..115.25 rows=5501 width=12) (actual time=0.127..1.319 rows=5501 loops=1)
Heap Fetches: 0
Buffers: shared hit=17
Planning:
Buffers: shared hit=199
Planning Time: 1.783 ms
Execution Time: 2.675 ms
(17 rows)
Сценарий-2 (GROUP BY)- plan2.sql
--scenario2
--GROUP BY
EXPLAIN (ANALYZE, BUFFERS , COSTS , SUMMARY )
WITH random_airplanes AS (
SELECT airplane_code
FROM bookings.airplanes_data
ORDER BY random()
LIMIT (random() * 9 + 1)::int -- От 1 до 10 значений
)
SELECT s.fare_conditions,
COUNT(*) as seat_count,
COUNT(DISTINCT s.airplane_code) as airplane_types
FROM bookings.seats s
WHERE s.airplane_code IN (SELECT airplane_code FROM random_airplanes)
GROUP BY s.fare_conditions
ORDER BY seat_count DESC;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sort (cost=23.59..23.60 rows=3 width=24) (actual time=2.231..2.235 rows=3 loops=1)
Sort Key: (count(*)) DESC
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=23
CTE random_airplanes
-> Limit (cost=1.29..1.29 rows=1 width=12) (actual time=0.080..0.083 rows=6 loops=1)
Buffers: shared hit=1
-> Sort (cost=1.29..1.32 rows=10 width=12) (actual time=0.066..0.067 rows=6 loops=1)
Sort Key: (random())
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=1
-> Seq Scan on airplanes_data (cost=0.00..1.12 rows=10 width=12) (actual time=0.051..0.053 rows=10 loops=1)
Buffers: shared hit=1
-> GroupAggregate (cost=20.07..22.28 rows=3 width=24) (actual time=1.844..2.187 rows=3 loops=1)
Group Key: s.fare_conditions
Buffers: shared hit=20
-> Sort (cost=20.07..20.61 rows=218 width=12) (actual time=1.787..1.877 rows=1294 loops=1)
Sort Key: s.fare_conditions, s.airplane_code
Sort Method: quicksort Memory: 89kB
Buffers: shared hit=20
-> Nested Loop (cost=0.30..7.41 rows=218 width=12) (actual time=0.191..0.632 rows=1294 loops=1)
Buffers: shared hit=14
-> HashAggregate (cost=0.02..0.03 rows=1 width=16) (actual time=0.114..0.118 rows=6 loops=1)
Group Key: random_airplanes.airplane_code
Batches: 1 Memory Usage: 24kB
Buffers: shared hit=1
-> CTE Scan on random_airplanes (cost=0.00..0.02 rows=1 width=16) (actual time=0.104..0.107 rows=6 loops=1)
Buffers: shared hit=1
-> Index Only Scan using idx_seats_airplane_code_fare_conditions on seats s (cost=0.28..5.19 rows=218 width=12) (actual time=0.017..0.050 rows=216 loops=6)
Index Cond: (airplane_code = random_airplanes.airplane_code)
Heap Fetches: 0
Buffers: shared hit=13
Planning:
Buffers: shared hit=90
Planning Time: 0.774 ms
Execution Time: 2.544 ms
(36 rows)
Сценарий-3 (ORDER BY)- plan3.sql
-scenario3
--ORDER BY
EXPLAIN (ANALYZE, BUFFERS , COSTS , SUMMARY )
SELECT book_ref,
book_date,
total_amount,
EXTRACT(DAY FROM book_date) as booking_day
FROM bookings.bookings
WHERE total_amount > 0
ORDER BY book_date
LIMIT (random() * 499 + 1)::int; -- От 1 до 500 записей
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.43..21335.15 rows=711319 width=53) (actual time=0.084..5.599 rows=142 loops=1)
Buffers: shared hit=91 read=10
I/O Timings: shared read=5.249
-> Index Scan using idx_bookings_book_date on bookings (cost=0.43..213347.50 rows=7113187 width=53) (actual time=0.081..5.576 rows=142 loops=1)
Filter: (total_amount > '0'::numeric)
Buffers: shared hit=91 read=10
I/O Timings: shared read=5.249
Planning:
Buffers: shared hit=72
Planning Time: 0.646 ms
Execution Time: 5.642 ms
(11 rows)
Сценарий-4 (JOIN)- plan4.sql
--scenario4
--JOIN
EXPLAIN (ANALYZE, BUFFERS , COSTS , SUMMARY )
WITH random_departures AS (
SELECT airport_code
FROM bookings.airports_data
ORDER BY random()
LIMIT (random() * 9 + 1)::int
),
random_validity_date AS (
SELECT
date_trunc('day',
lower(validity) +
(random() * EXTRACT(EPOCH FROM (upper(validity) - lower(validity)))) * interval '1 second'
) as random_date
FROM bookings.routes
WHERE validity IS NOT NULL
AND upper(validity) > lower(validity) + interval '7 days'
ORDER BY random()
LIMIT 1
)
SELECT r.route_no,
r.departure_airport,
a_dep.city->>'en' as departure_city,
r.arrival_airport,
a_arr.city->>'en' as arrival_city,
r.duration,
r.days_of_week
FROM bookings.routes r
JOIN bookings.airports_data a_dep ON r.departure_airport = a_dep.airport_code
JOIN bookings.airports_data a_arr ON r.arrival_airport = a_arr.airport_code
CROSS JOIN random_validity_date rvd
WHERE r.departure_airport IN (SELECT airport_code FROM random_departures)
AND r.validity @> rvd.random_date
AND array_length(r.days_of_week, 1) > 0
ORDER BY r.departure_airport, r.route_no
LIMIT 300;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=707.57..707.58 rows=2 width=133) (actual time=14.544..14.551 rows=0 loops=1)
Buffers: shared hit=1804
CTE random_departures
-> Limit (cost=457.01..458.39 rows=550 width=12) (actual time=3.396..3.398 rows=2 loops=1)
Buffers: shared hit=17
-> Sort (cost=457.01..470.77 rows=5501 width=12) (actual time=3.393..3.394 rows=2 loops=1)
Sort Key: (random())
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=17
-> Index Only Scan using airports_data_pkey on airports_data (cost=0.28..115.25 rows=5501 width=12) (actual time=0.055..1.765 rows=5501 loops=1)
Heap Fetches: 0
Buffers: shared hit=17
CTE random_validity_date
-> Limit (cost=200.26..200.31 rows=1 width=16) (actual time=6.880..6.883 rows=1 loops=1)
Buffers: shared hit=37
-> Result (cost=200.26..282.33 rows=1931 width=16) (actual time=6.879..6.881 rows=1 loops=1)
Buffers: shared hit=37
-> Sort (cost=200.26..205.09 rows=1931 width=30) (actual time=6.862..6.862 rows=1 loops=1)
Sort Key: (random())
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=37
-> Index Only Scan using idx_routes_route_no_validity on routes (cost=0.28..190.61 rows=1931 width=30) (actual time=0.114..5.148 rows=5792 loops=1)
Filter: (upper(validity) > (lower(validity) + '7 days'::interval))
Heap Fetches: 0
Buffers: shared hit=37
-> Sort (cost=48.88..48.88 rows=2 width=133) (actual time=14.542..14.546 rows=0 loops=1)
Sort Key: r.departure_airport, r.route_no
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=1804
-> Hash Semi Join (cost=19.91..48.86 rows=2 width=133) (actual time=14.512..14.515 rows=0 loops=1)
Hash Cond: (r.departure_airport = random_departures.airport_code)
Buffers: shared hit=1804
-> Nested Loop (cost=2.03..30.95 rows=2 width=171) (actual time=7.224..10.962 rows=290 loops=1)
Buffers: shared hit=1787
-> Nested Loop (cost=1.75..30.15 rows=2 width=122) (actual time=7.190..9.174 rows=290 loops=1)
Buffers: shared hit=917
-> Nested Loop (cost=1.47..29.36 rows=2 width=69) (actual time=7.129..7.455 rows=290 loops=1)
Buffers: shared hit=47
-> CTE Scan on random_validity_date rvd (cost=0.00..0.02 rows=1 width=8) (actual time=6.883..6.885 rows=1 loops=1)
Buffers: shared hit=37
-> Bitmap Heap Scan on routes r (cost=1.47..29.24 rows=10 width=91) (actual time=0.240..0.494 rows=290 loops=1)
Recheck Cond: (validity @> rvd.random_date)
Filter: (array_length(days_of_week, 1) > 0)
Heap Blocks: exact=6
Buffers: shared hit=10
-> Bitmap Index Scan on idx_routes_validity (cost=0.00..1.47 rows=29 width=0) (actual time=0.184..0.184 rows=290 loops=1)
Index Cond: (validity @> rvd.random_date)
Buffers: shared hit=4
-> Index Scan using airports_data_pkey on airports_data a_dep (cost=0.28..0.40 rows=1 width=53) (actual time=0.005..0.005 rows=1 loops=290)
Index Cond: (airport_code = r.departure_airport)
Buffers: shared hit=870
-> Index Scan using airports_data_pkey on airports_data a_arr (cost=0.28..0.40 rows=1 width=53) (actual time=0.005..0.005 rows=1 loops=290)
Index Cond: (airport_code = r.arrival_airport)
Buffers: shared hit=870
-> Hash (cost=11.00..11.00 rows=550 width=16) (actual time=3.423..3.423 rows=2 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
Buffers: shared hit=17
-> CTE Scan on random_departures (cost=0.00..11.00 rows=550 width=16) (actual time=3.398..3.401 rows=2 loops=1)
Buffers: shared hit=17
Planning:
Buffers: shared hit=216
Planning Time: 3.506 ms
Execution Time: 15.095 ms
(63 rows)
СПИСОК SQL ВЫРАЖЕНИЙ (sql_list.txt)
QUERYID | SQL TEXT |
-1247703524680257765|select scenario2()
-2326249669894930556|select scenario3()
3162304388436908605|select scenario4()
-3890986969840966328|select scenario1()
Размеры тестовых таблиц (количество строк)
relname | n_live_tup
-----------------+------------
airplanes_data | 10
seats | 1741
airports_data | 5501
airplanes_data | 10
airports_data | 5501
bookings | 7113192
routes | 5792
seats | 1741
tickets | 15575748
flights | 108435
segments | 20598447
boarding_passes | 19870557
(12 rows)План нагрузочного тестирования (param.conf)
# НАСТРОЙКИ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
# Максимальная нагрузка
finish_load = 20
# Тестовая БД
testdb = demo
# Веса сценариев
scenario1 = 1.0
scenario2 = 1.0
scenario3 = 1.0
scenario4 = 1.0Конфигурационные параметры СУБД (postgresql.auto.conf)
# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
track_io_timing = 'on'
listen_addresses = '0.0.0.0'
logging_collector = 'on'
log_directory = '/log/pg_log'
log_destination = 'stderr'
log_rotation_size = '0'
log_rotation_age = '1d'
log_filename = 'postgresql-%u.log'
log_line_prefix = '%m| %d| %a| %u| %h| %p| %e| '
log_truncate_on_rotation = 'on'
log_checkpoints = 'on'
archive_mode = 'on'
archive_command = 'true'
archive_timeout = '30min'
checkpoint_timeout = '15min'
checkpoint_warning = '60'
checkpoint_completion_target = '0.9'
min_wal_size = '2GB'
max_wal_size = '8GB'
synchronous_commit = 'on'
wal_compression = 'on'
random_page_cost = '1.1'
effective_io_concurrency = '300'
wal_sender_timeout = '0'
autovacuum_naptime = '1s'
autovacuum_vacuum_scale_factor = '0.01'
autovacuum_analyze_scale_factor = '0.005'
autovacuum_vacuum_cost_delay = '2ms'
autovacuum_max_workers = '4'
autovacuum_work_mem = '256MB'
vacuum_cost_limit = '4000'
bgwriter_delay = '10ms'
bgwriter_lru_multiplier = '4'
bgwriter_lru_maxpages = '400'
max_locks_per_transaction = '256'
max_pred_locks_per_transaction = '256'
temp_buffers = '14MB'
maintenance_work_mem = '479MB'
idle_in_transaction_session_timeout = '1h'
statement_timeout = '8h'
pg_stat_statements.track_utility = 'off'
max_parallel_maintenance_workers = '4'
hash_mem_multiplier = '2'
autovacuum_vacuum_insert_scale_factor = '0.01'
shared_preload_libraries = 'pg_stat_statements , pg_wait_sampling'
commit_delay = '1000'
log_autovacuum_min_duration = '0'
wipe_file_on_delete = 'on'
wipe_heaptuple_on_delete = 'on'
wipe_mem_on_free = 'on'
wipe_memctx_on_free = 'on'
wipe_xlog_on_free = 'on'
log_connections = 'on'
log_disconnections = 'on'
pg_stat_statements.track = 'all'
max_connections = '1000'
work_mem = '180MB'
max_parallel_workers_per_gather = '1'
max_parallel_workers = '16'
max_worker_processes = '16'
shared_buffers = '2GB'
effective_cache_size = '6GB'
Нагрузка на СУБД (load.txt)
ИЗМЕНЕНИЕ НАГРУЗКИ В ХОДЕ НАГРУЗОЧНОГО ТЕСТИРОВАНИЯ
№ LOAD
1 5
2 5
3 5
4 5
5 5
6 5
7 5
8 5
9 5
10 5
11 5
12 8
13 8
14 8
15 8
16 8
17 8
18 8
19 8
20 8
21 8
22 8
23 8
24 8
25 8
26 8
27 8
28 8
29 8
30 8
31 8
32 8
33 8
34 9
35 9
36 9
37 9
38 9
39 9
40 9
41 9
42 9
43 9
44 9
45 10
46 10
47 10
48 10
49 10
50 10
51 10
52 10
53 10
54 10
55 10
56 12
57 12
58 12
59 12
60 12
61 12
62 12
63 12
64 12
65 12
66 12
67 13
68 13
69 13
70 13
71 13
72 13
73 13
74 13
75 13
76 13
77 13
78 15
79 15
80 15
81 15
82 15
83 15
84 15
85 15
86 15
87 15
88 15
89 18
90 18
91 18
92 18
93 18
94 18
95 18
96 18
97 18
98 18
99 18
100 22
101 22
102 22
103 22
104 22
105 22
106 22
107 22
108 22Начальная гипотеза нейросети
Входные данные
Схема тестовой базы данных : demo_schema.sql
Размеры таблиц : tables.txt
Конфигурация СУБД : postgres.auto.conf
Таблица нагрузки: load.txt
Список queryid : sql_list.txt
Тестовые запросы и планы выполнения: plans.txt
Используя предоставленные входные данные, сформулируй гипотезу о влиянии увеличения параметра shared_buffers в ходе нагрузочного тестирования по сравнению базовым значением shared_buffers=2GB (Эксперимент-1) в экспериментах : shared_buffers=4GB (Эксперимент-2), shared_buffers=5GB (Эксперимент-3), shared_buffers=6GB (Эксперимент-4). Уточни ключевые признаки значений ожиданий СУБД wait_event_type и метрик производительности инфраструктуры vmstat, iostat, указывающие на слишком большой размер shared_buffers в ходе данных экспериментов.

Гипотеза о влиянии увеличения shared_buffers
Ожидаемый положительный эффект:
При увеличении shared_buffers с 2GB до 4-6GB в данных экспериментах ожидается:
Уменьшение физических чтений с диска, особенно для больших таблиц (bookings, tickets, segments, boarding_passes с 7-20 млн строк)
Улучшение производительности запросов, выполняющих полные сканирования или работающих с большими объемами данных
Снижение нагрузки на подсистему ввода-вывода
Однако существует риск избыточного размера shared_buffers, о котором свидетельствуют следующие признаки:
1. Признаки в wait_event_type СУБД:
Увеличение событий
BufferContentLock,LWLock- конкуренция за доступ к буферамРост
IOсобытий, связанных сWALWrite- из-за увеличения объема dirty buffers, требующих записиПоявление
CheckpointWriteиCheckpointSyncчаще - контрольные точки становятся более продолжительнымиУвеличение
BgWriterактивности - фоновый писатель не справляется с очисткой буферов
2. Признаки в метриках инфраструктуры:
vmstat:
Высокий
si(swap in) иso(swap out) при недостатке оперативной памятиУвеличение
cs(context switches) из-за борьбы за памятьРост
us(user CPU) без соответствующего улучшения throughput
iostat:
Увеличение
awaitвремени для устройств хранения, хотя%utilможет снижатьсяРост
svctm(service time) из-за более долгой записи на контрольных точкахНепропорциональное увеличение записи (
wkB/s) относительно чтения (rkB/s)
3. Ключевые индикаторы проблем с oversized shared_buffers:
Для текущей конфигурации (effective_cache_size=6GB, данные ~20GB+):
-
Эксперимент-4 (6GB shared_buffers) - риск наибольших проблем, так как:
shared_buffers приближается к effective_cache_size
Может вызывать вытеснение файлового кэша ОС
Увеличивает нагрузку на управление памятью
Специфические для нагрузки признаки:
Отсутствие улучшения после 4GB - если производительность стагнирует или ухудшается при переходе с 4GB на 5-6GB
Увеличение checkpoint_segments/wal в логах PostgreSQL
Рост
buffers_backend_fsyncв pg_stat_bgwriterУвеличение разницы между
buffers_allocиbuffers_backend
Оптимальная точка вероятно находится между 4-5GB для данной нагрузки, учитывая:
Общий объем данных ~20GB+
Наличие memory-intensive операций (сортировки, hash-агрегации)
Одновременное выполнение 4 различных сценариев запросов
Результаты экспериментов по итогам нагрузочных тестирований
Операционная скорость

SPEED-4GB / SPEED-2GB

Среднее снижение операционной скорости в эксперименте "shared_buffers=4GB" по сравнению с базовым значением "shared_buffers=2GB" состав��ло 0.54%
SPEED-5GB / SPEED-2GB

Среднее увеличение операционной скорости в эксперименте "shared_buffers=5GB" по сравнению с базовым значением "shared_buffers=2GB" составило 0.62%
SPEED-6GB / SPEED-2GB

Среднее увеличение операционной скорости в эксперименте "shared_buffers=6GB" по сравнению с базовым значением "shared_buffers=2GB" составило 0.56%
Ожидания СУБД

WAITINGS-4GB / WAITINGS-2GB

Среднее снижение количества ожиданий СУБД в эксперименте "shared_buffers=4GB" по сравнению с базовым значением "shared_buffers=2GB" составило 0.22%
WAITINGS-5GB / WAITINGS-2GB

Среднее увеличение количества ожиданий СУБД в эксперименте "shared_buffers=5GB" по сравнению с базовым значением "shared_buffers=2GB" составило 5.75%
WAITINGS-6GB / WAITINGS-2GB

Среднее увеличение количества ожиданий СУБД в эксперименте "shared_buffers=6GB" по сравнению с базовым значением "shared_buffers=2GB" составило 6.50%
Входные данные для анализа результатов экспериментов
Регрессионный и корреляционный анализ производительности и ожиданий СУБД
Статистические данные по производительности и ожиданиям СУБД
Статистические данные iostat
Статистические данные vmstat
PG_EXPECTO : Данные для построения графиков показателей vmstat | Postgres DBA | Дзен
1. Анализ операционной скорости и ожиданий СУБД
Входные данные:
Схема тестовой базы данных : demo_schema.sql
Размеры таблиц : tables.txt
Конфигурация СУБД : postgres.auto.conf
Таблица нагрузки: load.txt
Список queryid : sql_list.txt
Тестовые запросы и планы выполнения: plans.txt
Регрессионный и корреляционный анализ производительности и ожиданий СУБД для эксперимента N(1-4) : N.postgres.1.cluster_report_meta.txt
Статистические данные по производительности и ожиданиям СУБД (wait_event_type) для эксперимента N(1-4) : N.postgres.1.cluster_report_4graph.txt
Используя входные данные, сформируй сравнительный анализ . Выдели ключевые отличия в производительности(speed), типах ожиданий СУБД(wait_event_type) , событий ожидания СУБД(wait_event). Сформируй итог по серии экспериментов.

Сравнительный анализ экспериментов 1-4
1. Общая характеристика экспериментов
Временные периоды:
Эксперимент 1: 2025-12-12 10:21 - 12:10 (109 минут)
Эксперимент 2: 2025-12-12 13:13 - 15:02 (109 минут)
Эксперимент 3: 2025-12-12 17:04 - 18:53 (109 минут)
Эксперимент 4: 2025-12-13 08:49 - 10:38 (109 минут)
Нагрузка: Во всех экспериментах нагрузка плавно возрастала от 5 до 22 единиц.
2. Сравнительный анализ производительности (SPEED)
Эксперимент |
SPEED MAX |
SPEED MIN |
Диапазон |
Динамика (угол наклона) |
R² |
|---|---|---|---|---|---|
1 |
2.967.383 |
1.209.694 |
1.757.689 |
-44,37 |
0,96 |
2 |
2.944.562 |
1.181.182 |
1.763.380 |
-44,45 |
0,96 |
3 |
2.947.696 |
1.211.676 |
1.736.020 |
-44,36 |
0,96 |
4 |
2.931.559 |
1.224.471 |
1.707.088 |
-44,27 |
0,95 |
Ключевые наблюдения:
Все эксперименты демонстрируют стабильное снижение производительности с течением времени (отрицательные углы наклона)
Наивысшая пиковая производительность в эксперименте 1 (2.967.383)
Наименьшая минимальная производительность в эксперименте 2 (1.181.182)
Коэффициент детерминации R² ≈ 0,95-0,96 указывает на сильную линейную зависимость
3. Сравнительный анализ ожиданий СУБД (WAITINGS)
Эксперимент |
WAITINGS MAX |
WAITINGS MIN |
Диапазон |
Динамика (угол наклона) |
R² |
|---|---|---|---|---|---|
1 |
119 |
15 |
104 |
-41,81 |
0,80 |
2 |
183 |
10 |
173 |
-41,60 |
0,79 |
3 |
128 |
13 |
115 |
-41,97 |
0,81 |
4 |
161 |
12 |
149 |
-42,00 |
0,81 |
Ключевые наблюдения:
Эксперимент 2 имеет максимальные ожидания (183) и наибольший диапазон
Эксперимент 1 имеет минимальные максимальные ожидания (119)
Во всех экспериментах наблюдается снижение ожиданий со временем
Корреляция SPEED-WAITINGS: 0,87-0,91 (сильная обратная зависимость)
4. Анализ типов ожиданий (wait_event_type)
Эксперимент 1:
Основные типы: LWLOCK (0,95), TIMEOUT (1,00)
Отсутствуют: IO, IPC, LOCK, BUFFERPIN, EXTENSION
Корреляция: WAITINGS-LWLOCK=0,95, WAITINGS-TIMEOUT=1,00
Эксперимент 2:
Основные типы: LWLOCK (0,96), TIMEOUT (0,98)
Появляются: IO (незначительно), IPC (незначительно)
Корреляция: WAITINGS-LWLOCK=0,96, WAITINGS-TIMEOUT=0,98
Эксперимент 3:
Основные типы: LWLOCK (0,96), TIMEOUT (1,00)
Незначительные: IO, IPC
Корреляция: WAITINGS-LWLOCK=0,96, WAITINGS-TIMEOUT=1,00
Эксперимент 4:
Основные типы: LWLOCK (0,96), TIMEOUT (0,99), IO (0,93)
Корреляция: Сильная корреляция WAITINGS-IO=0,93
5. Анализ событий ожидания (wait_event)
Общие для всех экспериментов:
LWLOCK: Преобладают lightweight locks (средний уровень 5-8)
TIMEOUT: Доминирующий тип ожиданий (80-90% от WAITINGS)
Уникальные особенности:
Эксперимент 2: Пиковые значения IO=34 и IPC=20 (в начале эксперимента)
Эксперимент 4: Устойчивое присутствие IO ожиданий (до 12 единиц)
Эксперименты 2,3,4: Появление IPC ожиданий (до 21 в эксп. 4)
6. Связь с выполняемыми запросами
Из sql_list.txt и plans.txt:
scenario1(): SELECT BY PK (индексный доступ)
scenario2(): GROUP BY (агрегация с сортировкой)
scenario3(): ORDER BY (сортировка больших объемов)
scenario4(): JOIN (сложные соединения)
Гипотеза распределения:
Эксперимент 1: Преобладание scenario1 (минимальные IO ожидания)
Эксперимент 2: Преобладание scenario3/scenario4 (максимальные IO/IPC)
Эксперимент 4: Преобладание scenario4 (устойчивые IO ожидания)
7. Влияние конфигурации СУБД
Из postgresql.auto.conf:
effective_io_concurrency = 300(высокий)random_page_cost = 1.1(низкий)shared_buffers = 2GBwork_mem = 180MB
Выявленные эффекты:
Высокий
effective_io_concurrencyпозволяет параллельные IO операцииНизкий
random_page_costспособствует использованию индексовДостаточный
work_memуменьшает временные операции на диск
8. Итоговый вывод по серии экспериментов
Ключевые отличия между экспериментами:
-
Эксперимент 1 (базовый):
Наименьшие максимальные ожидания
Отсутствие IO/IPC ожиданий
Вероятно, выполнялись простые SELECT запросы
-
Эксперимент 2 (максимальная нагрузка):
Наибольшие общие ожидания (183)
Пиковые значения IO/IPC
Вероятно, выполнялись запросы с сортировкой больших объемов
-
Эксперимент 3 (сбалансированный):
Промежуточные значения ожиданий
Незначительные IO/IPC
Стабильная работа
-
Эксперимент 4 (IO-нагруженный):
Устойчивые IO ожидания (корреляция 0,93)
Вероятно, выполнялись JOIN запросы с большими хеш-таблицами
Общие тенденции:
Производительность стабильно снижается с увеличением нагрузки во всех экспериментах
TIMEOUT и LWLOCK - доминирующие типы ожиданий во всех сценариях
IO ожидания появляются только при выполнении запросов с большими объемами данных
Конфигурация СУБД адекватна нагрузке, но требует мониторинга при пиковых значениях
Общий итог: Серия экспериментов демонстрирует стабильную работу СУБД под различными типами нагрузки. Наибольшее влияние на производительность оказывают операции, требующие интенсивного ввода-вывода и блокировок. Конфигурация СУБД в целом оптимальна для данной нагрузки.
2. Анализ производительности подсистемы IO
Входные данные:
Таблица нагрузки: load.txt
Статистические данные ioatst для эксперимента N(1-4) : N.linux.x.iostat_vdd_4graph.txt
Используя входные данные, сформируй сравнительный анализ . Выдели ключевые отличия в метриках iostat. Сформируй итог по серии экспериментов.

1. Общие наблюдения
Во всех четырёх экспериментах зафиксированы идентичные значения метрик iostat для устройства vdd:
w/s (количество операций записи в секунду):
0,0000wrqm/s (количество слиянных операций записи в секунду):
0,0000%wrqm (процент слияний операций записи):
49,0000w_await (среднее время ожидания записи в мс):
2,0000wareq_sz (средний размер запроса записи в секторах):
10,0000%util (процент использования диска):
0,0000f/s (количество операций flush в секунду):
0,0000f_await (среднее время ожидания flush в мс):
0,0000
...
4. Итог по серии экспериментов
Диск vdd не был нагружен в ходе всех четырёх экспериментов.
Метрики iostat неизменны во времени и между экспериментами.
-
Нагрузочное тестирование, судя по данным, не затрагивало устройство vdd. Возможно:
Нагрузка направлялась на другие диски или ресурсы (CPU, память, сеть).
Данные собраны не с того устройства или в момент простоя системы.
Конфигурация теста не подразумевала операций ввода-вывода на
vdd.
2. Анализ производительности инфраструктуры (vmstat)
Входные данные:
Таблица нагрузки: load.txt
Тестовые запросы и планы выполнения: plans.txt
Статистические данные vmstat для эксперимента N(1-4) : N.linux.x.vmstat_4graph.txt
Используя входные данные, сформируй сравнительный анализ . Выдели ключевые отличия в метриках vmstat. Сформируй итог по серии экспериментов.

1. Ключевые отличия в метриках vmstat между экспериментами
Память (Memory):
-
Memory_swpd (виртуальная память):
Эксперимент 1: стабильно 190 MB
Эксперимент 2: стабильно 59 MB
Эксперимент 3: стабильно 59 MB
Эксперимент 4: стабильно 58 MB
Вывод: В первом эксперименте значительно выше использование свопа, что указывает на большую нагрузку на оперативную память.
-
Memory_free (свободная память):
-
Начальный уровень свободной памяти отличается:
Эксп 1: ~160-200 MB
Эксп 2: ~2000-2044 MB
Эксп 3: ~1600-1613 MB
Эксп 4: ~200-250 MB
Вывод: Эксперименты проводились в разных условиях загрузки системы, что влияет на сравнение.
-
Процессы (Procs_r):
-
Количество запущенных процессов:
Эксп 1: увеличивается с 21 до 50 (рост в 2.38 раза)
Эксп 2: увеличивается с 21 до 49 (рост в 2.33 раза)
Эксп 3: увеличивается с 21 до 51 (рост в 2.43 раза)
Эксп 4: увеличивается с 21 до 51 (рост в 2.43 раза)
Вывод: Во всех экспериментах наблюдается стабильный рост количества процессов, коррелирующий с увеличением нагрузки.
CPU (процессор):
-
cpu_us (пользовательское время CPU):
Во всех экспериментах: стабильно 89-95%
Незначительный рост к концу тестов
-
cpu_sy (системное время CPU):
Эксп 1: снижается с 10% до 5%
Эксп 2: снижается с 10% до 4%
Эксп 3: снижается с 10% до 4%
Эксп 4: снижается с 10% до 5%
Вывод: В первых экспериментах выше системная нагрузка, что может указывать на большее количество системных вызовов.
Ввод-вывод (I/O):
-
io_bo (блоки ввода-вывода):
Эксп 1: 53-56 (стабильно)
Эксп 2: 48-62 (более волатильно)
Эксп 3: 45-51 (наиболее стабильно)
Эксп 4: 51-58 (умеренная волатильность)
Системные метрики:
-
system_in (прерывания):
Значительно снижается во всех экспериментах к концу тестирования
Наиболее резкое падение в эксперименте 4
-
system_cs (переключения контекста):
Стабильное снижение во всех экспериментах
Наибольшие значения в эксперименте 1
2. Связь с нагрузочным тестированием
Из файла load.txt видно, что нагрузка увеличивалась постепенно:
С 5 до 22 единиц нагрузки
110 измерений соответствуют 110 записям в каждом эксперименте
Зависимости, наблюдаемые при увеличении нагрузки:
Количество процессов (procs_r) линейно возрастает с увеличением нагрузки
Свободная память (memory_free) уменьшается при увеличении нагрузки
CPU пользовательское время остается стабильно высоким
CPU системное время снижается при увеличении нагрузки
3. Анализ тестовых запросов (plans.txt)
Из планов выполнения видно 4 сценария:
SELECT BY PK - быстрый запрос (2.675 ms)
GROUP BY - умеренная сложность (2.544 ms)
ORDER BY - самый медленный (5.642 ms)
JOIN - сложный запрос с CTE (15.095 ms)
Связь с экспериментами:
Каждый эксперимент, соответствует одному из сценариев, что объясняет разницу в метриках:
Эксперимент 4 (с JOIN) показывает наибольшее изменение метрик
Эксперимент 1 (с SELECT BY PK) показывает наименьшую волатильность
4. Итоги по серии экспериментов
Ключевые выводы:
-
Производительность системы:
Система демонстрирует стабильность даже при 22 единицах нагрузки
CPU остается основным узким местом (высокий % пользовательского времени)
-
Память:
Значительная разница в использовании свопа между экспериментами
Наиболее эффективное использование памяти в экспериментах 2 и 3
-
Масштабируемость:
Система адекватно реагирует на увеличение нагрузки
Наблюдается линейный рост процессов при увеличении нагрузки
-
Рекомендации:
Оптимизировать запросы типа JOIN (самые ресурсоемкие)
Рассмотреть ув��личение оперативной памяти для снижения использования свопа
Мониторить системные прерывания и переключения контекста как индикаторы проблем
Сравнительная таблица итоговых показателей:
Метрика |
Эксп 1 |
Эксп 2 |
Эксп 3 |
Эксп 4 |
Лучший показатель |
|---|---|---|---|---|---|
procs_r (рост) |
2.38x |
2.33x |
2.43x |
2.43x |
Эксп 2 (наименьший рост) |
memory_swpd |
190 MB |
59 MB |
59 MB |
58 MB |
Эксп 4 |
CPU стабильность |
хорошая |
хорошая |
хорошая |
хорошая |
Все |
I/O стабильность |
средняя |
низкая |
высокая |
средняя |
Эксп 3 |
Общий вывод: Все эксперименты подтверждают стабильность системы под нагрузкой, но выявляют необходимость оптимизации работы с памятью и сложных JOIN-запросов. Наиболее сбалансированные показатели демонстрирует эксперимент 2.

Общий итог по анализу результатов экспериментов
1. Основные выводы о влиянии параметра shared_buffers
Незначительное влияние на производительность: Увеличение shared_buffers с 2GB до 4-6GB не привело к существенному изменению операционной скорости. Различия составляют всего 0,54-0,62%, что находится в пределах статистической погрешности.
Парадоксальный эффект на ожидания: При увеличении shared_buffers до 5GB и 6GB наблюдается рост количества ожиданий СУБД на 5,75% и 6,50% соответственно, что указывает на возможные блокировки и конкуренцию за ресурсы.
2. Общая характеристика экспериментов
Стабильность методологии: Все четыре эксперимента проведены по единой методологии с одинаковой продолжительностью (109 минут) и схемой нагрузки (плавный рост от 5 до 22 сессий).
Воспроизводимость результатов: Эксперименты демонстрируют схожую динамику снижения производительности с течением времени (углы наклона -44,27...-44,45) при высоких коэффициентах детерминации (R²=0,95-0,96).
3. Ключевые факторы, влияющие на производительность
3.1 Типы выполняемых запросов
SELECT BY PK: Минимальные IO ожидания, стабильная производительность
GROUP BY/ORDER BY: Умеренная нагрузка, возможны временные операции
JOIN запросы: Наибольшая ресурсоемкость, вызывают устойчивые IO ожидания
3.2 Доминирующие типы ожиданий
TIMEOUT: Преобладающий тип (80-90% от общего числа ожиданий)
LWLOCK (Lightweight locks): Значительная доля в структуре ожиданий
IO ожидания: Появляются только при выполнении запросов с большими объемами данных
4. Анализ подсистем
4.1 Дисковая подсистема (iostat)
-
Отсутствие нагрузки на устройство vdd: Все эксперименты показали нулевую утилизацию диска, что может указывать на:
Направление нагрузки на другие дисковые устройства
Достаточность оперативной памяти для кэширования
Особенности конфигурации тестовой среды
4.2 Системные ресурсы (vmstat)
CPU как узкое место: Стабильно высокое пользовательское время CPU (89-95%)
Проблемы с управлением памятью: Значительные различия в использовании свопа между экспериментами (от 58MB до 190MB)
Адекватное масштабирование: Линейный рост процессов при увеличении нагрузки
Общий вывод
Серия экспериментов подтвердила стабильность работы PostgreSQL под различными типами нагрузки. Увеличение параметра shared_buffers не оказало существенного влияния на производительность в данной тестовой конфигурации, что может указывать на:
Достаточность базового значения (2GB) для данной нагрузки
Преобладание других факторов, ограничивающих производительность (CPU, типы запросов, блокировки)
Наиболее значимыми факторами производительности оказались:
Типы выполняемых запросов (особенно JOIN-операции)
Управление блокировками (LWLOCK)
Эффективность использования оперативной памяти
Нагрузка на CPU
Методология испытаний с использованием pg_expecto показала свою эффективность для комплексного анализа производительности СУБД, позволяя выявлять узкие места на разных уровнях системы.
Анализ причин ошибки первоначального прогноза

Отчет по анализу причин ошибочности начальной гипотезы и итогам экспериментов
1. Анализ причин ошибочности начальной гипотезы
Начальная гипотеза предполагала, что увеличение shared_buffers с 2 ГБ до 4–6 ГБ приведёт к значимому улучшению производительности за счёт снижения физических чтений с диска и уменьшения нагрузки на подсистему ввода-вывода. Однако результаты экспериментов не подтвердили эти ожидания, что обусловлено следующими причинами:
Дисковая подсистема не являлась узким местом
Данныеiostatпоказали нулевую утилизацию диска (vdd), что указывает на отсутствие значимой нагрузки на хранилище. В таких условиях увеличение кэширования вshared_buffersне могло дать заметного прироста производительности.Доминирующим ресурсом оказался CPU
Показателиvmstatвыявили стабильно высокое пользовательское время CPU (89–95%), что свидетельствует о процессорном ограничении. Увеличениеshared_buffersне снижает нагрузку на CPU, а в некоторых случаях даже усиливает конкуренцию за ресурсы.Рост числа ожиданий и блокировок
При увеличенииshared_buffersдо 5–6 ГБ наблюдался рост событийLWLOCKи общего количества ожиданий СУБД (до 6,5%). Это подтверждает гипотезу о рисках избыточного размера буфера, но в данном случае негативный эффект проявился раньше ожидаемого.Неучтённые факторы нагрузки
Характер запросов (особенноJOIN-операции и агрегации) и структура данных (~20 ГБ) оказались более значимыми, чем размерshared_buffers. Оптимизация выполнения запросов и управление блокировками имели большее влияние на производительность.Эффективность базовой конфигурации
Значениеshared_buffers=2 ГБоказалось достаточным для данной тестовой нагрузки, что указывает на сбалансированность базовой конфигурации.
2. Общие итоги серии экспериментов
Минимальное влияние
shared_buffers
Увеличение параметра не привело к статистически значимому улучшению производительности. Различия между экспериментами составили менее 1%, что находится в пределах погрешности измерений.Стабильность и воспроизводимость результатов
Все эксперименты выполнены по единой методологии, показали схожую динамику снижения производительности во времени и высокую согласованность данных (R² = 0,95–0,96).-
Ключевые факторы производительности
Типы запросов —
JOIN-операции вызывали наибольшую нагрузку и устойчивые IO-ожидания.Блокировки — события
LWLOCKиTIMEOUTсоставляли основную долю ожиданий.Использование CPU — процессорное время было основным ограничивающим ресурсом.
Управление памятью — значительные колебания в использовании свопа указывают на потенциальные проблемы с распределением памяти.
Отсутствие нагрузки на диск
Нулевая утилизация дискаvddво всех экспериментах позволяет сделать вывод о достаточности оперативной памяти для кэширования или особенностях тестовой среды.
3. Рекомендации по дальнейшим исследованиям
Сфокусироваться на оптимизации запросов, особенно с
JOINи агрегациями.Исследовать влияние параметров, связанных с управлением блокировками и параллельным выполнением.
Проанализировать использование памяти ОС и взаимодействие
shared_buffersс файловым кэшем.Рассмотреть возможность увеличения вычислительных ресурсов (CPU) или оптимизации рабочих нагрузок.
4. Заключение
Начальная гипотеза переоценила влияние параметра shared_buffers в условиях данной тестовой среды, где производительность ограничивалась CPU и характером запросов, а не дисковыми операциями. Эксперименты подтвердили, что увеличение shared_buffers сверх оптимального значения может приводить к росту конкуренции за ресурсы без заметного выигрыша в производительности.
Методология нагрузочного тестирования с использованием pg_expecto показала свою эффективность для комплексной диагностики производительности СУБД и выявления реальных узких мест.
Отчёт составлен на основе анализа предоставленных документов «Начальная гипотеза нейросети.txt» и «Общий итог.txt».
izibrizi2
Опять ии слоп