{"id":1275,"date":"2012-07-31T15:15:08","date_gmt":"2012-07-31T19:15:08","guid":{"rendered":"http:\/\/mossiso.com\/?p=1275"},"modified":"2014-09-22T14:09:13","modified_gmt":"2014-09-22T18:09:13","slug":"making-multiple-mysql-instances-on-one-server","status":"publish","type":"post","link":"https:\/\/mossiso.com\/2012\/07\/31\/making-multiple-mysql-instances-on-one-server\/","title":{"rendered":"Making Multiple MySQL Instances on One Server"},"content":{"rendered":"<p>I&#8217;m trying this new idea for backing up our production MySQL servers. I have a backup server that basically runs rdiff-backup in the morning across several servers, but then does nothing for the rest of the day. It&#8217;s a pretty decent machine, so I&#8217;d like to utilize some resources. Replicating a MySQL server is a good way to ensure High Availability in case of a failure. The backup server acts as a slave to the master (production) server. Basically, the slave is an exact copy of the master. They are two separate instances of MySQL server running on two physical servers. Whatever queries run on the master are sent to the slave so it can do the same. This way they are kept completely in sync. You could also have the slave take over for the master, should the master server happen to fail.<\/p>\n<figure id=\"attachment_1279\" aria-describedby=\"caption-attachment-1279\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1279 \" title=\"master-and-slave\" src=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave-300x125.png\" alt=\"\" width=\"300\" height=\"125\" srcset=\"https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave-300x125.png 300w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave-250x104.png 250w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave-150x62.png 150w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/master-and-slave.png 503w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1279\" class=\"wp-caption-text\">The slave is an ever updating duplicate of the master.<\/figcaption><\/figure>\n<p>The only problem I face with this set up, though, is that I have multiple production servers out there. So this only works if this backup server could be a slave for multiple machines.<\/p>\n<figure id=\"attachment_1283\" aria-describedby=\"caption-attachment-1283\" style=\"width: 248px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1283\" title=\"no-2-masters\" src=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters-248x300.png\" alt=\"\" width=\"248\" height=\"300\" srcset=\"https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters-248x300.png 248w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters-250x301.png 250w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters-124x150.png 124w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/no-2-masters.png 496w\" sizes=\"(max-width: 248px) 100vw, 248px\" \/><\/a><figcaption id=\"caption-attachment-1283\" class=\"wp-caption-text\">No slave can serve two masters.<\/figcaption><\/figure>\n<p>This is not possible, though, because, of course, <a href=\"https:\/\/www.lds.org\/scriptures\/nt\/matt\/6.24?lang=eng#23\" target=\"_blank\">no slave can serve two masters<\/a>. Fortunately, a server can have multiple instances of MySQL running on it! So, in a sense, we have a server with multiple MySQL instances, to which a master can replicate. More about that set up in an upcoming post.<\/p>\n<figure id=\"attachment_1281\" aria-describedby=\"caption-attachment-1281\" style=\"width: 242px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1281\" title=\"mm-slave\" src=\"http:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave-242x300.png\" alt=\"\" width=\"242\" height=\"300\" srcset=\"https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave-242x300.png 242w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave-250x309.png 250w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave-121x150.png 121w, https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/mm-slave.png 493w\" sizes=\"(max-width: 242px) 100vw, 242px\" \/><\/a><figcaption id=\"caption-attachment-1281\" class=\"wp-caption-text\">The slave has multiple instances of MySQL running.<\/figcaption><\/figure>\n<p>A how to on <a href=\"http:\/\/blog.mydream.com.hk\/howto\/linux\/mysql-multiple-instance-on-centos-howto\" target=\"_blank\">this blog<\/a>, shows how this can be done. I&#8217;ll replicate the process below.<\/p>\n<h2>STEPS TO MULTIPLE MYSQL MADNESS<\/h2>\n<h3>On the slave server<\/h3>\n<h4>Step 1. Install MySQL<\/h4>\n<p>We&#8217;ll be working with CentOS 5.8, but this could really apply for any OS. First we&#8217;ll need to install MySQL like normal.<\/p>\n<pre class=\"lang:bash decode:1 \" >yum install mysql mysql-server<\/pre>\n<p>There are plenty of good tutorials out there on how to install the specific version of MySQL you want on the specific OS you&#8217;re running.<\/p>\n<h4>Step 2. Set up the data area.<\/h4>\n<p>You&#8217;ll need to have a different folder for each of the MySQL instances, say <code>\/dbases\/master-a\/<\/code>, <code>\/dbases\/master-b\/<\/code>, and <code>\/dbases\/master-c\/<\/code>.<\/p>\n<pre class=\"lang:bash decode:1 \" >mkdir -p \/dbases\/{master-a,master-b,master-c}<\/pre>\n<h4>Step 3. Copy the default my.cnf file<\/h4>\n<p>This is the default MySQL config file, it may be named differently on other OSes.<\/p>\n<pre class=\"lang:bash decode:1 \" >cp \/etc\/my.cnf \/etc\/master-a.cnf; cp \/etc\/my.cnf \/etc\/master-b.cnf; cp \/etc\/my.cnf \/etc\/master-c.cnf<\/pre>\n<h4>Step 4. Edit the new MySQL config files.<\/h4>\n<p>For each new config file, you&#8217;ll need to specify some unique variables.<\/p>\n<pre class=\"lang:bash decode:1 \" >\r\n[mysqld]\r\nport=3307\r\ndatadir=\/dbases\/master-a\r\nsocket=\/dbases\/master-a\/mysql.sock\r\nuser=mysql\r\nserver_id=3307\r\nlog-bin=\/dbases\/master\/mysql-bin.log\r\n\r\n# Disabling symbolic-links is recommended to prevent assorted security risks;\r\n# to do so, uncomment this line:\r\nsymbolic-links=0\r\n\r\n[mysqld_safe]\r\nlog-error=\/dbases\/master-a\/mysqld.log\r\npid-file=\/dbases\/master-a\/mysqld.pid\r\n<\/pre>\n<p>The <code>port<\/code> option sets this MySQL instance on a different port than the default 3306. The <code>datadir<\/code>, <code>socket<\/code>, <code>log-bin<\/code>, <code>log-error<\/code>, and <code>pid-file<\/code> options make sure the necessary files are not using the default files.<\/p>\n<h4>Step 5. Create new init scripts.<\/h4>\n<p>The init script allows the server to start and stop the service at boot time, and allows for easy start up and shutdown (on CentOS\/RedHat, at least &#8211; with an easy <code>service mysqld start<\/code>).<\/p>\n<pre class=\"lang:bash decode:1 \" >cp \/etc\/init.d\/mysqld \/etc\/init.d\/mysqld-master-a<\/pre>\n<p>Just do one for now. We&#8217;ll copy the new one to create the others, then just do a quick search and replace in those files to change the master-a to master-b and master-c.<\/p>\n<h4>Step 6. Edit the init script<\/h4>\n<div style=\"border: 1px solid #ddd; margin: 10px; padding: 10px;\">\n<pre>#!\/bin\/bash\r\n#\r\n# mysqld        This shell script takes care of starting and stopping\r\n#               the MySQL subsystem (mysqld).\r\n#\r\n# chkconfig: - 64 36\r\n# description:  MySQL database server.\r\n# processname: mysqld\r\n# config: <span style=\"color: #3366ff;\">\/etc\/master-a.cnf<\/span>\r\n# pidfile: <span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld.pid<\/span>\r\n\r\n# Source function library.\r\n. \/etc\/rc.d\/init.d\/functions\r\n\r\n# Source networking configuration.\r\n. \/etc\/sysconfig\/network\r\n\r\nprog=\"MySQL\"\r\n\r\n# extract value of a MySQL option from config files\r\n# Usage: get_mysql_option SECTION VARNAME DEFAULT\r\n# result is returned in $result\r\n# We use my_print_defaults which prints all options from multiple files,\r\n# with the more specific ones later; hence take the last match.\r\nget_mysql_option(){\r\n        result=<code>\/usr\/bin\/my_print_defaults \"$1\" | sed -n \"s\/^--$2=\/\/p\" | tail -n 1<\/code>\r\n        if [ -z \"$result\" ]; then\r\n            # not found, use default\r\n            result=\"$3\"\r\n        fi\r\n}\r\n\r\nget_mysql_option mysqld datadir \"<span style=\"color: #3366ff;\">\/dbases\/master-a<\/span>\"\r\ndatadir=\"<span style=\"color: #3366ff;\">\/dbases\/master-a<\/span>\"\r\nget_mysql_option mysqld socket \"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysql.sock<\/span>\"\r\nsocketfile=\"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysql.sock<\/span>\"\r\nget_mysql_option mysqld_safe log-error \"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld.log<\/span>\"\r\nerrlogfile=\"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld.log<\/span>\"\r\nget_mysql_option mysqld_safe pid-file \"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld.pid<\/span>\"\r\nmypidfile=\"<span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld.pid<\/span>\"\r\n\r\n<span style=\"color: #3366ff;\">defaultfile=\"\/etc\/master-a.cnf\"<\/span>\r\n\r\nstart(){\r\n        touch \"$errlogfile\"\r\n        chown mysql:mysql \"$errlogfile\"\r\n        chmod 0640 \"$errlogfile\"\r\n        [ -x \/sbin\/restorecon ] &amp;&amp; \/sbin\/restorecon \"$errlogfile\"\r\n        if [ ! -d \"$datadir\/mysql\" ] ; then\r\n            action $\"Initializing MySQL database: \" \/usr\/bin\/mysql_install_db --datadir=\"$datadir\" --user=mysql\r\n            ret=$?\r\n            chown -R mysql:mysql \"$datadir\"\r\n            if [ $ret -ne 0 ] ; then\r\n                return $ret\r\n            fi\r\n        fi\r\n        chown mysql:mysql \"$datadir\"\r\n        chmod 0755 \"$datadir\"\r\n        # Pass all the options determined above, to ensure consistent behavior.\r\n        # In many cases mysqld_safe would arrive at the same conclusions anyway\r\n        # but we need to be sure.\r\n        \/usr\/bin\/mysqld_safe  <span style=\"color: #3366ff;\">--defaults-file=\"$defaultfile\"<\/span> --datadir=\"$datadir\" --socket=\"$socketfile\" \\\r\n                --log-error=\"$errlogfile\" --pid-file=\"$mypidfile\" \\\r\n                --user=mysql &gt;\/dev\/null 2&gt;&amp;1 &amp;\r\n        ret=$?\r\n        # Spin for a maximum of N seconds waiting for the server to come up.\r\n        # Rather than assuming we know a valid username, accept an \"access\r\n        # denied\" response as meaning the server is functioning.        \r\n        if [ $ret -eq 0 ]; then\r\n      \u00a0     STARTTIMEOUT=30\r\n            while [ $STARTTIMEOUT -gt 0 ]; do\r\n\u00a0               RESPONSE=<code>\/usr\/bin\/mysqladmin --socket=\"$socketfile\" --user=UNKNOWN_MYSQL_USER ping 2&gt;&amp;1<\/code> &amp;&amp; break\r\n                echo \"$RESPONSE\" | grep -q \"Access denied for user\" &amp;&amp; break\r\n                sleep 1\r\n                let STARTTIMEOUT=${STARTTIMEOUT}-1\r\n            done\r\n            if [ $STARTTIMEOUT -eq 0 ]; then\r\n                    echo \"Timeout error occurred trying to start MySQL Daemon.\"\r\n                    action $\"Starting $prog: \" \/bin\/false\r\n                    ret=1\r\n            else\r\n                    action $\"Starting $prog: \" \/bin\/true\r\n            fi\r\n        else\r\n            action $\"Starting $prog: \" \/bin\/false\r\n        fi\r\n        [ $ret -eq 0 ] &amp;&amp; touch <span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld<\/span>\r\n        return $ret\r\n}\r\n\r\nstop(){ \r\n        MYSQLPID=<code>cat \"$mypidfile\"  2&gt;\/dev\/null <\/code>\r\n        if [ -n \"$MYSQLPID\" ]; then\r\n            \/bin\/kill \"$MYSQLPID\" &gt;\/dev\/null 2&gt;&amp;1\r\n            ret=$?\r\n            if [ $ret -eq 0 ]; then\r\n                STOPTIMEOUT=60\r\n                while [ $STOPTIMEOUT -gt 0 ]; do\r\n                    \/bin\/kill -0 \"$MYSQLPID\" &gt;\/dev\/null 2&gt;&amp;1 || break\r\n                    sleep 1\r\n                    let STOPTIMEOUT=${STOPTIMEOUT}-1\r\n                done\r\n                if [ $STOPTIMEOUT -eq 0 ]; then\r\n                    echo \"Timeout error occurred trying to stop MySQL Daemon.\"\r\n                    ret=1\r\n                    action $\"Stopping $prog: \" \/bin\/false\r\n                else\r\n                    rm -f <span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld<\/span>\r\n                    rm -f \"$socketfile\"\r\n                    action $\"Stopping $prog: \" \/bin\/true\r\n                fi\r\n            else\r\n                action $\"Stopping $prog: \" \/bin\/false\r\n            fi\r\n        else\r\n            ret=1\r\n            action $\"Stopping $prog: \" \/bin\/false\r\n        fi\r\n        return $ret\r\n}\r\n\r\nrestart(){\r\n    stop\r\n    start\r\n}\r\n\r\ncondrestart(){\r\n    [ -e <span style=\"color: #3366ff;\">\/dbases\/master-a\/mysqld<\/span> ] &amp;&amp; restart || :\r\n}\r\n\r\n# See how we were called.\r\ncase \"$1\" in\r\n  start)\r\n    start\r\n    ;;\r\n  stop)\r\n    stop\r\n    ;;\r\n  status)\r\n    status mysqld\r\n    ;;\r\n  restart)\r\n    restart\r\n    ;;\r\n  condrestart)\r\n    condrestart\r\n    ;;\r\n  *)\r\n    echo $\"Usage: $0 {start|stop|status|condrestart|restart}\"\r\n    exit 1\r\nesac\r\n\r\nexit $?<\/pre>\n<\/div>\n<h4>Step 7. Start each MySQL instance.<\/h4>\n<p>Now you can start each instance with the handy <code>service<\/code> command.<\/p>\n<pre class=\"lang:bash decode:1 \" >service mysqld-master-a start<\/pre>\n<h4>Step 8. Connect to MySQL instances.<\/h4>\n<p>Now, to connect to each MySQL instance, you&#8217;ll need to specify the port and\/or socket file.<\/p>\n<pre class=\"lang:bash decode:1 \" >mysql -P3307 --socket=\"\/dbases\/mysql-master-a\/mysql.sock\"<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;m trying this new idea for backing up our production MySQL servers. I have a backup server that basically runs rdiff-backup in the morning across several servers, but then does nothing for the rest of the day. It&#8217;s a pretty decent machine, so I&#8217;d like to utilize some resources. Replicating a MySQL server is a &hellip; <a href=\"https:\/\/mossiso.com\/2012\/07\/31\/making-multiple-mysql-instances-on-one-server\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">Making Multiple MySQL Instances on One Server<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1328,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[243,167],"tags":[242,63,179],"class_list":["post-1275","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howto","category-technical","tag-database-admin","tag-mysql","tag-servers"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/mossiso.com\/wp-content\/uploads\/2012\/07\/Conrad_von_Soest_Brillenapostel-seeing-double.jpg","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9wosP-kz","_links":{"self":[{"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/posts\/1275"}],"collection":[{"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/comments?post=1275"}],"version-history":[{"count":20,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/posts\/1275\/revisions"}],"predecessor-version":[{"id":1644,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/posts\/1275\/revisions\/1644"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/media\/1328"}],"wp:attachment":[{"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/media?parent=1275"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/categories?post=1275"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mossiso.com\/wp-json\/wp\/v2\/tags?post=1275"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}