<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Scripting MySQL</title>
	<atom:link href="http://scriptingmysql.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://scriptingmysql.wordpress.com</link>
	<description>- the world&#039;s most popular open source database.</description>
	<lastBuildDate>Fri, 24 May 2013 12:25:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='scriptingmysql.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/d853745e3dda3fc870832efb707ecb73?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Scripting MySQL</title>
		<link>http://scriptingmysql.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://scriptingmysql.wordpress.com/osd.xml" title="Scripting MySQL" />
	<atom:link rel='hub' href='http://scriptingmysql.wordpress.com/?pushpress=hub'/>
		<item>
		<title>MySQL Replication &#8211; Creating a New Master/Slave Topology with or without Virtual Machines</title>
		<link>http://scriptingmysql.wordpress.com/2013/02/21/mysql-replication-creating-a-new-masterslave-topology-with-or-without-virtual-machines/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/02/21/mysql-replication-creating-a-new-masterslave-topology-with-or-without-virtual-machines/#comments</comments>
		<pubDate>Thu, 21 Feb 2013 12:45:56 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=1089</guid>
		<description><![CDATA[In my last few posts, I wrote about &#8220;How to install MySQL replication using GTID&#8217;s&#8221; (Part One, Part Two). In this post, I will show you how to install MySQL 5.6 and set up replication between two MySQL servers the &#8220;old fashioned way&#8221; using the binary log and binary log position. I am going to [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=1089&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In my last few posts, I wrote about &#8220;How to install MySQL replication using GTID&#8217;s&#8221; (<a href="http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/" />Part One</a>, <a href="http://scriptingmysql.wordpress.com/2013/01/25/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-two/" />Part Two</a>).  In this post, I will show you how to install MySQL 5.6 and set up replication between two MySQL servers the &#8220;old fashioned way&#8221; using the <a href="http://dev.mysql.com/doc/refman/5.6/en/binary-log.html">binary log</a> and binary log position.  </p>
<p>I am going to create some virtual machines instead of using individual servers.  But, you can also use these instructions to create a MySQL replication (master/slave) setup with real servers.</p>
<p>Here is how replication works.  On the master server, when there are updates (inserts, updates, deletes, alter, etc.) to the database, MySQL will write the appropriate information to the binlog (binary log), depending upon which replication method you choose.  </p>
<p><i>From:  <a href="http://dev.mysql.com/doc/refman/5.6/en/binary-log.html" rel="nofollow">http://dev.mysql.com/doc/refman/5.6/en/binary-log.html</a></i></p>
<p>The binary log contains &#8220;events&#8221; that describe database changes such as table creation operations or changes to table data. It also contains events for statements that potentially could have made changes (for example, a <a href="http://dev.mysql.com/doc/refman/5.6/en/delete.html">DELETE</a> which matched no rows), unless row-based logging is used. The binary log also contains information about how long each statement took that updated data. The binary log has two important purposes:</p>
<p>For replication, the binary log on a master replication server provides a record of the data changes to be sent to slave servers. The master server sends the events contained in its binary log to its slaves, which execute those events to make the same data changes that were made on the master. See Section 16.2, &#8220;<a href="http://dev.mysql.com/doc/refman/5.6/en/replication-implementation.html">Replication Implementation</a>&#8220;.</p>
<p>Certain data recovery operations require use of the binary log. After a backup has been restored, the events in the binary log that were recorded after the backup was made are re-executed. These events bring databases up to date from the point of the backup. See Section 7.5, &#8220;<a href="http://dev.mysql.com/doc/refman/5.6/en/point-in-time-recovery.html">Point-in-Time (Incremental) Recovery Using the Binary Log</a>&#8220;.</p>
<p>The binary log is not used for statements such as <a href="http://dev.mysql.com/doc/refman/5.6/en/select.html">SELECT</a> or <a href="http://dev.mysql.com/doc/refman/5.6/en/show.html">SHOW</a> that do not modify data. To log all statements (for example, to identify a problem query), use the general query log. See Section 5.2.3, &#8220;<a href="http://dev.mysql.com/doc/refman/5.6/en/query-log.html">The General Query Log</a>&#8220;.</p>
<p>Running a server with binary logging enabled makes performance slightly slower. However, the benefits of the binary log in enabling you to set up replication and for restore operations generally outweigh this minor performance decrement.</p>
<p><i>From:  <a href="http://dev.mysql.com/doc/refman/5.6/en/replication-formats.html">http://dev.mysql.com/doc/refman/5.6/en/replication-formats.html</a></i></p>
<p>Replication works because events written to the binary log are read from the master and then processed on the slave. The events are recorded within the binary log in different formats according to the type of event. The different replication formats used correspond to the binary logging format used when the events were recorded in the master&#8217;s binary log. The correlation between binary logging formats and the terms used during replication are:</p>
<ul>
<li>Replication capabilities in MySQL originally were based on propagation of SQL statements from master to slave. This is called statement-based replication (often abbreviated as SBR), which corresponds to the standard statement-based binary logging format. In older versions of MySQL (5.1.4 and earlier), binary logging and replication used this format exclusively.
<li>Row-based binary logging logs changes in individual table rows. When used with MySQL replication, this is known as row-based replication (often abbreviated as RBR). In row-based replication, the master writes events to the binary log that indicate how individual table rows are changed.
<li>The server can change the binary logging format in real time according to the type of event using mixed-format logging.  When the mixed format is in effect, statement-based logging is used by default, but automatically switches to row-based logging in particular cases as described later. Replication using the mixed format is often referred to as mixed-based replication or mixed-format replication. For more information, see Section 5.2.4.3, &#8220;Mixed Binary Logging Format&#8221;.
</ul>
<p>Once a slave has the binlog and binlog position, the slave will connect to the master and retrieve all of the binlog entries from the specified binlog file and after a specified binlog position.  The slave creates a thread (<a href="http://dev.mysql.com/doc/refman/5.6/en/slave-io-thread-states.html">IO thread</a>) that connects to the master server.  The master server then creates a <a href="http://dev.mysql.com/doc/refman/5.6/en/master-thread-states.html">binlog dump thread</a>, and sends the data to the slave&#8217;s <a href="http://dev.mysql.com/doc/refman/5.6/en/slave-io-thread-states.html">IO thread</a>.  The slave will in effect retrieve the data that was written to the specified binary log starting after a specific binlog position and then write it to the slave&#8217;s relay log (<a href="http://dev.mysql.com/doc/refman/5.6/en/slave-io-thread-states.html">see IO thread states</a>).  The slave will then take the data from the relay log and apply it to the slave&#8217;s database via <a href="http://dev.mysql.com/doc/refman/5.6/en/slave-sql-thread-states.html">the SQL thread</a>.  If this isn&#8217;t confusing enough, maybe this <strike><del>poorly drawn</del></strike> diagram will help you understand the steps in replication:</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/mysql_replication_topology_threads.png"></p>
<p>For this example, I am starting with a fresh install on one virtual machine running Mac OS X 10.8.  MySQL doesn&#8217;t have a version specific to 10.8, but I found that the version for 10.7 will work.  I am not going to cover how to <a href="http://dev.mysql.com/doc/refman/5.6/en/installing.html">install MySQL</a>, but I will show you what you need to change in order to make MySQL replication work.</p>
<p>MySQL uses a configuration file (<a href="http://dev.mysql.com/doc/refman/5.6/en/option-files.html">my.cnf or my.ini </a>for Windows) for all of the database variables that will be read by MySQL at startup.  After I install MySQL &#8211; <b>but before I start MySQL</b>, I will need to choose a copy of the my.cnf file to use, and then modify that file to match my specific use of MySQL.  For this example, I am going to just copy the my.cnf file in my MySQL home directory to /etc/my.cnf and then edit the /etc/my.cnf file.  You may use the following variables for your my.cnf options file.  There are quite a few variables in this file that you will need to change or add.  Since the version of the my.cnf file that I copied is mostly blank, here is what I have in my my.cnf file:  <i>(And yes, these are not all of the variables that you might need &#8211; these are just the basic variables for this example)</i></p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
[mysqld_safe]
socket = /tmp/mysql.sock

[client]
port=3306

[mysqld]
port = 3306
user = mysql
tmpdir = /tmp
socket = /tmp/mysql.sock
basedir = /usr/local/mysql
datadir = /usr/local/mysql/data
log_error = /usr/local/mysql/error.log
</pre>
</td>
</tr>
</table>
<p>Since <a href="http://dev.mysql.com/doc/refman/5.6/en/innodb-storage-engine.html">InnoDB</a> is the default storage engine for MySQL (as of 5.5), I want to provide some InnoDB-specific variables:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
innodb_data_home_dir = /usr/local/mysql/data
innodb_data_file_path = ibdata1:25M:autoextend
innodb_log_group_home_dir = /usr/local/mysql/data

innodb_log_files_in_group = 2
innodb_log_file_size = 25M
innodb_buffer_pool_size = 16M
</pre>
</td>
</tr>
</table>
<p>And then to enable replication, MySQL will need to write all of the select, insert, update and delete etc. statements to the binary log (binlog).  I also need to choose the binlog format.  I will use &#8220;<a href="http://dev.mysql.com/doc/refman/5.6/en/binary-log-mixed.html">mixed</a>&#8220;, which allows MySQL to determine whether or not to use row or statement-based binlog format for each separate SQL statement.  The slave will retrieve these statements from the master and then write them to the slave&#8217;s relay log before applying these statements to the slave database.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
log-bin=mysql-bin
binlog_format=mixed
</pre>
</td>
</tr>
</table>
<p>I need to give each server a unique ID.  I always give my master server the id of one (1), and then for the slaves, I will assign a sequential number starting at two for the <font face="courier"><b>server-id</b></font>&#8216;s.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
server-id = 1
</pre>
</td>
</tr>
</table>
<p>If you want to possibly use the slave for failover (where you promote the slave to be the master), then you will need to log the updates that are on the slave to the slave&#8217;s binary log as well.  This will allow any other slaves to use this server as a master.  Even though this is a master, if it ever becomes a slave I might want to re-promote it to master at a future date.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
log-slave-updates
</pre>
</td>
</tr>
</table>
<p>And in order to enable auto crash recovery on the slaves, enable:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
relay-log-recovery
</pre>
</td>
</tr>
</table>
<p>You may now run the installation script for the version of MySQL that you are installing.  After you install the new database, you will want to execute the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html">mysql_install_db</a> script.  You can also refer to the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/postinstallation.html">post-installation procedures </a>on the MySQL web site. <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/automatic-start.html">Start MySQL</a>, and run the script:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: # ./scripts/mysql_install_db
Installing MySQL system tables...OK

Filling help tables...OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

  ./bin/mysqladmin -u root password 'new-password'
  ./bin/mysqladmin -u root -h macserver01 password 'new-password'

Alternatively you can run:

  ./bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:

  cd . ; ./bin/mysqld_safe &amp;

You can test the MySQL daemon with mysql-test-run.pl

  cd mysql-test ; perl mysql-test-run.pl

Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at

http://www.mysql.com

Support MySQL by buying support/licenses at http://shop.mysql.com

WARNING: Found existing config file ./my.cnf on the system.
Because this file might be in use, it was not replaced,
but was used in bootstrap (unless you used --defaults-file)
and when you later start the server.
The new default config file was created as ./my-new.cnf,
please compare it with your file and take the changes you need.

WARNING: Default config file /etc/my.cnf exists on the system
This file will be read by default by the MySQL server
If you do not want to use this, either remove it, or use the
--defaults-file argument to mysqld_safe when starting the server
</pre>
</td>
</tr>
</table>
<p>If you ran this script as root, you will need to change the ownership of the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/server-logs.html">mysql-bin</a> and <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/server-logs.html">mysql-bin.index</a> files in the mysql data directory to the mysql Unix user.  </p>
<p>Now you can <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/automatic-start.html">start the MySQL server</a> (if it isn&#8217;t already started).  When you executed the <font face="courier"><b>mysql_install_db</b></font> script, it created the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/grant-table-structure.html">grant tables</a>.  You are going to want to change the root password and delete any anonymous accounts.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/default-privileges.html">Securing the Initial MySQL Accounts</a> for specific information for your operating system.  </p>
<p>An easy way to change the root password is to use <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqladmin.html">mysqladmin</a> from a command prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ ./bin/mysqladmin -u root password 'new-password'
</pre>
</td>
</tr>
</table>
<p>Right after you change the root password, you will want to test the new root password by logging in with mysql as root at a Unix prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: $ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2259
Server version: 5.6.9-rc-log MySQL Community Server (GPL)

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; 
</pre>
</td>
</tr>
</table>
<p>Running the mysqladmin program (above) only changed your root password for the localhost.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select host, user, password from user;
+-----------+------+-------------------------------------------+
| host      | user | password                                  |
+-----------+------+-------------------------------------------+
| localhost | root | *8B7D321C58724D1990BB8DE02FBD22FE19DB0D0A |
| 127.0.0.1 | root |                                           |
| ::1       | root |                                           |
| localhost |      |                                           |
+-----------+------+-------------------------------------------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Now that you have logged in, you can change your password for all of your root accounts:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; UPDATE mysql.user SET Password=PASSWORD('new-password') WHERE User='root';
Query OK, 2 rows affected (0.00 sec)
Rows matched: 3  Changed: 2  Warnings: 0

mysql&gt; flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql&gt; select host, user, password from user;
+-----------+------+-------------------------------------------+
| host      | user | password                                  |
+-----------+------+-------------------------------------------+
| localhost | root | *8B7D321C58724D1990BB8DE02FBD22FE19DB0D0A |
| 127.0.0.1 | root | *8B7D321C58724D1990BB8DE02FBD22FE19DB0D0A |
| ::1       | root | *8B7D321C58724D1990BB8DE02FBD22FE19DB0D0A |
| localhost |      |                                           |
+-----------+------+-------------------------------------------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>To find and delete the anonymous accounts, you can find a list of all of the accounts.  From a mysql prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; use mysql;
Database changed
mysql&gt; SELECT user, host FROM user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
|      | localhost |
| root | localhost |
+------+-----------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The users that are blank are anonymous users. You can double-check the blank users with this statement:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user where user = '';
+------+-----------+
| user | host      |
+------+-----------+
|      | localhost |
+------+-----------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You may now delete the blank users:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; delete from user where user = '';
Query OK, 1 row affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>These are the users that are remaining:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user;
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1       |
| root | localhost |
+------+-----------+
3 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Since we are installing MySQL for the first time on your master, you will need to create a replication user for replication.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-howto-repuser.html">Creating a User for Replication</a> for more details, but here is a sample replication user creation statement:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CREATE USER 'replicate'@'%.mydomain.com' IDENTIFIED BY 'password';
mysql&gt; GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'%.mydomain.com';

mysql&gt; select user, host from user;
+-----------+-----------+
| user      | host      |
+-----------+-----------+
| replicate | %         |
| root      | 127.0.0.1 |
| root      | ::1       |
| root      | localhost |
+-----------+-----------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You will need to make sure that your replication user matches the domain names or IP addresses, so that it has permissions to access the other server(s). </p>
<p>MySQL should now be up and running on your master server.  If you aren&#8217;t using VM&#8217;s, you may now duplicate these same installation steps on your slave server(s) &#8211; but you must change the value of <font face="courier"><b>server-id</b></font> in your <font face="courier"><b>my.cnf</b></font> file for each server &#8211; to something other than the value that you have for your master server.</p>
<p>If you are working with virtual machines, you will need to:</p>
<ul>
<li>Stop the mysqld process
<li>Stop the virtual machine (shutdown the instance)
<li>Copy/duplicate the virtual machine
<li>Change the IP address of the new virtual machine
<li>Change the server-id in the my.cnf file of the new virtual machine
<li>Change my server name for use in file sharing (if file sharing is turned on)
<li>Generate a new UUID for the new slave servers and edit the auto.cnf file. <i>(more on this below)</i>
</ul>
<p>Beginning with MySQL 5.6, the MySQL server generates a unique ID (<a href="http://dev.mysql.com/doc/refman/5.6/en/replication-options.html#sysvar_server_uuid">UUID</a>) in addition to the server-id supplied by the user. This is available as the global, read-only variable <font face="courier"><b>server_uuid</b></font>.  If you aren&#8217;t using VM&#8217;s, a new UUID will be installed when you install MySQL.  On the new VM copies, we will need to generate a new UUID and then edit the auto.cnf file.  You can run the <font face="courier"><b>select UUID();</b></font> command from the master server:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select UUID();
+--------------------------------------+
| UUID()                               |
+--------------------------------------+
| 1da4ab9c-7baf-11e2-930f-6a4c3f56f0b5 |
+--------------------------------------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Next, edit the auto.cnf file that is in the MySQL home data directory:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
# cat auto.cnf 
[auto]
server-uuid=1da4ab9c-7baf-11e2-930f-6a4c3f56f0b5
</pre>
</td>
</tr>
</table>
<p>Edit the auto.cnf file with a text editor (or use vi) and change the old UUID to the new UUID (example &#8211; change <font face="courier"><b>33e3daac-79e5-11e2-9862-ec1bc27a1e29</b></font> to <font face="courier"><b>1da4ab9c-7baf-11e2-930f-6a4c3f56f0b5</b></font>).</p>
<p>After you have installed MySQL on the new slave or copied the original VM and repeated the steps above, you can check to see if your servers have unique <font face="courier"><b>server-id</b></font>&#8216;s and <font face="courier"><b>UUID</b></font>&#8216;s.  Login to each instance of mysql:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.6.10-enterprise-commercial-advanced-log MySQL Enterprise Server - Advanced Edition (Commercial)

Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; use mysql;
Database changed
mysql&gt; show variables where variable_name = 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
1 row in set (0.00 sec)

mysql&gt; show variables where variable_name = 'server_uuid';
+---------------+--------------------------------------+
| Variable_name | Value                                |
+---------------+--------------------------------------+
| server_uuid   | 33e3daac-79e5-11e2-9862-ec1bc27a1e29 |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Now that we have our servers up and running, we need to tell our slave server(s) about the master server.  If we have already started inserting data into our master servers, we need to put a read lock on the master, show the master status to get the binlog and binlog position of the master, and then release the lock.  You may do this on one line separated by a semi-colon to reduce the amount of time that the lock is in place:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; FLUSH TABLES WITH READ LOCK;SHOW MASTER STATUS;UNLOCK TABLES;
Query OK, 0 rows affected (0.00 sec)

+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000015 |      540 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>It is important that you save the <font face="courier"><b>SHOW MASTER STATUS</b></font> information, as you will need this for each slave.  </p>
<p>Now we need to tell the slave where the master is located, which binlog file to use, and which position to start.  Issue this <font face="courier"><b>CHANGE MASTER TO</b></font> command on the slave server(s):  <i>(don&#8217;t forget to change the values to match your master server)</i></p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CHANGE MASTER TO
    -&gt;   MASTER_HOST='master IP address',
    -&gt;   MASTER_USER='replication user',
    -&gt;   MASTER_PASSWORD='replication user password',
    -&gt;   MASTER_PORT=3306,
    -&gt;   MASTER_LOG_FILE='mysql-bin.000015',
    -&gt;   MASTER_LOG_POS=540,
    -&gt;   MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected, 2 warnings (0.27 sec)
</pre>
</td>
</tr>
</table>
<p>We have two warnings from the above statement.  Let&#8217;s look at the warnings:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show warnings\G
*************************** 1. row ***************************
  Level: Note
   Code: 1759
Message: Sending passwords in plain text without SSL/TLS is extremely insecure.
*************************** 2. row ***************************
  Level: Note
   Code: 1760
Message: Storing MySQL user name or password information in the master.info repository 
is not secure and is therefore not recommended. Please see the MySQL Manual for more 
about this issue and possible alternatives.
2 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The first error &#8220;Sending passwords in plain text&#8230;&#8221; can be ignored.  Since we are setting up replication using this method, we have to send the user name and password as plain text.  The second error explains that the information in the <font face="courier"><b>CHANGE MASTER TO</b></font> statement is stored in a non-secure file named <font face="courier"><b>master.info</b></font> in your MySQL data directory:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
# pwd
/usr/local/mysql/data
# ls -l master.info
-rw-rw----  1 _mysql  wheel  99 Feb 20 15:26 master.info
# cat master.info
23
mysql-bin.000015
540
192.168.1.2
replicate
replicate999
3306
10
....
</pre>
</td>
</tr>
</table>
<p>There are options to not using the master.info file:  &#8220;MySQL 5.6 extends the replication START SLAVE command to enable DBAs to specify master user and password as part of the replication slave options and to authenticate the account used to connect to the master through an external authentication plugin (user defined or those provided under MySQL Enterprise Edition).  With these options the user and password no longer need to be exposed in plain text in the master.info file.&#8221;  (from <a href="https://blogs.oracle.com/MySQL/entry/mysql_5_6_is_a">https://blogs.oracle.com/MySQL/entry/mysql_5_6_is_a</a>)</p>
<p>For this example, we don&#8217;t need to worry about these errors.  To begin replication, we need to start the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; start slave;
Query OK, 0 rows affected (0.01 sec)
</pre>
</td>
</tr>
</table>
<p>We now can check the status of the slave to see if it is working as a slave, with the <font face="courier"><b>SHOW SLAVE STATUS\G</b></font> command:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.181
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 10
              Master_Log_File: mysql-bin.000015
          Read_Master_Log_Pos: 540
               Relay_Log_File: macos-108-repl02-relay-bin.000002
                Relay_Log_Pos: 1551
        Relay_Master_Log_File: mysql-bin.000015
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 540
              Relay_Log_Space: 1735
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 33e3daac-79e5-11e2-9862-ec1bc27a1e29
             Master_Info_File: /usr/local/mysql-advanced-5.6.10-osx10.7-x86_64/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Two values to note in the slave status shows us that our <font face="courier"><b>CHANGE MASTER TO</b></font> statement worked:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
              Master_Log_File: mysql-bin.000015
          Read_Master_Log_Pos: 540
</pre>
</td>
</tr>
</table>
<p>We can now execute a statement on the master, to see if it propagates to the slave database.  Let&#8217;s see what databases are on the master:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.01 sec)
</pre>
</td>
</tr>
</table>
<p>When we execute the same command on the slave, we get the same results.  Since we already have a test database, let&#8217;s create a table in that database.  We can check to see if there are any tables in that database already:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; use test;
Database changed
mysql&gt; show tables;
Empty set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Currently there aren&#8217;t any tables in the test database.  We can now create one on the master database:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CREATE TABLE `address` (
    -&gt;   `serial_number` int(6) NOT NULL AUTO_INCREMENT,
    -&gt;   `last_name` char(40) NOT NULL DEFAULT '',
    -&gt;   `first_name` char(40) NOT NULL DEFAULT '',
    -&gt;   `address_01` char(40) NOT NULL DEFAULT '',
    -&gt;   `city` char(30) NOT NULL DEFAULT '',
    -&gt;   `state` char(20) NOT NULL DEFAULT '',
    -&gt;   `zip` char(11) NOT NULL DEFAULT '',
    -&gt;   `phone` char(15) NOT NULL DEFAULT '',
    -&gt;   PRIMARY KEY (`serial_number`)
    -&gt; ) ENGINE=InnoDB AUTO_INCREMENT=100000 DEFAULT CHARSET=latin1;
Query OK, 0 rows affected (0.07 sec)

mysql&gt; show tables;
+----------------+
| Tables_in_test |
+----------------+
| address        |
+----------------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>And let&#8217;s take a look at the new master status;</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000015 |     1808 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
</pre>
</td>
</tr>
</table>
<p>So, if we have replication set up correctly, when we go to the slave, we should see this table on the slave as well.  Let&#8217;s execute the same same <font face="courier"><b>show table</b></font> statement on the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; use test;
Database changed
mysql&gt; show tables;
+----------------+
| Tables_in_test |
+----------------+
| address        |
+----------------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Replication is now up and running.  You may continue these steps for additional slaves that you install manually or slaves where you copy the VM.</p>
<p>I can also use the MySQL Utility script <a href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html" />mysqldbcompare</a> to see if both tables are the same.  I wrote about <a href="http://scriptingmysql.wordpress.com/2013/01/31/using-mysql-utilities-workbench-script-mysqldbcompare-to-compare-two-databases-in-replication/" />mysqldbcompare</a> in an <a href="http://scriptingmysql.wordpress.com/2013/01/31/using-mysql-utilities-workbench-script-mysqldbcompare-to-compare-two-databases-in-replication/" />earlier post</a>.  Just like this post, on the master and slave databases, I will create a user named &#8220;scripts&#8221; to execute the mysqldbcompare script:  <i>I don&#8217;t need to actually create the user on the slave, as when I execute this command on the master, it will be replicated over to the slave.</i></p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CREATE USER 'scripts'@'%' IDENTIFIED BY 'scripts999';
Query OK, 0 rows affected (0.00 sec)
mysql&gt; GRANT ALL PRIVILEGES ON *.* TO 'scripts'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>I can now run the mysqldbcompare script:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ mysqldbcompare --server1=scripts:scripts999@192.168.1.181 --server2=scripts:scripts999@192.168.1.182 test:test --run-all-tests --changes-for=server2 --difftype=sql
# server1 on 192.168.1.181: ... connected.
# server2 on 192.168.1.182: ... connected.
# Checking databases test on server1 and test on server2
#
#                                                   Defn    Row     Data   
# Type      Object Name                             Diff    Count   Check  
# ------------------------------------------------------------------------- 
# TABLE     address                                 pass    pass    pass   

Databases are consistent.
#
# ...done
</pre>
</td>
</tr>
</table>
<p>The SQL statement that I executed on the master to create the table &#8220;address&#8221; has been replicated on the slave, so replication is running and confirmed to be working.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="150" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/1089/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/1089/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=1089&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/02/21/mysql-replication-creating-a-new-masterslave-topology-with-or-without-virtual-machines/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysql_replication_topology_threads.png" medium="image" />

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>Using MySQL Utilities Workbench Script mysqldbcompare To Compare Two Databases In Replication</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/31/using-mysql-utilities-workbench-script-mysqldbcompare-to-compare-two-databases-in-replication/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/31/using-mysql-utilities-workbench-script-mysqldbcompare-to-compare-two-databases-in-replication/#comments</comments>
		<pubDate>Thu, 31 Jan 2013 12:29:48 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=850</guid>
		<description><![CDATA[In my last two posts, I wrote about setting up replication with MySQL 5.6 using Global Transaction Identifiers. Even when I set up replication &#8220;the old-fashioned way&#8220;, one thought always enters my mind &#8211; did all of the data copy over to the slave? And, even after the master/slave has been running for a while, [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=850&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In my last <a target="new" href="http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/" />two posts</a>, I wrote about setting up replication with MySQL 5.6 using Global Transaction Identifiers.  Even when I set up replication &#8220;<a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication.html">the old-fashioned way</a>&#8220;, one thought always enters my mind &#8211; did all of the data copy over to the slave?  And, even after the master/slave has been running for a while, I am always wondering if the data in the slave matches the master.  Or did the change that I made to that table make it over to the slave?  It is probably more of a case of paranoia on my part, as <a href="http://dev.mysql.com/doc/refman/5.6/en/replication.html">MySQL replication</a> is very reliable and works really well.</p>
<p><a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />A few months ago</a>, I started writing about the MySQL Utilities.  If you haven&#8217;t heard about the <a target="new" href="http://dev.mysql.com/doc/workbench/en/index.html">MySQL Utilities</a>:</p>
<p>&#8220;MySQL Utilities is a package of utilities that are used for maintenance and administration of MySQL servers. These utilities encapsulate a set of primitive commands, and bundles them so they can be used to perform macro operations with a single command. MySQL Utilities may be installed via MySQL Workbench, or as a standalone package.  The utilities are written in Python, available under the GPLv2 license, and are extendable using the supplied library. They are designed to work with Python 2.x greater than 2.6.&#8221;  <i>(from the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysql-utils-intro-intro.html">introduction</a> to MySQL Utilities page)</i></p>
<p>In order to reduce my paranoia (I will never be able to eliminate it), I can simply use the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</a> utility.  The <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</a> utility <font color="blue">&#8220;compares the objects and data from two databases to find differences. It identifies objects having different definitions in the two databases and presents them in a diff-style format of choice. Differences in the data are shown using a similar diff-style format. Changed or missing rows are shown in a standard format of GRID, CSV, TAB, or VERTICAL.&#8221;</font>  (<i>from: <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare — Compare Two Databases and Identify Differences</a></i>)</p>
<p>You don&#8217;t have to use <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldcompare</a> to compare two databases in replication.  You may compare any two databases, even if they are on the same server.  But for this post, I will be comparing two databases on two separate servers in a master/slave replication topology.</p>
<p>The utility is fairly easy to use.  You just identify the two servers and which databases you want to compare.  You will need to refer to my earlier post <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />on using the MySQL Utilities</a> for more information on how to execute the scripts.</p>
<p>I will be comparing a database that is on my master server (at 192.168.1.2) and the same database that is on one of the slaves (at 192.168.1.122) connected to that master.  Instead of using root to execute the scripts, I create and use a MySQL user named &#8220;scripts&#8221; to use when I run a script. The syntax for <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</a> is fairly easy, and you can refer to the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</a> man page for more of the commands and their usage:</p>
<p>I need to specify the servers, user name and passwords:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--server1=scripts:scripts999@192.168.1.2 
--server2=scripts:scripts999@192.168.1.122 
</pre>
</td>
</tr>
</table>
<p>The name of the databases to compare (database_server1:database_server2):</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
cbgc:cbgc 
</pre>
</td>
</tr>
</table>
<p>Do not stop the script at the first difference that is found. Process all objects.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--run-all-tests 
</pre>
</td>
</tr>
</table>
<p>Specify the server to show transformations to match the other server.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--changes-for=server2 
</pre>
</td>
</tr>
</table>
<p>Specify the difference display format. Permitted format values are unified, context, differ, and sql. The default is unified.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--difftype=sql
</pre>
</td>
</tr>
</table>
<p>Now that I have decided on which options to use, I can run the scripts from within the MySQL Workbench Utilities shell:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ mysqldbcompare --server1=scripts:scripts999@192.168.1.2 \
  --server2=scripts:scripts999@192.168.1.122 \
  cbgc:cbgc --run-all-tests --changes-for=server2 --difftype=sql
# server1 on 192.168.1.2: ... connected.
# server2 on 192.168.1.122: ... connected.
# Checking databases cbgc on server1 and cbgc on server2
#
#                                                   Defn    Row     Data   
# Type      Object Name                             Diff    Count   Check  
# ------------------------------------------------------------------------- 
# TABLE     Activity_Affiliate                      pass    pass    pass    
# TABLE     FedEx_2nd_Day                           pass    pass    pass    
# TABLE     FedEx_Express_Saver                     pass    pass    pass    
# TABLE     FedEx_Ground                            pass    pass    pass    
# TABLE     FedEx_Home                              pass    pass    pass    
# TABLE     FedEx_Priority_Overnight                pass    pass    pass    
# TABLE     FedEx_Standard_Overnight                pass    pass    pass    
# TABLE     Orders                                  pass    pass    pass    
# TABLE     USPS                                    pass    pass    pass    
# TABLE     activity                                pass    pass    pass    
# TABLE     comics                                  pass    pass    pass    
# TABLE     coupons                                 pass    pass    pass    
# TABLE     customer                                pass    pass    pass    
# TABLE     giftcert                                pass    pass    pass   

Databases are consistent.
#
# ...done
</pre>
</td>
</tr>
</table>
<p>The output shows that my databases are consistent.  I have a rather small database, and I re-executed the script again with the &#8220;<a target="new" href="http://linux.about.com/library/cmd/blcmdl1_time.htm">time</a>&#8221; command, and here are the time results:</p>
<tr>
<td bgcolor="#FFFFFF">
<pre>
real	0m4.519s
user	0m0.429s
sys	0m0.068s
</pre>
</td>
</tr>
</table>
<p>It took about 4.5 seconds to execute on my database which is about 25 megabytes in size.  Obviously, the time will increase relative to the complexity and size of your database.  And the time will increase relative to the number of differences that the script finds.</p>
<p>In order to show you what happens when the databases are not in sync, I will now stop the slave database (at 192.168.1.122), and then add a line to one of the tables in the master database (at 192.168.1.2), and re-run the script (while the slave is still stopped).</p>
<p>On the slave server:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>On the master server:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; insert into `cbgc`.`activity` ( `Customer_Serial_Number`, `Customer_Activity_Action`) \
          values ( '1201201', 'Test Visit');
Query OK, 1 row affected (0.96 sec)
</pre>
</td>
</tr>
</table>
<p>Now I can run the mysqldbcompare script again.  The slave is still turned off:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ mysqldbcompare --server1=scripts:scripts999@192.168.1.2 \
  --server2=scripts:scripts999@192.168.1.122 cbgc:cbgc \ 
  --run-all-tests --changes-for=server2 --difftype=sql
# server1 on 192.168.1.2: ... connected.
# server2 on 192.168.1.122: ... connected.
# Checking databases cbgc on server1 and cbgc on server2
#
#                                                   Defn    Row     Data   
# Type      Object Name                             Diff    Count   Check  
# ------------------------------------------------------------------------- 
# TABLE     Activity_Affiliate                      pass    pass    pass    
# TABLE     FedEx_2nd_Day                           pass    pass    pass    
# TABLE     FedEx_Express_Saver                     pass    pass    pass    
# TABLE     FedEx_Ground                            pass    pass    pass    
# TABLE     FedEx_Home                              pass    pass    pass    
# TABLE     FedEx_Priority_Overnight                pass    pass    pass    
# TABLE     FedEx_Standard_Overnight                pass    pass    pass    
# TABLE     Orders                                  pass    pass    pass    
# TABLE     USPS                                    pass    pass    pass    
# TABLE     activity                                FAIL    FAIL    FAIL    
#
# Transformation for --changes-for=server2:
#

ALTER TABLE cbgc.activity 
  DROP PRIMARY KEY, 
  ADD PRIMARY KEY(serial_id), 
AUTO_INCREMENT=7542;

# Row counts are not the same among cbgc.activity and cbgc.activity.
#
# Transformation for --changes-for=server2:
#

INSERT INTO cbgc.activity (serial_id, Customer_Serial_Number, Customer_Activity_Action, 
Customer_Activity_Date_Time, Customer_Activity_Info, Notes, HTTP_REFERER) 
VALUES('7541', '1201201', 'Test Visit', NULL, NULL, NULL, NULL);


# TABLE     comics                                  pass    pass    pass    
# TABLE     coupons                                 pass    pass    pass    
# TABLE     customer                                pass    pass    pass    
# TABLE     giftcert                                pass    pass    pass   

# Database consistency check failed.
#
# ...done
</pre>
</td>
</tr>
</table>
<p>The script alerted me to two issues.  It tells me that I have one row of data missing (from the insert statement), but it also notices that my auto-increment on the activity database needs to be updated as well.  If I simply run the insert statement, my auto-increment value will be incorrect.  So, I need to run the auto-increment change first, and then I can execute the insert statement.</p>
<p>There are other <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html#option_mysqldbcompare_difftype">choices of output</a> that you can use besides sql &#8211; unified, context and differ.  You can try each one and see which one will fit your needs.  I prefer the sql output.</p>
<p>Since I stopped the slave, I can just start it again and it will catch up with the master.  But, if you are working with an active master, you might want to put a read lock on the database, run the script again, and then make your changes.  This is especially true if the changes involve something dynamic like a primary key or auto-increment column, as those values could change while you are trying to run the statements.</p>
<p>Let&#8217;s see what happens when we someone else makes some changes and we aren&#8217;t aware of the changes.  But first, I will start the slave so it can catch up to the master (for the earlier missing statements). We will then stop the slave and let someone else make a few changes.  And then we can run the mysqldbcompare utility again:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ mysqldbcompare --server1=scripts:scripts999@192.168.1.2 \
  --server2=scripts:scripts999@192.168.1.122 cbgc:cbgc \
  --run-all-tests --changes-for=server2 --difftype=sql
# server1 on 192.168.1.2: ... connected.
# server2 on 192.168.1.122: ... connected.
# Checking databases cbgc on server1 and cbgc on server2
#
#                                                   Defn    Row     Data   
# Type      Object Name                             Diff    Count   Check  
# ------------------------------------------------------------------------- 
# TABLE     Activity_Affiliate                      pass    pass    pass    
# TABLE     FedEx_2nd_Day                           pass    pass    pass    
# TABLE     FedEx_Express_Saver                     pass    pass    pass    
# TABLE     FedEx_Ground                            pass    pass    pass    
# TABLE     FedEx_Home                              pass    pass    pass    
# TABLE     FedEx_Priority_Overnight                pass    pass    pass    
# TABLE     FedEx_Standard_Overnight                pass    pass    pass    
# TABLE     Orders                                  pass    pass    pass    
# TABLE     USPS                                    pass    pass    pass    
# TABLE     activity                                FAIL    pass    pass    
#
# Transformation for --changes-for=server2:
#

ALTER TABLE cbgc.activity 
  DROP PRIMARY KEY, 
  DROP COLUMN Dummy_Field, 
  ADD PRIMARY KEY(serial_id);


# TABLE     comics                                  pass    pass    pass    
# TABLE     coupons                                 FAIL    pass    pass    
#
# Transformation for --changes-for=server2:
#

ALTER TABLE cbgc.coupons 
  CHANGE COLUMN Coupon_Notes Coupon_Notes varchar(100) NULL;


# TABLE     customer                                pass    pass    pass    
# TABLE     giftcert                                pass    pass    pass   

Databases are consistent.
#
# ...done
</pre>
</td>
</tr>
</table>
<p>This time, the script took about 20 seconds to run:</p>
<tr>
<td bgcolor="#FFFFFF">
<pre>
real	0m20.058s
user	0m0.452s
sys	0m0.224s
</pre>
</td>
</tr>
</table>
<p>We can see from the output that a column named <font face="courier"><b>Dummy_Field</b></font> was dropped.  We can also see that the <font face="courier"><b>Coupon_Notes</b></font> column has changed (or is different on the master).  I can now take these changes and implement them on the slave (again assuming that these changes aren&#8217;t waiting to be sent to the slave).  In my case, once I start the slave, the changes will propagate over to the slave, but there may be cases where that transaction was lost or skipped on the slave (for example, if you had to do a <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/set-global-sql-slave-skip-counter.html">SET GLOBAL sql_slave_skip_counter = N</a></b></font> on the slave).  You now have the ability to easily make the slave the same as the master by executing these differences.  If the changes are too complicated, then you might want to look at re-creating your slave.</p>
<p>There are many different options and output possibilities, so I would encourage you to just try <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</a> and see how it works for you.  And as always, feel free to post your feedback in the comments section.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="150" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/850/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/850/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=850&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/31/using-mysql-utilities-workbench-script-mysqldbcompare-to-compare-two-databases-in-replication/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL Replication with Global Transaction Identifiers – Step-by-Step Install and Addition of Slaves – Part Two</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/25/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-two/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/25/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-two/#comments</comments>
		<pubDate>Fri, 25 Jan 2013 21:49:05 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Enterprise Monitor]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=1041</guid>
		<description><![CDATA[This post is part two of MySQL Replication with Global Transaction Identifiers – Step-by-Step Install and Addition of Slaves. In this post, I will be showing you how to use the MySQL Utility Script mysqlreplicate to create a new replication slave off a master database. This is also the fourth in a series that I [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=1041&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This post is part two of <a href="http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/">MySQL Replication with Global Transaction Identifiers – Step-by-Step Install and Addition of Slaves</a>.  In this post, I will be showing you how to use the <a href="http://dev.mysql.com/doc/workbench/en/mysql-utils-man-overview.html">MySQL Utility Script</b> <a href="http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html">mysqlreplicate</a> to create a new replication slave off a master database.</p>
<p>This is also the fourth in a series that I will be doing on <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />MySQL Workbench Utilities – Administer MySQL with Python Scripts.</a>  You may want to read the first half of <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />this post </a>to understand how <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />MySQL Workbench Utilities</a> work and how you access the scripts.  These scripts were written by <a target="new" href="http://drcharlesbell.blogspot.com">Chuck Bell</a> (a <a target="new" href="http://mysql.com">MySQL</a> employee) and are available as stand-alone scripts (see Chuck&#8217;s <a target="new" href="http://drcharlesbell.blogspot.com">blog</a> for more information) or as part of the <a target="new" href="http://dev.mysql.com/downloads/workbench/" />MySQL Workbench</a> utility.</p>
<p>The <a href="http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html">mysqlreplicate</a> &#8220;utility permits an administrator to start replication from one server (the master) to another (the slave). The user provides login information for the slave and connection information for connecting to the master.&#8221;  (<i>From:  <a href="http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html">http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html</a>)</i> </p>
<p>In the <a href="http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/" />first post</a>, I showed you how to create a slave off a master.  The mysqlreplicate utility takes care of the manual steps for you, and makes it easy to create a slave database.  I am not going to rewrite a lot of the details from the <a href="http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/">first post</a>, so you may refer to that post for more information.</p>
<p>The first step is to install the MySQL database on a new server that is going to be your slave server.  In this example, I am installing MySQL version 5.6.9 (Community Edition) on a Macintosh with OS 10.6.8.  This tutorials should work for any platform, with just a few tweaks for Windows users.</p>
<p>After the install, I will need to change the permissions on my mysql directory, since I installed the database as root:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
# ls -l
total 8
lrwxr-xr-x   1 root  wheel   29 Jan 25 11:50 mysql -&gt; mysql-5.6.9-rc-osx10.7-x86_64
drwxr-xr-x  18 root  wheel  612 Jan 25 11:51 mysql-5.6.9-rc-osx10.7-x86_64
# chown -R _mysql mysql*
# ls -l
total 8
lrwxr-xr-x   1 _mysql  wheel   29 Jan 25 11:50 mysql -&gt; mysql-5.6.9-rc-osx10.7-x86_64
drwxr-xr-x  18 _mysql  wheel  612 Jan 25 11:51 mysql-5.6.9-rc-osx10.7-x86_64
</pre>
</td>
</tr>
</table>
<p>Next, I will run the mysql_install_db script from my mysql home directory (/usr/local/mysql) &#8211; <font face="courier"><b>/usr/local/mysql</b></font>:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root# cd /usr/local/mysql
root# ls -l scripts
total 72
-rwxr-xr-x  1 _mysql  wheel  33018 Nov 22 10:28 mysql_install_db
root# ./scripts/mysql_install_db
Installing MySQL system tables...OK

Filling help tables...OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

  ./bin/mysqladmin -u root password 'new-password'
  ./bin/mysqladmin -u root -h VM-Mac-1081-122.local password 'new-password'

Alternatively you can run:

  ./bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:

  cd . ; ./bin/mysqld_safe &amp;

You can test the MySQL daemon with mysql-test-run.pl

  cd mysql-test ; perl mysql-test-run.pl

Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at

http://www.mysql.com

Support MySQL by buying support/licenses at http://shop.mysql.com

WARNING: Found existing config file ./my.cnf on the system.
Because this file might be in use, it was not replaced,
but was used in bootstrap (unless you used --defaults-file)
and when you later start the server.
The new default config file was created as ./my-new.cnf,
please compare it with your file and take the changes you need.

WARNING: Default config file /etc/my.cnf exists on the system
This file will be read by default by the MySQL server
If you do not want to use this, either remove it, or use the
--defaults-file argument to mysqld_safe when starting the server
</pre>
</td>
</tr>
</table>
<p>Again, since I ran this as root, I will need to change permissions on a few files in the mysql directory to the mysql user.  There are some files in the data directory that are owned by root, but I can just do a change ownership of the entire mysql directory.</p>
<p>I will now need to <a href="http://dev.mysql.com/doc/refman/5.6/en/automatic-start.html">start mysql</a>, and then change the root password.  I can change the password with the <a href="http://dev.mysql.com/doc/refman/5.6/en/mysqladmin.html">mysqladmin</a> client application:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
./bin/mysqladmin -u root password 'newpassword'
</pre>
</td>
</tr>
</table>
<p>I then check to make sure that my password change worked.  I can do this by logging into mysql and I will also list the users in the database:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root# mysql -uroot -p

mysql&gt; use mysql;
Database changed
mysql&gt; select user, host, password from users;
ERROR 1146 (42S02): Table 'mysql.users' doesn't exist
mysql&gt; select user, host, password from user;
+---------+-----------------------+-------------------------------------------+
| user    | host                  | password                                  |
+---------+-----------------------+-------------------------------------------+
| root    | localhost             | *8FF7274XXF360A5BB33835F544D6617707C23968 |
| root    | VM-Mac-1081-122.local |                                           |
| root    | 127.0.0.1             |                                           |
| root    | ::1                   |                                           |
|         | localhost             |                                           |
|         | VM-Mac-1081-122.local |                                           |
+---------+-----------------------+-------------------------------------------+
6 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You can see that mysqladmin only changed the root password for the localhost (the rest of the password fields were blank).  I can change the rest of the root passwords once I am in mysql:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; UPDATE mysql.user SET Password=PASSWORD('newpassword') WHERE User='root';
Query OK, 3 rows affected (0.00 sec)
Rows matched: 4  Changed: 3  Warnings: 0
mysql&gt; flush privileges;
Query OK, 0 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>I will also want to delete the anonymous users.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; delete from user where user = '';
Query OK, 2 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Prior to starting this server as a slave, we can see that there are only the four mysql databases:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>And since we haven&#8217;t started it as a slave, the SHOW SLAVE STATUS is empty:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
Empty set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>I prefer to run all of my scripts with a user named &#8220;scripts&#8221; versus using the root mysql user, so I will create the scripts user:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CREATE USER 'scripts'@'192.168.1.122' IDENTIFIED BY 'scripts123';
GRANT ALL PRIVILEGES ON *.* TO 'scripts'@'192.168.1.122' WITH GRANT OPTION;
</pre>
</td>
</tr>
</table>
<p>You can just use the root user if you want.  But the mysqlreplicate script does not allow for special characters in the password field, so you will want to use a password without any special characters.</p>
<p>We will need to create a replication use on the master for the slave, which is at 192.168.1.2.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CREATE USER 'replicate'@'192.168.1.122' IDENTIFIED BY 'replicate123';
GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'192.168.1.122';
</pre>
</td>
</tr>
</table>
<p>Now we are ready to run the mysqlreplicate script.  You will want to review the <a href="http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html">mysqlreplicate man page</a> for the variables and their use:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ mysqlreplicate --master=scripts:scripts123@192.168.1.2:3306 \
   --slave=scripts:scripts123@192.168.1.122:3306 \ 
   --rpl-user=replicate:replicate123 --start-from-beginning -vvv
# master on 192.168.1.2: ... connected.
# slave on 192.168.1.122: ... connected.
# master id = 1
#  slave id = 5
# Checking InnoDB statistics for type and version conflicts.
# Checking storage engines...
# Checking for binary logging on master...
# Setting up replication...
# Connecting slave to master...
# CHANGE MASTER TO MASTER_HOST = '192.168.1.2', MASTER_USER = 'replicate', MASTER_PASSWORD = 'replicate123', MASTER_PORT = 3306
# Starting slave from the beginning...
# status: Queueing master event to the relay log
# Waiting for slave to synchronize with master
# status: Queueing master event to the relay log
# Waiting for slave to synchronize with master
# status: Waiting for master to send event
# ...done.
</pre>
</td>
</tr>
</table>
<p>That&#8217;s it!  The mysqlreplicate utility has done all of the steps necessary to start the slave.  After a few minutes, we can now look at the slave status:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.2
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000007
          Read_Master_Log_Pos: 137301
               Relay_Log_File: WEB_SERVER_01-relay-bin.000012
                Relay_Log_Pos: 354
        Relay_Master_Log_File: mysql-bin.000007
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 137301
              Relay_Log_Space: 769
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 82f20158-5a16-11e2-88f9-c4a801092abb
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162868
            Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162868,
                               B7DB3608-6729-11E2-9E3C-BDE2366761B1:1-4
1 row in set (0.00 sec)

mysql&gt; 
</pre>
</td>
</tr>
</table>
<p>If your slave hasn&#8217;t caught up with the master yet, the values for Retrieved_Gtid_Set and Executed_Gtid_Set will not match.  It only took my slave a few minutes to catch up to my master, but your situation will be different.  We can now compare the status of the <font face="courier"><b>Executed_Gtid_Set</b></font> to the master, and it matches:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000007
         Position: 137301
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162868
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>If your master database was active with write transactions, then master&#8217;s Executed_Gtid_Set value may be higher and not match the slave.  But your slave is now ready for use.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="600">
<tr>
<td style="vertical-align:middle;"><img width="150" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/1041/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/1041/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=1041&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/25/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-two/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL Replication with Global Transaction Identifiers &#8211; Step-by-Step Install and Addition of Slaves &#8211; Part One</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/#comments</comments>
		<pubDate>Fri, 18 Jan 2013 22:07:24 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=972</guid>
		<description><![CDATA[One of my favorite features of MySQL is replication. Replication provides you with the ability to have MySQL automatically copy data from one MySQL instance to another. There are many benefits to using replication, but I just like having an extra copy of my data on another server in case the main server crashes. But [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=972&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>One of my favorite features of <a target="new" href="http://mysql.com">MySQL</a> is <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication.html">replication</a>.  Replication provides you with the ability to have MySQL automatically copy data from one MySQL instance to another.  There are many benefits to using replication, but I just like having an extra copy of my data on another server in case the main server crashes.  But if the master crashes, I can then use the MySQL mysqlfailover script to automatically failover from the master to the slave.<i> (see my earlier post &#8211; <a target="new" href="http://scriptingmysql.wordpress.com/2012/12/06/using-the-mysql-script-mysqlfailover-for-automatic-failover-with-mysql-5-6-gtid-replication/" />Using the MySQL Script mysqlfailover for Automatic Failover with MySQL 5.6 GTID Replication</a>)</i>.  </p>
<p>MySQL Replication automatically copies the data from the main database (master) to another database (slave).  You can have multiple slaves pulling data from a single master, and you can have slaves replicating data off other slaves.  If you are new to replication, check out the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/faqs-replication.html">MySQL Replication FAQ</a> page.</p>
<p>In this post, I will explain how to install or upgrade MySQL (by exporting and importing the data for a &#8220;fresh&#8221; upgrade), create a master and slave server, and start <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication.html">replication</a>.  If you have never installed <a target="new" href="http://mysql.com">MySQL</a> or if you have never used replication, then this blog should be able to help you do this without too many headaches. One warning &#8211; this is a long post with a lot of details.  And, this is not the only way to setup replication.  This is just one way to do it.  I will show you a different way in part two of this post.  In order to try and keep this post as short as possible, I will not explain each command or feature, but instead I will post as many links as possible.  This install was performed on a Macintosh with OS version 10.6.8 (for the master) and 10.8.1 (for the slave).  This post should apply to most Unix installs, and it should work with Windows as well, with a few modifications.</p>
<p>I currently have one master database with three slaves attached.  I will be upgrading from MySQL 5.6.8 to 5.6.9 and all of the servers are <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html">GTID</a>-enabled.  This post will be relevant if you are able to stop both the master and the slave during the upgrade process &#8211; or if you are installing a new master and a slave (without an existing database on either system).</p>
<p>When I upgrade my master server, I like to export the data and do a fresh install, and then re-import my data back into MySQL.  Yes, there are ways to <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/upgrading.html">upgrade </a>without doing having to export your data.  But since I have a relatively small database (&lt;100MB), I like starting with a new server and re-importing the data. This is just my preference.</p>
<p>The first thing that I will need to do is to export my data with <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html">mysqldump</a>.  I like to export my databases one at a time, in case I have problems with the import, then I can narrow the problem down to a specific database.  I need a list of my databases, so from a MySQL prompt, I execute the <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/show-databases.html">show databases</a></b><font> command.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show databases;
+--------------------+
| Database           |
+--------------------+
| addressbook        |
| comicbooks         |
| genealogy          |
| information_schema |
| inventory          |
| mysql              |
| performance_schema |
| scripting          |
| test               |
| twtr               |
| website            |
+--------------------+
11 rows in set (0.92 sec)
</pre>
</td>
</tr>
</table>
<p>I don&#8217;t want to export the four MySQL databases &#8211; <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/information-schema.html">information_schema</a>, mysql, <a target="new">performance_schema</a> or test &#8211; as these will be created in the new install.  You are going to want to make sure that you don&#8217;t have any activity on your database before you export your data.  From a mysql prompt (on the server you want to export data), you can use the <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/flush.html">FLUSH TABLES WITH READ LOCK</a></b><font> command to prevent any additional inserts into the database and to allow all current transactions to be completed.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>I then export each database separately (my preference &#8211; you could do all of your databases at one time as well with the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html#option_mysqldump_all-databases">&#8211;all-databases</a> option).  In the command below, you will need to change <font face="courier"><b>DATABASE_NAME</b></font> to the actual name of each of your databases:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
/usr/local/mysql/bin/mysqldump --user=root --password --quick --skip-opt --create-options \
   --add-drop-database DATABASE_NAME &gt; $HOME/mysql_backups/DATABASE_NAME.sql
</pre>
</td>
</tr>
</table>
<p>Here is some information from the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html">mysqldump</a> page that explains each of the options that I used:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--quick, -q
This option is useful for dumping large tables. It forces mysqldump to retrieve rows for a table 
from the server a row at a time rather than retrieving the entire row set and buffering it in 
memory before writing it out.  <i>I use this option in case I have problems importing the data, 
I easily edit the dump file and remove the bad data</i>

--skip-opt
The --opt option is enabled by default, and --opt is shorthand for the combination of 
--add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables 
--quick --set-charset. It gives a fast dump operation and produces a dump file that can be 
reloaded into a MySQL server quickly.  Because the --opt option is enabled by default, you only 
specify its converse, the --skip-opt to turn off several default settings. See the discussion 
of mysqldump option groups for information about selectively enabling or disabling a subset 
of the options affected by --opt.

--create-options
Include all MySQL-specific table options in the CREATE TABLE statements.

--add-drop-database
Add a DROP DATABASE statement before each CREATE DATABASE statement. This option is typically used 
in conjunction with the --all-databases or --databases option because no CREATE DATABASE statements 
are written unless one of those options is specified.
</pre>
</td>
</tr>
</table>
<p>You might want to read the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqldump.html">mysqldump</a> page to see which options you will want to use.  </p>
<p>Once I have exported my data, I look at the export files to make sure that they were created.  You might even want to open one of the smaller dump files (if the file isn&#8217;t too large) in a text-editor and just take a look to make sure everything looks good.  If you used the same commands for each dump, then the smaller file will show you if the export is in the format you want. </p>
<p>If you have an existing MySQL database, you can also export the user and grant information so you can import this back into the new database.  See my last blog post <a target="new" href="http://scriptingmysql.wordpress.com/2013/01/10/retrieving-list-of-mysql-users-and-grants-with-perl/" />&#8220;Retrieving List of MySQL Users and Grants with Perl&#8221;</a> to find out how to export your users and grants.  You don&#8217;t have to use Perl to do this &#8211; you can manually use the commands explained in the post.</p>
<p>Now you can <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/server-shutdown.html">shutdown your MySQL instance</a>.</p>
<p>Once the database has shutdown, you can now <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/installing.html">install the new version of MySQL</a>.  In this case, I am installing version 5.6.9.  If you are on Unix or Mac, and you are installing as root, you will need to change ownership to the mysql user of the files in your home MySQL directory after the install process.</p>
<p>After you install the new database, you will want to execute the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysql-install-db.html">mysql_install_db</a> script.  You can also refer to the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/postinstallation.html">post-installation procedures </a>on the MySQL web site. <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/automatic-start.html">Start MySQL</a>, and run the script:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: # ./scripts/mysql_install_db
Installing MySQL system tables...OK

Filling help tables...OK

To start mysqld at boot time you have to copy
support-files/mysql.server to the right place for your system

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:

  ./bin/mysqladmin -u root password 'new-password'
  ./bin/mysqladmin -u root -h macserver01 password 'new-password'

Alternatively you can run:

  ./bin/mysql_secure_installation

which will also give you the option of removing the test
databases and anonymous user created by default.  This is
strongly recommended for production servers.

See the manual for more instructions.

You can start the MySQL daemon with:

  cd . ; ./bin/mysqld_safe &amp;

You can test the MySQL daemon with mysql-test-run.pl

  cd mysql-test ; perl mysql-test-run.pl

Please report any problems with the ./bin/mysqlbug script!

The latest information about MySQL is available on the web at

http://www.mysql.com

Support MySQL by buying support/licenses at http://shop.mysql.com

WARNING: Found existing config file ./my.cnf on the system.
Because this file might be in use, it was not replaced,
but was used in bootstrap (unless you used --defaults-file)
and when you later start the server.
The new default config file was created as ./my-new.cnf,
please compare it with your file and take the changes you need.

WARNING: Default config file /etc/my.cnf exists on the system
This file will be read by default by the MySQL server
If you do not want to use this, either remove it, or use the
--defaults-file argument to mysqld_safe when starting the server
</pre>
</td>
</tr>
</table>
<p>If you ran this script as root, you will need to change the ownership of the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/server-logs.html">mysql-bin</a> and <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/server-logs.html">mysql-bin.index</a> files in the mysql data directory to the mysql Unix user.  </p>
<p>If you intend to use this server as a master server, you will need to edit the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/option-files.html">my.cnf (my.ini on Windows)</a> file to make it ready to be a master server.  The minimum you must change is to add these lines under the <font face="courier"><b>[mysqld]</b></font> section of your my.cnf option file.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
log-bin=mysql-bin
server-id=1
</pre>
</td>
</tr>
</table>
<p>The &#8220;<font face="courier"><b>server-id</font></b>&#8221; must be unique to each server.  I usually set my master <font face="courier"></b>server-id = 1</b></font>. Check out the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-howto-masterbaseconfig.html">Setting the Replication Master Configuration</a> page on the MySQL web site to make sure you have the correct settings for your server.</p>
<p>We will be using <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html">global transaction identifiers (GTID) </a> for replication.  GTID&#8217;s are a new replication feature as of MySQL 5.6.5.  To enable GTID, you will need to add these lines under the [mysqld] section of your my.cnf option file. </p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
gtid_mode=ON
enforce-gtid-consistency
log-bin
log-slave-updates
binlog_format=mixed
</pre>
</td>
</tr>
</table>
<p>Now you can <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/automatic-start.html">start the MySQL server</a> (if it isn&#8217;t already started).  When you executed the <font face="courier"><b>mysql_install_db</b></font> script, it created the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/grant-table-structure.html">grant tables</a>.  You are going to want to change the root password and delete any anonymous accounts.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/default-privileges.html">Securing the Initial MySQL Accounts</a> for specific information for your operating system.  </p>
<p>An easy way to change the root password is to use <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqladmin.html">mysqladmin</a> from a command prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ ./bin/mysqladmin -u root password 'new-password'
</pre>
</td>
</tr>
</table>
<p>Right after you change the root password, you will want to test the new root password by logging in with mysql as root at a Unix prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: $ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2259
Server version: 5.6.9-rc-log MySQL Community Server (GPL)

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql&gt; 
</pre>
</td>
</tr>
</table>
<p>Before we perform any more transactions, we need to make sure that we have GTID enabled.  To see if GTID has been enabled, we can execute this statement from the mysql prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show global variables like '%GTID%';
+--------------------------+-----------------------------------------------+
| Variable_name            | Value                                         |
+--------------------------+-----------------------------------------------+
| enforce_gtid_consistency | ON                                            |
| gtid_executed            | 82F20158-5A16-11E2-88F9-C4A801092ABB:1-26     |
| gtid_mode                | ON                                            |
| gtid_owned               |                                               |
| gtid_purged              |                                               |
+--------------------------+-----------------------------------------------+
5 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The variables <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-gtids.html">enforce_gtid_consistency</a> and <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-gtids.html">gtid_mode</a> should have the value of &#8220;ON&#8221;.  The variable value for gtid_executed shows the UUID of the server, and the 1-26 shows that transactions one through 26 were executed.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html">GTID Concepts</a> for more information about this value.  Now that we know GTID has been enabled and our root password has been changed and confirmed, we can continue with deleting the anonymous accounts, creating our users and importing our data.</p>
<p>To find and delete the anonymous accounts, from a mysql prompt:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; use mysql;
Database changed
mysql&gt; SELECT user, host FROM user;
+------+-----------------------+
| user | host                  |
+------+-----------------------+
| root | 127.0.0.1             |
| root | ::1                   |
|      | macserver01.local     |
| root | macserver01.local     |
|      | localhost             |
| root | localhost             |
+------+-----------------------+
6 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The users that are blank are anonymous users. You can double-check the blank users with this statement:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user where user = '';
+------+-----------------------+
| user | host                  |
+------+-----------------------+
|      | VM-Mac-1081-128.local |
|      | localhost             |
+------+-----------------------+
2 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You may now delete the blank users:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; delete from user where user = '';
Query OK, 2 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>These are the users that are remaining:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user;
+------+-----------------------+
| user | host                  |
+------+-----------------------+
| root | 127.0.0.1             |
| root | ::1                   |
| root | VM-Mac-1081-128.local |
| root | localhost             |
+------+-----------------------+
4 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You can now create the users that you exported from your previous instance, or if this is a new install, you may create the users that you think you will need for this instance.  If you exported the users, then you will want to remove the &#8220;<font face="courier"><b>CREATE USER</b></font>&#8221; statement for the root users that match the user and host values above.  If you had grants for these users that were different than the default grants, you can still execute the grant statements.</p>
<p>If you are installing MySQL for the first time on your master or if you did not have a replication user in your previous instance, you will need a replication user for replication.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-howto-repuser.html">Creating a User for Replication</a> for more details, but here is a sample replication user creation statement:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CREATE USER 'replicate'@'%.mydomain.com' IDENTIFIED BY 'password';
mysql&gt; GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'%.mydomain.com';
</pre>
</td>
</tr>
</table>
<p>Now that our users have been created, we can import the data from our earlier export.  If this is a new install, then you may skip this step.  Before we import the data, let&#8217;s look at the master status.  We will use this information later, so save the output to a text file.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000006
         Position: 71046480
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-26
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>We can use the mysql program to import the data from the backups that we created earlier.  You will need to execute this command for each database backup file:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql -uroot -p DATABASE_NAME &lt; $HOME/mysql_backups/DATABASE_NAME.sql
</pre>
</td>
</tr>
</table>
<p>Once you have imported the data, you can check the master status to see how many transactions were executed.  Since I exported my data with one insert statement per line, the total number of insert statements that I had in my import should be close to the number of transactions that were executed.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql -uroot -p DATABASE_NAME  show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000006
         Position: 71046480
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162551
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The value of <font face="courier"><b>Executed_Gtid_Set</b><font> contains the same type of information from the variable <font face="courier"><b>gtid_executed</b><font> that we looked at previously.  The value <font face="courier"><b>82F20158-5A16-11E2-88F9-C4A801092ABB:1-162551</b></font></a> contains the <font face="courier"><b>UUID</b></a> of the server and shows that transactions one through 162551 have been executed on this new instance.  Since we exported the original data with each data row on an individual <font face="courier"><b>INSERT</b></font> line, we can now figure out how many rows of data we imported.  Before we imported the data, the value of <font face="courier"><b>Executed_Gtid_Set</b><font> was <font face="courier"><b>82F20158-5A16-11E2-88F9-C4A801092ABB:1-26</b><font> &#8211; so we executed 26 transactions before the data import.  The difference in the total number of rows from the data import less the number of transactions that were executed earlier, minus the total number of any other statements (such as <font face="courier"><b>CREATE TABLE</b><font>) should give us a count of the number of lines of data we imported.  This step isn&#8217;t really necessary, but I like to do it just to make sure that I didn&#8217;t lose any data.  And yes, it might be overkill.</p>
<p>We can do a line count for all of the data files that we imported earlier that contained an &#8220;<font face="courier"><b>INSERT</b><font>&#8221; statement.  This will give us a count of the total number of inserts from our import.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
$ ls -l $HOME/mysql_backups/*sql
total 61832
-rw-r--r--  1 root  staff   1151006 Jan  9 00:12 addressbook.sql
-rw-r--r--  1 root  staff    492652 Jan  8 23:11 comicbooks.sql
-rw-r--r--  1 root  staff  27485322 Jan  8 23:11 genealogy.sql
-rw-r--r--  1 root  staff    603943 Jan  8 23:11 inventory.sql
-rw-r--r--  1 root  staff    779634 Jan  8 23:11 scripting.sql
-rw-r--r--  1 root  staff   1077248 Jan  8 23:11 twtr.sql
-rw-r--r--  1 root  staff     50643 Jan  8 23:11 website.sql
$ grep INSERT *sql | wc -l
  162444
</pre>
</td>
</tr>
</table>
<p>Now we can get the total number of <font face="courier"><b>CREATE</b></font> statements:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: $ grep CREATE *sql | wc -l
      81
</pre>
</td>
</tr>
</table>
<p>The total number of transactions executed so far is 162551.  If we subtract the number of <font face="courier"><b>INSERT</b><font> lines from the import (162444) and <font face="courier"><b>CREATE</b><font> statements (81), we get the total of transactions that had taken place before the data import, which was 26.  We can now confirm that all of our data was imported successfully.  We can now install MySQL on the slave and start replication.</p>
<p>For the slave, we will want to do the same steps for the install process as we did on the master, but we will stop at importing any data.  Also, we will not have to create our additional users (with the exception of the replication user) and we will not have to import any data.  Once we turn on the slave instance, the users will be replicated and the data we imported will be copied to the slave.  Here are the steps:</p>
<ul>
<li> Install MySQL version 5.6.9 (change ownership of the files in the mysql directory to mysql if you installed as root)
<li> Run the post-install script <font face="courier"><b>mysql_install_db</b></font> (change ownership of the mysql-bin and mysql-bin.index files in the data directory if you installed as root)
<li> Change the root password and test it.
<li> <i>You don&#8217;t have to remove the anonymous accounts, as the SQL statements that we performed on the master will also be executed on the slave.</i>
<li> Create the replication user.
<li> Shutdown the mysql server.
<li> Edit the my.cnf options file (my.ini on Windows) and insert the GTID variables as shown earlier.  But, the server-id value must be something other than the value from the master server.  You can set this value to 2.
<li> Start the server
<li> Test to make sure GTID is enabled.
<li> Stop the slave by logging into mysql as root and executing &#8220;stop slave;&#8221;
</ul>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; stop slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>We can now provide the slave with the information on which master to use.  Before GTID, you would have to tell mysql which binary log you wanted to use, and the position within that binary log.  With GTID, you only need to set <font face="courier"><b>MASTER_AUTO_POSITION = 1</b></font>&#8220;;</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; CHANGE MASTER TO 
    -&gt; MASTER_HOST = '',
    -&gt; MASTER_PORT = 3306,
    -&gt; MASTER_USER = 'replication_user_name',
    -&gt; MASTER_PASSWORD = 'replication_user_password',
    -&gt; MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.20 sec)
</pre>
</td>
</tr>
</table>
<p>You will need to change the <font face="courier"><b>replication_user_name</b></font> and <font face="courier"><b>replication_user_password</b></font> to match the values you used when you created the replication user.</p>
<p>Before we turn on the slave, you may check the status of the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.1.2
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: WEB_SERVER_01-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 151
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: C242A198-5AAA-11E2-8CC0-387DCB822A4B:1-2
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>We can check the values for <font face="courier"><b>Master_Host</b></font> and <font face="courier"><b>Master_User</b></font> to make sure they match our master server.  Since the slave hasn&#8217;t been started yet, the value for <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/show-slave-status.html">Retrieved_Gtid_Set</a></b></font> is blank &#8211; as we haven&#8217;t retrieved any data from the master.  Once we start the slave, the value for <font face="courier"><b>Retrieved_Gtid_Set</b></font> will show us how many transactions have been retrieved from the master.  The value for <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/show-slave-status.html">Executed_Gtid_Set</a></b></font> shows that we have executed two transactions on this new slave instance &#8211; changing the root password and creating the replication user. Now we can start the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; start slave;
Query OK, 0 rows affected (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>After a few moments, you can check on the slave status again.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.2
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000007
          Read_Master_Log_Pos: 1914
               Relay_Log_File: WEB_SERVER_01-relay-bin.000007
                Relay_Log_Pos: 1024
        Relay_Master_Log_File: mysql-bin.000006
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1396
                   Last_Error: Error 'Operation CREATE USER failed for 'replicate'@'%'' on query. 
                               Default database: ''. Query: 'CREATE USER 'replicate'@'%' 
                               IDENTIFIED BY PASSWORD '*BE1BDEC0AA74B4XCB07X943E70X28096CXA985F8''
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 814
              Relay_Log_Space: 71051295
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 1396
               Last_SQL_Error: Error 'Operation CREATE USER failed for 'replicate'@'%'' on query. 
                               Default database: ''. Query: 'CREATE USER 'replicate'@'%' 
                               IDENTIFIED BY PASSWORD '*BE1BDEC0AA74B4DCB079943E70528096CCA985F8''
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 82f20158-5a16-11e2-88f9-c4a801092abb
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 130109 21:50:45
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162562
            Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-3,
C242A198-5AAA-11E2-8CC0-387DCB822A4B:1-2
</pre>
</td>
</tr>
</table>
<p>We can see from the value for <font face="courier"><b>Retrieved_Gtid_Set</b><font> is <font face="courier"><b>82F20158-5A16-11E2-88F9-C4A801092ABB:1-162562</b><font>, which shows that we have already retrieved all of the transactions from the master.  The <font face="courier"><b>Executed_Gtid_Set</b><font> value of <font face="courier"><b>82F20158-5A16-11E2-88F9-C4A801092ABB:1-3</b><font> shows that we have processed the first three transactions from the master, and the value of <font face="courier"><b>C242A198-5AAA-11E2-8CC0-387DCB822A4B:1-2</b><font> shows we have executed two transactions from the slave.</p>
<p>The variable <font face="courier"><b>Last_Error</b><font> shows that we also have an error because the <font face="courier"><b>CREATE USER</b><font> statement for the replication user from the master database fails on the slave, as we have already created a replication user.  I purposely created the same user to show you what happens when you have an error on the slave.  <i>In the above list of installation actions to do on the slave, you can skip &#8220;create replication user&#8221;.</i></p>
<p>To skip this error and continue with replication, you can set the <font face="courier"><b>SQL_SLAVE_SKIP_COUNTER</b><font> to &#8220;1&#8243;, which tells the slave to skip one transaction.  You must stop the slave, set <font face="courier"><b>SQL_SLAVE_SKIP_COUNTER = 1</b><font> and restart the slave.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; stop slave;SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;start slave;
Query OK, 0 rows affected (0.16 sec)
</pre>
</td>
</tr>
</table>
<p>Let&#8217;s look at the slave status again:  (the output is truncated as we only need to look at the values for <font face="courier"><b>Retrieved_Gtid_Set</b><font> and <font face="courier"><b>Executed_Gtid_Set</b><font>)</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
....
           Retrieved_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162562
            Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-3:5-15401,
C242A198-5AAA-11E2-8CC0-387DCB822A4B:1-12
....
</pre>
</td>
</tr>
</table>
<p>You can see that the value of the <font face="courier"><b>Executed_Gtid_Set</b><font> has changed to <font face="courier"><b>82F20158-5A16-11E2-88F9-C4A801092ABB:1-3:5-15401</b><font>, which means that the slave is starting to process the transactions from the master, and is on transaction 15401.  You can also see that transaction number four was skipped (when we executed the <font face="courier"><b>SET GLOBAL SQL_SLAVE_SKIP_COUNTER</b></font> command).  This was the transaction to create the replication slave user.</p>
<p>You can check the slave status until you see that all of the transactions that were retrieved from the master have been completed on the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
....
           Retrieved_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162562
            Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-3:5-162562,
C242A198-5AAA-11E2-8CC0-387DCB822A4B:1-12
....
</pre>
</td>
</tr>
</table>
<p>You can go back to the master and see the master&#8217;s status:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000007
         Position: 1914
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 82F20158-5A16-11E2-88F9-C4A801092ABB:1-162562
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>We can now see that the value for <font face="courier"><b>Executed_Gtid_Set</b><font> on the master is the same as the value on the slave (not including the transactions executed on the slave itself).  So, the slave now has the same data as the master, and it is up to date and not lagging behind the master.  If you have a busy master server, your slave might lag behind while it updates the records on the slave.</p>
<p>We can also check to make sure that all of the users that we created on the master are also now on the slave:</p>
<p>SLAVE:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user order by user, host;
+-------------+-----------------------+
| user        | host                  |
+-------------+-----------------------+
| WebSite     | 192.168.1.2           |
| WebSite     | localhost             |
| replicate   | 192.168.1.121         |
| replicate   | 192.168.1.2           |
| replicate   | 192.168.1.4           |
| replicate   | localhost             |
| root        | 127.0.0.1             |
| root        | 192.168.1.2           |
| root        | VM-Mac-1081-128.local |
| root        | localhost             |
| scripting   | 192.168.1.121         |
| scripting   | 192.168.1.122         |
| scripting   | 192.168.1.2           |
+-----------+-------------------------+
13 rows in set (0.01 sec)
</pre>
</td>
</tr>
</table>
<p>MASTER:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; select user, host from user order by user, host;
+-------------+---------------+
| user        | host          |
+-------------+---------------+
| WebSite     | 192.168.1.2   |
| WebSite     | localhost     |
| replicate   | 192.168.1.121 |
| replicate   | 192.168.1.2   |
| replicate   | 192.168.1.4   |
| replicate   | localhost     |
| root        | 127.0.0.1     |
| root        | 192.168.1.2   |
| root        | localhost     |
| root        | macserver01   |
| scripting   | 192.168.1.121 |
| scripting   | 192.168.1.122 |
| scripting   | 192.168.1.2   |
+-----------+-----------------+
13 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The only difference in the users on the master and slave is the root user for each machine:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
Slave - root, VM-Mac-1081-128.local
Master - root, macserver01
</pre>
</td>
</tr>
</table>
<p>The master and slave are now ready for use.  If you have an <a target="new" href="http://www.mysql.com/products/enterprise/" />Enterprise subscription </a>to MySQL, you can use <a target="new" href="http://www.mysql.com/products/enterprise/monitor.html">MySQL Enterprise Monitor</a> to look at the status of the master and the slave:</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/master_slave_on_MEM.png"></p>
<p>Otherwise, you may just do a periodic &#8220;<font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/show-master-status.html">show master status\G</a></b><font>&#8221; and <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/show-slave-status.html">&#8220;show slave status\G</a></b><font>&#8221; to see if the slave is lagging behind the master.  </p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="200" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/972/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/972/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=972&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/18/mysql-replication-with-global-transaction-identifiers-step-by-step-install-and-addition-of-slaves-part-one/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://scriptingmysql.com/scriptingmysql/master_slave_on_MEM.png" medium="image" />

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>Retrieving List of MySQL Users and Grants with Perl</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/10/retrieving-list-of-mysql-users-and-grants-with-perl/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/10/retrieving-list-of-mysql-users-and-grants-with-perl/#comments</comments>
		<pubDate>Thu, 10 Jan 2013 18:07:46 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=912</guid>
		<description><![CDATA[Before I upgrade MySQL to the latest and greatest version, one of the first things that I do is export the user and grant information. In the past, I would keep all of my user information (user name, password, grants) in a text file, with the SQL for each user/grant ready to be executed on [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=912&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Before I upgrade MySQL to the latest and greatest version, one of the first things that I do is export the user and grant information.  In the past, I would keep all of my user information (user name, password, grants) in a text file, with the SQL for each user/grant ready to be executed on the upgraded server.  I did use my own form of &#8220;mental encryption&#8221; for my passwords, so the passwords weren&#8217;t in plain English.  But then I would have to decode my passwords each time before I executed the SQL statements.</p>
<p>When I upgrade, I usually like to dump all of the data and import it into the new version, so I have a fresh copy of the database.  The MySQL server that I have is for my personal use and the data size is relatively small, so for my case it doesn&#8217;t take long to import the data.</p>
<p>But there were times when I would add a user in the MySQL database and forget to add it to my text file.  Then, when it came time to upgrade and I would refer to my text file, these new users would not get recreated.  For me it wasn&#8217;t that big of a deal, as I am only dealing with my own home-office server, and not a production server.  I would eventually figure out that these users weren&#8217;t available, and I would simply recreate them.  But I often add temporary users for testing purposes. Every once in a while I would want to keep some of the temporary users, and some users would be deleted after the testing was completed.  So my text file was rarely up to date.</p>
<p>I am in the process of upgrading my servers to MySQL 5.6.9, and I decided to write a quick Perl script to export all of the users, passwords and grants.  Since I will be doing a fresh install of MySQL, I can then just use the output from this script to recreate my users.  Of course, you need to run this script before the upgrade.</p>
<p>There are two SQL statements that we will execute with this script.  The first, is simply retrieving a list of the user and host names from the mysql.user table:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; SELECT user, host FROM user order by user, host;
+-------------+---------------+
| user        | host          |
+-------------+---------------+
| replicate   | 192.168.1.121 |
| replicate   | 192.168.1.2   |
| replicate   | 192.168.1.4   |
| replicate   | localhost     |
| root        | 127.0.0.1     |
| root        | 192.168.1.2   |
| root        | localhost     |
| root        | macserver01   |
| scripting   | 192.168.1.121 |
| scripting   | 192.168.1.122 |
| scripting   | 192.168.1.2   |
+-----------+---------------+
11 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Then, we will loop through each of the user and host names to retrieve their grants and passwords.  Here is a sample of retrieving this data for just one user and one host name:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; SHOW GRANTS FOR 'replicate'@'192.168.1.121';
+-------------------------------------------------------------------------------------------------------------------+
| Grants for replicate@192.168.1.121                                                                                |
+-------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'192.168.1.121' IDENTIFIED BY PASSWORD '*BF6F715A6EBFE63005BEB705C' |
+-------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>The script will create the necessary SQL statements to recreate the users and grants, with the output displayed in the terminal window.  You will just need to copy and save the output from the terminal window into a text file.  Or you can change the print statement to output the information directly to a file.  Here are the changes to output to a file:</p>
<p>Add this to the top of the script after the &#8220;my $Database&#8221; line.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
open(OUTFILE, "&gt;mysql_usernames.txt") || die "Can't redirect stdout";
</pre>
</td>
</tr>
</table>
<p>Add OUTFILE after each of your print commands:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
print OUTFILE "CREATE user \'$user\'\@'$host\'\ identified by '';\n";
print OUTFILE "$privileges;\n\n";
</pre>
</td>
</tr>
</table>
<p>And close the OUTFILE after the last right curly bracket &#8220;<font face="courier">}</font>&#8221;  and before the subroutine:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
close OUTFILE;
</pre>
</td>
</tr>
</table>
<p>For the script, you will need to install the <a href="http://dbi.perl.org/" />Perl::DBI</a> module.  You will also need to change the values for the $host, $userid and $passwd variables in the sub routine ConnectToMySql to match your system. Here is the Perl script.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
#!/usr/bin/perl

use DBI;

my $Database = "mysql";

        $dbh = ConnectToMySql($Database);

        # retrieve a list of users and host names
	$query = "SELECT user, host FROM user order by user, host";
	
        $sth = $dbh-&gt;prepare($query);

        $sth-&gt;execute();
    
          while (@data = $sth-&gt;fetchrow_array()) {
            my $user = $data[0];
            my $host = $data[1];
            
            print "CREATE user \'$user\'\@'$host\'\ identified by '';\n";

                $dbh2 = ConnectToMySql($Database);

	        # retrieve the grants for each user and host combination
                $query2 = "SHOW GRANTS FOR '$user'\@'$host'";
	
                $sth2 = $dbh2-&gt;prepare($query2);

                $sth2-&gt;execute();

                        while (@data2 = $sth2-&gt;fetchrow_array()) {
                            my $privileges = $data2[0];
                            print "$privileges;\n\n";
                        }

          # end first while statement           
          }

#----------------------------------------------------------------------
sub ConnectToMySql {
#----------------------------------------------------------------------

   my ($db) = @_;

   my $host ="";
   my $userid = "";
   my $passwd = "";
   my $connectionInfo = "dbi:mysql:$db;$host";

   # make connection to database
   my $l_dbh = DBI-&gt;connect($connectionInfo,$userid,$passwd);
   return $l_dbh;

}
</pre>
</td>
</tr>
</table>
<p>And here is the output from running the script.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
root@macserver01: $ perl get_mysql_users.pl
CREATE user 'replicate'@'192.168.1.121' identified by '';
GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'192.168.1.121' IDENTIFIED BY PASSWORD '*BF6F715A6EBF367E76X705C';

CREATE user 'replicate'@'192.168.1.2' identified by '';
GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'192.168.1.2' IDENTIFIED BY PASSWORD '*BF6F715A6EBF367E76X705C';

CREATE user 'replicate'@'192.168.1.4' identified by '';
GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'192.168.1.4' IDENTIFIED BY PASSWORD '*2A9C19E10B309BF1BE40E4A9C';

CREATE user 'replicate'@'localhost' identified by '';
GRANT REPLICATION SLAVE ON *.* TO 'replicate'@'localhost' IDENTIFIED BY PASSWORD '*2A9C19E10B309BF1BE40E4A9C';

CREATE user 'root'@'127.0.0.1' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' IDENTIFIED BY PASSWORD '*BF6F715A6EBFKK367E76X705C' WITH GRANT OPTION;

CREATE user 'root'@'192.168.1.2' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'192.168.1.2' IDENTIFIED BY PASSWORD '*BF6F715A6EBFKK367E76X705C' WITH GRANT OPTION;

CREATE user 'root'@'localhost' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY PASSWORD '*BF6F715A6EBFKK367E76X705C' WITH GRANT OPTION;

CREATE user 'root'@'macserver01' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'macserver01' WITH GRANT OPTION;

CREATE user 'scripting'@'192.168.1.121' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'scripting'@'192.168.1.121' IDENTIFIED BY PASSWORD '*DEE6483B0XX23K3AD402E34F7' WITH GRANT OPTION;

CREATE user 'scripting'@'192.168.1.122' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'scripting'@'192.168.1.122' IDENTIFIED BY PASSWORD '*DEE6483B0XX23K3AD402E34F7' WITH GRANT OPTION;

CREATE user 'scripting'@'192.168.1.2' identified by '';
GRANT ALL PRIVILEGES ON *.* TO 'scripting'@'192.168.1.2' IDENTIFIED BY PASSWORD '*DEE6483B0XX23K3AD402E34F7' WITH GRANT OPTION;
</pre>
</td>
</tr>
</table>
<p>Now when I upgrade my server, I can simply run this script prior to my upgrade and save the information.  I don&#8217;t have to worry about missing a user or keeping my user information in a text file.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="100" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/912/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/912/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=912&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/10/retrieving-list-of-mysql-users-and-grants-with-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL Replication &#8211; Multi-Threaded Slaves (Parallel Event Execution)</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/07/mysql-replication-multi-threaded-slaves-parallel-event-execution/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/07/mysql-replication-multi-threaded-slaves-parallel-event-execution/#comments</comments>
		<pubDate>Mon, 07 Jan 2013 12:55:52 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=892</guid>
		<description><![CDATA[If you aren&#8217;t familiar with MySQL replication, &#8220;Replication enables data from one MySQL database server (the master) to be replicated to one or more MySQL database servers (the slaves). Replication is asynchronous by default &#8211; slaves need not to connected permanently to receive updates from the master. This means that updates can occur over long-distance [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=892&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>If you aren&#8217;t familiar with MySQL replication, &#8220;<font color="blue">Replication enables data from one MySQL database server (the master) to be replicated to one or more MySQL database servers (the slaves). Replication is asynchronous by default &#8211; slaves need not to connected permanently to receive updates from the master. This means that updates can occur over long-distance connections and even over temporary or intermittent connections such as a dial-up service. Depending on the configuration, you can replicate all databases, selected databases, or even selected tables within a database.</font>&#8221;  (From:  <a href="http://dev.mysql.com/doc/refman/5.5/en/replication.html" rel="nofollow">http://dev.mysql.com/doc/refman/5.5/en/replication.html</a>).</p>
<p>I use MySQL replication on my home office server.  I don&#8217;t really have much data to store, but it is nice to have several replicated slaves for backup purposes and also for testing new replication features of MySQL.  I also use my setup to demo <a target="new" href="http://www.mysql.com/products/enterprise/monitor.html">MySQL Enterprise Monitor</a>.</p>
<p>Prior to MySQL 5.6.3, replication slaves were single-threaded.  There are three threads involved with replication, but only one of those threads writes the replicated data from the master to the slave database (more info about these threads may be found <a target="new" href="http://dev.mysql.com/doc/refman/5.5/en/replication-implementation-details.html">here</a>). If you had a busy master server, with a high number of writes, these writes could get bottlenecked at the slave, as the slave could only apply each event one at a time, in the same order that the events were executed on the master.  If you were using the slaves for your reads, then your data could be stale depending on how quickly (or slowly) the slaves could apply the writes from the master.</p>
<p>I was giving a presentation a couple years ago about MySQL replication.  I was trying to demonstrate that adding slaves doesn&#8217;t necessarily divide the workload equally among the number of servers that you have.  In my example, I stated that we had a master server that had a max load (at 100%) of 10,000 events (reads and writes) per a given time frame.  For these 10,000 events, we assumed that the master was performing 6,000 reads and 4,000 writes during this period.  If we added three slaves, we couldn&#8217;t figure that the master would now be at 25% capacity (100% capacity divided by the new total of four servers).  Each slave also has to perform the same number of writes as the master &#8211; we were really only scaling the number of reads across four servers.</p>
<p>In order to try and get my point across, I then presented a formula that looked like this:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
Master server alone:
Max. Load = 6000 reads + 4000 writes / 10,000

Master Server plus three slaves:
Load = (6000 reads + (4 x 4000 writes) / (4 servers x 10,000)) = (22,000 / 40,000) = 55%
</pre>
</td>
</tr>
</table>
<p>Someone in the audience then pointed out that this formula wouldn&#8217;t work exactly, as the slaves were single-threaded.  Of course that was a true statement, but the point that I was trying to make is that scaling out with slaves isn&#8217;t exactly linear.  Later, I tried to come up with an easy way to determine a formula that would take into account the fact that slaves were single-threaded, but I couldn&#8217;t find an easy way to do this.  There were just too many factors involved.  For future presentations, I just made sure that I added the caveat that slaves are single-threaded.</p>
<p>So, what are multi-threaded slaves?  Multi-threaded slaves allow you to execute the replication events from a master across different databases in parallel.  For best results, you should partition your data per database.  In other words, instead of having one database with many tables, you would have a database for each table.  If you have some tables that are read-only and you rarely write to these tables, you could include them in their own database or in another database.  By splitting the data into multiple databases, MySQL replication is able to update each database separately, in the same order relative to the updates as they occurred on the master.  There is a system variable named <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#option_mysqld_slave-parallel-workers">slave_parallel_workers</a></b></font>, which should be set to equal the same number of databases that you have.  There are some concerns in using multi-threaded replication, as events from the master might not be executed on the slave in the same order.  Click <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/news-5-6-3.html">here</a> for more information on MySQL multi-threaded replication (Parallel Event Execution).</p>
<p>Back in April, 2012, <a target="new" href="https://twitter.com/matkeep">Mat Keep<a /> wrote about <a target="new" href="https://blogs.oracle.com/MySQL/entry/benchmarking_mysql_replication_with_multi">Benchmarking MySQL Replication with Multi-Threaded Slaves</a> in which he demonstrated that multi-threaded slaves could improve slave performance by almost five times.  Mat&#8217;s example involved inserting 10,000 rows into 10 different schemas on a single slave.  Mat stated that there are three key variables that you need to set to achieve maximum performance with multi-threaded slaves:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
<a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/binary-log-setting.html">binlog-format</a>=STATEMENT 
<a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#option_mysqld_relay-log-info-repository">relay-log-info-repository</a>=TABLE 
<a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#option_mysqld_master-info-repository">master-info-repository</a>=TABLE 
</pre>
</td>
</tr>
</table>
<p>(From <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/slave-logs-status.html">http://dev.mysql.com/doc/refman/5.6/en/slave-logs-status.html</a>: use <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#option_mysqld_master-info-repository">&ndash;&ndash;master-info-repository</a></b></font> to have the master info log written to the <font face="courier"><b>mysql.slave_master_info</b></font> table, and use <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#option_mysqld_relay-log-info-repository">&ndash;&ndash;relay-log-info-repository</a></b></font> to have the relay log info log written to the <font face="courier"><b>mysql.slave_relay_log_info</b></font> table)</p>
<p>Mat also suggests that the variable <font face="courier"><b><a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-slave.html#sysvar_slave_parallel_workers">slave_parallel_workers</a></b></font> should be set to equal the number of schemas that you have.  If you look at the data he provided, increasing this variable beyond the total number of schemas did not improve performance.  Even though the slave is multi-threaded, each schema is still single-threaded, so having multiple worker threads didn&#8217;t really make a difference.</p>
<p>While I don&#8217;t have the need at this point to switch my replication setup to use multi-threaded slaves, it is still a great new feature of 5.6.  You may download a copy of MySQL at <a target="new">http://dev.mysql.com/downloads/mysql</a>.  As of this writing, 5.6 is under the Development Releases tab.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="100" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/892/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/892/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=892&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/07/mysql-replication-multi-threaded-slaves-parallel-event-execution/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL 5.6 Delayed Replication &#8211; Making a Slave Deliberately Lag Behind a Master</title>
		<link>http://scriptingmysql.wordpress.com/2013/01/02/mysql-5-6-delayed-replication-making-a-slave-deliberately-lag-behind-a-master/</link>
		<comments>http://scriptingmysql.wordpress.com/2013/01/02/mysql-5-6-delayed-replication-making-a-slave-deliberately-lag-behind-a-master/#comments</comments>
		<pubDate>Wed, 02 Jan 2013 18:16:11 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[MySQL Enterprise Monitor]]></category>
		<category><![CDATA[MySQL Replication]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=861</guid>
		<description><![CDATA[In the majority of MySQL replication scenarios, you want your slave databases to be a mirror of your master databases. You usually don&#8217;t want your slave to be behind your master by more than a few seconds &#8211; and your main goal is for your slave to always be in sync with your master. Would [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=861&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>In the majority of MySQL replication scenarios, you want your slave databases to be a mirror of your master databases.  You usually don&#8217;t want your slave to be behind your master by more than a few seconds &#8211; and your main goal is for your slave to always be in sync with your master.  Would you ever want your slave to deliberately be a few seconds, minutes or even hours behind your master?  There have been several suggestions from MySQL users over the years regarding this functionality as &#8220;feature request&#8221; (even though most of the requests were submitted as MySQL &#8220;bugs&#8221;, which was the easiest way to submit such a request).</p>
<p>The first request (that I could find) was by Jason Garrett, back in August of 2006, and was logged as <a href="http://bugs.mysql.com/bug.php?id=21639">&#8220;bug 21639&#8243;</a>.  Jason wanted MySQL to &#8220;provide a parameter/setting which allows an administrator to specify how many seconds a replication slave will be behind a replication master.  This will have the effect of delaying the replcation slave for this number of seconds.  This is useful in circumstances where the replication master is at risk of major data change/loss, and allow an administrator to intervene and isolate the slave from the impact.  ie.  In an environment where an adminstrator may accidentally drop a table.&#8221;</p>
<p>Anders Henke followed up the next month (September 2006) with this request (<a href="http://bugs.mysql.com/bug.php?id=22072">bug 22072</a>) &#8211; &#8220;Sometimes it&#8217;s also very nice being able to look on how some specific record did look last week &#8211; before you&#8217;ve made those critical changes yesterday, which might (or might not) relate to some issue being reported to you. And of course also without reloading that large database from backups.&#8221;</p>
<p>There have been a couple more requests related to delayed replication, and while there were some work-arounds, it is now a feature of 5.6.</p>
<p>On the <a href="http://dev.mysql.com/doc/refman/5.6/en/replication-delayed.html">MySQL web site</a> (in <font color="blue">blue</font> below), it gives three examples of why you would want to use time-delayed replication (including what Kay and Anders wanted to do).</p>
<p><font color="blue">Scenario #1 &#8211; To protect against user mistakes on the master. A DBA can roll back a delayed slave to the time just before the disaster.</font></p>
<p>If you have worked with databases for any period of time, I am sure that you have had the experience of accidentally deleting some rows or truncating a table.  And, if your database hasn&#8217;t had a recent backup, then that data could be lost.  And, if you have a fast slave, then that errant command will be executed before you can figure out what you just did.  So, you can then forget about using your slave as a backup for that lost data.  By setting your slave to lag behind your master for 10 minutes (more or less), you should have enough time to go to the slave, stop it, and export the data that you just lost for import into the master database.  Of course you can set this delay for a longer or shorter period, but it should be long enough for you to do what you need to do in order to at least stop the replication event from executing on the slave.</p>
<p><font color="blue">Scenario #2 &#8211; To test how the system behaves when there is a lag. For example, in an application, a lag might be caused by a heavy load on the slave. However, it can be difficult to generate this load level. Delayed replication can simulate the lag without having to simulate the load. It can also be used to debug conditions related to a lagging slave.</font></p>
<p>You can test how your particular application and system behaves when the slave is lagging behind the master.  Normally you would generate a huge load on the master so that the slave is bogged down and thus a lag is generated.  By delaying the slave, you can simulate this lag without having to generate the load on the master.  You can also use this to debug any applications or conditions that are related to a lagging slave.</p>
<p><font color="blue">Scenario #3 &#8211; To inspect what the database looked like long ago, without having to reload a backup. For example, if the delay is one week and the DBA needs to see what the database looked like before the last few days&#8217; worth of development, the delayed slave can be inspected.</font></p>
<p>Having a slave delayed by a long time &#8211; for example, a few days or longer &#8211; can give you a snapshot of what the database looked like before the last round of database development.  If you are working on an application and are making changes that effect the database, you can compare the two database states. You might wonder &#8220;how would the application perform if I made these changes to the database?&#8221;.  You could then make the changes and test the application on both servers to see the differences.<br />
</font></p>
<p>To set the amount of time that your slave will log behind the master, simply execute this command on the slave (you have to stop the slave first):</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CHANGE MASTER TO MASTER_DELAY = N;
</pre>
</td>
</tr>
</table>
<p>- where &#8220;N&#8221; is the number of seconds that you want the slave to lag behind the master.</p>
<p>On a slave, let&#8217;s execute this statement so that the slave is 10 minutes (600 seconds) behind the master.  But, for comparison, let&#8217;s do a &#8220;<font face="courier"><b>show slave status\G</b></font>&#8221; on the slave before we make the change:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.121
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000019
          Read_Master_Log_Pos: 798706
               Relay_Log_File: WEB_SERVER_01-relay-bin.000052
                Relay_Log_Pos: 63004
        Relay_Master_Log_File: mysql-bin.000019
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 798706
              Relay_Log_Space: 63491
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 4
                  Master_UUID: bf0fc6b6-3b3a-11e2-99fd-32f021d3be40
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 6CD03F68-3B38-11E2-99FA-588CB3DE3E9D:1-6:8-24:26-1497,
BF0FC6B6-3B3A-11E2-99FD-32F021D3BE40:1-1036
            Executed_Gtid_Set: 6CD03F68-3B38-11E2-99FA-588CB3DE3E9D:1-6:8-11:13-16:18:20-24:26-1497,
BF0FC6B6-3B3A-11E2-99FD-32F021D3BE40:1-1036,
E6DF8108-4BB2-11E2-AB25-ECEFE5B0C1B4:1-378
1 row in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>Now, let&#8217;s execute the statement:  (we have to stop the slave first, execute the statement, and restart the slave)</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; STOP SLAVE;
Query OK, 0 rows affected (0.07 sec)

mysql&gt; CHANGE MASTER TO MASTER_DELAY = 600;
Query OK, 0 rows affected (0.06 sec)

mysql&gt; START SLAVE;
Query OK, 0 rows affected (0.01 sec)
</pre>
</td>
</tr>
</table>
<p>Here is the &#8220;show slave status\G&#8221; command after the statement was executed:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.121
                  Master_User: replicate
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000019
          Read_Master_Log_Pos: 798706
               Relay_Log_File: WEB_SERVER_01-relay-bin.000002
                Relay_Log_Pos: 314
        Relay_Master_Log_File: mysql-bin.000019
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 798706
              Relay_Log_Space: 526
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 4
                  Master_UUID: bf0fc6b6-3b3a-11e2-99fd-32f021d3be40
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 600
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 6CD03F68-3B38-11E2-99FA-588CB3DE3E9D:1-6:8-11:13-16:18:20-24:26-1497,
BF0FC6B6-3B3A-11E2-99FD-32F021D3BE40:1-1036,
E6DF8108-4BB2-11E2-AB25-ECEFE5B0C1B4:1-378
1 row in set (0.01 sec)
</pre>
</td>
</tr>
</table>
<p><font face="courier"><b>SHOW SLAVE STATUS</b></font> has three fields that provide information about the delay, and you can see their values in the above output: (from <a href="http://dev.mysql.com/doc/refman/5.6/en/replication-delayed.html" rel="nofollow">http://dev.mysql.com/doc/refman/5.6/en/replication-delayed.html</a> in <font color="blue">blue</font>)</p>
<p>1. <font color="blue"><font face="courier"><b>SQL_Delay</b></font>: A nonnegative integer indicating the number of seconds that the slave must lag the master.</font></p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
                    SQL_Delay: 600
</pre>
</td>
</tr>
</table>
<p>You can see above that it has changed to 600.</p>
<p>2. <font color="blue"><font face="courier"><b>SQL_Remaining_Delay</b></font>: When Slave_SQL_Running_State is Waiting until <font face="courier"><b>MASTER_DELAY</b></font> seconds after master executed event, this field contains an integer indicating the number of seconds left of the delay. At other times, this field is <font face="courier"><b>NULL</b></font>.</font></p>
<p>The value of &#8220;<font face="courier"><b>SQL_Remaining_Delay</b></font>&#8221; from my &#8220;<font face="courier"><b>show slave status\G</b></font>&#8221; command shows &#8220;<font face="courier"><b>NULL</b></font>&#8220;.  </p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
          SQL_Remaining_Delay: NULL
</pre>
</td>
</tr>
</table>
<p>The value is &#8220;<font face="courier"><b>NULL</b></font>&#8221; because nothing has changed on the master that hasn&#8217;t been updated on the slave, so it doesn&#8217;t show the remaining seconds that the slave will lag behind the master.  I changed a record on the master, executed the &#8220;<font face="courier"><b>show slave status\G</b></font>&#8221; command again, and you can see the <font face="courier"><b>SQL_Remaining_Delay</b></font> status changed:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
                    SQL_Delay: 600
          SQL_Remaining_Delay: 592
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
</pre>
</td>
</tr>
</table>
<p>Also, if you are running the Enterprise version of MySQL and are using MySQL Enterprise Monitor (MEM), you will now see a change in the &#8220;Time Behind&#8221; column under the replication tab for this particular server, which is labeled as <font color="blue">VM-Mac-1081-123</font>.</p>
<p>Here is a snapshot from MEM before I updated the master:</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/slave_no_lag.png"></p>
<p>And here is a screenshot from MEM after I updated the master, which shows the slave starting to lag behind the master, as it is waiting 600 seconds before applying the update:</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/slave_starting_lag.png"></p>
<p>Once the slave has executed all statements on the master, in MEM you will see that the &#8220;Time Behind&#8221; column for VM-Mac-1081-123 will reset back to <font face="courier"><b>00:00:00</b></font>.  This does not mean that the slave isn&#8217;t still lagging behind the master by 600 seconds.  It just shows that the slave is current with the master.  </p>
<p>In my MEM example, I am running a slave (VM-Mac-1081-123) off another slave (with IP address of 192.168.1.121), which explains why MEM is stating that 192.168.1.121 is not being monitored.  That MySQL instance is being monitored, but it is a slave to another master (192.168.1.2), and is being monitored below the screenshot that I provided and is not shown in this example.</p>
<p>3. <font color="blue">Slave_SQL_Running_State: A string indicating the state of the SQL thread (analogous to Slave_IO_State). The value is identical to the State value of the SQL thread as displayed by <font face="courier"><b>SHOW PROCESSLIST</b></font>.</font></p>
<p>You can see that the <font face="courier"><b>Slave_SQL_Running_State</b></font> value from my &#8220;<font face="courier"><b>show slave status\G</b></font>&#8221; command is as follows:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
</pre>
</td>
</tr>
</table>
<p>The above value shows that we have pending statements on the master that have not been applied to the slave.  </p>
<p>Let&#8217;s run the <font face="courier"><b>SHOW PROCESSLIST</b></font> statement, but at this time we do not have any pending statements on the master:  (I removed all other processes that aren&#8217;t related to this discussion)</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show processlist;
+-----+-------------+-----------------+-------+---------+------+-----------------------------------------------------------------------------+------------------+
| Id  | User        | Host            | db    | Command | Time | State                                                                       | Info             |
+-----+-------------+-----------------+-------+---------+------+-----------------------------------------------------------------------------+------------------+
| 130 | system user |                 | NULL  | Connect |  379 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
| 129 | system user |                 | NULL  | Connect |  379 | Waiting for master to send event                                            | NULL             |
+-----+-------------+-----------------+-------+---------+------+-----------------------------------------------------------------------------+------------------+
</pre>
</td>
</tr>
</table>
<p>So, even with the slave delay, since we do not have any pending statements from the master, the value of &#8220;<font face="courier"><b>Slave_SQL_Running_State</b></font>&#8221; looks like the normal value that you have when you are not running a delay and the slave is current with the master.  Now I will change something on the master, and re-run the <font face="courier"><b>SHOW PROCESSLIST</b></font> statement:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show processlist;
+-----+-------------+-----------------+-------+---------+------+----------------------------------------------------------------+------------------+
| Id  | User        | Host            | db    | Command | Time | State                                                          | Info             |
+-----+-------------+-----------------+-------+---------+------+----------------------------------------------------------------+------------------+
| 130 | system user |                 | NULL  | Connect | 1784 | Waiting until MASTER_DELAY seconds after master executed event | NULL             |
| 129 | system user |                 | NULL  | Connect | 2503 | Waiting for master to send event                               | NULL             |
+-----+-------------+-----------------+-------+---------+------+----------------------------------------------------------------+------------------+
</pre>
</td>
</tr>
</table>
<p>You can see that the value of &#8220;<font face="courier"><b>State</b></font>&#8221; has changed from:</p>
<p>&#8220;<font face="courier"><b>Slave has read all relay log; waiting for the slave I/O thread to update it</b></font>&#8220;</p>
<p>to: </p>
<p>&#8220;<font face="courier"><b>Waiting until MASTER_DELAY seconds after master executed event</b></font>&#8220;.</p>
<p>After our <font face="courier"><b>MASTER_DELAY</b></font> value of 600 seconds has passed, the value of &#8220;<font face="courier"><b>State</b></font>&#8221; will revert back.</p>
<p>And when I run my &#8220;<font face="courier"><b>show slave status\G</b></font>&#8221; statement again, the value for &#8220;<font face="courier"><b>Slave_SQL_Running_State</b></font>&#8221; has changed, since I have a pending statement on the master:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
      Slave_SQL_Running_State: Waiting until MASTER_DELAY seconds after master executed event
</pre>
</td>
</tr>
</table>
<p>I now have a slave that is lagging 10 minutes behind the master.  If I ever have a situation where I accidentally delete some data, I now have 10 minutes to stop the slave and try to retrieve my data from the slave.  In a situation like this, I could try to stop the slave from executing the delete statement, but it might be easier to just export the data I need and re-import it back into the master.  My deletion command will eventually be executed on the slave, but so will my importing of the deleted data.  </p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="100" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/861/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/861/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=861&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2013/01/02/mysql-5-6-delayed-replication-making-a-slave-deliberately-lag-behind-a-master/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://scriptingmysql.com/scriptingmysql/slave_no_lag.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/slave_starting_lag.png" medium="image" />

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>Using the MySQL Script mysqlfailover for Automatic Failover with MySQL 5.6 GTID Replication</title>
		<link>http://scriptingmysql.wordpress.com/2012/12/06/using-the-mysql-script-mysqlfailover-for-automatic-failover-with-mysql-5-6-gtid-replication/</link>
		<comments>http://scriptingmysql.wordpress.com/2012/12/06/using-the-mysql-script-mysqlfailover-for-automatic-failover-with-mysql-5-6-gtid-replication/#comments</comments>
		<pubDate>Thu, 06 Dec 2012 12:55:33 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=786</guid>
		<description><![CDATA[This post is the second in a series that I will be doing on MySQL Workbench Utilities – Administer MySQL with Python Scripts. You may want to read the first half of this post to understand how MySQL Workbench Utilities work and how you access the scripts. These scripts were written by Chuck Bell (a [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=786&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>This post is the second in a series that I will be doing on <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />MySQL Workbench Utilities – Administer MySQL with Python Scripts.</a>  You may want to read the first half of <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />this post </a>to understand how <a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/" />MySQL Workbench Utilities</a> work and how you access the scripts.  These scripts were written by <a target="new" href="http://drcharlesbell.blogspot.com">Chuck Bell</a> (a <a target="new" href="http://mysql.com">MySQL</a> employee) and are available as stand-alone scripts (see Chuck&#8217;s <a target="new" href="http://drcharlesbell.blogspot.com">blog</a> for more information) or as part of the <a target="new" href="http://dev.mysql.com/downloads/workbench/" />MySQL Workbench</a> utility.</p>
<p>I am going to show you one way that you can use the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlfailover.html">mysqlfailover</a> script to monitor your replication stack and automatically failover to a slave database when your master has failed.  You will need to have both your master and slave databases running with GTID&#8217;s enabled. I will provide a brief overview of GTID&#8217;s, and how to start replication with GTID enabled.  The term &#8220;automatically failover&#8221; in the title might be a bit misleading, as the failover process is automatic, but it does take a couple of minutes.  It is automatic but not instantaneous.  Also, you may use the mysqlfailover script on a master with multiple slaves, but in this example I will only have one master and one slave.</p>
<p>Let&#8217;s start with a quick review of GTID&#8217;s &#8211; or global transaction identifiers.  GTID&#8217;s were introduced in <a target="new" href="http://mysql.com">MySQL</a> 5.6.5.  With GTID&#8217;s, each transaction can be identified and tracked as it is committed on the originating server and applied by any slaves; this means that it is not necessary when using GTIDs to refer to log files or positions within those files when starting a new slave or failing over to a new master, which greatly simplifies these tasks.</b></p>
<p><i>(From <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html">http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html</a>)</i></p>
<p>A global transaction identifier (GTID) is a unique identifier created and associated with each transaction when it is committed on the server of origin (master). This identifier is unique not only to the server on which it originated, but is unique across all servers in a given replication setup. There is a 1-to-1 mapping between all transactions and all GTIDs.  </p>
<p>The GTID has this format:  GTID = <b>source_id:transaction_id</b> &#8211; with the <b>source_id</b> identifying the originating server (in this case, the master server), and the <b>transaction_id</b> being a sequential number of the transactions that were committed on the originating server.  For example, the <b>twenty-third (23rd)</b> transaction to be committed originally on the server having the UUID <font face="courier"><b>3E11FA47-71CA-11E1-9E33-C80AA9429562</font></b> has this GTID:  </p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
3E11FA47-71CA-11E1-9E33-C80AA9429562:23
</pre>
</td>
</tr>
</table>
<p><i>(From <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html">http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html</a>.)</i></p>
<p>When you provide your slave server(s) with the information about which master to use for replication, without using GTID&#8217;s, you would normally execute a statement like this on the slave:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CHANGE MASTER TO
  MASTER_HOST = '192.168.1.121',
  MASTER_USER = 'replicate',
  MASTER_PASSWORD = 'password',
  MASTER_PORT = 3306,
  MASTER_LOG_FILE = 'mysql-bin.000003',
  MASTER_LOG_POS = 150691098,
  MASTER_CONNECT_RETRY = 10;
</pre>
</td>
</tr>
</table>
<p>When you have GTID&#8217;s enabled, you don&#8217;t have to provide the log file and position, you only have to provide this:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CHANGE MASTER TO 
MASTER_HOST = '192.168.1.121',
MASTER_PORT = 3306,
MASTER_USER = 'replicate',
MASTER_PASSWORD = 'password',
MASTER_AUTO_POSITION = 1;
</pre>
</td>
</tr>
</table>
<p>If you have worked with replication before, this should make some sense.  If not, then you will probably want to read more about <a target="new" href="http://dev.mysql.com/doc/refman/5.5/en/replication.html">replication </a> and <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html">GTID&#8217;s</a>.</p>
<p>For this example, I am going to take an existing <a target="new" href="http://mysql.com">MySQL</a> database, export the data, install the latest version of <a target="new" href="http://mysql.com">MySQL</a> (in this case 5.6.8), enable GTID&#8217;s, and then demo the mysqlfailover script.  This post is going to be a long one, but I will not try to go into as much detail as I normally would.  I am writing this after I have already tested this &#8211; so I am writing from memory &#8211; and hopefully I won&#8217;t forget any steps.  Here is my current configuration:</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_topology.png"></p>
<p>I have an application and web server at 192.168.1.2, a <a target="new" href="http://mysql.com">MySQL</a> master server at 192.168.1.121 and a <a target="new" href="http://mysql.com">MySQL</a> slave server at 192.168.1.122.</p>
<p>For my master and slave servers, I was running <a target="new" href="http://mysql.com">MySQL</a> version 5.5.27.  To export the data, I am going to just use mysqldump &#8211; but I will not export any of the <a target="new" href="http://mysql.com">MySQL</a> tables (such as information_schema, mysql, performance_schema and test).  When I upgrade from a new major version of <a target="new" href="http://mysql.com">MySQL</a> (such as from 5.5. to 5.6), I like to start with a new install versus trying to upgrade from a previous version.  (For large databases, this might not be as efficient or even possible, but since my database dump is only 26 megabytes, this will work for me.) </p>
<p>Since I only have a few <a target="new" href="http://mysql.com">MySQL</a> users, I keep the SQL statements that I need to re-create these users and their permissions in a text file.  Obviously this isn&#8217;t the best and most secure way to do this, but this is for my home system, so it doesn&#8217;t matter in my case.  If you prefer, you can just upgrade from 5.5 to 5.6 and not export the data &#8211; and instructions for upgrading this way may be found via this link &#8211; <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/installing.html">Installing and Upgrading MySQL</a>. </p>
<p>You need to make sure that there aren&#8217;t any updates to the database while you are doing your mysqldump.  You can lock the database with this command from a mysql prompt <font face="courier"><b>FLUSH TABLES WITH READ LOCK;</b></font> and then unlock it with <font face="courier"><b>UNLOCK TABLES;</b></font>.  Here is the mysqldump command that I used:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
/usr/local/mysql/bin/mysqldump --databases [list of your databases here, separated by spaces] 
--add-drop-database --add-drop-table --user=root --pass= &gt; /users/tonydarnell/2012_11_30_1645_dbdump.db
</pre>
</td>
</tr>
</table>
<p>(Yes, you will get a notification &#8220;Warning: Using a password on the command line interface can be insecure.&#8221; so you could leave the password blank and enter it when prompted.)</p>
<p>I usually also create a backup of the entire database in case I have any problems or if I destroy something.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
/usr/local/mysql/bin/mysqldump --all-databases --add-drop-database --add-drop-table --user=root \
  --pass=[your_password]
 &gt; /users/tonydarnell/2012_11_30_1645_all_dbdump.db
</pre>
</td>
</tr>
</table>
<p>I keep my data directory on two external USB hard drives that I have set up as a RAID on each machine.  I use a symbolic link from my <a target="new" href="http://mysql.com">MySQL</a> data directory (<font face="courier"><b>/usr/local/mysql/data</b></font>) to point to a directory on the RAID &#8211; with this command <font face="courier"><b>ln -s /volumes/server_raid/mysql_data/data /usr/local/mysql/data</b></font>).  Since I am creating a new install, I just rename the directory on the raid <font face="courier"><b>mv /volumes/server_raid/mysql_data/data /volumes/server_raid/mysql_data/data-old</b></font>.  When I install MySQ it will create a new data directory.  I then can move the new data directory to the RAID, and recreate the link.  You could also use this method to move your data directory to another internal or SSD drive.</p>
<p>Now I install <a target="new" href="http://mysql.com">MySQL</a> version 5.6.8. (see <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/installing.html">http://dev.mysql.com/doc/refman/5.6/en/installing.html</a> for instructions on installing <a target="new" href="http://mysql.com">MySQL</a>.)</p>
<p>Once I have <a target="new" href="http://mysql.com">MySQL</a> 5.6.8 installed on the master (including running any post-install scripts per the instructions above), I can import my database.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql -uroot -p &lt; /users/tonydarnell/2012_11_30_1645_all_dbdump.db
</pre>
</td>
</tr>
</table>
<p>I then start <a target="new" href="http://mysql.com">MySQL</a>, login, create my users, and the master is finished and ready.  I then repeat the same procedures on a slave machine.  Since no one has updated the master since my data dump, the master and the slave should be exact copies of each other.  If you are using virtual machines, once you have created the first virtual machine to be used as your master, you can just duplicate the VM to be your slave machine.  Just be sure to change the <font face="courier"><b>server-id</b></font> option in your mysql config file (<font face="courier"><b>my.cnf</b></font> or <font face="courier"><b>my.ini</b></font>) to be a different number.</p>
<p>It is time to turn on GTID&#039;s and to get replication started.  If you already have a master and slave configured, then you can refer to this link on how to start replication using GTID&#039;s <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-howto.html">http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-howto.html</a>.</p>
<p>You can either start the GTID process on both <a target="new" href="http://mysql.com">MySQL</a> servers by adding these options when you start <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqld.html">mysqld</a>:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--gtid_mode=ON --log-bin --log-slave-updates --disable-gtid-unsafe-statements
</pre>
</td>
</tr>
</table>
<p>Or, you can add these options to your <a target="new" href="http://mysql.com">MySQL</a> config file (<font face="courier"><b>/etc/my.cnf</b></font> or <font face="courier"><b>c:\my.cnf</b></font> or <font face="courier"><b>c:\Windows\my.ini</b></font>).</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
gtid_mode=ON
disable-gtid-unsafe-statements = 1
log-bin
log-slave-updates
</pre>
</td>
</tr>
</table>
<p>Binary logging should be enabled on the master, and you will also want to enable binary logging on the slave, so when the slave is promoted to the master, you can make the old master a slave to the new master.  See <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html"> this link for binary log options and variables</a>.</p>
<p>(Starting with <a target="new" href="http://mysql.com">MySQL</a> 5.6.9, <font face="courier"><b>&#8211;disable-gtid-unsafe-statements</b></font> is now named <font face="courier"><b>&#8211;enforce-gtid-consistency</b></font>)</p>
<p>Now that you have both of these options in place, you may start both of your servers.  On the slave, you will want to add <font face="courier"><b>&#8211;skip-slave-start</b></font> to the mysqld command.  You will want to start the slave manually, after you have given the slave the information about the master from a mysql prompt:</p>
<p>To test and make sure that GTID is running, you may issue this command on both servers:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
mysql&gt; show global variables like '%GTID%';
+--------------------------------+--------------------------------------------+
| Variable_name                  | Value                                      |
+--------------------------------+--------------------------------------------+
| disable_gtid_unsafe_statements | ON                                         |
| gtid_done                      | 6CD03F68-3B38-11E2-99FA-588CB3DE3E9D:1-242 |
| gtid_lost                      |                                            |
| gtid_mode                      | ON                                         |
| gtid_owned                     |                                            |
+--------------------------------+--------------------------------------------+
5 rows in set (0.00 sec)
</pre>
</td>
</tr>
</table>
<p>You can see the value for <font face="courier"><b>gtid_done</b></font> contains the GTID information &#8211; <font face="courier"><b>source_id:transaction_id</b></font>, where <font face="courier"><b>1-242</b></font> is the range of transactions that have been committed. (Your values will be different)</p>
<p>Now that we have <a target="new" href="http://mysql.com">MySQL</a> replication running with GTID&#8217;s enabled, we can look at running the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlfailover.html">mysqlfailover</a> script.  I use Perl on my web site, and my Perl scripts make a connection to the <a target="new" href="http://mysql.com">MySQL</a> database by reading the connection information from a text file (connection file) stored on the web server in the CGI directory.  (for more information on how I use this connection file, please see <a target="new" href="http://scriptingmysql.wordpress.com/2011/07/27/connecting-to-mysql-with-perl/" />Connecting to MySQL with Perl</a>)</p>
<p>This connection file contains the database name, IP address, mysql user and password.  This file determines which <a target="new" href="http://mysql.com">MySQL</a> server will be used by the web server and in this example the file is named accessWEB.  The file contains the following:  (you will have to configure the file to match your system)</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
scripts_db
192.168.1.121
user_name
password
</pre>
</td>
</tr>
</table>
<p>With the mysqlfailover script, you have the option to run a script before failover and after failover.  There is an option to also run a script prior to failing over, and one to run a script after failover has finished and mysqlfailover has refreshed the health report.</p>
<p>For this test, I will create a script that will change the connection file information to point to the slave database when the master fails.  This is as simple as creating a new connection file with the slave&#8217;s information, and then copying it on top of the existing file.  I will create a file for each server, and name the files after their IP addresses.  So, the file 192-168-1-121.txt will have the same information as the current accessWEB connection file, and the file 192-168-1-122.txt will contain:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
scripts_db
192.168.1.122
user_name
password
</pre>
</td>
</tr>
</table>
<p>For my pre-failover script, I will then create a shell script that input some text into a file so that I can see when failover started.  The script will be named &#8220;prefail.sh&#8221;, and it will contain the following:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
cd /Library/WebServer/cgi-bin/
echo "failover started" &gt; failover_started.txt
</pre>
</td>
</tr>
</table>
<p>I will need to make sure that prefail.sh has execute privileges and that all of the connection files have the correct privileges as well.  And I would want to test the script prior to using it.</p>
<p>For my post-failover script, I will create a shell script that will send me a text message, will change the connection file after failover has occurred and input some text into a file so that I can see when failover finished.  I will name this script postfail.sh.  It will contain the following:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
cd /Library/WebServer/cgi-bin/
cp 192-168-1-122.txt accessWEB
echo "Failover has occurred." | mail 4045552232@messaging.att.net
echo "failover finished" &gt; failover_finished.txt
</pre>
</td>
</tr>
</table>
<p>I have my master and slave using GTID, and the web server is connecting to the master (192.168.1.121).  I can now run the mysqlfailover script.  I don&#8217;t want to run it on the master or slave, because if one of them fails, then the script could fail as well.  I will run the script on the web server.  If it fails, then it doesn&#8217;t matter if the <a target="new" href="http://mysql.com">MySQL</a> servers are down, as no one can access the web site anyway.</p>
<p>Prior to running this script, I created a <a target="new" href="http://mysql.com">MySQL</a> user name &#8220;scripts&#8221; to use for the mysqlfailover script. I gave the user the same permissions as root.  I have a few options that I will use when executing the mysqlfailover script:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
--master=scripts:scripts123@192.168.1.121:3306 - connection information for the master
--slaves=scripts:scripts123@192.168.1.122:3306 - connection information for the slave(s)
--candidates=scripts:scripts123@192.168.1.122:3306 - a list of candidates for failover
--exec-before=/users/tonydarnell/scripts/prefail.sh - the script to execute before the failover
--exec-after=/users/tonydarnell/scripts/postfail.sh - the script to execute after the failover
</pre>
</td>
</tr>
</table>
<p>There is an option for setting the refresh time for the script with the <font face="courier"><b>&#8211;interval=X</b></font> option (where X is the number of seconds for the interval), but I will be using the default of 15 seconds.</p>
<p>I am also adding the <font face="courier"><b>&#8211;force</b></font> option &#8211; because at startup, the console will attempt to register itself with the master. If another console is already registered, and the failover mode is auto or elect, the console will be blocked from running failover. When a console quits, it deregisters itself from the master. If this process is broken, the user may override the registration check by using the &#8211;force option.  </p>
<p>(From: <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlfailover.html)">http://dev.mysql.com/doc/workbench/en/mysqlfailover.html</a></p>
<p>I can then open a terminal window and run the mysqlfailover script:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
# mysqlfailover --master=scripts:scripts123@192.168.1.121:3306 --slaves=scripts:scripts123@192.168.1.122:3306 
--candidates=scripts:scripts123@192.168.1.122:3306 --exec-before=/users/tonydarnell/scripts/prefail.sh 
--exec-after=/users/tonydarnell/scripts/postfail.sh --force
</pre>
</td>
</tr>
</table>
<p>Here is a screen shot of the script in action:</p>
<p><img width="625" src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_screen_shot.png"></p>
<p>To test the script, and to simulate the master server crashing or the mysqld process failing, I will just kill the mysqld process that is on the master server.  Since I am using <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqld-safe.html">mysqld_safe</a> to start the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqld.html">mysqld</a> process, I will need to kill that process as well.</p>
<p><img width="625" src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_kill_mysqld_processes.png"></p>
<p>Once the <a target="new" href="http://dev.mysql.com/doc/refman/5.6/en/mysqld.html">mysqld</a> processes have been killed, and the mysqlfailover script has refreshed (or you can refresh it manually), the failover process will start.  This entire process might take 20-30 seconds (give or take), and you will see something similar to this:</p>
<p><img width="625" src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_starting2.png"></p>
<p>Once the process has completed, the mysqlfailover script will now show you that the failover process has completed and the slave at 192.168.1.122 is now the master.</p>
<p><img width="625" src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_complete.png"></p>
<p>If you have more than one slave attached to the master, there are options that will allow you to specify a slave to become the master, or you can have the mysqlfailover script decide which slave is the best candidate to be promoted to master.  You will need to refer to the <a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlfailover.html">mysqlfailover page </a>for more information.</p>
<p>We can check to make sure that our scripts ran successfully by checking the actions of our pre and post-failover scripts.  We can check to see if the files were created by our &#8220;echo&#8221; commands in both scripts:</p>
<p><img width="625" src="http://scriptingmysql.com/scriptingmysql/mysqlfailover_files_created2.png"></p>
<p>We can also check our accessWEB file, to see that it has the new connection information.</p>
<p><img src="http://scriptingmysql.com/scriptingmysql/accessweb_file.png"></p>
<p>With the mysqlfailover script, both of our pre and post-failover scripts were executed, and our slave was promoted to the master.  Even though the failover process wasn&#8217;t immediate (the entire failover process took about a minute), it was successful.  </p>
<p>Once the failover has completed, and the old master has been restarted, you can then make the old master (192.168.1.121) a slave to the new master with this command:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>
CHANGE MASTER TO 
MASTER_HOST = '192.168.1.122',
MASTER_PORT = 3306,
MASTER_USER = 'replicate',
MASTER_PASSWORD = '',
MASTER_AUTO_POSITION = 1;
</pre>
</td>
</tr>
</table>
<p>The mysqlfailover script will recognize the new slave, but now your scripts will not be correct in that it will not copy the master info to the accessWEB file &#8211; so you would want to change them to match the new configuration.  Of course, you can obviously create scripts that provide the logic to failover to whichever server is available &#8211; maybe that is a topic for a future post.</p>
<p>If you prefer to have the old master as the current master, then you can wait until the old master catches up to the new master, stop both servers, and make the old master the new master again.  But it is easier to just keep both servers in the new configuration until failover happens again.  You could also use the mysqlfailover script to fail over to old master as well &#8211; making it the new master again.</p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="100" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/786/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/786/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=786&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2012/12/06/using-the-mysql-script-mysqlfailover-for-automatic-failover-with-mysql-5-6-gtid-replication/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_topology.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_screen_shot.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_kill_mysqld_processes.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_starting2.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_complete.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysqlfailover_files_created2.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/accessweb_file.png" medium="image" />

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL Workbench Utilities &#8211; Clone MySQL users with mysqluserclone</title>
		<link>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-clone-mysql-users-with-mysqluserclone/</link>
		<comments>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-clone-mysql-users-with-mysqluserclone/#comments</comments>
		<pubDate>Sun, 19 Aug 2012 23:45:54 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=714</guid>
		<description><![CDATA[This post is one in a series that I will be doing on MySQL Workbench Utilities &#8211; Administer MySQL with Python Scripts. MySQL Utilities are a part MySQL Workbench. The utilities are written in Python, available under the GPLv2 license, and are extendable using the supplied library. They are designed to work with Python 2.x [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=714&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><i>This post is one in a series that I will be doing on <a href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/">MySQL Workbench Utilities &#8211; Administer MySQL with Python Scripts</a>.  </p>
<p><a href="http://dev.mysql.com/doc/workbench/en/mysql-utilities.html">MySQL Utilities</a> are a part <a href="http://dev.mysql.com/doc/workbench/en/index.html">MySQL Workbench</a>.  The utilities are written in Python, available under the <a href="www.gnu.org/licenses/gpl-2.0.html">GPLv2</a> license, and are extendable using the supplied library. They are designed to work with Python 2.x greater than 2.6.  If you don&#8217;t have Workbench, you may download the MySQL Utility scripts from <a href="https://launchpad.net/mysql-utilities/" />launchpad.net</a>.  You will also need to install <a href="http://www.python.org/">Python</a> and to make sure that your execution <a href="http://en.wikipedia.org/wiki/PATH_(variable)">$PATH&#8217;s</a> are set correctly.</i></p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;
<p>I recently created a new MySQL replication slave instance on a new server, and I needed a way to copy a few of the users from the master database over to the slave database.  With the <a href="http://dev.mysql.com/doc/workbench/en/mysqluserclone.html">mysqluserclone</a> script, it was fairly easy.  The user that I wanted to copy from the master to the slave was named &#8220;WebUser&#8221;.  </p>
<p>Normally, to duplicate a user, I start by taking a look at the privileges that this user has by issuing a &#8220;<a href="http://dev.mysql.com/doc/refman/5.5/en/show-grants.html">SHOW GRANTS</a>&#8221; statement, like this:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>

mysql&gt; SHOW GRANTS FOR WebUser;
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for WebUser@%                                                                                                                               |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TABLESPACE ON *.* TO 'WebUser'@'%' IDENTIFIED BY PASSWORD '*xxxxxxxxxx' |
+----------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.04 sec)

</pre>
</td>
</tr>
</table>
<p>I would then go to the new instance, copy the above SQL statement, and issue the <a href="http://dev.mysql.com/doc/refman/5.5/en/create-user.html">CREATE USER</a> command using the HASH value of the password, and then issue the same &#8220;GRANT SELECT,&#8230;&#8221; statement &#8211; but without the IDENTIFIED BY PASSWORD part of the command.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>

mysql&gt; CREATE USER 'WebUser'@'localhost' IDENTIFIED BY PASSWORD '*xxxxxxxxxx';
Query OK, 0 rows affected (0.00 sec)

mysql&gt; GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TABLESPACE ON *.* TO 'WebUser'@'%';
Query OK, 0 rows affected (0.00 sec)

mysql&gt; SHOW GRANTS for WebUser;
+----------------------------------------------------------------------------------+
| Grants for WebUser@%                                                            |
+----------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE TABLESPACE ON *.* TO 'WebUser'@'%' |
+----------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql&gt; 

</pre>
</td>
</tr>
</table>
<p>This doesn&#8217;t take that much time, but what if you wanted to create the same user on several remote machines?  You would have to connect to each machine, login to mysql, and then issue the commands.  With <a href="http://dev.mysql.com/doc/workbench/en/mysqluserclone.html">mysqluserclone</a>, the process is much easier and faster.</p>
<p>From the <a href="http://dev.mysql.com/doc/workbench/en/mysqluserclone.html">mysqluserclone</a> man page:  &#8220;This utility [mysqluserclone] uses an existing MySQL user account on one server as a template, and clones it to create one or more new user accounts with the same privileges as the original user. The new users can be created on the original server or a different server.&#8221;</p>
<p>As the man page states, you may clone an existing user on the local machine, or on any remote machine.  In my case, I wanted to clone a user to a remote machine.  You need to make sure that the MySQL user on each machine that you are using to perform the user creation has the proper MySQL permissions on that machine.  I have created a user named &#8220;utility&#8221; on all of my servers, which I use instead of the root user for creating users and executing scripts.  </p>
<p>I needed to clone the user named &#8220;WebUser&#8221; from my master server (192.168.1.2) to my new replication slave server (192.168.1.5).  I issued the following command, and this is what happened:</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>

$ mysqluserclone --source=utility:tonyd765@192.168.1.2:3306 --destination=utility:tonyd959@192.168.1.5:3306 \
  WebUser@localhost WebUser:secret1@localhost
# Source on 192.168.1.2: ... connected.
# Destination on 192.168.1.5: ... connected.
ERROR: User WebUser:secret1@localhost already exists. Use --force to drop and recreate user.

</pre>
</td>
</tr>
</table>
<p>At first, it appeared that somehow during the creation of the new replication slave, I had already created the user named WebUser, or that user already existed.  I then realized that I had put in the wrong IP address of my new server.  In this situation, it was nice that mysqluserclone checked to make sure that the user did not exist before attempting to clone that user.  After getting the correct IP address (192.168.1.3), I decided that I wanted to clone the original WebUser (from the master server) to two new users on the new slave server &#8211; named WebUser1 and WebUser2.</p>
<table cellpadding="8">
<tr>
<td bgcolor="#FFFFFF">
<pre>

$ mysqluserclone --source=utility:tonyd32s@192.168.1.2:3306 --destination=utility:tonyd32s@192.168.1.3:3306 \
 WebUser@localhost WebUser1:secret1@localhost WebUser2:secret2@localhost
# Source on 192.168.1.2: ... connected.
# Destination on 192.168.1.3: ... connected.
# Cloning 2 users...
# Cloning WebUser@localhost to user WebUser1:secret1@localhost 
# Cloning WebUser@localhost to user WebUser2:secret2@localhost 
# ...done.

</pre>
</td>
</tr>
</table>
<p>In the above example, the first user &#8220;WebUser@localhost&#8221; was the user to be cloned, while WebUser1 and WebUser2 are the names of the new users on the remote machine.</p>
<p>I saved the syntax in a shell script, so that the next time I need to clone a user (or users), I can just quickly edit the script and execute it.  This makes it a lot easier than having to do everything manually.  There are a few more options that you may use with mysqluserclone, and you should reference the official <a>mysqluserclone</a> man page for more information.</p>
<table width="600">
<tr valign="top" bgcolor="#FFFFEE">
<td width="150">Option</td>
<td>Description</td>
</tr>
<tr valign="top">
<td>&#8211;help</td>
<td>Display a help message and exit. </td>
</tr>
<tr valign="top" bgcolor="#FFFFEE">
<td>&#8211;destination=</td>
<td>Connection information for the destination server in [:]@[:][:] format. </td>
</tr>
<tr valign="top">
<td>&#8211;dump, -d</td>
<td>Display the GRANT statements to create the account rather than executing them. In this case, the utility does not connect to the destination server and no &#8211;destination option is needed. </td>
</tr>
<tr valign="top" bgcolor="#FFFFEE">
<td>&#8211;format=, -f</td>
<td>Specify the user display format. Permitted format values are grid, csv, tab, and vertical. The default is grid. This option is valid only if &#8211;list is given. </td>
</tr>
<tr valign="top">
<td>&#8211;force</td>
<td>Drop the new user account if it exists before creating the new account. Without this option, it is an error to try to create an account that already exists. </td>
</tr>
<tr valign="top" bgcolor="#FFFFEE">
<td>&#8211;include-global-privileges</td>
<td>Include privileges that match base_user@% as well as base_user@host. </td>
</tr>
<tr valign="top">
<td>&#8211;list</td>
<td>List all users on the source server. With this option, a destination server need not be specified. </td>
</tr>
<tr valign="top" bgcolor="#FFFFEE">
<td>&#8211;quiet, -q</td>
<td>Turn off all messages for quiet execution. </td>
</tr>
<tr valign="top">
<td>&#8211;source=</td>
<td>Connection information for the source server in [:]@[:][:] format. </td>
</tr>
<tr valign="top" bgcolor="#FFFFEE">
<td>&#8211;verbose, -v</td>
<td>Specify how much information to display. Use this option multiple times to increase the amount of information. For example, -v = verbose, -vv = more verbose, -vvv = debug. </td>
</tr>
<tr valign="top">
<td>&#8211;version</td>
<td>Display version information and exit.</td>
</tr>
</table>
<p><a href="http://dev.mysql.com/doc/workbench/en/mysqluserclone.html">Source:  http://dev.mysql.com/doc/workbench/en/mysqluserclone.html</a></i></p>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="100" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/714/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/714/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=714&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-clone-mysql-users-with-mysqluserclone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
		<item>
		<title>MySQL Workbench Utilities &#8211; Administer MySQL with Python Scripts</title>
		<link>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/</link>
		<comments>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/#comments</comments>
		<pubDate>Sun, 19 Aug 2012 22:45:08 +0000</pubDate>
		<dc:creator>Tony Darnell</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://scriptingmysql.wordpress.com/?p=728</guid>
		<description><![CDATA[Over the next few months, I am going to be writing about the MySQL Utilities, and I will be posting links to each individual blog on this page. If you haven&#8217;t heard of the MySQL Utilities (from the introduction to MySQL Utilities page): &#8220;MySQL Utilities is a package of utilities that are used for maintenance [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=728&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Over the next few months, I am going to be writing about the <a href="http://dev.mysql.com/doc/workbench/en/index.html">MySQL Utilities</a>, and I will be posting links to each individual blog on this page.  </p>
<p>If you haven&#8217;t heard of the <a href="http://dev.mysql.com/doc/workbench/en/index.html">MySQL Utilities</a> <i>(from the <a href="http://dev.mysql.com/doc/workbench/en/mysql-utils-intro-intro.html">introduction</a> to MySQL Utilities page)</i>:</p>
<p>&#8220;MySQL Utilities is a package of utilities that are used for maintenance and administration of MySQL servers. These utilities encapsulate a set of primitive commands, and bundles them so they can be used to perform macro operations with a single command. MySQL Utilities may be installed via MySQL Workbench, or as a standalone package.  The utilities are written in Python, available under the GPLv2 license, and are extendable using the supplied library. They are designed to work with Python 2.x greater than 2.6.&#8221;</p>
<p>If you don&#8217;t have Workbench, you may download the MySQL Utility scripts from <a href="https://launchpad.net/mysql-utilities/" />launchpad.net</a>.  You will also need to install <a href="http://www.python.org/">Python</a> and to make sure that your execution <a href="http://en.wikipedia.org/wiki/PATH_(variable)">$PATH&#8217;s</a> are set correctly.</p>
<p>The MySQL Utilities are maintained by Chuck Bell.  You may find more information about MySQL Utilities on his <a href="http://drcharlesbell.blogspot.com/" />web site.</a>.</p>
<p>To start the MySQL Utilities, from within MySQL Workbench, simply click on the &#8220;MySQL Utilities&#8221; icon located in the top right area of the home window.
<p><img width="600" src="http://scriptingmysql.com/scriptingmysql/start_mysql_utilities1.png">
<p>Or, from the MySQL Workbench Plugins menu, select &#8220;Start Shell for MySQL Utilities&#8221;.
<p><img src="http://scriptingmysql.com/scriptingmysql/start_mysql_utilities2.png">
<p>When you open MySQL Utilities, you should be taken to a terminal window, with a list of all of the utilities that are available.
<p><img width="600" src="http://scriptingmysql.com/scriptingmysql/mysql_utilities_terminal_window.png">
<p>As long as you have your $PATH set correctly, you can just run the scripts from any terminal window and in cron jobs.</p>
<p>Here is a list of the available utilities, with a link to the manual page and a link to my blog about that page (if I have written a post about that utility).</p>
<table width="620">
<tr bgcolor="#FFFFEE">
<td><b>Blog Post Link</b></td>
<td><b>Script Name &amp; Man Page</b></td>
<td><b>Description</b></td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysql-utils-man-overview.html">MySQL Utilities Overview</td>
<td>Brief overview of command-line utilities</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysql-utils-man-mut.html">mut</a></td>
<td>MySQL Utilities Testing</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcompare.html">mysqldbcompare</td>
<td>Compare Two Databases and Identify Differences</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbcopy.html">mysqldbcopy</td>
<td>Copy Database Objects Between Servers</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbexport.html">mysqldbexport</td>
<td>Export Object Definitions or Data from a Database</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldbimport.html">mysqldbimport</td>
<td>Import Object Definitions or Data into a Database</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldiff.html">mysqldiff</td>
<td>Identify Differences Among Database Objects</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqldiskusage.html">mysqldiskusage</td>
<td>Show Database Disk Usage</td>
</tr>
<tr>
<td><a target="new" href="http://scriptingmysql.wordpress.com/2012/12/06/using-the-mysql-script-mysqlfailover-for-automatic-failover-with-mysql-5-6-gtid-replication/" />Blog</a></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlfailover.html">mysqlfailover</td>
<td>Automatic replication health monitoring and failover</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlindexcheck.html">mysqlindexcheck</td>
<td>Identify Potentially Redundant Table Indexes</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlmetagrep.html">mysqlmetagrep</td>
<td>Search Database Object Definitions</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlprocgrep.html">mysqlprocgrep</td>
<td>Search Server Process Lists</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlreplicate.html">mysqlreplicate</td>
<td>Set Up and Start Replication Between Two Servers</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlrpladmin.html">mysqlrpladmin</td>
<td>Administration utility for MySQL replication</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlrplcheck.html">mysqlrplcheck</td>
<td>Check Replication Prerequisites</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlrplshow.html">mysqlrplshow</td>
<td>Show Slaves for Master Server</td>
</tr>
<tr>
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlserverclone.html">mysqlserverclone</td>
<td>Clone Existing Server to Create New Server</td>
</tr>
<tr bgcolor="#FFFFEE">
<td></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqlserverinfo.html">mysqlserverinfo</td>
<td>Display Common Diagnostic Information from a Server</td>
</tr>
<tr>
<td><a target="new" href="http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-clone-mysql-users-with-mysqluserclone">Blog</a></td>
<td><a target="new" href="http://dev.mysql.com/doc/workbench/en/mysqluserclone.html">mysqluserclone</td>
<td>Clone Existing User to Create New User</td>
</tr>
</table>
<p>&nbsp;<br />
<hr width="100%">
<table width="100%">
<tr>
<td style="vertical-align:middle;"><img width="150" border="0" src="http://www.scriptingmysql.com/scriptingmysql/tony.jpg"></td>
<td style="vertical-align:top;">Tony Darnell is a Principal Sales Consultant for <a target="new" href="http://mysql.com/" />MySQL</a>, a division of <a target="new" href="http://oracle.com">Oracle</a>, Inc.  MySQL is the world&#8217;s most popular open-source database program.  Tony may be reached at info [at] ScriptingMySQL.com and on <a target="new" href="http://www.linkedin.com/in/tonydarnell">LinkedIn</a>.
</td>
</tr>
</table>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/scriptingmysql.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/scriptingmysql.wordpress.com/728/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=scriptingmysql.wordpress.com&#038;blog=25354808&#038;post=728&#038;subd=scriptingmysql&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://scriptingmysql.wordpress.com/2012/08/19/mysql-workbench-utilities-administer-mysql-with-python-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/37abb53c7b0fda756a698dc85bc7654c?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">tonydarnell</media:title>
		</media:content>

		<media:content url="http://scriptingmysql.com/scriptingmysql/start_mysql_utilities1.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/start_mysql_utilities2.png" medium="image" />

		<media:content url="http://scriptingmysql.com/scriptingmysql/mysql_utilities_terminal_window.png" medium="image" />

		<media:content url="http://www.scriptingmysql.com/scriptingmysql/tony.jpg" medium="image" />
	</item>
	</channel>
</rss>
