Задача
Определить максимальное количество предельное количество работающих соединений к СУБД , при заданном сценарии нагрузки .
Получение значения производительности СУБД Производительность СУБД — расчет метрики, временной анализ, параметрическая оптимизация / Хабр (habr.com)
Создание нагрузки на СУБД — используется инструмент pgbench
Конфигурация тестовой виртуальной машины
Аналогично описанным в Этюд: использование метода покоординатного спуска для оптимизации параметров СУБД / Хабр (habr.com)
Сценарий теста
1.Базовая нагрузка на СУБД
Запуск pgbench c неизменным значением параметра client:
--client=клиенты Число имитируемых клиентов, то есть число одновременных сеансов базы данных.
2.Период сбора статистических данных для долгой и короткой скользящей
3.Дополнительная нагрузка
Запуск дополнительного сценария pgbench с постоянным периодом выполнения и увеличением параметра client = Итерация * 40
4.Условие остановки теста
Значение коэффициента корреляции между количеством активных сессий и значением долгой скользящей Rxy < -0.7
5.Результат
Максимальное значение параметра client при выполнении дополнительного сценария pgbench.( Пункт 3.).
Реализация теста
Создание и инициализация БД для базовой нагрузки
stress_base.create_db.sh
#!/bin/sh # stress_base.create_db.sh # version 8.4 # Создать тестовую БД # Инициировать тестовую БД #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` LOG_FILE=$current_path'/stress_base.create_db.log' ERR_FILE=$current_path'/stress_base.create_db.err' PROGRESS_FILE=$current_path'/start_pg_bench.progress' timestamp_label=$(date "+%Y%m%d")'T'$(date "+%H%M%S") echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : STARTED '> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench CREATION IS STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench CREATION IS STARTED ' >> $LOG_FILE psql -c "DROP DATABASE IF EXISTS test_pgbench" 2>>$ERR_FILE exit_code $? $LOG_FILE $ERR_FILE psql -c "CREATE DATABASE test_pgbench WITH OWNER = pgpropwr" 2>>$ERR_FILE exit_code $? $LOG_FILE $ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench HAS BEEN CREATED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench HAS BEEN CREATED ' >> $LOG_FILE ################### # ПАРАМЕТРЫ ТЕСТОВОГО СЦЕНАРИЯ let pgbench_clients=`cat $current_path'/pgbench_clients'` let transactions=`cat $current_path'/transactions'` ################### echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_clients = '$pgbench_clients echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_clients = '$pgbench_clients >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : transactions = '$transactions echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : transactions = '$transactions >> $LOG_FILE ######################################################################################################### #Параметры инициализации pgbench_init_param='--quiet --foreign-keys --scale='"$pgbench_clients"' -i test_pgbench' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_init_param= '$pgbench_init_param echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_init_param= '$pgbench_init_param>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench STARTED' >> $LOG_FILE pgbench --username=pgpropwr $pgbench_init_param >>$LOG_FILE 2>>$PROGRESS_FILE exit_code $? $LOG_FILE $PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench FINISHED' >> $LOG_FILE exit 0
Сценарий базовой нагрузки
stress_base.sh
#!/bin/sh # stress_base.sh # version 8.4 # Тестовая БД создается отдельно # Тестовая БД создается отдельно # VACUUM ANALYZE после каждой итерации # Настройки СУБД - отдельно # Бесконечный цикл. Остановка вручную # touch /postgres/scripts/pgbench/STOP_PGBENCH #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` LOG_FILE=$current_path'/stress_base.log' timestamp_label=$(date "+%Y%m%d")'T'$(date "+%H%M%S") echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : STARTED '> $LOG_FILE #Удалить старый флаг if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then rm /postgres/scripts/pgbench/STOP_PGBENCH fi #отключить наблюдение touch /postgres/scripts/stress/STRESS_NOT_STARTED ; ################### # ПАРАМЕТРЫ ТЕСТОВОГО СЦЕНАРИЯ let pgbench_clients=`cat $current_path'/pgbench_clients'` let transactions=`cat $current_path'/transactions'` ################### echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench_clients = '$pgbench_clients echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench_clients = '$pgbench_clients >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : transactions = '$transactions echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : transactions = '$transactions >> $LOG_FILE RESULT_LOG_FILE=$current_path'/result.log' echo $(date "+%d-%m-%Y %H:%M:%S")' | stress_base | ' > $RESULT_LOG_FILE echo ' timestamp | response time | response time sort | response time long | CPI | Active | CPI MM short | Active short | CPI MM short/Active short correlation | CPI MM long | Active long | CPI MM short/Active long correlation |' >> $RESULT_LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : Количество клиентов: '$pgbench_clients echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : Количество клиентов: '$pgbench_clients >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : Количество транзакций: '$transactions echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : Количество транзакций: '$transactions >> $LOG_FILE #--jobs=потоки Число рабочих потоков в pgbench. Использовать нескольких потоков может быть полезно на многопроцессорных компьютерах jobs=`cat /proc/cpuinfo|grep processor|wc -l` echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : jobs= '$jobs echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : jobs= '$jobs>> $LOG_FILE ERR_FILE=$current_path'/stress_base.err' PROGRESS_FILE=$current_path'/stress_base.progress' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $PROGRESS_FILE pgbench_param='--protocol=extended --report-per-command --jobs='"$jobs"' --client='"$pgbench_clients"' --transactions='"$transactions"' test_pgbench' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench_param= '$pgbench_param echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench_param= '$pgbench_param>> $LOG_FILE let counter=1 while [ 1 = 1 ] do echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : iteration '$counter' - STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : iteration '$counter' - STARTED' >> $LOG_FILE ###################################################### if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench has been stopped ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pgbench has been stopped '>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : FINISHED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : FINISHED '>> $LOG_FILE rm $ERR_FILE exit 0 fi echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench STARTED' >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench progress stored in file :'$PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench progress stored in file :'$PROGRESS_FILE >> $LOG_FILE pgbench --username=pgpropwr $pgbench_param >>$LOG_FILE 2>>$PROGRESS_FILE exit_code $? $LOG_FILE $PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : pg_bench FINISHED' >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : iteration '$counter' - FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : iteration '$counter' - FINISHED' >> $LOG_FILE let counter=$counter+1 ###################################################### echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : VACUUM ANALYZE : STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : VACUUM ANALYZE : STARTED' >> $LOG_FILE psql -d test_pgbench -c 'VACUUM ANALYZE' >>$LOG_FILE 2>>$PROGRESS_FILE exit_code $? $LOG_FILE $PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : VACUUM ANALYZE : FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_base : OK : VACUUM ANALYZE : FINISHED' >> $LOG_FILE done exit 0
Используемые значения для создания нагрузки:
pgbench_clients
100
transactions
10000
Создание и инициализация БД для дополнительной нагрузки
stress_additional.create_db.sh
#!/bin/sh # stress_additional.create_db.sh # version 11 # Создать тестовую БД # Инициировать тестовую БД #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` LOG_FILE=$current_path'/stress_additional.create_db.log' ERR_FILE=$current_path'/stress_additional.create_db.err' PROGRESS_FILE=$current_path'/start_pg_bench.progress' timestamp_label=$(date "+%Y%m%d")'T'$(date "+%H%M%S") echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : STARTED '> $LOG_FILE ################### # ПАРАМЕТРЫ ТЕСТОВОГО СЦЕНАРИЯ let pgbench_clients=`cat $current_path'/pgbench_clients'` ################### echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench11 CREATION IS STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench11 CREATION IS STARTED ' >> $LOG_FILE psql -c "DROP DATABASE IF EXISTS test_pgbench11" 2>>$ERR_FILE exit_code $? $LOG_FILE $ERR_FILE psql -c "CREATE DATABASE test_pgbench11 WITH OWNER = pgpropwr" 2>>$ERR_FILE exit_code $? $LOG_FILE $ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench11 HAS BEEN CREATED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : DATABASE test_pgbench11 HAS BEEN CREATED ' >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_clients = '$pgbench_clients echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_clients = '$pgbench_clients >> $LOG_FILE ######################################################################################################### #Параметры инициализации pgbench_init_param='--quiet --foreign-keys --scale='"$pgbench_clients"' -i test_pgbench11' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_init_param= '$pgbench_init_param echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : pgbench_init_param= '$pgbench_init_param>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench STARTED' >> $LOG_FILE pgbench --username=pgpropwr $pgbench_init_param >>$LOG_FILE 2>>$PROGRESS_FILE exit_code $? $LOG_FILE $PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : OK : INITIALIZATION OF pg_bench FINISHED' >> $LOG_FILE exit 0
Сценарий дополнительной нагрузки
stress_additional.sh
#!/bin/sh # stress_additional.sh # version 11.0 # Дополнительная нагрузка # Входные параметры : время clients #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` LOG_FILE=$current_path'/stress_additional.log' timestamp_label=$(date "+%Y%m%d")'T'$(date "+%H%M%S") echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : STARTED '>> $LOG_FILE test_time=$1 clients=$2 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Время теста в секундах: '$test_time echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Время теста в секундах: '$test_time >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Количество клиентов: '$clients echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Количество клиентов: '$clients >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Проход: '$connect_count echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : Проход: '$connect_count >> $LOG_FILE ################################################################################## #--jobs=потоки Число рабочих потоков в pgbench. Использовать нескольких потоков может быть полезно на многопроцессорных компьютерах jobs=`cat /proc/cpuinfo|grep processor|wc -l` echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : jobs= '$jobs echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : jobs= '$jobs>> $LOG_FILE pg_bench_time=$1 let pgbench_clients=$2 ################## ERR_FILE=$current_path'/stress_additional.err' PROGRESS_FILE=$current_path'/stress_additional.progress' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $PROGRESS_FILE pgbench_param='--protocol=extended --report-per-command --jobs='"$jobs"' --client='"$pgbench_clients"' --time='"$pg_bench_time"' test_pgbench11' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pgbench_param= '$pgbench_param echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pgbench_param= '$pgbench_param>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench STARTED' >> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench progress stored in file :'$PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench progress stored in file :'$PROGRESS_FILE >> $LOG_FILE pgbench --username=pgpropwr $pgbench_param >>$LOG_FILE 2>>$PROGRESS_FILE exit_code $? $LOG_FILE $PROGRESS_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench FINISHED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pg_bench FINISHED' >> $LOG_FILE ################################################################################## echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : FINISHED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : FINISHED '>> $LOG_FILE ###################################################### if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pgbench has been stopped ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : pgbench has been stopped '>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : FINISHED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_additional : OK : FINISHED '>> $LOG_FILE rm $ERR_FILE exit 0 fi rm $ERR_FILE exit 0
Запуск дополнительной нагрузки
stress_start.sh
#!/bin/sh # stress_start.sh # version 12 # Стресс - тестирование # Бесконечный цикл. Остановка вручную # touch /postgres/scripts/pgbench/STOP_PGBENCH #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` LOG_FILE=$current_path'/stress_start.log' RESULT_LOG_FILE=$current_path'/result.log' timestamp_label=$(date "+%Y%m%d")'T'$(date "+%H%M%S") echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : STARTED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : STARTED '> $LOG_FILE #Удалить старый флаг if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then rm /postgres/scripts/pgbench/STOP_PGBENCH fi ERR_FILE=$current_path'/stress_start.err' PROGRESS_FILE=$current_path'/stress_start.progress' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") > $PROGRESS_FILE cd $current_path RESULT_LOG_FILE=$current_path'/result.log' echo $(date "+%d-%m-%Y %H:%M:%S")' | stress_start | ' >> $RESULT_LOG_FILE let counter=1 while [ 1 = 1 ] do echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : iteration '$counter' - STARTED' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : iteration '$counter' - STARTED' >> $LOG_FILE ###################################################### if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : pgbench has been stopped ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : pgbench has been stopped '>> $LOG_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : FINISHED ' echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : stress_start : OK : FINISHED '>> $LOG_FILE rm $ERR_FILE exit 0 fi ################################## # Старт стрессовой нагрузки # 10 минут # количество клиентов = counter*40 let clients=counter*40 ./stress_additional.sh 600 $clients let counter=$counter+1 done exit 0
Протоколирование результатов теста
stress.log.sh
#!/bin/sh # stress.log.sh # version 12 # Логирование # Бесконечный цикл. # Остановка теста - touch /postgres/scripts/pgbench/STOP_PGBENCH #Обработать код возврата function exit_code { ecode=$1 if [[ $ecode != 0 ]]; then ecode=$1 LOG_FILE=$2 ERR_FILE=$3 echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' : ERROR : Details in '$ERR_FILE >> $LOG_FILE exit $ecode fi } script=$(readlink -f $0) current_path=`dirname $script` if [ -f /postgres/scripts/pgbench/STOP_PGBENCH ]; then exit 0 fi RESULT_LOG_FILE=$current_path'/result.log' ERR_FILE=$current_path'/result.err' PROGRESS_FILE=$current_path'/result.progress' result_str=`psql -Aqtc 'select unnest(backrest.cpi_mm_active_report())' 2>$ERR_FILE` exit_code $? $LOG_FILE $PROGRESS_FILE echo $result_str >> $RESULT_LOG_FILE signal=`echo $result_str | awk -F '|' '{print $13}' ` echo 'signal='$signal #Если наблюдение , еще не включено if [ -f /postgres/scripts/stress/STRESS_NOT_STARTED ]; then exit 0 fi if [ "$signal" == 'SIGNAL' ] then echo 'TIMESTAMP : '$(date "+%d-%m-%Y %H:%M:%S") ' | ATTENTION : STRONG NEGATIVE CORRELATION !!! | ' >> $RESULT_LOG_FILE touch /postgres/scripts/pgbench/STOP_PGBENCH fi rm $ERR_FILE exit 0
Реализация теста
Для простоты и сокращения объема материала, приведены графики после запуска дополнительной нагрузки и до окончания теста.
Частота замеров показаний = 1 минута.
Период медианного сглаживания долгой скользящей = 1 час.
Результат теста
Завершение теста: 17.10.2024 22:22:00
Работающий сценарий добавочной нагрузки:
TIMESTAMP : 17-10-2024 22:20:03 : stress_additional : OK : STARTED TIMESTAMP : 17-10-2024 22:20:03 : stress_additional : OK : Количество клиентов: 120
Результат: предельная нагрузка по сценарию pgbench составляет 220 клиентов.
Итог и планы
-
Разработанная методика будет использована для настройки параметров СУБД при новых инсталляциях
-
После определения максимального значения нагрузки pgbench значение будет использовано для оптимизации конфигурационных параметров по методике описанной в Этюд: использование метода покоординатного спуска для оптимизации параметров СУБД / Хабр (habr.com) (Примечание: после разработки автоматизированного скрипта)
-
В дальнейшем данная методика будет использована при нагрузочном тестировании с использованием pgbench и пользовательских скриптов (Программа pgbench поддерживает запуск пользовательских сценариев оценки производительности, позволяя заменять стандартный скрипт транзакции (описанный выше) скриптом, считываемым из файла (с параметром
-f
). В этом случае «транзакцией» считается одно выполнение данного скрипта. ) -
После определения максимальной нагрузки с использованием pgbench + пользовательские скрипты , значение максимальной нагрузки будет проведена оптимизация конфигурационных параметров аналогично Пункту 2.
-
По завершении оптимизации конфигурационных параметров, СУБД передается в опытную эксплуатацию и сопровождение.
Таким образом — выстраивается простой , однозначный и математически обоснованный способ настройки конфигурационных параметров СУБД для новой инсталляции и при передаче СУБД в опытную эксплуатацию.
ссылка на оригинал статьи https://habr.com/ru/articles/851556/
Добавить комментарий