Commit 13836600 authored by Annamalai Gurusami's avatar Annamalai Gurusami

Bug #13113026 INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRUFROM 5.6 BACKPORT

Backporting the WL#5716, "Information schema table for InnoDB 
buffer pool information". Backporting revisions 2876.244.113, 
2876.244.102 from mysql-trunk.

rb://1175 approved by Jimmy Yang. 
parent 1cb513ba
......@@ -1001,6 +1001,9 @@ sub collect_one_test_case {
"innodb_cmp=$plugin_filename$sep" .
"innodb_cmp_reset=$plugin_filename$sep" .
"innodb_cmpmem=$plugin_filename$sep" .
"innodb_buffer_page=$plugin_filename$sep" .
"innodb_buffer_page_lru=$plugin_filename$sep" .
"innodb_buffer_pool_stats=$plugin_filename$sep" .
"innodb_cmpmem_reset=$plugin_filename";
foreach my $k ('master_opt', 'slave_opt')
......
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE;
SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE;
CREATE TABLE infoschema_buffer_test (col1 INT) ENGINE = INNODB;
INSERT INTO infoschema_buffer_test VALUES(9);
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and PAGE_TYPE="index";
TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE
test/infoschema_buffer_test GEN_CLUST_INDEX 1 29 FILE_PAGE INDEX
INSERT INTO infoschema_buffer_test VALUES(19);
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and PAGE_TYPE="index";
TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE
test/infoschema_buffer_test GEN_CLUST_INDEX 2 58 FILE_PAGE INDEX
CREATE INDEX idx ON infoschema_buffer_test(col1);
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and INDEX_NAME = "idx" and PAGE_TYPE="index";
TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE
test/infoschema_buffer_test idx 2 32 FILE_PAGE INDEX
DROP TABLE infoschema_buffer_test;
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test";
TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE PAGE_STATE PAGE_TYPE
CREATE TABLE infoschema_parent (id INT NOT NULL, PRIMARY KEY (id))
ENGINE=INNODB;
CREATE TABLE infoschema_child (id INT, parent_id INT, INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES infoschema_parent(id)
ON DELETE CASCADE)
ENGINE=INNODB;
SELECT count(*)
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_child" and PAGE_STATE="file_page"
and PAGE_TYPE="index";
count(*)
2
DROP TABLE infoschema_child;
DROP TABLE infoschema_parent;
show create table information_schema.innodb_buffer_page;
Table Create Table
INNODB_BUFFER_PAGE CREATE TEMPORARY TABLE `INNODB_BUFFER_PAGE` (
`BLOCK_ID` bigint(21) unsigned NOT NULL DEFAULT '0',
`SPACE` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGE_NUMBER` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGE_TYPE` varchar(64) DEFAULT NULL,
`FLUSH_TYPE` bigint(21) unsigned NOT NULL DEFAULT '0',
`FIX_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0',
`IS_HASHED` varchar(3) DEFAULT NULL,
`NEWEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0',
`OLDEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0',
`ACCESS_TIME` bigint(21) unsigned NOT NULL DEFAULT '0',
`TABLE_NAME` varchar(1024) DEFAULT NULL,
`INDEX_NAME` varchar(1024) DEFAULT NULL,
`NUMBER_RECORDS` bigint(21) unsigned NOT NULL DEFAULT '0',
`DATA_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0',
`COMPRESSED_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGE_STATE` varchar(64) DEFAULT NULL,
`IO_FIX` varchar(64) DEFAULT NULL,
`IS_OLD` varchar(3) DEFAULT NULL,
`FREE_PAGE_CLOCK` bigint(21) unsigned NOT NULL DEFAULT '0'
) ENGINE=MEMORY DEFAULT CHARSET=utf8
show create table information_schema.innodb_buffer_page_lru;
Table Create Table
INNODB_BUFFER_PAGE_LRU CREATE TEMPORARY TABLE `INNODB_BUFFER_PAGE_LRU` (
`LRU_POSITION` bigint(21) unsigned NOT NULL DEFAULT '0',
`SPACE` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGE_NUMBER` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGE_TYPE` varchar(64) DEFAULT NULL,
`FLUSH_TYPE` bigint(21) unsigned NOT NULL DEFAULT '0',
`FIX_COUNT` bigint(21) unsigned NOT NULL DEFAULT '0',
`IS_HASHED` varchar(3) DEFAULT NULL,
`NEWEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0',
`OLDEST_MODIFICATION` bigint(21) unsigned NOT NULL DEFAULT '0',
`ACCESS_TIME` bigint(21) unsigned NOT NULL DEFAULT '0',
`TABLE_NAME` varchar(1024) DEFAULT NULL,
`INDEX_NAME` varchar(1024) DEFAULT NULL,
`NUMBER_RECORDS` bigint(21) unsigned NOT NULL DEFAULT '0',
`DATA_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0',
`COMPRESSED_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0',
`COMPRESSED` varchar(3) DEFAULT NULL,
`IO_FIX` varchar(64) DEFAULT NULL,
`IS_OLD` varchar(3) DEFAULT NULL,
`FREE_PAGE_CLOCK` bigint(21) unsigned NOT NULL DEFAULT '0'
) ENGINE=MEMORY DEFAULT CHARSET=utf8
show create table information_schema.innodb_buffer_pool_stats;
Table Create Table
INNODB_BUFFER_POOL_STATS CREATE TEMPORARY TABLE `INNODB_BUFFER_POOL_STATS` (
`POOL_SIZE` bigint(21) unsigned NOT NULL DEFAULT '0',
`FREE_BUFFERS` bigint(21) unsigned NOT NULL DEFAULT '0',
`DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0',
`OLD_DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0',
`MODIFIED_DATABASE_PAGES` bigint(21) unsigned NOT NULL DEFAULT '0',
`PENDING_DECOMPRESS` bigint(21) unsigned NOT NULL DEFAULT '0',
`PENDING_READS` bigint(21) unsigned NOT NULL DEFAULT '0',
`PENDING_FLUSH_LRU` bigint(21) unsigned NOT NULL DEFAULT '0',
`PENDING_FLUSH_LIST` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGES_MADE_YOUNG` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGES_NOT_MADE_YOUNG` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGES_MADE_YOUNG_RATE` double NOT NULL DEFAULT '0',
`PAGES_MADE_NOT_YOUNG_RATE` double NOT NULL DEFAULT '0',
`NUMBER_PAGES_READ` bigint(21) unsigned NOT NULL DEFAULT '0',
`NUMBER_PAGES_CREATED` bigint(21) unsigned NOT NULL DEFAULT '0',
`NUMBER_PAGES_WRITTEN` bigint(21) unsigned NOT NULL DEFAULT '0',
`PAGES_READ_RATE` double NOT NULL DEFAULT '0',
`PAGES_CREATE_RATE` double NOT NULL DEFAULT '0',
`PAGES_WRITTEN_RATE` double NOT NULL DEFAULT '0',
`NUMBER_PAGES_GET` bigint(21) unsigned NOT NULL DEFAULT '0',
`HIT_RATE` bigint(21) unsigned NOT NULL DEFAULT '0',
`YOUNG_MAKE_PER_THOUSAND_GETS` bigint(21) unsigned NOT NULL DEFAULT '0',
`NOT_YOUNG_MAKE_PER_THOUSAND_GETS` bigint(21) unsigned NOT NULL DEFAULT '0',
`NUMBER_PAGES_READ_AHEAD` bigint(21) unsigned NOT NULL DEFAULT '0',
`NUMBER_READ_AHEAD_EVICTED` bigint(21) unsigned NOT NULL DEFAULT '0',
`READ_AHEAD_RATE` double NOT NULL DEFAULT '0',
`READ_AHEAD_EVICTED_RATE` double NOT NULL DEFAULT '0',
`LRU_IO_TOTAL` bigint(21) unsigned NOT NULL DEFAULT '0',
`LRU_IO_CURRENT` bigint(21) unsigned NOT NULL DEFAULT '0',
`UNCOMPRESS_TOTAL` bigint(21) unsigned NOT NULL DEFAULT '0',
`UNCOMPRESS_CURRENT` bigint(21) unsigned NOT NULL DEFAULT '0'
) ENGINE=MEMORY DEFAULT CHARSET=utf8
# Exercise the code path for INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS
# and INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
-- source include/have_innodb_plugin.inc
-- disable_result_log
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
# How many buffer pools we have
SELECT count(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS;
SELECT * FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE;
# This gives the over all buffer pool size
SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE;
-- enable_result_log
# Create a table and check its page info behave correctly in the pool
CREATE TABLE infoschema_buffer_test (col1 INT) ENGINE = INNODB;
INSERT INTO infoschema_buffer_test VALUES(9);
# We should be able to see this table in the buffer pool if we check
# right away
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and PAGE_TYPE="index";
# The NUMBER_RECORDS and DATA_SIZE should check with each insertion
INSERT INTO infoschema_buffer_test VALUES(19);
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and PAGE_TYPE="index";
CREATE INDEX idx ON infoschema_buffer_test(col1);
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test"
and PAGE_STATE="file_page" and INDEX_NAME = "idx" and PAGE_TYPE="index";
# Check the buffer after dropping the table
DROP TABLE infoschema_buffer_test;
SELECT TABLE_NAME, INDEX_NAME, NUMBER_RECORDS, DATA_SIZE, PAGE_STATE, PAGE_TYPE
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_buffer_test";
# Do one more test
#--replace_regex /'*[0-9]*'/'NUM'/
CREATE TABLE infoschema_parent (id INT NOT NULL, PRIMARY KEY (id))
ENGINE=INNODB;
CREATE TABLE infoschema_child (id INT, parent_id INT, INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES infoschema_parent(id)
ON DELETE CASCADE)
ENGINE=INNODB;
SELECT count(*)
FROM INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
WHERE TABLE_NAME like "%infoschema_child" and PAGE_STATE="file_page"
and PAGE_TYPE="index";
DROP TABLE infoschema_child;
DROP TABLE infoschema_parent;
show create table information_schema.innodb_buffer_page;
show create table information_schema.innodb_buffer_page_lru;
show create table information_schema.innodb_buffer_pool_stats;
......@@ -269,14 +269,6 @@ read-ahead or flush occurs */
UNIV_INTERN ibool buf_debug_prints = FALSE;
#endif /* UNIV_DEBUG */
/** A chunk of buffers. The buffer pool is allocated in chunks. */
struct buf_chunk_struct{
ulint mem_size; /*!< allocated size of the chunk */
ulint size; /*!< size of frames[] and blocks[] */
void* mem; /*!< pointer to the memory area which
was allocated for the frames */
buf_block_t* blocks; /*!< array of buffer control blocks */
};
#endif /* !UNIV_HOTBACKUP */
/********************************************************************//**
......@@ -3623,6 +3615,133 @@ buf_get_free_list_len(void)
return(len);
}
/*******************************************************************//**
Collect buffer pool stats information for a buffer pool. Also
record aggregated stats if there are more than one buffer pool
in the server */
UNIV_INTERN
void
buf_stats_get_pool_info(
/*====================*/
buf_pool_info_t* pool_info) /*!< in/out: buffer pool info
to fill */
{
time_t current_time;
double time_elapsed;
buf_pool_mutex_enter();
pool_info->pool_size = buf_pool->curr_size;
pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
pool_info->old_lru_len = buf_pool->LRU_old_len;
pool_info->free_list_len = UT_LIST_GET_LEN(buf_pool->free);
pool_info->flush_list_len = UT_LIST_GET_LEN(buf_pool->flush_list);
pool_info->n_pend_unzip = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
pool_info->n_pend_reads = buf_pool->n_pend_reads;
pool_info->n_pending_flush_lru =
(buf_pool->n_flush[BUF_FLUSH_LRU]
+ buf_pool->init_flush[BUF_FLUSH_LRU]);
pool_info->n_pending_flush_list =
(buf_pool->n_flush[BUF_FLUSH_LIST]
+ buf_pool->init_flush[BUF_FLUSH_LIST]);
pool_info->n_pending_flush_single_page =
(buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]
+ buf_pool->init_flush[BUF_FLUSH_SINGLE_PAGE]);
current_time = time(NULL);
time_elapsed = 0.001 + difftime(current_time,
buf_pool->last_printout_time);
pool_info->n_pages_made_young = buf_pool->stat.n_pages_made_young;
pool_info->n_pages_not_made_young =
buf_pool->stat.n_pages_not_made_young;
pool_info->n_pages_read = buf_pool->stat.n_pages_read;
pool_info->n_pages_created = buf_pool->stat.n_pages_created;
pool_info->n_pages_written = buf_pool->stat.n_pages_written;
pool_info->n_page_gets = buf_pool->stat.n_page_gets;
pool_info->n_ra_pages_read_rnd = buf_pool->stat.n_ra_pages_read_rnd;
pool_info->n_ra_pages_read = buf_pool->stat.n_ra_pages_read;
pool_info->n_ra_pages_evicted = buf_pool->stat.n_ra_pages_evicted;
pool_info->page_made_young_rate =
(buf_pool->stat.n_pages_made_young
- buf_pool->old_stat.n_pages_made_young) / time_elapsed;
pool_info->page_not_made_young_rate =
(buf_pool->stat.n_pages_not_made_young
- buf_pool->old_stat.n_pages_not_made_young) / time_elapsed;
pool_info->pages_read_rate =
(buf_pool->stat.n_pages_read
- buf_pool->old_stat.n_pages_read) / time_elapsed;
pool_info->pages_created_rate =
(buf_pool->stat.n_pages_created
- buf_pool->old_stat.n_pages_created) / time_elapsed;
pool_info->pages_written_rate =
(buf_pool->stat.n_pages_written
- buf_pool->old_stat.n_pages_written) / time_elapsed;
pool_info->n_page_get_delta = buf_pool->stat.n_page_gets
- buf_pool->old_stat.n_page_gets;
if (pool_info->n_page_get_delta) {
pool_info->page_read_delta = buf_pool->stat.n_pages_read
- buf_pool->old_stat.n_pages_read;
pool_info->young_making_delta =
buf_pool->stat.n_pages_made_young
- buf_pool->old_stat.n_pages_made_young;
pool_info->not_young_making_delta =
buf_pool->stat.n_pages_not_made_young
- buf_pool->old_stat.n_pages_not_made_young;
}
pool_info->pages_readahead_rnd_rate =
(buf_pool->stat.n_ra_pages_read_rnd
- buf_pool->old_stat.n_ra_pages_read_rnd) / time_elapsed;
pool_info->pages_readahead_rate =
(buf_pool->stat.n_ra_pages_read
- buf_pool->old_stat.n_ra_pages_read) / time_elapsed;
pool_info->pages_evicted_rate =
(buf_pool->stat.n_ra_pages_evicted
- buf_pool->old_stat.n_ra_pages_evicted) / time_elapsed;
pool_info->unzip_lru_len = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
pool_info->io_sum = buf_LRU_stat_sum.io;
pool_info->io_cur = buf_LRU_stat_cur.io;
pool_info->unzip_sum = buf_LRU_stat_sum.unzip;
pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
buf_refresh_io_stats();
buf_pool_mutex_exit();
}
#else /* !UNIV_HOTBACKUP */
/********************************************************************//**
Inits a page to the buffer buf_pool, for use in ibbackup --restore. */
......@@ -3653,3 +3772,5 @@ buf_page_init_for_backup_restore(
}
}
#endif /* !UNIV_HOTBACKUP */
......@@ -11341,7 +11341,10 @@ i_s_innodb_lock_waits,
i_s_innodb_cmp,
i_s_innodb_cmp_reset,
i_s_innodb_cmpmem,
i_s_innodb_cmpmem_reset
i_s_innodb_cmpmem_reset,
i_s_innodb_buffer_page,
i_s_innodb_buffer_page_lru,
i_s_innodb_buffer_stats
mysql_declare_plugin_end;
/** @brief Initialize the default value of innodb_commit_concurrency.
......
......@@ -41,10 +41,90 @@ extern "C" {
#include "buf0buf.h" /* for buf_pool and PAGE_ZIP_MIN_SIZE */
#include "ha_prototypes.h" /* for innobase_convert_name() */
#include "srv0start.h" /* for srv_was_started */
#include "btr0btr.h"
#include "log0log.h"
}
static const char plugin_author[] = "Innobase Oy";
/** structure associates a name string with a file page type and/or buffer
page state. */
struct buffer_page_desc_str_struct{
const char* type_str; /*!< String explain the page
type/state */
ulint type_value; /*!< Page type or page state */
};
typedef struct buffer_page_desc_str_struct buf_page_desc_str_t;
/** Any states greater than FIL_PAGE_TYPE_LAST would be treated as unknown. */
#define I_S_PAGE_TYPE_UNKNOWN (FIL_PAGE_TYPE_LAST + 1)
/** We also define I_S_PAGE_TYPE_INDEX as the Index Page's position
in i_s_page_type[] array */
#define I_S_PAGE_TYPE_INDEX 1
/** Name string for File Page Types */
static buf_page_desc_str_t i_s_page_type[] = {
{"ALLOCATED", FIL_PAGE_TYPE_ALLOCATED},
{"INDEX", FIL_PAGE_INDEX},
{"UNDO_LOG", FIL_PAGE_UNDO_LOG},
{"INODE", FIL_PAGE_INODE},
{"IBUF_FREE_LIST", FIL_PAGE_IBUF_FREE_LIST},
{"IBUF_BITMAP", FIL_PAGE_IBUF_BITMAP},
{"SYSTEM", FIL_PAGE_TYPE_SYS},
{"TRX_SYSTEM", FIL_PAGE_TYPE_TRX_SYS},
{"FILE_SPACE_HEADER", FIL_PAGE_TYPE_FSP_HDR},
{"EXTENT_DESCRIPTOR", FIL_PAGE_TYPE_XDES},
{"BLOB", FIL_PAGE_TYPE_BLOB},
{"COMPRESSED_BLOB", FIL_PAGE_TYPE_ZBLOB},
{"COMPRESSED_BLOB2", FIL_PAGE_TYPE_ZBLOB2},
{"UNKNOWN", I_S_PAGE_TYPE_UNKNOWN}
};
/* Check if we can hold all page type in a 4 bit value */
#if I_S_PAGE_TYPE_UNKNOWN > 1<<4
# error "i_s_page_type[] is too large"
#endif
/** This structure defines information we will fetch from pages
currently cached in the buffer pool. It will be used to populate
table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE */
struct buffer_page_info_struct{
ulint block_id; /*!< Buffer Pool block ID */
unsigned space_id:32; /*!< Tablespace ID */
unsigned page_num:32; /*!< Page number/offset */
unsigned access_time:32; /*!< Time of first access */
unsigned flush_type:2; /*!< Flush type */
unsigned io_fix:2; /*!< type of pending I/O operation */
unsigned fix_count:19; /*!< Count of how manyfold this block
is bufferfixed */
unsigned hashed:1; /*!< Whether hash index has been
built on this page */
unsigned is_old:1; /*!< TRUE if the block is in the old
blocks in buf_pool->LRU_old */
unsigned freed_page_clock:31; /*!< the value of
buf_pool->freed_page_clock */
unsigned zip_ssize:PAGE_ZIP_SSIZE_BITS;
/*!< Compressed page size */
unsigned page_state:BUF_PAGE_STATE_BITS; /*!< Page state */
unsigned page_type:4; /*!< Page type */
unsigned num_recs:UNIV_PAGE_SIZE_SHIFT-2;
/*!< Number of records on Page */
unsigned data_size:UNIV_PAGE_SIZE_SHIFT;
/*!< Sum of the sizes of the records */
lsn_t newest_mod; /*!< Log sequence number of
the youngest modification */
lsn_t oldest_mod; /*!< Log sequence number of
the oldest modification */
dulint index_id; /*!< Index ID if a index page */
};
typedef struct buffer_page_info_struct buf_page_info_t;
/** maximum number of buffer page info we would cache. */
#define MAX_BUF_INFO_CACHED 10000
#define OK(expr) \
if ((expr) != 0) { \
DBUG_RETURN(1); \
......@@ -1576,3 +1656,1675 @@ i_s_common_deinit(
DBUG_RETURN(0);
}
/* Fields of the dynamic table INNODB_BUFFER_POOL_STATS. */
static ST_FIELD_INFO i_s_innodb_buffer_stats_fields_info[] =
{
#define IDX_BUF_STATS_POOL_SIZE 0
{STRUCT_FLD(field_name, "POOL_SIZE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_FREE_BUFFERS 1
{STRUCT_FLD(field_name, "FREE_BUFFERS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_LRU_LEN 2
{STRUCT_FLD(field_name, "DATABASE_PAGES"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_OLD_LRU_LEN 3
{STRUCT_FLD(field_name, "OLD_DATABASE_PAGES"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_FLUSH_LIST_LEN 4
{STRUCT_FLD(field_name, "MODIFIED_DATABASE_PAGES"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PENDING_ZIP 5
{STRUCT_FLD(field_name, "PENDING_DECOMPRESS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PENDING_READ 6
{STRUCT_FLD(field_name, "PENDING_READS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_FLUSH_LRU 7
{STRUCT_FLD(field_name, "PENDING_FLUSH_LRU"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_FLUSH_LIST 8
{STRUCT_FLD(field_name, "PENDING_FLUSH_LIST"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_YOUNG 9
{STRUCT_FLD(field_name, "PAGES_MADE_YOUNG"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_NOT_YOUNG 10
{STRUCT_FLD(field_name, "PAGES_NOT_MADE_YOUNG"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_YOUNG_RATE 11
{STRUCT_FLD(field_name, "PAGES_MADE_YOUNG_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE 12
{STRUCT_FLD(field_name, "PAGES_MADE_NOT_YOUNG_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_READ 13
{STRUCT_FLD(field_name, "NUMBER_PAGES_READ"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_CREATED 14
{STRUCT_FLD(field_name, "NUMBER_PAGES_CREATED"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_WRITTEN 15
{STRUCT_FLD(field_name, "NUMBER_PAGES_WRITTEN"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_READ_RATE 16
{STRUCT_FLD(field_name, "PAGES_READ_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_CREATE_RATE 17
{STRUCT_FLD(field_name, "PAGES_CREATE_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_PAGE_WRITTEN_RATE 18
{STRUCT_FLD(field_name, "PAGES_WRITTEN_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_GET 19
{STRUCT_FLD(field_name, "NUMBER_PAGES_GET"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_HIT_RATE 20
{STRUCT_FLD(field_name, "HIT_RATE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_MADE_YOUNG_PCT 21
{STRUCT_FLD(field_name, "YOUNG_MAKE_PER_THOUSAND_GETS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_NOT_MADE_YOUNG_PCT 22
{STRUCT_FLD(field_name, "NOT_YOUNG_MAKE_PER_THOUSAND_GETS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_READ_AHREAD 23
{STRUCT_FLD(field_name, "NUMBER_PAGES_READ_AHEAD"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_READ_AHEAD_EVICTED 24
{STRUCT_FLD(field_name, "NUMBER_READ_AHEAD_EVICTED"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_READ_AHEAD_RATE 25
{STRUCT_FLD(field_name, "READ_AHEAD_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_READ_AHEAD_EVICT_RATE 26
{STRUCT_FLD(field_name, "READ_AHEAD_EVICTED_RATE"),
STRUCT_FLD(field_length, MAX_FLOAT_STR_LENGTH),
STRUCT_FLD(field_type, MYSQL_TYPE_FLOAT),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, 0),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_LRU_IO_SUM 27
{STRUCT_FLD(field_name, "LRU_IO_TOTAL"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_LRU_IO_CUR 28
{STRUCT_FLD(field_name, "LRU_IO_CURRENT"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_UNZIP_SUM 29
{STRUCT_FLD(field_name, "UNCOMPRESS_TOTAL"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_STATS_UNZIP_CUR 30
{STRUCT_FLD(field_name, "UNCOMPRESS_CURRENT"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
/*******************************************************************//**
Fill Information Schema table INNODB_BUFFER_POOL_STATS for a particular
buffer pool
@return 0 on success, 1 on failure */
static
int
i_s_innodb_stats_fill(
/*==================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
const buf_pool_info_t* info) /*!< in: buffer pool
information */
{
TABLE* table;
Field** fields;
DBUG_ENTER("i_s_innodb_stats_fill");
table = tables->table;
fields = table->field;
OK(fields[IDX_BUF_STATS_POOL_SIZE]->store(info->pool_size));
OK(fields[IDX_BUF_STATS_LRU_LEN]->store(info->lru_len));
OK(fields[IDX_BUF_STATS_OLD_LRU_LEN]->store(info->old_lru_len));
OK(fields[IDX_BUF_STATS_FREE_BUFFERS]->store(info->free_list_len));
OK(fields[IDX_BUF_STATS_FLUSH_LIST_LEN]->store(
info->flush_list_len));
OK(fields[IDX_BUF_STATS_PENDING_ZIP]->store(info->n_pend_unzip));
OK(fields[IDX_BUF_STATS_PENDING_READ]->store(info->n_pend_reads));
OK(fields[IDX_BUF_STATS_FLUSH_LRU]->store(info->n_pending_flush_lru));
OK(fields[IDX_BUF_STATS_FLUSH_LIST]->store(info->n_pending_flush_list));
OK(fields[IDX_BUF_STATS_PAGE_YOUNG]->store(info->n_pages_made_young));
OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG]->store(
info->n_pages_not_made_young));
OK(fields[IDX_BUF_STATS_PAGE_YOUNG_RATE]->store(
info->page_made_young_rate));
OK(fields[IDX_BUF_STATS_PAGE_NOT_YOUNG_RATE]->store(
info->page_not_made_young_rate));
OK(fields[IDX_BUF_STATS_PAGE_READ]->store(info->n_pages_read));
OK(fields[IDX_BUF_STATS_PAGE_CREATED]->store(info->n_pages_created));
OK(fields[IDX_BUF_STATS_PAGE_WRITTEN]->store(info->n_pages_written));
OK(fields[IDX_BUF_STATS_GET]->store(info->n_page_gets));
OK(fields[IDX_BUF_STATS_PAGE_READ_RATE]->store(info->pages_read_rate));
OK(fields[IDX_BUF_STATS_PAGE_CREATE_RATE]->store(info->pages_created_rate));
OK(fields[IDX_BUF_STATS_PAGE_WRITTEN_RATE]->store(info->pages_written_rate));
if (info->n_page_get_delta) {
OK(fields[IDX_BUF_STATS_HIT_RATE]->store(
1000 - (1000 * info->page_read_delta
/ info->n_page_get_delta)));
OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(
1000 * info->young_making_delta
/ info->n_page_get_delta));
OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(
1000 * info->not_young_making_delta
/ info->n_page_get_delta));
} else {
OK(fields[IDX_BUF_STATS_HIT_RATE]->store(0));
OK(fields[IDX_BUF_STATS_MADE_YOUNG_PCT]->store(0));
OK(fields[IDX_BUF_STATS_NOT_MADE_YOUNG_PCT]->store(0));
}
OK(fields[IDX_BUF_STATS_READ_AHREAD]->store(info->n_ra_pages_read));
OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICTED]->store(
info->n_ra_pages_evicted));
OK(fields[IDX_BUF_STATS_READ_AHEAD_RATE]->store(
info->pages_readahead_rate));
OK(fields[IDX_BUF_STATS_READ_AHEAD_EVICT_RATE]->store(
info->pages_evicted_rate));
OK(fields[IDX_BUF_STATS_LRU_IO_SUM]->store(info->io_sum));
OK(fields[IDX_BUF_STATS_LRU_IO_CUR]->store(info->io_cur));
OK(fields[IDX_BUF_STATS_UNZIP_SUM]->store(info->unzip_sum));
OK(fields[IDX_BUF_STATS_UNZIP_CUR]->store( info->unzip_cur));
DBUG_RETURN(schema_table_store_record(thd, table));
}
/*******************************************************************//**
This is the function that loops through each buffer pool and fetch buffer
pool stats to information schema table: I_S_INNODB_BUFFER_POOL_STATS
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_stats_fill_table(
/*===============================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
Item* ) /*!< in: condition (ignored) */
{
int status = 0;
buf_pool_info_t* pool_info;
DBUG_ENTER("i_s_innodb_buffer_fill_general");
/* Only allow the PROCESS privilege holder to access the stats */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
pool_info = (buf_pool_info_t*) mem_zalloc(sizeof *pool_info);
/* Fetch individual buffer pool info */
buf_stats_get_pool_info(pool_info);
status = i_s_innodb_stats_fill(thd, tables, pool_info);
mem_free(pool_info);
DBUG_RETURN(status);
}
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_POOL_STATS.
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_pool_stats_init(
/*==============================*/
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
DBUG_ENTER("i_s_innodb_buffer_pool_stats_init");
schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
schema->fields_info = i_s_innodb_buffer_stats_fields_info;
schema->fill_table = i_s_innodb_buffer_stats_fill_table;
DBUG_RETURN(0);
}
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_stats =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
/* int */
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
/* pointer to type-specific plugin descriptor */
/* void* */
STRUCT_FLD(info, &i_s_info),
/* plugin name */
/* const char* */
STRUCT_FLD(name, "INNODB_BUFFER_POOL_STATS"),
/* plugin author (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(author, plugin_author),
/* general descriptive text (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(descr, "InnoDB Buffer Pool Statistics Information "),
/* the plugin license (PLUGIN_LICENSE_XXX) */
/* int */
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
/* the function to invoke when plugin is loaded */
/* int (*)(void*); */
STRUCT_FLD(init, i_s_innodb_buffer_pool_stats_init),
/* the function to invoke when plugin is unloaded */
/* int (*)(void*); */
STRUCT_FLD(deinit, i_s_common_deinit),
/* plugin version (for SHOW PLUGINS) */
/* unsigned int */
STRUCT_FLD(version, INNODB_VERSION_SHORT),
/* struct st_mysql_show_var* */
STRUCT_FLD(status_vars, NULL),
/* struct st_mysql_sys_var** */
STRUCT_FLD(system_vars, NULL),
/* reserved for dependency checking */
/* void* */
STRUCT_FLD(__reserved1, NULL),
};
/* Fields of the dynamic table INNODB_BUFFER_POOL_PAGE. */
static ST_FIELD_INFO i_s_innodb_buffer_page_fields_info[] =
{
#define IDX_BUFFER_BLOCK_ID 0
{STRUCT_FLD(field_name, "BLOCK_ID"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_SPACE 1
{STRUCT_FLD(field_name, "SPACE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_NUM 2
{STRUCT_FLD(field_name, "PAGE_NUMBER"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_TYPE 3
{STRUCT_FLD(field_name, "PAGE_TYPE"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_FLUSH_TYPE 4
{STRUCT_FLD(field_name, "FLUSH_TYPE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_FIX_COUNT 5
{STRUCT_FLD(field_name, "FIX_COUNT"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_HASHED 6
{STRUCT_FLD(field_name, "IS_HASHED"),
STRUCT_FLD(field_length, 3),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_NEWEST_MOD 7
{STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_OLDEST_MOD 8
{STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_ACCESS_TIME 9
{STRUCT_FLD(field_name, "ACCESS_TIME"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_TABLE_NAME 10
{STRUCT_FLD(field_name, "TABLE_NAME"),
STRUCT_FLD(field_length, 1024),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_INDEX_NAME 11
{STRUCT_FLD(field_name, "INDEX_NAME"),
STRUCT_FLD(field_length, 1024),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_NUM_RECS 12
{STRUCT_FLD(field_name, "NUMBER_RECORDS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_DATA_SIZE 13
{STRUCT_FLD(field_name, "DATA_SIZE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_ZIP_SIZE 14
{STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_STATE 15
{STRUCT_FLD(field_name, "PAGE_STATE"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_IO_FIX 16
{STRUCT_FLD(field_name, "IO_FIX"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_IS_OLD 17
{STRUCT_FLD(field_name, "IS_OLD"),
STRUCT_FLD(field_length, 3),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUFFER_PAGE_FREE_CLOCK 18
{STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
/*******************************************************************//**
Fill Information Schema table INNODB_BUFFER_PAGE with information
cached in the buf_page_info_t array
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_page_fill(
/*========================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
const buf_page_info_t* info_array, /*!< in: array cached page
info */
ulint num_page, /*!< in: number of page info
cached */
mem_heap_t* heap) /*!< in: temp heap memory */
{
TABLE* table;
Field** fields;
DBUG_ENTER("i_s_innodb_buffer_page_fill");
table = tables->table;
fields = table->field;
/* Iterate through the cached array and fill the I_S table rows */
for (ulint i = 0; i < num_page; i++) {
const buf_page_info_t* page_info;
const char* table_name;
const char* index_name;
const char* state_str;
enum buf_page_state state;
page_info = info_array + i;
table_name = NULL;
index_name = NULL;
state_str = NULL;
OK(fields[IDX_BUFFER_BLOCK_ID]->store(page_info->block_id));
OK(fields[IDX_BUFFER_PAGE_SPACE]->store(page_info->space_id));
OK(fields[IDX_BUFFER_PAGE_NUM]->store(page_info->page_num));
OK(field_store_string(
fields[IDX_BUFFER_PAGE_TYPE],
i_s_page_type[page_info->page_type].type_str));
OK(fields[IDX_BUFFER_PAGE_FLUSH_TYPE]->store(
page_info->flush_type));
OK(fields[IDX_BUFFER_PAGE_FIX_COUNT]->store(
page_info->fix_count));
if (page_info->hashed) {
OK(field_store_string(
fields[IDX_BUFFER_PAGE_HASHED], "YES"));
} else {
OK(field_store_string(
fields[IDX_BUFFER_PAGE_HASHED], "NO"));
}
OK(fields[IDX_BUFFER_PAGE_NEWEST_MOD]->store(
(longlong) page_info->newest_mod, true));
OK(fields[IDX_BUFFER_PAGE_OLDEST_MOD]->store(
(longlong) page_info->oldest_mod, true));
OK(fields[IDX_BUFFER_PAGE_ACCESS_TIME]->store(
page_info->access_time));
/* If this is an index page, fetch the index name
and table name */
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
const dict_index_t* index;
mutex_enter(&dict_sys->mutex);
index = dict_index_get_if_in_cache_low(
page_info->index_id);
/* Copy the index/table name under mutex. We
do not want to hold the InnoDB mutex while
filling the IS table */
if (index) {
const char* name_ptr = index->name;
if (name_ptr[0] == TEMP_INDEX_PREFIX) {
name_ptr++;
}
index_name = mem_heap_strdup(heap, name_ptr);
table_name = mem_heap_strdup(heap,
index->table_name);
}
mutex_exit(&dict_sys->mutex);
}
OK(field_store_string(
fields[IDX_BUFFER_PAGE_TABLE_NAME], table_name));
OK(field_store_string(
fields[IDX_BUFFER_PAGE_INDEX_NAME], index_name));
OK(fields[IDX_BUFFER_PAGE_NUM_RECS]->store(
page_info->num_recs));
OK(fields[IDX_BUFFER_PAGE_DATA_SIZE]->store(
page_info->data_size));
OK(fields[IDX_BUFFER_PAGE_ZIP_SIZE]->store(
page_info->zip_ssize
? (PAGE_ZIP_MIN_SIZE >> 1) << page_info->zip_ssize
: 0));
#if BUF_PAGE_STATE_BITS > 3
# error "BUF_PAGE_STATE_BITS > 3, please ensure that all 1<<BUF_PAGE_STATE_BITS values are checked for"
#endif
state = static_cast<enum buf_page_state>(page_info->page_state);
switch (state) {
/* First three states are for compression pages and
are not states we would get as we scan pages through
buffer blocks */
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
state_str = NULL;
break;
case BUF_BLOCK_NOT_USED:
state_str = "NOT_USED";
break;
case BUF_BLOCK_READY_FOR_USE:
state_str = "READY_FOR_USE";
break;
case BUF_BLOCK_FILE_PAGE:
state_str = "FILE_PAGE";
break;
case BUF_BLOCK_MEMORY:
state_str = "MEMORY";
break;
case BUF_BLOCK_REMOVE_HASH:
state_str = "REMOVE_HASH";
break;
};
OK(field_store_string(fields[IDX_BUFFER_PAGE_STATE],
state_str));
switch (page_info->io_fix) {
case BUF_IO_NONE:
OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
"IO_NONE"));
break;
case BUF_IO_READ:
OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
"IO_READ"));
break;
case BUF_IO_WRITE:
OK(field_store_string(fields[IDX_BUFFER_PAGE_IO_FIX],
"IO_WRITE"));
break;
}
OK(field_store_string(fields[IDX_BUFFER_PAGE_IS_OLD],
(page_info->is_old) ? "YES" : "NO"));
OK(fields[IDX_BUFFER_PAGE_FREE_CLOCK]->store(
page_info->freed_page_clock));
if (schema_table_store_record(thd, table)) {
DBUG_RETURN(1);
}
}
DBUG_RETURN(0);
}
/*******************************************************************//**
Set appropriate page type to a buf_page_info_t structure */
static
void
i_s_innodb_set_page_type(
/*=====================*/
buf_page_info_t*page_info, /*!< in/out: structure to fill with
scanned info */
ulint page_type, /*!< in: page type */
const byte* frame) /*!< in: buffer frame */
{
if (page_type == FIL_PAGE_INDEX) {
const page_t* page = (const page_t*) frame;
/* FIL_PAGE_INDEX is a bit special, its value
is defined as 17855, so we cannot use FIL_PAGE_INDEX
to index into i_s_page_type[] array, its array index
in the i_s_page_type[] array is I_S_PAGE_TYPE_INDEX
(1) */
page_info->page_type = I_S_PAGE_TYPE_INDEX;
page_info->index_id = btr_page_get_index_id(page);
page_info->data_size = (ulint)(page_header_get_field(
page, PAGE_HEAP_TOP) - (page_is_comp(page)
? PAGE_NEW_SUPREMUM_END
: PAGE_OLD_SUPREMUM_END)
- page_header_get_field(page, PAGE_GARBAGE));
page_info->num_recs = page_get_n_recs(page);
} else if (page_type >= I_S_PAGE_TYPE_UNKNOWN) {
/* Encountered an unknown page type */
page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
} else {
/* Make sure we get the right index into the
i_s_page_type[] array */
ut_a(page_type == i_s_page_type[page_type].type_value);
page_info->page_type = page_type;
}
if (page_info->page_type == FIL_PAGE_TYPE_ZBLOB
|| page_info->page_type == FIL_PAGE_TYPE_ZBLOB2) {
page_info->page_num = mach_read_from_4(
frame + FIL_PAGE_OFFSET);
page_info->space_id = mach_read_from_4(
frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
}
}
/*******************************************************************//**
Scans pages in the buffer cache, and collect their general information
into the buf_page_info_t array which is zero-filled. So any fields
that are not initialized in the function will default to 0 */
static
void
i_s_innodb_buffer_page_get_info(
/*============================*/
const buf_page_t*bpage, /*!< in: buffer pool page to scan */
ulint pos, /*!< in: buffer block position in
buffer pool or in the LRU list */
buf_page_info_t*page_info) /*!< in: zero filled info structure;
out: structure filled with scanned
info */
{
page_info->block_id = pos;
page_info->page_state = buf_page_get_state(bpage);
/* Only fetch information for buffers that map to a tablespace,
that is, buffer page with state BUF_BLOCK_ZIP_PAGE,
BUF_BLOCK_ZIP_DIRTY or BUF_BLOCK_FILE_PAGE */
if (buf_page_in_file(bpage)) {
const byte* frame;
ulint page_type;
page_info->space_id = buf_page_get_space(bpage);
page_info->page_num = buf_page_get_page_no(bpage);
page_info->flush_type = bpage->flush_type;
page_info->fix_count = bpage->buf_fix_count;
page_info->newest_mod = bpage->newest_modification;
page_info->oldest_mod = bpage->oldest_modification;
page_info->access_time = bpage->access_time;
page_info->zip_ssize = bpage->zip.ssize;
page_info->io_fix = bpage->io_fix;
page_info->is_old = bpage->old;
page_info->freed_page_clock = bpage->freed_page_clock;
if (page_info->page_state == BUF_BLOCK_FILE_PAGE) {
const buf_block_t*block;
block = reinterpret_cast<const buf_block_t*>(bpage);
frame = block->frame;
page_info->hashed = (block->index != NULL);
} else {
ut_ad(page_info->zip_ssize);
frame = bpage->zip.data;
}
page_type = fil_page_get_type(frame);
i_s_innodb_set_page_type(page_info, page_type, frame);
} else {
page_info->page_type = I_S_PAGE_TYPE_UNKNOWN;
}
}
/*******************************************************************//**
This is the function that goes through each block of the buffer pool
and fetch information to information schema tables: INNODB_BUFFER_PAGE.
@return 0 on success, 1 on failure */
static
int
i_s_innodb_fill_buffer_pool(
/*========================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables) /*!< in/out: tables to fill */
{
int status = 0;
mem_heap_t* heap;
DBUG_ENTER("i_s_innodb_fill_buffer_pool");
heap = mem_heap_create(10000);
/* Go through each chunk of buffer pool. Currently, we only
have one single chunk for each buffer pool */
for (ulint n = 0; n < buf_pool->n_chunks; n++) {
const buf_block_t* block;
ulint n_blocks;
buf_page_info_t* info_buffer;
ulint num_page;
ulint mem_size;
ulint chunk_size;
ulint num_to_process = 0;
ulint block_id = 0;
/* Get buffer block of the nth chunk */
block = buf_get_nth_chunk_block(buf_pool, n, &chunk_size);
num_page = 0;
while (chunk_size > 0) {
/* we cache maximum MAX_BUF_INFO_CACHED number of
buffer page info */
num_to_process = ut_min(chunk_size,
MAX_BUF_INFO_CACHED);
mem_size = num_to_process * sizeof(buf_page_info_t);
/* For each chunk, we'll pre-allocate information
structures to cache the page information read from
the buffer pool. Doing so before obtain any mutex */
info_buffer = (buf_page_info_t*) mem_heap_zalloc(
heap, mem_size);
/* Obtain appropriate mutexes. Since this is diagnostic
buffer pool info printout, we are not required to
preserve the overall consistency, so we can
release mutex periodically */
buf_pool_mutex_enter();
/* GO through each block in the chunk */
for (n_blocks = num_to_process; n_blocks--; block++) {
i_s_innodb_buffer_page_get_info(
&block->page, block_id,
info_buffer + num_page);
block_id++;
num_page++;
}
buf_pool_mutex_exit();
/* Fill in information schema table with information
just collected from the buffer chunk scan */
status = i_s_innodb_buffer_page_fill(
thd, tables, info_buffer,
num_page, heap);
/* If something goes wrong, break and return */
if (status) {
break;
}
mem_heap_empty(heap);
chunk_size -= num_to_process;
num_page = 0;
}
}
mem_heap_free(heap);
DBUG_RETURN(status);
}
/*******************************************************************//**
Fill page information for pages in InnoDB buffer pool to the
dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_page_fill_table(
/*==============================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
Item* ) /*!< in: condition (ignored) */
{
int status = 0;
DBUG_ENTER("i_s_innodb_buffer_page_fill_table");
/* deny access to user without PROCESS privilege */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
/* Fetch information from pages in this buffer pool,
and fill the corresponding I_S table */
status = i_s_innodb_fill_buffer_pool(thd, tables);
DBUG_RETURN(status);
}
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE.
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_page_init(
/*========================*/
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
DBUG_ENTER("i_s_innodb_buffer_page_init");
schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
schema->fields_info = i_s_innodb_buffer_page_fields_info;
schema->fill_table = i_s_innodb_buffer_page_fill_table;
DBUG_RETURN(0);
}
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
/* int */
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
/* pointer to type-specific plugin descriptor */
/* void* */
STRUCT_FLD(info, &i_s_info),
/* plugin name */
/* const char* */
STRUCT_FLD(name, "INNODB_BUFFER_PAGE"),
/* plugin author (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(author, plugin_author),
/* general descriptive text (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(descr, "InnoDB Buffer Page Information"),
/* the plugin license (PLUGIN_LICENSE_XXX) */
/* int */
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
/* the function to invoke when plugin is loaded */
/* int (*)(void*); */
STRUCT_FLD(init, i_s_innodb_buffer_page_init),
/* the function to invoke when plugin is unloaded */
/* int (*)(void*); */
STRUCT_FLD(deinit, i_s_common_deinit),
/* plugin version (for SHOW PLUGINS) */
/* unsigned int */
STRUCT_FLD(version, INNODB_VERSION_SHORT),
/* struct st_mysql_show_var* */
STRUCT_FLD(status_vars, NULL),
/* struct st_mysql_sys_var** */
STRUCT_FLD(system_vars, NULL),
/* reserved for dependency checking */
/* void* */
STRUCT_FLD(__reserved1, NULL),
};
static ST_FIELD_INFO i_s_innodb_buf_page_lru_fields_info[] =
{
#define IDX_BUF_LRU_POS 0
{STRUCT_FLD(field_name, "LRU_POSITION"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_SPACE 1
{STRUCT_FLD(field_name, "SPACE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_NUM 2
{STRUCT_FLD(field_name, "PAGE_NUMBER"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_TYPE 3
{STRUCT_FLD(field_name, "PAGE_TYPE"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_FLUSH_TYPE 4
{STRUCT_FLD(field_name, "FLUSH_TYPE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_FIX_COUNT 5
{STRUCT_FLD(field_name, "FIX_COUNT"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_HASHED 6
{STRUCT_FLD(field_name, "IS_HASHED"),
STRUCT_FLD(field_length, 3),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_NEWEST_MOD 7
{STRUCT_FLD(field_name, "NEWEST_MODIFICATION"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_OLDEST_MOD 8
{STRUCT_FLD(field_name, "OLDEST_MODIFICATION"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_ACCESS_TIME 9
{STRUCT_FLD(field_name, "ACCESS_TIME"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_TABLE_NAME 10
{STRUCT_FLD(field_name, "TABLE_NAME"),
STRUCT_FLD(field_length, 1024),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_INDEX_NAME 11
{STRUCT_FLD(field_name, "INDEX_NAME"),
STRUCT_FLD(field_length, 1024),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_NUM_RECS 12
{STRUCT_FLD(field_name, "NUMBER_RECORDS"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_DATA_SIZE 13
{STRUCT_FLD(field_name, "DATA_SIZE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_ZIP_SIZE 14
{STRUCT_FLD(field_name, "COMPRESSED_SIZE"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_STATE 15
{STRUCT_FLD(field_name, "COMPRESSED"),
STRUCT_FLD(field_length, 3),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_IO_FIX 16
{STRUCT_FLD(field_name, "IO_FIX"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_IS_OLD 17
{STRUCT_FLD(field_name, "IS_OLD"),
STRUCT_FLD(field_length, 3),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
#define IDX_BUF_LRU_PAGE_FREE_CLOCK 18
{STRUCT_FLD(field_name, "FREE_PAGE_CLOCK"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};
/*******************************************************************//**
Fill Information Schema table INNODB_BUFFER_PAGE_LRU with information
cached in the buf_page_info_t array
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buf_page_lru_fill(
/*=========================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
const buf_page_info_t* info_array, /*!< in: array cached page
info */
ulint num_page) /*!< in: number of page info
cached */
{
TABLE* table;
Field** fields;
mem_heap_t* heap;
DBUG_ENTER("i_s_innodb_buf_page_lru_fill");
table = tables->table;
fields = table->field;
heap = mem_heap_create(1000);
/* Iterate through the cached array and fill the I_S table rows */
for (ulint i = 0; i < num_page; i++) {
const buf_page_info_t* page_info;
const char* table_name;
const char* index_name;
const char* state_str;
enum buf_page_state state;
table_name = NULL;
index_name = NULL;
state_str = NULL;
page_info = info_array + i;
OK(fields[IDX_BUF_LRU_POS]->store(page_info->block_id));
OK(fields[IDX_BUF_LRU_PAGE_SPACE]->store(page_info->space_id));
OK(fields[IDX_BUF_LRU_PAGE_NUM]->store(page_info->page_num));
OK(field_store_string(
fields[IDX_BUF_LRU_PAGE_TYPE],
i_s_page_type[page_info->page_type].type_str));
OK(fields[IDX_BUF_LRU_PAGE_FLUSH_TYPE]->store(
page_info->flush_type));
OK(fields[IDX_BUF_LRU_PAGE_FIX_COUNT]->store(
page_info->fix_count));
if (page_info->hashed) {
OK(field_store_string(
fields[IDX_BUF_LRU_PAGE_HASHED], "YES"));
} else {
OK(field_store_string(
fields[IDX_BUF_LRU_PAGE_HASHED], "NO"));
}
OK(fields[IDX_BUF_LRU_PAGE_NEWEST_MOD]->store(
page_info->newest_mod, true));
OK(fields[IDX_BUF_LRU_PAGE_OLDEST_MOD]->store(
page_info->oldest_mod, true));
OK(fields[IDX_BUF_LRU_PAGE_ACCESS_TIME]->store(
page_info->access_time));
/* If this is an index page, fetch the index name
and table name */
if (page_info->page_type == I_S_PAGE_TYPE_INDEX) {
const dict_index_t* index;
mutex_enter(&dict_sys->mutex);
index = dict_index_get_if_in_cache_low(
page_info->index_id);
/* Copy the index/table name under mutex. We
do not want to hold the InnoDB mutex while
filling the IS table */
if (index) {
const char* name_ptr = index->name;
if (name_ptr[0] == TEMP_INDEX_PREFIX) {
name_ptr++;
}
index_name = mem_heap_strdup(heap, name_ptr);
table_name = mem_heap_strdup(heap,
index->table_name);
}
mutex_exit(&dict_sys->mutex);
}
OK(field_store_string(
fields[IDX_BUF_LRU_PAGE_TABLE_NAME], table_name));
OK(field_store_string(
fields[IDX_BUF_LRU_PAGE_INDEX_NAME], index_name));
OK(fields[IDX_BUF_LRU_PAGE_NUM_RECS]->store(
page_info->num_recs));
OK(fields[IDX_BUF_LRU_PAGE_DATA_SIZE]->store(
page_info->data_size));
OK(fields[IDX_BUF_LRU_PAGE_ZIP_SIZE]->store(
page_info->zip_ssize ?
512 << page_info->zip_ssize : 0));
state = static_cast<enum buf_page_state>(page_info->page_state);
switch (state) {
/* Compressed page */
case BUF_BLOCK_ZIP_PAGE:
case BUF_BLOCK_ZIP_DIRTY:
state_str = "YES";
break;
/* Uncompressed page */
case BUF_BLOCK_FILE_PAGE:
state_str = "NO";
break;
/* We should not see following states */
case BUF_BLOCK_ZIP_FREE:
case BUF_BLOCK_READY_FOR_USE:
case BUF_BLOCK_NOT_USED:
case BUF_BLOCK_MEMORY:
case BUF_BLOCK_REMOVE_HASH:
state_str = NULL;
break;
};
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_STATE],
state_str));
switch (page_info->io_fix) {
case BUF_IO_NONE:
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
"IO_NONE"));
break;
case BUF_IO_READ:
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
"IO_READ"));
break;
case BUF_IO_WRITE:
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IO_FIX],
"IO_WRITE"));
break;
}
OK(field_store_string(fields[IDX_BUF_LRU_PAGE_IS_OLD],
(page_info->is_old) ? "YES" : "NO"));
OK(fields[IDX_BUF_LRU_PAGE_FREE_CLOCK]->store(
page_info->freed_page_clock));
if (schema_table_store_record(thd, table)) {
mem_heap_free(heap);
DBUG_RETURN(1);
}
mem_heap_empty(heap);
}
mem_heap_free(heap);
DBUG_RETURN(0);
}
/*******************************************************************//**
This is the function that goes through buffer pool's LRU list
and fetch information to INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
@return 0 on success, 1 on failure */
static
int
i_s_innodb_fill_buffer_lru(
/*=======================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables) /*!< in/out: tables to fill */
{
int status = 0;
buf_page_info_t* info_buffer;
ulint lru_pos = 0;
const buf_page_t* bpage;
ulint lru_len;
DBUG_ENTER("i_s_innodb_fill_buffer_lru");
/* Obtain buf_pool mutex before allocate info_buffer, since
UT_LIST_GET_LEN(buf_pool->LRU) could change */
buf_pool_mutex_enter();
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
/* Print error message if malloc fail */
info_buffer = (buf_page_info_t*) my_malloc(
lru_len * sizeof *info_buffer, MYF(MY_WME));
if (!info_buffer) {
status = 1;
goto exit;
}
memset(info_buffer, 0, lru_len * sizeof *info_buffer);
/* Walk through Pool's LRU list and print the buffer page
information */
bpage = UT_LIST_GET_LAST(buf_pool->LRU);
while (bpage != NULL) {
/* Use the same function that collect buffer info for
INNODB_BUFFER_PAGE to get buffer page info */
i_s_innodb_buffer_page_get_info(bpage, lru_pos,
(info_buffer + lru_pos));
bpage = UT_LIST_GET_PREV(LRU, bpage);
lru_pos++;
}
ut_ad(lru_pos == lru_len);
ut_ad(lru_pos == UT_LIST_GET_LEN(buf_pool->LRU));
exit:
buf_pool_mutex_exit();
if (info_buffer) {
status = i_s_innodb_buf_page_lru_fill(
thd, tables, info_buffer, lru_len);
my_free(info_buffer, MYF(MY_ALLOW_ZERO_PTR));
}
DBUG_RETURN(status);
}
/*******************************************************************//**
Fill page information for pages in InnoDB buffer pool to the
dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buf_page_lru_fill_table(
/*===============================*/
THD* thd, /*!< in: thread */
TABLE_LIST* tables, /*!< in/out: tables to fill */
Item* ) /*!< in: condition (ignored) */
{
int status = 0;
DBUG_ENTER("i_s_innodb_buf_page_lru_fill_table");
/* deny access to any users that do not hold PROCESS_ACL */
if (check_global_access(thd, PROCESS_ACL)) {
DBUG_RETURN(0);
}
/* Fetch information from pages in this buffer pool's LRU list,
and fill the corresponding I_S table */
status = i_s_innodb_fill_buffer_lru(thd, tables);
DBUG_RETURN(status);
}
/*******************************************************************//**
Bind the dynamic table INFORMATION_SCHEMA.INNODB_BUFFER_PAGE_LRU.
@return 0 on success, 1 on failure */
static
int
i_s_innodb_buffer_page_lru_init(
/*============================*/
void* p) /*!< in/out: table schema object */
{
ST_SCHEMA_TABLE* schema;
DBUG_ENTER("i_s_innodb_buffer_page_lru_init");
schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);
schema->fields_info = i_s_innodb_buf_page_lru_fields_info;
schema->fill_table = i_s_innodb_buf_page_lru_fill_table;
DBUG_RETURN(0);
}
UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_page_lru =
{
/* the plugin type (a MYSQL_XXX_PLUGIN value) */
/* int */
STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
/* pointer to type-specific plugin descriptor */
/* void* */
STRUCT_FLD(info, &i_s_info),
/* plugin name */
/* const char* */
STRUCT_FLD(name, "INNODB_BUFFER_PAGE_LRU"),
/* plugin author (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(author, plugin_author),
/* general descriptive text (for SHOW PLUGINS) */
/* const char* */
STRUCT_FLD(descr, "InnoDB Buffer Page in LRU"),
/* the plugin license (PLUGIN_LICENSE_XXX) */
/* int */
STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
/* the function to invoke when plugin is loaded */
/* int (*)(void*); */
STRUCT_FLD(init, i_s_innodb_buffer_page_lru_init),
/* the function to invoke when plugin is unloaded */
/* int (*)(void*); */
STRUCT_FLD(deinit, i_s_common_deinit),
/* plugin version (for SHOW PLUGINS) */
/* unsigned int */
STRUCT_FLD(version, INNODB_VERSION_SHORT),
/* struct st_mysql_show_var* */
STRUCT_FLD(status_vars, NULL),
/* struct st_mysql_sys_var** */
STRUCT_FLD(system_vars, NULL),
/* reserved for dependency checking */
/* void* */
STRUCT_FLD(__reserved1, NULL),
};
......@@ -33,5 +33,8 @@ extern struct st_mysql_plugin i_s_innodb_cmp;
extern struct st_mysql_plugin i_s_innodb_cmp_reset;
extern struct st_mysql_plugin i_s_innodb_cmpmem;
extern struct st_mysql_plugin i_s_innodb_cmpmem_reset;
extern struct st_mysql_plugin i_s_innodb_buffer_page;
extern struct st_mysql_plugin i_s_innodb_buffer_page_lru;
extern struct st_mysql_plugin i_s_innodb_buffer_stats;
#endif /* i_s_h */
......@@ -103,6 +103,81 @@ enum buf_page_state {
before putting to the free list */
};
/** This structure defines information we will fetch from each buffer pool. It
will be used to print table IO stats */
struct buf_pool_info_struct{
/* General buffer pool info */
ulint pool_size; /*!< Buffer Pool size in pages */
ulint lru_len; /*!< Length of buf_pool->LRU */
ulint old_lru_len; /*!< buf_pool->LRU_old_len */
ulint free_list_len; /*!< Length of buf_pool->free list */
ulint flush_list_len; /*!< Length of buf_pool->flush_list */
ulint n_pend_unzip; /*!< buf_pool->n_pend_unzip, pages
pending decompress */
ulint n_pend_reads; /*!< buf_pool->n_pend_reads, pages
pending read */
ulint n_pending_flush_lru; /*!< Pages pending flush in LRU */
ulint n_pending_flush_single_page;/*!< Pages pending to be
flushed as part of single page
flushes issued by various user
threads */
ulint n_pending_flush_list; /*!< Pages pending flush in FLUSH
LIST */
ulint n_pages_made_young; /*!< number of pages made young */
ulint n_pages_not_made_young; /*!< number of pages not made young */
ulint n_pages_read; /*!< buf_pool->n_pages_read */
ulint n_pages_created; /*!< buf_pool->n_pages_created */
ulint n_pages_written; /*!< buf_pool->n_pages_written */
ulint n_page_gets; /*!< buf_pool->n_page_gets */
ulint n_ra_pages_read_rnd; /*!< buf_pool->n_ra_pages_read_rnd,
number of pages readahead */
ulint n_ra_pages_read; /*!< buf_pool->n_ra_pages_read, number
of pages readahead */
ulint n_ra_pages_evicted; /*!< buf_pool->n_ra_pages_evicted,
number of readahead pages evicted
without access */
ulint n_page_get_delta; /*!< num of buffer pool page gets since
last printout */
/* Buffer pool access stats */
double page_made_young_rate; /*!< page made young rate in pages
per second */
double page_not_made_young_rate;/*!< page not made young rate
in pages per second */
double pages_read_rate; /*!< num of pages read per second */
double pages_created_rate; /*!< num of pages create per second */
double pages_written_rate; /*!< num of pages written per second */
ulint page_read_delta; /*!< num of pages read since last
printout */
ulint young_making_delta; /*!< num of pages made young since
last printout */
ulint not_young_making_delta; /*!< num of pages not make young since
last printout */
/* Statistics about read ahead algorithm. */
double pages_readahead_rnd_rate;/*!< random readahead rate in pages per
second */
double pages_readahead_rate; /*!< readahead rate in pages per
second */
double pages_evicted_rate; /*!< rate of readahead page evicted
without access, in pages per second */
/* Stats about LRU eviction */
ulint unzip_lru_len; /*!< length of buf_pool->unzip_LRU
list */
/* Counters for LRU policy */
ulint io_sum; /*!< buf_LRU_stat_sum.io */
ulint io_cur; /*!< buf_LRU_stat_cur.io, num of IO
for current interval */
ulint unzip_sum; /*!< buf_LRU_stat_sum.unzip */
ulint unzip_cur; /*!< buf_LRU_stat_cur.unzip, num
pages decompressed in current
interval */
};
typedef struct buf_pool_info_struct buf_pool_info_t;
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Creates the buffer pool.
......@@ -618,6 +693,16 @@ void
buf_print_io(
/*=========*/
FILE* file); /*!< in: file where to print */
/*******************************************************************//**
Collect buffer pool stats information for a buffer pool. Also
record aggregated stats if there are more than one buffer pool
in the server */
UNIV_INTERN
void
buf_stats_get_pool_info(
/*====================*/
buf_pool_info_t* pool_info); /*!< in/out: buffer pool info
to fill */
/*********************************************************************//**
Returns the ratio in percents of modified pages in the buffer pool /
database pages in the buffer pool.
......@@ -1037,12 +1122,27 @@ UNIV_INTERN
ulint
buf_get_free_list_len(void);
/*=======================*/
/*********************************************************************//**
Get the nth chunk's buffer block in the specified buffer pool.
@return the nth chunk's buffer block. */
UNIV_INLINE
buf_block_t*
buf_get_nth_chunk_block(
/*====================*/
const buf_pool_t* buf_pool, /*!< in: buffer pool instance */
ulint n, /*!< in: nth chunk in the buffer pool */
ulint* chunk_size); /*!< in: chunk size */
#endif /* !UNIV_HOTBACKUP */
/** The common buffer control block structure
for compressed and uncompressed frames */
/** Number of bits used for buffer page states. */
#define BUF_PAGE_STATE_BITS 3
struct buf_page_struct{
/** @name General fields
None of these bit-fields must be modified without holding
......@@ -1057,7 +1157,8 @@ struct buf_page_struct{
unsigned offset:32; /*!< page number; also protected
by buf_pool_mutex. */
unsigned state:3; /*!< state of the control block; also
unsigned state:BUF_PAGE_STATE_BITS;
/*!< state of the control block; also
protected by buf_pool_mutex.
State transitions from
BUF_BLOCK_READY_FOR_USE to
......
......@@ -36,6 +36,16 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0lru.h"
#include "buf0rea.h"
/** A chunk of buffers. The buffer pool is allocated in chunks. */
struct buf_chunk_struct{
ulint mem_size; /*!< allocated size of the chunk */
ulint size; /*!< size of frames[] and blocks[] */
void* mem; /*!< pointer to the memory area which
was allocated for the frames */
buf_block_t* blocks; /*!< array of buffer control blocks */
};
/********************************************************************//**
Reads the freed_page_clock of a buffer block.
@return freed_page_clock */
......@@ -1106,4 +1116,23 @@ buf_block_dbg_add_level(
sync_thread_add_level(&block->lock, level, FALSE);
}
#endif /* UNIV_SYNC_DEBUG */
/*********************************************************************//**
Get the nth chunk's buffer block in the specified buffer pool.
@return the nth chunk's buffer block. */
UNIV_INLINE
buf_block_t*
buf_get_nth_chunk_block(
/*====================*/
const buf_pool_t* buf_pool, /*!< in: buffer pool instance */
ulint n, /*!< in: nth chunk in the buffer pool */
ulint* chunk_size) /*!< in: chunk size */
{
const buf_chunk_t* chunk;
chunk = buf_pool->chunks + n;
*chunk_size = chunk->size;
return(chunk->blocks);
}
#endif /* !UNIV_HOTBACKUP */
......@@ -141,6 +141,8 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_ZBLOB2
/*!< Last page type */
/* @} */
/** Space types @{ */
......
......@@ -41,6 +41,9 @@ Created 12/9/1995 Heikki Tuuri
#include "sync0rw.h"
#endif /* !UNIV_HOTBACKUP */
/* Type used for all log sequence number storage and arithmetics */
typedef ib_uint64_t lsn_t;
/** Redo log buffer */
typedef struct log_struct log_t;
/** Redo log group */
......
......@@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_buffer_pool_stats SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_buffer_page SONAME 'ha_innodb.so';
INSTALL PLUGIN innodb_buffer_page_lru SONAME 'ha_innodb.so';
......@@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmp_reset SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_cmpmem_reset SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_buffer_pool_stats SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_buffer_page SONAME 'ha_innodb.dll';
INSTALL PLUGIN innodb_buffer_page_lru SONAME 'ha_innodb.dll';
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