This example
% /usr/local/mysql/bin/mysqladmin -uroot -pg00r002b shutdown 020821 23:40:49 mysqld ended.
You'll use the same table as in the previous example. On the master, delete it and reset the binary logs to start afresh before inserting some records, as
mysql> DELETE FROM replication_table; Query OK, 4 rows affected (0.09 sec) mysql> RESET MASTER; Query OK, 0 rows affected (0.02 sec) mysql> INSERT INTO replication_table (f1,f2) VALUES(1,'first'); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO replication_table (f1,f2) VALUES(2,'second'); Query OK, 1 row affected (0.01 sec)
Now copy this data to the slave, and check the offset on the master's binary log. Make sure no new data was written to the master after you
mysql> SHOW MASTER STATUS; +-----------+----------+--------------+------------------+ File Position Binlog_do_db Binlog_ignore_db +-----------+----------+--------------+------------------+ g-bin.001 280 +-----------+----------+--------------+------------------+ 1 row in set (0.00 sec)
Now, on the slave, perform the same options as in the previous example—that is, copy the data, set the configuration options (with the following change), delete the
master.
skip-slave-start
You don't want to start the slave replicating until you have set it to begin at the right point. Now add some more records to the master:
mysql> INSERT INTO replication_table (f1,f2) VALUES(3,'third'); Query OK, 1 row affected (0.01 sec) mysql> INSERT INTO replication_table (f1,f2) VALUES(4,'fourth'); Query OK, 1 row affected (0.01 sec)
Now, on the slave, you'll need to tell it to start with the correct binary log file and the correct offset. To do this, set the
MASTER_LOG_FILE
to
g-bin.001
(or whatever was shown when you ran
SHOW
MASTER
STATUS
), and set the
MASTER_LOG_POS
to 280 (or whatever is
mysql> CHANGE MASTER TO MASTER_LOG_FILE='g-bin.001', MASTER_LOG_POS=280; Query OK, 0 rows affected (0.00 sec) mysql> SLAVE START; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM replication_table; +------+--------+ f1 f2 +------+--------+ 1 first 2 second 3 third 4 fourth +------+--------+ 4 rows in set (0.01 sec)
When using replication, removing binary logs is risky because a slave may not yet have finished with one of the logs you plan to remove.
For this example you'll need to delete the data and reset the master, to start from a clean slate, and then add some data:
mysql> DELETE FROM replication_table; mysql> RESET MASTER; mysql> INSERT INTO replication_table (f1,f2) VALUES(1,'first'); mysql> INSERT INTO replication_table (f1,f2) VALUES(2,'second'); mysql> INSERT INTO replication_table (f1,f2) VALUES(3,'third');
Copy this data onto a clean slave (if you've run previous examples on the slave server, make sure you delete the
master.
Now flush the logs on the master, simulating a server that's been running a while:
mysql> FLUSH LOGS; mysql> FLUSH LOGS;
Now, when you look at the master status, you'll see that the server is already onto its third binary log:
mysql> SHOW MASTER STATUS; +-----------+----------+--------------+------------------+ File Position Binlog_do_db Binlog_ignore_db +-----------+----------+--------------+------------------+ g-bin.003 4 +-----------+----------+--------------+------------------+ 1 row in set (0.00 sec)
Now start the slave, and start it replicating from the correct point:
mysql> CHANGE MASTER TO MASTER_LOG_FILE='g-bin.003',MASTER_LOG_POS=4; Query OK, 0 rows affected (0.01 sec) mysql> SLAVE START; Query OK, 0 rows affected (0.00 sec)
The slave will now start from the correct log on the master. You still have two other binary logs on the master server, taking up space, and you'll need to start maintaining the log files to ensure they don't get out of hand. You may feel tempted to delete logs one and two, but you cannot safely do this if there is still the possibility that slaves may need to make use of them.
To check this, you'll need to check the slave status for each slave. In this case, there's only one:
mysql> SHOW SLAVE STATUS; +---------------+------------------+-------------+---------------+----- ---------------+---------------------+--------------------------+------ ---------+-----------------------+------------------+------------------ -+-----------------+---------------------+------------+------------+--- -----------+---------------------+-----------------+ Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +---------------+------------------+-------------+---------------+----- ---------------+---------------------+--------------------------+------ ---------+-----------------------+------------------+------------------ -+-----------------+---------------------+------------+------------+--- -----------+---------------------+-----------------+ 192.168.4.100 replication_user 3306 60 g-bin.003 4 s-bin.003 830 g-bin.003 Yes Yes replication_db 0 0 4 1885
You can see that the slave is using
g-bin.003
and is up-to-date (position 4). If all slaves are
up-to-date, you can safely remove binary logs 1 and 2 from the master, with the
PURGE
MASTER
LOGS
statement, as
mysql> PURGE MASTER LOGS TO "g-bin.003"; Query OK, 0 rows affected (0.00 sec)
If you did a listing in the data directory (or wherever you've specified the binary logs to be), you'll see that the two earlier ones have been removed. This statement will fail if an active slave is attempting to read a log you're trying to delete, giving the following error:
mysql> PURGE MASTER LOGS TO "g-bin.003"; ERROR: A purgeable log is in use, will not purge
If slave is not connected, and you purge a binary log that has not yet been used, that slave will be unable to continue replicating. At some stage this process may be automated, but for now you'll have to check each slave manually to see its position. Let's see what would happen if you didn't check. First, stop the slave:
mysql> SLAVE STOP; Query OK, 0 rows affected (0.00 sec)
Now, on the master, flush the logs once more, add a new record, and then purge the binary logs:
mysql> FLUSH LOGS; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO replication_table (f1,f2) VALUES(4,'fourth'); Query OK, 1 row affected (0.00 sec) mysql> FLUSH LOGS; Query OK, 0 rows affected (0.00 sec) mysql> SHOW MASTER STATUS; +-----------+----------+--------------+------------------+ File Position Binlog_do_db Binlog_ignore_db +-----------+----------+--------------+------------------+ g-bin.005 4 +-----------+----------+--------------+------------------+ 1 row in set (0.00 sec) mysql> PURGE MASTER LOGS TO "g-bin.005"; Query OK, 0 rows affected (0.02 sec)
Now, if you restart the slave, it will not replicate, as it's looking for a nonexistent binary log:
mysql> SLAVE START; Query OK, 0 rows affected (0.00 sec)
The problem now is that the most recent
INSERT
statement on the master does not appear in a log
mysql> INSERT INTO replication_table (f1,f2) VALUES(4,'fourth'); Query OK, 1 row affected (0.00 sec) mysql> CHANGE MASTER TO MASTER_LOG_FILE='g-bin.005',MASTER_LOG_POS=4; Query OK, 0 rows affected (0.01 sec)
Now, if you add another record to the master:
mysql> INSERT INTO replication_table (f1,f2) VALUES(5,'fifth'); Query OK, 1 row affected (0.00 sec)
it will be smoothly replicated onto the slave:
mysql> SELECT * FROM replication_table; +------+--------+ f1 f2 +------+--------+ 1 first 2 second 3 third 4 fourth 5 fifth +------+--------+ 5 rows in set (0.00 sec)
This example