{"id":697,"date":"2014-03-03T11:13:10","date_gmt":"2014-03-03T11:13:10","guid":{"rendered":"http:\/\/10sa.com\/sql_stories\/?p=697"},"modified":"2015-02-12T12:33:35","modified_gmt":"2015-02-12T12:33:35","slug":"the-copy-of-a-database-into-slave","status":"publish","type":"post","link":"http:\/\/10sa.com\/sql_stories\/?p=697","title":{"rendered":"The online copy of a database into slave."},"content":{"rendered":"<p>For some time I have been thinking that the export of a large database from master into slave w\/o a long breake in the production is not possible. In case you profit from LVM, it seems quite simple&#8230;<br \/>\nI tested the b\/m solution with my database which is 233G in size.<\/p>\n<p><strong>A simple description of the idea:<\/strong><br \/>\nStop slave as well as master. Create snapshot for the volume where database files are stored. Start master. Run the second instance of mysql on master server which has datadir=snapshot. Copy structure and data between the &#8220;master-snapshot&#8221; and the slave. Remove snapshot. Start slave, voila&#8230;<\/p>\n<p><strong>The receipe (database name is postfix) [neither simple nor fast]<\/strong><br \/>\n<em>1. Prepare replication<\/em><br \/>\n&#8211; Master: binlog-do-db=postfix (my.cnf) (restart is required)<br \/>\n&#8211; Slave: replicate-do-db=postfix, replicate-wild-do-table=postfix.% (restart is required)<br \/>\n&#8211; Slave: skip-slave-start (my.cnf)<\/p>\n<p><em>2.  Prepare second | snapshot instance of mysql database<\/em><br \/>\n&#8211; Master: configure new instance<br \/>\nCopy all files to new localization:<\/p>\n<pre lang=\"bash\">\r\ncp -rpv .\/mysql .\/mysql_snapshot\r\n<\/pre>\n<p>Change some variables for snapshot instance (.\/mysql_snapshot\/my.cnf)<\/p>\n<pre lang=\"bash\">\r\n# set alternative path | value\r\ndatadir=\/db_storage_ssd_snapshot\/data\r\nrelay-log-index=\/db_binlog\/slave2\/mysql-relay-bin.index\r\nrelay-log=\/db_binlog\/slave2\/mysql-relay-bin-db01\r\nsocket\t\t= \/tmp\/mysql-3309.sock\r\nport\t\t= 3309\r\npid-file=\/usr\/local\/services\/mysql_snapshot\/var\/mysql5.1.pid\r\nlog-bin=\/alternative_path\r\n\r\n# turn off\r\nslow_query_log=0\r\nskip-slave-start\r\n<\/pre>\n<p>Copy start script and make changes to the new start script (cp -pv \/etc\/init.d\/mysql.server \/etc\/init.d\/mysql.server.3309 ):<\/p>\n<pre lang=\"bash\">\r\n# change path\r\nlock_file_path=\"$lockdir\/mysql-3309\"\r\nbasedir=\/usr\/local\/services\/mysql_snapshot\r\nbindir=\/usr\/local\/services\/mysql_snapshot\/bin\r\nsbindir=\/usr\/local\/services\/mysql_snapshot\/bin\r\nlibexecdir=\/usr\/local\/services\/mysql_snapshot\/bin\r\n<\/pre>\n<p><em>3. Replication consistency<\/em><br \/>\nYou should ensure that replication is up to now. To do this I limit master to the special &#8220;backup&#8221; network.<br \/>\nYou can do this with some special IP, which is known only to your slave and run the master for a while to be sure<br \/>\nthat everything was replicated.<\/p>\n<pre>\r\nbind-address    = SOME.SPECIAL.IP.ADDRESS\r\n<\/pre>\n<p>Now you can restart master instance, ensure that slave is working.<br \/>\nWhen the position of master logs in replication does not change you can perform &#8220;stop slave;&#8221;.<br \/>\nBecause of the fact you set skip-slave-start you do not have to worry about that the replication<br \/>\nis active after slave restart. You can remove the bind-address and stop master instance.<br \/>\nThen you are ready to make LVM snapshot.<\/p>\n<p><em>4. Additional settings<\/em><\/p>\n<p>If you copy a large database I suggest set the following parameter:<\/p>\n<pre>\r\n# master\r\nmysql -S \/tmp\/mysql-3309.sock -uroot --password=xxx -e \"SET GLOBAL net_write_timeout=31536000;\"\r\n<\/pre>\n<p>Otherwise you can excpect the fallowing errors:<br \/>\nmysqldump: Error 2013: Lost connection to MySQL server during query when dumping table&#8230;<br \/>\n[However, I suggest to copy the largest tables as a separate processes. Not actual :)]   <\/p>\n<p>If your mysql server >= 5.6.7 set the following variable:<\/p>\n<pre lang=\"bash\">\r\ninnodb_read_only\r\n<\/pre>\n<p>In contrary (mysql < 5.6.7) I suggest to copy innodb files and logs to another localizations:\n\n\n<pre lang=\"bash\">\r\ncp -rpv \/db_storage_ssd_snapshot\/innodb \/db_storage\/\r\ninnodb_data_home_dir=\/db_storage\/innodb\r\ncp -rpv \/db_storage_ssd_snapshot\/innodb_log \/db_storage\/\r\ninnodb_log_group_home_dir=\/db_storage\/innodb_log\r\n<\/pre>\n<p><em>5. Prepare snapshot<\/em><br \/>\n&#8211; Master:<\/p>\n<pre lang=\"bash\">\r\nmkdir \/db_storage_ssd_snapshot\/ \r\nchown mysql:mysql \/db_storage_ssd_snapshot\/ \r\nlvcreate -L6G -s -n datasnapshot \/dev\/vg_s7v0_ssd\/data\r\nmount \/dev\/vg_s7v0_ssd\/datasnapshot \/db_storage_ssd_snapshot\/ -onouuid,rw\r\n<\/pre>\n<p><em>6. Perform export<\/em><br \/>\nStart the snapshot master instance.<\/p>\n<p>&#8211; Copy the table structure (master->slave):<\/p>\n<pre lang=\"bash\"> \r\nmysqldump \\\r\n-S \/tmp\/mysql-3309.sock -uroot --password=xxx \\\r\n--add-drop-table=0 --skip-triggers -d -i -Q -q postfix  \\\r\n| mysql -uroot --password=xxx -h 10.0.15.206 -D postfix\r\n<\/pre>\n<p>&#8211; Copy the data: <\/p>\n<pre lang=\"bash\">\r\nmysqldump -S \/tmp\/mysql-3309.sock -uroot --password=xxx \\\r\n-K --skip-tz-utc --triggers=0 -t -q postfix \\\r\n| mysql -uroot --password=xxx -h 10.0.15.206 -D postfix -f \r\n<\/pre>\n<p>&#8211; Complete the rest of the structure (triggers\/events\/procedures\/functions):<\/p>\n<pre lang=\"bash\">\r\nmysqldump -S \/tmp\/mysql-3309.sock -uroot --password=xxx \\\r\n--add-drop-table=0 --triggers --events --routines -d -i -Q -q postfix  \\\r\n| mysql -uroot --password=xxx -h 10.0.15.206 -D postfix -f\r\n<\/pre>\n<p>&#8211; Slave: my.cnf: replicate-do-db=postfix<br \/>\n&#8211; Slave: restart<\/p>\n<p>Now, your copy is ready. But you have to remember that after such massive operation performed on the slave, the statistics have to be rebuilt.<br \/>\nFor MyISAM engine you can use myisamchk with analyze option, i.e.:<\/p>\n<pre>\r\nmyisamchk -F --analyze \/db_storage\/data\/DATABASE\/*.MYI\r\n<\/pre>\n<p>For InnoDb engine you can use ALTER TABLE syntax (<a href=\"http:\/\/www.mysqlperformanceblog.com\/2008\/09\/03\/analyze-myisam-vs-innodb\/\" title=\"http:\/\/www.mysqlperformanceblog.com\">http:\/\/www.mysqlperformanceblog.com<\/a>), i.e.:<\/p>\n<pre>\r\nALTER TABLE `TABLE_NAME` TYPE=INNODB;\r\n<\/pre>\n<p>You might also need to change the status of the events into DISABLE ON SLAVE state.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For some time I have been thinking that the export of a large database from master into slave w\/o a long breake in the production is not possible. In case you profit from LVM, it seems quite simple&#8230; I tested the b\/m solution with my database which is 233G in size. A simple description of [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[7],"tags":[],"_links":{"self":[{"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/posts\/697"}],"collection":[{"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=697"}],"version-history":[{"count":64,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/posts\/697\/revisions"}],"predecessor-version":[{"id":977,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=\/wp\/v2\/posts\/697\/revisions\/977"}],"wp:attachment":[{"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=697"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=697"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/10sa.com\/sql_stories\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=697"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}