#At file:///C:/source/bzr/mysql-6.0-wl-4280/
2707 Chuck Bell 2008-10-27
WL#4280 : ST: Service Interface for Replication Services
This patch adds a service interface for use in integrating backup
and replication.
It adds abstractions for controlling connection of slaves,
detection of slaves, detection of binlog states, writing
incident events (for restore), and engaging the binlog.
modified:
sql/mysqld.cc
sql/rpl_constants.h
sql/set_var.cc
sql/share/errmsg.txt
sql/si_objects.cc
sql/si_objects.h
sql/sql_repl.cc
per-file messages:
sql/mysqld.cc
Add boolean to allow disable of slave connections.
sql/rpl_constants.h
Added incident for restore run on master.
sql/set_var.cc
Added new variable used to disable slave connections.
sql/share/errmsg.txt
Added internationalized messages for disabled slaves and restore
incident event. Messages are sent to the slave(s) at event
horizon.
sql/si_objects.cc
Main code addition for new methods in service interface for
backup and replication integration. Also added code to detect
slaves and disable slave connections.
sql/si_objects.h
Added definitions for backup and replication integration
service interface.
sql/sql_repl.cc
Added code for detecting disabled slave status.
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-09-26 16:30:56 +0000
+++ b/sql/mysqld.cc 2008-10-27 21:17:42 +0000
@@ -516,6 +516,7 @@ my_bool opt_old_style_user_limits= 0, tr
volatile bool mqh_used = 0;
my_bool opt_noacl;
my_bool sp_automatic_privileges= 1;
+my_bool disable_slaves= 0;
ulong opt_binlog_rows_event_max_size;
const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
=== modified file 'sql/rpl_constants.h'
--- a/sql/rpl_constants.h 2007-03-29 18:31:09 +0000
+++ b/sql/rpl_constants.h 2008-10-27 21:17:42 +0000
@@ -11,6 +11,9 @@ enum Incident {
/** There are possibly lost events in the replication stream */
INCIDENT_LOST_EVENTS,
+ /** Restore event: Restore has occurred on the master during replication */
+ INCIDENT_RESTORE_EVENT,
+
/** Shall be last event of the enumeration */
INCIDENT_COUNT
};
=== modified file 'sql/set_var.cc'
--- a/sql/set_var.cc 2008-09-16 08:34:30 +0000
+++ b/sql/set_var.cc 2008-10-27 21:17:42 +0000
@@ -76,7 +76,7 @@ extern ulong ndb_report_thresh_binlog_me
#endif
extern CHARSET_INFO *character_set_filesystem;
-
+extern my_bool disable_slaves;
static DYNAMIC_ARRAY fixed_show_vars;
static HASH system_variable_hash;
@@ -538,6 +538,8 @@ static sys_var_thd_ulonglong sys_tmp_tab
&SV::tmp_table_size);
static sys_var_bool_ptr sys_timed_mutexes(&vars, "timed_mutexes",
&timed_mutexes);
+static sys_var_bool_ptr sys_disable_slaves(&vars, "disable_slave_connections",
+ &disable_slaves);
static sys_var_const_str sys_version(&vars, "version", server_version);
static sys_var_const_str sys_version_comment(&vars, "version_comment",
MYSQL_COMPILATION_COMMENT);
=== modified file 'sql/share/errmsg.txt'
--- a/sql/share/errmsg.txt 2008-09-29 18:41:59 +0000
+++ b/sql/share/errmsg.txt 2008-10-27 21:17:42 +0000
@@ -6392,3 +6392,7 @@ ER_BACKUP_LOGPATHS
eng "The log names for backup_history and backup_progress must be unique."
ER_BACKUP_LOGPATH_INVALID
eng "The path specified for the %-.64s is invalid. ref: %-.64s"
+ER_MASTER_BLOCKING_SLAVES
+ eng "The master is not allowing slave connections."
+ER_RESTORE_ON_MASTER
+ eng "A restore operation was initiated on the master."
=== modified file 'sql/si_objects.cc'
--- a/sql/si_objects.cc 2008-09-11 16:28:29 +0000
+++ b/sql/si_objects.cc 2008-10-27 21:17:42 +0000
@@ -25,11 +25,15 @@
#include "sql_trigger.h"
#include "sp.h"
#include "sp_head.h" // for sp_add_to_query_tables().
+#include "rpl_mi.h"
TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list); // defined in sql_show.cc
DDL_blocker_class *DDL_blocker= NULL;
+extern HASH slave_list;
+extern my_bool disable_slaves;
+
///////////////////////////////////////////////////////////////////////////
namespace {
@@ -459,6 +463,36 @@ COND *create_db_select_condition(THD *th
///////////////////////////////////////////////////////////////////////////
/**
+ @class ProcessObj
+
+ This class provides an abstraction to a process object for reading
+ items from the process list.
+*/
+class ProcessObj : public Obj
+{
+public:
+ ProcessObj(const String *proc_name) { m_command.copy(*proc_name); };
+
+public:
+ bool materialize(uint serialization_version,
+ const String *serialization)
+ { return FALSE; }
+
+ const String* get_name()
+ { return &m_command; }
+
+ const String *get_db_name() { return NULL; }
+
+private:
+ // These attributes are to be used only for serialization.
+ String m_command;
+
+ bool drop(THD *thd) { return FALSE; }
+ bool do_serialize(THD *thd, String *serialization) { return FALSE; }
+ bool do_execute(THD *thd) { return FALSE; }
+};
+
+/**
@class DatabaseObj
This class provides an abstraction to a database object for creation and
@@ -945,6 +979,22 @@ protected:
};
///////////////////////////////////////////////////////////////////////////
+class ProcesslistIterator : public InformationSchemaIterator
+{
+public:
+ ProcesslistIterator(THD *thd,
+ TABLE *is_table,
+ handler *ha,
+ my_bitmap_map *orig_columns) :
+ InformationSchemaIterator(thd, is_table, ha, orig_columns)
+ { }
+
+protected:
+ virtual ProcessObj *create_obj(TABLE *t);
+};
+
+
+///////////////////////////////////////////////////////////////////////////
class DatabaseIterator : public InformationSchemaIterator
{
public:
@@ -1272,6 +1322,25 @@ Obj *InformationSchemaIterator::next()
///////////////////////////////////////////////////////////////////////////
//
+// Implementation: ProcesslistIterator class.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+ProcessObj* ProcesslistIterator::create_obj(TABLE *t)
+{
+ String name;
+
+ t->field[4]->val_str(&name);
+
+ DBUG_PRINT("ProcesslistIterator::next", (" Found process %s", name.ptr()));
+
+ return new ProcessObj(&name);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
// Implementation: DatabaseIterator class.
//
@@ -3877,6 +3946,196 @@ int Name_locker::release_name_locks()
unlock_table_names(m_thd);
}
DBUG_RETURN(0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Implementation: Replication methods.
+//
+
+///////////////////////////////////////////////////////////////////////////
+
+/*
+ Replication methods
+*/
+
+/**
+ Turn on or off logging for the current thread.
+
+ This method can be used to turn logging on or off in situations where it is
+ necessary to prevent some operations from being logged, e.g.
+ BACKUP DATABASE.
+
+ @param[IN] enable TRUE = turn on, FALSE = turn off
+
+ @returns 0
+*/
+int engage_binlog(bool enable)
+{
+ int ret= 0;
+ THD *thd= current_thd;
+
+ if (enable)
+ thd->options|= OPTION_BIN_LOG;
+ else
+ thd->options&= ~OPTION_BIN_LOG;
+ return ret;
+}
+
+/**
+ Check if binlog is enabled for the current thread.
+
+ This method can be used to check to see if logging is enabled and operate
+ as a gate for those areas of code that are conditional on whether logging is
+ enabled (or disabled).
+
+ @returns TRUE if logging is enabled and binlog is open
+ @returns FALSE if logging is turned off or binlog is closed
+*/
+bool is_binlog_engaged()
+{
+ THD *thd= current_thd;
+
+ return (thd->options & OPTION_BIN_LOG);
+}
+
+/**
+ Check if current server is executing as a slave.
+
+ This method can be used to detect when running as a slave. This means that
+ the server is configured to act as a slave. This can make it easier to
+ organize the code for specialized sections where running as a slave requires
+ additional work, prohibiting backup and restore operations, or error
+ conditions.
+
+ @returns TRUE if operating as a slave
+*/
+bool is_slave()
+{
+ bool running= FALSE;
+
+#ifdef HAVE_REPLICATION
+ pthread_mutex_lock(&LOCK_active_mi);
+ running= (active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT);
+ pthread_mutex_unlock(&LOCK_active_mi);
+#endif
+ return running;
+}
+
+/**
+ Check if any slaves are connected.
+
+ This method can be used to detect whether there are slaves attached to the
+ current server. This will allow the code to know if replication is active.
+
+ @returns int number of slaves currently attached
+*/
+int num_slaves_attached()
+{
+ int num_slaves= 0;
+ TABLE *is_table;
+ handler *ha;
+ my_bitmap_map *orig_columns;
+ ProcesslistIterator *pl= 0;
+ Obj *proc= 0;
+ THD *thd= current_thd;
+
+ if (InformationSchemaIterator::prepare_is_table(
+ thd, &is_table, &ha, &orig_columns, SCH_PROCESSLIST,
+ thd->lex->db_list))
+ goto err;
+
+ pl= new ProcesslistIterator(thd, is_table, ha, orig_columns);
+
+ if (pl)
+ {
+ while (proc= pl->next())
+ {
+ const String *p= proc->get_name();
+ if (my_strcasecmp(system_charset_info, p->ptr(),
+ "Binlog Dump") == 0)
+ num_slaves++;
+ }
+ }
+err:
+ return num_slaves;
+}
+
+/**
+ Disable or enable connection of new slaves to the master.
+
+ This method can be used to temporarily prevent new slaves from connecting to
+ the master. This can allow operations such as RESTORE to prevent new slaves
+ from attaching during the execution of RESTORE.
+
+ @param[IN] disable TRUE = turn off, FALSE = turn on
+
+ @returns value of disable_slaves (TRUE | FALSE)
+*/
+int disable_slave_connections(bool disable)
+{
+ // Protect with a mutex?
+ disable_slaves= disable ? 1 : 0;
+ return disable_slaves;
+}
+
+/**
+ Write an incident event in the binary log.
+
+ This method can be used to issue an incident event to inform the slave
+ that an unusual event has occurred on the master. For example an incident
+ event could represent that a restore has been issued on the master. This
+ should force the slave to stop and allow the user to analyze the effect
+ of the restore on the master and take the appropriate steps to correct
+ the slave (e.g. running the same restore on the slave.
+
+ @param[IN] thd The current thread
+ @param[IN] incident_enum The indicent being reported
+
+ @retval FALSE on success.
+ @retval TRUE on error.
+*/
+int write_incident_event(THD *thd, incident_events incident_enum)
+{
+ bool res= FALSE;
+
+#ifdef HAVE_REPLICATION
+ Incident incident;
+
+ /*
+ Generate an incident log event (gap event) to signal the slave
+ that a restore has been issued on the master.
+ */
+ switch (incident_enum){
+ case NONE:
+ incident= INCIDENT_NONE;
+ break;
+ case LOST_EVENTS:
+ incident= INCIDENT_LOST_EVENTS;
+ break;
+ case RESTORE_EVENT:
+ incident= INCIDENT_RESTORE_EVENT;
+ break;
+ default: // fail safe : should not occur
+ incident= INCIDENT_NONE;
+ break;
+ }
+ DBUG_PRINT("debug", ("Before generate_incident() for gap event."));
+ /*
+ Don't write this unless binlog is engaged.
+ */
+ if (incident && is_binlog_engaged())
+ {
+ LEX_STRING msg;
+ msg.str= (char *)ER(ER_RESTORE_ON_MASTER);
+ msg.length = strlen(ER(ER_RESTORE_ON_MASTER));
+ Incident_log_event ev(thd, incident, msg);
+ res= mysql_bin_log.write(&ev);
+ mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE);
+ }
+#endif
+ return res;
}
} // obs namespace
=== modified file 'sql/si_objects.h'
--- a/sql/si_objects.h 2008-09-11 16:28:29 +0000
+++ b/sql/si_objects.h 2008-10-27 21:17:42 +0000
@@ -697,6 +697,53 @@ private:
void free_table_list(TABLE_LIST*);
};
+///////////////////////////////////////////////////////////////////////////
+
+//
+// Replication methods.
+//
+
+/*
+ Turn on or off logging for the current thread.
+*/
+int engage_binlog(bool enable);
+
+/*
+ Check if binlog is enabled for the current thread.
+*/
+bool is_binlog_engaged();
+
+/*
+ Check if current server is executing as a slave.
+*/
+bool is_slave();
+
+/*
+ Check if any slaves are connected.
+*/
+int num_slaves_attached();
+
+/*
+ Disable or enable connection of new slaves to the master.
+*/
+int disable_slave_connections(bool disable);
+
+/**
+ Enumeration of the incidents that can occur on the master.
+*/
+enum incident_events {
+ NONE, // Indicates there was no incident
+ LOST_EVENTS, // Indicates lost events
+ RESTORE_EVENT, // Indicates a restore has executed on the master
+ COUNT // Value counts the enumerations
+};
+
+/*
+ Write incident event to signal slave an unusual event has been issued
+ on the master.
+*/
+int write_incident_event(THD *thd, incident_events incident_enum);
+
} // obs namespace
#endif // SI_OBJECTS_H_
=== modified file 'sql/sql_repl.cc'
--- a/sql/sql_repl.cc 2008-09-23 14:33:18 +0000
+++ b/sql/sql_repl.cc 2008-10-27 21:17:42 +0000
@@ -28,6 +28,7 @@ my_bool opt_sporadic_binlog_dump_fail =
#ifndef DBUG_OFF
static int binlog_dump_count = 0;
#endif
+extern my_bool disable_slaves;
/*
fake_rotate_event() builds a fake (=which does not exist physically in any
@@ -470,6 +471,17 @@ void mysql_binlog_send(THD* thd, char* l
goto err;
}
#endif
+
+ /*
+ Tell the connecting slave the master cannot accept any connections
+ if disable_slaves == TRUE.
+ */
+ if (disable_slaves)
+ {
+ errmsg= "Master does not allow slaves to connect.";
+ my_errno= ER_MASTER_BLOCKING_SLAVES;
+ goto err;
+ }
if (!mysql_bin_log.is_open())
{
| Thread |
|---|
| • bzr commit into mysql-6.0-backup branch (cbell:2707) WL#4280 | Chuck Bell | 27 Oct |