List:Commits« Previous MessageNext Message »
From:Annamalai Gurusami Date:July 25 2012 8:26am
Subject:bzr push into mysql-5.1 branch (annamalai.gurusami:3776 to 3777) Bug#13113026
View as plain text  
 3777 Annamalai Gurusami	2012-07-25
      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. 

    added:
      mysql-test/suite/innodb_plugin/r/innodb_information_schema_buffer.result
      mysql-test/suite/innodb_plugin/t/innodb_information_schema_buffer.test
    modified:
      mysql-test/lib/mtr_cases.pm
      storage/innodb_plugin/buf/buf0buf.c
      storage/innodb_plugin/handler/ha_innodb.cc
      storage/innodb_plugin/handler/i_s.cc
      storage/innodb_plugin/handler/i_s.h
      storage/innodb_plugin/include/buf0buf.h
      storage/innodb_plugin/include/buf0buf.ic
      storage/innodb_plugin/include/fil0fil.h
      storage/innodb_plugin/include/log0log.h
      storage/innodb_plugin/scripts/install_innodb_plugins.sql
      storage/innodb_plugin/scripts/install_innodb_plugins_win.sql
 3776 Alexander Barkov	2012-07-24
      Fixing wrong copyright. Index.xml was modified in 2005,
      while the copyright notice still mentioned 2003.

    modified:
      sql/share/charsets/Index.xml
=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm	revid:alexander.barkov@stripped
+++ b/mysql-test/lib/mtr_cases.pm	revid:annamalai.gurusami@stripped
@@ -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') 

=== added file 'mysql-test/suite/innodb_plugin/r/innodb_information_schema_buffer.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb_information_schema_buffer.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb_information_schema_buffer.result	revid:annamalai.gurusami@stripped
@@ -0,0 +1,127 @@
+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

=== added file 'mysql-test/suite/innodb_plugin/t/innodb_information_schema_buffer.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb_information_schema_buffer.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb_information_schema_buffer.test	revid:annamalai.gurusami@stripped
@@ -0,0 +1,76 @@
+# 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;
+

=== modified file 'storage/innodb_plugin/buf/buf0buf.c'
--- a/storage/innodb_plugin/buf/buf0buf.c	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/buf/buf0buf.c	revid:annamalai.gurusami@stripped
@@ -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 */
+
+

=== modified file 'storage/innodb_plugin/handler/ha_innodb.cc'
--- a/storage/innodb_plugin/handler/ha_innodb.cc	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/handler/ha_innodb.cc	revid:annamalai.gurusami@stripped
@@ -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.

=== modified file 'storage/innodb_plugin/handler/i_s.cc'
--- a/storage/innodb_plugin/handler/i_s.cc	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/handler/i_s.cc	revid:annamalai.gurusami@stripped
@@ -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),
+};

=== modified file 'storage/innodb_plugin/handler/i_s.h'
--- a/storage/innodb_plugin/handler/i_s.h	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/handler/i_s.h	revid:annamalai.gurusami@stripped
@@ -33,5 +33,8 @@ extern struct st_mysql_plugin	i_s_innodb
 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 */

=== modified file 'storage/innodb_plugin/include/buf0buf.h'
--- a/storage/innodb_plugin/include/buf0buf.h	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/include/buf0buf.h	revid:annamalai.gurusami@stripped
@@ -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

=== modified file 'storage/innodb_plugin/include/buf0buf.ic'
--- a/storage/innodb_plugin/include/buf0buf.ic	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/include/buf0buf.ic	revid:annamalai.gurusami@stripped
@@ -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 */
+

=== modified file 'storage/innodb_plugin/include/fil0fil.h'
--- a/storage/innodb_plugin/include/fil0fil.h	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/include/fil0fil.h	revid:annamalai.gurusami@stripped
@@ -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 @{ */

=== modified file 'storage/innodb_plugin/include/log0log.h'
--- a/storage/innodb_plugin/include/log0log.h	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/include/log0log.h	revid:annamalai.gurusami@stripped
@@ -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 */

=== modified file 'storage/innodb_plugin/scripts/install_innodb_plugins.sql'
--- a/storage/innodb_plugin/scripts/install_innodb_plugins.sql	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/scripts/install_innodb_plugins.sql	revid:annamalai.gurusami@stripped
@@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_inn
 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';

=== modified file 'storage/innodb_plugin/scripts/install_innodb_plugins_win.sql'
--- a/storage/innodb_plugin/scripts/install_innodb_plugins_win.sql	revid:alexander.barkov@stripped
+++ b/storage/innodb_plugin/scripts/install_innodb_plugins_win.sql	revid:annamalai.gurusami@stripped
@@ -7,3 +7,6 @@ INSTALL PLUGIN innodb_cmp SONAME 'ha_inn
 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';

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.1 branch (annamalai.gurusami:3776 to 3777) Bug#13113026Annamalai Gurusami25 Jul