Mysql主从复制实现及实施过程中遇到的问题

1、mysql主从复制原理:

    Mysql主从复制的实现,主要依赖于二进制日志来实现,过程主要是根据把主(master)的MySQL 的数据复制到其它主机( Slave )上。在复制过程中,可以理解为一台mysql服充当服务器,而其他的mysql服务器充当从服务器,而这种从服务器可以是一个或者是多个。在主从复制过程中,mysql-master会将更新写入二进制日志,并维护文件的一个索引以跟踪日志循环。开启的二进制,mysql主服务器就会安装你配置的二进制文件名生成二进制文件,而这些日志主要是用来记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置,从服务器接收从那时起发生的任何更新。mysql要做到主从复制,其实是把事务都记录到二进制日志上,只需要从服务拿到这份日志,照着日志上面的动作施加到自己身上就可以了。这样就实现了主从复制。

2.主master库跟从slave数据库直接的UUID必须要不一致。在云端的服务器需要注意是否为通过克隆的方式复制的服务器,在实现主从复制的时候有可能日志会报UUID冲突的错误:此时需要找到auto.cnf下文件并重命名,我这边的路径是在/var/lib/mysql,里面的内容就是记录UUID。mv /var/lib/mysql/auto.cnf /var/lib/mysql/auto.cnf.bak 重命名该文件,并重启mysql服务。(systemctl restart mysql) 即可。建立Mysql主从复制主从服务器直接必须要能ping通,Mysql版本必须一致(mysql -V 查看mysql版本)。

3.在master数据库上的操作:

编辑master数据库的my.cnf文件

[root@master ~]# vi /usr/local/mysql/my.cnf
.......
server-id=1        #数据库唯一ID,主从的标识号绝对不能重复。
log-bin=mysql-bin    #开启bin-log,并指定文件目录和文件名前缀
#binlog-do-db=  #需要同步的数据库。如果是多个同步库,就以此格式另写几行即可。如果不指明对某个具体库同步,就去掉此行,表示同步所有库(除了ignore忽略的库)。
#binlog-ignore-db=  #不同步mysql系统数据库。如果是多个不同步库,就以此格式另写几行;也可以在一行,中间逗号隔开。
sync_binlog = 1      #确保binlog日志写入后与硬盘同步
binlog_checksum = none  #跳过现有的采用checksum的事件,mysql5.6.5以后的版本中binlog_checksum=crc32,而低版本都是binlog_checksum=none
binlog_format = mixed   #bin-log日志文件格式,设置为MIXED可以防止主键重复。
character-set-server=utf8  #设置mysql默认编码
skip-name-resolve     #解决有可能出现的DNS域名错误
 
 
4.在从数据库slave的操作
编辑从数据库配置文件:vi /etc/mysql/mysql.d/mysql.cnf

server-id=2 #设置从服务器id,必须于主服务器不同

#log-bin=/var/lib/mysql/log-bin #启动MySQ二进制日志系统

#replicate-do-db=huanqiu #需要同步的数据库名。如果不指明同步哪些库,就去掉这行,表示所有库的同步(除了ignore忽略的库)。

#replicate-ignore-db=mysql #不同步mysql系统数据库

slave-skip-errors = all #跳过所有的错误,继续执行复制操作,这个配置可以解决主从复制中可能出现的因为主键(primary key)冲突引起的错误

skip-name-resolve

 

5.在主库中创建账号slave并授权:

GRANT REPLICATION SLAVE ON *.* to 'slave'@'%' identified by 'abc123456';

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)  刷新日志

 

mysql> show grants for slave@'10.18.104.146';
+-------------------------------------------------------------------------------+
| Grants for slave@10.18.104.146 |
+-------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'10.18.104.146' 
+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)

查看slave权限。

 

mysql> show master status; (查看master状态,)
+----------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------+----------+--------------+------------------+-------------------+
| log-bin.000003 | 144148 | | | |
+----------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec) 

注意记下File(log-bin.000003),Position(144148) 这2个字段内容是否由输出,有则正常。

此时主master库操作完成。

 

6.在从数据库slave开始主从同步指令

命令行进入mysql (mysql -u root -p )

mysql>stop slave;

mysql>change  master to master_host='10.18.104.146',master_user='slave',master_password='abc123456',master_log_file='log-bin.000003',master_log_pos=144148;

mysql>start slave;

mysql> show slave status \G  # 查看slave状态确定2个线程是否完成

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.18.154.194
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: log-bin.000003
Read_Master_Log_Pos: 145504
Relay_Log_File: Backup-relay-bin.000020
Relay_Log_Pos: 137591
Relay_Master_Log_File: log-bin.000003
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: 145504
Relay_Log_Space: 137799
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: d03a315b-1967-11e8-9d8d-1d73e62c2842
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
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
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)

 

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

这2个字段信息必须要为yes,证明主从复制搭建成功。

 

7.从主数据库master中备份导出一个数据库用于测试

mysql -u root -p test>/root/tmp/test.sql

从库中导入这部分数据用于测试source /root/tmp/test.sql

在主库中创建一个表create table test (id int(8)),从库中执行查询select * from test.test 测试是否完成。

自此,完成mysQL主从复制。

解除mysql主从复制(

stop slave;
reset slave;

)

 

二。在实现Mysql中遇到的坑

1.Got fatal error 1236 from master when reading data from binary log  ('Could not find first log file name in binary log index file')

从库中同步主库数据文件不一致。在master中查看数据文件保存的位置 (mysql> show variables like '%dir%';)

+-----------------------------------------+----------------------------+
| Variable_name | Value |
+-----------------------------------------+----------------------------+
| basedir | /usr/ |
| binlog_direct_non_transactional_updates | OFF |
| character_sets_dir | /usr/share/mysql/charsets/ |
| datadir | /var/lib/mysql/ |
| ignore_db_dirs | |
| innodb_data_home_dir | |
| innodb_log_group_home_dir | ./ |
| innodb_max_dirty_pages_pct | 75.000000 |
| innodb_max_dirty_pages_pct_lwm | 0.000000 |
| innodb_tmpdir | |
| innodb_undo_directory | ./ |
| lc_messages_dir | /usr/share/mysql/ |
| plugin_dir | /usr/lib/mysql/plugin/ |
| slave_load_tmpdir | /tmp |
| tmpdir | /tmp |
+-----------------------------------------+----------------------------+

找到错误日志路径/var/lib/mysq/

查看错误日志得知是主从数据库直接的bin-log或者file-pos位置不一致。

解决办法:进入主数据库master,执行flush logs;  查看当前master状态:show master status ,发现其日志+1.此时进入从库中执行,

mysql>CHANGE MASTER TO MASTER_LOG_FILE='mysqld-bin.000011',MASTER_LOG_POS=106; 

mysql>start slave;

mysql>show slave status \G

查看2个线程是否就绪:

Slave_IO_Running: Yes

Slave_SQL_Running: Yes

 

posted @ 2018-09-21 17:43  alphabetter  阅读(190)  评论(0)    收藏  举报