1. mysql主从复制的原理
mysql的主从同步复制方案和scp、rsync等文件级别同步是类似的,都是数据的传输。但不同的是,mysql无需借助第三方工具来实现,而是利用其内建的复制功能。将Mysql的数据分布到多个系统上去,这种分布的机制,是通过将Mysql的某一台主机的 数据复制到其它主机(slaves)上,并重新执行一遍来实现的。复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更 新写入二进制日志文件,并维护文件的一个索引以跟踪日志循环。这些日志可以记录发送到从服务器的更新。当一个从服务器连接主服务器时,它通知主服务器从服 务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,然后封锁并等待主服务器通知新的更新。
1.1 mysql复制支持的类型
(1)基于语句的复制(statement):即将主服务器上执行的语句在从服务器上再执行一遍。
(2)基于行的复制(row):把改变的数据内容复制过去,比较消耗磁盘空间。但数据比较精确。从mysql5.0开始支持。
(3)基于混合模式的复制(mixed):Mysql默认使用的就是基于语句复制,效率比较高,一旦发现没办法语句精确复制时就会自动选择基于行复制。
1.2 mysql复制解决的问题
MySQL复制技术有以下一些特点:
(1) 数据分布 (Data distribution )
(2) 负载平衡(load balancing)
(3) 备份(Backups)
(4) 高可用性和容错行 High availability and failover
1.3 mysql主从复制的过程
mysql复制整体上有3个步骤:
(1)slave服务器启动一个I/O thread向master服务器发起读取二进制日志事件的请求,也就是读取binlog中的events;
(2)master服务器为每个slave服务器的I/O thread启动一个dump thread用于向其发送二进制日志events;
(3)slave服务器接收到master服务器上的二进制日志中的events后将其保存于realylog中继日志中,再启动SQL thread对中继日志中的事件进行读取并执行一遍(replay)并保存于本地数据文件中。
下图描述了复制的过程
2.mysql主从复制的部署
有两台Mysql服务器master和slave,master为主服务器,slave为从服务器,初始状态时,Master和slave中的数据信息相同,当Master 中的数据发生变化时,slave也跟着发生相应的变化,使得master和slave的数据信息同步,达到备份的目的。
要点:
负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限。
环境:
master和slave的mysql数据库版本为 5.5.44
操作系统:
CentOS Linux release 7.2.1511
IP地址:
Master: 192.168.100.10/24
Slave: 192.168.100.20/24
2.1 配置master
1.接下来对master进行,添加如下用于启用二进制日志功能,包括定义唯一的服务器标识server_id,在配置文件添加如下:
[mysqld]
server_id=10 #定义服务器标识
log_bin=master-bin #启用二进制日志功能并命名为master-bin
innodb_file_per_table=ON #为每个表使用单独的表空间
重启mysql服务后,运行“SHOW MASTER STATUS;”可以查看到二进制日志的状态:
MariaDB [(none)]> SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000004 | 245 | | |
+-------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
2.创建复制账号,赋予此用户复制权限,使得slave服务器通过此用户连接至master服务器进行复制操作:
MariaDB [(none)]> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'repluser'@'192.168.100.20' IDENTIFIED BY 'redhat';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
2.2 配置slave
1.接下来对slave进行,添加如下用于启用中继日志功能,包括定义唯一的服务器标识server_id,在配置文件添加如下:
[mysqld]
relay_log=relay-log #定义服务器标识
server_id=20 #启用中继日志功能并命名为relay-log
innodb_file_per_table=ON #为每个表使用单独的表空间
2.重启slave后,使用有复制权限的用户账号连接至主服务器,并启动复制线程;
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='192.168.100.10',MASTER_USER='repluser',MASTER_PASSWORD='redhat',MASTER_LOG_FILE='master-bin.000004',MASTER_LOG_POS=245;
Query OK, 0 rows affected (0.05 sec)
注意:以上指定的MASTER_LOG_FILE=需为master节点正在使用的二进制日志文件名,MASTER_LOG_POS=可以指定为0,即从第一个事件开始复制,或者指定为当前master服务器的位置,在master通过“SHOW MASTER STATUS;”查看
3.启动slave并查看slave的状态:
MariaDB [(none)]> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.100.10
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: master-bin.000004
Read_Master_Log_Pos: 499
Relay_Log_File: relay-log.000002
Relay_Log_Pos: 784
Relay_Master_Log_File: master-bin.000004
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: 499
Relay_Log_Space: 1072
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: 10
1 row in set (0.00 sec)
在这里主要是看:
Slave_IO_Running=Yes
Slave_SQL_Running=Yes
slave的I/O和SQL线程都已经开始运行,而且Seconds_Behind_Master不再是NULL。日志的位置增加了,意味着一些事件被获取并执行了。如果你在master上进行修改,你可以在slave上看到各种日志文件的位置的变化,同样,你也可以看到数据库中数据的变化。
通过查看master和slave上的线程状态,可以看到master启用的Binlog dump线程:
MariaDB [(none)]> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 3
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: NULL
Info: SHOW PROCESSLIST
Progress: 0.000
*************************** 2. row ***************************
Id: 4
User: repluser
Host: 192.168.100.20:43838
db: NULL
Command: Binlog Dump
Time: 17555
State: Master has sent all binlog to slave; waiting for binlog to be updated
Info: NULL
Progress: 0.000
2 rows in set (0.00 sec)
查看slave上的线程状态可以看到I/O线程和SQL线程已经被启用:
MariaDB [(none)]> SHOW PROCESSLIST\G
*************************** 1. row ***************************
Id: 2
User: root
Host: localhost
db: NULL
Command: Query
Time: 0
State: NULL
Info: SHOW PROCESSLIST
Progress: 0.000
*************************** 2. row ***************************
Id: 3
User: system user
Host:
db: NULL
Command: Connect
Time: 17820
State: Waiting for master to send event
Info: NULL
Progress: 0.000
*************************** 3. row ***************************
Id: 4
User: system user
Host:
db: NULL
Command: Connect
Time: 19010
State: Slave has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
Progress: 0.000
3 rows in set (0.00 sec)
2.3 验证
在主服务器上创建数据库mydb:
MariaDB [(none)]> CREATE DATABASE mydb;
Query OK, 1 row affected (0.00 sec)
在从服务器上就能看到备份的数据库mydb了:
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.00 sec)
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.00 sec)
至此,mysql主从复制部署完成了,希望对你有所帮助。
PS: 博主刚开始写博客,写的不好的地方请多多包容,多谢指点。