MySQL配置Master-Slave¶
简单的MySQL主从架构的建立和维护。
三步实现Master-Slave¶
最简单的Master-Slave只需要三步(前提是Master和Slave上的数据完全一样)。
配置一个Master服务器
开启binlog,设置一个唯一的服务器ID。配置文件
[mysqld] # ...... log-bin = master-bin log-bin-index = master-bin.index server-id = 1
创建用于复制的帐户
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.%.%' IDENTIFIED BY 'replication'
配置一个Slave服务器
配置文件
[mysqld] # ...... server-id = 2 relay-log-index = slave-relay-bin.index relay-log = slave-relay-bin
将Slave连接到Master
在命令配置
CHANGE MASTER TO MASTER_HOST='master', MASTER_PORT=3306, MASTER_USER='replication', MASTER_PASSWORD='replication'; START SLAVE;
Data snapshot¶
如果Master库中已经有数据,建立一个Slave库则需要一份Master库数据的snapshot。对 master库进行snapshot有多种方法:
方法一 mysqldump¶
使用mysqldump可以将Master中的数据完整的导出,并在Slave上恢复,操作简单。但是此方法存在严重的问题,因为mysqldump操作需要锁定数据的写操作,会导致数据库一定时间内无法写入数据,相关服务可能会受到影响。
刷新并锁定数据库写操作,防止再导出数据时数据库发生变化
-- 在终端1执行 FLUSH TABLES WITH READ LOCK;
记录Master上binlog的位置。如下面bin-log文件为: “mysql-bin.000015”,position为: “245”
-- 在终端2执行 SHOW MASTER STATUS; -- *************************** 1. row *************************** -- File: mysqld-bin.000015 -- Position: 245 -- Binlog_Do_DB: -- Binlog_Ignore_DB: -- 1 row in set (0.00 sec)
利用命令mysqldump导出Master上的数据,完成后解锁Master
mysqldump --all-databases; --host=master-1 > backup-2013xxxx.sql
UNLOCK TABLES;
在Slave上恢复Master的数据
mysql --host=slave-1 -u root -p < backup-2013xxxx.sql
方法二: 更简单的mysqldump¶
在slave库的服务器上运行:
mysqlpdump --all-databases --master-data | mysql
选项--master-data将会锁定所有表,不允许写操作;同时插入CHANGE MASTER TO语句;并在完成时释放锁。
Warning
如果你只同步一部分数据(mysqldump只dump了部分数据),需要在slave的配置 文件中指明(设置过滤器),
方法三:从Slave上克隆数据¶
如果本来就存在着一个Master-Slave关系,就可以方便的在不影响任何服务的情况下建立一个新的Slave——从Slave上复制数据至新的Slave。操作类似于从Master复制数据。
停止Slave并刷新锁定数据库
STOP SLAVE; SHOW SLAVE STATUS; -- *************************** 1. row *************************** -- Slave_IO_State: Waiting for master to send event -- Master_Host: 192.168.122.1 -- Master_User: replication -- Master_Port: 3306 -- Connect_Retry: 60 -- Master_Log_File: mysqld-bin.000015 -- Read_Master_Log_Pos: 245 -- Relay_Log_File: db-server-relay-bin.000015 -- Relay_Log_Pos: 530 -- Relay_Master_Log_File: mysqld-bin.000015 -- Slave_IO_Running: Yes -- Slave_SQL_Running: Yes -- Replicate_Do_DB: wiki -- ...... -- Exec_Master_Log_Pos: 245 -- Relay_Log_Space: 1113 -- Until_Condition: None -- Until_Log_File: -- Until_Log_Pos: 0 -- Master_SSL_Allowed: No -- 锁定数据库 FLUSH TABLES WITH READ LOCK;
记录在Slave上Master的bin-log执行到的位置。主要关注两个字段:“Relay_Master_Log_File”和“Exec_Master_Log_Pos”。
同方法一中复制Slave中的数据并在新的Slave上恢复。
将新的Slave连接到Master。其中“MASTER_LOG_FILE”和“MASTER_LOG_POS”的值为第二步所记录的值。
CHANGE MASTER TO MASTER_HOST='master', MASTER_PORT=3306, MASTER_USER='replication', MASTER_PASSWORD='replication', MASTER_LOG_FILE='mysql-bin.000015', MASTER_LOG_POS=245; START SLAVE;
方法四:使用Raw数据文件¶
如果数据库比较大,拷贝raw数据文件的方法比mysqldump更加有效。同时拷贝raw数据的方法与表所使用的引擎、缓存和日志方案都有关系。
如果master和slave的配置选项ft_stopword_file, ft_min_word_len, ft_max_word_len值不相同,或者需要拷贝的表使用全文索引,不能使用这种方法。
另外,可以排除一些文件: * mysql库相关的文件 * master信息文件 * binlog文件 * relay log文件
为了保证数据的一致性,在拷贝raw数据文件时,按下面的步骤操作:
- 在一个终端获取一个读锁,并查看master的状态
- 在另一个终端关闭master服务mysqladmin shutdown
- 拷贝MySQL数据文件
- 重启master服务
如果使用的是InnoDB引擎,可以在不停止服务的情形下创建一个snapshot
- 在一个终端获取一个读锁,并查看master的状态
- 拷贝MySQL数据文件
- 重启master服务
故障说明¶
运行主从同步时,出现如下情况:
Slave_IO_Running: Connecting Slave_SQL_Running: Yes
从网上查询了一下原因,大家提到的有:
- log_file_pos不正确
- 同步帐户设置不正确
- 网络问题
全都试着重新完成一遍,结果没有解决,看看日志发现是“binlog找不到”,再回头看看主库,binlog被清除了。
一句话:出错的原因可能有千百种,看日志才是王道。
如果master/slave的server-id没有设置,master和slave将无法建立连接; 如果master/slave的server-id一样,命令行会提示出错。
参考资料¶
- 高可用的MySQL——构建健壮的数据中心