MySQL主从复制的工作原理如下:
(1)Mysql服务器之间的主从复制是基于二进制日志,主服务器使用二进制日志来记录数据库的变动情况,从服务器通过读取和执行该日志文件来保持和主服务器的数据一致。
(2)在使用二进制日志时,主服务器的所有操作都会被记录下来,然后从服务器会接收到该日志的一个副本。从服务器可以指定执行该日志中的哪一类事件(插入数据、更新数据、删除数据),默认会执行日志中的所有语句。
(3)每一个从服务器会记录关于二进制日志的信息(文件名和已经处理过的语句),这样意味着不同的从服务器可以分别执行同一个二进制日志的不同部分,并且从服务器可以随时连接或者中断和服务器的连接。
(4)主服务器和每一个从服务器都必须配置一个唯一的server-id,每一个从服务器需要通过CHANGE MASTER TO语句来配置它要连接的主服务器的ip地址,日志文件名称和该日志里面的位置等信息。
MySQL主从复制配置的步骤如下:
MySQL版本:MySQL5.7
Linux版本:CentOS7.0
主数据库地址:192.168.1.11
从数据库地址:192.168.1.12; 192.168.1.13
找到主数据库的配置文件my.cnf,在[mysqld]部分添加如下内容:
[root@Mysql11 ~]# vim /etc/my.cnf
[mysqld]
.........
server-id=1 ### 服务器ID
log-bin=mysql-bin ### 开启binlog
binlog_format=mixed ### binlog模式为mixed
### 在ROW模式下,即使我们只更新了一条记录的其中某个字段,也会记录每个字段变更前后的值,binlog日志会很大。这个行为可以通过binlog_row_image参数控制,该参数的取值如下:
### FULL(默认值):记录列的所有修改,即使字段没有发生变更也会记录。
### MINIMAL:只记录修改的列。
binlog_row_image=MINIMAL
## 在Row模式下,binlog只记录数据的改变。使用binlog_rows_query_log_events参数也可以记录SQL。参数的默认为值为FALSE,如果为true的情况下,会通过Rows Query Event事件来记录SQL。
binlog-rows-query-log_events=1
### 设置同步时需要忽略哪些数据库
## 一般同步不要同步mysql库,用户名和密码信息在mysql数据库中
binlog-ignore-db=mysql
binlog-ignore-db=sys
........
配置完成后重启mysql服务,查看binlog日志文件信息:
[root@Mysql11 ~]# ll /var/lib/mysql/mysql-bin*
-rw-r-----. 1 mysql mysql 923 7月 3 23:19 /var/lib/mysql/mysql-bin.000001
-rw-r-----. 1 mysql mysql 266 7月 5 10:16 /var/lib/mysql/mysql-bin.index
每一个从服务器都需要用到一个账户名和密码来连接主服务器,可以为每一个从服务器都创建一个账户,也可以让全部服务器使用同一个账户。该账户可以被【192.168.1】网段下的所有IP地址使用,且只能进行主从同步,没有其他权限。
mysql> set global validate_password_policy=low;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_length=4;
Query OK, 0 rows affected (0.00 sec)
mysql> grant replication slave on *.* to 'repl'@'192.168.1.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.02 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> select host,user,authentication_string from mysql.user;
+-------------+---------------+-------------------------------------------+
| host | user | authentication_string |
+-------------+---------------+-------------------------------------------+
| localhost | root | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| localhost | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| localhost | mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| % | wgx | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
| 192.168.1.% | repl | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 |
+-------------+---------------+-------------------------------------------+
5 rows in set (0.00 sec)
(1)导出数据库之前,给数据库加锁,阻止对数据库进行任何的写操作。
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.01 sec)
mysql> use hist;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> drop table t1;
ERROR 1223 (HY000): Can't execute the query because you have a conflicting read lock
(2)导出主库中的所有数据库数据
[root@Mysql11 ~]# mysqldump -uroot -p123456 --all-databases --master-data=2 --events > /tmp/all_bak.sql
(3)把备份的主库数据复制到从库
[root@Mysql11 ~]# scp /tmp/all_bak.sql 192.168.1.12:/tmp/
[email protected]'s password:
all_bak.sql 100% 834KB 833.7KB/s 00:00
[root@Mysql11 ~]#
(4)解锁,查看二进制日志信息
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000014 | 599 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
找到从数据库的配置文件my.cnf,在[mysqld]部分添加如下内容:
[root@Mysql11 ~]# vim /etc/my.cnf
[mysqld]
.........
server-id=2 ### 服务器ID,每个服务器上配置的server-id都必须不一致
relay-log=mysql-relay-log ### 开启relay log
........
说明:从服务器也可以根据需要配置log-bin选项。
配置完成后重启mysql服务,查看relay log文件信息:
[root@localhost ~]# ll /var/lib/mysql/mysql-relay-log*
-rw-r-----. 1 mysql mysql 177 7月 5 11:00 /var/lib/mysql/mysql-relay-log.000001
-rw-r-----. 1 mysql mysql 25 7月 5 11:00 /var/lib/mysql/mysql-relay-log.index
[root@localhost ~]# mysql -uroot -p123456 < /tmp/all_bak.sql
(1)查看主服务器的数据库信息
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hist |
| mysql |
| performance_schema |
| sys |
| wanggx |
+--------------------+
6 rows in set (0.00 sec)
(2)查看从服务器的数据库信息
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hist |
| mysql |
| performance_schema |
| sys |
| wanggx |
+--------------------+
6 rows in set (0.00 sec)
在从服务器上执行如下命令:
--master_log_file和master_log_pos两个参数的取值可以在主库导出数据时使用show master logs命令得到
--也可以在主库导出数据库时添加参数【--master-data=2】得到
change master to
master_host='192.168.1.11',
master_port=3306,
master_user='repl',
master_password='123456',
master_log_file='mysql-bin.000014',
master_log_pos=599;
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.11
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000014
Read_Master_Log_Pos: 599
Relay_Log_File: mysql-relay-log.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000014
--############### Slave_IO_Running 和 Slave_SQL_Running 两个都为yes表示正常 #############
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: 599
Relay_Log_Space: 527
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: 95cfc8eb-2d58-11ea-840b-000c296166d5
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)
在hist数据库中创建一张表t222并输入数据
mysql> use hist;
Database changed
mysql> show tables;
+----------------+
| Tables_in_hist |
+----------------+
| course |
| dept |
| score |
| stu |
| t1 |
+----------------+
5 rows in set (0.00 sec)
mysql>
mysql>
mysql> create table t222(id int auto_increment primary key,name char(20),age int);
Query OK, 0 rows affected (0.03 sec)
mysql> insert into t222(name,age) values('Jack',20);
Query OK, 1 row affected (0.02 sec)
mysql> insert into t222(name,age) values('Mary',21);
Query OK, 1 row affected (0.03 sec)
mysql> insert into t222(name,age) values('Tom',18);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t222;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | Jack | 20 |
| 2 | Mary | 21 |
| 3 | Tom | 18 |
+----+------+------+
3 rows in set (0.00 sec)
mysql> use hist;
Database changed
mysql> show tables;
+----------------+
| Tables_in_hist |
+----------------+
| course |
| dept |
| score |
| stu |
| t1 |
| t222 |
+----------------+
6 rows in set (0.00 sec)
mysql> select * from t222;
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | Jack | 20 |
| 2 | Mary | 21 |
| 3 | Tom | 18 |
+----+------+------+
3 rows in set (0.00 sec)
如果要创建多个从库,其他从库的创建过程和第一个从库完全相同。