Commit 8d061996 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-23161 avg_count_reset may wrongly be NULL in I_S.INNODB_METRICS

This issue was originally reported by Fungo Wang, along with a fix, as
MySQL Bug #98990.

His suggested fix was applied as part of
mysql/mysql-server@a003fc373d1adb3ccea353b5d7d83f6c4c552383
and released in MySQL 5.7.31.

i_s_metrics_fill(): Add the missing call to Field::set_notnull(),
and simplify some code.
parent dc58987e
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2019, MariaDB Corporation. Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -2557,7 +2557,7 @@ i_s_metrics_fill( ...@@ -2557,7 +2557,7 @@ i_s_metrics_fill(
time_diff = 0; time_diff = 0;
} }
/* Unless MONITOR__NO_AVERAGE is marked, we will need /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated the value by another counter (number of calls) designated
...@@ -2565,8 +2565,9 @@ i_s_metrics_fill( ...@@ -2565,8 +2565,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled time that the counter is enabled and time it is disabled
or time it is sampled. */ or time it is sampled. */
if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) if ((monitor_info->monitor_type
&& (monitor_info->monitor_type & MONITOR_SET_OWNER) & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
== MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) { && monitor_info->monitor_related_id) {
mon_type_t value_start mon_type_t value_start
= MONITOR_VALUE_SINCE_START( = MONITOR_VALUE_SINCE_START(
...@@ -2582,18 +2583,18 @@ i_s_metrics_fill( ...@@ -2582,18 +2583,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null(); fields[METRIC_AVG_VALUE_START]->set_null();
} }
if (MONITOR_VALUE(monitor_info->monitor_related_id)) { if (mon_type_t related_value =
OK(fields[METRIC_AVG_VALUE_RESET]->store( MONITOR_VALUE(monitor_info->monitor_related_id)) {
MONITOR_VALUE(count) OK(fields[METRIC_AVG_VALUE_RESET]
/ MONITOR_VALUE( ->store(MONITOR_VALUE(count)
monitor_info->monitor_related_id), / related_value, false));
FALSE)); fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else { } else {
fields[METRIC_AVG_VALUE_RESET]->set_null(); fields[METRIC_AVG_VALUE_RESET]->set_null();
} }
} else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) } else if (!(monitor_info->monitor_type
&& !(monitor_info->monitor_type & (MONITOR_NO_AVERAGE
& MONITOR_DISPLAY_CURRENT)) { | MONITOR_DISPLAY_CURRENT))) {
if (time_diff) { if (time_diff) {
OK(fields[METRIC_AVG_VALUE_START]->store( OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START( (double) MONITOR_VALUE_SINCE_START(
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2019, MariaDB Corporation. Copyright (c) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -2553,7 +2553,7 @@ i_s_metrics_fill( ...@@ -2553,7 +2553,7 @@ i_s_metrics_fill(
time_diff = 0; time_diff = 0;
} }
/* Unless MONITOR__NO_AVERAGE is marked, we will need /* Unless MONITOR_NO_AVERAGE is set, we must
to calculate the average value. If this is a monitor set to calculate the average value. If this is a monitor set
owner marked by MONITOR_SET_OWNER, divide owner marked by MONITOR_SET_OWNER, divide
the value by another counter (number of calls) designated the value by another counter (number of calls) designated
...@@ -2561,8 +2561,9 @@ i_s_metrics_fill( ...@@ -2561,8 +2561,9 @@ i_s_metrics_fill(
Otherwise average the counter value by the time between the Otherwise average the counter value by the time between the
time that the counter is enabled and time it is disabled time that the counter is enabled and time it is disabled
or time it is sampled. */ or time it is sampled. */
if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) if ((monitor_info->monitor_type
&& (monitor_info->monitor_type & MONITOR_SET_OWNER) & (MONITOR_NO_AVERAGE | MONITOR_SET_OWNER))
== MONITOR_SET_OWNER
&& monitor_info->monitor_related_id) { && monitor_info->monitor_related_id) {
mon_type_t value_start mon_type_t value_start
= MONITOR_VALUE_SINCE_START( = MONITOR_VALUE_SINCE_START(
...@@ -2578,18 +2579,18 @@ i_s_metrics_fill( ...@@ -2578,18 +2579,18 @@ i_s_metrics_fill(
fields[METRIC_AVG_VALUE_START]->set_null(); fields[METRIC_AVG_VALUE_START]->set_null();
} }
if (MONITOR_VALUE(monitor_info->monitor_related_id)) { if (mon_type_t related_value =
OK(fields[METRIC_AVG_VALUE_RESET]->store( MONITOR_VALUE(monitor_info->monitor_related_id)) {
MONITOR_VALUE(count) OK(fields[METRIC_AVG_VALUE_RESET]
/ MONITOR_VALUE( ->store(MONITOR_VALUE(count)
monitor_info->monitor_related_id), / related_value, false));
FALSE)); fields[METRIC_AVG_VALUE_RESET]->set_notnull();
} else { } else {
fields[METRIC_AVG_VALUE_RESET]->set_null(); fields[METRIC_AVG_VALUE_RESET]->set_null();
} }
} else if (!(monitor_info->monitor_type & MONITOR_NO_AVERAGE) } else if (!(monitor_info->monitor_type
&& !(monitor_info->monitor_type & (MONITOR_NO_AVERAGE
& MONITOR_DISPLAY_CURRENT)) { | MONITOR_DISPLAY_CURRENT))) {
if (time_diff) { if (time_diff) {
OK(fields[METRIC_AVG_VALUE_START]->store( OK(fields[METRIC_AVG_VALUE_START]->store(
(double) MONITOR_VALUE_SINCE_START( (double) MONITOR_VALUE_SINCE_START(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment