Mysql5.6主从 replication同步

来自linux中国网wiki
Evan讨论 | 贡献2019年10月14日 (一) 13:52的版本 (导入1个版本)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)
跳到导航 跳到搜索

 

角色 :主 192.168.1.11 从 192.168.1.12

binlog-format:二进制日志的格式,有row、statement和mixed几种类型;需要注意的是:当设置隔离级别为READ-COMMITED必须设置二进制日志格式为ROW,现在MySQL官方认为STATEMENT这个已经不再适合继续使用;但mixed类型在默认的事务隔离级别下,可能会导致主从数据不一致;

记住: 以后用 GTID 见参考资料

1、主库创建/etc/my.cnf,修改[mysqld]里边的键值增加

server-id=1 log-bin=binlog_name # 可以自己命名 也可以加目录 binlog_do_db = test //要做同步的数据库名字,可以是多个数据库,之间用分号分割 我的例子

#例如 如下
server-id=1
log-bin=mysql-bin

2、主库增加用户,用于从库读取主库日志

grant replication slave,reload,super on *.* to 'slave'@'192.168.1.12' identified by '123456'; # good 这个比较好 这两个选择一个
grant all on *.* to 'slave'@'192.168.1.12' identified by '123456';

select user,host from mysql.user;
show master status;
+——————+———-+————–+——————+
| File            | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———-+————–+——————+
| mysql-bin.000001 | 233 | | |
+——————+———-+————–+——————+

主库lock table 导出数据

在锁表之后,再导出数据库里的数据(如果数据库里没有数据,可以忽略这一步

获取二进制日志的信息并导出数据库,步骤:

首先登陆数据库,然后刷新所有的表,同时给数据库加上一把锁,阻止对数据库进行任何的写操作

mysql > flush tables with read lock;
然后执行下面的语句获取二进制日志的信息

mysql > show master status;

注意:如果之前的服务器并没有配置使用二进制日志,那么使用上面的sql语句会显示空,在锁表之后,再导出数据库里的数据(如果数据库里没有数据,可以忽略这一步)

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases > /server/backup/mysql_bak.$(date +%F).sql
如果数据量很大,可以在导出时就压缩为原来的大概三分之一

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
这时可以对数据库解锁,恢复对主数据库的操作

mysql > unlock tables;

Creating a User for Replication

3、从库连接主库进行测试

mysql -u slave -p123456 -h 192.168.1.11

 

4、从库配置

停从库,修改从库/etc/my.cnf,增加选项: 记得id  默认是1,作为从库不能是1

 [mysqld]
## by evan
log-bin=mysql-bin
server-id=2 #其实只有这个是必要的
master-host=192.168.1.11 #这个在5.5加上会报错呢
master-user=slave
master-password=123456


relay_log         = mysql-relay-bin
log_slave_updates = 1
read_only         = 1

#解说 
当设置log_slave_updates时,你可以让slave扮演其它slave的master


replicate-do-db = test //需要同步的库名字 如果是单个库的话 如果 是一主多从 id 要大于2 

5、启动从库,进行主从库数据同步

如果主服务器导出了数据,下面就导入该文件,如果主服务器没有数据,就忽略这一步

[root@localhost ~]# mysql -uroot -p'123456' -S /data/3306/data/mysql.sock < /server/backup/mysql_bak.2015-07-01.sql
如果从主服务器上拿过来的是压缩文件,就先解压再导入


#这两行不是一定要的
/etc/init.d/mysqld restart #restart mysqld
mysql >load data from master; 

说明:这一步也可以用数据库倒入或者直接目录考过来

#on mysql slave cli

#Note master_log_file  master_log_pos 在master 查看可得 show master status;

stop slave;
change master to master_host='192.168.1.11',master_user='slave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=233;
start slave;

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.4.241.13
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000009
          Read_Master_Log_Pos: 552783919
               Relay_Log_File: db2-relay-bin.000007
                Relay_Log_Pos: 552784082
        Relay_Master_Log_File: mysql-bin.000009
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 552783919
              Relay_Log_Space: 552784307
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 5d43a4d9-8229-11e6-a39e-00163e00166e
             Master_Info_File: /mysql/data/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0


mysql> show processlist;
+----------+-------------+-----------+------+---------+---------+-----------------------------------------------------------------------------+------------------+
| Id       | User        | Host      | db   | Command | Time    | State                                                                       | Info             |
+----------+-------------+-----------+------+---------+---------+-----------------------------------------------------------------------------+------------------+
|      526 | system user |           | NULL | Connect | 9123850 | Waiting for master to send event                                            | NULL             |
|      527 | system user |           | NULL | Connect |       0 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
| 19319210 | root        | localhost | NULL | Query   |       0 | init                                                                        | show processlist |
+----------+-------------+-----------+------+---------+---------+-----------------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

 

 

6 数据

[Creating a Data Snapshot Using mysqldump https://dev.mysql.com/doc/refman/5.6/en/replication-howto-mysqldump.html]

7 进行测试

主库创建表

 mysql> create database evan;
Query OK, 1 row affected (0.00 sec)

mysql> use evan;
Database changed
mysql> create table new (name char(20),phone char(20));
Query OK, 0 rows affected (0.07 sec)

mysql>insert into new  values('abc','0532555555');

报错 Slave_IO_Running: No 以及最下面是 Fatal error: The slave I/O thread stops because master and slave have equal MySQL server ids; these ids must be different for replication to work (or the –replicate-same-server-id option must be used on slave but this does not always make sense; please check the manual before using it).

  1. 删除多余的my.cnf就可以

find / -name "my.cnf"

server_id 与主的一样导致 http://www.jb51.net/article/27242.htm Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: ‘Client requested master to start replication from impossible position’ 后面我在主删除一个database 竟然就好了 好怪

 

 

8添加新slave服务器

 使用mysqldump
使用mysqldump来得到一个数据快照可分为以下几步:
<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下:
mysql> FLUSH TABLES WITH READ LOCK;
<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:
shell> mysqldump --all-databases --lock-all-tables >dbdump.db
<3>对表释放锁。
mysql> UNLOCK TABLES;

9 主从不同步时,如何进行数据同步至一致

 #转
将主服务器上的数据做完全备份
mysqldump --lock-all-tables --all-databases --flush-logs --master-data=2 >/root/all.sql

在从服务器上导入主服务上的完全备份,在导入时关闭I/O和SQL线程

总结:此实战中最为关键主要有两步①主服务器上锁表做完全备份,并滚动日志,②从服务器上进行半道恢复.

MySQL主从不同步问题解决

1.首先停掉Slave服务:

mysql> slave stop

2.到主服务器上查看主机状态:
记录File和Position对应的值。

mysql> show master status;
+------------------+-----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+-----------+--------------+------------------+
| mysql-bin.000020 | 135617781 | | |
+------------------+-----------+--------------+------------------+
1 row in set (0.00 sec)

3.到slave服务器上执行手动同步:

mysql> change master to
> master_host='master_ip',
> master_user='user',
> master_password='pwd',
> master_port=3307,
> master_log_file='mysql-bin.000020',
> master_log_pos=135617781;
1 row in set (0.00 sec)
mysql> slave start;
1 row in set (0.00 sec)

再次查看slave状态发现:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
Seconds_Behind_Master: 0

我们知道,因为DATA REPLICATION机制完全是基于在主上执行的增量SQL要被传播到辅服务器上,并且被成功运行。这就势必要求:在运行此机制前,主辅数据库中数据是一致的;以及在运行此机制中,辅数据库禁止来自其他的SQL(非主上传播过来SQL)的写操作。但是在运行中仍然可能遇到不一致的产生,这会导致通信无法正常继续下去。因此一旦主从出现问题,首先应该解决同步位置的问题,修复丢失的数据。

 

常见问题

主从同步出现错误:

Slave_IO_Running: Connecting Slave_SQL_Running: Yes

解决方法: 导致lave_IO_Running 为connecting 的原因主要有以下 3 个方面:

1、网络不通 2、密码不对 3、pos不对

主从同步出现一下错误:Slave_IO_Running: Connecting

mysql主从失败, 错误Got fatal error 1236解决方法

问题出现 Slave_IO_Running: No Got fatal error 1236

(vm机器 几天不用 再启动就) 由于主服务器异外重启, 导致从报错, 错误如下:
show slave status错误:

Slave_IO_Running: No
     Last_IO_Errno: 1236
                Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file'
              
查看mysql err log 如下  
2017-08-22 10:56:23 9100 [Note] Slave I/O thread: connected to master '[email protected]:3306',replication started in log 'mysql-bin.000010' at position 120
2017-08-22 10:56:23 9100 [ERROR] Error reading packet from server: Could not find first log file name in binary log index file (server_errno=1236)
2017-08-22 10:56:23 9100 [ERROR] Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in binary log index file', Error_code: 1236
2017-08-22 10:56:23 9100 [Note] Slave I/O thread exiting, read up to log 'mysql-bin.000010', position 120
2017-08-22 10:56:23 9100 [Warning] Slave SQL: If a crash happens this configuration does not guarantee that the relay log info will be consistent, Error_code: 0

解决办法

按照习惯, 先尝试必改position位置.
mysql> stop slave; 
mysql> change master to master_log_file='mysql-bin.000011',master_log_pos=203; 
mysql> start slave; 
show slave status\G 
居然就成功了 

做好主从 如何导入测试环境的数据

到时如何导出测试的mysql 数据, 如何导入比较 准


排除一些比较 好 

mysql > flush tables with read lock;
然后执行下面的语句获取二进制日志的信息

mysql > show master status;

注意:如果之前的服务器并没有配置使用二进制日志,那么使用上面的sql语句会显示空,在锁表之后,再导出数据库里的数据(如果数据库里没有数据,可以忽略这一步)

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases > /server/backup/mysql_bak.$(date +%F).sql
如果数据量很大,可以在导出时就压缩为原来的大概三分之一

[root@localhost backup]# mysqldump -uroot -p'123456' -S /data/3306/data/mysql.sock --all-databases | gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
这时可以对数据库解锁,恢复对主数据库的操作

mysql > unlock tables;


做了MySQL主从复制以后,使用mysqldump对数据备份时,一定要注意按照如下方式:

mysqldump --master-data --single-transaction --user=username --password=password dbname> dumpfilename

这样就可以保留 file 和 position 的信息,在新搭建一个slave的时候,还原完数据库, file 和 position 的信息也随之更新,接着再start slave 就可以很迅速的完成增量同步!

还可以设置一个log保存周期:

expire_logs_days=14

做好主从好 如何快速导入别的数据到主 

参考

MySQL主从失败, 错误Got fatal error 1236解决方法

参考C资料

MySQL主从复制架构及原理

MySQL 5.6基于GTID及多线程的同步复制(Mysql util主从配置工具)详解

mysql GTID Replication

与MySQL传统复制相比,GTID有哪些独特的复制姿势?

Mysql主从同步(复制)

MySQL5.6主从同步(binlog方式)