MySQL主从复制搭建(一主一从)

本次操作

一、主库与从库配置

MySQL版本:MySQL 5.7
系统:Centos 6.5

服务器 IP
192.168.172.129
192.168.172.128
主从两台服务器配置完全相同。
1.主库配置:

在主库服务器安装MySQL数据库,安装方式参考:Linux系统部署MySQL 5.7数据库(Generic免安装部署)

主库MySQL安装完毕后信息如下:
安装位置:/data/mysql5.7
数据库状态:刚初始化数据库,并未存储表结构和数据。

主库参数文件my.cnf配置:
1)修改配置文件my.cnf,是主要修改参数log-bin、server-id两个参数。

[root@local129 ~]# vim /etc/my.cnf
......
log-bin = master-bin
server-id = 129 #可以保持默认1,只要是主库和从库不可以相同即可
......

2)主库服务器启动MySQL数据库,登陆root用户后创建主从复制用户rep并授权。

[root@local129 ~]# service mysqld start    # 由于配置了/etc/init.d/mysqld,可以直接启动。
[root@local129 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 21
Server version: 5.7.26-log MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>grant replication slave on *.* to rep@'%' identified by 'rep123456';

2.将主库数据导入到从库服务器,两种方式:

(1).直接将主库安装好的MySQL数据库停库后整体拷贝到从库服务器相同目录下(包括安装目录、初始化数据目录、/etc下的my.cnf文件、/etc/init.d下的mysqld启动文件等),但是注意在拷贝过去后必须删除/data/mysql5.7/data/auto.cnf文件,因为其中的uuid是与主库相同的,如果没有删除,在启动从库slave进程后,在查看slave状态时会发现Slave_IO_Running 为NO,从库启动失败。

(2)使用mysqldump备份主库,然后恢复到从库。有足够的停机时间,然后主库锁表后使用mysqldump工具导出主库,锁表导出时查看主库binlog日志位置,便于在从库执行change master语句时指定从库复制的起始位置。
相关操作参考如下:

主库锁定表

mysql> flush tables with read lock;

查看主库状态。

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

此处主要查看主库的bin-log日志文件名和Postion值,在配置从库是需要指定这两个参数。
这两个参数如果是运行一段时间的MySQL库日志名称和Postion值都会有所变化。

使用mysqldump导出库:

[root@local129 ~]# mysqldump -uroot -proot123 --events   --single-transaction dbname > dbname_full.sql

参数 -B 生成创建库的语句及use语句.
-F 刷新日志,主要用于恢复时便于找寻binlog日志.

在备份结束后记得解锁主库:

mysql> unlock tables;
2.从库配置

(1)从库安装MySQL软件(习建议安装与主库相同方式和目录),并初始化数据库,修改配置文件my.cnf(参数文件可直接使用主库my.cnf),其中主要修改参数server-id参数。一般从库关于binlog参数可注释掉。

[root@local129 ~]# vim /etc/my.cnf
......
server-id = 128 # 从库必须要和主库不一样,否则会配置启动会失败。
......
[root@local128 ~]# service mysqld start

(2)创建于主库相同名称和字符集的database,以及相关用户,保持与主库一样(便于主从切换后不影响服务使用)。

(3)上传主库导出文件到从库服务器,并导入从库:

[root@local129 ~]# mysqldump -uroot -proot123   dbname < dbname_full.sql

(4)登陆root用户,设置主库信息。


[root@local128 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.7.26-log MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> change master to master_host='192.168.172.129',master_user='rep',master_port=3306,master_password='rep123',master_log_file='master-bin.000001',master_log_pos=154;

(5)从库开启SQL线程,查看状态。

mysql> start slave;
Query OK, 0 rows affected (0.07 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.172.129
                  Master_User: rep
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 8935536
               Relay_Log_File: local128-relay-bin.000003
                Relay_Log_Pos: 321
        Relay_Master_Log_File: master-bin.000001
             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: 8935536
              Relay_Log_Space: 8936080
              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: f147354f-803d-11e9-a73b-000c29e309bf
             Master_Info_File: /usr/local/mysql/data/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)

mysql> 

一定要注意,主从复制配置成功后,slave状态中:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
这两个进程一定要是 Yes 状态才可以!!!

本次操作用于测试,主从库都是第一次安装,如果是已经运行一段时间MySQL数据库在不停数据库和不停止服务的情况搭建主从复制(当前主库开启了MySQL的binlog,否则需要配置binlog并重启后执行一下操作)相关参考方法如下
1.导出主库:
mysqldump -uroot -proot123 --events --flush-privileges --master-data=2 --single-transaction --all-databases> dbname_full.sql
–master-data 参数可以在导出的sql中记录change master 语句,显示主库的binlog名称和位置,用于从库指定主句,相当于主库锁表后执行了show master status语句。等于1,change master语句没有注释,等于2则是注释掉。
2.将备份上传从库服务器,然后用一下命令查看binlog位置:
[root@local128 ~] # head -n 100 | grep MASTER
CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000077’, MASTER_LOG_POS=154;
3.导入从库:
[root@local128 ~] # mysql -uroot -proot123 dbname < dbname_full.sql
4.登陆从库执行主库:
change master to master_host=‘192.168.172.129’,master_user=‘rep’,master_port=3306,master_password=‘rep123’,master_log_file=‘master-bin.000077’,master_log_pos=154;

三、测试

1.主库创建数据库。

[root@local129 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.26-log MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database magl;
Query OK, 1 row affected (0.03 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| magl               |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
6 rows in set (0.03 sec)

mysql> 

从库查看:

[root@local128 ~]# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.26-log MySQL Community Server (GPL)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| magl               |
| mysql              |
| performance_schema |
| sys                |
| test               |
+--------------------+
6 rows in set (0.00 sec)

mysql> 

从库可以看到主库创建的数据已经复制过来,主从复制成功。
如果配置一主多从模式,操作方式类似。

注意:

1.以上创建的主从复制搭建完成后主库创建函数会报错:

Error Code : 1418
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
(0 ms taken)

主要是安全设置方面的配置,参数 log_bin_trust_function_creators参数缺省0,是不允许function的同步的,一般我们在配置repliaction的时候,没有特别进行此参数设置,主库创建函数时就会报错1418,,并且从库的slave就会报告错误,然后slave stoped。

处理方法:

登陆mysql数据库(主从都要执行)

set global log_bin_trust_function_creators = 1;

然后从库重新启动slave:

start slave;

为了以防再出现错误,可以将参数log_bin_trust_function_creators = 1写进参数文件my.cnf中,永久生效。

2.从库重启时slave会自动启动。

3.为了防止从库被用户修改数据,导致主从不一致,要在从库的参数文件/etc/my.cnf 中添加read-only参数,将从库设置为只读模式。

[root@local128 ~]# grep read-only /etc/my.cnf

read-only

4.主从数据差异很大,可以定期手动进行数据同步操作:
(1)在主库上执行锁库语句,阻塞所有主库更新操作:

mysql> flush tables with read lock;

查看当前主库日志名和偏移量:

mysql> show master status;

(2)在从库上执行语句,其中MASTER_POS_WAIT()函数的参数是前面查看主库状态中的日志信息:

mysql> select MASTER_POS_WAIT('mysql-bin.000039','947');

这个select语句会阻塞,直到从库达到指定的日志文件和偏移量后,返回0.如果返回-1,则表示超时退出。查询返回0时,则主从库同步完成。

(3)最后主库释放锁:

mysql> unlock tables;
附录1:

1.同步中出现无法同步问题,可以用一下方法跳过忽略当前出现的无法同步的错误:

mysql> stop slave;
mysql> set global sql_slave_skip_counter=1;
mysql> start slave;

1)仅限于无足轻重的错误,忽略后对整体业务数据影响不大。
2)主从同步比一致性重要,然后 找个时间点在同步从库。

2.根据错误号跳过指定的错误
slave-skip-errors=1032,1062,1007

添加参数到my.cnf配置文件中,忽略一般入库重复(已存在的数据库或表)导致的同步错误
1032:记录不存在;1062:字段值重复,入库失败;1007:数据库已存在,创建失败。

3.skip-name-resolve

添加my.cnf参数文件中,一般处理MySQL连接慢。

3.MySQL从库记录binlog方法
适用场景:
1)当前从库做其他从库主库,即级联主从同步。
2)把从库作为数据库备份服务器需要开启binlog

log-bin=/data/mysql/log/binlog/mysql-bin
log-slave-updates
expire_logs_days=7

不建议用find进行定期删除文件:
find /data/mysql/log/binlog -type f -name “mysql-bin.000*” -mtime +7 | xargs rm -rf

附录2

1.主库宕机
一般分两种情况:主库数据库宕机;主库所在服务器宕机。
登陆从库查看两个主要线程状态:

mysql> show processlist\G
*************************** 1. row ***************************
     Id: 5
   User: system user
   Host: 
     db: NULL
Command: Query
   Time: 170807
  State: Slave has read all relay log; waiting for more updates
   Info: NULL
*************************** 2. row ***************************
     Id: 6
   User: system user
   Host: connecting host
     db: NULL
Command: Connect
   Time: 229445
  State: Waiting for master to send event
   Info: NULL
*************************** 3. row ***************************

此状态说明从库已经同步主库最新状态。

如果是多个从库,则查看所有从库的show slave status中查看值最新,

Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 3476

然后选择最大的Pos值的从库作为主库。
1)确保所有relay-log应用完成。从库查看slave状态:

mysql> show slave status\G
*************************** 1. row ***************************

......
 Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
......

2)登陆从库(多个从库时选定的最新的从库,多从库时也要关闭slave等待新主库后再指向新主库)

mysql> stop slave;
mysql> reset master;

3)进入从库数据库目录中删除relay-log相关文件。
4)修改从库参数文件my.cnf中参数

log-bin=/data/mysql/log/binlog/mysql-bin
expire_logs_days=7

如果存在log-slave-updates、read-only等一定要注释掉!

5)重启从库完成主从切换。如果主库服务器没有宕机可以拿到原主库binlog,则需要将原主库binlog应用到新主库。

6)如果多个从库,则需要检查新主库中同步同步用户例如rep是否存在,其他从库重置新主库连接,重新启动slave来同步新主库数据。

2.从库宕机
恢复方法:直接重做slave。
主库备份数据恢复至从库,然后重新change master。

生产环境一般建议2个及以上从库。

附录3

MySQL主从架构需要关闭数据库时,建议遵守一下步骤:
1.关闭从库slave,然后关闭从库MySQL。
2.关闭主库MySQL。

如果先关闭主库,再关闭从库,在下次启动主从库时,从库启动salve会报错:

ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repositor

处理方式:
1.停止从库salve:stop slave。 (已停止可以不用再次执行)
2.重置从库:reset slave
3.查看从库MySQL日志,会在主库停止的大概时间提示从库无法连接主库进行数据同步,同时记录断开时的日志名称和日志位置,大概日志内容参考如下:


2022-07-02T08:19:15.66789+08:00 114 [Note] Slave SQL thread for channel '' exiting, replication stopped in log 'mysq-bin.001348' at position 72522

4.重新配置从库同步主库的位置:

mysql> change master to master_host='192.168.172.129',master_user='rep',master_port=3306,master_password='rep123',master_log_file='mysq-bin.001348',master_log_pos=72522;
mysql> start slave;

你可能感兴趣的:(MySQL,mysql)