Under normal circumstances I would recommend setting up parallel mysqldumps ( Mysql backup strategies? ). However, it will be ineffective an against gigantic tables. Why ?
The recreation of a table in a mysqldump basically does this
- CREATE TABLE
- LOCK TABLE ... WRITE
- ALTER TABLE ... DISABLE KEYS (Applies to MyISAM only)
- multiple extended INSERT INTO
- ALTER TABLE ... ENABLE KEYS (Applies to MyISAM only)
- UNLOCK TABLES
A giant MyISAM table with either a lot of indexes or indexes with large columns becomes the instant bottleneck of the entire reload, even if you dump each individual table.
What can you do. Well, there is only one thing I would recommend. RSYNC !!! What possible advantage would rsync have?
ADVANTAGE #1 : There would be no processing of SQL. Your strict focus would be just copying (Drawback : Increased Disk I/O on Master during any given rsync)
ADVANTAGE #2 : There would be minimal downtime. You will need to shutdown mysql on the source server, but you can minimize how long that downtime can be.
Here is the basic idea: You could run rsync against /var/lib/mysql on a master and copy it to /var/lib/mysql on a slave. Of course, you need to run rsync several times. Before copying make sure you hose all binary logs and start from scratch.
NOTE : In case you don't have binary logging enabled : Before running anything, please make sure binary logs are written in /var/lib/mysql on both master and slave by having something like the following in /etc/my.cnf:
[mysqld]
log-bin=mysql-bin
The following script will shutdown mysql for the final rsync:
SOURCE_DATADIR=`mysql -u... -p... -ANe"SHOW VARIABLES LIKE 'datadir'" | awk '{print $2}'`
TARGET_DATADIR=${SOURCE_DATADIR}
mysql -u... -p... -e"RESET MASTER;"
RSYNCSTOTRY=7
cd ${SOURCE_DATADIR}
X=0
while [ ${X} -lt ${RSYNCSTOTRY} ]
do
X=`echo ${X}+1|bc`
rsync -r * slaveserver:${TARGET_DATADIR}/.
sleep 60
done
service mysql stop
rsync -r * slaveserver:${TARGET_DATADIR}/.
service mysql start
That's all for the rsync portion from the master. What about the Slave ???
Before you start mysql on the slave, you need to have the log file and log position from the master. The binary logs you copied have you need, particularly the last binary log. Here is how you get it on the slave:
cd /var/lib/mysql (or the datadir for your OS)
for X=`ls -l mysql-bin.0* | awk '{print $5}'`
do
LOGFIL=${X}
done
LOGPOS=`ls -l ${LOGFIL} | awk '{print $9}'`
echo "Master Log File ${LOGFIL} Position ${LOGPOS}"
You can trust these numbers because you copied them personally from the master. Now that you have the master log and position, you can start up mysql on the slave and setup replication using the log file and log position that was just reported.
CAVEAT #1 : I cannot make any promises on the the performance of this method. This is an option nonetheless.
CAVEAT #2 : Make sure you are copying to another server running the same version of MySQL (5.0 - > 5.0,5.1 - > 5.1,5.5 - > 5.5)
CAVEAT #3 : Make sure you are copying to the same DATADIR on Slave Server. Otherwise, set TARGET_DATADIR to the folder of your choice.