О разнесении БД с одного сервера на несколько  
  Содержание  


Эти материалы являются объектом авторского права и защищены законами РФ и международными соглашениями о защите авторских прав. Перед использованием материалов вы обязаны принять условия лицензионного договора на использование этих материалов, или же вы не имеете права использовать настоящие материалы

Авторская площадка "Наши орбиты" состоит из ряда тематических подразделов, являющихся моими лабораторными дневниками, содержащими записи за разное, иногда продолжительно отличающееся, время. Эти материалы призваны рассказать о прошедшем опыте, они никого ни к чему не призывают и совершенно не обязательно могут быть применимы кем-то ещё. Это только лишь истории о прошлом


Основной задачей является выделение ресурсов для каждой отдельной БД, жившей на одном сервере. Это касается CPU, RAM, ёмкости типовых разделов - софта, данных, архивных журналов. Производительности этих разделов

CPU - в целом можно вычислит вес каждой БД, сверив количество активных сессий на графиках ОрСиМОН или по статистикам или метрикам из AWR. После чего рассчитать количество требуемых ядер на новых серверах как пропорцию от количества ядер сервера, на котором жило несколько БД. При этом нужно учитывать, что минисальное количество ядер должно быть не меньше некоторого минимума, определяемого с учетом всей специфики ситуации, например 4 ядра

RAM - необходимо взять текущие значения SGA и PGA, и умножить их сумму на 4/3. В соответствии с рекомендацией оракла - использовать под СУБД 75% всей доступной памяти сервера. ПРи этом обязательно нужен честный раздел SWAP, желательно на быстрой ёмкости

Разделы под СУБД - их три. Это раздел под софт, под данные и под архивные журналы. [1] Раздел под софт может быть типовым, например размером в 50 Гб. С большой вероятностью кроме софта там будут копиться текстовые журналы диагностики, которые могут расти очень быстро, и которые не всегда удобно вычищать сразу [2] Раздел под данные берется из текущих значений размера БД, плюс запас на возможный рост базы [3] Раздел под архивные журналы зависит от размера генерируемых redo. Т.к. эта величина постоянно изменяется, полезно взять максимальное значение, скажем за 1 день, и умножить его на 3 или 5 дней

-- пример доступа к значениям в моменте, но в этой вьюхе не сохраняются долгте данные
select mh.BEGIN_TIME, mh.END_TIME, mh.INTSIZE_CSEC, mh.METRIC_ID, mh.METRIC_NAME, mh.VALUE, mh.METRIC_UNIT,
       mn.GROUP_NAME, 'Event#' ENTITY_ID_DESC, mh.ENTITY_ID, en.NAME
       from SYS.V_$METRIC_HISTORY mh, SYS.V_$METRICNAME mn, V$EVENT_NAME en
       WHERE mh.METRIC_ID = mn.METRIC_ID and mh.GROUP_ID = mn.GROUP_ID
             and mn.GROUP_NAME = 'Resource Manager Stats'
             and mh.ENTITY_ID = en.EVENT# and mn.metric_name like 'I/O Requests'
       order by mh.BEGIN_TIME desc, mh.METRIC_ID, mh.ENTITY_ID ;

-- какие метрики по теме IOps
select METRIC_NAME, count(*) from SYS.V_$METRIC_HISTORY mh where METRIC_NAME
       IN (
'MegaBytes of I/O',
'I/O Megabytes per Second',
'I/O Requests per Second',
'Physical Read Bytes Per Sec',
'Physical Read IO Requests Per Sec',
'Physical Read IO Requests Per Sec',
'Physical Write Bytes Per Sec',
'Physical Write IO Requests Per Sec',
'Physical Writes Per Sec')
       group by METRIC_NAME.
       order by 1 desc ;

-- какие метрики есть в долговременной табличке - их хранится не так и много,
select METRIC_NAME from sys.DBA_HIST_SYSMETRIC_HISTORY group by metric_name order by 1;
select METRIC_NAME descend from sys.DBA_HIST_SYSMETRIC_HISTORY ;

-- пример - посмотреть одну из метрик, количество записейц и сами записи
select count(*) from sys.DBA_HIST_SYSMETRIC_HISTORY 
       where METRIC_NAME = 'I/O Requests per Second'  order by BEGIN_TIME ASC;
select * from sys.DBA_HIST_SYSMETRIC_HISTORY
       where METRIC_NAME = 'I/O Requests per Second'  order by BEGIN_TIME ASC;

-- готовим основные аналитические запросы
select TRUNC(BEGIN_TIME, 'dd') as TIMEPOINT, ROUND(MAX(VALUE),2) max_OPps, ROUND(AVG(VALUE),2) avg_OPps
       from sys.DBA_HIST_SYSMETRIC_HISTORY
       where METRIC_NAME = 'I/O Requests per Second'
       group by TRUNC(BEGIN_TIME, 'dd')
       order by 1 ASC ;

select ROUND(MAX(VALUE),2), ROUND(AVG(VALUE),2)
       from sys.DBA_HIST_SYSMETRIC_HISTORY
       where METRIC_NAME = 'I/O Requests per Second'
       --group by TRUNC(BEGIN_TIME, 'dd')
       order by 1 ASC ;

К этому моменту мы определились, что таблицей источником для получения статистических данных по вводу выводу экземпляра в нашем случае должна стать SYS.DBA_HIST_SYSMETRIC_HISTORY. Дальше - нам необходимо посмотреть, кволько операций из общего количества вписывается в разные диапазоны размеров IOps. для этого мы делаем раскадровку по последовательно нарастающим диапазонам. В целом, думаю себе, будет вполне достаточно выбрать тот максимальный диапазон, в который входит около 1% от всех записей. Это значит, что в более, чем 99% производительности СХД по операциям ввода - вывода хватит. Только нухно помнить, что обязательна поправка на виды IOps, которые бывают разные. Нужно смотреть, одноблочные или многоблочные IOps обеспечивает хранилище, сравнивать размер блока хранилища и БД. Это сложная история, которую можно упростить, если параллельно рассчитать параметр пропускной спохобности СХД не только по операциям, но и по Мегабайтам в секунду. Такая метрика тоже есть

-- --------------------------------------------------------
-- опреаций чтения/записи в секунду - пресловутые IOps через метрики
-- но помним, что IOps бывают разные
-- --------------------------------------------------------
select sum(val_0_2000) val_0_2000, sum(val_2000_4000) val_2000_4000, sum(val_4000_6000) val_4000_6000,
       sum(val_6000_8000) val_6000_8000, sum(val_8000_10000) val_8000_10000, sum(val_10000_12000) val_10000_12000,
       sum(val_12000_14000) val_12000_14000, sum(val_14000_16000) val_14000_16000,
       sum(val_16000_18000) val_16000_18000, sum(val_18000_20000) val_18000_20000, sum(val_20000_22000) val_18000_20000,
       sum(val_22000_24000) val_18000_20000, sum(val_24000_30000) val_24000_30000, sum(val_30000_50000) val_30000_50000
       from (
select CASE WHEN VALUE > 0 AND  VALUE <= 2000 THEN 1 ELSE 0 END as val_0_2000,
       CASE WHEN VALUE > 2000 AND  VALUE <= 4000 THEN 1 ELSE 0 END as val_2000_4000,
       CASE WHEN VALUE > 4000 AND  VALUE <= 6000 THEN 1 ELSE 0 END as val_4000_6000,
       CASE WHEN VALUE > 6000 AND  VALUE <= 8000 THEN 1 ELSE 0 END as val_6000_8000,
       CASE WHEN VALUE > 8000 AND  VALUE <= 10000 THEN 1 ELSE 0 END as val_8000_10000,
       CASE WHEN VALUE > 10000 AND  VALUE <= 12000 THEN 1 ELSE 0 END as val_10000_12000,
       CASE WHEN VALUE > 12000 AND  VALUE <= 14000 THEN 1 ELSE 0 END as val_12000_14000,
       CASE WHEN VALUE > 14000 AND  VALUE <= 16000 THEN 1 ELSE 0 END as val_14000_16000,
       CASE WHEN VALUE > 16000 AND  VALUE <= 18000 THEN 1 ELSE 0 END as val_16000_18000,
       CASE WHEN VALUE > 18000 AND  VALUE <= 20000 THEN 1 ELSE 0 END as val_18000_20000,
       CASE WHEN VALUE > 20000 AND  VALUE <= 22000 THEN 1 ELSE 0 END as val_20000_22000,
       CASE WHEN VALUE > 22000 AND  VALUE <= 24000 THEN 1 ELSE 0 END as val_22000_24000,
       CASE WHEN VALUE > 24000 AND  VALUE <= 30000 THEN 1 ELSE 0 END as val_24000_30000,
       CASE WHEN VALUE > 30000 AND  VALUE <= 50000 THEN 1 ELSE 0 END as val_30000_50000
       from sys.DBA_HIST_SYSMETRIC_HISTORY
       where METRIC_NAME = 'I/O Requests per Second' ) ;

-- --------------------------------------------------------
-- в Мегабайтах чтения/записи в секунду через метрики
-- Пропускная способность для подстраховки показателя IOps
-- но, опять же - в моей картине мира метрики - это всеж агрегированные значения, они могут сглаживать
-- пики, и потому полезно увеличить значения на некий запас
-- --------------------------------------------------------
select sum(val_0_500) val_0_500, sum(val_500_1000) val_500_1000, sum(val_1000_1500) val_1000_1500, sum(val_1500_2000) val_1500_2000,
       sum(val_2000_2500) val_2000_2500, sum(val_2500_3000) val_2500_3000, sum(val_3000_3500) val_3000_3500, sum(val_3500_4000) val_3500_4000,
       sum(val_3500_4000) val_3500_4000, sum(val_4000_6000) val_4000_6000, sum(val_6000_90000) val_6000_9000
       from (
select CASE WHEN VALUE > 0 AND  VALUE <= 500 THEN 1 ELSE 0 END as val_0_500,
       CASE WHEN VALUE > 500 AND  VALUE <= 1000 THEN 1 ELSE 0 END as val_500_1000,
       CASE WHEN VALUE > 1000 AND  VALUE <= 1500 THEN 1 ELSE 0 END as val_1000_1500,
       CASE WHEN VALUE > 1500 AND  VALUE <= 2000 THEN 1 ELSE 0 END as val_1500_2000,
       CASE WHEN VALUE > 2000 AND  VALUE <= 2500 THEN 1 ELSE 0 END as val_2000_2500,
       CASE WHEN VALUE > 2500 AND  VALUE <= 3000 THEN 1 ELSE 0 END as val_2500_3000,
       CASE WHEN VALUE > 3000 AND  VALUE <= 3500 THEN 1 ELSE 0 END as val_3000_3500,
       CASE WHEN VALUE > 3500 AND  VALUE <= 4000 THEN 1 ELSE 0 END as val_3500_4000,
       CASE WHEN VALUE > 4000 AND  VALUE <= 4500 THEN 1 ELSE 0 END as val_4000_4500,
       CASE WHEN VALUE > 4500 AND  VALUE <= 6000 THEN 1 ELSE 0 END as val_4500_6000,
       CASE WHEN VALUE > 6000 AND  VALUE <= 9000 THEN 1 ELSE 0 END as val_6000_9000
       from sys.DBA_HIST_SYSMETRIC_HISTORY
       where METRIC_NAME = 'I/O Megabytes per Second' ) ;

И вот здесь хочется подстраховаться, и проверить полученные данные ещё каким нибудь методом. Такой метод есть - это сохрняемые в AWR системные статистики. Только опять же нужно держать в голове, что диапазоны между срезами статистик ещё больше, чем в метриках обычно. Это значит - пики будут сильно сглаживаться, и рассчитать "линию поддержки", ниже которой показатели, полученные через метрики опускаться не должны

-- --------------------------------------------------------------
-- проверка через статистики
-- --------------------------------------------------------------
-- статистики
-- physical read total IO requests
-- physical write total IO requests
-- redo writes

-- physical read total bytes
-- physical write total bytes
-- redo size

-- выбираем сырые данные
select snap_id, stat_name, value, LAG(value, 1) OVER (ORDER BY snap_id asc) as pre_value,
       value - LAG(value, 1) OVER (ORDER BY snap_id asc) as diff_value
       from DBA_HIST_SYSSTAT
       where stat_name = 'physical read total IO requests' order by snap_id asc ;

-- выбираем сырые данные с данными снапшотов и источниками группировки
select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
       extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
       extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
       extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
       sh.stat_name,
       sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
       sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
       from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
       where stat_name = 'physical read total IO requests'
             and sh.snap_id = sn.snap_id
       order by snap_id asc ;

-- выбираем сырые данные с данными снапшотов и источниками группировки
-- тут уже добавляем расчёт посекундно - но только для одной из трех суммирующих метрик
select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical read total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour ;

-- ОТДЕЛЬНЫЕ ТЕХНОЛОИЧЕСКИЕ ПРОВЕРКИ выбираем сырые данные с данными снапшотов и источниками группировки
select max(diff_ps_value) from (
select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical read total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour) ;

-- проверка writes
select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_write_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical write total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour ;

-- проверка redo
select max(diff_redo_ps_value) from (
select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_redo_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'redo writes'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour ) ;

-- а тут - общее по записи и чтению и redo
select max(diff_read_ps_value + diff_write_ps_value + diff_redo_ps_value)
from
(select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_read_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical read total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour) read_iops,
(select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_write_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical write total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour) write_iops,
(select per_hour, sum(diff_second) diff_second, sum(diff_value) diff_value, round(sum(diff_value)/sum(diff_second),0) diff_redo_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'redo writes'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       group by per_hour
       order by per_hour) redo_iops
    where write_iops.per_hour = read_iops.per_hour and read_iops.per_hour = redo_iops.per_hour ;

-- --------------------------------------------------------
-- а тут - общее по записи и чтению и redo IOps по более удобному snap_id
-- --------------------------------------------------------
select max(diff_read_ps_value + diff_write_ps_value + diff_redo_ps_value)
from
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_read_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical read total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) read_iops,
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_write_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical write total IO requests'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) write_iops,
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_redo_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'redo writes'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) redo_iops
    where write_iops.snap_id = read_iops.snap_id and read_iops.snap_id = redo_iops.snap_id ;

-- --------------------------------------------------------
-- а тут - общее по записи и чтению и redo Mbytes
-- --------------------------------------------------------
select max(diff_read_ps_value + diff_write_ps_value + diff_redo_ps_value)
from
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_read_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical read total bytes'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) read_iops,
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_write_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'physical write total bytes'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) write_iops,
(select snap_id, diff_second, diff_value, round(diff_value/diff_second,0) diff_redo_ps_value
       from (select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
                    extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                    extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                    extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                    sh.stat_name,
                    sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
                    sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
                    from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                    where stat_name = 'redo size'
                          and sh.snap_id = sn.snap_id
                    order by snap_id asc)
       order by snap_id) redo_iops
    where write_iops.snap_id = read_iops.snap_id and read_iops.snap_id = redo_iops.snap_id ;

-- redo
select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'hh') as per_hour,
       extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
       extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
       extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
       sh.stat_name,
       sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as pre_value,
       sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time, sh.snap_id asc) as diff_value
       from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
       where stat_name = 'redo size'
             and sh.snap_id = sn.snap_id
      order by snap_id asc ;

-- окончательный запрос планирования объёмов архивных журналов, с расчетом 5 дней
-- ищем максимальный объём за день и умножаем на пять
select count(*) rec, max(gbs_redo_day), max(gbs_redo_day) * 5 for_5_days from (
       select per_day, round(sum(diff_value/1024/1024/1023),2) gbs_redo_day from (
              select sh.snap_id, sn.begin_interval_time, sn.end_interval_time, TRUNC(sn.end_interval_time, 'dd') as per_day,
                     extract(hour from (sn.end_interval_time - sn.begin_interval_time)) * 3600 +
                     extract(minute from (sn.end_interval_time - sn.begin_interval_time)) * 60 +
                     extract(second from (sn.end_interval_time - sn.begin_interval_time)) as diff_second,
                     sh.stat_name,
                     sh.value, LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number,
                               sn.startup_time, sh.snap_id asc) as pre_value,
                     sh.value - LAG(sh.value, 1) OVER (ORDER BY sn.dbid, sn.instance_number, sn.startup_time,
                               sh.snap_id asc) as diff_value
                     from DBA_HIST_SYSSTAT sh, DBA_HIST_SNAPSHOT sn
                     where stat_name = 'redo size'
                           and sh.snap_id = sn.snap_id
                     order by snap_id asc)
              group by per_day
       order by per_day ) ;








Белонин С.С.
март 2010 г., Москва

(даты последующих модификаций не фиксируются)


        
   
    Нравится     

(C) Белонин С.С., 2000-2026. Дата последней модификации страницы:2026-08-28 12:15:21