From dfe8588017d8b7eac30aef7921e6e611a1a96f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 11 Jul 2023 12:47:19 +0200 Subject: [PATCH 1/2] Fix timestamps regression for 'stats_mysql_query_digest' --- lib/ProxySQL_Admin.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index 5e46ffc16..12fcfc4d6 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -9849,6 +9849,12 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( max_bulk_row_idx=max_bulk_row_idx*32; auto it = resultset ? digest_umap->cend() : digest_umap->cbegin(); int i = 0; + + time_t __now; + time(&__now); + unsigned long long curtime=monotonic_time(); + time_t seen_time; + // If the function do not receives a resultset, it gets the values directly from the digest_umap while (resultset ? i != resultset->rows_count : it != digest_umap->end()) { QP_query_digest_stats *qds = (QP_query_digest_stats *)(resultset ? NULL : it->second); @@ -9868,8 +9874,14 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+5, resultset ? row->fields[3] : digest_hex_str.c_str(), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement32, (idx*14)+6, resultset ? row->fields[4] : qds->get_digest_text(digest_text_umap), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+7, resultset ? atoll(row->fields[5]) : qds->count_star); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+8, resultset ? atoll(row->fields[6]) : qds->first_seen); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+9, resultset ? atoll(row->fields[7]) : qds->last_seen); ASSERT_SQLITE_OK(rc, statsdb); + { + seen_time = qds != nullptr ? __now - curtime/1000000 + qds->first_seen/1000000 : 0; + rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+8, resultset ? atoll(row->fields[6]) : seen_time); ASSERT_SQLITE_OK(rc, statsdb); + } + { + seen_time = qds != nullptr ? __now - curtime/1000000 + qds->last_seen/1000000 : 0; + rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+9, resultset ? atoll(row->fields[7]) : seen_time); ASSERT_SQLITE_OK(rc, statsdb); + } rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+10, resultset ? atoll(row->fields[8]) : qds->sum_time); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+11, resultset ? atoll(row->fields[9]) : qds->min_time); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement32, (idx*14)+12, resultset ? atoll(row->fields[10]) : qds->max_time); ASSERT_SQLITE_OK(rc, statsdb); @@ -9888,8 +9900,14 @@ int ProxySQL_Admin::stats___save_mysql_query_digest_to_sqlite( rc=(*proxy_sqlite3_bind_text)(statement1, 5, resultset ? row->fields[3] : digest_hex_str.c_str(), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_text)(statement1, 6, resultset ? row->fields[4] : qds->get_digest_text(digest_text_umap), -1, SQLITE_TRANSIENT); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement1, 7, resultset ? atoll(row->fields[5]) : qds->count_star); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_int64)(statement1, 8, resultset ? atoll(row->fields[6]) : qds->first_seen); ASSERT_SQLITE_OK(rc, statsdb); - rc=(*proxy_sqlite3_bind_int64)(statement1, 9, resultset ? atoll(row->fields[7]) : qds->last_seen); ASSERT_SQLITE_OK(rc, statsdb); + { + seen_time = qds != nullptr ? __now - curtime/1000000 + qds->first_seen/1000000 : 0; + rc=(*proxy_sqlite3_bind_int64)(statement1, 8, resultset ? atoll(row->fields[6]) : seen_time); ASSERT_SQLITE_OK(rc, statsdb); + } + { + seen_time = qds != nullptr ? __now - curtime/1000000 + qds->last_seen/1000000 : 0; + rc=(*proxy_sqlite3_bind_int64)(statement1, 9, resultset ? atoll(row->fields[7]) : seen_time); ASSERT_SQLITE_OK(rc, statsdb); + } rc=(*proxy_sqlite3_bind_int64)(statement1, 10, resultset ? atoll(row->fields[8]) : qds->sum_time); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement1, 11, resultset ? atoll(row->fields[9]) : qds->min_time); ASSERT_SQLITE_OK(rc, statsdb); rc=(*proxy_sqlite3_bind_int64)(statement1, 12, resultset ? atoll(row->fields[10]) : qds->max_time); ASSERT_SQLITE_OK(rc, statsdb); From 83efe7d790fda7bfb39f976a7dd21a164774d996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 11 Jul 2023 12:59:03 +0200 Subject: [PATCH 2/2] Add regression testing for 'stats_mysql_query_digest' timestamps - Added regression testing for timestamps 'first_seen' and 'last_seen'. - Make the test idempotent by cleaning up 'stats_mysql_query_digest'. --- test/tap/tests/test_digest_umap_aux-t.cpp | 24 ++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/tap/tests/test_digest_umap_aux-t.cpp b/test/tap/tests/test_digest_umap_aux-t.cpp index 477dac1f1..609640cec 100644 --- a/test/tap/tests/test_digest_umap_aux-t.cpp +++ b/test/tap/tests/test_digest_umap_aux-t.cpp @@ -174,7 +174,7 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } - plan(1 + DUMMY_QUERIES.size() * 3); // always specify the number of tests that are going to be performed + plan(1 + DUMMY_QUERIES.size() * 5); // always specify the number of tests that are going to be performed MYSQL *proxy_admin = mysql_init(NULL); if (!mysql_real_connect(proxy_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { @@ -182,6 +182,8 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + MYSQL_QUERY(proxy_admin, "TRUNCATE TABLE stats.stats_mysql_query_digest"); + vector admin_queries = { "DELETE FROM mysql_query_rules", "LOAD MYSQL QUERY RULES TO RUNTIME", @@ -199,6 +201,8 @@ int main(int argc, char** argv) { return EXIT_FAILURE; } + time_t init_time = time(NULL); + MYSQL_RES *res = NULL; for (const auto &query : DUMMY_QUERIES) { diag("Running: %s", query); @@ -243,6 +247,8 @@ int main(int argc, char** argv) { ); vector ds_vector_after = get_digest_stats(proxy_admin); + time_t final_time = time(NULL); + for (int i = 0; i < DUMMY_QUERIES.size(); i++) { ok( ds_vector_before[i].hostgroup == ds_vector_after[i].hostgroup && @@ -285,7 +291,23 @@ int main(int argc, char** argv) { ds_vector_before[i].last_seen, ds_vector_after[i].last_seen, ds_vector_before[i].sum_time, ds_vector_after[i].sum_time ); + + uint64_t bf_first_seen = ds_vector_before[i].first_seen; + ok( + init_time - 1 <= bf_first_seen && init_time + 1 >= bf_first_seen, + "'first_seen' within required time range - min: %ld, max: %ld, first_seen: %ld", + init_time - 1, init_time + 1, bf_first_seen + ); + + uint64_t bf_last_seen = ds_vector_before[i].last_seen; + ok( + init_time <= bf_last_seen && final_time >= bf_last_seen, + "'last_seen' within required time range - min: %ld, max: %ld, last_seen: %ld", + init_time, final_time, bf_last_seen + ); } + mysql_close(proxy_admin); + return exit_status(); }