mysql AB复制实战
mysqldump解决了mysql数据库的备份,它只是基于某个时间点做备份,无法解决实时备份的问题,为了解决mysql实时备份的问题,mysql官方推出了mysql主从备份机制,可以让用户通过设置mysql主从来实现数据库实时备份。
1、MySQL服务器宕机怎么 单点故障
2、数据的安全
一、mysql AB复制
通过多台机器实现一主多从的方式来实现数据备份,主服务器负责让用户读写数据,从服务器负责同步主服务器数据,也可以承担用户读的任务。
至少两台机器
二、AB复制原理

1、用户or web 对主服务器的所有修改操作都会记录在binary log日志
成功的修改操作【增加 修改 删除】 记录的是SQL语句 主上的一个线程
2、从 有两个线程
IO线程:负责连接主mysql【AB通信 A授权账号】提取binlog中的SQL语句到relay log
SQL线程:在本地执行relay log中新增的SQL语句
注意:AB是异步
三、master服务器设置
实验拓扑

- 安装mysql并启动
- 关闭防火墙,selinux
- 设置时间服务器
- 修改配置文件 设置server-id=N
- 创建slave连接master的账号,用于取SQL语句
3.1、安装mysql并启动
a、安装mysql
1 2
| 官网下载mysql yum源,安装 安装方法:yum -y install mysql-server mysql
|
b、启动mysql
1
| systemctl enable mysqld;systemctl start mysqld
|
c、修改root密码
1 2
| mysql> alter user 'root'@'localhost' identified by '98989'; Query OK, 0 rows affected (0.01 sec)
|
3.2、关闭防火墙,selinux
1 2 3 4 5 6 7 8
| [root@node1 ~]# systemctl disable firewalld [root@node1 ~]# iptables -F [root@node1 ~]# iptables -t nat -F [root@node1 ~]# sed -i -r '/SELINUX=/c\SELINUX=disabled' /etc/selinux/config [root@node1 ~]# reboot
其他机器同理
|
3.3、设置时间服务器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 禁止向centos默认时间服务器同步时间 [root@node1 ~]# sed -i.bak '/^pool 2.centos.pool.ntp.org iburst$/s//#/' /etc/chrony.conf
设置时间服务器为阿里云的 [root@node1 ~]# cat >> /etc/chrony.conf <<EOF > server ntp1.aliyun.com > server ntp2.aliyun.com > server ntp3.aliyun.com > server ntp4.aliyun.com > EOF
重启服务生效 [root@node1 ~]# systemctl restart chronyd 查看命令,看一下时间服务器IP地址 [root@node1 ~]# chronyc sources -v
|
3.4、修改配置文件 设置server-id=N
server-id的数字越小,优先级越高。
1
| [root@node1 ~]# echo "server-id=1" >> /etc/my.cnf.d/mysql-server.cnf
|
确认binlog是开启的
3.5、创建slave连接master的账号,用于取SQL语句
登陆进入mysql: mysql -u root -p
password:
1 2 3 4 5 6 7 8
| mysql> create user sko identified by "98989"; Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to sko; Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
|
查看主的状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| mysql> show master status \G; *************************** 1. row *************************** File: binlog.000002 Position: 155 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)
ERROR: No query specified
mysql> mysql> create database db1; Query OK, 1 row affected (0.00 sec)
File: binlog.000002 当前主的binlog日志 Position: 155 当前binlog日志的SQL语句记录点
|
四、slave设置
实验步骤
- 安装mysql并启动
- 关闭防火墙、selinux
- 设置时间服务器
- 修改配置文件 设置server-id=N+x
- 设置master主信息
- 测试同步
1 2 3 4 5
| - [4.1] 安装mysql并启动 - [4.2] 关闭防火墙、selinux - [4.3] 设置时间服务器
省略......
|
4.3、修改配置文件 设置server-id=N+x
从服务器的server-id要比主的数字大。
1
| [root@node2 ~]# echo "server-id=2" >> /etc/my.cnf.d/mysql-server.cnf
|
4.4、设置slave同步
1 2 3 4 5 6 7 8
| mysql> stop slave; Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> change master to master_host='192.168.98.201',master_user='sko',master_password='98989',master_log_file='binlog.000002'; Query OK, 0 rows affected, 3 warnings (0.01 sec)
mysql> start slave; Query OK, 0 rows affected (0.00 sec)
|
4.5、验证slave
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.98.201 Master_User: sko Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.000002 Read_Master_Log_Pos: 337 Relay_Log_File: node2-relay-bin.000002 Relay_Log_Pos: 545 Relay_Master_Log_File: binlog.000002 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: 337 Relay_Log_Space: 753 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: ae106b21-59c3-11ea-aa77-000c29b8d045 Master_Info_File: mysql.slave_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: Master_public_key_path: Get_master_public_key: 0 Network_Namespace: 1 row in set (0.00 sec)
ERROR: No query specified
|
4.6、干货分享,如何解决AB不同步的问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
| Slave_IO_Running: Yes #该线程负责从master上拿binlog日志到relaylog,复制线程 #该线程如果是NO,如何排除 #1、查主从网络是否能通信,iptables selinux #2、查你的repl账号在slave上是否能连接master
Slave_SQL_Running: Yes #该线程负责将本机relaylog中的SQL语句执行一次 #该线程为NO,如何排除 #该线程为NO说明relaylog中的SQL语句在本地无法执行 #1、查看mysql> show slave status \G; 找到不能执行的语句
mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.98.201 Master_User: sko Master_Port: 3306 Connect_Retry: 60 Master_Log_File: binlog.000002 Read_Master_Log_Pos: 515 Relay_Log_File: node2-relay-bin.000002 Relay_Log_Pos: 545 Relay_Master_Log_File: binlog.000002 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1008 Last_Error: Error 'Can't drop database 'db1'; database doesn't exist' on query. Default database: 'db1'. Query: 'drop database db1' Skip_Counter: 0 Exec_Master_Log_Pos: 337 Relay_Log_Space: 931 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: NULL Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1008 Last_SQL_Error: Error 'Can't drop database 'db1'; database doesn't exist' on query. Default database: 'db1'. Query: 'drop database db1' Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: ae106b21-59c3-11ea-aa77-000c29b8d045 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 200227 20:36:57 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: Master_public_key_path: Get_master_public_key: 0 Network_Namespace: 1 row in set (0.00 sec)
ERROR: No query specified
#这段就能看到为何不能执行,原因是slave上没有db1数据库,所以不能删除。 Last_SQL_Error: Error 'Can't drop database 'db1'; database doesn't exist' on query. Default database: 'db1'. Query: 'drop database db1' #2、最关键的一步,如何定位错误点 #Read_Master_Log_Pos: 515 找到目前复制的master Binlog日志的pos位置,从这个位置开始,后续在slave上做差异还原同步。 #拓展:如何找下一个POS位置,去看你master的当前binlog日志 #定位错误点SQL语句的位置号 [root@node1 ~]# mysqlbinlog /var/lib/mysql/binlog.000002|egrep -B 30 "drop database db1" ......... # at 414 错误点SQL语句的位置号 #200227 20:36:57 server id 1 end_log_pos 515 CRC32 0x683207a9 Query thread_id=8 exec_time=0 error_code=0 Xid = 17 SET TIMESTAMP=1582853817/*!*/; drop database db1 ..........
#定位错误点SQL语句之后一条的位置号 [root@node1 ~]# mysqlbinlog /var/lib/mysql/binlog.000002|egrep -A 30 "drop database db1" drop database db1 /*!*/; # at 515 发现下一条SQL语句是515 #200227 20:42:37 server id 1 end_log_pos 592 CRC32 0x2677edde Anonymous_GTID last_committed=2 sequence_number=3 rbr_only=no original_committed_timestamp=1582854157245396 immediate_commit_timestamp=1582854157245396 transaction_length=182 # original_commit_timestamp=1582854157245396 (2020-02-27 20:42:37.245396 EST) # immediate_commit_timestamp=1582854157245396 (2020-02-27 20:42:37.245396 EST) /*!80001 SET @@session.original_commit_timestamp=1582854157245396*//*!*/; /*!80014 SET @@session.original_server_version=80017*//*!*/; /*!80014 SET @@session.immediate_server_version=80017*//*!*/; SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 592 #200227 20:42:37 server id 1 end_log_pos 697 CRC32 0x3624f753 Query thread_id=11 exec_time=0 error_code=0 Xid = 24 SET TIMESTAMP=1582854157/*!*/; /*!80016 SET @@session.default_table_encryption=0*//*!*/; create database db2 /*!*/; .................... #发现下一条SQL语句是515
#通过上述命令可以查看pos 515之后的语句,-A 30 是指往后30行 -B 30是看往前30行,根据自己的需求设置 #3、重新设置同步指令 mysql> stop slave; Query OK, 0 rows affected (0.01 sec)
mysql> change master to master_host='192.168.98.201',master_user='sko',master_password='98989',master_log_file='binlog.000002',master_log_pos=515; Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave; Query OK, 0 rows affected (0.00 sec)
|