modify target objective (db time)

This commit is contained in:
Dongsheng Yang 2020-04-06 12:56:01 -04:00 committed by Dana Van Aken
parent b711914bd6
commit 4fd1abbe6f
12 changed files with 27398 additions and 6284 deletions

View File

@ -58,7 +58,8 @@ def create_settings(metric_data, dbms):
if vartype in (2, 3): # Numeric (integer/real) if vartype in (2, 3): # Numeric (integer/real)
if 'average' in name or name.endswith('current') or \ if 'average' in name or name.endswith('current') or \
name.startswith('sysstat.session pga memory') or \ name.startswith('sysstat.session pga memory') or \
name.startswith('sysstat.session uga memory'): name.startswith('sysstat.session uga memory') or \
name.endswith('wait_class#'):
mettype = 3 # Statistic mettype = 3 # Statistic
else: else:
mettype = 1 # Counter - most common type of numeric metric mettype = 1 # Counter - most common type of numeric metric
@ -73,6 +74,7 @@ def create_settings(metric_data, dbms):
('dbms', dbms), ('dbms', dbms),
('name', 'global.{}'.format(name)), ('name', 'global.{}'.format(name)),
('vartype', vartype), ('vartype', vartype),
('default', value),
('summary', summary), ('summary', summary),
('scope', 'global'), ('scope', 'global'),
('metric_type', mettype), ('metric_type', mettype),

View File

@ -75,6 +75,7 @@ def main():
fields['name'] = '{}.{}'.format(view_name, metric_name) fields['name'] = '{}.{}'.format(view_name, metric_name)
fields['vartype'] = mstats['vartype'] fields['vartype'] = mstats['vartype']
vartypes.add(fields['vartype']) vartypes.add(fields['vartype'])
fields['default'] = None
fields['summary'] = mstats['summary'] fields['summary'] = mstats['summary']
fields['scope'] = scope fields['scope'] = scope
metric_type = mstats['metric_type'] metric_type = mstats['metric_type']

View File

@ -210,7 +210,7 @@ class BaseParser:
if metadata.metric_type == MetricType.COUNTER: if metadata.metric_type == MetricType.COUNTER:
assert isinstance(converted, float) assert isinstance(converted, float)
base_metric_data[name] = converted base_metric_data[name] = converted
metric_data[name] = converted / observation_time metric_data[name] = converted
elif metadata.metric_type == MetricType.STATISTICS: elif metadata.metric_type == MetricType.STATISTICS:
assert isinstance(converted, float) assert isinstance(converted, float)
base_metric_data[name] = converted base_metric_data[name] = converted

View File

@ -4,22 +4,107 @@
# Copyright (c) 2017-18, Carnegie Mellon University Database Group # Copyright (c) 2017-18, Carnegie Mellon University Database Group
# #
from website.models import DBMSCatalog, MetricCatalog
from website.types import DBMSType from website.types import DBMSType
from ..base.target_objective import BaseTargetObjective, BaseThroughput, LESS_IS_BETTER from ..base.target_objective import (BaseTargetObjective, BaseThroughput, LESS_IS_BETTER,
MORE_IS_BETTER)
class DBTime(BaseTargetObjective): class SummedUpDBTime(BaseTargetObjective):
def __init__(self): def __init__(self):
super().__init__(name='db_time', pprint='DB Time', unit='seconds', short_unit='s', super().__init__(name='summed_up_db_time', pprint='Summed Up DB Time', unit='seconds',
improvement=LESS_IS_BETTER) short_unit='s', improvement=LESS_IS_BETTER)
def compute(self, metrics, observation_time): def compute(self, metrics, observation_time):
return float(metrics['global.sys_time_model.db time']) / observation_time / 1000. total_wait_time = 0.
for name, value in metrics.items():
if 'sys_time_model.db cpu' in name:
total_wait_time += float(value)
elif 'time_waited_micro_fg' in name:
wait_time = float(value)
elif name.endswith('wait_class#'):
# 0: Other; 1: Application; 2: Configuration; 3: Administrative; 4: Concurrency;
# 5: Commit; 6: Idle; 7: Network; 8: User I/O; 9: System I/O
if int(value) == 6:
wait_time = 0
total_wait_time += wait_time
return total_wait_time / 1000000.
class NormalizedDBTime(BaseTargetObjective):
def __init__(self):
super().__init__(name='db_time', pprint='Normalized DB Time', unit='seconds',
short_unit='s', improvement=LESS_IS_BETTER)
def compute(self, metrics, observation_time):
extra_io_metrics = ("log file sync")
not_io_metrics = ("read by other session")
total_wait_time = 0.
# This target objective is designed for Oracle v12.2.0.1.0
dbms = DBMSCatalog.objects.get(type=DBMSType.ORACLE, version='12.2.0.1.0')
for name, value in metrics.items():
if 'sys_time_model.db cpu' in name:
total_wait_time += float(value)
elif 'average_wait_fg' in name:
average_wait = MetricCatalog.objects.get(dbms=dbms, name=name).default
average_wait = float(average_wait) * 10000 # unit = micro seconds
elif 'time_waited_micro_fg' in name:
wait_time = float(value)
elif 'total_waits_fg' in name:
total_waits = int(value)
elif name.endswith('wait_class#'):
value = int(value)
# 0: Other; 1: Application; 2: Configuration; 3: Administrative; 4: Concurrency;
# 5: Commit; 6: Idle; 7: Network; 8: User I/O; 9: System I/O
if value == 6:
wait_time = 0
elif value == 8 or value == 9 or any(n in name for n in extra_io_metrics):
if not any(n in name for n in not_io_metrics):
wait_time = total_waits * average_wait
total_wait_time += wait_time
return total_wait_time / 1000000.
class RawDBTime(BaseTargetObjective):
def __init__(self):
super().__init__(name='raw_db_time', pprint='DB Time (from sys_time_model)',
unit='seconds', short_unit='s', improvement=LESS_IS_BETTER)
def compute(self, metrics, observation_time):
return metrics['global.sys_time_model.db time'] / 1000000.
class TransactionCounter(BaseTargetObjective):
def __init__(self):
super().__init__(name='transaction_counter', pprint='Number of commits and rollbacks',
unit='transactions', short_unit='txn', improvement=MORE_IS_BETTER)
def compute(self, metrics, observation_time):
num_txns = sum(metrics[ctr] for ctr in ('global.sysstat.user commits',
'global.sysstat.user rollbacks'))
return num_txns
class ElapsedTime(BaseTargetObjective):
def __init__(self):
super().__init__(name='elapsed_time', pprint='Elapsed Time', unit='seconds',
short_unit='s', improvement=LESS_IS_BETTER)
def compute(self, metrics, observation_time):
return observation_time
target_objective_list = tuple((DBMSType.ORACLE, target_obj) for target_obj in [ # pylint: disable=invalid-name target_objective_list = tuple((DBMSType.ORACLE, target_obj) for target_obj in [ # pylint: disable=invalid-name
BaseThroughput(transactions_counter=('global.sysstat.user commits', BaseThroughput(transactions_counter=('global.sysstat.user commits',
'global.sysstat.user rollbacks')), 'global.sysstat.user rollbacks')),
DBTime(), SummedUpDBTime(),
NormalizedDBTime(),
RawDBTime(),
TransactionCounter(),
ElapsedTime(),
]) ])

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -97,6 +97,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)), ('name', models.CharField(max_length=128)),
('vartype', models.IntegerField(choices=[(1, 'STRING'), (2, 'INTEGER'), (3, 'REAL'), (4, 'BOOL'), (5, 'ENUM'), (6, 'TIMESTAMP')])), ('vartype', models.IntegerField(choices=[(1, 'STRING'), (2, 'INTEGER'), (3, 'REAL'), (4, 'BOOL'), (5, 'ENUM'), (6, 'TIMESTAMP')])),
('default', models.CharField(max_length=32, null=True)),
('summary', models.TextField(null=True, verbose_name='description')), ('summary', models.TextField(null=True, verbose_name='description')),
('scope', models.CharField(max_length=16)), ('scope', models.CharField(max_length=16)),
('metric_type', models.IntegerField(choices=[(1, 'COUNTER'), (2, 'INFO'), (3, 'STATISTICS')])), ('metric_type', models.IntegerField(choices=[(1, 'COUNTER'), (2, 'INFO'), (3, 'STATISTICS')])),

View File

@ -92,6 +92,7 @@ class MetricCatalog(BaseModel):
dbms = models.ForeignKey(DBMSCatalog) dbms = models.ForeignKey(DBMSCatalog)
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
vartype = models.IntegerField(choices=VarType.choices()) vartype = models.IntegerField(choices=VarType.choices())
default = models.CharField(max_length=32, null=True)
summary = models.TextField(null=True, verbose_name='description') summary = models.TextField(null=True, verbose_name='description')
scope = models.CharField(max_length=16) scope = models.CharField(max_length=16)
metric_type = models.IntegerField(choices=MetricType.choices()) metric_type = models.IntegerField(choices=MetricType.choices())
@ -291,9 +292,9 @@ class SessionKnobManager(models.Manager):
knob = KnobCatalog.objects.get(name=session_knob.name, dbms=session.dbms) knob = KnobCatalog.objects.get(name=session_knob.name, dbms=session.dbms)
knob.tunable = session_knob.tunable knob.tunable = session_knob.tunable
if knob.vartype in (VarType.INTEGER, VarType.REAL): if knob.vartype in (VarType.INTEGER, VarType.REAL):
if knob.minval is None or session_knob.minval < float(knob.minval): if knob.minval is None or float(session_knob.minval) < float(knob.minval):
knob.minval = session_knob.minval knob.minval = session_knob.minval
if knob.maxval is None or session_knob.maxval > float(knob.maxval): if knob.maxval is None or float(session_knob.maxval) > float(knob.maxval):
knob.maxval = session_knob.maxval knob.maxval = session_knob.maxval
knob.save() knob.save()
elif disable_others: elif disable_others:

View File

@ -657,6 +657,17 @@ def handle_result_files(session, files, execution_times=None):
# We tag the metric as invalid, so later they will be set to the worst result # We tag the metric as invalid, so later they will be set to the worst result
metric_data.name = 'default_' + metric_data.name metric_data.name = 'default_' + metric_data.name
metric_data.save() metric_data.save()
if 'transaction_counter' in numeric_metric_dict.keys():
# Normalize metrics by the amount of work
first_metric = MetricData.objects.filter(session=session).first()
first_metric_data = JSONUtil.loads(first_metric.data)
first_transaction_counter = first_metric_data['transaction_counter']
transaction_counter = numeric_metric_dict['transaction_counter']
ratio = transaction_counter / first_transaction_counter
for name in numeric_metric_dict.keys():
numeric_metric_dict[name] = numeric_metric_dict[name] / ratio
metric_data.data = JSONUtil.dumps(numeric_metric_dict)
metric_data.save()
# Create a new workload if this one does not already exist # Create a new workload if this one does not already exist
workload = Workload.objects.create_workload( workload = Workload.objects.create_workload(