mirror of
				https://github.com/MariaDB/server.git
				synced 2025-11-04 04:46:15 +01:00 
			
		
		
		
	The symptoms were: take a server with no activity and a table that's not in the buffer pool. Run a query that reads the whole table and observe that r_engine_stats.pages_read_count shows about 2% of the table was read. Who reads the rest? The cause was that page prefetching done inside InnoDB was not counted. This counts page prefetch requests made in buf_read_ahead_random() and buf_read_ahead_linear() and makes them visible in: - ANALYZE: r_engine_stats.pages_prefetch_read_count - Slow Query Log: Pages_prefetched: This patch intentionally doesn't attempt to count the time to read the prefetched pages: * there's no obvious place where one can do it * prefetch reads may be done in parallel (right?), it is not clear how to count the time in this case.
		
			
				
	
	
		
			135 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*****************************************************************************
 | 
						|
 | 
						|
Copyright (c) 2023, MariaDB Foundation
 | 
						|
 | 
						|
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
 | 
						|
Foundation; version 2 of the License.
 | 
						|
 | 
						|
This program is distributed in the hope that it will be useful, but WITHOUT
 | 
						|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | 
						|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License along with
 | 
						|
this program; if not, write to the Free Software Foundation, Inc.,
 | 
						|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
 | 
						|
 | 
						|
*****************************************************************************/
 | 
						|
 | 
						|
#pragma once
 | 
						|
 | 
						|
#include "ha_handler_stats.h"
 | 
						|
#include "my_rdtsc.h"
 | 
						|
 | 
						|
/* We do not want a dynamic initialization function to be
 | 
						|
conditionally invoked on each access to a C++11 extern thread_local. */
 | 
						|
#if __cplusplus >= 202002L
 | 
						|
# define simple_thread_local constinit thread_local
 | 
						|
#else
 | 
						|
# define simple_thread_local IF_WIN(__declspec(thread),__thread)
 | 
						|
#endif
 | 
						|
 | 
						|
/** Pointer to handler::active_handler_stats or nullptr (via .tbss) */
 | 
						|
extern simple_thread_local ha_handler_stats *mariadb_stats;
 | 
						|
 | 
						|
/*
 | 
						|
  Returns nonzero if MariaDB wants engine status
 | 
						|
*/
 | 
						|
 | 
						|
inline uint mariadb_stats_active()
 | 
						|
{
 | 
						|
  if (ha_handler_stats *stats= mariadb_stats)
 | 
						|
    return stats->active;
 | 
						|
  return 0;
 | 
						|
}
 | 
						|
 | 
						|
/* The following functions increment different engine status */
 | 
						|
 | 
						|
inline void mariadb_increment_pages_accessed(ha_handler_stats *stats)
 | 
						|
{
 | 
						|
  if (stats)
 | 
						|
    stats->pages_accessed++;
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_pages_accessed()
 | 
						|
{
 | 
						|
  mariadb_increment_pages_accessed(mariadb_stats);
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_pages_updated(ulonglong count)
 | 
						|
{
 | 
						|
  if (ha_handler_stats *stats= mariadb_stats)
 | 
						|
    stats->pages_updated+= count;
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_pages_read(ha_handler_stats *stats)
 | 
						|
{
 | 
						|
  if (stats)
 | 
						|
    stats->pages_read_count++;
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_pages_read()
 | 
						|
{
 | 
						|
  mariadb_increment_pages_read(mariadb_stats);
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_undo_records_read()
 | 
						|
{
 | 
						|
  if (ha_handler_stats *stats= mariadb_stats)
 | 
						|
    stats->undo_records_read++;
 | 
						|
}
 | 
						|
 | 
						|
inline void mariadb_increment_pages_prefetched(ulint n_pages)
 | 
						|
{
 | 
						|
  if (ha_handler_stats *stats= mariadb_stats)
 | 
						|
    stats->pages_prefetched += n_pages;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  The following has to be identical code as measure() in sql_analyze_stmt.h
 | 
						|
 | 
						|
  One should only call this if mariadb_stats_active() is true.
 | 
						|
*/
 | 
						|
 | 
						|
inline ulonglong mariadb_measure()
 | 
						|
{
 | 
						|
#if (MY_TIMER_ROUTINE_CYCLES)
 | 
						|
    return my_timer_cycles();
 | 
						|
#else
 | 
						|
    return my_timer_microseconds();
 | 
						|
#endif
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Call this only of start_time != 0
 | 
						|
  See buf0rea.cc for an example of how to use it efficiently
 | 
						|
*/
 | 
						|
 | 
						|
inline void mariadb_increment_pages_read_time(ulonglong start_time)
 | 
						|
{
 | 
						|
  ha_handler_stats *stats= mariadb_stats;
 | 
						|
  ulonglong end_time= mariadb_measure();
 | 
						|
  /* Check that we only call this if active, see example! */
 | 
						|
  DBUG_ASSERT(start_time);
 | 
						|
  DBUG_ASSERT(stats->active);
 | 
						|
 | 
						|
  stats->pages_read_time+= (end_time - start_time);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/*
 | 
						|
  Helper class to set mariadb_stats temporarly for one call in handler.cc
 | 
						|
*/
 | 
						|
 | 
						|
class mariadb_set_stats
 | 
						|
{
 | 
						|
public:
 | 
						|
  mariadb_set_stats(ha_handler_stats *stats)
 | 
						|
  {
 | 
						|
    mariadb_stats= stats;
 | 
						|
  }
 | 
						|
  ~mariadb_set_stats()
 | 
						|
  {
 | 
						|
    mariadb_stats= nullptr;
 | 
						|
  }
 | 
						|
};
 |