MySQL主从复制实验记录


1,MySQL主从复制原理
2,实验环境介绍
3,搭建步骤
4,测试结果


一,MySQL主从复制原理







在slave端会有两个线程负责同步,一个IO线程,负责将master中的bin log读取过来转换为
relay log;另一个是sql线程,根据relay log执行sql语句。
MySQL数据库复制操作大致可以分为三个步骤:
(1) 主服务器将数据的改变记录到二进制日志中(binary log)。
(2) 从服务器将主服务器的binary log events复制到自己的中继日志中(relay log)。
(3) 从服务器重放中继日志中的事件,将数据改变应用到自己的数据库上。
MySQL复制的基本过程如下:
(1) Slave上面的IO线程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)
之后的日志内容;
(2) Master接收到来自Slave的IO线程的请求后,通过负责复制的IO线程根据请求信息读取指定
日志指定位置之后的日志信息,返回给Slave端的IO线程。返回信息中除了日志所包含的信息外,
还包含本次返回的信息在Master端的Binary Log文件的名称以及在Binary Log中的位置;
(3) Slave的IO线程接收到信息后,将接受到的日志内容依次写入到Slave端的Relay Log文件
(mysql-relay-bin.XXXXXX)的最末端,并将读取到的Master端的bin-log的文件名称和位置记录
到master-info文件中,以便下一次读取的时候能够清楚的告诉Master"我需要从某个bin-log"
的哪个位置开始往后的日志内容,请发给我。"
(4) Slave的SQL线程检测到Relay Log中新增加了内容后,会马上解析该Log文件中的内容成为
在Master端真实执行时候的那些可执行的Query语句,并在自身执行这些Query。这样,实际上就
是在Master端和Slave端执行了同样的Query,所以两端的数据是完全一样的。

二 实验环境介绍

h30119.bj.cn  192.168.30.119 (主库)


h30120.bj.cn  192.168.30.120 (从库)




grant all privileges on *.* to 'u1'@'192.168.30.%' identified by 'u1';


flush privileges;







上述语句是为了本实验操作方便,特意创建的用户。





额外的准备工作,为主库准备数据
参考资料:http://blog.chinaunix.net/uid-7692530-id-2567540.html
mysql---为测试数据库填充大量数据 
首先创建一个库
CREATE DATABASE db119;
USE db119;
创建两个表 - innodb的和myisam的
USE db119;
CREATE TABLE `tabl_myisam` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT NULL,
`post` TEXT,
PRIMARY KEY (`id`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;


USE db119;
CREATE TABLE `tab2_innodb` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) DEFAULT NULL,
`post` TEXT,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


这样就创建了两个表。


创建可插入数据的 存储过程


DELIMITER $$
CREATE PROCEDURE insert_tabl_myisam(IN item INT)
BEGIN
DECLARE counter INT;
SET counter = item;
WHILE counter >= 1 DO
INSERT INTO tabl_myisam VALUES(counter,CONCAT('mysqlsystems.com',counter),REPEAT('bla',10));
SET counter = counter - 1;
END WHILE;
END
$$
DELIMITER ;


--
DELIMITER $$
create procedure insert_tab2_innodb(in item int)
begin
declare counter int;
set counter = item;
while counter >= 1 do
insert into tab2_innodb values(counter,concat('mysqlsystems.com',counter),repeat('bla',10));
set counter = counter - 1;
end while;
end
$$
DELIMITER ;
--测试数据,执行
你要插入1000条到innodb?         call insert_tab2_innodb(1000);
插入1000000到myisam?           call insert_tabl_myisam(1000000);
记得再一次插入新的内容时,要清空你的表,delete from ,或者truncate 。
这里我执行了以下语句。
CALL insert_tab2_innodb(10000);
CALL insert_tabl_myisam(5000);
select count(*) from tab2_innodb;
select count(*) from tabl_myisam;
好了,数据已经准备完毕了。

三,搭建步骤

在192.168.30.119(主库上操作),创建用户。


GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'repl'@'192.168.30.%' IDENTIFIED BY 'repl';


flush privileges; 




--然后导出主库上的数据


flush tables with read lock;  


[mysql@h30119 ~]$ mysqldump -uroot -p -P 3306 -F --hex-blob --master-data=2  --single-transaction -q \


 -R --dump-date  --triggers --routines --databases db119>/home/mysql/db119_bak.sql


[mysql@h30119 ~]$ scp db119_bak.sql mysql@192.168.30.120:/home/mysql/




因为自己的环境,故需要修改如下信息


[mysql@h30120 var]$ cat /home/mysql/mysql120_3307/var/auto.cnf 


[auto]


server-uuid=891e19b6-9980-11e4-b127-525400ddc84b 


这里的uuid必须和主库上的不一样。


接下来导入数据。


source /home/mysql/db119_bak.sql;


[mysql@h30120 ~]$ mysql -u repl -p -h 192.168.30.119 -P 3306 --测试是否成功连接到主库上


主库上最主要的两个参数


[mysql@h30119 ~]$ vi /home/mysql/mysql119_3306/etc/my.cnf 


[mysqld]


server-id       = 20154040


log-bin=mysql-bin


replicate-wild-ignore-table     = mysql.%  --忽略复制该库下面的所有表


replicate-wild-ignore-table     = test.%   --忽略复制该库下面的所有表


root@localhost:mysql.sock  20:12:  [(none)]>show master status;


+------------------+----------+--------------+------------------+-------------------+


| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |


+------------------+----------+--------------+------------------+-------------------+


| mysql-bin.000004 |      120 |              |                  |                   |


+------------------+----------+--------------+------------------+-------------------+


1 row in set (0.00 sec)




然后在192.168.30.120(从库上执行)


CHANGE MASTER TO


  MASTER_HOST='192.168.30.119',


  MASTER_USER='repl',


  MASTER_PASSWORD='repl',


  MASTER_PORT=3306,


  MASTER_LOG_FILE='mysql-bin.000004',


  MASTER_LOG_POS=120,


  MASTER_CONNECT_RETRY=10;


root@localhost:mysql.sock  20:17:  [(none)]>CHANGE MASTER TO


    ->   MASTER_HOST='192.168.30.119',


    ->   MASTER_USER='repl',


    ->   MASTER_PASSWORD='repl',


    ->   MASTER_PORT=3306,


    ->   MASTER_LOG_FILE='mysql-bin.000004',


    ->   MASTER_LOG_POS=120,


    ->   MASTER_CONNECT_RETRY=10;


Query OK, 0 rows affected, 2 warnings (0.21 sec)




root@localhost:mysql.sock  20:18:  [(none)]>start slave;


Query OK, 0 rows affected (0.04 sec)




root@localhost:mysql.sock  20:19:  [(none)]>show slave status\G;


*************************** 1. row ***************************


               Slave_IO_State: Waiting for master to send event


                  Master_Host: 192.168.30.119


                  Master_User: repl


                  Master_Port: 3306


                Connect_Retry: 10


              Master_Log_File: mysql-bin.000004


          Read_Master_Log_Pos: 5036191


               Relay_Log_File: relay-log.000002


                Relay_Log_Pos: 5036354


        Relay_Master_Log_File: mysql-bin.000004


             Slave_IO_Running: Yes


            Slave_SQL_Running: Yes




四,测试同步

在主库上操作:


root@localhost:mysql.sock  20:16:  [db119]>update  tab2_innodb set id=id+10000;


Query OK, 10000 rows affected (0.26 sec)


Rows matched: 10000  Changed: 10000  Warnings: 0




root@localhost:mysql.sock  20:16:  [db119]>update  tabl_myisam set id=id+10000;


Query OK, 5000 rows affected (0.06 sec)


Rows matched: 5000  Changed: 5000  Warnings: 0




root@localhost:mysql.sock  20:17:  [db119]>CALL insert_tab2_innodb(10000);


CALL insert_tabl_myisam(5000);Query OK, 1 row affected (0.56 sec)




root@localhost:mysql.sock  20:17:  [db119]>CALL insert_tabl_myisam(5000);


Query OK, 1 row affected (0.28 sec)






---主库上查询


MySQL_119>select count(*) from tabl_myisam;


+----------+


| count(*) |


+----------+


|    15000 |


+----------+


1 row in set (0.00 sec)




MySQL_119>select count(*) from tab2_innodb;


+----------+


| count(*) |


+----------+


|    30000 |


+----------+


1 row in set (0.01 sec)




--从裤上查询


MySQL_120>select count(*) from tabl_myisam;


+----------+


| count(*) |


+----------+


|    15000 |


+----------+


1 row in set (0.00 sec)




MySQL_120>select count(*) from tab2_innodb;


+----------+


| count(*) |


+----------+


|    30000 |


+----------+


1 row in set (0.01 sec)




MySQL_120>


经测试,两边数据一致。