#At file:///home/andrei/MySQL/BZR/2a-23May/WL/5.5-trunk-wl3656-p_s-sss/ based on revid:sunanda.menon@stripped
3073 Andrei Elkin 2010-07-16
WL#3656 Performance Schema table for SHOW SLAVE STATUS.
The patch implements a new
table to the existing P_S collection.
The new interface allows to fetch individual items and handle them according
to their mysql types (see show create peformance_schema.SLAVE_STATUS).
Output of the old SHOW SLAVE STATUS is identical to one of
SELECT * from peformance_schema.SLAVE_STATUS.
In particular if active_mi is NULL both outputs are NULL set.
A test checks the mentioned basic properties.
CAVEAT: building fail at embedded library testing. There is a bug in PS build scheme allowing
PS linking into libmysqld that should not take place (Marc_Alff is alerted and works on the issue).
@ mysql-test/suite/rpl/r/rpl_ps_slave_status.result
new test results.
@ mysql-test/suite/rpl/t/rpl_ps_slave_status.test
basic functionalilty of performance_schema.SLAVE_STATUS as comparsion with
SHOW SLAVE STATUS to prove identical output.
@ scripts/mysql_system_tables.sql
adding static definition for the new P_S.SLAVE_STATUS table.
@ storage/perfschema/Makefile.am
adding h,cc files to build in static P_S.SLAVE_STATUS.
@ storage/perfschema/pfs_engine_table.cc
Extending PFS private global array of specific table shares with
one for the new table.
@ storage/perfschema/table_slave_status.cc
Implementation of classes for the new table.
@ storage/perfschema/table_slave_status.h
Declarations for the new table.
added:
mysql-test/suite/rpl/r/rpl_ps_slave_status.result
mysql-test/suite/rpl/t/rpl_ps_slave_status.test
storage/perfschema/table_slave_status.cc
storage/perfschema/table_slave_status.h
modified:
scripts/mysql_system_tables.sql
storage/perfschema/Makefile.am
storage/perfschema/pfs_engine_table.cc
=== added file 'mysql-test/suite/rpl/r/rpl_ps_slave_status.result'
--- a/mysql-test/suite/rpl/r/rpl_ps_slave_status.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/r/rpl_ps_slave_status.result 2010-07-16 15:05:34 +0000
@@ -0,0 +1,12 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+CREATE TABLE t1 (n INT);
+insert into t1 value (1);
+include/stop_slave.inc
+include/start_slave.inc
+DROP TABLE t1;
+End of tests
=== added file 'mysql-test/suite/rpl/t/rpl_ps_slave_status.test'
--- a/mysql-test/suite/rpl/t/rpl_ps_slave_status.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/rpl/t/rpl_ps_slave_status.test 2010-07-16 15:05:34 +0000
@@ -0,0 +1,56 @@
+#
+# Test demonstrates that output of SHOW SLAVE STATUS is identical to
+# one of select * from performance_schema.SLAVE_STATUS (wl#3656).
+# The current wl#3656 time implementation of the test leaves out a more rigorous
+# approach to compare output per each field (todo).
+#
+source include/master-slave.inc;
+
+connection master;
+CREATE TABLE t1 (n INT);
+insert into t1 value (1);
+
+##--connection slave
+sync_slave_with_master;
+
+--exec $MYSQL -e "show slave status\G" > $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--exec $MYSQL -e "select * from performance_schema.SLAVE_STATUS\G" > $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+# Comparing outputs when SLAVE is UP
+
+diff_files $MYSQLTEST_VARDIR/tmp/show_slave_status.out $MYSQLTEST_VARDIR/tmp/ps_slave_status.out;
+--remove_file $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--remove_file $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+--source include/stop_slave.inc
+--exec $MYSQL -e "show slave status\G" > $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--exec $MYSQL -e "select * from performance_schema.SLAVE_STATUS\G" > $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+# Comparing outputs when SLAVE is DOWN
+
+diff_files $MYSQLTEST_VARDIR/tmp/show_slave_status.out $MYSQLTEST_VARDIR/tmp/ps_slave_status.out;
+--remove_file $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--remove_file $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+--source include/start_slave.inc
+
+#
+# Clean-up
+#
+--connection master
+DROP TABLE t1;
+
+##--connection slave
+sync_slave_with_master;
+
+--exec $MYSQL -e "show slave status\G" > $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--exec $MYSQL -e "select * from performance_schema.SLAVE_STATUS\G" > $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+# Comparing outputs when SLAVE is UP 2nd time
+
+diff_files $MYSQLTEST_VARDIR/tmp/show_slave_status.out $MYSQLTEST_VARDIR/tmp/ps_slave_status.out;
+
+--remove_file $MYSQLTEST_VARDIR/tmp/show_slave_status.out
+--remove_file $MYSQLTEST_VARDIR/tmp/ps_slave_status.out
+
+--echo End of tests
=== modified file 'scripts/mysql_system_tables.sql'
--- a/scripts/mysql_system_tables.sql 2010-04-14 16:40:04 +0000
+++ b/scripts/mysql_system_tables.sql 2010-07-16 15:05:34 +0000
@@ -412,6 +412,60 @@ EXECUTE stmt;
DROP PREPARE stmt;
--
+-- TABLE SLAVE_STATUS
+--
+
+SET @l1="CREATE TABLE performance_schema.SLAVE_STATUS(";
+SET @l2="`Slave_IO_State` VARCHAR(1024) not null,";
+SET @l3="`Master_Host` VARCHAR(60) not null,";
+SET @l4="`Master_User` varchar(16) not null,";
+SET @l5="`Master_Port` bigint not null,";
+SET @l6="`Connect_Retry` bigint not null,";
+SET @l7="`Master_Log_File` varchar(512) not null,";
+SET @l8="`Read_Master_Log_Pos` bigint not null,";
+SET @l9="`Relay_Log_File` varchar(512) not null,";
+SET @l10="`Relay_Log_Pos` bigint not null,";
+SET @l11="`Relay_Master_Log_File` varchar(512) not null,";
+SET @l12="`Slave_IO_Running` ENUM('Yes','No','Connecting') not null,";
+SET @l13="`Slave_SQL_Running` ENUM('Yes','No') not null,";
+SET @l14="`Replicate_Do_DB` varchar(256) not null,";
+SET @l15="`Replicate_Ignore_DB` varchar(256) not null,";
+SET @l16="`Replicate_Do_Table` varchar(256) not null,";
+SET @l17="`Replicate_Ignore_Table` varchar(256) not null,";
+SET @l18="`Replicate_Wild_Do_Table` varchar(256) not null,";
+SET @l19="`Replicate_Wild_Ignore_Table` varchar(256) not null,";
+SET @l20="`Last_Errno` bigint not null,";
+SET @l21="`Last_Error` varchar(1024) not null,";
+SET @l22="`Skip_Counter` bigint not null,";
+SET @l23="`Exec_Master_Log_Pos` bigint not null,";
+SET @l24="`Relay_Log_Space` bigint not null,";
+SET @l25="`Until_Condition` ENUM('None','Master','Relay') not null,";
+SET @l26="`Until_Log_File` varchar(512) not null,";
+SET @l27="`Until_Log_Pos` bigint not null,";
+SET @l28="`Master_SSL_Allowed` ENUM('Yes','No','Ignored') not null,";
+SET @l29="`Master_SSL_CA_File` varchar(512) not null,";
+SET @l30="`Master_SSL_CA_Path` varchar(512) not null,";
+SET @l31="`Master_SSL_Cert` varchar(512) not null,";
+SET @l32="`Master_SSL_Cipher` varchar(512) not null,";
+SET @l33="`Master_SSL_Key` varchar(512) not null,";
+SET @l34="`Seconds_Behind_Master` bigint,";
+SET @l35="`Master_SSL_Verify_Server_Cert` ENUM('Yes','No') not null,";
+SET @l36="`Last_IO_Errno` bigint not null,";
+SET @l37="`Last_IO_Error` varchar(1024) not null,";
+SET @l38="`Last_SQL_Errno` bigint not null,";
+SET @l39="`Last_SQL_Error` varchar(1024) not null,";
+SET @l40="`Replicate_Ignore_Server_Ids` varchar(512) not null,";
+SET @l41="`Master_Server_Id` bigint not null";
+SET @l42=") ENGINE=PERFORMANCE_SCHEMA;";
+
+SET @cmd=concat(@l1,@l2,@l3,@l4,@l5,@l6,@l7,@l8,@l9,@l10,@l11,@l12,@l13,@l14,@l15,@l16,@l17,@l18,@l19,@l20,@l21,@l22,@l23,@l24,@l25,@l26,@l27,@l28,@l29,@l30,@l31,@l32,@l33,@l34,@l35,@l36,@l37,@l38,@l39,@l40,@l41,@l42);
+
+SET @str = IF(@have_pfs = 1, @cmd, 'SET @dummy = 0');
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+DROP PREPARE stmt;
+
+--
-- TABLE RWLOCK_INSTANCES
--
=== modified file 'storage/perfschema/Makefile.am'
--- a/storage/perfschema/Makefile.am 2010-01-12 01:47:27 +0000
+++ b/storage/perfschema/Makefile.am 2010-07-16 15:05:34 +0000
@@ -44,6 +44,7 @@ noinst_HEADERS = ha_perfschema.h pfs_eng
table_events_waits_summary.h pfs_stat.h \
table_all_instr.h \
table_file_instances.h table_file_summary.h \
+ table_slave_status.h \
table_setup_objects.h pfs_lock.h pfs_atomic.h
PSE_SOURCES = ha_perfschema.cc pfs_engine_table.cc pfs.cc pfs_server.cc \
@@ -57,6 +58,7 @@ PSE_SOURCES = ha_perfschema.cc pfs_engin
table_events_waits_summary.cc \
table_all_instr.cc \
table_file_instances.cc table_file_summary.cc \
+ table_slave_status.cc \
table_setup_objects.cc pfs_atomic.cc pfs_check.cc
EXTRA_LIBRARIES = libperfschema.a
=== modified file 'storage/perfschema/pfs_engine_table.cc'
--- a/storage/perfschema/pfs_engine_table.cc 2010-03-31 14:05:33 +0000
+++ b/storage/perfschema/pfs_engine_table.cc 2010-07-16 15:05:34 +0000
@@ -28,6 +28,7 @@
#include "table_setup_timers.h"
#include "table_performance_timers.h"
#include "table_processlist.h"
+#include "table_slave_status.h"
#include "table_events_waits_summary.h"
#include "table_sync_instances.h"
#include "table_file_instances.h"
@@ -65,9 +66,17 @@ static PFS_engine_table_share *all_share
&table_rwlock_instances::m_share,
&table_cond_instances::m_share,
&table_file_instances::m_share,
+ &table_slave_status::m_share,
NULL
};
+PFS_engine_table_share** get_free_ps_engine_share()
+{
+PFS_engine_table_share **current;
+for (current= &all_shares[0]; (*current) != NULL; current++) {};
+return current;
+}
+
/**
Check all the tables structure.
@param thd current thread
=== added file 'storage/perfschema/table_slave_status.cc'
--- a/storage/perfschema/table_slave_status.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_slave_status.cc 2010-07-16 15:05:34 +0000
@@ -0,0 +1,622 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file storage/perfschema/table_repl_slave_status.cc
+ Table SLAVE_STATUS (implementation).
+*/
+
+#include "sql_priv.h"
+#include "table_slave_status.h"
+#include "pfs_instr_class.h"
+#include "pfs_instr.h"
+#include "slave.h"
+
+extern Master_info *active_mi;
+
+THR_LOCK table_slave_status::m_table_lock;
+
+static const TABLE_FIELD_TYPE field_types[]=
+{
+ {
+ { C_STRING_WITH_LEN("Slave_IO_State") },
+ { C_STRING_WITH_LEN("varchar(1024)") },
+ { NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_Host")},
+ {C_STRING_WITH_LEN("varchar(60)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_User")},
+ {C_STRING_WITH_LEN("varchar(16)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_Port")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Connect_Retry")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_Log_File")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Read_Master_Log_Pos")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Relay_Log_File")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Relay_Log_Pos")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Relay_Master_Log_File")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Slave_IO_Running")},
+ {C_STRING_WITH_LEN("enum('Yes','No','Connecting')")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Slave_SQL_Running")},
+ {C_STRING_WITH_LEN("enum('Yes','No')")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Do_DB")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Ignore_DB")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Do_Table")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Ignore_Table")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Wild_Do_Table")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Wild_Ignore_Table")},
+ {C_STRING_WITH_LEN("varchar(256)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_Errno")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_Error")},
+ {C_STRING_WITH_LEN("varchar(1024)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Skip_Counter")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Exec_Master_Log_Pos")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Relay_Log_Space")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Until_Condition")},
+ {C_STRING_WITH_LEN("enum('None','Master','Relay')")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Until_Log_File")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Until_Log_Pos")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_Allowed")},
+ {C_STRING_WITH_LEN("enum('Yes','No','Ignored')")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_CA_File")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_CA_Path")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_Cert")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_Cipher")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_Key")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Seconds_Behind_Master")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_SSL_Verify_Server_Cert")},
+ {C_STRING_WITH_LEN("enum('Yes','No')")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_IO_Errno")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_IO_Error")},
+ {C_STRING_WITH_LEN("varchar(1024)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_SQL_Errno")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Last_SQL_Error")},
+ {C_STRING_WITH_LEN("varchar(1024)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Replicate_Ignore_Server_Ids")},
+ {C_STRING_WITH_LEN("varchar(512)")},
+ {NULL, 0}
+ },
+ {
+ {C_STRING_WITH_LEN("Master_Server_Id")},
+ {C_STRING_WITH_LEN("bigint")},
+ {NULL, 0}
+ }
+};
+
+TABLE_FIELD_DEF
+table_slave_status::m_field_def=
+{ 40, field_types };
+
+PFS_engine_table_share
+table_slave_status::m_share=
+{
+ { C_STRING_WITH_LEN("SLAVE_STATUS") },
+ &pfs_readonly_acl,
+ &table_slave_status::create,
+ NULL, /* write_row */
+ NULL, /* delete_all_rows */
+ 1, /* records is 1 while single master only */ /* TODO: set it to zero to make table inactive */
+ sizeof(PFS_simple_index), /* ref length */
+ &m_table_lock,
+ &m_field_def,
+ false /* checked */
+};
+
+PFS_engine_table* table_slave_status::create(void)
+{
+ return new table_slave_status();
+}
+
+static ST_STATUS_FIELD_INFO slave_field_info[]=
+{
+ {"Slave_IO_State", MAX_SLAVE_ERRMSG, MYSQL_TYPE_STRING, 0},
+ {"Master_Host", 60, MYSQL_TYPE_STRING, 0},
+ {"Master_User", 16, MYSQL_TYPE_STRING, 0},
+ {"Master_Port", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Connect_Retry", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Master_Log_File", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Read_Master_Log_Pos", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Relay_Log_File", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Relay_Log_Pos", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Relay_Master_Log_File", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Slave_IO_Running", sizeof(ulonglong), MYSQL_TYPE_ENUM, 0},
+ {"Slave_SQL_Running", sizeof(ulonglong), MYSQL_TYPE_ENUM, 0},
+ {"Replicate_Do_DB", 256, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Ignore_DB", 256, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Do_Table", 256, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Ignore_Table", 256, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Wild_Do_Table", 256, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Wild_Ignore_Table", 256, MYSQL_TYPE_STRING, 0},
+ {"Last_Errno", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Last_Error", MAX_SLAVE_ERRMSG, MYSQL_TYPE_STRING, 0},
+ {"Skip_Counter", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Exec_Master_Log_Pos", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Relay_Log_Space", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Until_Condition", sizeof(ulonglong), MYSQL_TYPE_ENUM, 0},
+ {"Until_Log_File", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Until_Log_Pos", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Master_SSL_Allowed", sizeof(ulonglong), MYSQL_TYPE_ENUM, 0},
+ {"Master_SSL_CA_File", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Master_SSL_CA_Path", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Master_SSL_Cert", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Master_SSL_Cipher", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Master_SSL_Key", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Seconds_Behind_Master", sizeof(ulonglong), MYSQL_TYPE_LONG, 1},
+ {"Master_SSL_Verify_Server_Cert", sizeof(ulonglong), MYSQL_TYPE_ENUM, 0},
+ {"Last_IO_Errno", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Last_IO_Error", MAX_SLAVE_ERRMSG, MYSQL_TYPE_STRING, 0},
+ {"Last_SQL_Errno", sizeof(ulonglong), MYSQL_TYPE_LONG, 0},
+ {"Last_SQL_Error", MAX_SLAVE_ERRMSG, MYSQL_TYPE_STRING, 0},
+ {"Replicate_Ignore_Server_Ids", FN_REFLEN, MYSQL_TYPE_STRING, 0},
+ {"Master_Server_Id", sizeof(ulonglong), MYSQL_TYPE_LONG, 0}
+};
+
+table_slave_status::table_slave_status()
+ : PFS_readonly_table(&m_share, &m_pos),
+ m_filled(false), m_pos(0), m_next_pos(0)
+{
+ for (int i= SLAVE_IO_STATE; i <= _LAST_FIELD_; i++)
+ {
+ if (slave_field_info[i].type == MYSQL_TYPE_STRING)
+ m_fields[i].u.s.str= (char*) my_malloc(slave_field_info[i].max_size, MYF(0));
+ if (slave_field_info[i].can_be_null)
+ m_fields[i].is_null= false;
+ }
+}
+
+table_slave_status::~table_slave_status()
+{
+ for (int i= SLAVE_IO_STATE; i <= _LAST_FIELD_; i++)
+ {
+ if (slave_field_info[i].type == MYSQL_TYPE_STRING)
+ my_free(m_fields[i].u.s.str, MYF(0));
+ }
+}
+
+void table_slave_status::reset_position(void)
+{
+ m_pos.m_index= 0;
+ m_next_pos.m_index= 0;
+}
+
+int table_slave_status::rnd_next(void)
+{
+ Master_info *mi= active_mi;
+
+ if (!m_filled)
+ {
+ if (mi->host[0])
+ fill_rows(mi);
+ else
+ return HA_ERR_END_OF_FILE;
+ }
+
+ m_pos.set_at(&m_next_pos);
+ m_next_pos.set_after(&m_pos);
+ if (m_pos.m_index == m_share.m_records)
+ return HA_ERR_END_OF_FILE;
+
+ return 0;
+}
+
+
+int table_slave_status::rnd_pos(const void *pos)
+{
+ Master_info *mi= active_mi;
+ set_position(pos);
+ DBUG_ASSERT(m_pos.m_index < m_share.m_records);
+
+ if (!m_filled)
+ fill_rows(mi);
+ return 0;
+}
+
+#define DROP_NULL(name) if (slave_field_info[name].can_be_null) \
+ m_fields[name].is_null= false;
+
+#define STR_STORE(name, val) { \
+ strncpy(m_fields[name].u.s.str, val, slave_field_info[name].max_size); \
+ m_fields[name].u.s.length= strlen(m_fields[name].u.s.str); \
+ DROP_NULL(name) \
+ }
+
+#define ENUM_STORE(name, val) { \
+ m_fields[name].u.n= val; \
+ DROP_NULL(name) \
+ }
+
+#define INT_STORE(name, val) { \
+ m_fields[name].u.n= val; \
+ DROP_NULL(name) \
+ }
+
+#define SET_NULL(name) { \
+ DBUG_ASSERT(slave_field_info[name].can_be_null); \
+ m_fields[name].is_null= true; \
+ }
+
+/**
+ Send a set of strings as one long string with ',' in between.
+*/
+
+static const char * comma_list_to_string(I_List<i_string>* str_list, String *bstr)
+{
+ uint32 len;
+ I_List_iterator<i_string> it(*str_list);
+ i_string* s;
+
+ bstr->length(0);
+ while ((s=it++))
+ {
+ bstr->append(s->ptr);
+ bstr->append(',');
+ }
+ if ((len= bstr->length()))
+ len--; // Remove last ','
+ return bstr->ptr();
+}
+
+void table_slave_status::fill_rows(Master_info *mi)
+{
+ char buf[256];
+ String tmp(buf, sizeof(buf), &my_charset_bin);
+
+ mysql_mutex_lock(&mi->run_lock);
+ STR_STORE(SLAVE_IO_STATE, mi->io_thd ? mi->io_thd->proc_info : "");
+ mysql_mutex_unlock(&mi->run_lock);
+
+ mysql_mutex_lock(&mi->data_lock);
+ mysql_mutex_lock(&mi->rli.data_lock);
+ mysql_mutex_lock(&mi->err_lock);
+ mysql_mutex_lock(&mi->rli.err_lock);
+
+ STR_STORE(MASTER_HOST, mi->host);
+ STR_STORE(MASTER_USER, mi->user);
+ INT_STORE(MASTER_PORT, (long int) mi->port);
+ INT_STORE(CONNECT_RETRY, (long int) mi->connect_retry);
+ STR_STORE(MASTER_LOG_FILE, mi->master_log_name);
+ INT_STORE(READ_MASTER_LOG_POS, mi->master_log_pos);
+ STR_STORE(RELAY_LOG_FILE,
+ mi->rli.group_relay_log_name + dirname_length(mi->rli.group_relay_log_name));
+ INT_STORE(RELAY_LOG_POS, mi->rli.group_relay_log_pos);
+ STR_STORE(RELAY_MASTER_LOG_FILE, mi->rli.group_master_log_name);
+ ENUM_STORE(SLAVE_IO_RUNNING, mi->slave_running == MYSQL_SLAVE_RUN_CONNECT ?
+ PS_SLAVE_IO_RUNNING_YES :
+ (mi->slave_running == MYSQL_SLAVE_RUN_NOT_CONNECT ?
+ PS_SLAVE_IO_RUNNING_CONNECTING :PS_SLAVE_IO_RUNNING_NO));
+ ENUM_STORE(SLAVE_SQL_RUNNING, mi->rli.slave_running ?
+ PS_SLAVE_YES : PS_SLAVE_NO);
+ buf[0]= 0;
+ STR_STORE(REPLICATE_DO_DB, comma_list_to_string(rpl_filter->get_do_db(), &tmp));
+ buf[0]= 0;
+ STR_STORE(REPLICATE_IGNORE_DB,
+ comma_list_to_string(rpl_filter->get_ignore_db(), &tmp));
+ buf[0]= 0;
+ rpl_filter->get_do_table(&tmp);
+ STR_STORE(REPLICATE_DO_TABLE, buf);
+ buf[0]= 0;
+ rpl_filter->get_ignore_table(&tmp);
+ STR_STORE(REPLICATE_IGNORE_TABLE, buf);
+ buf[0]= 0;
+ rpl_filter->get_wild_do_table(&tmp);
+ STR_STORE(REPLICATE_WILD_DO_TABLE, buf);
+ buf[0]= 0;
+ rpl_filter->get_wild_ignore_table(&tmp);
+ STR_STORE(REPLICATE_WILD_IGNORE_TABLE, buf);
+ INT_STORE(LAST_ERRNO, (long int) mi->rli.last_error().number);
+ STR_STORE(LAST_ERROR, mi->rli.last_error().message);
+ INT_STORE(SKIP_COUNTER, (long int) mi->rli.slave_skip_counter);
+ INT_STORE(EXEC_MASTER_LOG_POS, mi->rli.group_master_log_pos);
+ INT_STORE(RELAY_LOG_SPACE, mi->rli.log_space_total);
+ ENUM_STORE(UNTIL_CONDITION,
+ mi->rli.until_condition == Relay_log_info::UNTIL_NONE ?
+ PS_SLAVE_UNTIL_NONE:
+ (mi->rli.until_condition == Relay_log_info::UNTIL_MASTER_POS ?
+ PS_SLAVE_UNTIL_MASTER: PS_SLAVE_UNTIL_RELAY));
+ STR_STORE(UNTIL_LOG_FILE, mi->rli.until_log_name);
+ INT_STORE(UNTIL_LOG_POS, mi->rli.until_log_pos);
+#ifdef HAVE_OPENSSL
+ ENUM_STORE(MASTER_SSL_ALLOWED, mi->ssl ?
+ PS_MASTER_SSL_ALLOWED_YES : PS_MASTER_SSL_ALLOWED_NO);
+#else
+ ENUM_STORE(MASTER_SSL_ALLOWED, mi->ssl ?
+ PS_MASTER_SSL_ALLOWED_IGNORED : PS_MASTER_SSL_ALLOWED_NO);
+#endif
+ STR_STORE(MASTER_SSL_CA_FILE, mi->ssl_ca);
+ STR_STORE(MASTER_SSL_CA_PATH, mi->ssl_capath);
+ STR_STORE(MASTER_SSL_CERT, mi->ssl_cert);
+ STR_STORE(MASTER_SSL_CIPHER, mi->ssl_cipher);
+ STR_STORE(MASTER_SSL_KEY, mi->ssl_key);
+
+ if ((mi->slave_running == MYSQL_SLAVE_RUN_CONNECT) &&
+ mi->rli.slave_running)
+ {
+ long time_diff= ((long)(time(0) - mi->rli.last_master_timestamp)
+ - mi->clock_diff_with_master);
+ INT_STORE(SECONDS_BEHIND_MASTER,
+ (longlong)(mi->rli.last_master_timestamp ?
+ max(0, time_diff) : 0));
+ }
+ else
+ {
+ SET_NULL(SECONDS_BEHIND_MASTER);
+ }
+
+
+ ENUM_STORE(MASTER_SSL_VERIFY_SERVER_CERT, mi->ssl_verify_server_cert ?
+ PS_SLAVE_YES : PS_SLAVE_NO);
+ INT_STORE(LAST_IO_ERRNO, (long int) mi->last_error().number);
+ STR_STORE(LAST_IO_ERROR, mi->last_error().message);
+ INT_STORE(LAST_SQL_ERRNO, (long int) mi->rli.last_error().number);
+ STR_STORE(LAST_SQL_ERROR, mi->rli.last_error().message);
+ {
+ char buff[FN_REFLEN];
+ ulong i, cur_len;
+ for (i= 0, buff[0]= 0, cur_len= 0;
+ i < mi->ignore_server_ids.elements; i++)
+ {
+ ulong s_id, slen;
+ char sbuff[FN_REFLEN];
+ get_dynamic(&mi->ignore_server_ids, (uchar*) &s_id, i);
+ slen= my_sprintf(sbuff, (sbuff, (i==0? "%lu" : ", %lu"), s_id));
+ if (cur_len + slen + 4 > FN_REFLEN)
+ {
+ /*
+ break the loop whenever remained space could not fit
+ ellipses on the next cycle
+ */
+ my_sprintf(buff + cur_len, (buff + cur_len, "..."));
+ break;
+ }
+ cur_len += my_sprintf(buff + cur_len, (buff + cur_len, "%s", sbuff));
+ }
+ STR_STORE(REPLICATE_IGNORE_SERVER_IDS, buff);
+ }
+ INT_STORE(MASTER_SERVER_ID, (long int) mi->master_id);
+
+ mysql_mutex_unlock(&mi->rli.err_lock);
+ mysql_mutex_unlock(&mi->err_lock);
+ mysql_mutex_unlock(&mi->rli.data_lock);
+ mysql_mutex_unlock(&mi->data_lock);
+
+ m_filled= true;
+}
+
+
+int table_slave_status::read_row_values(TABLE *table,
+ unsigned char *,
+ Field **fields,
+ bool read_all)
+{
+ Field *f;
+
+ DBUG_ASSERT(table->s->null_bytes == 1);
+
+ for (; (f= *fields) ; fields++)
+ {
+ if (read_all || bitmap_is_set(table->read_set, f->field_index))
+ {
+ if (slave_field_info[f->field_index].can_be_null)
+ {
+ if (m_fields[f->field_index].is_null)
+ {
+ f->set_null();
+ continue;
+ }
+ else
+ f->set_notnull();
+ }
+
+ switch(f->field_index)
+ {
+ case SLAVE_IO_STATE:
+ case MASTER_HOST:
+ case MASTER_USER:
+ case MASTER_LOG_FILE:
+ case RELAY_LOG_FILE:
+ case RELAY_MASTER_LOG_FILE:
+ case REPLICATE_DO_DB:
+ case REPLICATE_IGNORE_DB:
+ case REPLICATE_DO_TABLE:
+ case REPLICATE_IGNORE_TABLE:
+ case REPLICATE_WILD_DO_TABLE:
+ case REPLICATE_WILD_IGNORE_TABLE:
+ case LAST_ERROR:
+ case UNTIL_LOG_FILE:
+ case MASTER_SSL_CA_FILE:
+ case MASTER_SSL_CA_PATH:
+ case MASTER_SSL_CERT:
+ case MASTER_SSL_CIPHER:
+ case MASTER_SSL_KEY:
+ case LAST_IO_ERROR:
+ case LAST_SQL_ERROR:
+ case REPLICATE_IGNORE_SERVER_IDS:
+
+ set_field_varchar_utf8(f,
+ m_fields[f->field_index].u.s.str,
+ m_fields[f->field_index].u.s.length);
+ break;
+
+ case MASTER_PORT:
+ case CONNECT_RETRY:
+ case READ_MASTER_LOG_POS:
+ case RELAY_LOG_POS:
+ case LAST_ERRNO:
+ case SKIP_COUNTER:
+ case EXEC_MASTER_LOG_POS:
+ case RELAY_LOG_SPACE:
+ case UNTIL_LOG_POS:
+ case SECONDS_BEHIND_MASTER:
+ case LAST_IO_ERRNO:
+ case LAST_SQL_ERRNO:
+ case MASTER_SERVER_ID:
+
+ set_field_ulonglong(f, m_fields[f->field_index].u.n);
+ break;
+
+ case SLAVE_IO_RUNNING:
+ case SLAVE_SQL_RUNNING:
+ case UNTIL_CONDITION:
+ case MASTER_SSL_ALLOWED:
+ case MASTER_SSL_VERIFY_SERVER_CERT:
+
+ set_field_enum(f, m_fields[f->field_index].u.n);
+ break;
+
+ default:
+ DBUG_ASSERT(false);
+ }
+ }
+ }
+ return 0;
+}
+
=== added file 'storage/perfschema/table_slave_status.h'
--- a/storage/perfschema/table_slave_status.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_slave_status.h 2010-07-16 15:05:34 +0000
@@ -0,0 +1,170 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef TABLE_REPL_SLAVE_STATUS_H
+#define TABLE_REPL_SLAVE_STATUS_H
+
+/**
+ @file storage/perfschema/table_repl_slave_status.h
+ Table SLAVE_STATUS (declarations).
+*/
+
+#include "pfs_column_types.h"
+#include "pfs_engine_table.h"
+#include "rpl_mi.h"
+#include "mysql_com.h"
+
+/**
+ @addtogroup Performance_schema_tables
+ @{
+*/
+
+enum enum_slave_yes_no {
+ PS_SLAVE_YES= 1,
+ PS_SLAVE_NO
+};
+
+enum enum_slave_io_running {
+ PS_SLAVE_IO_RUNNING_YES= 1,
+ PS_SLAVE_IO_RUNNING_NO,
+ PS_SLAVE_IO_RUNNING_CONNECTING
+};
+
+enum enum_until_cond {
+ PS_SLAVE_UNTIL_NONE= 1,
+ PS_SLAVE_UNTIL_MASTER,
+ PS_SLAVE_UNTIL_RELAY
+};
+
+enum enum_master_ssl_allowed {
+ PS_MASTER_SSL_ALLOWED_YES= 1,
+ PS_MASTER_SSL_ALLOWED_NO,
+ PS_MASTER_SSL_ALLOWED_IGNORED
+};
+
+
+typedef struct st_slave_status_field {
+ union {
+ LEX_STRING s;
+ ulonglong n;
+ } u;
+ bool is_null;
+} ST_STATUS_FIELD_DATA;
+
+typedef struct st_slave_status_field_info
+{
+ /**
+ the column name.
+ */
+ const char* name;
+ /**
+ the maximum size of internal representation
+ */
+ uint max_size;
+ /**
+ mysql data type
+ */
+ enum enum_field_types type;
+ bool can_be_null;
+} ST_STATUS_FIELD_INFO;
+
+
+enum enum_field_names {
+ SLAVE_IO_STATE= 0,
+ MASTER_HOST,
+ MASTER_USER,
+ MASTER_PORT,
+ CONNECT_RETRY,
+ MASTER_LOG_FILE,
+ READ_MASTER_LOG_POS,
+ RELAY_LOG_FILE,
+ RELAY_LOG_POS,
+ RELAY_MASTER_LOG_FILE,
+ SLAVE_IO_RUNNING,
+ SLAVE_SQL_RUNNING,
+ REPLICATE_DO_DB,
+ REPLICATE_IGNORE_DB,
+ REPLICATE_DO_TABLE,
+ REPLICATE_IGNORE_TABLE,
+ REPLICATE_WILD_DO_TABLE,
+ REPLICATE_WILD_IGNORE_TABLE,
+ LAST_ERRNO,
+ LAST_ERROR,
+ SKIP_COUNTER,
+ EXEC_MASTER_LOG_POS,
+ RELAY_LOG_SPACE,
+ UNTIL_CONDITION,
+ UNTIL_LOG_FILE,
+ UNTIL_LOG_POS,
+ MASTER_SSL_ALLOWED,
+ MASTER_SSL_CA_FILE,
+ MASTER_SSL_CA_PATH,
+ MASTER_SSL_CERT,
+ MASTER_SSL_CIPHER,
+ MASTER_SSL_KEY,
+ SECONDS_BEHIND_MASTER,
+ MASTER_SSL_VERIFY_SERVER_CERT,
+ LAST_IO_ERRNO,
+ LAST_IO_ERROR,
+ LAST_SQL_ERRNO,
+ LAST_SQL_ERROR,
+ REPLICATE_IGNORE_SERVER_IDS,
+ MASTER_SERVER_ID,
+ _LAST_FIELD_= MASTER_SERVER_ID
+};
+
+/** Table PERFORMANCE_SCHEMA.SLAVE_STATUS. */
+class table_slave_status : public PFS_readonly_table
+{
+public:
+ /** Table share. */
+ static PFS_engine_table_share m_share;
+ static PFS_engine_table* create();
+
+ virtual int rnd_next();
+ virtual int rnd_pos(const void *pos);
+ virtual void reset_position(void);
+
+protected:
+ virtual int read_row_values(TABLE *table,
+ unsigned char *buf,
+ Field **fields,
+ bool read_all);
+
+protected:
+ table_slave_status();
+
+public:
+ ~table_slave_status();
+
+private:
+ void fill_rows(Master_info *);
+
+ /** Table share lock. */
+ static THR_LOCK m_table_lock;
+ /** Fields definition. */
+ static TABLE_FIELD_DEF m_field_def;
+ /** Current only row is represented by array of fields */
+ ST_STATUS_FIELD_DATA m_fields[_LAST_FIELD_ + 1];
+ /** True is the table is filled up */
+ bool m_filled;
+ /** Current position. */
+ PFS_simple_index m_pos;
+ /** Next position. */
+ PFS_simple_index m_next_pos;
+};
+
+/** @} */
+#endif
Attachment: [text/bzr-bundle] bzr/aelkin@mysql.com-20100716150534-c36w8iaf7li8r207.bundle