设为首页 收藏本站
查看: 542|回复: 0

[经验分享] MySQL主从多种架构部署及常见错误问题解析

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2017-2-15 09:08:27 | 显示全部楼层 |阅读模式
本文的主要内容有mysql复制原理,mysql一主多从、双主架构的示例解读,以及mysql在主从复制架构实践中的常见错误问题和解决方法。


一 mysql复制原理

1 原理解读

    mysql的复制(replication)是异步复制,即从一个mysql实列或端口(Master)复制到另一个mysql实列的或端口(slave);复制操作由3个进程完成,其中2个(SQL进程和I/O进程)在Slave上,另一个在Master上;要实现复制,必须打开Master端的二进制日志(log-bin),log-bin记录着整个数据对的操作信息,所有slave从master端获取该更新的日志,将其传送到本地并写到本地文件中,然后在读取本地文件内容执行日志中记录的更新操作;slave上已经完整拷贝master数据后,就可以连接到master上然后等待处理更新了。如果master当机或者slave连接断开,slave会定期尝试连接到master上直到能重连并且等待更新.重试的时间间隔由--master-connect-retry选项来控制,它的默认值是60秒。每个slave都记录了它关闭时的日志位置,msater也不知道有多少个slave连接上来或者哪个slave从什么时候开始更新。


2 数据同步实现步骤
    (1)mysql的同步功能由三个线程来实现,master上一个,slave上两个;

    (2)slave启动时,I/O线程连接到mater上,请求master发送二进制日志中的语句;

    (3)mater建立一个I/O线程,把日志内容发送到salve上;

    (4)slave上的I/O线程读取master上的binlog dump发送的语句,并且记录到中继日志relay logs;

    (5)slave开启SQL线程,读取中继日志,然后执行这些语句来更新数据

    slave上开启两个线程很有用:把读日志和执行日志分作两个线程任务处理,执行任务慢的话,读日志的任务不会跟着慢下来,而且读日志任务常常很快就完成,执行任务的sql线程往往需要很久。


二 一主多从架构部署示例及常见故障解决



    1 实验环境分配
        192.168.1.2    master.test.com   

        192.168.1.3    slave1.test.com

        192.168.1.4    slave2.test.com



    2 创建主从复制账号,限定账户在指定服务器登录

在master上创建用户
> grant replication salve on *.* to 'slave1'@'192.168.1.3' identified by '123456';
>grant replication salve on *.* to 'slave2'@'192.168.1.4' identified by '123456';
>flush privileges;


    3 备份已有数据,并复制数据到从节点(如果都是新数据库,可以略去此步)

>flush tables with read lock;
>show matser status;
+------------------+----------+--------------+------------------+
| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB
+------------------+----------+--------------+------------------+
| mysql-bin.000001|   106      | test               |         
+------------------+----------+--------------+------------------+
tar zcvf /tmp/mysql.tar.gz /var/lib/mysql/

rsync -zrvz --delete /tmp/mysql.tar.gz 192.168.1.3:/tmp/
rsync -zrvz --delete /tmp/mysql.tar.gz 192.168.1.4:/tmp/


    3 解锁
>unlock tables;

Query OK, 0 rows affected (0.00 sec)


    4 配置master服务器,修改mysql的主配置文件

vim /etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0


#### Master ####
server-id                 = 1
log-bin                   = mysql-bin
log-bin-index            = mysql-bin.index
relay-log                = mysql-relay
relay-log-index         = mysql-relay.index
expire-logs-days         = 10
max-binlog-size          = 100M
log-slave-updates        = 1
binlog-do-db             = test
replicate-do-db          = test
binlog-ignore-db         = mysql
replicate-ignore-db     = mysql

如果需要备份多个数据库,那么应该写多行
binlog-do-db=test1
binlog-do-db=test2
replicate-do-db=test1
replicate-do-db=test2
修改完成后重启mysql
/etc/init.d/mysqld restart


    5 配置slave服务器,修改两个从服务器的配置文件,并重启服务(注意修改server-id)

vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0

server-id = 2


    6 在两个slave上配置开启同步
> CHANGE MASTER TO
    ->   MASTER_HOST='192.168.1.2',
    ->   MASTER_USER='salve1', # 在104 上面改成slave2
    ->   MASTER_PASSWORD='123456',
    ->   MASTER_PORT=3306,
    ->   MASTER_LOG_FILE='mysql-bin.000001',
    ->   MASTER_LOG_POS=106,
    ->   MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW SLAVE STATUS\G;
            .............

            Slave_IO_Running: Yes
            Slave_SQL_Running: Yes


    7 查看主数据库的状态


>show matser status;        ##查看主数据库状态
+------------------+----------+--------------+------------------+
| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB
+------------------+----------+--------------+------------------+
| mysql-bin.000001|   106      | test               |         
+------------------+----------+--------------+------------------+
>show processlist;        ##查看复制进程状态


    8 测试验证

验证方法:在主数据库上创建数据库和在test下创建表,到从数据查看数据是否已经同步。
注意:新建的数据库不会同步,因为数据库的更新只设置了test数据库。



    9 故障排除

从服务器上show slave status\G;查看slave状态
Slave_IO_Running,为No,则说明IO_THREAD没有启动,请执行: start slave io_thread;
Slave_SQL_Running为No.则复制出错,查看Last_error字段排除错误后执行: start slave sql_thread;



三 双主互为主备部署解析


    1 实验环境准备      
        192.168.1.2    master1.test.com   
        192.168.1.3    master2.test.com

        和一主多从的步骤是一样的,只是同样的步骤执行2次而已


    2 双主配置
    在masterA上新建一个账户,用户masterB同步数据
masterA操作
> GRANT REPLICATION SLAVE ON *.* TO 'master'@'192.168.1..%' IDENTIFIED BY '123456';   
> FLUSH PRIVILEGES;
> FLUSH TABLES WITH READ LOCK;
mysqldump -uroot -p123456 --databases test >/tmp/testA.sql
scp /tmp/testA.sql 192.168.1.103:/tmp
> UNLOCK TABLES;

Query OK, 0 rows affected (0.00 sec)

masterB:上同样的建立复制到账户,并导入数据
mysql> GRANT REPLICATION SLAVE ON *.* TO 'master'@'192.168.1.%' IDENTIFIED BY '123456';mysql> FLUSH TABLES WITH READ LOCK;
mysqldump -uroot -p123456 --databases test >/tmp/testB.sql
scp /tmp/testB.sql 192.168.1.102:/tmp/
# 分别在master1 和 master2上分别导入对方的数据.但是存在一个问题: 因为存在主键冲突的情况,导出数据的时候,不要把主键给导出来了;如果是一方没有数据,那就直接导入数据就好了,不过也要跳过主键;

mysql -uroot -p123456 </tmp/testA.sql
mysql -uroot -p123456 </tmp/testB.sql


     3 修改master1和master2 的配置文件 ,只是server-id 不同

master1:的配置文件
vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
#datadir=/mysqldata
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0


#### Master ####

server-id                = 1
log-bin                  = mysql-bin
log-bin-index            = mysql-bin.index
relay-log                = mysql-relay
relay-log-index          = mysql-relay.index
expire-logs-days         = 10
max-binlog-size          = 100M
log-slave-updates        = 1
binlog-do-db             = test
replicate-do-db          = test
binlog-ignore-db         = mysql
replicate-ignore-db     = mysql
sync-binlog              = 1
auto-increment-increment = 2
auto-increment-offset   = 1



# master2:的配置文件

vim /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0


### Master ####

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
symbolic-links=0

server-id                = 2
log-bin                  = mysql-bin
log-bin-index            = mysql-bin.index
relay-log                = mysql-relay
relay-log-index          = mysql-relay.index
expire-logs-days         = 10
max-binlog-size          = 100M
log-slave-updates
skip-slave-start
slave-skip-errors        = all

binlog-do-db             = test
replicate-do-db          = test
binlog-ignore-db         = mysql
replicate-ignore-db     = mysql

sync-binlog             = 1
auto-increment-increment = 2
auto-increment-offset   = 2


    4 分别在master1和master2上获取File和Position位置

master1:
>flush tables with read lock;
>show matser status;
+------------------+----------+--------------+------------------+
| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB
+------------------+----------+--------------+------------------+
| mysql-bin.000002|   106      | test               |       mysql   
+------------------+----------+--------------+------------------+
>unlock tables;
master2:

>flush tables with read lock;
>show matser status;
+------------------+----------+--------------+------------------+
| File                       | Position | Binlog_Do_DB |Binlog_Ignore_DB
+------------------+----------+--------------+------------------+
| mysql-bin.000003|   106      | test               |          mysql
+------------------+----------+--------------+------------------+
>unlock tables;


    5 配置主从,分别在master1和 master2上配置对方的从

master1上:
> CHANGE MASTER TO
    ->   MASTER_HOST='192.168.1.3',
    ->   MASTER_USER='master',
    ->   MASTER_PASSWORD='123456',
    ->   MASTER_PORT=3306,
    ->   MASTER_LOG_FILE='mysql-bin.000003',
    ->   MASTER_LOG_POS=106,
    ->   MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
master2上:

> CHANGE MASTER TO
    ->   MASTER_HOST='192.168.1.2',
    ->   MASTER_USER='master',
    ->   MASTER_PASSWORD='123456',
    ->   MASTER_PORT=3306,
    ->   MASTER_LOG_FILE='mysql-bin.000002',
    ->   MASTER_LOG_POS=106,
    ->   MASTER_CONNECT_RETRY=10;
Query OK, 0 rows affected (0.02 sec)

mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
用>show processlist查看进程状态
    6 测试,在其中一个数据库test中创建新表,插入数据,在另一个数据库中查看是否同步。



四 主从复制中常见的故障及解决方法


1 从服务器上show slave status\G;查看slave状态为NO
Slave_IO_Running,为No,则说明IO_THREAD没有启动,请执行: start slave io_thread;
Slave_SQL_Running为No.则复制出错,查看Last_error字段排除错误后执行: start slave sql_thread;


2 主服务器宕机了,如何把从服务器提升会主服务器
在一主多从的环境中,必须选择数据最新的从服务器做新的主服务器,以保证数据的完整可靠。在一主两从的环境中,Server1宕机后,等到Server1和Server2把宕机前同步到的日志都执行完,比较Master_Log_File和Read_Master_Log_Pos就可以判断出谁快谁慢,因为Server2从 Server1同步的数据(1589)比Server3从Server1同步的数据(1293)新,所以应该提升Server2为新的主服务器。


3 主从复制突然停止了,该怎么处理
复制错误多半是因为日志错误引起的,所以首先要搞清楚是主日志错误还是中继日志错误,从错误信息里就能判断,如果不能判断,则使用下面的mysqlbinlog命令:
shell> mysqlbinlog <MASTER_BINLOG_FILE> > /dev/null
shell> mysqlbinlog <SLAVE_BINLOG_FILE> > /dev/null
# 如果没有错误,则不会有任何输出,反之如果有错误,则会显示出来.
如果是主日志错误,则需要在从服务器设置SET GLOBAL sql_slave_skip_counter
mysql> SET GLOBAL sql_slave_skip_counter = 1;

mysql> START SLAVE;
注:如果有多个错误,可能需要执行多次(提醒:主从服务器数据可能因此不一致)
如果是中继日志错误,只要在从服务器使用CHANGE MASTER TO即可,系统会抛弃当前的中继日志,重新下载。
mysql> CHANGE MASTER TO
MASTER_LOG_FILE=’<Relay_Master_Log_File>’,
MASTER_LOG_POS=<Exec_Master_Log_Pos>;
mysql> START SLAVE;


    另外,不同的应用环境系统总会出现各种各样的错误,处理错误的最重要依据是根据日志中错误信息分析定位故障所在,建议在出现故障时候,不要忙着百度谷歌找答案,先去日志上看看,大部分的应用故障都会有相应的日志输出,通过日志分析错误是基本的”救火之道“。







运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-342294-1-1.html 上篇帖子: 脚本之mysql数据同步重建 下篇帖子: mysql5.7.17主从同步配置
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表