第25章 MySQL replication(主从)配置

学习Linux请加微信:lishiming2009

跟阿铭学Linux邀请函 (http://www.aminglinux.com),猿课已上线,请加微信lishiming2009索要配套视频教程。

MySQL Replication 又叫做AB复制或者主从复制。它主要用于MySQL的时时备份或者读写分离。在配置之前先做一下准备工作,配置两台mysql服务器,或者在一台服务器上配置两个端口也可以。阿铭本章的实验中就是在一台服务器上跑了两个mysql。

配置mysql服务

详细步骤,请参考(http://study.lishiming.net/chapter17.html#mysql), 阿铭只把简单步骤写一下。

根据阿铭提供的地址,假如你已经搭建好了一个mysql,跑的是3306端口,下面阿铭再搭建一个3307端口的mysql:

[root@localhost ~]# cd /usr/local/
[root@localhost local]# cp -r mysql mysql_2
[root@localhost local]# cd mysql_2
[root@localhost mysql_2]# ./scripts/mysql_install_db --user=mysql --datadir=/data/mysql2

最后一步是初始化数据库目录,如果出现两个 “OK” 并且生成/data/mysql2目录才正确,否则请仔细查看错误信息,如果不能解决请到阿铭论坛(http://www.aminglinux.com/bbs/forum-40-1.html)发帖咨询阿铭。拷贝配置文件到mysql_2下,并修改相关项目:

[root@localhost mysql_2]# cp /etc/my.cnf  ./my.cnf
[root@localhost mysql_2]# vim my.cnf

其中:

port          = 3306

改为:

port          = 3307

把:

socket        = /tmp/mysql.sock

改为:

socket        = /tmp/mysql2.sock

在这一行的下面再加一行:

datadir         = /data/mysql2

保存后就可以启动它了:

[root@localhost mysql_2]# cd bin/
[root@localhost bin]# ./mysqld_safe --defaults-file=../my.cnf --user=mysql &

如果以后想开机启动,就把它加入/etc/rc.d/rc.local文件中:

echo "./mysqld_safe --defaults-file=../my.cnf --user=mysql &" >>/etc/rc.d/rc.local

到此,目前阿铭已经在一个Linux上启动了两个mysql:

[root@localhost ~]# netstat -lnp |grep mysqld
tcp        0      0 0.0.0.0:3306                0.0.0.0:*    LISTEN      3169/mysqld
tcp        0      0 0.0.0.0:3307                0.0.0.0:*    LISTEN      3037/mysqld
unix  2      [ ACC ]     STREAM     LISTENING     29027  3037/mysqld    /tmp/mysql2.sock
unix  2      [ ACC ]     STREAM     LISTENING     29155  3169/mysqld    /tmp/mysql.sock

配置replication

阿铭打算把3307端口的mysql作为主(master),而把3306的mysql作为从(slave). 为了让实验更加像生产环境,所以阿铭先在master上创建一个库db1,并且把mysql的库数据复制给它:

[root@localhost bin]# mysql -uroot -S /tmp/mysql2.sock

mysql> create database db1;
Query OK, 1 row affected (0.01 sec)

mysql> quit
Bye

也许你对阿铭使用的这个命令有点疑问,-S 后面指定mysql的socket文件路径,这也是登陆mysql的一种方法,因为在一台服务器上跑了两个mysql端口,所以,只能用 -S 这样的方法来区分。首先创建了db1库,然后把mysql库的数据复制给它:

mysqldump -uroot -S /tmp/mysql2.sock mysql > 123.sql
mysql -uroot -S /tmp/mysql2.sock db1 < 123.sql

1. 设置master

修改配置文件:

vim /usr/local/mysql_2/my.cnf

在[mysqld]部分查看是否有以下内容,如果没有则添加:

server-id=1
log-bin=mysql-bin

除了这两行是必须的外,还有两个参数,你可以选择性的使用:

binlog-do-db=databasename1,databasename2
binlog-ignore-db=databasename1,databasename2

binlog-do-db=需要复制的数据库名,多个数据库名,使用逗号分隔。binlog-ignore-db=不需要复制的数据库库名,多个数据库名,使用逗号分隔。这两个参数其实用一个就可以啦。

如果修改过配置文件需要重启mysqld服务,否则不需要重启:

[root@localhost ~]# pid=`ps uax |grep mysql2.sock |grep -v grep |awk '{print $2}'`
[root@localhost ~]# kill -0 $pid; sleep 3; kill $pid
[root@localhost ~]# cd /usr/local/mysql_2/bin/
[root@localhost bin]# ./mysqld_safe --defaults-file=../my.cnf --user=mysql &

由于阿铭没有编写启动脚本,所以3307端口的mysql重启有点麻烦。

设置mysql数据库的root访问密码:

mysqladmin -u root -S /tmp/mysql2.sock password '123456'
mysql -u root -S /tmp/mysql2.sock -p'123456'

mysql> grant replication slave on *.* to 'repl'@'127.0.0.1' identified by '123123';
//这里的repl是为slave端设置的访问master端mysql数据的用户,密码为123123,这里的127.0.0.1为slave的ip(因为阿铭配置的master和slave都在本机)。
mysql> flush tables with read lock;  //锁定数据库,此时不允许更改任何数据
mysql> show master status;  //查看状态,这些数据是要记录的,一会要在slave端用到
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000006 |   474952 |              |                  |
+------------------+----------+--------------+------------------+

2. 设置slave

先修改slave的配置文件my.cnf:

vim /etc/my.cnf

找到 “server-id = 1” 这一行,删除掉或者改为 “server-id = 2” 总之不能让这个id和master一样,否则会报错。另外在从上,你也可以选择性的增加如下两行,对应于主上增加的两行:

replicate-do-db=databasename1,databasename2
replicate-ignore-db=databasename1,databasename2

改完后,重启slave:

service mysqld restart

拷贝master上的db1库的数据到slave上,因为master和slave都在一台服务器上,所以操作起来简单了很多,如果是不同的机器,可能就需要远程拷贝了,希望你注意这一点:

[root@localhost ~]# mysqldump -uroot -S /tmp/mysql2.sock -p123456 db1 > db1.sql
[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock -pyourpassword -e "create database db1"
[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock -pyourpassword db1 < db1.sql

第二行中,阿铭使用了一个-e选项,这个选项阿铭在之前的章节中并没有介绍,它用来把mysql的命令写到shell中,这样可以方便把mysql操作写进脚本中,它的格式就是 -e "commond" 它很实用,阿铭用的也是蛮多的,所以请你熟记它。把数据拷贝过来后,就需要在slave上配置主从了:

[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock -pyourpassword
mysql> slave stop;
mysql> change master to master_host='127.0.0.1', master_port=3307,
master_user='repl', master_password='123123',
master_log_file='mysql-bin.000006', master_log_pos=474952;
mysql> slave start;

相信聪明的你一定可以看懂上面的各个参数分别表示什么含义,其中master_log_file和master_log_pos是在上面使用 show master status 查到的数据。执行完这一步后,需要在master上执行一步:

mysql -uroot -S /tmp/mysql2.sock -p123456 -e "unlock tables"

然后查看slave的状态:

mysql> show slave status\G;

确认以下两项参数都为yes:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

测试主从

在master上执行如下命令:

[root@localhost ~]# mysql -uroot -S /tmp/mysql2.sock -p123456 -e "use db1;
select count(*) from db"
+----------+
| count(*) |
+----------+
|        2 |
+----------+
[root@localhost ~]# mysql -uroot -S /tmp/mysql2.sock -p123456 -e "use db1;
truncate table db"
[root@localhost ~]# mysql -uroot -S /tmp/mysql2.sock -p123456 -e "use db1;
select count(*) from db"
+----------+
| count(*) |
+----------+
|        0 |
+----------+

这样清空了db1.db表的数据,下面查看slave上的该表数据:

[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock -pyourpassword -e "use db1; select count(*) from db"
+----------+
| count(*) |
+----------+
|        0 |
+----------+

slave上的该表也被清空了。这样好像不太明显,不妨继续把db表删除试试:

[root@localhost ~]# mysql -uroot -S /tmp/mysql2.sock -p123456 -e "use db1; drop table db"
[root@localhost ~]# mysql -uroot -S /tmp/mysql.sock -pyourpassword -e "use db1; select count(*) from db"
ERROR 1146 (42S02) at line 1: Table 'db1.db' doesn't exist

这次很明显了。

主从配置起来很简单,但是这种机制也是非常脆弱的,一旦我们不小心在从上写了数据,那么主从也就被破坏了。另外如果重启master,务必要先把slave停掉,也就是说需要在slave上去执行 slave stop 命令,然后再去重启master的mysql服务,否则很有可能就会中断了。当然重启完后,还需要把slave给开启 slave start.

阿铭建议你最好再扩展学习一下: http://www.aminglinux.com/bbs/thread-5449-1-1.html

教程答疑: 请移步这里.

欢迎你加入 阿铭学院 和阿铭一起学习Linux,让阿铭成为你Linux生涯中永远的朋友吧!