Updated fixtures, human-readable values values in knob/metric comparison view

This commit is contained in:
dvanaken 2020-01-09 02:47:22 -05:00 committed by Dana Van Aken
parent c33defa29a
commit 16348d1c7a
8 changed files with 55 additions and 115 deletions

View File

@ -207,14 +207,6 @@ class BaseParserTests(object, metaclass=ABCMeta):
with self.assertRaises(Exception): with self.assertRaises(Exception):
self.test_dbms.format_dbms_knobs(test_exceptions) self.test_dbms.format_dbms_knobs(test_exceptions)
@abstractmethod
def test_filter_numeric_metrics(self):
pass
@abstractmethod
def test_filter_tunable_knobs(self):
pass
class PostgresParserTests(BaseParserTests, TestCase): class PostgresParserTests(BaseParserTests, TestCase):
@ -501,57 +493,6 @@ class PostgresParserTests(BaseParserTests, TestCase):
self.assertEqual(test_formatted_knobs.get('global.geqo_effort'), 5) self.assertEqual(test_formatted_knobs.get('global.geqo_effort'), 5)
self.assertEqual(test_formatted_knobs.get('global.wal_buffers'), '1kB') self.assertEqual(test_formatted_knobs.get('global.wal_buffers'), '1kB')
def test_filter_numeric_metrics(self):
super().test_filter_numeric_metrics()
test_metrics = {'pg_stat_bgwriter.checkpoints_req': (2, 'global'),
'pg_stat_archiver.last_failed_wal': (1, 'global'),
'pg_stat_database.stats_reset': (6, 'database'),
'pg_statio_user_indexes.indexrelname': (1, 'index'),
'pg_stat_bgwriter.maxwritten_clean': (2, 'global'),
'pg_stat_database.tup_fetched': (2, 'database'),
'pg_statio_user_tables.heap_blks_read': (2, 'table'),
'pg_FAKE_METRIC': (2, 'database')}
filtered_metrics = self.test_dbms.filter_numeric_metrics(test_metrics)
self.assertEqual(len(list(filtered_metrics.keys())), 4)
self.assertEqual(filtered_metrics.get('pg_stat_bgwriter.checkpoints_req'),
(2, 'global'))
self.assertEqual(filtered_metrics.get('pg_stat_archiver.last_failed_wal'), None)
self.assertEqual(filtered_metrics.get('pg_stat_database.stats_reset'), None)
self.assertEqual(filtered_metrics.get('pg_statio_user_indexes.indexrelname'),
None)
self.assertEqual(filtered_metrics.get('pg_stat_bgwriter.maxwritten_clean'),
(2, 'global'))
self.assertEqual(filtered_metrics.get('pg_stat_database.tup_fetched'),
(2, 'database'))
self.assertEqual(filtered_metrics.get('pg_statio_user_tables.heap_blks_read'),
(2, 'table'))
self.assertEqual(filtered_metrics.get('pg_FAKE_KNOB'), None)
def test_filter_tunable_knobs(self):
super().test_filter_tunable_knobs()
test_knobs = {'global.wal_sync_method': 5,
'global.random_page_cost': 3,
'global.archive_command': 1,
'global.cpu_tuple_cost': 3,
'global.force_parallel_mode': 5,
'global.enable_hashjoin': 3,
'global.geqo_effort': 2,
'global.wal_buffers': 2,
'global.FAKE_KNOB': 2}
filtered_knobs = self.test_dbms.filter_tunable_knobs(test_knobs)
self.assertEqual(len(list(filtered_knobs.keys())), 3)
self.assertEqual(filtered_knobs.get('global.wal_sync_method'), 5)
self.assertEqual(filtered_knobs.get('global.wal_buffers'), 2)
self.assertEqual(filtered_knobs.get('global.random_page_cost'), 3)
self.assertEqual(filtered_knobs.get('global.cpu_tuple_cost'), None)
self.assertEqual(filtered_knobs.get('global.FAKE_KNOB'), None)
def test_parse_helper(self): def test_parse_helper(self):
super().test_parse_helper() super().test_parse_helper()

View File

@ -420,12 +420,4 @@ class BaseParser:
formatted_knobs[knob_name] = fvalue formatted_knobs[knob_name] = fvalue
return formatted_knobs return formatted_knobs
def filter_numeric_metrics(self, metrics):
return OrderedDict(((k, v) for k, v in list(metrics.items()) if
k in self.numeric_metric_catalog_))
def filter_tunable_knobs(self, knobs):
return OrderedDict(((k, v) for k, v in list(knobs.items()) if
k in self.tunable_knob_catalog_))
# pylint: enable=no-self-use # pylint: enable=no-self-use

View File

@ -206,10 +206,3 @@ class MyRocksParser(BaseParser):
knob_data[name] = conv_value knob_data[name] = conv_value
return knob_data return knob_data
def filter_numeric_metrics(self, metrics):
return OrderedDict([(k, v) for k, v in list(metrics.items()) if
self.partial_name(k) in self.numeric_metric_catalog_])
def filter_tunable_knobs(self, knobs):
return OrderedDict([(k, v) for k, v in list(knobs.items()) if
self.partial_name(k) in self.tunable_knob_catalog_])

View File

@ -11,11 +11,11 @@ from website.types import DBMSType
class DBTime(BaseTargetObjective): class DBTime(BaseTargetObjective):
def __init__(self): def __init__(self):
super().__init__(name='db_time', pprint='DB Time', unit='milliseconds', short_unit='ms', super().__init__(name='db_time', pprint='DB Time', unit='seconds', short_unit='s',
improvement=LESS_IS_BETTER) 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 return float(metrics['global.sys_time_model.db time']) / observation_time / 1000.
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

View File

@ -73,14 +73,6 @@ def format_dbms_knobs(dbms_id, knobs):
return _get(dbms_id).format_dbms_knobs(knobs) return _get(dbms_id).format_dbms_knobs(knobs)
def filter_numeric_metrics(dbms_id, metrics):
return _get(dbms_id).filter_numeric_metrics(metrics)
def filter_tunable_knobs(dbms_id, knobs):
return _get(dbms_id).filter_tunable_knobs(knobs)
def calculate_change_in_metrics(dbms_id, metrics_start, metrics_end): def calculate_change_in_metrics(dbms_id, metrics_start, metrics_end):
return _get(dbms_id).calculate_change_in_metrics( return _get(dbms_id).calculate_change_in_metrics(
metrics_start, metrics_end) metrics_start, metrics_end)

View File

@ -41,9 +41,9 @@
<caption></caption> <caption></caption>
<tr> <tr>
<td><h5><strong>Name</strong><h5></td> <td><h5><strong>Name</strong><h5></td>
<td><h5><strong>Value {{ target_obj }}</strong></h5></td> <td><h5><strong>Value &emsp; {{ target_obj }}</strong></h5></td>
{% if compare != "none" %} {% if compare != "none" %}
<td><h5><strong>Comparing Value {{ cmp_target_obj }}</strong></h5></td> <td><h5><strong>Comparing Value &emsp; {{ cmp_target_obj }}</strong></h5></td>
{% endif %} {% endif %}
</tr> </tr>
{% for pair in featured_data %} {% for pair in featured_data %}
@ -71,9 +71,9 @@
<caption></caption> <caption></caption>
<tr> <tr>
<td><h5><strong>Name</strong><h5></td> <td><h5><strong>Name</strong><h5></td>
<td><h5><strong>Value</strong></h5></td> <td><h5><strong>Value &emsp; {{ target_obj }}</strong></h5></td>
{% if compare != "none" %} {% if compare != "none" %}
<td><h5><strong>Comparing Value</strong></h5></td> <td><h5><strong>Comparing Value &emsp; {{ cmp_target_obj }}</strong></h5></td>
{% endif %} {% endif %}
</tr> </tr>
{% for pair in all_data %} {% for pair in all_data %}

View File

@ -310,8 +310,6 @@ class ConversionUtil(object):
raise ValueError('Invalid min suffix for system: suffix={}, system={}'.format( raise ValueError('Invalid min suffix for system: suffix={}, system={}'.format(
min_suffix, system)) min_suffix, system))
LOG.info('min_suffix: %s, min_factor: %s, unit: %s, value: %s\nMOD_SYS:\n%s\n\n',
min_suffix, min_factor, unit, value, mod_system)
for factor, suffix in mod_system: for factor, suffix in mod_system:
adj_factor = factor / min_factor adj_factor = factor / min_factor
if value % adj_factor == 0: if value % adj_factor == 0:

View File

@ -415,7 +415,7 @@ def result_view(request, project_id, session_id, result_id):
vwidth = max(len(str(v)) for v in cfg.values()) vwidth = max(len(str(v)) for v in cfg.values())
next_conf = '' next_conf = ''
for k, v in cfg.items(): for k, v in cfg.items():
next_conf += '{: <{kwidth}} = {: >{vwidth}}\n'.format( next_conf += '{: <{kwidth}} = {: <{vwidth}}\n'.format(
k, v, kwidth=kwidth, vwidth=vwidth) k, v, kwidth=kwidth, vwidth=vwidth)
except Exception as e: # pylint: disable=broad-except except Exception as e: # pylint: disable=broad-except
LOG.exception("Failed to format the next config (type=%s): %s.\n\n%s\n", LOG.exception("Failed to format the next config (type=%s): %s.\n\n%s\n",
@ -749,45 +749,69 @@ def metric_data_view(request, project_id, session_id, data_id): # pylint: disab
def dbms_data_view(request, context, dbms_data, session, target_obj): def dbms_data_view(request, context, dbms_data, session, target_obj):
if context['data_type'] == 'knobs': data_type = context['data_type']
dbms_id = session.dbms.pk
def _format_knobs(_dict):
if data_type == 'knobs' and session.dbms.type in (DBMSType.ORACLE,):
_knob_meta = KnobCatalog.objects.filter(
dbms_id=dbms_id, unit=KnobUnitType.BYTES)
_parser = parser._get(dbms_id) # pylint: disable=protected-access
for _meta in _knob_meta:
if _meta.name in _dict:
try:
_v = int(_dict[_meta.name])
_v = _parser.format_integer(_v, _meta)
except (ValueError, TypeError):
LOG.warning("Error parsing knob %s=%s.", _meta.name,
_v, exc_info=True)
_dict[_meta.name] = _v
if data_type == 'knobs':
model_class = KnobData model_class = KnobData
filter_fn = parser.filter_tunable_knobs featured_names = set(SessionKnob.objects.filter(
obj_data = dbms_data.knobs session=session, tunable=True).values_list(
'knob__name', flat=True))
else: else:
model_class = MetricData model_class = MetricData
filter_fn = parser.filter_numeric_metrics num_types = (MetricType.COUNTER, MetricType.STATISTICS)
obj_data = dbms_data.metrics featured_names = set(MetricCatalog.objects.filter(
dbms=session.dbms, metric_type__in=num_types).values_list(
'name', flat=True))
dbms_id = dbms_data.dbms.pk obj_data = getattr(dbms_data, data_type)
all_data_dict = JSONUtil.loads(obj_data) all_data_dict = JSONUtil.loads(obj_data)
featured_dict = filter_fn(dbms_id, all_data_dict) _format_knobs(all_data_dict)
target_obj_name = target_objectives.get_instance( featured_dict = OrderedDict([(k, v) for k, v in all_data_dict.items()
session.dbms.pk, session.target_objective).pprint if k in featured_names])
target_obj = '('+target_obj_name+'='+str(int(target_obj))+')' target_inst = target_objectives.get_instance(dbms_id, session.target_objective)
if 'compare' in request.GET and request.GET['compare'] != 'none': target_obj_name = target_inst.pprint
comp_id = request.GET['compare'] target_fmt = "({}: {{v:.0f}}{})".format(target_obj_name, target_inst.short_unit).format
target_obj = target_fmt(v=target_obj)
comp_id = request.GET.get('compare', 'none')
if comp_id != 'none':
compare_obj = model_class.objects.get(pk=comp_id) compare_obj = model_class.objects.get(pk=comp_id)
comp_data = compare_obj.knobs if \ comp_data = getattr(compare_obj, data_type)
context['data_type'] == 'knobs' else compare_obj.metrics
comp_dict = JSONUtil.loads(comp_data) comp_dict = JSONUtil.loads(comp_data)
comp_featured_dict = filter_fn(dbms_id, comp_dict) _format_knobs(comp_dict)
all_data = [(k, v, comp_dict[k]) for k, v in list(all_data_dict.items())] all_data = [(k, v, comp_dict[k]) for k, v in list(all_data_dict.items())]
featured_data = [(k, v, comp_featured_dict[k]) featured_data = [(k, v, comp_dict[k]) for k, v in list(featured_dict.items())]
for k, v in list(featured_dict.items())]
result = Result.objects.filter(knob_data=compare_obj)[0] if data_type == 'knobs':
cmp_target_obj = JSONUtil.loads(result.metric_data.data)[session.target_objective] met_data = Result.objects.get(knob_data=compare_obj).metric_data.data
cmp_target_obj = '('+target_obj_name+'='+str(int(cmp_target_obj))+')' else:
met_data = dbms_data.data
cmp_target_obj = JSONUtil.loads(met_data)[session.target_objective]
cmp_target_obj = target_fmt(v=cmp_target_obj)
else: else:
comp_id = None
all_data = list(all_data_dict.items()) all_data = list(all_data_dict.items())
featured_data = list(featured_dict.items()) featured_data = list(featured_dict.items())
cmp_target_obj = "" cmp_target_obj = ""
peer_data = model_class.objects.filter( peer_data = model_class.objects.filter(session=session).exclude(pk=dbms_data.pk)
dbms=dbms_data.dbms, session=dbms_data.session)
peer_data = [peer for peer in peer_data if peer.pk != dbms_data.pk]
context['all_data'] = all_data context['all_data'] = all_data
context['featured_data'] = featured_data context['featured_data'] = featured_data